PM-2165 Migrate delete account dialog (#8503)

* PM-2165 Migrate delete account dialog

* PM-2165 Addressed Review comments

* PM-2165 Removed legacy user verfication component and used new one

* PM-2165 Added invalidSecret to form input
This commit is contained in:
KiruthigaManivannan 2024-05-24 12:25:43 +05:30 committed by GitHub
parent f2fcf5ce2e
commit 36c6dc27e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 48 additions and 61 deletions

View File

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

View File

@ -8,7 +8,7 @@ import { DialogService } from "@bitwarden/components";
import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component";
import { DeauthorizeSessionsComponent } from "./deauthorize-sessions.component";
import { DeleteAccountComponent } from "./delete-account.component";
import { DeleteAccountDialogComponent } from "./delete-account-dialog.component";
@Component({
selector: "app-account",
@ -17,8 +17,6 @@ import { DeleteAccountComponent } from "./delete-account.component";
export class AccountComponent {
@ViewChild("deauthorizeSessionsTemplate", { read: ViewContainerRef, static: true })
deauthModalRef: ViewContainerRef;
@ViewChild("deleteAccountTemplate", { read: ViewContainerRef, static: true })
deleteModalRef: ViewContainerRef;
showChangeEmail = true;
@ -41,7 +39,8 @@ export class AccountComponent {
await lastValueFrom(dialogRef.closed);
};
async deleteAccount() {
await this.modalService.openViewRef(DeleteAccountComponent, this.deleteModalRef);
}
deleteAccount = async () => {
const dialogRef = DeleteAccountDialogComponent.open(this.dialogService);
await lastValueFrom(dialogRef.closed);
};
}

View File

@ -0,0 +1,21 @@
<form [formGroup]="deleteForm" [bitSubmit]="submit">
<bit-dialog dialogSize="default" [title]="'deleteAccount' | i18n">
<ng-container bitDialogContent>
<p bitTypography="body1">{{ "deleteAccountDesc" | i18n }}</p>
<app-callout type="warning">{{ "deleteAccountWarning" | i18n }}</app-callout>
<app-user-verification-form-input
formControlName="verification"
name="verification"
[(invalidSecret)]="invalidSecret"
></app-user-verification-form-input>
</ng-container>
<ng-container bitDialogFooter>
<button bitButton bitFormButton type="submit" buttonType="danger">
{{ "deleteAccount" | i18n }}
</button>
<button bitButton bitFormButton type="button" buttonType="secondary" bitDialogClose>
{{ "close" | i18n }}
</button>
</ng-container>
</bit-dialog>
</form>

View File

@ -1,43 +1,50 @@
import { DialogRef } from "@angular/cdk/dialog";
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
import { Verification } from "@bitwarden/common/auth/types/verification";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
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 { DialogService } from "@bitwarden/components";
@Component({
selector: "app-delete-account",
templateUrl: "delete-account.component.html",
templateUrl: "delete-account-dialog.component.html",
})
export class DeleteAccountComponent {
formPromise: Promise<void>;
export class DeleteAccountDialogComponent {
deleteForm = this.formBuilder.group({
verification: undefined as Verification | undefined,
});
invalidSecret: boolean = false;
constructor(
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private formBuilder: FormBuilder,
private accountApiService: AccountApiService,
private logService: LogService,
private dialogRef: DialogRef,
) {}
async submit() {
submit = async () => {
try {
const verification = this.deleteForm.get("verification").value;
this.formPromise = this.accountApiService.deleteAccount(verification);
await this.formPromise;
await this.accountApiService.deleteAccount(verification);
this.dialogRef.close();
this.platformUtilsService.showToast(
"success",
this.i18nService.t("accountDeleted"),
this.i18nService.t("accountDeletedDesc"),
);
} catch (e) {
this.logService.error(e);
if (e instanceof ErrorResponse && e.statusCode === 400) {
this.invalidSecret = true;
}
throw e;
}
};
static open(dialogService: DialogService) {
return dialogService.open(DeleteAccountDialogComponent);
}
}

View File

@ -1,39 +0,0 @@
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="deleteAccountTitle">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<form
class="modal-content"
#form
(ngSubmit)="submit()"
[appApiAction]="formPromise"
ngNativeValidate
[formGroup]="deleteForm"
>
<div class="modal-header">
<h1 class="modal-title" id="deleteAccountTitle">{{ "deleteAccount" | 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>{{ "deleteAccountDesc" | i18n }}</p>
<app-callout type="warning">{{ "deleteAccountWarning" | i18n }}</app-callout>
<app-user-verification ngDefaultControl formControlName="verification" name="verification">
</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>{{ "deleteAccount" | i18n }}</span>
</button>
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
{{ "close" | i18n }}
</button>
</div>
</form>
</div>
</div>

View File

@ -33,7 +33,7 @@ import { ChangeAvatarComponent } from "../auth/settings/account/change-avatar.co
import { ChangeEmailComponent } from "../auth/settings/account/change-email.component";
import { DangerZoneComponent } from "../auth/settings/account/danger-zone.component";
import { DeauthorizeSessionsComponent } from "../auth/settings/account/deauthorize-sessions.component";
import { DeleteAccountComponent } from "../auth/settings/account/delete-account.component";
import { DeleteAccountDialogComponent } from "../auth/settings/account/delete-account-dialog.component";
import { ProfileComponent } from "../auth/settings/account/profile.component";
import { EmergencyAccessAttachmentsComponent } from "../auth/settings/emergency-access/attachments/emergency-access-attachments.component";
import { EmergencyAccessConfirmComponent } from "../auth/settings/emergency-access/confirm/emergency-access-confirm.component";
@ -130,7 +130,7 @@ import { SharedModule } from "./shared.module";
ChangeEmailComponent,
CollectionsComponent,
DeauthorizeSessionsComponent,
DeleteAccountComponent,
DeleteAccountDialogComponent,
DomainRulesComponent,
EmergencyAccessAddEditComponent,
EmergencyAccessAttachmentsComponent,
@ -203,7 +203,7 @@ import { SharedModule } from "./shared.module";
ChangeEmailComponent,
CollectionsComponent,
DeauthorizeSessionsComponent,
DeleteAccountComponent,
DeleteAccountDialogComponent,
DomainRulesComponent,
DynamicAvatarComponent,
EmergencyAccessAddEditComponent,