1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 22:33:35 +00:00

[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
This commit is contained in:
SmithThe4th
2024-12-04 11:57:03 -05:00
committed by GitHub
parent 7e934bc6d3
commit 45db17627e
5 changed files with 50 additions and 4 deletions

View File

@@ -30,7 +30,7 @@
<button type="button" bitMenuItem (click)="restore(cipher)"> <button type="button" bitMenuItem (click)="restore(cipher)">
{{ "restore" | i18n }} {{ "restore" | i18n }}
</button> </button>
<button type="button" bitMenuItem (click)="delete(cipher)"> <button type="button" bitMenuItem *appCanDeleteCipher="cipher" (click)="delete(cipher)">
{{ "deleteForever" | i18n }} {{ "deleteForever" | i18n }}
</button> </button>
</bit-menu> </bit-menu>

View File

@@ -1,5 +1,5 @@
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { Component, Input } from "@angular/core"; import { ChangeDetectionStrategy, Component, Input } from "@angular/core";
import { Router } from "@angular/router"; import { Router } from "@angular/router";
import { JslibModule } from "@bitwarden/angular/jslib.module"; import { JslibModule } from "@bitwarden/angular/jslib.module";
@@ -17,7 +17,7 @@ import {
ToastService, ToastService,
TypographyModule, TypographyModule,
} from "@bitwarden/components"; } from "@bitwarden/components";
import { PasswordRepromptService } from "@bitwarden/vault"; import { CanDeleteCipherDirective, PasswordRepromptService } from "@bitwarden/vault";
@Component({ @Component({
selector: "app-trash-list-items-container", selector: "app-trash-list-items-container",
@@ -29,10 +29,12 @@ import { PasswordRepromptService } from "@bitwarden/vault";
JslibModule, JslibModule,
SectionComponent, SectionComponent,
SectionHeaderComponent, SectionHeaderComponent,
CanDeleteCipherDirective,
MenuModule, MenuModule,
IconButtonModule, IconButtonModule,
TypographyModule, TypographyModule,
], ],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class TrashListItemsContainerComponent { export class TrashListItemsContainerComponent {
/** /**

View File

@@ -1,5 +1,5 @@
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { Component } from "@angular/core"; import { ChangeDetectionStrategy, Component } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module"; import { JslibModule } from "@bitwarden/angular/jslib.module";
import { CalloutModule, NoItemsModule } from "@bitwarden/components"; import { CalloutModule, NoItemsModule } from "@bitwarden/components";
@@ -27,6 +27,7 @@ import { TrashListItemsContainerComponent } from "./trash-list-items-container/t
CalloutModule, CalloutModule,
NoItemsModule, NoItemsModule,
], ],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class TrashComponent { export class TrashComponent {
protected deletedCiphers$ = this.vaultPopupItemsService.deletedCiphers$; protected deletedCiphers$ = this.vaultPopupItemsService.deletedCiphers$;

View File

@@ -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<void>();
@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<any>,
private viewContainer: ViewContainerRef,
private cipherAuthorizationService: CipherAuthorizationService,
) {}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}

View File

@@ -2,6 +2,7 @@ export { PasswordRepromptService } from "./services/password-reprompt.service";
export { CopyCipherFieldService, CopyAction } from "./services/copy-cipher-field.service"; export { CopyCipherFieldService, CopyAction } from "./services/copy-cipher-field.service";
export { CopyCipherFieldDirective } from "./components/copy-cipher-field.directive"; export { CopyCipherFieldDirective } from "./components/copy-cipher-field.directive";
export { OrgIconDirective } from "./components/org-icon.directive"; export { OrgIconDirective } from "./components/org-icon.directive";
export { CanDeleteCipherDirective } from "./components/can-delete-cipher.directive";
export * from "./cipher-view"; export * from "./cipher-view";
export * from "./cipher-form"; export * from "./cipher-form";