mirror of
https://github.com/bitwarden/browser
synced 2026-01-31 00:33:33 +00:00
[PM-27086 TDE Offboarding] Use new KM APIs; create new methods
This commit is contained in:
@@ -19,7 +19,11 @@ import { AccountCryptographicStateService } from "@bitwarden/common/key-manageme
|
||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
import { MasterPasswordSalt } from "@bitwarden/common/key-management/master-password/types/master-password.types";
|
||||
import {
|
||||
MasterPasswordAuthenticationData,
|
||||
MasterPasswordSalt,
|
||||
MasterPasswordUnlockData,
|
||||
} from "@bitwarden/common/key-management/master-password/types/master-password.types";
|
||||
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@@ -32,6 +36,7 @@ import {
|
||||
SetInitialPasswordCredentials,
|
||||
SetInitialPasswordUserType,
|
||||
SetInitialPasswordTdeOffboardingCredentialsOld,
|
||||
SetInitialPasswordTdeOffboardingCredentials,
|
||||
} from "./set-initial-password.service.abstraction";
|
||||
|
||||
export class DefaultSetInitialPasswordService implements SetInitialPasswordService {
|
||||
@@ -362,4 +367,52 @@ export class DefaultSetInitialPasswordService implements SetInitialPasswordServi
|
||||
// Clear force set password reason to allow navigation back to vault.
|
||||
await this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.None, userId);
|
||||
}
|
||||
|
||||
async setInitialPasswordTdeOffboarding(
|
||||
credentials: SetInitialPasswordTdeOffboardingCredentials,
|
||||
userId: UserId,
|
||||
) {
|
||||
const { newPassword, kdfConfig, salt, newPasswordHint } = credentials;
|
||||
|
||||
for (const [key, value] of Object.entries(credentials)) {
|
||||
if (value == null) {
|
||||
throw new Error(`${key} not found. Could not set password.`);
|
||||
}
|
||||
}
|
||||
|
||||
if (userId == null) {
|
||||
throw new Error("userId not found. Could not set password.");
|
||||
}
|
||||
|
||||
const userKey = await firstValueFrom(this.keyService.userKey$(userId));
|
||||
if (userKey == null) {
|
||||
throw new Error("userKey not found. Could not set password.");
|
||||
}
|
||||
|
||||
const authenticationData: MasterPasswordAuthenticationData =
|
||||
await this.masterPasswordService.makeMasterPasswordAuthenticationData(
|
||||
newPassword,
|
||||
kdfConfig,
|
||||
salt,
|
||||
);
|
||||
|
||||
const unlockData: MasterPasswordUnlockData =
|
||||
await this.masterPasswordService.makeMasterPasswordUnlockData(
|
||||
newPassword,
|
||||
kdfConfig,
|
||||
salt,
|
||||
userKey,
|
||||
);
|
||||
|
||||
const request = UpdateTdeOffboardingPasswordRequest.newConstructorWithHint(
|
||||
authenticationData,
|
||||
unlockData,
|
||||
newPasswordHint,
|
||||
);
|
||||
|
||||
await this.masterPasswordApiService.putUpdateTdeOffboardingPassword(request);
|
||||
|
||||
// Clear force set password reason to allow navigation back to vault.
|
||||
await this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.None, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import { I18nPipe } from "@bitwarden/ui-common";
|
||||
import {
|
||||
SetInitialPasswordCredentials,
|
||||
SetInitialPasswordService,
|
||||
SetInitialPasswordTdeOffboardingCredentials,
|
||||
SetInitialPasswordTdeOffboardingCredentialsOld,
|
||||
SetInitialPasswordUserType,
|
||||
} from "./set-initial-password.service.abstraction";
|
||||
@@ -276,7 +277,7 @@ export class SetInitialPasswordComponent implements OnInit {
|
||||
case SetInitialPasswordUserType.OFFBOARDED_TDE_ORG_USER:
|
||||
// Remove wrapping "if" check and early return in PM-28143
|
||||
if (passwordInputResult.newApisFlagEnabled) {
|
||||
// ...
|
||||
await this.setInitialPasswordTdeOffboarding(passwordInputResult);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -340,6 +341,42 @@ export class SetInitialPasswordComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
private async setInitialPasswordTdeOffboarding(passwordInputResult: PasswordInputResult) {
|
||||
const ctx = "Could not set initial password.";
|
||||
|
||||
assertTruthy(passwordInputResult.newPassword, "newPassword", ctx);
|
||||
assertTruthy(passwordInputResult.kdfConfig, "kdfConfig", ctx);
|
||||
assertTruthy(passwordInputResult.salt, "salt", ctx);
|
||||
assertNonNullish(passwordInputResult.newPasswordHint, "newPasswordHint", ctx); // can have an empty string as a valid value, so check non-nullish
|
||||
|
||||
assertTruthy(this.userId, "userId", ctx);
|
||||
|
||||
try {
|
||||
const credentials: SetInitialPasswordTdeOffboardingCredentials = {
|
||||
newPassword: passwordInputResult.newPassword,
|
||||
kdfConfig: passwordInputResult.kdfConfig,
|
||||
salt: passwordInputResult.salt,
|
||||
newPasswordHint: passwordInputResult.newPasswordHint,
|
||||
};
|
||||
|
||||
await this.setInitialPasswordService.setInitialPasswordTdeOffboarding(
|
||||
credentials,
|
||||
this.userId,
|
||||
);
|
||||
|
||||
this.showSuccessToastByUserType();
|
||||
|
||||
await this.logoutService.logout(this.userId);
|
||||
// navigate to root so redirect guard can properly route next active user or null user to correct page
|
||||
await this.router.navigate(["/"]);
|
||||
} catch (e) {
|
||||
this.logService.error("Error setting initial password during TDE offboarding", e);
|
||||
this.validationService.showError(e);
|
||||
} finally {
|
||||
this.submitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated To be removed in PM-28143
|
||||
*/
|
||||
|
||||
@@ -64,6 +64,13 @@ export interface SetInitialPasswordTdeOffboardingCredentialsOld {
|
||||
newPasswordHint: string;
|
||||
}
|
||||
|
||||
export interface SetInitialPasswordTdeOffboardingCredentials {
|
||||
newPassword: string;
|
||||
kdfConfig: KdfConfig;
|
||||
salt: MasterPasswordSalt;
|
||||
newPasswordHint: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles setting an initial password for an existing authed user.
|
||||
*
|
||||
@@ -102,4 +109,17 @@ export abstract class SetInitialPasswordService {
|
||||
credentials: SetInitialPasswordTdeOffboardingCredentialsOld,
|
||||
userId: UserId,
|
||||
) => Promise<void>;
|
||||
|
||||
/**
|
||||
* Sets an initial password for a user who logs in after their org offboarded from
|
||||
* trusted device encryption and is now a master-password-encryption org:
|
||||
* - {@link SetInitialPasswordUserType.OFFBOARDED_TDE_ORG_USER}
|
||||
*
|
||||
* @param passwordInputResult credentials object received from the `InputPasswordComponent`
|
||||
* @param userId the account `userId`
|
||||
*/
|
||||
abstract setInitialPasswordTdeOffboarding: (
|
||||
credentials: SetInitialPasswordTdeOffboardingCredentials,
|
||||
userId: UserId,
|
||||
) => Promise<void>;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,28 @@
|
||||
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { OrganizationUserResetPasswordRequest } from "@bitwarden/admin-console/common";
|
||||
import {
|
||||
MasterPasswordAuthenticationData,
|
||||
MasterPasswordUnlockData,
|
||||
} from "@bitwarden/common/key-management/master-password/types/master-password.types";
|
||||
|
||||
export class UpdateTdeOffboardingPasswordRequest extends OrganizationUserResetPasswordRequest {
|
||||
masterPasswordHint: string;
|
||||
|
||||
// This will eventually be changed to be an actual constructor, once all callers are updated.
|
||||
// The body of this request will be changed to carry the authentication data and unlock data.
|
||||
// https://bitwarden.atlassian.net/browse/PM-23234
|
||||
static newConstructorWithHint(
|
||||
authenticationData: MasterPasswordAuthenticationData,
|
||||
unlockData: MasterPasswordUnlockData,
|
||||
masterPasswordHint: string,
|
||||
): UpdateTdeOffboardingPasswordRequest {
|
||||
const request = OrganizationUserResetPasswordRequest.newConstructor(
|
||||
authenticationData,
|
||||
unlockData,
|
||||
) as UpdateTdeOffboardingPasswordRequest;
|
||||
|
||||
request.masterPasswordHint = masterPasswordHint;
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user