import { DashlaneCsvImporter as Importer } from "@bitwarden/common/importers/dashlane/dashlane-csv-importer"; import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; import { credentialsData } from "./test-data/dashlane-csv/credentials.csv"; import { identityData } from "./test-data/dashlane-csv/id.csv"; import { multiplePersonalInfoData } from "./test-data/dashlane-csv/multiple-personal-info.csv"; import { paymentsData } from "./test-data/dashlane-csv/payments.csv"; import { personalInfoData } from "./test-data/dashlane-csv/personal-info.csv"; import { secureNoteData } from "./test-data/dashlane-csv/securenotes.csv"; describe("Dashlane CSV Importer", () => { let importer: Importer; beforeEach(() => { importer = new Importer(); }); it("should parse login records", async () => { const result = await importer.parse(credentialsData); expect(result != null).toBe(true); const cipher = result.ciphers.shift(); expect(cipher.name).toEqual("example.com"); expect(cipher.login.username).toEqual("jdoe"); expect(cipher.login.password).toEqual("somePassword"); expect(cipher.login.totp).toEqual("someTOTPSeed"); expect(cipher.login.uris.length).toEqual(1); const uriView = cipher.login.uris.shift(); expect(uriView.uri).toEqual("https://www.example.com"); expect(cipher.notes).toEqual("some note for example.com"); }); it("should parse an item and create a folder", async () => { const result = await importer.parse(credentialsData); expect(result).not.toBeNull(); expect(result.success).toBe(true); expect(result.folders.length).toBe(1); expect(result.folders[0].name).toBe("Entertainment"); expect(result.folderRelationships[0]).toEqual([0, 0]); }); it("should parse payment records", async () => { const result = await importer.parse(paymentsData); expect(result).not.toBeNull(); expect(result.success).toBe(true); expect(result.ciphers.length).toBe(2); // Account const cipher = result.ciphers.shift(); expect(cipher.type).toBe(CipherType.Card); expect(cipher.name).toBe("John's savings account"); expect(cipher.card.brand).toBeNull(); expect(cipher.card.cardholderName).toBe("John Doe"); expect(cipher.card.number).toBe("accountNumber"); expect(cipher.card.code).toBeNull(); expect(cipher.card.expMonth).toBeNull(); expect(cipher.card.expYear).toBeNull(); expect(cipher.fields.length).toBe(4); expect(cipher.fields[0].name).toBe("type"); expect(cipher.fields[0].value).toBe("bank"); expect(cipher.fields[1].name).toBe("routing_number"); expect(cipher.fields[1].value).toBe("routingNumber"); expect(cipher.fields[2].name).toBe("country"); expect(cipher.fields[2].value).toBe("US"); expect(cipher.fields[3].name).toBe("issuing_bank"); expect(cipher.fields[3].value).toBe("US-ALLY"); // CreditCard const cipher2 = result.ciphers.shift(); expect(cipher2.type).toBe(CipherType.Card); expect(cipher2.name).toBe("John Doe"); expect(cipher2.card.brand).toBe("Visa"); expect(cipher2.card.cardholderName).toBe("John Doe"); expect(cipher2.card.number).toBe("41111111111111111"); expect(cipher2.card.code).toBe("123"); expect(cipher2.card.expMonth).toBe("1"); expect(cipher2.card.expYear).toBe("2023"); expect(cipher2.fields.length).toBe(2); expect(cipher2.fields[0].name).toBe("type"); expect(cipher2.fields[0].value).toBe("credit_card"); expect(cipher2.fields[1].name).toBe("country"); expect(cipher2.fields[1].value).toBe("US"); }); it("should parse ids records", async () => { const result = await importer.parse(identityData); expect(result).not.toBeNull(); expect(result.success).toBe(true); // Type card const cipher = result.ciphers.shift(); expect(cipher.type).toBe(CipherType.Identity); expect(cipher.name).toBe("John Doe card"); expect(cipher.identity.fullName).toBe("John Doe"); expect(cipher.identity.firstName).toBe("John"); expect(cipher.identity.middleName).toBeNull(); expect(cipher.identity.lastName).toBe("Doe"); expect(cipher.identity.licenseNumber).toBe("123123123"); expect(cipher.fields.length).toBe(3); expect(cipher.fields[0].name).toEqual("type"); expect(cipher.fields[0].value).toEqual("card"); expect(cipher.fields[1].name).toEqual("issue_date"); expect(cipher.fields[1].value).toEqual("2022-1-30"); expect(cipher.fields[2].name).toEqual("expiration_date"); expect(cipher.fields[2].value).toEqual("2032-1-30"); // Type passport const cipher2 = result.ciphers.shift(); expect(cipher2.type).toBe(CipherType.Identity); expect(cipher2.name).toBe("John Doe passport"); expect(cipher2.identity.fullName).toBe("John Doe"); expect(cipher2.identity.firstName).toBe("John"); expect(cipher2.identity.middleName).toBeNull(); expect(cipher2.identity.lastName).toBe("Doe"); expect(cipher2.identity.passportNumber).toBe("123123123"); expect(cipher2.fields.length).toBe(4); expect(cipher2.fields[0].name).toEqual("type"); expect(cipher2.fields[0].value).toEqual("passport"); expect(cipher2.fields[1].name).toEqual("issue_date"); expect(cipher2.fields[1].value).toEqual("2022-1-30"); expect(cipher2.fields[2].name).toEqual("expiration_date"); expect(cipher2.fields[2].value).toEqual("2032-1-30"); expect(cipher2.fields[3].name).toEqual("place_of_issue"); expect(cipher2.fields[3].value).toEqual("somewhere in Germany"); // Type license const cipher3 = result.ciphers.shift(); expect(cipher3.type).toBe(CipherType.Identity); expect(cipher3.name).toBe("John Doe license"); expect(cipher3.identity.fullName).toBe("John Doe"); expect(cipher3.identity.firstName).toBe("John"); expect(cipher3.identity.middleName).toBeNull(); expect(cipher3.identity.lastName).toBe("Doe"); expect(cipher3.identity.licenseNumber).toBe("1234556"); expect(cipher3.identity.state).toBe("DC"); expect(cipher3.fields.length).toBe(3); expect(cipher3.fields[0].name).toEqual("type"); expect(cipher3.fields[0].value).toEqual("license"); expect(cipher3.fields[1].name).toEqual("issue_date"); expect(cipher3.fields[1].value).toEqual("2022-8-10"); expect(cipher3.fields[2].name).toEqual("expiration_date"); expect(cipher3.fields[2].value).toEqual("2022-10-10"); // Type social_security const cipher4 = result.ciphers.shift(); expect(cipher4.type).toBe(CipherType.Identity); expect(cipher4.name).toBe("John Doe social_security"); expect(cipher4.identity.fullName).toBe("John Doe"); expect(cipher4.identity.firstName).toBe("John"); expect(cipher4.identity.middleName).toBeNull(); expect(cipher4.identity.lastName).toBe("Doe"); expect(cipher4.identity.ssn).toBe("123123123"); expect(cipher4.fields.length).toBe(1); expect(cipher4.fields[0].name).toEqual("type"); expect(cipher4.fields[0].value).toEqual("social_security"); // Type tax_number const cipher5 = result.ciphers.shift(); expect(cipher5.type).toBe(CipherType.Identity); expect(cipher5.name).toBe("tax_number"); expect(cipher5.identity.licenseNumber).toBe("123123123"); expect(cipher5.fields.length).toBe(1); expect(cipher5.fields[0].name).toEqual("type"); expect(cipher5.fields[0].value).toEqual("tax_number"); }); it("should parse secureNote records", async () => { const result = await importer.parse(secureNoteData); expect(result).not.toBeNull(); expect(result.success).toBe(true); expect(result.ciphers.length).toBe(1); const cipher = result.ciphers.shift(); expect(cipher.type).toBe(CipherType.SecureNote); expect(cipher.name).toBe("01"); expect(cipher.notes).toBe("test"); }); it("should parse personal information records (multiple identities)", async () => { const result = await importer.parse(multiplePersonalInfoData); expect(result).not.toBeNull(); expect(result.success).toBe(true); expect(result.ciphers.length).toBe(6); // name const cipher = result.ciphers.shift(); expect(cipher.type).toBe(CipherType.SecureNote); expect(cipher.name).toBe("MR John Doe"); expect(cipher.fields.length).toBe(7); expect(cipher.fields[0].name).toEqual("type"); expect(cipher.fields[0].value).toEqual("name"); expect(cipher.fields[1].name).toEqual("title"); expect(cipher.fields[1].value).toEqual("MR"); expect(cipher.fields[2].name).toEqual("first_name"); expect(cipher.fields[2].value).toEqual("John"); expect(cipher.fields[3].name).toEqual("last_name"); expect(cipher.fields[3].value).toEqual("Doe"); expect(cipher.fields[4].name).toEqual("login"); expect(cipher.fields[4].value).toEqual("jdoe"); expect(cipher.fields[5].name).toEqual("date_of_birth"); expect(cipher.fields[5].value).toEqual("2022-01-30"); expect(cipher.fields[6].name).toEqual("place_of_birth"); expect(cipher.fields[6].value).toEqual("world"); // email const cipher2 = result.ciphers.shift(); expect(cipher2.type).toBe(CipherType.SecureNote); expect(cipher2.name).toBe("Johns email"); expect(cipher2.fields.length).toBe(4); expect(cipher2.fields[0].name).toEqual("type"); expect(cipher2.fields[0].value).toEqual("email"); expect(cipher2.fields[1].name).toEqual("email"); expect(cipher2.fields[1].value).toEqual("jdoe@example.com"); expect(cipher2.fields[2].name).toEqual("email_type"); expect(cipher2.fields[2].value).toEqual("personal"); expect(cipher2.fields[3].name).toEqual("item_name"); expect(cipher2.fields[3].value).toEqual("Johns email"); // number const cipher3 = result.ciphers.shift(); expect(cipher3.type).toBe(CipherType.SecureNote); expect(cipher3.name).toBe("John's number"); expect(cipher3.fields.length).toBe(3); expect(cipher3.fields[0].name).toEqual("type"); expect(cipher3.fields[0].value).toEqual("number"); expect(cipher3.fields[1].name).toEqual("item_name"); expect(cipher3.fields[1].value).toEqual("John's number"); expect(cipher3.fields[2].name).toEqual("phone_number"); expect(cipher3.fields[2].value).toEqual("+49123123123"); // address const cipher4 = result.ciphers.shift(); expect(cipher4.type).toBe(CipherType.SecureNote); expect(cipher4.name).toBe("John's home address"); expect(cipher4.fields.length).toBe(12); expect(cipher4.fields[0].name).toEqual("type"); expect(cipher4.fields[0].value).toEqual("address"); expect(cipher4.fields[1].name).toEqual("item_name"); expect(cipher4.fields[1].value).toEqual("John's home address"); expect(cipher4.fields[2].name).toEqual("address"); expect(cipher4.fields[2].value).toEqual("1 some street"); expect(cipher4.fields[3].name).toEqual("country"); expect(cipher4.fields[3].value).toEqual("de"); expect(cipher4.fields[4].name).toEqual("state"); expect(cipher4.fields[4].value).toEqual("DE-0-NW"); expect(cipher4.fields[5].name).toEqual("city"); expect(cipher4.fields[5].value).toEqual("some city"); expect(cipher4.fields[6].name).toEqual("zip"); expect(cipher4.fields[6].value).toEqual("123123"); expect(cipher4.fields[7].name).toEqual("address_recipient"); expect(cipher4.fields[7].value).toEqual("John"); expect(cipher4.fields[8].name).toEqual("address_building"); expect(cipher4.fields[8].value).toEqual("1"); expect(cipher4.fields[9].name).toEqual("address_apartment"); expect(cipher4.fields[9].value).toEqual("1"); expect(cipher4.fields[10].name).toEqual("address_floor"); expect(cipher4.fields[10].value).toEqual("1"); expect(cipher4.fields[11].name).toEqual("address_door_code"); expect(cipher4.fields[11].value).toEqual("123"); // website const cipher5 = result.ciphers.shift(); expect(cipher5.type).toBe(CipherType.SecureNote); expect(cipher5.name).toBe("Website"); expect(cipher5.fields.length).toBe(3); expect(cipher5.fields[0].name).toEqual("type"); expect(cipher5.fields[0].value).toEqual("website"); expect(cipher5.fields[1].name).toEqual("item_name"); expect(cipher5.fields[1].value).toEqual("Website"); expect(cipher5.fields[2].name).toEqual("url"); expect(cipher5.fields[2].value).toEqual("website.com"); // 2nd name/identity const cipher6 = result.ciphers.shift(); expect(cipher6.type).toBe(CipherType.SecureNote); expect(cipher6.name).toBe("Mrs Jane Doe"); expect(cipher6.fields.length).toBe(7); expect(cipher6.fields[0].name).toEqual("type"); expect(cipher6.fields[0].value).toEqual("name"); expect(cipher6.fields[1].name).toEqual("title"); expect(cipher6.fields[1].value).toEqual("Mrs"); expect(cipher6.fields[2].name).toEqual("first_name"); expect(cipher6.fields[2].value).toEqual("Jane"); expect(cipher6.fields[3].name).toEqual("last_name"); expect(cipher6.fields[3].value).toEqual("Doe"); expect(cipher6.fields[4].name).toEqual("login"); expect(cipher6.fields[4].value).toEqual("jdoe"); expect(cipher6.fields[5].name).toEqual("date_of_birth"); expect(cipher6.fields[5].value).toEqual("2022-01-30"); expect(cipher6.fields[6].name).toEqual("place_of_birth"); expect(cipher6.fields[6].value).toEqual("earth"); }); it("should combine personal information records to one identity if only one identity present", async () => { const result = await importer.parse(personalInfoData); expect(result).not.toBeNull(); expect(result.success).toBe(true); const cipher = result.ciphers.shift(); expect(cipher.type).toBe(CipherType.Identity); expect(cipher.name).toBe("MR John Doe"); expect(cipher.identity.fullName).toBe("MR John Doe"); expect(cipher.identity.title).toBe("MR"); expect(cipher.identity.firstName).toBe("John"); expect(cipher.identity.middleName).toBeNull(); expect(cipher.identity.lastName).toBe("Doe"); expect(cipher.identity.username).toBe("jdoe"); expect(cipher.identity.email).toBe("jdoe@example.com"); expect(cipher.identity.phone).toBe("+49123123123"); expect(cipher.fields.length).toBe(9); expect(cipher.fields[0].name).toBe("date_of_birth"); expect(cipher.fields[0].value).toBe("2022-01-30"); expect(cipher.fields[1].name).toBe("place_of_birth"); expect(cipher.fields[1].value).toBe("world"); expect(cipher.fields[2].name).toBe("email_type"); expect(cipher.fields[2].value).toBe("personal"); expect(cipher.fields[3].name).toBe("address_recipient"); expect(cipher.fields[3].value).toBe("John"); expect(cipher.fields[4].name).toBe("address_building"); expect(cipher.fields[4].value).toBe("1"); expect(cipher.fields[5].name).toBe("address_apartment"); expect(cipher.fields[5].value).toBe("1"); expect(cipher.fields[6].name).toBe("address_floor"); expect(cipher.fields[6].value).toBe("1"); expect(cipher.fields[7].name).toBe("address_door_code"); expect(cipher.fields[7].value).toBe("123"); expect(cipher.fields[8].name).toBe("url"); expect(cipher.fields[8].value).toBe("website.com"); }); });