1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-08 20:50:28 +00:00

Add tests

This commit is contained in:
Bernd Schoolmann
2025-05-09 14:18:44 +02:00
parent 217af4277f
commit bc426fc79b
3 changed files with 68 additions and 22 deletions

View File

@@ -11,7 +11,6 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { SendWithIdRequest } from "@bitwarden/common/tools/send/models/request/send-with-id.request";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
@@ -30,6 +29,7 @@ import {
EmergencyAccessTrustComponent,
KeyRotationTrustInfoComponent,
} from "@bitwarden/key-management-ui";
import { PureCrypto } from "@bitwarden/sdk-internal";
import { OrganizationUserResetPasswordService } from "../../admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service";
import { WebauthnLoginAdminService } from "../../auth";
@@ -96,6 +96,13 @@ describe("KeyRotationService", () => {
const mockTrustedPublicKeys = [Utils.fromUtf8ToArray("test-public-key")];
beforeAll(() => {
jest.spyOn(PureCrypto, "generate_user_key_aes256_cbc_hmac").mockReturnValue(new Uint8Array(64));
jest
.spyOn(PureCrypto, "generate_user_key_xchacha20_poly1305")
.mockReturnValue(new Uint8Array(70));
jest
.spyOn(PureCrypto, "encrypt_user_key_with_master_password")
.mockReturnValue("mockNewUserKey");
mockUserVerificationService = mock<UserVerificationService>();
mockApiService = mock<UserKeyRotationApiService>();
mockCipherService = mock<CipherService>();
@@ -158,6 +165,7 @@ describe("KeyRotationService", () => {
mockToastService,
mockI18nService,
mockDialogService,
mockConfigService,
);
});
@@ -181,7 +189,7 @@ describe("KeyRotationService", () => {
} as any,
]);
mockKeyService.hashMasterKey.mockResolvedValue("mockMasterPasswordHash");
mockConfigService.getFeatureFlag.mockResolvedValue(true);
mockConfigService.getFeatureFlag.mockResolvedValue(false);
mockEncryptService.wrapSymmetricKey.mockResolvedValue({
encryptedString: "mockEncryptedData",
@@ -286,6 +294,59 @@ describe("KeyRotationService", () => {
expect(arg.accountUnlockData.emergencyAccessUnlockData.length).toBe(1);
expect(arg.accountUnlockData.organizationAccountRecoveryUnlockData.length).toBe(1);
expect(arg.accountUnlockData.passkeyUnlockData.length).toBe(2);
expect(PureCrypto.generate_user_key_aes256_cbc_hmac).toHaveBeenCalled();
expect(PureCrypto.encrypt_user_key_with_master_password).toHaveBeenCalledWith(
new Uint8Array(64),
"newMasterPassword",
mockUser.email,
DEFAULT_KDF_CONFIG.toSdkConfig(),
);
expect(PureCrypto.generate_user_key_xchacha20_poly1305).not.toHaveBeenCalled();
});
it("rotates the userkey to xchacha20poly1305 and encrypted data and changes master password when featureflag is active", async () => {
mockConfigService.getFeatureFlag.mockResolvedValue(true);
KeyRotationTrustInfoComponent.open = initialPromptedOpenTrue;
EmergencyAccessTrustComponent.open = emergencyAccessTrustOpenTrusted;
AccountRecoveryTrustComponent.open = accountRecoveryTrustOpenTrusted;
await keyRotationService.rotateUserKeyMasterPasswordAndEncryptedData(
"mockMasterPassword",
"newMasterPassword",
mockUser,
);
expect(mockApiService.postUserKeyUpdateV2).toHaveBeenCalled();
const arg = mockApiService.postUserKeyUpdateV2.mock.calls[0][0];
expect(arg.accountUnlockData.masterPasswordUnlockData.masterKeyEncryptedUserKey).toBe(
"mockNewUserKey",
);
expect(arg.oldMasterKeyAuthenticationHash).toBe("mockMasterPasswordHash");
expect(arg.accountUnlockData.masterPasswordUnlockData.email).toBe("mockEmail");
expect(arg.accountUnlockData.masterPasswordUnlockData.kdfType).toBe(
DEFAULT_KDF_CONFIG.kdfType,
);
expect(arg.accountUnlockData.masterPasswordUnlockData.kdfIterations).toBe(
DEFAULT_KDF_CONFIG.iterations,
);
expect(arg.accountKeys.accountPublicKey).toBe(Utils.fromUtf8ToB64("mockPublicKey"));
expect(arg.accountKeys.userKeyEncryptedAccountPrivateKey).toBe("mockEncryptedData");
expect(arg.accountData.ciphers.length).toBe(2);
expect(arg.accountData.folders.length).toBe(2);
expect(arg.accountData.sends.length).toBe(2);
expect(arg.accountUnlockData.emergencyAccessUnlockData.length).toBe(1);
expect(arg.accountUnlockData.organizationAccountRecoveryUnlockData.length).toBe(1);
expect(arg.accountUnlockData.passkeyUnlockData.length).toBe(2);
expect(PureCrypto.generate_user_key_aes256_cbc_hmac).toHaveBeenCalled();
expect(PureCrypto.encrypt_user_key_with_master_password).toHaveBeenCalledWith(
new Uint8Array(70),
"newMasterPassword",
mockUser.email,
DEFAULT_KDF_CONFIG.toSdkConfig(),
);
expect(PureCrypto.generate_user_key_xchacha20_poly1305).toHaveBeenCalled();
});
it("returns early when first trust warning dialog is declined", async () => {
@@ -344,21 +405,6 @@ describe("KeyRotationService", () => {
).rejects.toThrow();
});
it("throws if user key creation fails", async () => {
mockKeyService.makeUserKey.mockResolvedValueOnce([
null as unknown as UserKey,
null as unknown as EncString,
]);
await expect(
keyRotationService.rotateUserKeyMasterPasswordAndEncryptedData(
"mockMasterPassword",
"mockMasterPassword1",
mockUser,
),
).rejects.toThrow();
});
it("legacy throws if no private key is found", async () => {
privateKey.next(null);

8
package-lock.json generated
View File

@@ -24,7 +24,7 @@
"@angular/platform-browser": "18.2.13",
"@angular/platform-browser-dynamic": "18.2.13",
"@angular/router": "18.2.13",
"@bitwarden/sdk-internal": "0.2.0-main.137",
"@bitwarden/sdk-internal": "0.2.0-main.163",
"@electron/fuses": "1.8.0",
"@emotion/css": "11.13.5",
"@koa/multer": "3.0.2",
@@ -4700,9 +4700,9 @@
"link": true
},
"node_modules/@bitwarden/sdk-internal": {
"version": "0.2.0-main.137",
"resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.137.tgz",
"integrity": "sha512-Df0pB5tOEc4WiMjskunTrqHulPzenFv8C61sqsBhHfy80xcf5kU5JyPd4asbf3e4uNS6QGXptd8imp09AuiFEA==",
"version": "0.2.0-main.163",
"resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.163.tgz",
"integrity": "sha512-k8Z4wUhgQi4+vc/Zy3GgRZqxqrCiEzC0M4dRkoieMSU65e/8b0HBy0kXYcrcip2HKIxFZd6hXsv/auIf7fgEFg==",
"license": "GPL-3.0"
},
"node_modules/@bitwarden/send-ui": {

View File

@@ -156,7 +156,7 @@
"@angular/platform-browser": "18.2.13",
"@angular/platform-browser-dynamic": "18.2.13",
"@angular/router": "18.2.13",
"@bitwarden/sdk-internal": "0.2.0-main.137",
"@bitwarden/sdk-internal": "0.2.0-main.163",
"@electron/fuses": "1.8.0",
"@emotion/css": "11.13.5",
"@koa/multer": "3.0.2",