mirror of
https://github.com/bitwarden/browser
synced 2026-02-25 00:53:22 +00:00
Merge branch 'km/encstring-remove-decrypt-vault' into km/decrypt-obj
This commit is contained in:
@@ -186,15 +186,15 @@ export class EditCommand {
|
||||
return Response.notFound();
|
||||
}
|
||||
|
||||
let folderView = await folder.decrypt();
|
||||
const userKey = await firstValueFrom(this.keyService.userKey$(activeUserId));
|
||||
let folderView = await folder.decrypt(userKey);
|
||||
folderView = FolderExport.toView(req, folderView);
|
||||
|
||||
const userKey = await this.keyService.getUserKey(activeUserId);
|
||||
const encFolder = await this.folderService.encrypt(folderView, userKey);
|
||||
try {
|
||||
const folder = await this.folderApiService.save(encFolder, activeUserId);
|
||||
const updatedFolder = new Folder(folder);
|
||||
const decFolder = await updatedFolder.decrypt();
|
||||
const decFolder = await updatedFolder.decrypt(userKey);
|
||||
const res = new FolderResponse(decFolder);
|
||||
return Response.success(res);
|
||||
} catch (e) {
|
||||
|
||||
@@ -417,10 +417,11 @@ export class GetCommand extends DownloadCommand {
|
||||
private async getFolder(id: string) {
|
||||
let decFolder: FolderView = null;
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const userKey = await firstValueFrom(this.keyService.userKey$(activeUserId));
|
||||
if (Utils.isGuid(id)) {
|
||||
const folder = await this.folderService.getFromState(id, activeUserId);
|
||||
if (folder != null) {
|
||||
decFolder = await folder.decrypt();
|
||||
decFolder = await folder.decrypt(userKey);
|
||||
}
|
||||
} else if (id.trim() !== "") {
|
||||
let folders = await this.folderService.getAllDecryptedFromState(activeUserId);
|
||||
|
||||
@@ -181,12 +181,12 @@ export class CreateCommand {
|
||||
|
||||
private async createFolder(req: FolderExport) {
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const userKey = await this.keyService.getUserKey(activeUserId);
|
||||
const userKey = await firstValueFrom(this.keyService.userKey$(activeUserId));
|
||||
const folder = await this.folderService.encrypt(FolderExport.toView(req), userKey);
|
||||
try {
|
||||
const folderData = await this.folderApiService.save(folder, activeUserId);
|
||||
const newFolder = new Folder(folderData);
|
||||
const decFolder = await newFolder.decrypt();
|
||||
const decFolder = await newFolder.decrypt(userKey);
|
||||
const res = new FolderResponse(decFolder);
|
||||
return Response.success(res);
|
||||
} catch (e) {
|
||||
|
||||
@@ -39,6 +39,8 @@ import { IdentityView } from "../../models/view/identity.view";
|
||||
import { LoginView } from "../../models/view/login.view";
|
||||
import { CipherPermissionsApi } from "../api/cipher-permissions.api";
|
||||
|
||||
const mockSymmetricKey = new SymmetricCryptoKey(makeStaticByteArray(64));
|
||||
|
||||
describe("Cipher DTO", () => {
|
||||
it("Convert from empty CipherData", () => {
|
||||
const data = new CipherData();
|
||||
@@ -100,6 +102,9 @@ describe("Cipher DTO", () => {
|
||||
const cipherService = mock<CipherService>();
|
||||
|
||||
encryptService.unwrapSymmetricKey.mockRejectedValue(new Error("Failed to unwrap key"));
|
||||
cipherService.getKeyForCipherKeyDecryption.mockResolvedValue(
|
||||
new SymmetricCryptoKey(makeStaticByteArray(64)),
|
||||
);
|
||||
|
||||
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
|
||||
|
||||
@@ -319,7 +324,6 @@ describe("Cipher DTO", () => {
|
||||
|
||||
const keyService = mock<KeyService>();
|
||||
const encryptService = mock<EncryptService>();
|
||||
const cipherService = mock<CipherService>();
|
||||
|
||||
encryptService.unwrapSymmetricKey.mockResolvedValue(
|
||||
new SymmetricCryptoKey(makeStaticByteArray(64)),
|
||||
@@ -327,9 +331,7 @@ describe("Cipher DTO", () => {
|
||||
|
||||
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
|
||||
|
||||
const cipherView = await cipher.decrypt(
|
||||
await cipherService.getKeyForCipherKeyDecryption(cipher, mockUserId),
|
||||
);
|
||||
const cipherView = await cipher.decrypt(mockSymmetricKey);
|
||||
|
||||
expect(cipherView).toMatchObject({
|
||||
id: "id",
|
||||
@@ -447,7 +449,6 @@ describe("Cipher DTO", () => {
|
||||
|
||||
const keyService = mock<KeyService>();
|
||||
const encryptService = mock<EncryptService>();
|
||||
const cipherService = mock<CipherService>();
|
||||
|
||||
encryptService.unwrapSymmetricKey.mockResolvedValue(
|
||||
new SymmetricCryptoKey(makeStaticByteArray(64)),
|
||||
@@ -455,9 +456,7 @@ describe("Cipher DTO", () => {
|
||||
|
||||
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
|
||||
|
||||
const cipherView = await cipher.decrypt(
|
||||
await cipherService.getKeyForCipherKeyDecryption(cipher, mockUserId),
|
||||
);
|
||||
const cipherView = await cipher.decrypt(mockSymmetricKey);
|
||||
|
||||
expect(cipherView).toMatchObject({
|
||||
id: "id",
|
||||
@@ -593,7 +592,6 @@ describe("Cipher DTO", () => {
|
||||
|
||||
const keyService = mock<KeyService>();
|
||||
const encryptService = mock<EncryptService>();
|
||||
const cipherService = mock<CipherService>();
|
||||
|
||||
encryptService.unwrapSymmetricKey.mockResolvedValue(
|
||||
new SymmetricCryptoKey(makeStaticByteArray(64)),
|
||||
@@ -601,9 +599,7 @@ describe("Cipher DTO", () => {
|
||||
|
||||
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
|
||||
|
||||
const cipherView = await cipher.decrypt(
|
||||
await cipherService.getKeyForCipherKeyDecryption(cipher, mockUserId),
|
||||
);
|
||||
const cipherView = await cipher.decrypt(mockSymmetricKey);
|
||||
|
||||
expect(cipherView).toMatchObject({
|
||||
id: "id",
|
||||
@@ -763,7 +759,6 @@ describe("Cipher DTO", () => {
|
||||
|
||||
const keyService = mock<KeyService>();
|
||||
const encryptService = mock<EncryptService>();
|
||||
const cipherService = mock<CipherService>();
|
||||
|
||||
encryptService.unwrapSymmetricKey.mockResolvedValue(
|
||||
new SymmetricCryptoKey(makeStaticByteArray(64)),
|
||||
@@ -771,9 +766,7 @@ describe("Cipher DTO", () => {
|
||||
|
||||
(window as any).bitwardenContainerService = new ContainerService(keyService, encryptService);
|
||||
|
||||
const cipherView = await cipher.decrypt(
|
||||
await cipherService.getKeyForCipherKeyDecryption(cipher, mockUserId),
|
||||
);
|
||||
const cipherView = await cipher.decrypt(mockSymmetricKey);
|
||||
|
||||
expect(cipherView).toMatchObject({
|
||||
id: "id",
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("Folder", () => {
|
||||
folder.name = mockEnc("encName");
|
||||
folder.revisionDate = new Date("2022-01-31T12:00:00.000Z");
|
||||
|
||||
const view = await folder.decrypt();
|
||||
const view = await folder.decrypt(null);
|
||||
|
||||
expect(view).toEqual({
|
||||
id: "id",
|
||||
|
||||
@@ -39,8 +39,8 @@ export class Folder extends Domain {
|
||||
this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;
|
||||
}
|
||||
|
||||
decrypt(): Promise<FolderView> {
|
||||
return this.decryptObj<Folder, FolderView>(this, new FolderView(this), ["name"], null);
|
||||
decrypt(key: SymmetricCryptoKey): Promise<FolderView> {
|
||||
return this.decryptObj<Folder, FolderView>(this, new FolderView(this), ["name"], null, key);
|
||||
}
|
||||
|
||||
async decryptWithKey(
|
||||
|
||||
@@ -1533,10 +1533,15 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
}
|
||||
|
||||
async getKeyForCipherKeyDecryption(cipher: Cipher, userId: UserId): Promise<UserKey | OrgKey> {
|
||||
return (
|
||||
(await this.keyService.getOrgKey(cipher.organizationId)) ||
|
||||
((await this.keyService.getUserKey(userId)) as UserKey)
|
||||
);
|
||||
if (cipher.organizationId == null) {
|
||||
return await firstValueFrom(this.keyService.userKey$(userId));
|
||||
} else {
|
||||
return await firstValueFrom(
|
||||
this.keyService
|
||||
.orgKeys$(userId)
|
||||
.pipe(map((orgKeys) => orgKeys[cipher.organizationId as OrganizationId] as OrgKey)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async setAddEditCipherInfo(value: AddEditCipherInfo, userId: UserId) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
} from "@bitwarden/common/models/export";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { OrganizationId, UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
@@ -45,6 +45,7 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
}
|
||||
|
||||
async parse(data: string): Promise<ImportResult> {
|
||||
const account = await firstValueFrom(this.accountService.activeAccount$);
|
||||
this.result = new ImportResult();
|
||||
const results: BitwardenJsonExport = JSON.parse(data);
|
||||
if (results == null || results.items == null) {
|
||||
@@ -53,9 +54,9 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
}
|
||||
|
||||
if (results.encrypted) {
|
||||
await this.parseEncrypted(results as any);
|
||||
await this.parseEncrypted(results as any, account.id);
|
||||
} else {
|
||||
await this.parseDecrypted(results as any);
|
||||
await this.parseDecrypted(results as any, account.id);
|
||||
}
|
||||
|
||||
return this.result;
|
||||
@@ -63,14 +64,13 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
|
||||
private async parseEncrypted(
|
||||
results: BitwardenEncryptedIndividualJsonExport | BitwardenEncryptedOrgJsonExport,
|
||||
userId: UserId,
|
||||
) {
|
||||
const account = await firstValueFrom(this.accountService.activeAccount$);
|
||||
|
||||
if (results.encKeyValidation_DO_NOT_EDIT != null) {
|
||||
const orgKeys = await firstValueFrom(this.keyService.orgKeys$(account.id));
|
||||
const orgKeys = await firstValueFrom(this.keyService.orgKeys$(userId));
|
||||
let keyForDecryption: SymmetricCryptoKey = orgKeys?.[this.organizationId];
|
||||
if (keyForDecryption == null) {
|
||||
keyForDecryption = await firstValueFrom(this.keyService.userKey$(account.id));
|
||||
keyForDecryption = await firstValueFrom(this.keyService.userKey$(userId));
|
||||
}
|
||||
const encKeyValidation = new EncString(results.encKeyValidation_DO_NOT_EDIT);
|
||||
try {
|
||||
@@ -84,7 +84,7 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
|
||||
const groupingsMap = this.organization
|
||||
? await this.parseCollections(results as BitwardenEncryptedOrgJsonExport)
|
||||
: await this.parseFolders(results as BitwardenEncryptedIndividualJsonExport);
|
||||
: await this.parseFolders(results as BitwardenEncryptedIndividualJsonExport, userId);
|
||||
|
||||
for (const c of results.items) {
|
||||
const cipher = CipherWithIdExport.toDomain(c);
|
||||
@@ -114,7 +114,7 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
});
|
||||
}
|
||||
|
||||
const view = await this.cipherService.decrypt(cipher, account.id);
|
||||
const view = await this.cipherService.decrypt(cipher, userId);
|
||||
this.cleanupCipher(view);
|
||||
this.result.ciphers.push(view);
|
||||
}
|
||||
@@ -124,10 +124,11 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
|
||||
private async parseDecrypted(
|
||||
results: BitwardenUnEncryptedIndividualJsonExport | BitwardenUnEncryptedOrgJsonExport,
|
||||
userId: UserId,
|
||||
) {
|
||||
const groupingsMap = this.organization
|
||||
? await this.parseCollections(results as BitwardenUnEncryptedOrgJsonExport)
|
||||
: await this.parseFolders(results as BitwardenUnEncryptedIndividualJsonExport);
|
||||
: await this.parseFolders(results as BitwardenUnEncryptedIndividualJsonExport, userId);
|
||||
|
||||
results.items.forEach((c) => {
|
||||
const cipher = CipherWithIdExport.toView(c);
|
||||
@@ -166,11 +167,14 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
|
||||
private async parseFolders(
|
||||
data: BitwardenUnEncryptedIndividualJsonExport | BitwardenEncryptedIndividualJsonExport,
|
||||
userId: UserId,
|
||||
): Promise<Map<string, number>> | null {
|
||||
if (data.folders == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const userKey = await firstValueFrom(this.keyService.userKey$(userId));
|
||||
|
||||
const groupingsMap = new Map<string, number>();
|
||||
|
||||
for (const f of data.folders) {
|
||||
@@ -178,7 +182,7 @@ export class BitwardenJsonImporter extends BaseImporter implements Importer {
|
||||
if (data.encrypted) {
|
||||
const folder = FolderWithIdExport.toDomain(f);
|
||||
if (folder != null) {
|
||||
folderView = await folder.decrypt();
|
||||
folderView = await folder.decrypt(userKey);
|
||||
}
|
||||
} else {
|
||||
folderView = FolderWithIdExport.toView(f);
|
||||
|
||||
Reference in New Issue
Block a user