mirror of
https://github.com/bitwarden/browser
synced 2026-02-25 00:53:22 +00:00
[PM-30144] Implement client-side user-key-rotation-service (#18285)
* Implement client-side user-key-rotation-service * Feature flag * Add tests * Fix flag name * Fix build * Prettier * Small clean-up * Codeowners order cleanup * Fix eslint issue * Update sdk to 550 * Cleanup & fix incompatibilities * Prettier
This commit is contained in:
@@ -57,6 +57,7 @@ import {
|
||||
KeyRotationTrustInfoComponent,
|
||||
} from "@bitwarden/key-management-ui";
|
||||
import { BitwardenClient, PureCrypto } from "@bitwarden/sdk-internal";
|
||||
import { UserKeyRotationServiceAbstraction } from "@bitwarden/user-crypto-management";
|
||||
|
||||
import { OrganizationUserResetPasswordService } from "../../admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service";
|
||||
import { WebauthnLoginAdminService } from "../../auth";
|
||||
@@ -287,6 +288,7 @@ describe("KeyRotationService", () => {
|
||||
let mockSdkClientFactory: MockProxy<SdkClientFactory>;
|
||||
let mockSecurityStateService: MockProxy<SecurityStateService>;
|
||||
let mockMasterPasswordService: MockProxy<MasterPasswordServiceAbstraction>;
|
||||
let mockSdkUserKeyRotationService: MockProxy<UserKeyRotationServiceAbstraction>;
|
||||
|
||||
const mockUser = {
|
||||
id: "mockUserId" as UserId,
|
||||
@@ -348,6 +350,7 @@ describe("KeyRotationService", () => {
|
||||
mockDialogService = mock<DialogService>();
|
||||
mockCryptoFunctionService = mock<CryptoFunctionService>();
|
||||
mockKdfConfigService = mock<KdfConfigService>();
|
||||
mockSdkUserKeyRotationService = mock<UserKeyRotationServiceAbstraction>();
|
||||
mockSdkClientFactory = mock<SdkClientFactory>();
|
||||
mockSdkClientFactory.createSdkClient.mockResolvedValue({
|
||||
crypto: () => {
|
||||
@@ -358,6 +361,7 @@ describe("KeyRotationService", () => {
|
||||
} as any;
|
||||
},
|
||||
} as BitwardenClient);
|
||||
|
||||
mockSecurityStateService = mock<SecurityStateService>();
|
||||
mockMasterPasswordService = mock<MasterPasswordServiceAbstraction>();
|
||||
|
||||
@@ -384,6 +388,7 @@ describe("KeyRotationService", () => {
|
||||
mockSdkClientFactory,
|
||||
mockSecurityStateService,
|
||||
mockMasterPasswordService,
|
||||
mockSdkUserKeyRotationService,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -509,7 +514,12 @@ describe("KeyRotationService", () => {
|
||||
);
|
||||
mockKeyService.userSigningKey$.mockReturnValue(new BehaviorSubject(null));
|
||||
mockSecurityStateService.accountSecurityState$.mockReturnValue(new BehaviorSubject(null));
|
||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
||||
mockConfigService.getFeatureFlag.mockImplementation(async (flag: FeatureFlag) => {
|
||||
if (flag === FeatureFlag.EnrollAeadOnKeyRotation) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const spy = jest.spyOn(keyRotationService, "getRotatedAccountKeysFlagged").mockResolvedValue({
|
||||
userKey: TEST_VECTOR_USER_KEY_V2,
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
KeyRotationTrustInfoComponent,
|
||||
} from "@bitwarden/key-management-ui";
|
||||
import { PureCrypto, TokenProvider } from "@bitwarden/sdk-internal";
|
||||
import { UserKeyRotationServiceAbstraction } from "@bitwarden/user-crypto-management";
|
||||
|
||||
import { OrganizationUserResetPasswordService } from "../../admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service";
|
||||
import { WebauthnLoginAdminService } from "../../auth/core";
|
||||
@@ -101,6 +102,7 @@ export class UserKeyRotationService {
|
||||
private sdkClientFactory: SdkClientFactory,
|
||||
private securityStateService: SecurityStateService,
|
||||
private masterPasswordService: MasterPasswordServiceAbstraction,
|
||||
private sdkUserKeyRotationService: UserKeyRotationServiceAbstraction,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -116,6 +118,28 @@ export class UserKeyRotationService {
|
||||
user: Account,
|
||||
newMasterPasswordHint?: string,
|
||||
): Promise<void> {
|
||||
const useSdkKeyRotation = await this.configService.getFeatureFlag(FeatureFlag.SdkKeyRotation);
|
||||
if (useSdkKeyRotation) {
|
||||
this.logService.info(
|
||||
"[UserKey Rotation] Using SDK-based key rotation service from user-crypto-management",
|
||||
);
|
||||
await this.sdkUserKeyRotationService.changePasswordAndRotateUserKey(
|
||||
currentMasterPassword,
|
||||
newMasterPassword,
|
||||
newMasterPasswordHint,
|
||||
asUuid(user.id),
|
||||
);
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: this.i18nService.t("rotationCompletedTitle"),
|
||||
message: this.i18nService.t("rotationCompletedDesc"),
|
||||
timeout: 15000,
|
||||
});
|
||||
|
||||
await this.logoutService.logout(user.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Key-rotation uses the SDK, so we need to ensure that the SDK is loaded / the WASM initialized.
|
||||
await SdkLoadService.Ready;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user