1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 02:03:39 +00:00

[PM-22136] Implement SDK cipher encryption (#15337)

* [PM-22136] Update sdk cipher view map to support uknown uuid type

* [PM-22136] Add key to CipherView for copying to SdkCipherView for encryption

* [PM-22136] Add fromSdk* helpers to Cipher domain objects

* [PM-22136] Add toSdk* helpers to Cipher View objects

* [PM-22136] Add encrypt() to cipher encryption service

* [PM-22136] Add feature flag

* [PM-22136] Use new SDK encrypt method when feature flag is enabled

* [PM-22136] Filter out null/empty URIs

* [PM-22136] Change default value for cipher view arrays to []. See ADR-0014.

* [PM-22136] Keep encrypted key value on attachment so that it is passed to the SDK

* [PM-22136] Keep encrypted key value on CipherView so that it is passed to the SDK during encryption

* [PM-22136] Update failing attachment test

* [PM-22136] Update failing importer tests due to new default value for arrays

* [PM-22136] Update CipherView.fromJson to handle the prototype of EncString for the cipher key

* [PM-22136] Add tickets for followup work

* [PM-22136] Use new set_fido2_credentials SDK method instead

* [PM-22136] Fix missing prototype when decrypting Fido2Credentials

* [PM-22136] Fix test after sdk change

* [PM-22136] Update @bitwarden/sdk-internal version

* [PM-22136] Fix some strict typing errors

* [PM-23348] Migrate move cipher to org to SDK (#15567)

* [PM-23348] Add moveToOrganization method to cipher-encryption.service.ts

* [PM-23348] Use cipherEncryptionService.moveToOrganization in cipherService shareWithServer and shareManyWithServer methods

* [PM-23348] Update cipherFormService to use the shareWithServer() method instead of encrypt()

* [PM-23348] Fix typo

* [PM-23348] Add missing docs

* [PM-22136] Fix EncString import after merge with main
This commit is contained in:
Shane Melton
2025-07-21 23:27:01 -07:00
committed by GitHub
parent 81ee26733e
commit 391f540d1f
43 changed files with 1485 additions and 149 deletions

View File

@@ -5,7 +5,7 @@ import { firstValueFrom, map } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { UserId } from "@bitwarden/common/types/guid";
import { UserId, OrganizationId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CipherType } from "@bitwarden/common/vault/enums";
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
@@ -31,21 +31,13 @@ export class DefaultCipherFormService implements CipherFormService {
}
async saveCipher(cipher: CipherView, config: CipherFormConfig): Promise<CipherView> {
// Passing the original cipher is important here as it is responsible for appending to password history
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
const encrypted = await this.cipherService.encrypt(
cipher,
activeUserId,
null,
null,
config.originalCipher ?? null,
);
const encryptedCipher = encrypted.cipher;
let savedCipher: Cipher;
// Creating a new cipher
if (cipher.id == null) {
const encrypted = await this.cipherService.encrypt(cipher, activeUserId);
savedCipher = await this.cipherService.createWithServer(encrypted, config.admin);
return await this.cipherService.decrypt(savedCipher, activeUserId);
}
@@ -61,16 +53,37 @@ export class DefaultCipherFormService implements CipherFormService {
// Call shareWithServer if the owner is changing from a user to an organization
if (config.originalCipher.organizationId === null && cipher.organizationId != null) {
// shareWithServer expects the cipher to have no organizationId set
const organizationId = cipher.organizationId as OrganizationId;
cipher.organizationId = null;
savedCipher = await this.cipherService.shareWithServer(
cipher,
cipher.organizationId,
organizationId,
cipher.collectionIds,
activeUserId,
config.originalCipher,
);
// If the collectionIds are the same, update the cipher normally
} else if (isSetEqual(originalCollectionIds, newCollectionIds)) {
const encrypted = await this.cipherService.encrypt(
cipher,
activeUserId,
null,
null,
config.originalCipher,
);
savedCipher = await this.cipherService.updateWithServer(encrypted, config.admin);
} else {
const encrypted = await this.cipherService.encrypt(
cipher,
activeUserId,
null,
null,
config.originalCipher,
);
const encryptedCipher = encrypted.cipher;
// Updating a cipher with collection changes is not supported with a single request currently
// First update the cipher with the original collectionIds
encryptedCipher.collectionIds = config.originalCipher.collectionIds;

View File

@@ -67,12 +67,12 @@
</ng-container>
<!-- CUSTOM FIELDS -->
<ng-container *ngIf="cipher.fields">
<ng-container *ngIf="cipher.hasFields">
<app-custom-fields-v2 [cipher]="cipher"> </app-custom-fields-v2>
</ng-container>
<!-- ATTACHMENTS SECTION -->
<ng-container *ngIf="cipher.attachments">
<ng-container *ngIf="cipher.hasAttachments">
<app-attachments-v2-view
[emergencyAccessId]="emergencyAccessId"
[cipher]="cipher"

View File

@@ -9,6 +9,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CipherType } from "@bitwarden/common/vault/enums";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { PasswordHistoryView } from "@bitwarden/common/vault/models/view/password-history.view";
import { ColorPasswordComponent, ColorPasswordModule, ItemModule } from "@bitwarden/components";
import { PasswordHistoryViewComponent } from "./password-history-view.component";
@@ -54,8 +55,14 @@ describe("PasswordHistoryViewComponent", () => {
});
describe("history", () => {
const password1 = { password: "bad-password-1", lastUsedDate: new Date("09/13/2004") };
const password2 = { password: "bad-password-2", lastUsedDate: new Date("02/01/2004") };
const password1 = {
password: "bad-password-1",
lastUsedDate: new Date("09/13/2004"),
} as PasswordHistoryView;
const password2 = {
password: "bad-password-2",
lastUsedDate: new Date("02/01/2004"),
} as PasswordHistoryView;
beforeEach(async () => {
mockCipher.passwordHistory = [password1, password2];