mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
[PM-16603] Implement userkey rotation v2 (#12646)
* Implement key rotation v2 * Pass through masterpassword hint * Properly split old and new code * Mark legacy rotation as deprecated * Throw when data is null * Cleanup * Add tests * Fix build * Update libs/key-management/src/key.service.spec.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update apps/web/src/app/auth/settings/change-password.component.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Add documentation * Centralize loading logic * Fix build * Remove sharedlib from legacymigration component --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { mock } from "jest-mock-extended";
|
||||
import { bufferCount, firstValueFrom, lastValueFrom, of, take, tap } from "rxjs";
|
||||
import { BehaviorSubject, bufferCount, firstValueFrom, lastValueFrom, of, take, tap } from "rxjs";
|
||||
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { EncryptedOrganizationKeyData } from "@bitwarden/common/admin-console/models/data/encrypted-organization-key.data";
|
||||
@@ -802,4 +802,51 @@ describe("keyService", () => {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("userPrivateKey$", () => {
|
||||
type SetupKeysParams = {
|
||||
makeMasterKey: boolean;
|
||||
makeUserKey: boolean;
|
||||
};
|
||||
|
||||
function setupKeys({ makeMasterKey, makeUserKey }: SetupKeysParams): [UserKey, MasterKey] {
|
||||
const userKeyState = stateProvider.singleUser.getFake(mockUserId, USER_KEY);
|
||||
const fakeMasterKey = makeMasterKey ? makeSymmetricCryptoKey<MasterKey>(64) : null;
|
||||
masterPasswordService.masterKeySubject.next(fakeMasterKey);
|
||||
userKeyState.nextState(null);
|
||||
const fakeUserKey = makeUserKey ? makeSymmetricCryptoKey<UserKey>(64) : null;
|
||||
userKeyState.nextState(fakeUserKey);
|
||||
return [fakeUserKey, fakeMasterKey];
|
||||
}
|
||||
|
||||
it("returns null when private key is null", async () => {
|
||||
setupKeys({ makeMasterKey: false, makeUserKey: false });
|
||||
|
||||
keyService.userPrivateKey$ = jest.fn().mockReturnValue(new BehaviorSubject(null));
|
||||
const key = await firstValueFrom(keyService.userEncryptionKeyPair$(mockUserId));
|
||||
expect(key).toEqual(null);
|
||||
});
|
||||
|
||||
it("returns null when private key is undefined", async () => {
|
||||
setupKeys({ makeUserKey: true, makeMasterKey: false });
|
||||
|
||||
keyService.userPrivateKey$ = jest.fn().mockReturnValue(new BehaviorSubject(undefined));
|
||||
const key = await firstValueFrom(keyService.userEncryptionKeyPair$(mockUserId));
|
||||
expect(key).toEqual(null);
|
||||
});
|
||||
|
||||
it("returns keys when private key is defined", async () => {
|
||||
setupKeys({ makeUserKey: false, makeMasterKey: true });
|
||||
|
||||
keyService.userPrivateKey$ = jest.fn().mockReturnValue(new BehaviorSubject("private key"));
|
||||
cryptoFunctionService.rsaExtractPublicKey.mockResolvedValue(
|
||||
Utils.fromUtf8ToArray("public key"),
|
||||
);
|
||||
const key = await firstValueFrom(keyService.userEncryptionKeyPair$(mockUserId));
|
||||
expect(key).toEqual({
|
||||
privateKey: "private key",
|
||||
publicKey: Utils.fromUtf8ToArray("public key"),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user