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:
parent
f2fcf5ce2e
commit
36c6dc27e5
|
@ -15,13 +15,12 @@
|
||||||
<button type="button" bitButton buttonType="danger" [bitAction]="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" [bitAction]="deleteAccount">
|
||||||
{{ "deleteAccount" | i18n }}
|
{{ "deleteAccount" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
</app-danger-zone>
|
</app-danger-zone>
|
||||||
|
|
||||||
<ng-template #deauthorizeSessionsTemplate></ng-template>
|
<ng-template #deauthorizeSessionsTemplate></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>
|
||||||
</bit-container>
|
</bit-container>
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { DialogService } from "@bitwarden/components";
|
||||||
import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component";
|
import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component";
|
||||||
|
|
||||||
import { DeauthorizeSessionsComponent } from "./deauthorize-sessions.component";
|
import { DeauthorizeSessionsComponent } from "./deauthorize-sessions.component";
|
||||||
import { DeleteAccountComponent } from "./delete-account.component";
|
import { DeleteAccountDialogComponent } from "./delete-account-dialog.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-account",
|
selector: "app-account",
|
||||||
|
@ -17,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("deleteAccountTemplate", { read: ViewContainerRef, static: true })
|
|
||||||
deleteModalRef: ViewContainerRef;
|
|
||||||
|
|
||||||
showChangeEmail = true;
|
showChangeEmail = true;
|
||||||
|
|
||||||
|
@ -41,7 +39,8 @@ export class AccountComponent {
|
||||||
await lastValueFrom(dialogRef.closed);
|
await lastValueFrom(dialogRef.closed);
|
||||||
};
|
};
|
||||||
|
|
||||||
async deleteAccount() {
|
deleteAccount = async () => {
|
||||||
await this.modalService.openViewRef(DeleteAccountComponent, this.deleteModalRef);
|
const dialogRef = DeleteAccountDialogComponent.open(this.dialogService);
|
||||||
}
|
await lastValueFrom(dialogRef.closed);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -1,43 +1,50 @@
|
||||||
|
import { DialogRef } from "@angular/cdk/dialog";
|
||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder } from "@angular/forms";
|
||||||
|
|
||||||
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
|
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
|
||||||
import { Verification } from "@bitwarden/common/auth/types/verification";
|
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 { 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 { DialogService } from "@bitwarden/components";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-delete-account",
|
templateUrl: "delete-account-dialog.component.html",
|
||||||
templateUrl: "delete-account.component.html",
|
|
||||||
})
|
})
|
||||||
export class DeleteAccountComponent {
|
export class DeleteAccountDialogComponent {
|
||||||
formPromise: Promise<void>;
|
|
||||||
|
|
||||||
deleteForm = this.formBuilder.group({
|
deleteForm = this.formBuilder.group({
|
||||||
verification: undefined as Verification | undefined,
|
verification: undefined as Verification | undefined,
|
||||||
});
|
});
|
||||||
|
invalidSecret: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private accountApiService: AccountApiService,
|
private accountApiService: AccountApiService,
|
||||||
private logService: LogService,
|
private dialogRef: DialogRef,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async submit() {
|
submit = async () => {
|
||||||
try {
|
try {
|
||||||
const verification = this.deleteForm.get("verification").value;
|
const verification = this.deleteForm.get("verification").value;
|
||||||
this.formPromise = this.accountApiService.deleteAccount(verification);
|
await this.accountApiService.deleteAccount(verification);
|
||||||
await this.formPromise;
|
this.dialogRef.close();
|
||||||
this.platformUtilsService.showToast(
|
this.platformUtilsService.showToast(
|
||||||
"success",
|
"success",
|
||||||
this.i18nService.t("accountDeleted"),
|
this.i18nService.t("accountDeleted"),
|
||||||
this.i18nService.t("accountDeletedDesc"),
|
this.i18nService.t("accountDeletedDesc"),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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">×</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>
|
|
|
@ -33,7 +33,7 @@ import { ChangeAvatarComponent } from "../auth/settings/account/change-avatar.co
|
||||||
import { ChangeEmailComponent } from "../auth/settings/account/change-email.component";
|
import { ChangeEmailComponent } from "../auth/settings/account/change-email.component";
|
||||||
import { DangerZoneComponent } from "../auth/settings/account/danger-zone.component";
|
import { DangerZoneComponent } from "../auth/settings/account/danger-zone.component";
|
||||||
import { DeauthorizeSessionsComponent } from "../auth/settings/account/deauthorize-sessions.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 { ProfileComponent } from "../auth/settings/account/profile.component";
|
||||||
import { EmergencyAccessAttachmentsComponent } from "../auth/settings/emergency-access/attachments/emergency-access-attachments.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";
|
import { EmergencyAccessConfirmComponent } from "../auth/settings/emergency-access/confirm/emergency-access-confirm.component";
|
||||||
|
@ -130,7 +130,7 @@ import { SharedModule } from "./shared.module";
|
||||||
ChangeEmailComponent,
|
ChangeEmailComponent,
|
||||||
CollectionsComponent,
|
CollectionsComponent,
|
||||||
DeauthorizeSessionsComponent,
|
DeauthorizeSessionsComponent,
|
||||||
DeleteAccountComponent,
|
DeleteAccountDialogComponent,
|
||||||
DomainRulesComponent,
|
DomainRulesComponent,
|
||||||
EmergencyAccessAddEditComponent,
|
EmergencyAccessAddEditComponent,
|
||||||
EmergencyAccessAttachmentsComponent,
|
EmergencyAccessAttachmentsComponent,
|
||||||
|
@ -203,7 +203,7 @@ import { SharedModule } from "./shared.module";
|
||||||
ChangeEmailComponent,
|
ChangeEmailComponent,
|
||||||
CollectionsComponent,
|
CollectionsComponent,
|
||||||
DeauthorizeSessionsComponent,
|
DeauthorizeSessionsComponent,
|
||||||
DeleteAccountComponent,
|
DeleteAccountDialogComponent,
|
||||||
DomainRulesComponent,
|
DomainRulesComponent,
|
||||||
DynamicAvatarComponent,
|
DynamicAvatarComponent,
|
||||||
EmergencyAccessAddEditComponent,
|
EmergencyAccessAddEditComponent,
|
||||||
|
|
Loading…
Reference in New Issue