From 45db17627ee6c9e8e8382b07e8db41dd77585cd2 Mon Sep 17 00:00:00 2001 From: SmithThe4th Date: Wed, 4 Dec 2024 11:57:03 -0500 Subject: [PATCH] [PM-15535] User with Edit* permission can permanently delete item from more actions menu on extension (#12234) * Added conditional to check if a cipher can be delete by user * Added change detection on push * Added directive to check if user can delete a cipher * Added directive to check if user can delete a cipher * Replaced check with directive * removed takeUntilDestroyed --- .../trash-list-items-container.component.html | 2 +- .../trash-list-items-container.component.ts | 6 ++- .../vault/popup/settings/trash.component.ts | 3 +- .../components/can-delete-cipher.directive.ts | 42 +++++++++++++++++++ libs/vault/src/index.ts | 1 + 5 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 libs/vault/src/components/can-delete-cipher.directive.ts diff --git a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html index 69322b08c8..a79b6c74b0 100644 --- a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html +++ b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html @@ -30,7 +30,7 @@ - diff --git a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts index de9d95aab0..6827823704 100644 --- a/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts +++ b/apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Component, Input } from "@angular/core"; +import { ChangeDetectionStrategy, Component, Input } from "@angular/core"; import { Router } from "@angular/router"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -17,7 +17,7 @@ import { ToastService, TypographyModule, } from "@bitwarden/components"; -import { PasswordRepromptService } from "@bitwarden/vault"; +import { CanDeleteCipherDirective, PasswordRepromptService } from "@bitwarden/vault"; @Component({ selector: "app-trash-list-items-container", @@ -29,10 +29,12 @@ import { PasswordRepromptService } from "@bitwarden/vault"; JslibModule, SectionComponent, SectionHeaderComponent, + CanDeleteCipherDirective, MenuModule, IconButtonModule, TypographyModule, ], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class TrashListItemsContainerComponent { /** diff --git a/apps/browser/src/vault/popup/settings/trash.component.ts b/apps/browser/src/vault/popup/settings/trash.component.ts index b6f77ef6a5..8bac22df53 100644 --- a/apps/browser/src/vault/popup/settings/trash.component.ts +++ b/apps/browser/src/vault/popup/settings/trash.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Component } from "@angular/core"; +import { ChangeDetectionStrategy, Component } from "@angular/core"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { CalloutModule, NoItemsModule } from "@bitwarden/components"; @@ -27,6 +27,7 @@ import { TrashListItemsContainerComponent } from "./trash-list-items-container/t CalloutModule, NoItemsModule, ], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class TrashComponent { protected deletedCiphers$ = this.vaultPopupItemsService.deletedCiphers$; diff --git a/libs/vault/src/components/can-delete-cipher.directive.ts b/libs/vault/src/components/can-delete-cipher.directive.ts new file mode 100644 index 0000000000..c1c7706a1f --- /dev/null +++ b/libs/vault/src/components/can-delete-cipher.directive.ts @@ -0,0 +1,42 @@ +import { Directive, Input, OnDestroy, TemplateRef, ViewContainerRef } from "@angular/core"; +import { Subject, takeUntil } from "rxjs"; + +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; + +/** + * Only shows the element if the user can delete the cipher. + */ +@Directive({ + selector: "[appCanDeleteCipher]", + standalone: true, +}) +export class CanDeleteCipherDirective implements OnDestroy { + private destroy$ = new Subject(); + + @Input("appCanDeleteCipher") set cipher(cipher: CipherView) { + this.viewContainer.clear(); + + this.cipherAuthorizationService + .canDeleteCipher$(cipher) + .pipe(takeUntil(this.destroy$)) + .subscribe((canDelete: boolean) => { + if (canDelete) { + this.viewContainer.createEmbeddedView(this.templateRef); + } else { + this.viewContainer.clear(); + } + }); + } + + constructor( + private templateRef: TemplateRef, + private viewContainer: ViewContainerRef, + private cipherAuthorizationService: CipherAuthorizationService, + ) {} + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } +} diff --git a/libs/vault/src/index.ts b/libs/vault/src/index.ts index f6a95281f8..dca9b2dee7 100644 --- a/libs/vault/src/index.ts +++ b/libs/vault/src/index.ts @@ -2,6 +2,7 @@ export { PasswordRepromptService } from "./services/password-reprompt.service"; export { CopyCipherFieldService, CopyAction } from "./services/copy-cipher-field.service"; export { CopyCipherFieldDirective } from "./components/copy-cipher-field.directive"; export { OrgIconDirective } from "./components/org-icon.directive"; +export { CanDeleteCipherDirective } from "./components/can-delete-cipher.directive"; export * from "./cipher-view"; export * from "./cipher-form";