[PM-9631] MP reprompt view items (#10291)
* MP reprompt check will run before viewing item
This commit is contained in:
parent
2eea253dac
commit
3b668deaac
|
@ -25,7 +25,7 @@
|
||||||
{{ favoriteText | i18n }}
|
{{ favoriteText | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<ng-container *ngIf="canEdit">
|
<ng-container *ngIf="canEdit">
|
||||||
<a routerLink="" bitMenuItem (click)="clone()">
|
<a bitMenuItem (click)="clone()">
|
||||||
{{ "clone" | i18n }}
|
{{ "clone" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
<a bitMenuItem (click)="conditionallyNavigateToAssignCollections()">
|
<a bitMenuItem (click)="conditionallyNavigateToAssignCollections()">
|
||||||
|
|
|
@ -76,6 +76,13 @@ export class ItemMoreOptionsComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
async doAutofillAndSave() {
|
async doAutofillAndSave() {
|
||||||
|
if (
|
||||||
|
this.cipher.reprompt === CipherRepromptType.Password &&
|
||||||
|
!(await this.passwordRepromptService.showPasswordPrompt())
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.vaultPopupAutofillService.doAutofillAndSave(this.cipher);
|
await this.vaultPopupAutofillService.doAutofillAndSave(this.cipher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
<bit-item *ngFor="let cipher of ciphers">
|
<bit-item *ngFor="let cipher of ciphers">
|
||||||
<a
|
<a
|
||||||
bit-item-content
|
bit-item-content
|
||||||
[routerLink]="['/view-cipher']"
|
(click)="onViewCipher(cipher)"
|
||||||
[queryParams]="{ cipherId: cipher.id, type: cipher.type }"
|
|
||||||
[appA11yTitle]="'viewItemTitle' | i18n: cipher.name"
|
[appA11yTitle]="'viewItemTitle' | i18n: cipher.name"
|
||||||
>
|
>
|
||||||
<app-vault-icon slot="start" [cipher]="cipher"></app-vault-icon>
|
<app-vault-icon slot="start" [cipher]="cipher"></app-vault-icon>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { booleanAttribute, Component, EventEmitter, Input, Output } from "@angular/core";
|
import { booleanAttribute, Component, EventEmitter, Input, Output } from "@angular/core";
|
||||||
import { RouterLink } from "@angular/router";
|
import { Router, RouterLink } from "@angular/router";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -13,7 +13,7 @@ import {
|
||||||
SectionHeaderComponent,
|
SectionHeaderComponent,
|
||||||
TypographyModule,
|
TypographyModule,
|
||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
import { OrgIconDirective } from "@bitwarden/vault";
|
import { OrgIconDirective, PasswordRepromptService } from "@bitwarden/vault";
|
||||||
|
|
||||||
import { VaultPopupAutofillService } from "../../../services/vault-popup-autofill.service";
|
import { VaultPopupAutofillService } from "../../../services/vault-popup-autofill.service";
|
||||||
import { PopupCipherView } from "../../../views/popup-cipher.view";
|
import { PopupCipherView } from "../../../views/popup-cipher.view";
|
||||||
|
@ -100,9 +100,22 @@ export class VaultListItemsContainerComponent {
|
||||||
constructor(
|
constructor(
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private vaultPopupAutofillService: VaultPopupAutofillService,
|
private vaultPopupAutofillService: VaultPopupAutofillService,
|
||||||
|
private passwordRepromptService: PasswordRepromptService,
|
||||||
|
private router: Router,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async doAutofill(cipher: PopupCipherView) {
|
async doAutofill(cipher: PopupCipherView) {
|
||||||
await this.vaultPopupAutofillService.doAutofill(cipher);
|
await this.vaultPopupAutofillService.doAutofill(cipher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onViewCipher(cipher: PopupCipherView) {
|
||||||
|
const repromptPassed = await this.passwordRepromptService.passwordRepromptCheck(cipher);
|
||||||
|
if (!repromptPassed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.router.navigate(["/view-cipher"], {
|
||||||
|
queryParams: { cipherId: cipher.id, type: cipher.type },
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import {
|
||||||
DialogService,
|
DialogService,
|
||||||
ToastService,
|
ToastService,
|
||||||
} from "@bitwarden/components";
|
} from "@bitwarden/components";
|
||||||
import { PasswordRepromptService } from "@bitwarden/vault";
|
|
||||||
|
|
||||||
import { CipherViewComponent } from "../../../../../../../../libs/vault/src/cipher-view";
|
import { CipherViewComponent } from "../../../../../../../../libs/vault/src/cipher-view";
|
||||||
|
|
||||||
|
@ -55,14 +54,12 @@ export class ViewV2Component {
|
||||||
organization$: Observable<Organization>;
|
organization$: Observable<Organization>;
|
||||||
folder$: Observable<FolderView>;
|
folder$: Observable<FolderView>;
|
||||||
collections$: Observable<CollectionView[]>;
|
collections$: Observable<CollectionView[]>;
|
||||||
private passwordReprompted = false;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private cipherService: CipherService,
|
private cipherService: CipherService,
|
||||||
private passwordRepromptService: PasswordRepromptService,
|
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
|
@ -102,20 +99,7 @@ export class ViewV2Component {
|
||||||
return await cipher.decrypt(await this.cipherService.getKeyForCipherKeyDecryption(cipher));
|
return await cipher.decrypt(await this.cipherService.getKeyForCipherKeyDecryption(cipher));
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkForPasswordReprompt() {
|
|
||||||
this.passwordReprompted =
|
|
||||||
this.passwordReprompted ||
|
|
||||||
(await this.passwordRepromptService.passwordRepromptCheck(this.cipher));
|
|
||||||
if (!this.passwordReprompted) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
async editCipher() {
|
async editCipher() {
|
||||||
if (!(await this.checkForPasswordReprompt())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.cipher.isDeleted) {
|
if (this.cipher.isDeleted) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -126,10 +110,6 @@ export class ViewV2Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete = async (): Promise<boolean> => {
|
delete = async (): Promise<boolean> => {
|
||||||
if (!(await this.checkForPasswordReprompt())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirmed = await this.dialogService.openSimpleDialog({
|
const confirmed = await this.dialogService.openSimpleDialog({
|
||||||
title: { key: "deleteItem" },
|
title: { key: "deleteItem" },
|
||||||
content: {
|
content: {
|
||||||
|
|
|
@ -18,8 +18,6 @@ import { AttachmentView } from "@bitwarden/common/vault/models/view/attachment.v
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
import { AsyncActionsModule, IconButtonModule, ToastService } from "@bitwarden/components";
|
import { AsyncActionsModule, IconButtonModule, ToastService } from "@bitwarden/components";
|
||||||
|
|
||||||
import { PasswordRepromptService } from "../../services/password-reprompt.service";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
standalone: true,
|
standalone: true,
|
||||||
selector: "app-download-attachment",
|
selector: "app-download-attachment",
|
||||||
|
@ -39,8 +37,6 @@ export class DownloadAttachmentComponent {
|
||||||
/** The organization key if the cipher is associated with one */
|
/** The organization key if the cipher is associated with one */
|
||||||
private orgKey: OrgKey | null = null;
|
private orgKey: OrgKey | null = null;
|
||||||
|
|
||||||
private passwordReprompted = false;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
|
@ -49,7 +45,6 @@ export class DownloadAttachmentComponent {
|
||||||
private encryptService: EncryptService,
|
private encryptService: EncryptService,
|
||||||
private stateProvider: StateProvider,
|
private stateProvider: StateProvider,
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private passwordRepromptService: PasswordRepromptService,
|
|
||||||
) {
|
) {
|
||||||
this.stateProvider.activeUserId$
|
this.stateProvider.activeUserId$
|
||||||
.pipe(
|
.pipe(
|
||||||
|
@ -65,15 +60,6 @@ export class DownloadAttachmentComponent {
|
||||||
|
|
||||||
/** Download the attachment */
|
/** Download the attachment */
|
||||||
download = async () => {
|
download = async () => {
|
||||||
if (this.checkPwReprompt) {
|
|
||||||
this.passwordReprompted =
|
|
||||||
this.passwordReprompted ||
|
|
||||||
(await this.passwordRepromptService.passwordRepromptCheck(this.cipher));
|
|
||||||
if (!this.passwordReprompted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let url: string;
|
let url: string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -58,10 +58,10 @@ const CopyActions: Record<CopyAction, CopyActionInfo> = {
|
||||||
protected: true,
|
protected: true,
|
||||||
event: EventType.Cipher_ClientCopiedCardCode,
|
event: EventType.Cipher_ClientCopiedCardCode,
|
||||||
},
|
},
|
||||||
email: { typeI18nKey: "email", protected: false },
|
email: { typeI18nKey: "email", protected: true },
|
||||||
phone: { typeI18nKey: "phone", protected: false },
|
phone: { typeI18nKey: "phone", protected: true },
|
||||||
address: { typeI18nKey: "address", protected: false },
|
address: { typeI18nKey: "address", protected: true },
|
||||||
secureNote: { typeI18nKey: "note", protected: false },
|
secureNote: { typeI18nKey: "note", protected: true },
|
||||||
hiddenField: {
|
hiddenField: {
|
||||||
typeI18nKey: "value",
|
typeI18nKey: "value",
|
||||||
protected: true,
|
protected: true,
|
||||||
|
|
Loading…
Reference in New Issue