1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-02 04:48:57 +02:00

PM-2166 Update Purge vault dialog (#8658)

* PM-2166 Update purge vault dialog

* PM-2166 Fixed ESlint issue
This commit is contained in:
KiruthigaManivannan 2024-05-21 18:37:01 +05:30 committed by GitHub
parent f8c64fe8ae
commit f6d28bed70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 68 additions and 81 deletions

View File

@ -104,12 +104,11 @@
<button type="button" bitButton buttonType="danger" (click)="deleteOrganization()"> <button type="button" bitButton buttonType="danger" (click)="deleteOrganization()">
{{ "deleteOrganization" | i18n }} {{ "deleteOrganization" | i18n }}
</button> </button>
<button type="button" bitButton buttonType="danger" (click)="purgeVault()"> <button type="button" bitButton buttonType="danger" [bitAction]="purgeVault">
{{ "purgeVault" | i18n }} {{ "purgeVault" | i18n }}
</button> </button>
</app-danger-zone> </app-danger-zone>
<ng-template #purgeOrganizationTemplate></ng-template>
<ng-template #apiKeyTemplate></ng-template> <ng-template #apiKeyTemplate></ng-template>
<ng-template #rotateApiKeyTemplate></ng-template> <ng-template #rotateApiKeyTemplate></ng-template>
</bit-container> </bit-container>

View File

@ -28,8 +28,6 @@ import { DeleteOrganizationDialogResult, openDeleteOrganizationDialog } from "./
templateUrl: "account.component.html", templateUrl: "account.component.html",
}) })
export class AccountComponent { export class AccountComponent {
@ViewChild("purgeOrganizationTemplate", { read: ViewContainerRef, static: true })
purgeModalRef: ViewContainerRef;
@ViewChild("apiKeyTemplate", { read: ViewContainerRef, static: true }) @ViewChild("apiKeyTemplate", { read: ViewContainerRef, static: true })
apiKeyModalRef: ViewContainerRef; apiKeyModalRef: ViewContainerRef;
@ViewChild("rotateApiKeyTemplate", { read: ViewContainerRef, static: true }) @ViewChild("rotateApiKeyTemplate", { read: ViewContainerRef, static: true })
@ -232,11 +230,14 @@ export class AccountComponent {
} }
} }
async purgeVault() { purgeVault = async () => {
await this.modalService.openViewRef(PurgeVaultComponent, this.purgeModalRef, (comp) => { const dialogRef = PurgeVaultComponent.open(this.dialogService, {
comp.organizationId = this.organizationId; data: {
organizationId: this.organizationId,
},
}); });
} await lastValueFrom(dialogRef.closed);
};
async viewApiKey() { async viewApiKey() {
await this.modalService.openViewRef(ApiKeyComponent, this.apiKeyModalRef, (comp) => { await this.modalService.openViewRef(ApiKeyComponent, this.apiKeyModalRef, (comp) => {

View File

@ -12,7 +12,7 @@
<button type="button" bitButton buttonType="danger" (click)="deauthorizeSessions()"> <button type="button" bitButton buttonType="danger" (click)="deauthorizeSessions()">
{{ "deauthorizeSessions" | i18n }} {{ "deauthorizeSessions" | i18n }}
</button> </button>
<button type="button" bitButton buttonType="danger" (click)="purgeVault()"> <button type="button" bitButton buttonType="danger" [bitAction]="purgeVault">
{{ "purgeVault" | i18n }} {{ "purgeVault" | i18n }}
</button> </button>
<button type="button" bitButton buttonType="danger" (click)="deleteAccount()"> <button type="button" bitButton buttonType="danger" (click)="deleteAccount()">
@ -21,7 +21,6 @@
</app-danger-zone> </app-danger-zone>
<ng-template #deauthorizeSessionsTemplate></ng-template> <ng-template #deauthorizeSessionsTemplate></ng-template>
<ng-template #purgeVaultTemplate></ng-template>
<ng-template #deleteAccountTemplate></ng-template> <ng-template #deleteAccountTemplate></ng-template>
<ng-template #viewUserApiKeyTemplate></ng-template> <ng-template #viewUserApiKeyTemplate></ng-template>
<ng-template #rotateUserApiKeyTemplate></ng-template> <ng-template #rotateUserApiKeyTemplate></ng-template>

View File

@ -1,7 +1,9 @@
import { Component, ViewChild, ViewContainerRef } from "@angular/core"; import { Component, ViewChild, ViewContainerRef } from "@angular/core";
import { lastValueFrom } from "rxjs";
import { ModalService } from "@bitwarden/angular/services/modal.service"; import { ModalService } from "@bitwarden/angular/services/modal.service";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { DialogService } from "@bitwarden/components";
import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component"; import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component";
@ -15,8 +17,6 @@ import { DeleteAccountComponent } from "./delete-account.component";
export class AccountComponent { export class AccountComponent {
@ViewChild("deauthorizeSessionsTemplate", { read: ViewContainerRef, static: true }) @ViewChild("deauthorizeSessionsTemplate", { read: ViewContainerRef, static: true })
deauthModalRef: ViewContainerRef; deauthModalRef: ViewContainerRef;
@ViewChild("purgeVaultTemplate", { read: ViewContainerRef, static: true })
purgeModalRef: ViewContainerRef;
@ViewChild("deleteAccountTemplate", { read: ViewContainerRef, static: true }) @ViewChild("deleteAccountTemplate", { read: ViewContainerRef, static: true })
deleteModalRef: ViewContainerRef; deleteModalRef: ViewContainerRef;
@ -24,6 +24,7 @@ export class AccountComponent {
constructor( constructor(
private modalService: ModalService, private modalService: ModalService,
private dialogService: DialogService,
private userVerificationService: UserVerificationService, private userVerificationService: UserVerificationService,
) {} ) {}
@ -35,9 +36,10 @@ export class AccountComponent {
await this.modalService.openViewRef(DeauthorizeSessionsComponent, this.deauthModalRef); await this.modalService.openViewRef(DeauthorizeSessionsComponent, this.deauthModalRef);
} }
async purgeVault() { purgeVault = async () => {
await this.modalService.openViewRef(PurgeVaultComponent, this.purgeModalRef); const dialogRef = PurgeVaultComponent.open(this.dialogService);
} await lastValueFrom(dialogRef.closed);
};
async deleteAccount() { async deleteAccount() {
await this.modalService.openViewRef(DeleteAccountComponent, this.deleteModalRef); await this.modalService.openViewRef(DeleteAccountComponent, this.deleteModalRef);

View File

@ -1,38 +1,19 @@
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="purgeVaultTitle"> <form [formGroup]="formGroup" [bitSubmit]="submit">
<div class="modal-dialog modal-dialog-scrollable" role="document"> <bit-dialog dialogSize="default" [title]="'purgeVault' | i18n">
<form <ng-container bitDialogContent>
class="modal-content" <p bitTypography="body1">
#form {{ (organizationId ? "purgeOrgVaultDesc" : "purgeVaultDesc") | i18n }}
(ngSubmit)="submit()" </p>
[appApiAction]="formPromise" <app-callout type="warning">{{ "purgeVaultWarning" | i18n }}</app-callout>
ngNativeValidate <app-user-verification formControlName="masterPassword"></app-user-verification>
> </ng-container>
<div class="modal-header"> <ng-container bitDialogFooter>
<h1 class="modal-title" id="purgeVaultTitle">{{ "purgeVault" | i18n }}</h1> <button bitButton bitFormButton type="submit" buttonType="danger">
<button {{ "purgeVault" | i18n }}
type="button" </button>
class="close" <button bitButton bitFormButton type="button" buttonType="secondary" bitDialogClose>
data-dismiss="modal" {{ "close" | i18n }}
appA11yTitle="{{ 'close' | i18n }}" </button>
> </ng-container>
<span aria-hidden="true">&times;</span> </bit-dialog>
</button> </form>
</div>
<div class="modal-body">
<p>{{ (organizationId ? "purgeOrgVaultDesc" : "purgeVaultDesc") | i18n }}</p>
<app-callout type="warning">{{ "purgeVaultWarning" | i18n }}</app-callout>
<app-user-verification [(ngModel)]="masterPassword" ngDefaultControl name="secret">
</app-user-verification>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-danger btn-submit" [disabled]="form.loading">
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
<span>{{ "purgeVault" | i18n }}</span>
</button>
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
{{ "close" | i18n }}
</button>
</div>
</form>
</div>
</div>

View File

@ -1,55 +1,60 @@
import { Component, Input } from "@angular/core"; import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
import { Component, Inject } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { Router } from "@angular/router"; import { Router } from "@angular/router";
import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { Verification } from "@bitwarden/common/auth/types/verification"; import { Verification } from "@bitwarden/common/auth/types/verification";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { DialogService } from "@bitwarden/components";
export interface PurgeVaultDialogData {
organizationId: string;
}
@Component({ @Component({
selector: "app-purge-vault", selector: "app-purge-vault",
templateUrl: "purge-vault.component.html", templateUrl: "purge-vault.component.html",
}) })
export class PurgeVaultComponent { export class PurgeVaultComponent {
@Input() organizationId?: string = null; organizationId: string = null;
masterPassword: Verification; formGroup = new FormGroup({
formPromise: Promise<unknown>; masterPassword: new FormControl<Verification>(null),
});
constructor( constructor(
@Inject(DIALOG_DATA) protected data: PurgeVaultDialogData,
private dialogRef: DialogRef,
private apiService: ApiService, private apiService: ApiService,
private i18nService: I18nService, private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
private userVerificationService: UserVerificationService, private userVerificationService: UserVerificationService,
private router: Router, private router: Router,
private logService: LogService,
private syncService: SyncService, private syncService: SyncService,
) {} ) {
this.organizationId = data && data.organizationId ? data.organizationId : null;
}
async submit() { submit = async () => {
try { const response = this.userVerificationService
this.formPromise = this.userVerificationService .buildRequest(this.formGroup.value.masterPassword)
.buildRequest(this.masterPassword) .then((request) => this.apiService.postPurgeCiphers(request, this.organizationId));
.then((request) => this.apiService.postPurgeCiphers(request, this.organizationId)); await response;
await this.formPromise; this.platformUtilsService.showToast("success", null, this.i18nService.t("vaultPurged"));
this.platformUtilsService.showToast("success", null, this.i18nService.t("vaultPurged")); await this.syncService.fullSync(true);
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. if (this.organizationId != null) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises await this.router.navigate(["organizations", this.organizationId, "vault"]);
this.syncService.fullSync(true); } else {
if (this.organizationId != null) { await this.router.navigate(["vault"]);
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.router.navigate(["organizations", this.organizationId, "vault"]);
} else {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.router.navigate(["vault"]);
}
} catch (e) {
this.logService.error(e);
} }
this.dialogRef.close();
};
static open(dialogService: DialogService, config?: DialogConfig<PurgeVaultDialogData>) {
return dialogService.open(PurgeVaultComponent, config);
} }
} }