[PM-6790][Tech Debt] Cleanup export web component (#8323)
* Remove formPromise and use bitSubmit * Use formGroup.invalid instead of !valid * Move variables related to encrypted exports into base component. * Migrate to use new userVerificationDialogComponent --------- Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
This commit is contained in:
parent
ea0035f658
commit
dcea468281
|
@ -1,13 +1,7 @@
|
|||
<app-header></app-header>
|
||||
|
||||
<bit-container>
|
||||
<form
|
||||
#form
|
||||
(ngSubmit)="submit()"
|
||||
[appApiAction]="formPromise"
|
||||
[formGroup]="exportForm"
|
||||
*ngIf="exportForm"
|
||||
>
|
||||
<form [formGroup]="exportForm" [bitSubmit]="submit">
|
||||
<bit-callout type="danger" title="{{ 'vaultExportDisabled' | i18n }}" *ngIf="disabledByPolicy">
|
||||
{{ "personalVaultExportPolicyInEffect" | i18n }}
|
||||
</bit-callout>
|
||||
|
@ -110,9 +104,9 @@
|
|||
|
||||
<button
|
||||
bitButton
|
||||
bitFormButton
|
||||
type="submit"
|
||||
buttonType="primary"
|
||||
[loading]="form.loading"
|
||||
[disabled]="disabledByPolicy"
|
||||
>
|
||||
{{ "confirmFormat" | i18n }}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component } from "@angular/core";
|
||||
import { UntypedFormBuilder } from "@angular/forms";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component";
|
||||
import { UserVerificationDialogComponent } from "@bitwarden/auth/angular";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
|
@ -11,20 +11,14 @@ import { FileDownloadService } from "@bitwarden/common/platform/abstractions/fil
|
|||
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 { EncryptedExportType } from "@bitwarden/common/tools/enums/encrypted-export-type.enum";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core";
|
||||
|
||||
import { openUserVerificationPrompt } from "../../auth/shared/components/user-verification";
|
||||
|
||||
@Component({
|
||||
selector: "app-export",
|
||||
templateUrl: "export.component.html",
|
||||
})
|
||||
export class ExportComponent extends BaseExportComponent {
|
||||
encryptedExportType = EncryptedExportType;
|
||||
protected showFilePassword: boolean;
|
||||
|
||||
constructor(
|
||||
i18nService: I18nService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
|
@ -53,7 +47,7 @@ export class ExportComponent extends BaseExportComponent {
|
|||
);
|
||||
}
|
||||
|
||||
async submit() {
|
||||
submit = async () => {
|
||||
if (this.isFileEncryptedExport && this.filePassword != this.confirmFilePassword) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
|
@ -64,7 +58,7 @@ export class ExportComponent extends BaseExportComponent {
|
|||
}
|
||||
|
||||
this.exportForm.markAllAsTouched();
|
||||
if (!this.exportForm.valid) {
|
||||
if (this.exportForm.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -85,14 +79,14 @@ export class ExportComponent extends BaseExportComponent {
|
|||
// 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.doExport();
|
||||
}
|
||||
};
|
||||
|
||||
protected saved() {
|
||||
super.saved();
|
||||
this.platformUtilsService.showToast("success", null, this.i18nService.t("exportSuccess"));
|
||||
}
|
||||
|
||||
private verifyUser() {
|
||||
private async verifyUser(): Promise<boolean> {
|
||||
let confirmDescription = "exportWarningDesc";
|
||||
if (this.isFileEncryptedExport) {
|
||||
confirmDescription = "fileEncryptedExportWarningDesc";
|
||||
|
@ -100,32 +94,30 @@ export class ExportComponent extends BaseExportComponent {
|
|||
confirmDescription = "encExportKeyWarningDesc";
|
||||
}
|
||||
|
||||
const ref = openUserVerificationPrompt(this.dialogService, {
|
||||
data: {
|
||||
confirmDescription: confirmDescription,
|
||||
confirmButtonText: "exportVault",
|
||||
modalTitle: "confirmVaultExport",
|
||||
const result = await UserVerificationDialogComponent.open(this.dialogService, {
|
||||
clientSideOnlyVerification: true,
|
||||
title: "confirmVaultExport",
|
||||
bodyText: confirmDescription,
|
||||
confirmButtonOptions: {
|
||||
text: "exportVault",
|
||||
type: "primary",
|
||||
},
|
||||
});
|
||||
|
||||
if (ref == null) {
|
||||
return;
|
||||
// Handle the result of the dialog based on user action and verification success
|
||||
if (result.userAction === "cancel") {
|
||||
// User cancelled the dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
return firstValueFrom(ref.closed);
|
||||
}
|
||||
|
||||
get isFileEncryptedExport() {
|
||||
return (
|
||||
this.format === "encrypted_json" &&
|
||||
this.fileEncryptionType === EncryptedExportType.FileEncrypted
|
||||
);
|
||||
}
|
||||
|
||||
get isAccountEncryptedExport() {
|
||||
return (
|
||||
this.format === "encrypted_json" &&
|
||||
this.fileEncryptionType === EncryptedExportType.AccountEncrypted
|
||||
);
|
||||
// User confirmed the dialog so check verification success
|
||||
if (!result.verificationSuccess) {
|
||||
if (result.noAvailableClientVerificationMethods) {
|
||||
// No client-side verification methods are available
|
||||
// Could send user to configure a verification method like PIN or biometrics
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,10 @@ export class ExportComponent implements OnInit, OnDestroy {
|
|||
@Output() onSaved = new EventEmitter();
|
||||
@ViewChild(PasswordStrengthComponent) passwordStrengthComponent: PasswordStrengthComponent;
|
||||
|
||||
encryptedExportType = EncryptedExportType;
|
||||
protected showFilePassword: boolean;
|
||||
|
||||
filePasswordValue: string = null;
|
||||
formPromise: Promise<string>;
|
||||
private _disabledByPolicy = false;
|
||||
|
||||
protected organizationId: string = null;
|
||||
|
@ -126,10 +128,23 @@ export class ExportComponent implements OnInit, OnDestroy {
|
|||
return this.format === "encrypted_json";
|
||||
}
|
||||
|
||||
get isFileEncryptedExport() {
|
||||
return (
|
||||
this.format === "encrypted_json" &&
|
||||
this.fileEncryptionType === EncryptedExportType.FileEncrypted
|
||||
);
|
||||
}
|
||||
|
||||
get isAccountEncryptedExport() {
|
||||
return (
|
||||
this.format === "encrypted_json" &&
|
||||
this.fileEncryptionType === EncryptedExportType.AccountEncrypted
|
||||
);
|
||||
}
|
||||
|
||||
protected async doExport() {
|
||||
try {
|
||||
this.formPromise = this.getExportData();
|
||||
const data = await this.formPromise;
|
||||
const data = await this.getExportData();
|
||||
this.downloadFile(data);
|
||||
this.saved();
|
||||
await this.collectEvent();
|
||||
|
|
Loading…
Reference in New Issue