1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-07 11:03:30 +00:00

refactor(set-change-password): [Auth/PM-18458] Create new ChangePasswordComponent (#14226)

This PR creates a new ChangePasswordComponent. The first use-case of the ChangePasswordComponent is to place it inside a new PasswordSettingsComponent, which is accessed by going to Account Settings > Security.

The ChangePasswordComponent will be updated in future PRs to handle more change password scenarios.

Feature Flags: PM16117_ChangeExistingPasswordRefactor
This commit is contained in:
rr-bw
2025-05-16 10:41:46 -07:00
committed by GitHub
parent d16a5cb73e
commit afbddeaf86
37 changed files with 1349 additions and 310 deletions

View File

@@ -111,12 +111,12 @@ describe("DefaultSetPasswordJitService", () => {
userId = "userId" as UserId;
passwordInputResult = {
masterKey: masterKey,
serverMasterKeyHash: "serverMasterKeyHash",
localMasterKeyHash: "localMasterKeyHash",
hint: "hint",
newMasterKey: masterKey,
newServerMasterKeyHash: "newServerMasterKeyHash",
newLocalMasterKeyHash: "newLocalMasterKeyHash",
newPasswordHint: "newPasswordHint",
kdfConfig: DEFAULT_KDF_CONFIG,
newPassword: "password",
newPassword: "newPassword",
};
credentials = {
@@ -131,9 +131,9 @@ describe("DefaultSetPasswordJitService", () => {
userDecryptionOptionsService.userDecryptionOptions$ = userDecryptionOptionsSubject;
setPasswordRequest = new SetPasswordRequest(
passwordInputResult.serverMasterKeyHash,
passwordInputResult.newServerMasterKeyHash,
protectedUserKey[1].encryptedString,
passwordInputResult.hint,
passwordInputResult.newPasswordHint,
orgSsoIdentifier,
keysRequest,
passwordInputResult.kdfConfig.kdfType,

View File

@@ -20,7 +20,7 @@ import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { UserId } from "@bitwarden/common/types/guid";
import { MasterKey, UserKey } from "@bitwarden/common/types/key";
import { PBKDF2KdfConfig, KdfConfigService, KeyService } from "@bitwarden/key-management";
import { KdfConfigService, KeyService, KdfConfig } from "@bitwarden/key-management";
import {
SetPasswordCredentials,
@@ -43,10 +43,10 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
async setPassword(credentials: SetPasswordCredentials): Promise<void> {
const {
masterKey,
serverMasterKeyHash,
localMasterKeyHash,
hint,
newMasterKey,
newServerMasterKeyHash,
newLocalMasterKeyHash,
newPasswordHint,
kdfConfig,
orgSsoIdentifier,
orgId,
@@ -60,7 +60,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
}
}
const protectedUserKey = await this.makeProtectedUserKey(masterKey, userId);
const protectedUserKey = await this.makeProtectedUserKey(newMasterKey, userId);
if (protectedUserKey == null) {
throw new Error("protectedUserKey not found. Could not set password.");
}
@@ -70,12 +70,12 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
const [keyPair, keysRequest] = await this.makeKeyPairAndRequest(protectedUserKey);
const request = new SetPasswordRequest(
serverMasterKeyHash,
newServerMasterKeyHash,
protectedUserKey[1].encryptedString,
hint,
newPasswordHint,
orgSsoIdentifier,
keysRequest,
kdfConfig.kdfType, // kdfConfig is always DEFAULT_KDF_CONFIG (see InputPasswordComponent)
kdfConfig.kdfType,
kdfConfig.iterations,
);
@@ -85,14 +85,14 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
await this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.None, userId);
// User now has a password so update account decryption options in state
await this.updateAccountDecryptionProperties(masterKey, kdfConfig, protectedUserKey, userId);
await this.updateAccountDecryptionProperties(newMasterKey, kdfConfig, protectedUserKey, userId);
await this.keyService.setPrivateKey(keyPair[1].encryptedString, userId);
await this.masterPasswordService.setMasterKeyHash(localMasterKeyHash, userId);
await this.masterPasswordService.setMasterKeyHash(newLocalMasterKeyHash, userId);
if (resetPasswordAutoEnroll) {
await this.handleResetPasswordAutoEnroll(serverMasterKeyHash, orgId, userId);
await this.handleResetPasswordAutoEnroll(newServerMasterKeyHash, orgId, userId);
}
}
@@ -127,7 +127,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
private async updateAccountDecryptionProperties(
masterKey: MasterKey,
kdfConfig: PBKDF2KdfConfig,
kdfConfig: KdfConfig,
protectedUserKey: [UserKey, EncString],
userId: UserId,
) {

View File

@@ -13,11 +13,12 @@
</app-callout>
<auth-input-password
[inputPasswordFlow]="InputPasswordFlow.SetInitialPassword"
[primaryButtonText]="{ key: 'createAccount' }"
[flow]="inputPasswordFlow"
[email]="email"
[userId]="userId"
[loading]="submitting"
[masterPasswordPolicyOptions]="masterPasswordPolicyOptions"
[primaryButtonText]="{ key: 'createAccount' }"
(onPasswordFormSubmit)="handlePasswordFormSubmit($event)"
></auth-input-password>
</ng-container>

View File

@@ -3,7 +3,7 @@
import { CommonModule } from "@angular/common";
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { firstValueFrom, map } from "rxjs";
import { firstValueFrom } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
@@ -36,7 +36,7 @@ import {
imports: [CommonModule, InputPasswordComponent, JslibModule],
})
export class SetPasswordJitComponent implements OnInit {
protected InputPasswordFlow = InputPasswordFlow;
protected inputPasswordFlow = InputPasswordFlow.SetInitialPasswordAuthedUser;
protected email: string;
protected masterPasswordPolicyOptions: MasterPasswordPolicyOptions;
protected orgId: string;
@@ -60,9 +60,9 @@ export class SetPasswordJitComponent implements OnInit {
) {}
async ngOnInit() {
this.email = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.email)),
);
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
this.userId = activeAccount?.id;
this.email = activeAccount?.email;
await this.syncService.fullSync(true);
this.syncLoading = false;
@@ -97,14 +97,12 @@ export class SetPasswordJitComponent implements OnInit {
protected async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
this.submitting = true;
const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id;
const credentials: SetPasswordCredentials = {
...passwordInputResult,
orgSsoIdentifier: this.orgSsoIdentifier,
orgId: this.orgId,
resetPasswordAutoEnroll: this.resetPasswordAutoEnroll,
userId,
userId: this.userId,
};
try {

View File

@@ -2,14 +2,14 @@
// @ts-strict-ignore
import { UserId } from "@bitwarden/common/types/guid";
import { MasterKey } from "@bitwarden/common/types/key";
import { PBKDF2KdfConfig } from "@bitwarden/key-management";
import { KdfConfig } from "@bitwarden/key-management";
export interface SetPasswordCredentials {
masterKey: MasterKey;
serverMasterKeyHash: string;
localMasterKeyHash: string;
kdfConfig: PBKDF2KdfConfig;
hint: string;
newMasterKey: MasterKey;
newServerMasterKeyHash: string;
newLocalMasterKeyHash: string;
newPasswordHint: string;
kdfConfig: KdfConfig;
orgSsoIdentifier: string;
orgId: string;
resetPasswordAutoEnroll: boolean;