From 0c84fcbcef23c0c108be5ce8263d78899762399e Mon Sep 17 00:00:00 2001 From: Brandon Maharaj Date: Thu, 9 Mar 2023 23:54:11 -0500 Subject: [PATCH] [SG-1016] Move MP confirmation to modal for encryptions settings changes (#4762) * work: moving the form * fix: lint do be crazy sometimes * fix: remove debug stuff * fix: dialogService * per Danielle Flinn: option 1, leave sizing wide. * work: move modules to own container * work: reorg modules --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> --- .../change-kdf-confirmation.component.html | 50 +++++++++++++ .../change-kdf-confirmation.component.ts} | 74 +++++++------------ .../change-kdf.component.html | 26 ++----- .../change-kdf/change-kdf.component.ts | 62 ++++++++++++++++ .../settings/change-kdf/change-kdf.module.ts | 14 ++++ .../src/app/shared/loose-components.module.ts | 12 ++- apps/web/src/locales/en/messages.json | 2 +- 7 files changed, 170 insertions(+), 70 deletions(-) create mode 100644 apps/web/src/app/settings/change-kdf/change-kdf-confirmation.component.html rename apps/web/src/app/settings/{change-kdf.component.ts => change-kdf/change-kdf-confirmation.component.ts} (62%) rename apps/web/src/app/settings/{ => change-kdf}/change-kdf.component.html (85%) create mode 100644 apps/web/src/app/settings/change-kdf/change-kdf.component.ts create mode 100644 apps/web/src/app/settings/change-kdf/change-kdf.module.ts diff --git a/apps/web/src/app/settings/change-kdf/change-kdf-confirmation.component.html b/apps/web/src/app/settings/change-kdf/change-kdf-confirmation.component.html new file mode 100644 index 00000000000..df5c5c275f6 --- /dev/null +++ b/apps/web/src/app/settings/change-kdf/change-kdf-confirmation.component.html @@ -0,0 +1,50 @@ + + + {{ "changeKdf" | i18n }} + + + + {{ "changeKdfLoggedOutWarning" | i18n }} +
+
+
+ {{ "masterPass" | i18n }} + + + {{ "confirmIdentity" | i18n }} + +
+
+
+
+
+ + +
+
diff --git a/apps/web/src/app/settings/change-kdf.component.ts b/apps/web/src/app/settings/change-kdf/change-kdf-confirmation.component.ts similarity index 62% rename from apps/web/src/app/settings/change-kdf.component.ts rename to apps/web/src/app/settings/change-kdf/change-kdf-confirmation.component.ts index c11d127c0e0..9e56fe6b3dd 100644 --- a/apps/web/src/app/settings/change-kdf.component.ts +++ b/apps/web/src/app/settings/change-kdf/change-kdf-confirmation.component.ts @@ -1,4 +1,6 @@ -import { Component, OnInit } from "@angular/core"; +import { DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, Inject } from "@angular/core"; +import { FormGroup, FormControl, Validators } from "@angular/forms"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { CryptoService } from "@bitwarden/common/abstractions/crypto.service"; @@ -8,28 +10,24 @@ import { MessagingService } from "@bitwarden/common/abstractions/messaging.servi import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; -import { - DEFAULT_KDF_CONFIG, - DEFAULT_PBKDF2_ITERATIONS, - DEFAULT_ARGON2_ITERATIONS, - DEFAULT_ARGON2_MEMORY, - DEFAULT_ARGON2_PARALLELISM, - KdfType, -} from "@bitwarden/common/enums/kdfType"; +import { KdfType } from "@bitwarden/common/enums/kdfType"; import { KdfRequest } from "@bitwarden/common/models/request/kdf.request"; @Component({ - selector: "app-change-kdf", - templateUrl: "change-kdf.component.html", + selector: "app-change-kdf-confirmation", + templateUrl: "change-kdf-confirmation.component.html", }) -export class ChangeKdfComponent implements OnInit { +export class ChangeKdfConfirmationComponent { + kdf: KdfType; + kdfConfig: KdfConfig; + + form = new FormGroup({ + masterPassword: new FormControl(null, Validators.required), + }); + showPassword = false; masterPassword: string; - kdf = KdfType.PBKDF2_SHA256; - kdfConfig: KdfConfig = DEFAULT_KDF_CONFIG; - kdfType = KdfType; - kdfOptions: any[] = []; formPromise: Promise; - recommendedPbkdf2Iterations = DEFAULT_PBKDF2_ITERATIONS; + loading = false; constructor( private apiService: ApiService, @@ -37,21 +35,17 @@ export class ChangeKdfComponent implements OnInit { private platformUtilsService: PlatformUtilsService, private cryptoService: CryptoService, private messagingService: MessagingService, + private stateService: StateService, private logService: LogService, - private stateService: StateService + @Inject(DIALOG_DATA) params: { kdf: KdfType; kdfConfig: KdfConfig } ) { - this.kdfOptions = [ - { name: "PBKDF2 SHA-256", value: KdfType.PBKDF2_SHA256 }, - { name: "Argon2id", value: KdfType.Argon2id }, - ]; - } - - async ngOnInit() { - this.kdf = await this.stateService.getKdfType(); - this.kdfConfig = await this.stateService.getKdfConfig(); + this.kdf = params.kdf; + this.kdfConfig = params.kdfConfig; + this.masterPassword = null; } async submit() { + this.loading = true; const hasEncKey = await this.cryptoService.hasEncKey(); if (!hasEncKey) { this.platformUtilsService.showToast("error", null, this.i18nService.t("updateKey")); @@ -69,41 +63,27 @@ export class ChangeKdfComponent implements OnInit { this.messagingService.send("logout"); } catch (e) { this.logService.error(e); - } - } - - async onChangeKdf(newValue: KdfType) { - if (newValue === KdfType.PBKDF2_SHA256) { - this.kdfConfig = new KdfConfig(DEFAULT_PBKDF2_ITERATIONS); - } else if (newValue === KdfType.Argon2id) { - this.kdfConfig = new KdfConfig( - DEFAULT_ARGON2_ITERATIONS, - DEFAULT_ARGON2_MEMORY, - DEFAULT_ARGON2_PARALLELISM - ); - } else { - throw new Error("Unknown KDF type."); + } finally { + this.loading = false; } } private async makeKeyAndSaveAsync() { + const masterPassword = this.form.value.masterPassword; const request = new KdfRequest(); request.kdf = this.kdf; request.kdfIterations = this.kdfConfig.iterations; request.kdfMemory = this.kdfConfig.memory; request.kdfParallelism = this.kdfConfig.parallelism; - request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null); + request.masterPasswordHash = await this.cryptoService.hashPassword(masterPassword, null); const email = await this.stateService.getEmail(); const newKey = await this.cryptoService.makeKey( - this.masterPassword, + masterPassword, email, this.kdf, this.kdfConfig ); - request.newMasterPasswordHash = await this.cryptoService.hashPassword( - this.masterPassword, - newKey - ); + request.newMasterPasswordHash = await this.cryptoService.hashPassword(masterPassword, newKey); const newEncKey = await this.cryptoService.remakeEncKey(newKey); request.key = newEncKey[1].encryptedString; diff --git a/apps/web/src/app/settings/change-kdf.component.html b/apps/web/src/app/settings/change-kdf/change-kdf.component.html similarity index 85% rename from apps/web/src/app/settings/change-kdf.component.html rename to apps/web/src/app/settings/change-kdf/change-kdf.component.html index e9d13e375f3..0411c373803 100644 --- a/apps/web/src/app/settings/change-kdf.component.html +++ b/apps/web/src/app/settings/change-kdf/change-kdf.component.html @@ -2,23 +2,7 @@

{{ "encKeySettings" | i18n }}

{{ "changeKdfLoggedOutWarning" | i18n }} -
-
-
-
- - -
-
-
+
@@ -122,7 +106,13 @@
- diff --git a/apps/web/src/app/settings/change-kdf/change-kdf.component.ts b/apps/web/src/app/settings/change-kdf/change-kdf.component.ts new file mode 100644 index 00000000000..15fd6fda125 --- /dev/null +++ b/apps/web/src/app/settings/change-kdf/change-kdf.component.ts @@ -0,0 +1,62 @@ +import { Component, OnInit } from "@angular/core"; + +import { StateService } from "@bitwarden/common/abstractions/state.service"; +import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; +import { + DEFAULT_KDF_CONFIG, + DEFAULT_PBKDF2_ITERATIONS, + DEFAULT_ARGON2_ITERATIONS, + DEFAULT_ARGON2_MEMORY, + DEFAULT_ARGON2_PARALLELISM, + KdfType, +} from "@bitwarden/common/enums/kdfType"; +import { DialogService } from "@bitwarden/components"; + +import { ChangeKdfConfirmationComponent } from "./change-kdf-confirmation.component"; + +@Component({ + selector: "app-change-kdf", + templateUrl: "change-kdf.component.html", +}) +export class ChangeKdfComponent implements OnInit { + kdf = KdfType.PBKDF2_SHA256; + kdfConfig: KdfConfig = DEFAULT_KDF_CONFIG; + kdfType = KdfType; + kdfOptions: any[] = []; + recommendedPbkdf2Iterations = DEFAULT_PBKDF2_ITERATIONS; + + constructor(private stateService: StateService, private dialogService: DialogService) { + this.kdfOptions = [ + { name: "PBKDF2 SHA-256", value: KdfType.PBKDF2_SHA256 }, + { name: "Argon2id", value: KdfType.Argon2id }, + ]; + } + + async ngOnInit() { + this.kdf = await this.stateService.getKdfType(); + this.kdfConfig = await this.stateService.getKdfConfig(); + } + + async onChangeKdf(newValue: KdfType) { + if (newValue === KdfType.PBKDF2_SHA256) { + this.kdfConfig = new KdfConfig(DEFAULT_PBKDF2_ITERATIONS); + } else if (newValue === KdfType.Argon2id) { + this.kdfConfig = new KdfConfig( + DEFAULT_ARGON2_ITERATIONS, + DEFAULT_ARGON2_MEMORY, + DEFAULT_ARGON2_PARALLELISM + ); + } else { + throw new Error("Unknown KDF type."); + } + } + + async openConfirmationModal() { + this.dialogService.open(ChangeKdfConfirmationComponent, { + data: { + kdf: this.kdf, + kdfConfig: this.kdfConfig, + }, + }); + } +} diff --git a/apps/web/src/app/settings/change-kdf/change-kdf.module.ts b/apps/web/src/app/settings/change-kdf/change-kdf.module.ts new file mode 100644 index 00000000000..342ad43e368 --- /dev/null +++ b/apps/web/src/app/settings/change-kdf/change-kdf.module.ts @@ -0,0 +1,14 @@ +import { CommonModule } from "@angular/common"; +import { NgModule } from "@angular/core"; + +import { SharedModule } from "../../shared"; + +import { ChangeKdfConfirmationComponent } from "./change-kdf-confirmation.component"; +import { ChangeKdfComponent } from "./change-kdf.component"; + +@NgModule({ + imports: [CommonModule, SharedModule], + declarations: [ChangeKdfComponent, ChangeKdfConfirmationComponent], + exports: [ChangeKdfComponent, ChangeKdfConfirmationComponent], +}) +export class ChangeKdfModule {} diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index cc7ae661045..7b988acc511 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -74,7 +74,7 @@ import { BillingHistoryComponent } from "../settings/billing-history.component"; import { BillingSyncKeyComponent } from "../settings/billing-sync-key.component"; import { ChangeAvatarComponent } from "../settings/change-avatar.component"; import { ChangeEmailComponent } from "../settings/change-email.component"; -import { ChangeKdfComponent } from "../settings/change-kdf.component"; +import { ChangeKdfModule } from "../settings/change-kdf/change-kdf.module"; import { ChangePasswordComponent } from "../settings/change-password.component"; import { CreateOrganizationComponent } from "../settings/create-organization.component"; import { DeleteAccountComponent } from "../settings/delete-account.component"; @@ -117,7 +117,13 @@ import { SharedModule } from "./shared.module"; // Please do not add to this list of declarations - we should refactor these into modules when doing so makes sense until there are none left. // If you are building new functionality, please create or extend a feature module instead. @NgModule({ - imports: [SharedModule, OrganizationCreateModule, RegisterFormModule, ProductSwitcherModule], + imports: [ + SharedModule, + OrganizationCreateModule, + RegisterFormModule, + ProductSwitcherModule, + ChangeKdfModule, + ], declarations: [ PremiumBadgeComponent, AcceptEmergencyComponent, @@ -135,7 +141,6 @@ import { SharedModule } from "./shared.module"; AttachmentsComponent, BillingSyncKeyComponent, ChangeEmailComponent, - ChangeKdfComponent, ChangePasswordComponent, CollectionsComponent, CreateOrganizationComponent, @@ -245,7 +250,6 @@ import { SharedModule } from "./shared.module"; ApiKeyComponent, AttachmentsComponent, ChangeEmailComponent, - ChangeKdfComponent, ChangePasswordComponent, CollectionsComponent, CreateOrganizationComponent, diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 3910581d450..013f6fa6bca 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -6491,7 +6491,7 @@ "message": "Change KDF settings" }, "changeKdfLoggedOutWarning": { - "message": "Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour. We recommend exporting your vault before changing your encryption settings to prevent data loss." + "message": "Proceeding will log you out of all active sessions. You will need to log back in and complete two-step login setup. We recommend exporting your vault before changing your encryption settings to prevent data loss." }, "secretsManagerBeta": { "message": "Secrets Manager Beta"