PM-2166 Update purge vault dialog

This commit is contained in:
KiruthigaManivannan 2024-04-09 19:27:16 +05:30
parent 4069371b85
commit 9db6df2452
6 changed files with 68 additions and 81 deletions

View File

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

View File

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

View File

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

View File

@ -7,6 +7,8 @@ import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.compone
import { DeauthorizeSessionsComponent } from "./deauthorize-sessions.component";
import { DeleteAccountComponent } from "./delete-account.component";
import { DialogService } from "@bitwarden/components";
import { lastValueFrom } from "rxjs";
@Component({
selector: "app-account",
@ -15,8 +17,6 @@ import { DeleteAccountComponent } from "./delete-account.component";
export class AccountComponent {
@ViewChild("deauthorizeSessionsTemplate", { read: ViewContainerRef, static: true })
deauthModalRef: ViewContainerRef;
@ViewChild("purgeVaultTemplate", { read: ViewContainerRef, static: true })
purgeModalRef: ViewContainerRef;
@ViewChild("deleteAccountTemplate", { read: ViewContainerRef, static: true })
deleteModalRef: ViewContainerRef;
@ -24,6 +24,7 @@ export class AccountComponent {
constructor(
private modalService: ModalService,
private dialogService: DialogService,
private userVerificationService: UserVerificationService,
) {}
@ -35,9 +36,10 @@ export class AccountComponent {
await this.modalService.openViewRef(DeauthorizeSessionsComponent, this.deauthModalRef);
}
async purgeVault() {
await this.modalService.openViewRef(PurgeVaultComponent, this.purgeModalRef);
}
purgeVault = async () => {
const dialogRef = PurgeVaultComponent.open(this.dialogService);
await lastValueFrom(dialogRef.closed);
};
async deleteAccount() {
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">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<form
class="modal-content"
#form
(ngSubmit)="submit()"
[appApiAction]="formPromise"
ngNativeValidate
>
<div class="modal-header">
<h1 class="modal-title" id="purgeVaultTitle">{{ "purgeVault" | i18n }}</h1>
<button
type="button"
class="close"
data-dismiss="modal"
appA11yTitle="{{ 'close' | i18n }}"
>
<span aria-hidden="true">&times;</span>
</button>
</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>
<form [formGroup]="formGroup" [bitSubmit]="submit">
<bit-dialog dialogSize="default" [title]="'purgeVault' | i18n">
<ng-container bitDialogContent>
<p bitTypography="body1">
{{ (organizationId ? "purgeOrgVaultDesc" : "purgeVaultDesc") | i18n }}
</p>
<app-callout type="warning">{{ "purgeVaultWarning" | i18n }}</app-callout>
<app-user-verification formControlName="masterPassword"></app-user-verification>
</ng-container>
<ng-container bitDialogFooter>
<button bitButton bitFormButton type="submit" buttonType="danger">
{{ "purgeVault" | i18n }}
</button>
<button bitButton bitFormButton type="button" buttonType="secondary" bitDialogClose>
{{ "close" | i18n }}
</button>
</ng-container>
</bit-dialog>
</form>

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 { ApiService } from "@bitwarden/common/abstractions/api.service";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { Verification } from "@bitwarden/common/auth/types/verification";
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 { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { DialogService } from "@bitwarden/components";
export interface PurgeVaultDialogData {
organizationId: string;
}
@Component({
selector: "app-purge-vault",
templateUrl: "purge-vault.component.html",
})
export class PurgeVaultComponent {
@Input() organizationId?: string = null;
organizationId: string = null;
masterPassword: Verification;
formPromise: Promise<unknown>;
formGroup = new FormGroup({
masterPassword: new FormControl<Verification>(null),
});
constructor(
@Inject(DIALOG_DATA) protected data: PurgeVaultDialogData,
private dialogRef: DialogRef,
private apiService: ApiService,
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private userVerificationService: UserVerificationService,
private router: Router,
private logService: LogService,
private syncService: SyncService,
) {}
) {
this.organizationId = data && data.organizationId ? data.organizationId : null;
}
async submit() {
try {
this.formPromise = this.userVerificationService
.buildRequest(this.masterPassword)
.then((request) => this.apiService.postPurgeCiphers(request, this.organizationId));
await this.formPromise;
this.platformUtilsService.showToast("success", null, this.i18nService.t("vaultPurged"));
// 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.syncService.fullSync(true);
if (this.organizationId != null) {
// 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);
submit = async () => {
const response = this.userVerificationService
.buildRequest(this.formGroup.value.masterPassword)
.then((request) => this.apiService.postPurgeCiphers(request, this.organizationId));
await response;
this.platformUtilsService.showToast("success", null, this.i18nService.t("vaultPurged"));
await this.syncService.fullSync(true);
if (this.organizationId != null) {
await this.router.navigate(["organizations", this.organizationId, "vault"]);
} else {
await this.router.navigate(["vault"]);
}
this.dialogRef.close();
};
static open(dialogService: DialogService, config?: DialogConfig<PurgeVaultDialogData>) {
return dialogService.open(PurgeVaultComponent, config);
}
}