1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 16:53:34 +00:00

[PM-13374] Update all SDK uuids (#14962)

* fix: broken SDK interface

* Fix all compile errors related to uuids

* Fix browser desktop

* Fix tests

---------

Co-authored-by: Andreas Coroiu <andreas.coroiu@gmail.com>
This commit is contained in:
Oscar Hinton
2025-08-29 19:09:33 +02:00
committed by GitHub
parent d57d653551
commit e0da2671b4
31 changed files with 133 additions and 93 deletions

View File

@@ -849,9 +849,9 @@ describe("Cipher DTO", () => {
const lastLaunched = new Date("2025-04-15T12:00:00.000Z").getTime();
const cipherData: CipherData = {
id: "id",
organizationId: "orgId",
folderId: "folderId",
id: "2afb03fd-0d8e-4c08-a316-18b2f0efa618",
organizationId: "4748ad12-212e-4bc8-82b7-a75f6709d033",
folderId: "b4dac811-e44a-495a-9334-9e53b7aaf54c",
edit: true,
permissions: new CipherPermissionsApi(),
viewPassword: true,
@@ -920,9 +920,9 @@ describe("Cipher DTO", () => {
const sdkCipher = cipher.toSdkCipher();
expect(sdkCipher).toEqual({
id: "id",
organizationId: "orgId",
folderId: "folderId",
id: "2afb03fd-0d8e-4c08-a316-18b2f0efa618",
organizationId: "4748ad12-212e-4bc8-82b7-a75f6709d033",
folderId: "b4dac811-e44a-495a-9334-9e53b7aaf54c",
collectionIds: [],
key: "EncryptedString",
name: "EncryptedString",
@@ -1007,9 +1007,9 @@ describe("Cipher DTO", () => {
it("should map from SDK Cipher", () => {
jest.restoreAllMocks();
const sdkCipher: SdkCipher = {
id: "id",
organizationId: "orgId",
folderId: "folderId",
id: "id" as any,
organizationId: "orgId" as any,
folderId: "folderId" as any,
collectionIds: [],
key: "EncryptedString" as SdkEncString,
name: "EncryptedString" as SdkEncString,

View File

@@ -2,10 +2,10 @@
// @ts-strict-ignore
import { Jsonify } from "type-fest";
import { uuidToString } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
import { Cipher as SdkCipher } from "@bitwarden/sdk-internal";
import { EncString } from "../../../key-management/crypto/models/enc-string";
import { asUuid, uuidAsString } from "../../../platform/abstractions/sdk/sdk.service";
import { Decryptable } from "../../../platform/interfaces/decryptable.interface";
import { Utils } from "../../../platform/misc/utils";
import Domain from "../../../platform/models/domain/domain-base";
@@ -344,10 +344,10 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
*/
toSdkCipher(): SdkCipher {
const sdkCipher: SdkCipher = {
id: this.id,
organizationId: this.organizationId ?? undefined,
folderId: this.folderId ?? undefined,
collectionIds: this.collectionIds ?? [],
id: asUuid(this.id),
organizationId: this.organizationId ? asUuid(this.organizationId) : undefined,
folderId: this.folderId ? asUuid(this.folderId) : undefined,
collectionIds: this.collectionIds ? this.collectionIds.map(asUuid) : ([] as any),
key: this.key?.toSdk(),
name: this.name.toSdk(),
notes: this.notes?.toSdk(),
@@ -412,12 +412,12 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
const cipher = new Cipher();
cipher.id = sdkCipher.id ? uuidToString(sdkCipher.id) : undefined;
cipher.id = sdkCipher.id ? uuidAsString(sdkCipher.id) : undefined;
cipher.organizationId = sdkCipher.organizationId
? uuidToString(sdkCipher.organizationId)
? uuidAsString(sdkCipher.organizationId)
: undefined;
cipher.folderId = sdkCipher.folderId ? uuidToString(sdkCipher.folderId) : undefined;
cipher.collectionIds = sdkCipher.collectionIds ? sdkCipher.collectionIds.map(uuidToString) : [];
cipher.folderId = sdkCipher.folderId ? uuidAsString(sdkCipher.folderId) : undefined;
cipher.collectionIds = sdkCipher.collectionIds ? sdkCipher.collectionIds.map(uuidAsString) : [];
cipher.key = EncString.fromJSON(sdkCipher.key);
cipher.name = EncString.fromJSON(sdkCipher.name);
cipher.notes = EncString.fromJSON(sdkCipher.notes);

View File

@@ -14,6 +14,7 @@ import {
} from "@bitwarden/sdk-internal";
import { mockFromJson, mockFromSdk } from "../../../../spec";
import { asUuid } from "../../../platform/abstractions/sdk/sdk.service";
import { CipherRepromptType } from "../../enums";
import { CipherType } from "../../enums/cipher-type";
@@ -123,10 +124,10 @@ describe("CipherView", () => {
jest.spyOn(FieldView, "fromSdkFieldView").mockImplementation(mockFromSdk);
sdkCipherView = {
id: "id",
organizationId: "orgId",
folderId: "folderId",
collectionIds: ["collectionId"],
id: "id" as any,
organizationId: "orgId" as any,
folderId: "folderId" as any,
collectionIds: ["collectionId" as any],
key: undefined,
name: "name",
notes: undefined,
@@ -260,11 +261,11 @@ describe("CipherView", () => {
const sdkCipherView = cipherView.toSdkCipherView();
expect(sdkCipherView).toMatchObject({
id: "0a54d80c-14aa-4ef8-8c3a-7ea99ce5b602",
organizationId: "000f2a6e-da5e-4726-87ed-1c5c77322c3c",
folderId: "41b22db4-8e2a-4ed2-b568-f1186c72922f",
collectionIds: ["b0473506-3c3c-4260-a734-dfaaf833ab6f"],
key: "some-key",
id: asUuid("0a54d80c-14aa-4ef8-8c3a-7ea99ce5b602"),
organizationId: asUuid("000f2a6e-da5e-4726-87ed-1c5c77322c3c"),
folderId: asUuid("41b22db4-8e2a-4ed2-b568-f1186c72922f"),
collectionIds: [asUuid("b0473506-3c3c-4260-a734-dfaaf833ab6f")],
key: "some-key" as any,
name: "name",
notes: "notes",
type: SdkCipherType.Login,

View File

@@ -1,7 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
import { uuidToString, asUuid } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
import { asUuid, uuidAsString } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
import { CipherView as SdkCipherView } from "@bitwarden/sdk-internal";
import { View } from "../../../models/view/view";
@@ -256,9 +256,9 @@ export class CipherView implements View, InitializerMetadata {
}
const cipherView = new CipherView();
cipherView.id = uuidToString(obj.id) ?? null;
cipherView.organizationId = uuidToString(obj.organizationId) ?? null;
cipherView.folderId = uuidToString(obj.folderId) ?? null;
cipherView.id = uuidAsString(obj.id) ?? null;
cipherView.organizationId = uuidAsString(obj.organizationId) ?? null;
cipherView.folderId = uuidAsString(obj.folderId) ?? null;
cipherView.name = obj.name;
cipherView.notes = obj.notes ?? null;
cipherView.type = obj.type;
@@ -273,7 +273,7 @@ export class CipherView implements View, InitializerMetadata {
cipherView.fields = obj.fields?.map((f) => FieldView.fromSdkFieldView(f)) ?? [];
cipherView.passwordHistory =
obj.passwordHistory?.map((ph) => PasswordHistoryView.fromSdkPasswordHistoryView(ph)) ?? [];
cipherView.collectionIds = obj.collectionIds?.map((i) => uuidToString(i)) ?? [];
cipherView.collectionIds = obj.collectionIds?.map((i) => uuidAsString(i)) ?? [];
cipherView.revisionDate = obj.revisionDate == null ? null : new Date(obj.revisionDate);
cipherView.creationDate = obj.creationDate == null ? null : new Date(obj.creationDate);
cipherView.deletedDate = obj.deletedDate == null ? null : new Date(obj.deletedDate);
@@ -325,7 +325,7 @@ export class CipherView implements View, InitializerMetadata {
attachments: this.attachments?.map((a) => a.toSdkAttachmentView()),
fields: this.fields?.map((f) => f.toSdkFieldView()),
passwordHistory: this.passwordHistory?.map((ph) => ph.toSdkPasswordHistoryView()),
collectionIds: this.collectionIds?.map((i) => i) ?? [],
collectionIds: this.collectionIds?.map((i) => asUuid(i)) ?? [],
// Revision and creation dates are non-nullable in SDKCipherView
revisionDate: (this.revisionDate ?? new Date()).toISOString(),
creationDate: (this.creationDate ?? new Date()).toISOString(),

View File

@@ -8,6 +8,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
import { getByIds } from "@bitwarden/common/platform/misc";
import { getUserId } from "../../auth/services/account.service";
import { uuidAsString } from "../../platform/abstractions/sdk/sdk.service";
import { CipherLike } from "../types/cipher-like";
/**
@@ -140,7 +141,7 @@ export class DefaultCipherAuthorizationService implements CipherAuthorizationSer
}
return this.collectionService.decryptedCollections$(userId).pipe(
getByIds(cipher.collectionIds),
getByIds(cipher.collectionIds.map(uuidAsString)),
map((allCollections) => allCollections.some((collection) => collection.manage)),
);
}),

View File

@@ -31,6 +31,7 @@ import { ListResponse } from "../../models/response/list.response";
import { View } from "../../models/view/view";
import { ConfigService } from "../../platform/abstractions/config/config.service";
import { I18nService } from "../../platform/abstractions/i18n.service";
import { uuidAsString } from "../../platform/abstractions/sdk/sdk.service";
import { Utils } from "../../platform/misc/utils";
import Domain from "../../platform/models/domain/domain-base";
import { EncArrayBuffer } from "../../platform/models/domain/enc-array-buffer";
@@ -2035,7 +2036,7 @@ export class CipherService implements CipherServiceAbstraction {
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
);
const cipher = await this.get(c.id!, activeUserId);
const cipher = await this.get(uuidAsString(c.id!), activeUserId);
return this.decrypt(cipher, activeUserId);
}

View File

@@ -124,15 +124,15 @@ describe("DefaultCipherEncryptionService", () => {
cipherViewObj = new CipherView(cipherObj);
jest.spyOn(cipherObj, "toSdkCipher").mockImplementation(() => {
return { id: cipherData.id } as SdkCipher;
return { id: cipherData.id as any } as SdkCipher;
});
jest.spyOn(cipherViewObj, "toSdkCipherView").mockImplementation(() => {
return { id: cipherData.id } as SdkCipherView;
return { id: cipherData.id as any } as SdkCipherView;
});
sdkCipherView = {
id: cipherId as string,
id: cipherId as any,
type: SdkCipherType.Login,
name: "test-name",
login: {
@@ -334,7 +334,7 @@ describe("DefaultCipherEncryptionService", () => {
.vault()
.ciphers()
.set_fido2_credentials.mockReturnValue({
id: cipherId as string,
id: cipherId as any,
login: {
fido2Credentials: [mockSdkCredentialView],
},
@@ -519,8 +519,8 @@ describe("DefaultCipherEncryptionService", () => {
const ciphers = [new Cipher(cipherData), new Cipher(cipherData)];
const expectedListViews = [
{ id: "list1", name: "List 1" } as CipherListView,
{ id: "list2", name: "List 2" } as CipherListView,
{ id: "list1" as any, name: "List 1" } as CipherListView,
{ id: "list2" as any, name: "List 2" } as CipherListView,
];
mockSdkClient.vault().ciphers().decrypt_list.mockReturnValue(expectedListViews);
@@ -554,7 +554,7 @@ describe("DefaultCipherEncryptionService", () => {
const encryptedContent = new Uint8Array([1, 2, 3, 4]);
const expectedDecryptedContent = new Uint8Array([5, 6, 7, 8]);
jest.spyOn(cipher, "toSdkCipher").mockReturnValue({ id: "id" } as SdkCipher);
jest.spyOn(cipher, "toSdkCipher").mockReturnValue({ id: "id" as any } as SdkCipher);
jest
.spyOn(attachment, "toSdkAttachmentView")
.mockReturnValue({ id: "a1" } as SdkAttachmentView);

View File

@@ -9,7 +9,7 @@ import {
} from "@bitwarden/sdk-internal";
import { LogService } from "../../platform/abstractions/log.service";
import { SdkService, asUuid } from "../../platform/abstractions/sdk/sdk.service";
import { SdkService, asUuid, uuidAsString } from "../../platform/abstractions/sdk/sdk.service";
import { UserId, OrganizationId } from "../../types/guid";
import { CipherEncryptionService } from "../abstractions/cipher-encryption.service";
import { CipherType } from "../enums";
@@ -39,7 +39,7 @@ export class DefaultCipherEncryptionService implements CipherEncryptionService {
return {
cipher: Cipher.fromSdkCipher(encryptionContext.cipher)!,
encryptedFor: asUuid<UserId>(encryptionContext.encryptedFor),
encryptedFor: uuidAsString(encryptionContext.encryptedFor) as UserId,
};
}),
catchError((error: unknown) => {
@@ -74,7 +74,7 @@ export class DefaultCipherEncryptionService implements CipherEncryptionService {
return {
cipher: Cipher.fromSdkCipher(encryptionContext.cipher)!,
encryptedFor: asUuid<UserId>(encryptionContext.encryptedFor),
encryptedFor: uuidAsString(encryptionContext.encryptedFor) as UserId,
};
}),
catchError((error: unknown) => {
@@ -107,7 +107,7 @@ export class DefaultCipherEncryptionService implements CipherEncryptionService {
return {
cipher: Cipher.fromSdkCipher(encryptionContext.cipher)!,
encryptedFor: asUuid<UserId>(encryptionContext.encryptedFor),
encryptedFor: uuidAsString(encryptionContext.encryptedFor) as UserId,
};
}),
catchError((error: unknown) => {

View File

@@ -10,6 +10,7 @@ import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CipherType } from "@bitwarden/common/vault/enums";
import { uuidAsString } from "../../platform/abstractions/sdk/sdk.service";
import { CipherLike } from "../types/cipher-like";
import { CipherViewLikeUtils } from "../utils/cipher-view-like-utils";
@@ -108,7 +109,7 @@ export class RestrictedItemTypesService {
// If cipher belongs to an organization
if (cipher.organizationId) {
// Check if this organization allows viewing this cipher type
return !restriction.allowViewOrgIds.includes(cipher.organizationId);
return !restriction.allowViewOrgIds.includes(uuidAsString(cipher.organizationId));
}
// Cipher is restricted by at least one organization, restrict it

View File

@@ -9,6 +9,7 @@ import { perUserCache$ } from "@bitwarden/common/vault/utils/observable-utilitie
import { UriMatchStrategy } from "../../models/domain/domain-service";
import { I18nService } from "../../platform/abstractions/i18n.service";
import { LogService } from "../../platform/abstractions/log.service";
import { uuidAsString } from "../../platform/abstractions/sdk/sdk.service";
import {
SingleUserState,
StateProvider,
@@ -261,7 +262,7 @@ export class SearchService implements SearchServiceAbstraction {
}
const ciphersMap = new Map<string, C>();
ciphers.forEach((c) => ciphersMap.set(c.id, c));
ciphers.forEach((c) => ciphersMap.set(uuidAsString(c.id), c));
let searchResults: lunr.Index.Result[] = null;
const isQueryString = query != null && query.length > 1 && query.indexOf(">") === 0;
@@ -304,7 +305,7 @@ export class SearchService implements SearchServiceAbstraction {
if (c.name != null && c.name.toLowerCase().indexOf(query) > -1) {
return true;
}
if (query.length >= 8 && c.id.startsWith(query)) {
if (query.length >= 8 && uuidAsString(c.id).startsWith(query)) {
return true;
}
const subtitle = CipherViewLikeUtils.subtitle(c);

View File

@@ -175,13 +175,13 @@ describe("CipherViewLikeUtils", () => {
});
it("returns false when the cipher is assigned to an organization and cannot be edited", () => {
cipherListView.organizationId = "org-id";
cipherListView.organizationId = "org-id" as any;
expect(CipherViewLikeUtils.canAssignToCollections(cipherListView)).toBe(false);
});
it("returns true when the cipher is assigned to an organization and can be edited", () => {
cipherListView.organizationId = "org-id";
cipherListView.organizationId = "org-id" as any;
cipherListView.edit = true;
cipherListView.viewPassword = true;