mirror of
https://github.com/bitwarden/browser
synced 2026-01-31 08:43:54 +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:
@@ -87,6 +87,10 @@ describe("DesktopSetInitialPasswordService", () => {
|
||||
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;
|
||||
@@ -116,6 +120,8 @@ describe("DesktopSetInitialPasswordService", () => {
|
||||
orgSsoIdentifier: "orgSsoIdentifier",
|
||||
orgId: "orgId",
|
||||
resetPasswordAutoEnroll: false,
|
||||
newPassword: "Test@Password123!",
|
||||
salt: "user@example.com" as MasterPasswordSalt,
|
||||
};
|
||||
userId = "userId" as UserId;
|
||||
userType = SetInitialPasswordUserType.JIT_PROVISIONED_MP_ORG_USER;
|
||||
|
||||
@@ -54,6 +54,9 @@ export class DesktopSetInitialPasswordService
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated To be removed in PM-28143
|
||||
*/
|
||||
override async setInitialPassword(
|
||||
credentials: SetInitialPasswordCredentials,
|
||||
userType: SetInitialPasswordUserType,
|
||||
|
||||
@@ -90,6 +90,10 @@ describe("WebSetInitialPasswordService", () => {
|
||||
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;
|
||||
@@ -119,6 +123,8 @@ describe("WebSetInitialPasswordService", () => {
|
||||
orgSsoIdentifier: "orgSsoIdentifier",
|
||||
orgId: "orgId",
|
||||
resetPasswordAutoEnroll: false,
|
||||
newPassword: "Test@Password123!",
|
||||
salt: "user@example.com" as MasterPasswordSalt,
|
||||
};
|
||||
userId = "userId" as UserId;
|
||||
userType = SetInitialPasswordUserType.JIT_PROVISIONED_MP_ORG_USER;
|
||||
|
||||
@@ -56,6 +56,9 @@ export class WebSetInitialPasswordService
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated To be removed in PM-28143
|
||||
*/
|
||||
override async setInitialPassword(
|
||||
credentials: SetInitialPasswordCredentials,
|
||||
userType: SetInitialPasswordUserType,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -10,7 +10,9 @@ import {
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { MasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||
@@ -209,6 +211,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
constructor(
|
||||
private auditService: AuditService,
|
||||
private cipherService: CipherService,
|
||||
private configService: ConfigService,
|
||||
private dialogService: DialogService,
|
||||
private formBuilder: FormBuilder,
|
||||
private i18nService: I18nService,
|
||||
@@ -312,7 +315,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
}
|
||||
|
||||
if (!this.email) {
|
||||
throw new Error("Email is required to create master key.");
|
||||
throw new Error("Email not found.");
|
||||
}
|
||||
|
||||
// 1. Determine kdfConfig
|
||||
@@ -320,13 +323,13 @@ export class InputPasswordComponent implements OnInit {
|
||||
this.kdfConfig = DEFAULT_KDF_CONFIG;
|
||||
} else {
|
||||
if (!this.userId) {
|
||||
throw new Error("userId not passed down");
|
||||
throw new Error("userId not found.");
|
||||
}
|
||||
this.kdfConfig = await firstValueFrom(this.kdfConfigService.getKdfConfig$(this.userId));
|
||||
}
|
||||
|
||||
if (this.kdfConfig == null) {
|
||||
throw new Error("KdfConfig is required to create master key.");
|
||||
throw new Error("KdfConfig not found.");
|
||||
}
|
||||
|
||||
const salt =
|
||||
@@ -334,7 +337,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
? await firstValueFrom(this.masterPasswordService.saltForUser$(this.userId))
|
||||
: this.masterPasswordService.emailToSalt(this.email);
|
||||
if (salt == null) {
|
||||
throw new Error("Salt is required to create master key.");
|
||||
throw new Error("Salt not found.");
|
||||
}
|
||||
|
||||
// 2. Verify current password is correct (if necessary)
|
||||
@@ -361,6 +364,41 @@ export class InputPasswordComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
|
||||
// When you unwind the flag in PM-28143, also remove the ConfigService if it is un-used.
|
||||
const newApisWithInputPasswordFlagEnabled = await this.configService.getFeatureFlag(
|
||||
FeatureFlag.PM27086_UpdateAuthenticationApisForInputPassword,
|
||||
);
|
||||
|
||||
if (newApisWithInputPasswordFlagEnabled) {
|
||||
// 4. Build a PasswordInputResult object
|
||||
const passwordInputResult: PasswordInputResult = {
|
||||
newPassword,
|
||||
kdfConfig: this.kdfConfig,
|
||||
salt,
|
||||
newPasswordHint,
|
||||
newApisWithInputPasswordFlagEnabled, // To be removed in PM-28143
|
||||
};
|
||||
|
||||
if (
|
||||
this.flow === InputPasswordFlow.ChangePassword ||
|
||||
this.flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation
|
||||
) {
|
||||
passwordInputResult.currentPassword = currentPassword;
|
||||
}
|
||||
|
||||
if (this.flow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation) {
|
||||
passwordInputResult.rotateUserKey = this.formGroup.controls.rotateUserKey?.value;
|
||||
}
|
||||
|
||||
// 5. Emit and return PasswordInputResult object
|
||||
this.onPasswordFormSubmit.emit(passwordInputResult);
|
||||
return passwordInputResult;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* The following code (within this `try`) to be removed in PM-28143
|
||||
*******************************************************************/
|
||||
|
||||
// 4. Create cryptographic keys and build a PasswordInputResult object
|
||||
const newMasterKey = await this.keyService.makeMasterKey(
|
||||
newPassword,
|
||||
|
||||
@@ -6,14 +6,12 @@ import * as stories from "./input-password.stories.ts";
|
||||
|
||||
# InputPassword Component
|
||||
|
||||
The `InputPasswordComponent` allows a user to enter master password related credentials.
|
||||
Specifically, it does the following:
|
||||
The `InputPasswordComponent` allows a user to enter a new master password for the purpose of setting
|
||||
an initial password or changing an existing password. Specifically, it does the following:
|
||||
|
||||
1. Displays form fields in the UI
|
||||
2. Validates form fields
|
||||
3. Generates cryptographic properties based on the form inputs (e.g. `newMasterKey`,
|
||||
`newServerMasterKeyHash`, etc.)
|
||||
4. Emits the generated properties to the parent component
|
||||
3. Emits values to the parent component
|
||||
|
||||
The `InputPasswordComponent` is central to our set/change password flows, allowing us to keep our
|
||||
form UI and validation logic consistent. As such, it is intended for re-use in different set/change
|
||||
@@ -30,7 +28,6 @@ those values as needed.
|
||||
- [The InputPasswordFlow](#the-inputpasswordflow)
|
||||
- [Use Cases](#use-cases)
|
||||
- [HTML - Form Fields](#html---form-fields)
|
||||
- [TypeScript - Credential Generation](#typescript---credential-generation)
|
||||
- [Difference between SetInitialPasswordAccountRegistration and SetInitialPasswordAuthedUser](#difference-between-setinitialpasswordaccountregistration-and-setinitialpasswordautheduser)
|
||||
- [Validation](#validation)
|
||||
- [Submit Logic](#submit-logic)
|
||||
@@ -44,20 +41,20 @@ those values as needed.
|
||||
**Required**
|
||||
|
||||
- `flow` - the parent component must provide an `InputPasswordFlow`, which is used to determine
|
||||
which form input elements will be displayed in the UI and which cryptographic keys will be created
|
||||
and emitted. [Click here](#the-inputpasswordflow) to learn more about the different
|
||||
`InputPasswordFlow` options.
|
||||
which form input elements will be displayed in the UI and which values will be emitted.
|
||||
[Click here](#the-inputpasswordflow) to learn more about the different `InputPasswordFlow`
|
||||
options.
|
||||
|
||||
**Optional (sometimes)**
|
||||
|
||||
These two `@Inputs` are optional on some flows, but required on others. Therefore these `@Inputs`
|
||||
are not marked as `{ required: true }`, but there _is_ component logic that ensures (requires) that
|
||||
the `email` and/or `userId` is present in certain flows, while not present in other flows.
|
||||
These `@Inputs` are optional on some flows, but required on others. Therefore these `@Inputs` are
|
||||
not marked as `{ required: true }`, but there _is_ component logic that ensures (requires) that the
|
||||
`email` and/or `userId` is present in certain flows, while not present in other flows.
|
||||
|
||||
- `email` - allows the `InputPasswordComponent` to generate a master key
|
||||
- `email` - allows the `InputPasswordComponent` to use the email as a salt (if needed)
|
||||
- `userId` - allows the `InputPasswordComponent` to do things like get the user's `kdfConfig`,
|
||||
verify that a current password is correct, and perform validation prior to user key rotation on
|
||||
the parent
|
||||
verify that a current password is correct, and perform validation prior to user key rotation (if
|
||||
selected) on the parent
|
||||
|
||||
**Optional**
|
||||
|
||||
@@ -87,8 +84,7 @@ These `@Inputs` are truly optional.
|
||||
## The `InputPasswordFlow`
|
||||
|
||||
The `InputPasswordFlow` is a crucial and required `@Input` that influences both the HTML and the
|
||||
credential generation logic of the component. It is important for the dev to understand when to use
|
||||
each flow.
|
||||
logic of the component. It is important for the dev to understand when to use each flow.
|
||||
|
||||
### Use Cases
|
||||
|
||||
@@ -106,8 +102,9 @@ Used in scenarios where we do have an existing and authed user, and thus an acti
|
||||
|
||||
- A "just-in-time" (JIT) provisioned user joins a master password (MP) encryption org and must set
|
||||
their initial password
|
||||
- A "just-in-time" (JIT) provisioned user joins a trusted device encryption (TDE) org with a
|
||||
starting role that requires them to have/set their initial password
|
||||
- A "just-in-time" (JIT) provisioned user joins a trusted device encryption (TDE) org with the reset
|
||||
password permission ("manage account recovery") from the start, which requires them to have/set
|
||||
their initial password
|
||||
- A note on JIT provisioned user flows:
|
||||
- Even though a JIT provisioned user is a brand-new user who was “just” created, we consider
|
||||
them to be an “existing authed user” _from the perspective of the set-password flow_. This is
|
||||
@@ -117,8 +114,9 @@ Used in scenarios where we do have an existing and authed user, and thus an acti
|
||||
registration when a user reaches the `/finish-signup` or `/trial-initiation` page to set their
|
||||
initial password, their account does not yet exist in the database, and will only be created
|
||||
once they set an initial password.
|
||||
- An existing user in a TDE org logs in after the org admin upgraded the user to a role that now
|
||||
requires them to have/set their initial password
|
||||
- An existing user in a TDE org logs in after an org admin upgraded the user to have the reset
|
||||
password persmission ("manage account recovery"), which now requires the user to have/set their
|
||||
initial password
|
||||
- An existing user logs in after their org admin offboarded the org from TDE, and the user must now
|
||||
have/set their initial password<br /><br />
|
||||
|
||||
@@ -126,7 +124,7 @@ Used in scenarios where we do have an existing and authed user, and thus an acti
|
||||
|
||||
Used in scenarios where we simply want to offer the user the ability to change their password:
|
||||
|
||||
- User clicks an org email invite link an logs in with their password which does not meet the org's
|
||||
- User clicks an org email invite link and logs in with their password which does not meet the org's
|
||||
policy requirements
|
||||
- User logs in with password that does not meet the org's policy requirements
|
||||
- User logs in after their password was reset via Account Recovery (and now they must change their
|
||||
@@ -156,26 +154,10 @@ which form field UI elements get displayed.
|
||||
|
||||
<br />
|
||||
|
||||
### TypeScript - Credential Generation
|
||||
|
||||
- **`SetInitialPasswordAccountRegistration`** and **`SetInitialPasswordAuthedUser`**
|
||||
- These flows involve a user setting their password for the first time. Therefore on submit the
|
||||
component will only generate new credentials (`newMasterKey`) and not current credentials
|
||||
(`currentMasterKey`).<br /><br />
|
||||
- **`ChangePassword`** and **`ChangePasswordWithOptionalUserKeyRotation`**
|
||||
- These flows both require the user to enter a current password along with a new password.
|
||||
Therefore on submit the component will generate current credentials (`currentMasterKey`) along
|
||||
with new credentials (`newMasterKey`).<br /><br />
|
||||
- **`ChangePasswordDelegation`**
|
||||
- This flow does not generate any credentials, but simply validates the new password and emits it
|
||||
up to the parent.
|
||||
|
||||
<br />
|
||||
|
||||
### Difference between `SetInitialPasswordAccountRegistration` and `SetInitialPasswordAuthedUser`
|
||||
|
||||
These two flows are similar in that they display the same form fields and only generate new
|
||||
credentials, but we need to keep them separate for the following reasons:
|
||||
These two flows are similar in that they display the same form fields, but we need to keep them
|
||||
separate for the following reasons:
|
||||
|
||||
- `SetInitialPasswordAccountRegistration` involves scenarios where we have no existing user, and
|
||||
**thus NO active account `userId`**:
|
||||
@@ -183,7 +165,7 @@ credentials, but we need to keep them separate for the following reasons:
|
||||
and **thus an active account `userId`**:
|
||||
|
||||
The presence or absence of an active account `userId` is important because it determines how we get
|
||||
the correct `kdfConfig` prior to key generation:
|
||||
the correct `kdfConfig`:
|
||||
|
||||
- If there is no `userId` passed down from the parent, we default to `DEFAULT_KDF_CONFIG`
|
||||
- If there is a `userId` passed down from the parent, we get the `kdfConfig` from state using the
|
||||
@@ -223,25 +205,16 @@ When the form is submitted, the `InputPasswordComponent` does the following in o
|
||||
checkbox)
|
||||
- Checks that the new password adheres to any enforced master password policies that were
|
||||
optionally passed down by the parent
|
||||
2. Uses the form inputs to create cryptographic properties (`newMasterKey`,
|
||||
`newServerMasterKeyHash`, etc.)
|
||||
3. Emits those cryptographic properties up to the parent (along with other values defined in
|
||||
`PasswordInputResult`) to be used by the parent as needed.
|
||||
2. Emits values up to the parent (along with other values defined in `PasswordInputResult`) to be
|
||||
used by the parent as needed.
|
||||
|
||||
```typescript
|
||||
export interface PasswordInputResult {
|
||||
currentPassword?: string;
|
||||
currentMasterKey?: MasterKey;
|
||||
currentServerMasterKeyHash?: string;
|
||||
currentLocalMasterKeyHash?: string;
|
||||
|
||||
newPassword: string;
|
||||
newPasswordHint?: string;
|
||||
newMasterKey?: MasterKey;
|
||||
newServerMasterKeyHash?: string;
|
||||
newLocalMasterKeyHash?: string;
|
||||
|
||||
kdfConfig?: KdfConfig;
|
||||
salt?: MasterPasswordSalt;
|
||||
newPasswordHint?: string;
|
||||
rotateUserKey?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -10,6 +10,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { MasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||
@@ -59,6 +60,13 @@ export default {
|
||||
getAllDecrypted: () => Promise.resolve([]),
|
||||
},
|
||||
},
|
||||
// Can remove ConfigService from component and stories in PM-28143 (if it is no longer used)
|
||||
{
|
||||
provide: ConfigService,
|
||||
useValue: {
|
||||
getFeatureFlag: () => false, // default to false since flag does not effect UI
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: KdfConfigService,
|
||||
useValue: {
|
||||
|
||||
@@ -10,6 +10,20 @@ export interface PasswordInputResult {
|
||||
newPasswordHint?: string;
|
||||
rotateUserKey?: boolean;
|
||||
|
||||
/**
|
||||
* Temporary property that persists the flag state through the entire set/change password process.
|
||||
* This allows flows to consume this value instead of re-checking the flag state via ConfigService themselves.
|
||||
*
|
||||
* The ChangePasswordDelegation flows (Emergency Access Takeover and Account Recovery), however, only ever
|
||||
* require a raw newPassword from the InputPasswordComponent regardless of whether the flag is on or off.
|
||||
* Flagging for those 2 flows will be done via the ConfigService in their respective services.
|
||||
*
|
||||
* To be removed in PM-28143
|
||||
*/
|
||||
newApisWithInputPasswordFlagEnabled?: boolean;
|
||||
|
||||
// The deprecated properties below will be removed in PM-28143: https://bitwarden.atlassian.net/browse/PM-28143
|
||||
|
||||
/** @deprecated This low-level cryptographic state will be removed. It will be replaced by high level calls to masterpassword service, in the consumers of this interface. */
|
||||
currentMasterKey?: MasterKey;
|
||||
/** @deprecated */
|
||||
|
||||
@@ -18,6 +18,7 @@ export enum FeatureFlag {
|
||||
|
||||
/* Auth */
|
||||
PM23801_PrefetchPasswordPrelogin = "pm-23801-prefetch-password-prelogin",
|
||||
PM27086_UpdateAuthenticationApisForInputPassword = "pm-27086-update-authentication-apis-for-input-password",
|
||||
SafariAccountSwitching = "pm-5594-safari-account-switching",
|
||||
|
||||
/* Autofill */
|
||||
@@ -137,6 +138,7 @@ export const DefaultFeatureFlagValue = {
|
||||
|
||||
/* Auth */
|
||||
[FeatureFlag.PM23801_PrefetchPasswordPrelogin]: FALSE,
|
||||
[FeatureFlag.PM27086_UpdateAuthenticationApisForInputPassword]: FALSE,
|
||||
[FeatureFlag.SafariAccountSwitching]: FALSE,
|
||||
|
||||
/* Billing */
|
||||
|
||||
Reference in New Issue
Block a user