1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 05:13:29 +00:00

[PM-6789] finish key rotation distribution and fix legacy user (#9498)

* finish key rotation distribution and fix legacy user

* add ticket to TODO

* PR feedback: docs and renaming

* fix webauthn tests

* add test for send service

* add await to test
This commit is contained in:
Jake Fink
2024-06-20 11:36:24 -04:00
committed by GitHub
parent eadb1fa4ef
commit b306554675
23 changed files with 516 additions and 196 deletions

View File

@@ -1,5 +1,5 @@
import { mock } from "jest-mock-extended";
import { of } from "rxjs";
import { BehaviorSubject, of } from "rxjs";
import { FakeAccountService, mockAccountServiceWith } from "../../../spec/fake-account-service";
import { FakeStateProvider } from "../../../spec/fake-state-provider";
@@ -10,7 +10,7 @@ import { AutofillSettingsService } from "../../autofill/services/autofill-settin
import { DomainSettingsService } from "../../autofill/services/domain-settings.service";
import { UriMatchStrategy } from "../../models/domain/domain-service";
import { ConfigService } from "../../platform/abstractions/config/config.service";
import { CryptoService } from "../../platform/abstractions/crypto.service";
import { CipherDecryptionKeys, CryptoService } from "../../platform/abstractions/crypto.service";
import { EncryptService } from "../../platform/abstractions/encrypt.service";
import { I18nService } from "../../platform/abstractions/i18n.service";
import { StateService } from "../../platform/abstractions/state.service";
@@ -19,8 +19,8 @@ import { EncArrayBuffer } from "../../platform/models/domain/enc-array-buffer";
import { EncString } from "../../platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
import { ContainerService } from "../../platform/services/container.service";
import { UserId } from "../../types/guid";
import { CipherKey, OrgKey } from "../../types/key";
import { CipherId, UserId } from "../../types/guid";
import { CipherKey, OrgKey, UserKey } from "../../types/key";
import { CipherFileUploadService } from "../abstractions/file-upload/cipher-file-upload.service";
import { FieldType } from "../enums";
import { CipherRepromptType } from "../enums/cipher-reprompt-type";
@@ -331,6 +331,64 @@ describe("Cipher Service", () => {
});
});
});
describe("getRotatedData", () => {
const originalUserKey = new SymmetricCryptoKey(new Uint8Array(32)) as UserKey;
const newUserKey = new SymmetricCryptoKey(new Uint8Array(32)) as UserKey;
let decryptedCiphers: BehaviorSubject<Record<CipherId, CipherView>>;
let encryptedKey: EncString;
beforeEach(() => {
setEncryptionKeyFlag(true);
configService.checkServerMeetsVersionRequirement$.mockReturnValue(of(true));
searchService.indexedEntityId$ = of(null);
stateService.getUserId.mockResolvedValue(mockUserId);
const keys = {
userKey: originalUserKey,
} as CipherDecryptionKeys;
cryptoService.cipherDecryptionKeys$.mockReturnValue(of(keys));
const cipher1 = new CipherView(cipherObj);
cipher1.id = "Cipher 1";
const cipher2 = new CipherView(cipherObj);
cipher2.id = "Cipher 2";
decryptedCiphers = new BehaviorSubject({
Cipher1: cipher1,
Cipher2: cipher2,
});
cipherService.cipherViews$ = decryptedCiphers;
encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(32));
encryptedKey = new EncString("Re-encrypted Cipher Key");
encryptService.encrypt.mockResolvedValue(encryptedKey);
cryptoService.makeCipherKey.mockResolvedValue(
new SymmetricCryptoKey(new Uint8Array(32)) as CipherKey,
);
});
it("returns re-encrypted user ciphers", async () => {
const result = await cipherService.getRotatedData(originalUserKey, newUserKey, mockUserId);
expect(result[0]).toMatchObject({ id: "Cipher 1", key: "Re-encrypted Cipher Key" });
expect(result[1]).toMatchObject({ id: "Cipher 2", key: "Re-encrypted Cipher Key" });
});
it("throws if the original user key is null", async () => {
await expect(cipherService.getRotatedData(null, newUserKey, mockUserId)).rejects.toThrow(
"Original user key is required to rotate ciphers",
);
});
it("throws if the new user key is null", async () => {
await expect(cipherService.getRotatedData(originalUserKey, null, mockUserId)).rejects.toThrow(
"New user key is required to rotate ciphers",
);
});
});
});
function setEncryptionKeyFlag(value: boolean) {