mirror of
https://github.com/bitwarden/browser
synced 2026-02-12 06:23:38 +00:00
updated to use sdk function without prociding the key
This commit is contained in:
@@ -152,7 +152,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
id === excludedCipher.id ? ({ decrypt: () => excludedCipher } as any) : undefined,
|
||||
);
|
||||
cipherService.getAllDecrypted.mockResolvedValue([excludedCipher]);
|
||||
cipherService.decryptCipherWithSdkOrLegacy.mockResolvedValue(excludedCipher);
|
||||
cipherService.decrypt.mockResolvedValue(excludedCipher);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -221,7 +221,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
id === existingCipher.id ? ({ decrypt: () => existingCipher } as any) : undefined,
|
||||
);
|
||||
cipherService.getAllDecrypted.mockResolvedValue([existingCipher]);
|
||||
cipherService.decryptCipherWithSdkOrLegacy.mockResolvedValue(existingCipher);
|
||||
cipherService.decrypt.mockResolvedValue(existingCipher);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -308,7 +308,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
const encryptedCipher = { ...existingCipher, reprompt: CipherRepromptType.Password };
|
||||
cipherService.get.mockResolvedValue(encryptedCipher as unknown as Cipher);
|
||||
|
||||
cipherService.decryptCipherWithSdkOrLegacy.mockResolvedValue({
|
||||
cipherService.decrypt.mockResolvedValue({
|
||||
...existingCipher,
|
||||
reprompt: CipherRepromptType.Password,
|
||||
} as unknown as CipherView);
|
||||
@@ -354,7 +354,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
cipherId === cipher.id ? ({ decrypt: () => cipher } as any) : undefined,
|
||||
);
|
||||
cipherService.getAllDecrypted.mockResolvedValue([await cipher]);
|
||||
cipherService.decryptCipherWithSdkOrLegacy.mockResolvedValue(cipher);
|
||||
cipherService.decrypt.mockResolvedValue(cipher);
|
||||
cipherService.encrypt.mockImplementation(async (cipher) => {
|
||||
cipher.login.fido2Credentials[0].credentialId = credentialId; // Replace id for testability
|
||||
return {} as any;
|
||||
|
||||
@@ -151,7 +151,7 @@ export class Fido2AuthenticatorService<ParentWindowReference>
|
||||
);
|
||||
const encrypted = await this.cipherService.get(cipherId, activeUserId);
|
||||
|
||||
cipher = await this.cipherService.decryptCipherWithSdkOrLegacy(encrypted, activeUserId);
|
||||
cipher = await this.cipherService.decrypt(encrypted, activeUserId);
|
||||
|
||||
if (
|
||||
!userVerified &&
|
||||
|
||||
@@ -221,5 +221,5 @@ export abstract class CipherService implements UserKeyRotationDataProvider<Ciphe
|
||||
* @param userId The user ID to use for decryption.
|
||||
* @returns A promise that resolves to the decrypted cipher view.
|
||||
*/
|
||||
abstract decryptCipherWithSdkOrLegacy(cipher: Cipher, userId: UserId): Promise<CipherView>;
|
||||
abstract decrypt(cipher: Cipher, userId: UserId): Promise<CipherView>;
|
||||
}
|
||||
|
||||
@@ -477,12 +477,12 @@ describe("Cipher Service", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("decryptCipherWithSdkOrLegacy", () => {
|
||||
describe("decrypt", () => {
|
||||
it("should call decrypt method of CipherEncryptionService when feature flag is true", async () => {
|
||||
configService.getFeatureFlag.mockResolvedValue(true);
|
||||
cipherEncryptionService.decrypt.mockResolvedValue(new CipherView(cipherObj));
|
||||
|
||||
const result = await cipherService.decryptCipherWithSdkOrLegacy(cipherObj, userId);
|
||||
const result = await cipherService.decrypt(cipherObj, userId);
|
||||
|
||||
expect(result).toEqual(new CipherView(cipherObj));
|
||||
expect(cipherEncryptionService.decrypt).toHaveBeenCalledWith(cipherObj, userId);
|
||||
@@ -495,7 +495,7 @@ describe("Cipher Service", () => {
|
||||
encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(32));
|
||||
jest.spyOn(cipherObj, "decrypt").mockResolvedValue(new CipherView(cipherObj));
|
||||
|
||||
const result = await cipherService.decryptCipherWithSdkOrLegacy(cipherObj, userId);
|
||||
const result = await cipherService.decrypt(cipherObj, userId);
|
||||
|
||||
expect(result).toEqual(new CipherView(cipherObj));
|
||||
expect(cipherObj.decrypt).toHaveBeenCalledWith(mockUserKey);
|
||||
|
||||
@@ -428,57 +428,57 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
): Promise<[CipherView[], CipherView[]] | null> {
|
||||
if (await this.configService.getFeatureFlag(FeatureFlag.PM19941MigrateCipherDomainToSdk)) {
|
||||
return this.decryptCiphersWithSdk(ciphers, userId);
|
||||
} else {
|
||||
const keys = await firstValueFrom(this.keyService.cipherDecryptionKeys$(userId, true));
|
||||
if (keys == null || (keys.userKey == null && Object.keys(keys.orgKeys).length === 0)) {
|
||||
// return early if there are no keys to decrypt with
|
||||
return null;
|
||||
}
|
||||
// Group ciphers by orgId or under 'null' for the user's ciphers
|
||||
const grouped = ciphers.reduce(
|
||||
(agg, c) => {
|
||||
agg[c.organizationId] ??= [];
|
||||
agg[c.organizationId].push(c);
|
||||
return agg;
|
||||
},
|
||||
{} as Record<string, Cipher[]>,
|
||||
);
|
||||
const decryptStartTime = new Date().getTime();
|
||||
const allCipherViews = (
|
||||
await Promise.all(
|
||||
Object.entries(grouped).map(async ([orgId, groupedCiphers]) => {
|
||||
if (await this.configService.getFeatureFlag(FeatureFlag.PM4154_BulkEncryptionService)) {
|
||||
return await this.bulkEncryptService.decryptItems(
|
||||
groupedCiphers,
|
||||
keys.orgKeys[orgId as OrganizationId] ?? keys.userKey,
|
||||
);
|
||||
} else {
|
||||
return await this.encryptService.decryptItems(
|
||||
groupedCiphers,
|
||||
keys.orgKeys[orgId as OrganizationId] ?? keys.userKey,
|
||||
);
|
||||
}
|
||||
}),
|
||||
)
|
||||
)
|
||||
.flat()
|
||||
.sort(this.getLocaleSortingFunction());
|
||||
this.logService.info(
|
||||
`[CipherService] Decrypting ${allCipherViews.length} ciphers took ${new Date().getTime() - decryptStartTime}ms`,
|
||||
);
|
||||
// Split ciphers into two arrays, one for successfully decrypted ciphers and one for ciphers that failed to decrypt
|
||||
return allCipherViews.reduce(
|
||||
(acc, c) => {
|
||||
if (c.decryptionFailure) {
|
||||
acc[1].push(c);
|
||||
} else {
|
||||
acc[0].push(c);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
[[], []] as [CipherView[], CipherView[]],
|
||||
);
|
||||
}
|
||||
|
||||
const keys = await firstValueFrom(this.keyService.cipherDecryptionKeys$(userId, true));
|
||||
if (keys == null || (keys.userKey == null && Object.keys(keys.orgKeys).length === 0)) {
|
||||
// return early if there are no keys to decrypt with
|
||||
return null;
|
||||
}
|
||||
// Group ciphers by orgId or under 'null' for the user's ciphers
|
||||
const grouped = ciphers.reduce(
|
||||
(agg, c) => {
|
||||
agg[c.organizationId] ??= [];
|
||||
agg[c.organizationId].push(c);
|
||||
return agg;
|
||||
},
|
||||
{} as Record<string, Cipher[]>,
|
||||
);
|
||||
const decryptStartTime = new Date().getTime();
|
||||
const allCipherViews = (
|
||||
await Promise.all(
|
||||
Object.entries(grouped).map(async ([orgId, groupedCiphers]) => {
|
||||
if (await this.configService.getFeatureFlag(FeatureFlag.PM4154_BulkEncryptionService)) {
|
||||
return await this.bulkEncryptService.decryptItems(
|
||||
groupedCiphers,
|
||||
keys.orgKeys[orgId as OrganizationId] ?? keys.userKey,
|
||||
);
|
||||
} else {
|
||||
return await this.encryptService.decryptItems(
|
||||
groupedCiphers,
|
||||
keys.orgKeys[orgId as OrganizationId] ?? keys.userKey,
|
||||
);
|
||||
}
|
||||
}),
|
||||
)
|
||||
)
|
||||
.flat()
|
||||
.sort(this.getLocaleSortingFunction());
|
||||
this.logService.info(
|
||||
`[CipherService] Decrypting ${allCipherViews.length} ciphers took ${new Date().getTime() - decryptStartTime}ms`,
|
||||
);
|
||||
// Split ciphers into two arrays, one for successfully decrypted ciphers and one for ciphers that failed to decrypt
|
||||
return allCipherViews.reduce(
|
||||
(acc, c) => {
|
||||
if (c.decryptionFailure) {
|
||||
acc[1].push(c);
|
||||
} else {
|
||||
acc[0].push(c);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
[[], []] as [CipherView[], CipherView[]],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -487,7 +487,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
* @param userId The user ID to use for decryption.
|
||||
* @returns A promise that resolves to the decrypted cipher view.
|
||||
*/
|
||||
async decryptCipherWithSdkOrLegacy(cipher: Cipher, userId: UserId): Promise<CipherView> {
|
||||
async decrypt(cipher: Cipher, userId: UserId): Promise<CipherView> {
|
||||
if (await this.configService.getFeatureFlag(FeatureFlag.PM19941MigrateCipherDomainToSdk)) {
|
||||
return await this.cipherEncryptionService.decrypt(cipher, userId);
|
||||
} else {
|
||||
@@ -907,7 +907,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
//then we rollback to using the user key as the main key of encryption of the item
|
||||
//in order to keep item and it's attachments with the same encryption level
|
||||
if (cipher.key != null && !cipherKeyEncryptionEnabled) {
|
||||
const model = await this.decryptCipherWithSdkOrLegacy(cipher, userId);
|
||||
const model = await this.decrypt(cipher, userId);
|
||||
cipher = await this.encrypt(model, userId);
|
||||
await this.updateWithServer(cipher);
|
||||
}
|
||||
@@ -1438,7 +1438,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
originalCipher: Cipher,
|
||||
userId: UserId,
|
||||
): Promise<void> {
|
||||
const existingCipher = await this.decryptCipherWithSdkOrLegacy(originalCipher, userId);
|
||||
const existingCipher = await this.decrypt(originalCipher, userId);
|
||||
model.passwordHistory = existingCipher.passwordHistory || [];
|
||||
if (model.type === CipherType.Login && existingCipher.type === CipherType.Login) {
|
||||
if (
|
||||
|
||||
@@ -212,7 +212,6 @@ describe("DefaultCipherEncryptionService", () => {
|
||||
);
|
||||
expect(mockSdkClient.vault().ciphers().decrypt_fido2_private_key).toHaveBeenCalledWith(
|
||||
sdkCipherView,
|
||||
fido2Credentials[0].keyValue,
|
||||
);
|
||||
expect(Fido2CredentialView.fromSdkFido2CredentialView).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -43,15 +43,14 @@ export class DefaultCipherEncryptionService implements CipherEncryptionService {
|
||||
.ciphers()
|
||||
.decrypt_fido2_credentials(sdkCipherView);
|
||||
|
||||
// TEMPORARY: Manually decrypt the keyValue for Fido2 credentials since don't currently use the SDK for Fido2 Authentication.
|
||||
const decryptedKeyValue = ref.value
|
||||
.vault()
|
||||
.ciphers()
|
||||
.decrypt_fido2_private_key(sdkCipherView);
|
||||
|
||||
clientCipherView.login.fido2Credentials = fido2CredentialViews
|
||||
.map((f) => {
|
||||
// TEMPORARY: Manually decrypt the keyValue for Fido2 credentials since don't currently use
|
||||
// the SDK for Fido2 Authentication.
|
||||
const decryptedKeyValue = ref.value
|
||||
.vault()
|
||||
.ciphers()
|
||||
.decrypt_fido2_private_key(sdkCipherView, f.keyValue);
|
||||
|
||||
const view = Fido2CredentialView.fromSdkFido2CredentialView(f)!;
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user