1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-05 11:13:44 +00:00

refactor(input-password-flows): [Auth/PM-27086] JIT MP org user flow - remove masterKey generation from InputPasswordComponent (#18006)

- Updates `InputPasswordComponent` to emit raw data instead of generating cryptographic properties (`newMasterKey`, `newServerMasterKeyHash`, `newLocalMasterKeyHash`).
  - This helps us in moving away from using the deprecated `makeMasterKey()` method in the component (which takes email as salt) as we seek to eventually separate the email from the salt.
- Updates the `JIT_PROVISIONED_MP_ORG_USER` case of the switch to handle the flow when the `PM27086_UpdateAuthenticationApisForInputPassword` flag is on.

Feature Flag: `PM27086_UpdateAuthenticationApisForInputPassword`
This commit is contained in:
rr-bw
2026-01-30 15:11:59 -08:00
committed by GitHub
parent 4a45414f4a
commit 1f0e0ca098
13 changed files with 189 additions and 59 deletions

View File

@@ -63,6 +63,10 @@ export class DefaultSetInitialPasswordService implements SetInitialPasswordServi
protected registerSdkService: RegisterSdkService,
) {}
/**
* @deprecated To be removed in PM-28143. When you remove this, also check for any objects/methods
* in this default service that are now un-used and can also be removed.
*/
async setInitialPassword(
credentials: SetInitialPasswordCredentials,
userType: SetInitialPasswordUserType,
@@ -333,6 +337,9 @@ export class DefaultSetInitialPasswordService implements SetInitialPasswordServi
);
}
/**
* @deprecated To be removed in PM-28143
*/
private async makeMasterKeyEncryptedUserKey(
masterKey: MasterKey,
userId: UserId,
@@ -410,6 +417,8 @@ export class DefaultSetInitialPasswordService implements SetInitialPasswordServi
}
/**
* @deprecated To be removed in PM-28143
*
* As part of [PM-28494], adding this setting path to accommodate the changes that are
* emerging with pm-23246-unlock-with-master-password-unlock-data.
* Without this, immediately locking/unlocking the vault with the new password _may_ still fail

View File

@@ -124,6 +124,10 @@ describe("DefaultSetInitialPasswordService", () => {
expect(sut).not.toBeFalsy();
});
/**
* @deprecated To be removed in PM-28143. When you remove this, check also if there are any imports/properties
* in the test setup above that are now un-used and can also be removed.
*/
describe("setInitialPassword(...)", () => {
// Mock function parameters
let credentials: SetInitialPasswordCredentials;

View File

@@ -29,6 +29,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
import { HashPurpose } from "@bitwarden/common/platform/enums";
import { SyncService } from "@bitwarden/common/platform/sync";
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
import {
@@ -38,6 +39,7 @@ import {
DialogService,
ToastService,
} from "@bitwarden/components";
import { KeyService } from "@bitwarden/key-management";
import { I18nPipe } from "@bitwarden/ui-common";
import {
@@ -76,6 +78,7 @@ export class SetInitialPasswordComponent implements OnInit {
private anonLayoutWrapperDataService: AnonLayoutWrapperDataService,
private dialogService: DialogService,
private i18nService: I18nService,
private keyService: KeyService,
private logoutService: LogoutService,
private logService: LogService,
private masterPasswordService: InternalMasterPasswordServiceAbstraction,
@@ -110,16 +113,72 @@ export class SetInitialPasswordComponent implements OnInit {
switch (this.userType) {
case SetInitialPasswordUserType.JIT_PROVISIONED_MP_ORG_USER: {
/**
* "KM flag" = EnableAccountEncryptionV2JitPasswordRegistration
* "Auth flag" = PM27086_UpdateAuthenticationApisForInputPassword (checked in InputPasswordComponent and
* passed through via PasswordInputResult)
*
* Flag unwinding for this specific `case` will depend on which flag gets unwound first:
* - If KM flag gets unwound first, remove all code (in this `case`) after the call
* to setInitialPasswordJitMPUserV2Encryption(), as the V2Encryption method is the
* end-goal for this `case`.
* - If Auth flag gets unwound first (in PM-28143), keep the KM code & early return,
* but unwind the auth flagging logic and then remove the method call marked with
* the "Default Scenario" comment.
*/
const accountEncryptionV2 = await this.configService.getFeatureFlag(
FeatureFlag.EnableAccountEncryptionV2JitPasswordRegistration,
);
// Scenario 1: KM flag ON
if (accountEncryptionV2) {
await this.setInitialPasswordJitMPUserV2Encryption(passwordInputResult);
return;
}
await this.setInitialPassword(passwordInputResult);
// Scenario 2: KM flag OFF, Auth flag ON
if (passwordInputResult.newApisWithInputPasswordFlagEnabled) {
/**
* If the Auth flag is enabled, it means the InputPasswordComponent will not emit a newMasterKey,
* newServerMasterKeyHash, and newLocalMasterKeyHash. So we must create them here and add them late
* to the PasswordInputResult before calling setInitialPassword().
*
* This is a temporary state. The end-goal will be to use KM's V2Encryption method above.
*/
const ctx = "Could not set initial password.";
assertTruthy(passwordInputResult.newPassword, "newPassword", ctx);
assertNonNullish(passwordInputResult.kdfConfig, "kdfConfig", ctx);
assertTruthy(this.email, "email", ctx);
const newMasterKey = await this.keyService.makeMasterKey(
passwordInputResult.newPassword,
this.email.trim().toLowerCase(),
passwordInputResult.kdfConfig,
);
const newServerMasterKeyHash = await this.keyService.hashMasterKey(
passwordInputResult.newPassword,
newMasterKey,
HashPurpose.ServerAuthorization,
);
const newLocalMasterKeyHash = await this.keyService.hashMasterKey(
passwordInputResult.newPassword,
newMasterKey,
HashPurpose.LocalAuthorization,
);
passwordInputResult.newMasterKey = newMasterKey;
passwordInputResult.newServerMasterKeyHash = newServerMasterKeyHash;
passwordInputResult.newLocalMasterKeyHash = newLocalMasterKeyHash;
await this.setInitialPassword(passwordInputResult); // passwordInputResult masterKey properties generated on the SetInitialPasswordComponent (just above)
return;
}
// Default Scenario: both flags OFF
await this.setInitialPassword(passwordInputResult); // passwordInputResult masterKey properties generated on the InputPasswordComponent (default)
break;
}
@@ -274,6 +333,9 @@ export class SetInitialPasswordComponent implements OnInit {
}
}
/**
* @deprecated To be removed in PM-28143
*/
private async setInitialPassword(passwordInputResult: PasswordInputResult) {
const ctx = "Could not set initial password.";
assertTruthy(passwordInputResult.newMasterKey, "newMasterKey", ctx);

View File

@@ -87,6 +87,8 @@ export interface InitializeJitPasswordCredentials {
*/
export abstract class SetInitialPasswordService {
/**
* @deprecated To be removed in PM-28143
*
* Sets an initial password for an existing authed user who is either:
* - {@link SetInitialPasswordUserType.JIT_PROVISIONED_MP_ORG_USER}
* - {@link SetInitialPasswordUserType.TDE_ORG_USER_RESET_PASSWORD_PERMISSION_REQUIRES_MP}