1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 17:23:37 +00:00

[PM-10607] Require userId for getKeyForCipherKeyDecryption (#10509)

* updated cipher service to stop using the deprecated getUserKeyWithLegacySupport and use the version that requires a user id

* Added account service mock

* fixed cipher test

* Fixed test

* removed async from encryptCipher

* updated encryptSharedCipher to pass userId to the encrypt function

* Pass userId to getUserKeyWithLegacySupport on encryptSharedCipher

* pass in userid when setting masterKeyEncryptedUserKey

* Added activer usedId to new web refresh function
This commit is contained in:
SmithThe4th
2024-08-20 12:00:48 -04:00
committed by GitHub
parent ed719f835a
commit dedd7f1b5c
67 changed files with 534 additions and 118 deletions

View File

@@ -1,7 +1,10 @@
import { TextEncoder } from "util";
import { mock, MockProxy } from "jest-mock-extended";
import { BehaviorSubject } from "rxjs";
import { AccountInfo, AccountService } from "../../../auth/abstractions/account.service";
import { UserId } from "../../../types/guid";
import { CipherService } from "../../../vault/abstractions/cipher.service";
import { SyncService } from "../../../vault/abstractions/sync/sync.service.abstraction";
import { CipherRepromptType } from "../../../vault/enums/cipher-reprompt-type";
@@ -30,10 +33,18 @@ import { guidToRawFormat } from "./guid-utils";
const RpId = "bitwarden.com";
describe("FidoAuthenticatorService", () => {
const activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>({
id: "testId" as UserId,
email: "test@example.com",
emailVerified: true,
name: "Test User",
});
let cipherService!: MockProxy<CipherService>;
let userInterface!: MockProxy<Fido2UserInterfaceService>;
let userInterfaceSession!: MockProxy<Fido2UserInterfaceSession>;
let syncService!: MockProxy<SyncService>;
let accountService!: MockProxy<AccountService>;
let authenticator!: Fido2AuthenticatorService;
let tab!: chrome.tabs.Tab;
@@ -43,8 +54,15 @@ describe("FidoAuthenticatorService", () => {
userInterfaceSession = mock<Fido2UserInterfaceSession>();
userInterface.newSession.mockResolvedValue(userInterfaceSession);
syncService = mock<SyncService>();
authenticator = new Fido2AuthenticatorService(cipherService, userInterface, syncService);
accountService = mock<AccountService>();
authenticator = new Fido2AuthenticatorService(
cipherService,
userInterface,
syncService,
accountService,
);
tab = { id: 123, windowId: 456 } as chrome.tabs.Tab;
accountService.activeAccount$ = activeAccountSubject;
});
describe("makeCredential", () => {
@@ -677,6 +695,7 @@ describe("FidoAuthenticatorService", () => {
],
}),
}),
"testId",
);
});

View File

@@ -1,3 +1,6 @@
import { firstValueFrom, map } from "rxjs";
import { AccountService } from "../../../auth/abstractions/account.service";
import { CipherService } from "../../../vault/abstractions/cipher.service";
import { SyncService } from "../../../vault/abstractions/sync/sync.service.abstraction";
import { CipherRepromptType } from "../../../vault/enums/cipher-reprompt-type";
@@ -42,6 +45,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
private cipherService: CipherService,
private userInterface: Fido2UserInterfaceService,
private syncService: SyncService,
private accountService: AccountService,
private logService?: LogService,
) {}
@@ -130,8 +134,12 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
keyPair = await createKeyPair();
pubKeyDer = await crypto.subtle.exportKey("spki", keyPair.publicKey);
const encrypted = await this.cipherService.get(cipherId);
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
);
cipher = await encrypted.decrypt(
await this.cipherService.getKeyForCipherKeyDecryption(encrypted),
await this.cipherService.getKeyForCipherKeyDecryption(encrypted, activeUserId),
);
if (
@@ -150,7 +158,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
if (Utils.isNullOrEmpty(cipher.login.username)) {
cipher.login.username = fido2Credential.userName;
}
const reencrypted = await this.cipherService.encrypt(cipher);
const reencrypted = await this.cipherService.encrypt(cipher, activeUserId);
await this.cipherService.updateWithServer(reencrypted);
credentialId = fido2Credential.credentialId;
} catch (error) {
@@ -277,7 +285,10 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr
};
if (selectedFido2Credential.counter > 0) {
const encrypted = await this.cipherService.encrypt(selectedCipher);
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
);
const encrypted = await this.cipherService.encrypt(selectedCipher, activeUserId);
await this.cipherService.updateWithServer(encrypted);
}