mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
Auth/PM-7811 - Refactor User Auto Unlock Key Hydration Process To Remove Race Conditions (#8979)
* PM-7811 - Refactor UserKeyInitService to UserAutoUnlockKeyService - remove active account listening logic as it introduced race conditions with user key memory retrieval happening before the user auto unlock key was set into memory. * PM-7811 - CLI - (1) Fix deps (2) On CLI init (pre command execution), if there is an active account, then set the user key in memory from the user auto unlock key. * PM-7811 - Browser Extension / desktop - (1) Update deps (2) Sets user key in memory if the auto unlock key is set on account switch and background init (must act on all accounts so that account switcher displays unlock status properly). * PM-7811 - Web - (1) Update deps (2) Sets user key in memory if the auto unlock key is set on init * PM-7811 - Fix account switcher service changes not being necessary.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { CsprngArray } from "../../types/csprng";
|
||||
import { UserId } from "../../types/guid";
|
||||
import { UserKey } from "../../types/key";
|
||||
import { KeySuffixOptions } from "../enums";
|
||||
import { Utils } from "../misc/utils";
|
||||
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
|
||||
|
||||
import { CryptoService } from "./crypto.service";
|
||||
import { UserAutoUnlockKeyService } from "./user-auto-unlock-key.service";
|
||||
|
||||
describe("UserAutoUnlockKeyService", () => {
|
||||
let userAutoUnlockKeyService: UserAutoUnlockKeyService;
|
||||
|
||||
const mockUserId = Utils.newGuid() as UserId;
|
||||
|
||||
const cryptoService = mock<CryptoService>();
|
||||
|
||||
beforeEach(() => {
|
||||
userAutoUnlockKeyService = new UserAutoUnlockKeyService(cryptoService);
|
||||
});
|
||||
|
||||
describe("setUserKeyInMemoryIfAutoUserKeySet", () => {
|
||||
it("does nothing if the userId is null", async () => {
|
||||
// Act
|
||||
await (userAutoUnlockKeyService as any).setUserKeyInMemoryIfAutoUserKeySet(null);
|
||||
|
||||
// Assert
|
||||
expect(cryptoService.getUserKeyFromStorage).not.toHaveBeenCalled();
|
||||
expect(cryptoService.setUserKey).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does nothing if the autoUserKey is null", async () => {
|
||||
// Arrange
|
||||
const userId = mockUserId;
|
||||
|
||||
cryptoService.getUserKeyFromStorage.mockResolvedValue(null);
|
||||
|
||||
// Act
|
||||
await (userAutoUnlockKeyService as any).setUserKeyInMemoryIfAutoUserKeySet(userId);
|
||||
|
||||
// Assert
|
||||
expect(cryptoService.getUserKeyFromStorage).toHaveBeenCalledWith(
|
||||
KeySuffixOptions.Auto,
|
||||
userId,
|
||||
);
|
||||
expect(cryptoService.setUserKey).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("sets the user key in memory if the autoUserKey is not null", async () => {
|
||||
// Arrange
|
||||
const userId = mockUserId;
|
||||
|
||||
const mockRandomBytes = new Uint8Array(64) as CsprngArray;
|
||||
const mockAutoUserKey: UserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey;
|
||||
|
||||
cryptoService.getUserKeyFromStorage.mockResolvedValue(mockAutoUserKey);
|
||||
|
||||
// Act
|
||||
await (userAutoUnlockKeyService as any).setUserKeyInMemoryIfAutoUserKeySet(userId);
|
||||
|
||||
// Assert
|
||||
expect(cryptoService.getUserKeyFromStorage).toHaveBeenCalledWith(
|
||||
KeySuffixOptions.Auto,
|
||||
userId,
|
||||
);
|
||||
expect(cryptoService.setUserKey).toHaveBeenCalledWith(mockAutoUserKey, userId);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user