diff --git a/libs/importer/spec/test-data/bitwarden-json/cipher-with-collections.json.ts b/libs/importer/spec/test-data/bitwarden-json/cipher-with-collections.json.ts new file mode 100644 index 0000000000..ef92ea7984 --- /dev/null +++ b/libs/importer/spec/test-data/bitwarden-json/cipher-with-collections.json.ts @@ -0,0 +1,37 @@ +export const cipherWithCollections = `{ + "encrypted": false, + "collections": [ + { + "id": "8e3f5ba1-3e87-4ee8-8da9-b1180099ff9f", + "organizationId": "c6181652-66eb-4cd9-a7f2-b02a00e12352", + "name": "asdf", + "externalId": null + } + ], + "items": [ + { + "passwordHistory": null, + "revisionDate": "2024-02-16T09:20:48.383Z", + "creationDate": "2024-02-16T09:20:48.383Z", + "deletedDate": null, + "id": "f761a968-4b0f-4090-a568-b118009a07b5", + "organizationId": "c6181652-66eb-4cd9-a7f2-b02a00e12352", + "folderId": null, + "type": 1, + "reprompt": 0, + "name": "asdf123", + "notes": null, + "favorite": false, + "login": { + "fido2Credentials": [], + "uris": [], + "username": null, + "password": null, + "totp": null + }, + "collectionIds": [ + "8e3f5ba1-3e87-4ee8-8da9-b1180099ff9f" + ] + } + ] + }`; diff --git a/libs/importer/src/services/import.service.spec.ts b/libs/importer/src/services/import.service.spec.ts index a95b74d792..eb21f384b5 100644 --- a/libs/importer/src/services/import.service.spec.ts +++ b/libs/importer/src/services/import.service.spec.ts @@ -6,6 +6,7 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; @@ -207,5 +208,60 @@ describe("ImportService", () => { await expect(setImportTargetMethod).rejects.toThrow("Error assigning target folder"); }); + + it("passing importTarget, collectionRelationship has the expected values", async () => { + collectionService.getAllDecrypted.mockResolvedValue([ + mockImportTargetCollection, + mockCollection1, + mockCollection2, + ]); + + importResult.ciphers.push(createCipher({ name: "cipher1" })); + importResult.ciphers.push(createCipher({ name: "cipher2" })); + importResult.collectionRelationships.push([0, 0]); + importResult.collections.push(mockCollection1); + importResult.collections.push(mockCollection2); + + await importService["setImportTarget"]( + importResult, + organizationId, + mockImportTargetCollection, + ); + expect(importResult.collectionRelationships.length).toEqual(2); + expect(importResult.collectionRelationships[0]).toEqual([1, 0]); + expect(importResult.collectionRelationships[1]).toEqual([0, 1]); + }); + + it("passing importTarget, folderRelationship has the expected values", async () => { + folderService.getAllDecryptedFromState.mockResolvedValue([ + mockImportTargetFolder, + mockFolder1, + mockFolder2, + ]); + + importResult.folders.push(mockFolder1); + importResult.folders.push(mockFolder2); + + importResult.ciphers.push(createCipher({ name: "cipher1", folderId: mockFolder1.id })); + importResult.ciphers.push(createCipher({ name: "cipher2" })); + importResult.folderRelationships.push([0, 0]); + + await importService["setImportTarget"](importResult, "", mockImportTargetFolder); + expect(importResult.folderRelationships.length).toEqual(2); + expect(importResult.folderRelationships[0]).toEqual([1, 0]); + expect(importResult.folderRelationships[1]).toEqual([0, 1]); + }); }); }); + +function createCipher(options: Partial = {}) { + const cipher = new CipherView(); + + cipher.name; + cipher.type = options.type; + cipher.folderId = options.folderId; + cipher.collectionIds = options.collectionIds; + cipher.organizationId = options.organizationId; + + return cipher; +} diff --git a/libs/importer/src/services/import.service.ts b/libs/importer/src/services/import.service.ts index a6fd233dcf..62961a77c4 100644 --- a/libs/importer/src/services/import.service.ts +++ b/libs/importer/src/services/import.service.ts @@ -437,8 +437,10 @@ export class ImportService implements ImportServiceAbstraction { const noCollectionRelationShips: [number, number][] = []; importResult.ciphers.forEach((c, index) => { - if (!Array.isArray(c.collectionIds) || c.collectionIds.length == 0) { - c.collectionIds = [importTarget.id]; + if ( + !Array.isArray(importResult.collectionRelationships) || + !importResult.collectionRelationships.some(([cipherPos]) => cipherPos === index) + ) { noCollectionRelationShips.push([index, 0]); } });