[PM-9631] MP reprompt view items (#10291)

* MP reprompt check will run before viewing item
This commit is contained in:
Jason Ng 2024-07-29 16:08:35 -04:00 committed by GitHub
parent 2eea253dac
commit 3b668deaac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 28 additions and 43 deletions

View File

@ -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()">

View File

@ -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);
} }

View File

@ -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>

View File

@ -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 },
});
}
} }

View File

@ -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: {

View File

@ -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 {

View File

@ -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,