diff --git a/jslib/angular/src/services/jslib-services.module.ts b/jslib/angular/src/services/jslib-services.module.ts index 99901d722..14dbb4ff4 100644 --- a/jslib/angular/src/services/jslib-services.module.ts +++ b/jslib/angular/src/services/jslib-services.module.ts @@ -11,7 +11,6 @@ import { CryptoService as CryptoServiceAbstraction } from "@/jslib/common/src/ab import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@/jslib/common/src/abstractions/cryptoFunction.service"; import { EnvironmentService as EnvironmentServiceAbstraction } from "@/jslib/common/src/abstractions/environment.service"; import { EventService as EventServiceAbstraction } from "@/jslib/common/src/abstractions/event.service"; -import { ExportService as ExportServiceAbstraction } from "@/jslib/common/src/abstractions/export.service"; import { FileUploadService as FileUploadServiceAbstraction } from "@/jslib/common/src/abstractions/fileUpload.service"; import { FolderService as FolderServiceAbstraction } from "@/jslib/common/src/abstractions/folder.service"; import { I18nService as I18nServiceAbstraction } from "@/jslib/common/src/abstractions/i18n.service"; @@ -51,7 +50,6 @@ import { ConsoleLogService } from "@/jslib/common/src/services/consoleLog.servic import { CryptoService } from "@/jslib/common/src/services/crypto.service"; import { EnvironmentService } from "@/jslib/common/src/services/environment.service"; import { EventService } from "@/jslib/common/src/services/event.service"; -import { ExportService } from "@/jslib/common/src/services/export.service"; import { FileUploadService } from "@/jslib/common/src/services/fileUpload.service"; import { FolderService } from "@/jslib/common/src/services/folder.service"; import { KeyConnectorService } from "@/jslib/common/src/services/keyConnector.service"; @@ -371,16 +369,6 @@ import { ValidationService } from "./validation.service"; ), deps: [StorageServiceAbstraction, "SECURE_STORAGE"], }, - { - provide: ExportServiceAbstraction, - useClass: ExportService, - deps: [ - FolderServiceAbstraction, - CipherServiceAbstraction, - ApiServiceAbstraction, - CryptoServiceAbstraction, - ], - }, { provide: SearchServiceAbstraction, useClass: SearchService, diff --git a/jslib/common/spec/importers/bitwardenJsonImporter.spec.ts b/jslib/common/spec/importers/bitwardenJsonImporter.spec.ts deleted file mode 100644 index 9dc6d0206..000000000 --- a/jslib/common/spec/importers/bitwardenJsonImporter.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; -import { BitwardenJsonImporter } from "@/jslib/common/src/importers/bitwardenJsonImporter"; - -import { data as passwordProtectedData } from "./testData/bitwardenJson/passwordProtected.json"; - -describe("bitwarden json importer", () => { - let sut: BitwardenJsonImporter; - let cryptoService: SubstituteOf; - let i18nService: SubstituteOf; - - beforeEach(() => { - cryptoService = Substitute.for(); - i18nService = Substitute.for(); - - sut = new BitwardenJsonImporter(cryptoService, i18nService); - }); - - it("should fail if password is needed", async () => { - expect((await sut.parse(passwordProtectedData)).success).toBe(false); - }); - - it("should return password needed error message", async () => { - const expected = "Password required error message"; - i18nService.t("importPasswordRequired").returns(expected); - - expect((await sut.parse(passwordProtectedData)).errorMessage).toEqual(expected); - }); -}); diff --git a/jslib/common/spec/importers/bitwardenPasswordProtectedImporter.spec.ts b/jslib/common/spec/importers/bitwardenPasswordProtectedImporter.spec.ts deleted file mode 100644 index 81b0e2338..000000000 --- a/jslib/common/spec/importers/bitwardenPasswordProtectedImporter.spec.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Substitute, Arg, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; -import { KdfType } from "@/jslib/common/src/enums/kdfType"; -import { BitwardenPasswordProtectedImporter } from "@/jslib/common/src/importers/bitwardenPasswordProtectedImporter"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { ImportResult } from "@/jslib/common/src/models/domain/importResult"; - -import { data as emptyDecryptedData } from "./testData/bitwardenJson/empty.json"; - -describe("BitwardenPasswordProtectedImporter", () => { - let importer: BitwardenPasswordProtectedImporter; - let cryptoService: SubstituteOf; - let i18nService: SubstituteOf; - const password = Utils.newGuid(); - const result = new ImportResult(); - let jDoc: { - encrypted?: boolean; - passwordProtected?: boolean; - salt?: string; - kdfIterations?: any; - kdfType?: any; - encKeyValidation_DO_NOT_EDIT?: string; - data?: string; - }; - - beforeEach(() => { - cryptoService = Substitute.for(); - i18nService = Substitute.for(); - - jDoc = { - encrypted: true, - passwordProtected: true, - salt: "c2FsdA==", - kdfIterations: 100000, - kdfType: KdfType.PBKDF2_SHA256, - encKeyValidation_DO_NOT_EDIT: Utils.newGuid(), - data: Utils.newGuid(), - }; - - result.success = true; - importer = new BitwardenPasswordProtectedImporter(cryptoService, i18nService, password); - }); - - describe("Required Json Data", () => { - it("succeeds with default jdoc", async () => { - cryptoService.decryptToUtf8(Arg.any(), Arg.any()).resolves(emptyDecryptedData); - - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(true); - }); - - it("fails if encrypted === false", async () => { - jDoc.encrypted = false; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if encrypted === null", async () => { - jDoc.encrypted = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if passwordProtected === false", async () => { - jDoc.passwordProtected = false; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if passwordProtected === null", async () => { - jDoc.passwordProtected = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if salt === null", async () => { - jDoc.salt = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfIterations === null", async () => { - jDoc.kdfIterations = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfIterations is not a number", async () => { - jDoc.kdfIterations = "not a number"; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfType === null", async () => { - jDoc.kdfType = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfType is not a string", async () => { - jDoc.kdfType = "not a valid kdf type"; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if kdfType is not a known kdfType", async () => { - jDoc.kdfType = -1; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if encKeyValidation_DO_NOT_EDIT === null", async () => { - jDoc.encKeyValidation_DO_NOT_EDIT = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - - it("fails if data === null", async () => { - jDoc.data = null; - expect((await importer.parse(JSON.stringify(jDoc))).success).toEqual(false); - }); - }); -}); diff --git a/jslib/common/spec/importers/dashlaneCsvImporter.spec.ts b/jslib/common/spec/importers/dashlaneCsvImporter.spec.ts deleted file mode 100644 index 8aab8351a..000000000 --- a/jslib/common/spec/importers/dashlaneCsvImporter.spec.ts +++ /dev/null @@ -1,367 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { DashlaneCsvImporter as Importer } from "@/jslib/common/src/importers/dashlaneImporters/dashlaneCsvImporter"; - -import { credentialsData } from "./testData/dashlaneCsv/credentials.csv"; -import { identityData } from "./testData/dashlaneCsv/id.csv"; -import { multiplePersonalInfoData } from "./testData/dashlaneCsv/multiplePersonalInfo.csv"; -import { paymentsData } from "./testData/dashlaneCsv/payments.csv"; -import { personalInfoData } from "./testData/dashlaneCsv/personalInfo.csv"; -import { secureNoteData } from "./testData/dashlaneCsv/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("01"); - expect(cipher2.card.expYear).toBe("23"); - - 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"); - }); -}); diff --git a/jslib/common/spec/importers/firefoxCsvImporter.spec.ts b/jslib/common/spec/importers/firefoxCsvImporter.spec.ts deleted file mode 100644 index fdc786b5e..000000000 --- a/jslib/common/spec/importers/firefoxCsvImporter.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { FirefoxCsvImporter as Importer } from "@/jslib/common/src/importers/firefoxCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { LoginUriView } from "@/jslib/common/src/models/view/loginUriView"; -import { LoginView } from "@/jslib/common/src/models/view/loginView"; - -import { data as firefoxAccountsData } from "./testData/firefoxCsv/firefoxAccountsData.csv"; -import { data as simplePasswordData } from "./testData/firefoxCsv/simplePasswordData.csv"; - -const CipherData = [ - { - title: "should parse password", - csv: simplePasswordData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com", - login: Object.assign(new LoginView(), { - username: "foo", - password: "bar", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - }), - notes: null, - type: 1, - }), - }, - { - title: 'should skip "chrome://FirefoxAccounts"', - csv: firefoxAccountsData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com", - login: Object.assign(new LoginView(), { - username: "foo", - password: "bar", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - }), - notes: null, - type: 1, - }), - }, -]; - -describe("Firefox CSV Importer", () => { - CipherData.forEach((data) => { - it(data.title, async () => { - const importer = new Importer(); - const result = await importer.parse(data.csv); - expect(result != null).toBe(true); - expect(result.ciphers.length).toBeGreaterThan(0); - - const cipher = result.ciphers.shift(); - let property: keyof typeof data.expected; - for (property in data.expected) { - // eslint-disable-next-line - if (data.expected.hasOwnProperty(property)) { - // eslint-disable-next-line - expect(cipher.hasOwnProperty(property)).toBe(true); - expect(cipher[property]).toEqual(data.expected[property]); - } - } - }); - }); -}); diff --git a/jslib/common/spec/importers/fsecureFskImporter.spec.ts b/jslib/common/spec/importers/fsecureFskImporter.spec.ts deleted file mode 100644 index 4fe4af56b..000000000 --- a/jslib/common/spec/importers/fsecureFskImporter.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { FSecureFskImporter as Importer } from "@/jslib/common/src/importers/fsecureFskImporter"; - -const TestDataWithStyleSetToWebsite: string = JSON.stringify({ - data: { - "8d58b5cf252dd06fbd98f5289e918ab1": { - color: "#00baff", - reatedDate: 1609302913, - creditCvv: "", - creditExpiry: "", - creditNumber: "", - favorite: 0, - modifiedDate: 1609302913, - notes: "note", - password: "word", - passwordList: [], - passwordModifiedDate: 1609302913, - rev: 1, - service: "My first pass", - style: "website", - type: 1, - url: "https://bitwarden.com", - username: "pass", - }, - }, -}); - -const TestDataWithStyleSetToGlobe: string = JSON.stringify({ - data: { - "8d58b5cf252dd06fbd98f5289e918ab1": { - color: "#00baff", - reatedDate: 1609302913, - creditCvv: "", - creditExpiry: "", - creditNumber: "", - favorite: 0, - modifiedDate: 1609302913, - notes: "note", - password: "word", - passwordList: [], - passwordModifiedDate: 1609302913, - rev: 1, - service: "My first pass", - style: "globe", - type: 1, - url: "https://bitwarden.com", - username: "pass", - }, - }, -}); - -describe("FSecure FSK Importer", () => { - it("should parse data with style set to website", async () => { - const importer = new Importer(); - const result = await importer.parse(TestDataWithStyleSetToWebsite); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.username).toEqual("pass"); - expect(cipher.login.password).toEqual("word"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://bitwarden.com"); - }); - - it("should parse data with style set to globe", async () => { - const importer = new Importer(); - const result = await importer.parse(TestDataWithStyleSetToGlobe); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.username).toEqual("pass"); - expect(cipher.login.password).toEqual("word"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://bitwarden.com"); - }); -}); diff --git a/jslib/common/spec/importers/keepass2XmlImporter.spec.ts b/jslib/common/spec/importers/keepass2XmlImporter.spec.ts deleted file mode 100644 index b3305dd5e..000000000 --- a/jslib/common/spec/importers/keepass2XmlImporter.spec.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { KeePass2XmlImporter as Importer } from "@/jslib/common/src/importers/keepass2XmlImporter"; - -const TestData = ` - - - KeePass - - 2016-12-31T21:33:52Z - - 2016-12-31T21:33:52Z - - 2016-12-31T21:33:52Z - 365 - - 2016-12-31T21:33:59Z - -1 - -1 - - False - False - True - False - False - - True - AAAAAAAAAAAAAAAAAAAAAA== - 2016-12-31T21:33:52Z - AAAAAAAAAAAAAAAAAAAAAA== - 2016-12-31T21:33:52Z - 10 - 6291456 - AAAAAAAAAAAAAAAAAAAAAA== - AAAAAAAAAAAAAAAAAAAAAA== - - - - - - KvS57lVwl13AfGFLwkvq4Q== - Root - - 48 - - 2016-12-31T21:33:52Z - 2016-12-31T21:33:52Z - 2017-01-01T22:58:00Z - 2016-12-31T21:33:52Z - False - 1 - 2016-12-31T21:33:52Z - - True - - null - null - AAAAAAAAAAAAAAAAAAAAAA== - - P0ParXgGMBW6caOL2YrhqQ== - Folder2 - a note about the folder - 48 - - 2016-12-31T21:43:30Z - 2016-12-31T21:43:43Z - 2017-01-01T22:58:00Z - 2016-12-31T21:43:30Z - False - 1 - 2016-12-31T21:43:43Z - - True - - null - null - AAAAAAAAAAAAAAAAAAAAAA== - - fAa543oYlgnJKkhKag5HLw== - 1 - - - - - - 2016-12-31T21:34:13Z - 2016-12-31T21:40:23Z - 2016-12-31T21:40:23Z - 2016-12-31T21:34:13Z - False - 0 - 2016-12-31T21:43:48Z - - - att2 - att2value - - - attr1 - att1value - -line1 -line2 - - - Notes - This is a note!!! - -line1 -line2 - - - Password - googpass - - - Title - Google - - - URL - google.com - - - UserName - googleuser - - - True - 0 - - - - fAa543oYlgnJKkhKag5HLw== - 0 - - - - - - 2016-12-31T21:34:13Z - 2016-12-31T21:34:40Z - 2016-12-31T21:34:40Z - 2016-12-31T21:34:13Z - False - 0 - 2016-12-31T21:34:40Z - - - Notes - This is a note!!! - -line1 -line2 - - - Password - googpass - - - Title - Google - - - URL - google.com - - - UserName - googleuser - - - True - 0 - - - - - - - - -`; - -describe("KeePass2 Xml Importer", () => { - it("should parse XML data", async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - expect(result != null).toBe(true); - }); -}); diff --git a/jslib/common/spec/importers/keeperJsonImporter.spec.ts b/jslib/common/spec/importers/keeperJsonImporter.spec.ts deleted file mode 100644 index 70b8f3c31..000000000 --- a/jslib/common/spec/importers/keeperJsonImporter.spec.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { KeeperJsonImporter as Importer } from "@/jslib/common/src/importers/keeperImporters/keeperJsonImporter"; -import { Utils } from "@/jslib/common/src/misc/utils"; - -import { testData as TestData } from "./testData/keeperJson/testData"; - -describe("Keeper Json Importer", () => { - const testDataJson = JSON.stringify(TestData); - - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse login data", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Bank Account 1"); - expect(cipher.login.username).toEqual("customer1234"); - expect(cipher.login.password).toEqual("4813fJDHF4239fdk"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://chase.com"); - expect(cipher.notes).toEqual("These are some notes."); - - const cipher2 = result.ciphers.shift(); - expect(cipher2.name).toEqual("Bank Account 2"); - expect(cipher2.login.username).toEqual("mybankusername"); - expect(cipher2.login.password).toEqual("w4k4k193f$^&@#*%2"); - expect(cipher2.login.uris.length).toEqual(1); - const uriView2 = cipher2.login.uris.shift(); - expect(uriView2.uri).toEqual("https://amex.com"); - expect(cipher2.notes).toEqual("Some great information here."); - - const cipher3 = result.ciphers.shift(); - expect(cipher3.name).toEqual("Some Account"); - expect(cipher3.login.username).toEqual("someUserName"); - expect(cipher3.login.password).toEqual("w4k4k1wergf$^&@#*%2"); - expect(cipher3.notes).toBeNull(); - expect(cipher3.fields).toBeNull(); - expect(cipher3.login.uris.length).toEqual(1); - const uriView3 = cipher3.login.uris.shift(); - expect(uriView3.uri).toEqual("https://example.com"); - }); - - it("should import TOTP when present", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.totp).toBeNull(); - - // 2nd Cipher - const cipher2 = result.ciphers.shift(); - expect(cipher2.login.totp).toEqual( - "otpauth://totp/Amazon:me@company.com?secret=JBSWY3DPEHPK3PXP&issuer=Amazon&algorithm=SHA1&digits=6&period=30" - ); - }); - - it("should parse custom fields", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.fields.length).toBe(1); - expect(cipher.fields[0].name).toEqual("Account Number"); - expect(cipher.fields[0].value).toEqual("123-456-789"); - - // 2nd Cipher - const cipher2 = result.ciphers.shift(); - expect(cipher2.fields.length).toBe(2); - expect(cipher2.fields[0].name).toEqual("Security Group"); - expect(cipher2.fields[0].value).toEqual("Public"); - - expect(cipher2.fields[1].name).toEqual("IP Address"); - expect(cipher2.fields[1].value).toEqual("12.45.67.8"); - }); - - it("should create folders and assigned ciphers to them", async () => { - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const folders = result.folders; - expect(folders.length).toBe(2); - expect(folders[0].name).toBe("Optional Private Folder 1"); - expect(folders[1].name).toBe("My Customer 1"); - - expect(result.folderRelationships[0]).toEqual([0, 0]); - expect(result.folderRelationships[1]).toEqual([1, 0]); - expect(result.folderRelationships[2]).toEqual([1, 1]); - }); - - it("should create collections if part of an organization", async () => { - importer.organizationId = Utils.newGuid(); - const result = await importer.parse(testDataJson); - expect(result != null).toBe(true); - - const collections = result.collections; - expect(collections.length).toBe(2); - expect(collections[0].name).toBe("Optional Private Folder 1"); - expect(collections[1].name).toBe("My Customer 1"); - - expect(result.collectionRelationships[0]).toEqual([0, 0]); - expect(result.collectionRelationships[1]).toEqual([1, 0]); - expect(result.collectionRelationships[2]).toEqual([1, 1]); - }); -}); diff --git a/jslib/common/spec/importers/lastpassCsvImporter.spec.ts b/jslib/common/spec/importers/lastpassCsvImporter.spec.ts deleted file mode 100644 index 5014d8c86..000000000 --- a/jslib/common/spec/importers/lastpassCsvImporter.spec.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { LastPassCsvImporter as Importer } from "@/jslib/common/src/importers/lastpassCsvImporter"; -import { ImportResult } from "@/jslib/common/src/models/domain/importResult"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { FieldView } from "@/jslib/common/src/models/view/fieldView"; - -function baseExcept(result: ImportResult) { - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); -} - -function expectLogin(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Login); - - expect(cipher.name).toBe("example.com"); - expect(cipher.notes).toBe("super secure notes"); - expect(cipher.login.uri).toBe("http://example.com"); - expect(cipher.login.username).toBe("someUser"); - expect(cipher.login.password).toBe("myPassword"); - expect(cipher.login.totp).toBe("Y64VEVMBTSXCYIWRSHRNDZW62MPGVU2G"); -} - -const CipherData = [ - { - title: "should parse expiration date", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card:John Doe -Type: -Number:1234567812345678 -Security Code:123 -Start Date:October,2017 -Expiration Date:June,2020 -Notes:some text -",Credit-card,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "Credit-card", - notes: "some text\n", - type: 3, - card: { - cardholderName: "John Doe", - number: "1234567812345678", - code: "123", - expYear: "2020", - expMonth: "6", - }, - fields: [ - Object.assign(new FieldView(), { - name: "Start Date", - value: "October,2017", - type: FieldType.Text, - }), - ], - }), - }, - { - title: "should parse blank card note", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card: -Type: -Number: -Security Code: -Start Date:, -Expiration Date:, -Notes:",empty,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "empty", - notes: null, - type: 3, - card: { - expMonth: undefined, - }, - fields: [ - Object.assign(new FieldView(), { - name: "Start Date", - value: ",", - type: FieldType.Text, - }), - ], - }), - }, - { - title: "should parse card expiration date w/ no exp year", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card:John Doe -Type:Visa -Number:1234567887654321 -Security Code:321 -Start Date:, -Expiration Date:January, -Notes:",noyear,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "noyear", - notes: null, - type: 3, - card: { - cardholderName: "John Doe", - number: "1234567887654321", - code: "321", - expMonth: "1", - }, - fields: [ - Object.assign(new FieldView(), { - name: "Type", - value: "Visa", - type: FieldType.Text, - }), - Object.assign(new FieldView(), { - name: "Start Date", - value: ",", - type: FieldType.Text, - }), - ], - }), - }, - { - title: "should parse card expiration date w/ no month", - csv: `url,username,password,extra,name,grouping,fav -http://sn,,,"NoteType:Credit Card -Name on Card:John Doe -Type:Mastercard -Number:8765432112345678 -Security Code:987 -Start Date:, -Expiration Date:,2020 -Notes:",nomonth,,0`, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "nomonth", - notes: null, - type: 3, - card: { - cardholderName: "John Doe", - number: "8765432112345678", - code: "987", - expYear: "2020", - expMonth: undefined, - }, - fields: [ - Object.assign(new FieldView(), { - name: "Type", - value: "Mastercard", - type: FieldType.Text, - }), - Object.assign(new FieldView(), { - name: "Start Date", - value: ",", - type: FieldType.Text, - }), - ], - }), - }, -]; - -describe("Lastpass CSV Importer", () => { - CipherData.forEach((data) => { - it(data.title, async () => { - const importer = new Importer(); - const result = await importer.parse(data.csv); - expect(result != null).toBe(true); - expect(result.ciphers.length).toBeGreaterThan(0); - - const cipher = result.ciphers.shift(); - let property: keyof typeof data.expected; - for (property in data.expected) { - // eslint-disable-next-line - if (data.expected.hasOwnProperty(property)) { - // eslint-disable-next-line - expect(cipher.hasOwnProperty(property)).toBe(true); - expect(cipher[property]).toEqual(data.expected[property]); - } - } - }); - }); - - it("should parse login with totp", async () => { - const input = `url,username,password,totp,extra,name,grouping,fav - http://example.com,someUser,myPassword,Y64VEVMBTSXCYIWRSHRNDZW62MPGVU2G,super secure notes,example.com,,0`; - - const importer = new Importer(); - const result = await importer.parse(input); - baseExcept(result); - - const cipher = result.ciphers[0]; - expectLogin(cipher); - }); -}); diff --git a/jslib/common/spec/importers/mykiCsvImporter.spec.ts b/jslib/common/spec/importers/mykiCsvImporter.spec.ts deleted file mode 100644 index 72283b3c1..000000000 --- a/jslib/common/spec/importers/mykiCsvImporter.spec.ts +++ /dev/null @@ -1,633 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { MykiCsvImporter as Importer } from "@/jslib/common/src/importers/mykiCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; - -import { userAccountData } from "./testData/mykiCsv/UserAccount.csv"; -import { userCreditCardData } from "./testData/mykiCsv/UserCreditCard.csv"; -import { userIdCardData } from "./testData/mykiCsv/UserIdCard.csv"; -import { userIdentityData } from "./testData/mykiCsv/UserIdentity.csv"; -import { userNoteData } from "./testData/mykiCsv/UserNote.csv"; -import { userTwoFaData } from "./testData/mykiCsv/UserTwofa.csv"; - -function expectDriversLicense(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Joe User's nickname"); - expect(cipher.notes).toBe("Additional information"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123456"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Driver's License"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("02/02/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("02/02/2024"); -} - -function expectPassport(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Passport ID card"); - expect(cipher.notes).toBe("Additional information field"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.passportNumber).toBe("1234567"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Passport"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectSocialSecurity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Social Security ID card"); - expect(cipher.notes).toBe("Additional information field text"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.ssn).toBe("123455678"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Social Security"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectIdCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("ID card type ID card"); - expect(cipher.notes).toBe("Additional Information field text"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("1234566"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("ID Card"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectTaxNumber(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Tax number ID card"); - expect(cipher.notes).toBe("Additinoal information text field"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345678"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Tax Number"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectBankAccount(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Bank account ID card"); - expect(cipher.notes).toBe("Additional text information here"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12344556677"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Bank Account"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectInsuranceCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Insurance card ID card"); - expect(cipher.notes).toBe("Additional information text goes here"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123456677"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Insurance Card"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2022"); -} - -function expectHealthCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Health card Id card"); - expect(cipher.notes).toBe("More info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("1234670"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Health Card"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectMembershipCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Membership ID card"); - expect(cipher.notes).toBe("Add'l info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345709"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Membership"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectDatabase(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Database ID card"); - expect(cipher.notes).toBe("Addin't info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345089u"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Database"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectOutdoorLicense(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Outdoor license ID card"); - expect(cipher.notes).toBe("Additional info"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123890090"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Outdoor License"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectRewardProgram(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Reward program Id card"); - expect(cipher.notes).toBe("1234890"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("12345890b"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Reward Program"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectSoftwareLicense(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Software license ID card"); - expect(cipher.notes).toBe( - "It seems like the fields don't change, which makes it pretty useless that they have so many ID card types." - ); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("1234567c"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Software License"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -function expectTourVisa(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Tour visa ID card"); - expect(cipher.notes).toBe("Additional Informaion text"); - - expect(cipher.identity.fullName).toBe("Joe M User"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.licenseNumber).toBe("123456lkhj"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(5); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toEqual("tags"); - expect(cipher.fields[1].value).toEqual("someTag"); - - expect(cipher.fields[2].name).toEqual("idType"); - expect(cipher.fields[2].value).toEqual("Tour Visa"); - - expect(cipher.fields[3].name).toEqual("idIssuanceDate"); - expect(cipher.fields[3].value).toEqual("03/07/2022"); - - expect(cipher.fields[4].name).toEqual("idExpirationDate"); - expect(cipher.fields[4].value).toEqual("03/07/2028"); -} - -describe("Myki CSV Importer", () => { - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse userAccount records", async () => { - const result = await importer.parse(userAccountData); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - - expect(cipher.name).toEqual("PasswordNickname"); - expect(cipher.login.username).toEqual("user.name@email.com"); - expect(cipher.login.password).toEqual("abc123"); - expect(cipher.login.totp).toEqual("someTOTPSeed"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("http://www.google.com"); - expect(cipher.notes).toEqual("This is the additional information text."); - - expect(cipher.fields.length).toBe(2); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - }); - - it("should parse userTwoFa records", async () => { - const result = await importer.parse(userTwoFaData); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - - expect(cipher.name).toEqual("2FA nickname"); - expect(cipher.login.username).toBeNull(); - expect(cipher.login.password).toBeNull(); - expect(cipher.login.totp).toBe("someTOTPSeed"); - expect(cipher.notes).toEqual("Additional information field content."); - - expect(cipher.fields.length).toBe(2); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - }); - - it("should parse creditCard records", async () => { - const result = await importer.parse(userCreditCardData); - - 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.Card); - expect(cipher.name).toBe("Visa test card"); - expect(cipher.card.brand).toBe("Visa"); - expect(cipher.card.cardholderName).toBe("Joe User"); - expect(cipher.card.number).toBe("4111111111111111"); - expect(cipher.card.code).toBe("222"); - expect(cipher.card.expMonth).toBe("04"); - expect(cipher.card.expYear).toBe("24"); - - expect(cipher.notes).toBe("This is the additional information field"); - - expect(cipher.fields.length).toBe(2); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - }); - - it("should parse identity records", async () => { - const result = await importer.parse(userIdentityData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.type).toBe(CipherType.Identity); - expect(cipher.name).toBe("Joe User's nickname"); - expect(cipher.identity.fullName).toBe("Mr Joe M User"); - expect(cipher.identity.title).toBe("Mr"); - expect(cipher.identity.firstName).toBe("Joe"); - expect(cipher.identity.middleName).toBe("M"); - expect(cipher.identity.lastName).toBe("User"); - expect(cipher.identity.email).toBe("joe.user@email.com"); - - expect(cipher.identity.address1).toBe("1 Example House"); - expect(cipher.identity.address2).toBe("Suite 300"); - - expect(cipher.identity.city).toBe("Portland"); - expect(cipher.identity.postalCode).toBe("04101"); - expect(cipher.identity.country).toBe("United States"); - - expect(cipher.fields.length).toBe(4); - - expect(cipher.fields[0].name).toEqual("status"); - expect(cipher.fields[0].value).toEqual("active"); - - expect(cipher.fields[1].name).toBe("tags"); - expect(cipher.fields[1].value).toBe("someTag"); - - expect(cipher.fields[2].name).toEqual("gender"); - expect(cipher.fields[2].value).toEqual("Male"); - - expect(cipher.fields[3].name).toEqual("number"); - expect(cipher.fields[3].value).toEqual("2223334444"); - }); - - it("should parse secureNote records", async () => { - const result = await importer.parse(userNoteData); - - 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("The title of a secure note"); - expect(cipher.notes).toBe("The content of a secure note. Lorem ipsum, etc."); - - expect(cipher.fields.length).toBe(1); - - expect(cipher.fields[0].name).toBe("status"); - expect(cipher.fields[0].value).toBe("active"); - }); - - it("should parse idCard records", async () => { - const result = await importer.parse(userIdCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - - expect(result.ciphers.length).toBe(14); - - // Driver's license - const cipher = result.ciphers.shift(); - expectDriversLicense(cipher); - - // Passport - const cipher2 = result.ciphers.shift(); - expectPassport(cipher2); - - // Social Security - const cipher3 = result.ciphers.shift(); - expectSocialSecurity(cipher3); - - // Id Card - const cipher4 = result.ciphers.shift(); - expectIdCard(cipher4); - - // Tax Number - const cipher5 = result.ciphers.shift(); - expectTaxNumber(cipher5); - - // Bank Account - const cipher6 = result.ciphers.shift(); - expectBankAccount(cipher6); - - // Insurance card - const cipher7 = result.ciphers.shift(); - expectInsuranceCard(cipher7); - - // Health card - const cipher8 = result.ciphers.shift(); - expectHealthCard(cipher8); - - // Membership card - const cipher9 = result.ciphers.shift(); - expectMembershipCard(cipher9); - - // Database card - const cipher10 = result.ciphers.shift(); - expectDatabase(cipher10); - - // Outdoor license - const cipher11 = result.ciphers.shift(); - expectOutdoorLicense(cipher11); - - // Reward program - const cipher12 = result.ciphers.shift(); - expectRewardProgram(cipher12); - - // Software license - const cipher13 = result.ciphers.shift(); - expectSoftwareLicense(cipher13); - - // Tour visa - const cipher14 = result.ciphers.shift(); - expectTourVisa(cipher14); - }); -}); diff --git a/jslib/common/spec/importers/nordpassCsvImporter.spec.ts b/jslib/common/spec/importers/nordpassCsvImporter.spec.ts deleted file mode 100644 index 1c1f14cd4..000000000 --- a/jslib/common/spec/importers/nordpassCsvImporter.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { SecureNoteType } from "@/jslib/common/src/enums/secureNoteType"; -import { NordPassCsvImporter as Importer } from "@/jslib/common/src/importers/nordpassCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { IdentityView } from "@/jslib/common/src/models/view/identityView"; - -import { data as creditCardData } from "./testData/nordpassCsv/nordpass.card.csv"; -import { data as identityData } from "./testData/nordpassCsv/nordpass.identity.csv"; -import { data as loginData } from "./testData/nordpassCsv/nordpass.login.csv"; -import { data as secureNoteData } from "./testData/nordpassCsv/nordpass.secureNote.csv"; - -const namesTestData = [ - { - title: "Given #fullName should set firstName", - fullName: "MyFirstName", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: null, - lastName: null, - }), - }, - { - title: "Given #fullName should set first- and lastName", - fullName: "MyFirstName MyLastName", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: null, - lastName: "MyLastName", - }), - }, - { - title: "Given #fullName should set first-, middle and lastName", - fullName: "MyFirstName MyMiddleName MyLastName", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: "MyMiddleName", - lastName: "MyLastName", - }), - }, - { - title: "Given #fullName should set first-, middle and lastName with Jr", - fullName: "MyFirstName MyMiddleName MyLastName Jr", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: "MyMiddleName", - lastName: "MyLastName Jr", - }), - }, - { - title: "Given #fullName should set first-, middle and lastName with Jr and III", - fullName: "MyFirstName MyMiddleName MyLastName Jr III", - expected: Object.assign(new IdentityView(), { - firstName: "MyFirstName", - middleName: "MyMiddleName", - lastName: "MyLastName Jr III", - }), - }, -]; - -function expectLogin(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Login); - - expect(cipher.name).toBe("SomeVaultItemName"); - expect(cipher.notes).toBe("Some note for the VaultItem"); - expect(cipher.login.uri).toBe("https://example.com"); - expect(cipher.login.username).toBe("hello@bitwarden.com"); - expect(cipher.login.password).toBe("someStrongPassword"); -} - -function expectCreditCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Card); - - expect(cipher.name).toBe("SomeVisa"); - expect(cipher.card.brand).toBe("Visa"); - expect(cipher.card.cardholderName).toBe("SomeHolder"); - expect(cipher.card.number).toBe("4024007103939509"); - expect(cipher.card.code).toBe("123"); - expect(cipher.card.expMonth).toBe("1"); - expect(cipher.card.expYear).toBe("22"); -} - -function expectIdentity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - - expect(cipher.name).toBe("SomeTitle"); - expect(cipher.identity.fullName).toBe("MyFirstName MyMiddleName MyLastName"); - expect(cipher.identity.firstName).toBe("MyFirstName"); - expect(cipher.identity.middleName).toBe("MyMiddleName"); - expect(cipher.identity.lastName).toBe("MyLastName"); - expect(cipher.identity.email).toBe("hello@bitwarden.com"); - expect(cipher.identity.phone).toBe("123456789"); - - expect(cipher.identity.address1).toBe("Test street 123"); - expect(cipher.identity.address2).toBe("additional addressinfo"); - expect(cipher.identity.postalCode).toBe("123456"); - expect(cipher.identity.city).toBe("Cologne"); - expect(cipher.identity.state).toBe("North-Rhine-Westphalia"); - expect(cipher.identity.country).toBe("GERMANY"); - expect(cipher.notes).toBe("SomeNoteToMyIdentity"); -} - -function expectSecureNote(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.SecureNote); - - expect(cipher.name).toBe("MySuperSecureNoteTitle"); - expect(cipher.secureNote.type).toBe(SecureNoteType.Generic); - expect(cipher.notes).toBe("MySuperSecureNote"); -} - -describe("NordPass CSV Importer", () => { - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse login records", async () => { - const result = await importer.parse(loginData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectLogin(cipher); - }); - - it("should parse credit card records", async () => { - const result = await importer.parse(creditCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectCreditCard(cipher); - }); - - it("should parse identity records", async () => { - const result = await importer.parse( - identityData.replace("#fullName", "MyFirstName MyMiddleName MyLastName") - ); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectIdentity(cipher); - }); - - namesTestData.forEach((data) => { - it(data.title.replace("#fullName", data.fullName), async () => { - const result = await importer.parse(identityData.replace("#fullName", data.fullName)); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expect(cipher.identity.firstName).toBe(data.expected.firstName); - expect(cipher.identity.middleName).toBe(data.expected.middleName); - expect(cipher.identity.lastName).toBe(data.expected.lastName); - }); - }); - - 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[0]; - expectSecureNote(cipher); - }); - - it("should parse an item and create a folder", async () => { - const result = await importer.parse(secureNoteData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.folders.length).toBe(1); - const folder = result.folders[0]; - expect(folder.name).toBe("notesFolder"); - }); -}); diff --git a/jslib/common/spec/importers/onepassword1PifImporter.spec.ts b/jslib/common/spec/importers/onepassword1PifImporter.spec.ts deleted file mode 100644 index 739b0fadd..000000000 --- a/jslib/common/spec/importers/onepassword1PifImporter.spec.ts +++ /dev/null @@ -1,527 +0,0 @@ -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { OnePassword1PifImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepassword1PifImporter"; - -const TestData: string = - "***aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee***\n" + - JSON.stringify({ - uuid: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - updatedAt: 1486071244, - securityLevel: "SL5", - contentsHash: "aaaaaaaa", - title: "Imported Entry", - location: "https://www.google.com", - secureContents: { - fields: [ - { - value: "user@test.net", - id: "email-input", - name: "email", - type: "T", - designation: "username", - }, - { - value: "myservicepassword", - id: "password-input", - name: "password", - type: "P", - designation: "password", - }, - ], - sections: [ - { - fields: [ - { - k: "concealed", - n: "AAAAAAAAAAAABBBBBBBBBBBCCCCCCCCC", - v: "console-password-123", - t: "console password", - }, - ], - title: "Admin Console", - name: "admin_console", - }, - ], - passwordHistory: [ - { - value: "old-password", - time: 1447791421, - }, - ], - }, - URLs: [ - { - label: "website", - url: "https://www.google.com", - }, - ], - txTimestamp: 1508941334, - createdAt: 1390426636, - typeName: "webforms.WebForm", - }); - -const WindowsOpVaultTestData = JSON.stringify({ - category: "001", - created: 1544823719, - hmac: "NtyBmTTPOb88HV3JUKPx1xl/vcMhac9kvCfe/NtszY0=", - k: "**REMOVED LONG LINE FOR LINTER** -Kyle", - tx: 1553395669, - updated: 1553395669, - uuid: "528AB076FB5F4FBF960884B8E01619AC", - overview: { - title: "Google", - URLs: [ - { - u: "google.com", - }, - ], - url: "google.com", - ps: 26, - ainfo: "googluser", - }, - details: { - passwordHistory: [ - { - value: "oldpass1", - time: 1553394449, - }, - { - value: "oldpass2", - time: 1553394457, - }, - { - value: "oldpass3", - time: 1553394458, - }, - { - value: "oldpass4", - time: 1553394459, - }, - { - value: "oldpass5", - time: 1553394460, - }, - { - value: "oldpass6", - time: 1553394461, - }, - ], - fields: [ - { - type: "T", - id: "username", - name: "username", - value: "googluser", - designation: "username", - }, - { - type: "P", - id: "password", - name: "password", - value: "12345678901", - designation: "password", - }, - ], - notesPlain: "This is a note\r\n\r\nline1\r\nline2", - sections: [ - { - title: "test", - name: "1214FD88CD30405D9EED14BEB4D61B60", - fields: [ - { - k: "string", - n: "6CC3BD77482D4559A4B8BB2D360F821B", - v: "fgfg", - t: "fgggf", - }, - { - k: "concealed", - n: "5CFE7BCAA1DF4578BBF7EB508959BFF3", - v: "dfgdfgfdg", - t: "pwfield", - }, - ], - }, - ], - }, -}); - -const IdentityTestData = JSON.stringify({ - uuid: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - updatedAt: 1553365894, - securityLevel: "SL5", - contentsHash: "eeeeeeee", - title: "Test Identity", - secureContents: { - lastname: "Fritzenberger", - zip: "223344", - birthdate_dd: "11", - homephone: "+49 333 222 111", - company: "Web Inc.", - firstname: "Frank", - birthdate_mm: "3", - country: "de", - sex: "male", - sections: [ - { - fields: [ - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "firstname", - v: "Frank", - a: { - guarded: "yes", - }, - t: "first name", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "initial", - v: "MD", - a: { - guarded: "yes", - }, - t: "initial", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "lastname", - v: "Fritzenberger", - a: { - guarded: "yes", - }, - t: "last name", - }, - { - k: "menu", - v: "male", - n: "sex", - a: { - guarded: "yes", - }, - t: "sex", - }, - { - k: "date", - v: 1552305660, - n: "birthdate", - a: { - guarded: "yes", - }, - t: "birth date", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "occupation", - v: "Engineer", - a: { - guarded: "yes", - }, - t: "occupation", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "company", - v: "Web Inc.", - a: { - guarded: "yes", - }, - t: "company", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "department", - v: "IT", - a: { - guarded: "yes", - }, - t: "department", - }, - { - k: "string", - inputTraits: { - autocapitalization: "Words", - }, - n: "jobtitle", - v: "Developer", - a: { - guarded: "yes", - }, - t: "job title", - }, - ], - title: "Identification", - name: "name", - }, - { - fields: [ - { - k: "address", - inputTraits: { - autocapitalization: "Sentences", - }, - n: "address", - v: { - street: "Mainstreet 1", - city: "Berlin", - country: "de", - zip: "223344", - }, - a: { - guarded: "yes", - }, - t: "address", - }, - { - k: "phone", - v: "+49 001 222 333 44", - n: "defphone", - a: { - guarded: "yes", - }, - t: "default phone", - }, - { - k: "phone", - v: "+49 333 222 111", - n: "homephone", - a: { - guarded: "yes", - }, - t: "home", - }, - { - k: "phone", - n: "cellphone", - a: { - guarded: "yes", - }, - t: "mobile", - }, - { - k: "phone", - n: "busphone", - a: { - guarded: "yes", - }, - t: "business", - }, - ], - title: "Address", - name: "address", - }, - { - fields: [ - { - k: "string", - n: "username", - a: { - guarded: "yes", - }, - t: "username", - }, - { - k: "string", - n: "reminderq", - t: "reminder question", - }, - { - k: "string", - n: "remindera", - t: "reminder answer", - }, - { - k: "string", - inputTraits: { - keyboard: "EmailAddress", - }, - n: "email", - v: "test@web.de", - a: { - guarded: "yes", - }, - t: "email", - }, - { - k: "string", - n: "website", - inputTraits: { - keyboard: "URL", - }, - t: "website", - }, - { - k: "string", - n: "icq", - t: "ICQ", - }, - { - k: "string", - n: "skype", - t: "skype", - }, - { - k: "string", - n: "aim", - t: "AOL/AIM", - }, - { - k: "string", - n: "yahoo", - t: "Yahoo", - }, - { - k: "string", - n: "msn", - t: "MSN", - }, - { - k: "string", - n: "forumsig", - t: "forum signature", - }, - ], - title: "Internet Details", - name: "internet", - }, - { - title: "Related Items", - name: "linked items", - }, - ], - initial: "MD", - address1: "Mainstreet 1", - city: "Berlin", - jobtitle: "Developer", - occupation: "Engineer", - department: "IT", - email: "test@web.de", - birthdate_yy: "2019", - homephone_local: "+49 333 222 111", - defphone_local: "+49 001 222 333 44", - defphone: "+49 001 222 333 44", - }, - txTimestamp: 1553365894, - createdAt: 1553364679, - typeName: "identities.Identity", -}); - -describe("1Password 1Pif Importer", () => { - it("should parse data", async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.login.username).toEqual("user@test.net"); - expect(cipher.login.password).toEqual("myservicepassword"); - expect(cipher.login.uris.length).toEqual(1); - const uriView = cipher.login.uris.shift(); - expect(uriView.uri).toEqual("https://www.google.com"); - }); - - it('should create concealed field as "hidden" type', async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - - const cipher = ciphers.shift(); - const fields = cipher.fields; - expect(fields.length).toEqual(1); - - const field = fields.shift(); - expect(field.name).toEqual("console password"); - expect(field.value).toEqual("console-password-123"); - expect(field.type).toEqual(FieldType.Hidden); - }); - - it("should create identity records", async () => { - const importer = new Importer(); - const result = await importer.parse(IdentityTestData); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Test Identity"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Frank"); - expect(identity.middleName).toEqual("MD"); - expect(identity.lastName).toEqual("Fritzenberger"); - expect(identity.company).toEqual("Web Inc."); - expect(identity.address1).toEqual("Mainstreet 1"); - expect(identity.country).toEqual("DE"); - expect(identity.city).toEqual("Berlin"); - expect(identity.postalCode).toEqual("223344"); - expect(identity.phone).toEqual("+49 001 222 333 44"); - expect(identity.email).toEqual("test@web.de"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(6); - const fields = cipher.fields; - expect(fields[0].name).toEqual("sex"); - expect(fields[0].value).toEqual("male"); - expect(fields[1].name).toEqual("birth date"); - expect(fields[1].value).toEqual("Mon, 11 Mar 2019 12:01:00 GMT"); - expect(fields[2].name).toEqual("occupation"); - expect(fields[2].value).toEqual("Engineer"); - expect(fields[3].name).toEqual("department"); - expect(fields[3].value).toEqual("IT"); - expect(fields[4].name).toEqual("job title"); - expect(fields[4].value).toEqual("Developer"); - expect(fields[5].name).toEqual("home"); - expect(fields[5].value).toEqual("+49 333 222 111"); - }); - - it("should create password history", async () => { - const importer = new Importer(); - const result = await importer.parse(TestData); - const cipher = result.ciphers.shift(); - - expect(cipher.passwordHistory.length).toEqual(1); - const ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("old-password"); - expect(ph.lastUsedDate.toISOString()).toEqual("2015-11-17T20:17:01.000Z"); - }); - - it("should create password history from windows opvault 1pif format", async () => { - const importer = new Importer(); - const result = await importer.parse(WindowsOpVaultTestData); - const cipher = result.ciphers.shift(); - - expect(cipher.passwordHistory.length).toEqual(5); - let ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass6"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:41.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass5"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:40.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass4"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:39.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass3"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:38.000Z"); - ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("oldpass2"); - expect(ph.lastUsedDate.toISOString()).toEqual("2019-03-24T02:27:37.000Z"); - }); -}); diff --git a/jslib/common/spec/importers/onepassword1PuxImporter.spec.ts b/jslib/common/spec/importers/onepassword1PuxImporter.spec.ts deleted file mode 100644 index 2d73ffeae..000000000 --- a/jslib/common/spec/importers/onepassword1PuxImporter.spec.ts +++ /dev/null @@ -1,689 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { SecureNoteType } from "@/jslib/common/src/enums/secureNoteType"; -import { OnePassword1PuxImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepassword1PuxImporter"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { FieldView } from "@/jslib/common/src/models/view/fieldView"; - -import { APICredentialsData } from "./testData/onePassword1Pux/APICredentials"; -import { BankAccountData } from "./testData/onePassword1Pux/BankAccount"; -import { CreditCardData } from "./testData/onePassword1Pux/CreditCard"; -import { DatabaseData } from "./testData/onePassword1Pux/Database"; -import { DriversLicenseData } from "./testData/onePassword1Pux/DriversLicense"; -import { EmailAccountData } from "./testData/onePassword1Pux/EmailAccount"; -import { EmailFieldData } from "./testData/onePassword1Pux/Emailfield"; -import { EmailFieldOnIdentityData } from "./testData/onePassword1Pux/EmailfieldOnIdentity"; -import { EmailFieldOnIdentityPrefilledData } from "./testData/onePassword1Pux/EmailfieldOnIdentity_Prefilled"; -import { IdentityData } from "./testData/onePassword1Pux/IdentityData"; -import { LoginData } from "./testData/onePassword1Pux/LoginData"; -import { MedicalRecordData } from "./testData/onePassword1Pux/MedicalRecord"; -import { MembershipData } from "./testData/onePassword1Pux/Membership"; -import { OnePuxExampleFile } from "./testData/onePassword1Pux/Onepux_example"; -import { OutdoorLicenseData } from "./testData/onePassword1Pux/OutdoorLicense"; -import { PassportData } from "./testData/onePassword1Pux/Passport"; -import { PasswordData } from "./testData/onePassword1Pux/Password"; -import { RewardsProgramData } from "./testData/onePassword1Pux/RewardsProgram"; -import { SSNData } from "./testData/onePassword1Pux/SSN"; -import { SanitizedExport } from "./testData/onePassword1Pux/SanitizedExport"; -import { SecureNoteData } from "./testData/onePassword1Pux/SecureNote"; -import { ServerData } from "./testData/onePassword1Pux/Server"; -import { SoftwareLicenseData } from "./testData/onePassword1Pux/SoftwareLicense"; -import { WirelessRouterData } from "./testData/onePassword1Pux/WirelessRouter"; - -function validateCustomField(fields: FieldView[], fieldName: string, expectedValue: any) { - expect(fields).toBeDefined(); - const customField = fields.find((f) => f.name === fieldName); - expect(customField).toBeDefined(); - - expect(customField.value).toEqual(expectedValue); -} - -describe("1Password 1Pux Importer", () => { - const OnePuxExampleFileJson = JSON.stringify(OnePuxExampleFile); - const LoginDataJson = JSON.stringify(LoginData); - const CreditCardDataJson = JSON.stringify(CreditCardData); - const IdentityDataJson = JSON.stringify(IdentityData); - const SecureNoteDataJson = JSON.stringify(SecureNoteData); - const SanitizedExportJson = JSON.stringify(SanitizedExport); - - it("should parse login data", async () => { - const importer = new Importer(); - const result = await importer.parse(LoginDataJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("eToro"); - - expect(cipher.login.username).toEqual("username123123123@gmail.com"); - expect(cipher.login.password).toEqual("password!"); - expect(cipher.login.uris.length).toEqual(1); - expect(cipher.login.uri).toEqual("https://www.fakesite.com"); - expect(cipher.login.totp).toEqual("otpseed777"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(3); - validateCustomField(cipher.fields, "terms", "false"); - validateCustomField(cipher.fields, "policies", "true"); - validateCustomField(cipher.fields, "cyqyggt2otns6tbbqtsl6w2ceu", "username123123"); - }); - - it("should parse notes", async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.notes).toEqual("This is a note. *bold*! _italic_!"); - }); - - it("should set favourite if favIndex equals 1", async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - expect(result != null).toBe(true); - - const cipher = result.ciphers.shift(); - expect(cipher.favorite).toBe(true); - }); - - it("should handle custom boolean fields", async () => { - const importer = new Importer(); - const result = await importer.parse(LoginDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - - const cipher = ciphers.shift(); - expect(cipher.fields[0].name).toEqual("terms"); - expect(cipher.fields[0].value).toEqual("false"); - expect(cipher.fields[0].type).toBe(FieldType.Boolean); - - expect(cipher.fields[1].name).toEqual("policies"); - expect(cipher.fields[1].value).toEqual("true"); - expect(cipher.fields[1].type).toBe(FieldType.Boolean); - }); - - it("should add fields of type email as custom fields", async () => { - const importer = new Importer(); - const EmailFieldDataJson = JSON.stringify(EmailFieldData); - const result = await importer.parse(EmailFieldDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - const cipher = ciphers.shift(); - - expect(cipher.fields[0].name).toEqual("reg_email"); - expect(cipher.fields[0].value).toEqual("kriddler@nullvalue.test"); - expect(cipher.fields[0].type).toBe(FieldType.Text); - - expect(cipher.fields[1].name).toEqual("provider"); - expect(cipher.fields[1].value).toEqual("myEmailProvider"); - expect(cipher.fields[1].type).toBe(FieldType.Text); - }); - - it('should create concealed field as "hidden" type', async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - - const cipher = ciphers.shift(); - const fields = cipher.fields; - expect(fields.length).toEqual(1); - - const field = fields.shift(); - expect(field.name).toEqual("PIN"); - expect(field.value).toEqual("12345"); - expect(field.type).toEqual(FieldType.Hidden); - }); - - it("should create password history", async () => { - const importer = new Importer(); - const result = await importer.parse(OnePuxExampleFileJson); - const cipher = result.ciphers.shift(); - - expect(cipher.passwordHistory.length).toEqual(1); - const ph = cipher.passwordHistory.shift(); - expect(ph.password).toEqual("12345password"); - expect(ph.lastUsedDate.toISOString()).toEqual("2016-03-18T17:32:35.000Z"); - }); - - it("should create credit card records", async () => { - const importer = new Importer(); - const result = await importer.parse(CreditCardDataJson); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Parent's Credit Card"); - expect(cipher.notes).toEqual("My parents' credit card."); - - const card = cipher.card; - expect(card.cardholderName).toEqual("Fred Engels"); - expect(card.number).toEqual("6011111111111117"); - expect(card.code).toEqual("1312"); - expect(card.brand).toEqual("Discover"); - expect(card.expMonth).toEqual("12"); - expect(card.expYear).toEqual("2099"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(12); - validateCustomField(cipher.fields, "txbzvwzpck7ejhfres3733rbpm", "card"); - validateCustomField(cipher.fields, "cashLimit", "$500"); - validateCustomField(cipher.fields, "creditLimit", "$1312"); - validateCustomField(cipher.fields, "validFrom", "200101"); - validateCustomField(cipher.fields, "bank", "Some bank"); - validateCustomField(cipher.fields, "phoneLocal", "123456"); - validateCustomField(cipher.fields, "phoneTollFree", "0800123456"); - validateCustomField(cipher.fields, "phoneIntl", "+49123456"); - validateCustomField(cipher.fields, "website", "somebank.com"); - validateCustomField(cipher.fields, "pin", "1234"); - validateCustomField(cipher.fields, "interest", "1%"); - validateCustomField(cipher.fields, "issuenumber", "123456"); - }); - - it("should create identity records", async () => { - const importer = new Importer(); - const result = await importer.parse(IdentityDataJson); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("George Engels"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("George"); - expect(identity.middleName).toEqual("S"); - expect(identity.lastName).toEqual("Engels"); - expect(identity.company).toEqual("Acme Inc."); - expect(identity.address1).toEqual("1312 Main St."); - expect(identity.country).toEqual("US"); - expect(identity.state).toEqual("California"); - expect(identity.city).toEqual("Atlantis"); - expect(identity.postalCode).toEqual("90210"); - expect(identity.phone).toEqual("4565555555"); - expect(identity.email).toEqual("gengels@nullvalue.test"); - expect(identity.username).toEqual("gengels"); - - // remaining fields as custom fields - expect(cipher.fields.length).toEqual(17); - validateCustomField(cipher.fields, "sex", "male"); - validateCustomField(cipher.fields, "birthdate", "Thu, 01 Jan 1981 12:01:00 GMT"); - validateCustomField(cipher.fields, "occupation", "Steel Worker"); - validateCustomField(cipher.fields, "department", "QA"); - validateCustomField(cipher.fields, "jobtitle", "Quality Assurance Manager"); - validateCustomField(cipher.fields, "homephone", "4575555555"); - validateCustomField(cipher.fields, "cellphone", "4585555555"); - validateCustomField(cipher.fields, "busphone", "4595555555"); - validateCustomField(cipher.fields, "reminderq", "Who's a super cool guy?"); - validateCustomField(cipher.fields, "remindera", "Me, buddy."); - validateCustomField(cipher.fields, "website", "cv.gengels.nullvalue.test"); - validateCustomField(cipher.fields, "icq", "12345678"); - validateCustomField(cipher.fields, "skype", "skypeisbad1619"); - validateCustomField(cipher.fields, "aim", "aollol@lololol.aol.com"); - validateCustomField(cipher.fields, "yahoo", "sk8rboi13@yah00.com"); - validateCustomField(cipher.fields, "msn", "msnothankyou@msn&m&m.com"); - validateCustomField(cipher.fields, "forumsig", "super cool guy"); - }); - - it("emails fields on identity types should be added to the identity email field", async () => { - const importer = new Importer(); - const EmailFieldOnIdentityDataJson = JSON.stringify(EmailFieldOnIdentityData); - const result = await importer.parse(EmailFieldOnIdentityDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - const cipher = ciphers.shift(); - - const identity = cipher.identity; - expect(identity.email).toEqual("gengels@nullvalue.test"); - - expect(cipher.fields[0].name).toEqual("provider"); - expect(cipher.fields[0].value).toEqual("myEmailProvider"); - expect(cipher.fields[0].type).toBe(FieldType.Text); - }); - - it("emails fields on identity types should be added to custom fields if identity.email has been filled", async () => { - const importer = new Importer(); - const EmailFieldOnIdentityPrefilledDataJson = JSON.stringify(EmailFieldOnIdentityPrefilledData); - const result = await importer.parse(EmailFieldOnIdentityPrefilledDataJson); - expect(result != null).toBe(true); - - const ciphers = result.ciphers; - expect(ciphers.length).toEqual(1); - const cipher = ciphers.shift(); - - const identity = cipher.identity; - expect(identity.email).toEqual("gengels@nullvalue.test"); - - expect(cipher.fields[0].name).toEqual("2nd_email"); - expect(cipher.fields[0].value).toEqual("kriddler@nullvalue.test"); - expect(cipher.fields[0].type).toBe(FieldType.Text); - - expect(cipher.fields[1].name).toEqual("provider"); - expect(cipher.fields[1].value).toEqual("myEmailProvider"); - expect(cipher.fields[1].type).toBe(FieldType.Text); - }); - - it("should parse category 005 - Password (Legacy)", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(PasswordData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("SuperSecret Password"); - expect(cipher.notes).toEqual("SuperSecret Password Notes"); - - expect(cipher.login.password).toEqual("GBq[AGb]4*Si3tjwuab^"); - expect(cipher.login.uri).toEqual("https://n0t.y0ur.n0rm4l.w3bs1t3"); - }); - - it("should parse category 100 - SoftwareLicense", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(SoftwareLicenseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.SecureNote); - expect(cipher.name).toEqual("Limux Product Key"); - expect(cipher.notes).toEqual("My Software License"); - - expect(cipher.fields.length).toEqual(13); - validateCustomField(cipher.fields, "product_version", "5.10.1000"); - validateCustomField(cipher.fields, "reg_code", "265453-13457355-847327"); - validateCustomField(cipher.fields, "reg_name", "Kay Riddler"); - validateCustomField(cipher.fields, "reg_email", "kriddler@nullvalue.test"); - validateCustomField(cipher.fields, "company", "Riddles and Jigsaw Puzzles GmbH"); - validateCustomField( - cipher.fields, - "download_link", - "https://limuxcompany.nullvalue.test/5.10.1000/isos" - ); - validateCustomField(cipher.fields, "publisher_name", "Limux Software and Hardware"); - validateCustomField(cipher.fields, "publisher_website", "https://limuxcompany.nullvalue.test/"); - validateCustomField(cipher.fields, "retail_price", "$999"); - validateCustomField(cipher.fields, "support_email", "support@nullvalue.test"); - validateCustomField(cipher.fields, "order_date", "Thu, 01 Apr 2021 12:01:00 GMT"); - validateCustomField(cipher.fields, "order_number", "594839"); - validateCustomField(cipher.fields, "order_total", "$1086.59"); - }); - - it("should parse category 101 - BankAccount", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(BankAccountData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.Card); - expect(cipher.name).toEqual("Bank Account"); - expect(cipher.notes).toEqual("My Bank Account"); - - expect(cipher.card.cardholderName).toEqual("Cool Guy"); - - expect(cipher.fields.length).toEqual(9); - validateCustomField(cipher.fields, "bankName", "Super Credit Union"); - validateCustomField(cipher.fields, "accountType", "checking"); - validateCustomField(cipher.fields, "routingNo", "111000999"); - validateCustomField(cipher.fields, "accountNo", "192837465918273645"); - validateCustomField(cipher.fields, "swift", "123456"); - validateCustomField(cipher.fields, "iban", "DE12 123456"); - validateCustomField(cipher.fields, "telephonePin", "5555"); - validateCustomField(cipher.fields, "branchPhone", "9399399933"); - validateCustomField(cipher.fields, "branchAddress", "1 Fifth Avenue"); - }); - - it("should parse category 102 - Database", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(DatabaseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("Database"); - expect(cipher.notes).toEqual("My Database"); - - const login = cipher.login; - expect(login.username).toEqual("cooldbuser"); - expect(login.password).toEqual("^+kTjhLaN7wVPAhGU)*J"); - - expect(cipher.fields.length).toEqual(7); - validateCustomField(cipher.fields, "database_type", "postgresql"); - validateCustomField(cipher.fields, "hostname", "my.secret.db.server"); - validateCustomField(cipher.fields, "port", "1337"); - validateCustomField(cipher.fields, "database", "user_database"); - validateCustomField(cipher.fields, "sid", "ASDIUFU-283234"); - validateCustomField(cipher.fields, "alias", "cdbu"); - validateCustomField(cipher.fields, "options", "ssh"); - }); - - it("should parse category 103 - Drivers license", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(DriversLicenseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("Michael Scarn"); - expect(cipher.subTitle).toEqual("Michael Scarn"); - expect(cipher.notes).toEqual("My Driver's License"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Michael"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Scarn"); - expect(identity.address1).toEqual("2120 Mifflin Rd."); - expect(identity.state).toEqual("Pennsylvania"); - expect(identity.country).toEqual("United States"); - expect(identity.licenseNumber).toEqual("12345678901"); - - expect(cipher.fields.length).toEqual(6); - validateCustomField(cipher.fields, "birthdate", "Sun, 01 Jan 1978 12:01:00 GMT"); - validateCustomField(cipher.fields, "sex", "male"); - validateCustomField(cipher.fields, "height", "5'11\""); - validateCustomField(cipher.fields, "class", "C"); - validateCustomField(cipher.fields, "conditions", "B"); - validateCustomField(cipher.fields, "expiry_date", "203012"); - }); - - it("should parse category 104 - Outdoor License", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(OutdoorLicenseData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Harvest License"); - expect(cipher.subTitle).toEqual("Cash Bandit"); - expect(cipher.notes).toEqual("My Outdoor License"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Cash"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Bandit"); - expect(identity.state).toEqual("Washington"); - expect(identity.country).toEqual("United States of America"); - - expect(cipher.fields.length).toEqual(4); - validateCustomField(cipher.fields, "valid_from", "Thu, 01 Apr 2021 12:01:00 GMT"); - validateCustomField(cipher.fields, "expires", "Fri, 01 Apr 2044 12:01:00 GMT"); - validateCustomField(cipher.fields, "game", "Bananas,blueberries,corn"); - validateCustomField(cipher.fields, "quota", "100/each"); - }); - - it("should parse category 105 - Membership", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(MembershipData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Library Card"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("George"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Engels"); - expect(identity.company).toEqual("National Public Library"); - expect(identity.phone).toEqual("9995555555"); - - expect(cipher.fields.length).toEqual(5); - validateCustomField(cipher.fields, "website", "https://npl.nullvalue.gov.test"); - validateCustomField(cipher.fields, "member_since", "199901"); - validateCustomField(cipher.fields, "expiry_date", "203412"); - validateCustomField(cipher.fields, "membership_no", "64783862"); - validateCustomField(cipher.fields, "pin", "19191"); - }); - - it("should parse category 106 - Passport", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(PassportData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Mr. Globewide"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("David"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Global"); - expect(identity.passportNumber).toEqual("76436847"); - - expect(cipher.fields.length).toEqual(8); - validateCustomField(cipher.fields, "type", "US Passport"); - validateCustomField(cipher.fields, "sex", "female"); - validateCustomField(cipher.fields, "nationality", "International"); - validateCustomField(cipher.fields, "issuing_authority", "Department of State"); - validateCustomField(cipher.fields, "birthdate", "Fri, 01 Apr 1983 12:01:00 GMT"); - validateCustomField(cipher.fields, "birthplace", "A cave somewhere in Maine"); - validateCustomField(cipher.fields, "issue_date", "Wed, 01 Jan 2020 12:01:00 GMT"); - validateCustomField(cipher.fields, "expiry_date", "Sat, 01 Jan 2050 12:01:00 GMT"); - }); - - it("should parse category 107 - RewardsProgram", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(RewardsProgramData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Identity); - expect(cipher.name).toEqual("Retail Reward Thing"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Chef"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Coldroom"); - expect(identity.company).toEqual("Super Cool Store Co."); - - expect(cipher.fields.length).toEqual(7); - validateCustomField(cipher.fields, "membership_no", "member-29813569"); - validateCustomField(cipher.fields, "pin", "99913"); - validateCustomField(cipher.fields, "additional_no", "additional member id"); - validateCustomField(cipher.fields, "member_since", "202101"); - validateCustomField(cipher.fields, "customer_service_phone", "123456"); - validateCustomField(cipher.fields, "reservations_phone", "123456"); - validateCustomField(cipher.fields, "website", "supercoolstore.com"); - }); - - it("should parse category 108 - SSN", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(SSNData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.name).toEqual("SSN"); - - const identity = cipher.identity; - expect(identity.firstName).toEqual("Jack"); - expect(identity.middleName).toBeNull(); - expect(identity.lastName).toEqual("Judd"); - expect(identity.ssn).toEqual("131-216-1900"); - }); - - it("should parse category 109 - WirelessRouter", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(WirelessRouterData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("Wireless Router"); - expect(cipher.notes).toEqual("My Wifi Router Config"); - - expect(cipher.login.password).toEqual("BqatGTVQ9TCN72tLbjrsHqkb"); - - expect(cipher.fields.length).toEqual(7); - validateCustomField(cipher.fields, "name", "pixel 2Xl"); - validateCustomField(cipher.fields, "server", "127.0.0.1"); - validateCustomField(cipher.fields, "airport_id", "some airportId"); - validateCustomField(cipher.fields, "network_name", "some network name"); - validateCustomField(cipher.fields, "wireless_security", "WPA"); - validateCustomField(cipher.fields, "wireless_password", "wifipassword"); - validateCustomField(cipher.fields, "disk_password", "diskpassword"); - }); - - it("should parse category 110 - Server", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(ServerData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("Super Cool Server"); - expect(cipher.notes).toEqual("My Server"); - - expect(cipher.login.username).toEqual("frankly-notsure"); - expect(cipher.login.password).toEqual("*&YHJI87yjy78u"); - expect(cipher.login.uri).toEqual("https://coolserver.nullvalue.test"); - - expect(cipher.fields.length).toEqual(7); - validateCustomField( - cipher.fields, - "admin_console_url", - "https://coolserver.nullvalue.test/admin" - ); - validateCustomField(cipher.fields, "admin_console_username", "frankly-idontknowwhatimdoing"); - validateCustomField(cipher.fields, "admin_console_password", "^%RY&^YUiju8iUYHJI(U"); - validateCustomField(cipher.fields, "name", "Private Hosting Provider Inc."); - validateCustomField(cipher.fields, "website", "https://phpi.nullvalue.test"); - validateCustomField( - cipher.fields, - "support_contact_url", - "https://phpi.nullvalue.test/support" - ); - validateCustomField(cipher.fields, "support_contact_phone", "8882569382"); - }); - - it("should parse category 111 - EmailAccount", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(EmailAccountData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.SecureNote); - expect(cipher.name).toEqual("Email Config"); - expect(cipher.notes).toEqual("My Email Config"); - - expect(cipher.fields.length).toEqual(17); - validateCustomField(cipher.fields, "pop_type", "either"); - validateCustomField(cipher.fields, "pop_username", "someuser@nullvalue.test"); - validateCustomField(cipher.fields, "pop_server", "mailserver.nullvalue.test"); - validateCustomField(cipher.fields, "pop_port", "587"); - validateCustomField(cipher.fields, "pop_password", "u1jsf { - const importer = new Importer(); - const jsonString = JSON.stringify(APICredentialsData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.type).toEqual(CipherType.Login); - expect(cipher.name).toEqual("API Credential"); - expect(cipher.notes).toEqual("My API Credential"); - - expect(cipher.login.username).toEqual("apiuser@nullvalue.test"); - expect(cipher.login.password).toEqual("apiapiapiapiapiapiappy"); - expect(cipher.login.uri).toEqual("http://not.your.everyday.hostname"); - - expect(cipher.fields.length).toEqual(4); - validateCustomField(cipher.fields, "type", "jwt"); - validateCustomField(cipher.fields, "filename", "filename.jwt"); - validateCustomField(cipher.fields, "validFrom", "Mon, 04 Apr 2011 12:01:00 GMT"); - validateCustomField(cipher.fields, "expires", "Tue, 01 Apr 2031 12:01:00 GMT"); - }); - - it("should create secure notes", async () => { - const importer = new Importer(); - const result = await importer.parse(SecureNoteDataJson); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - - expect(cipher.name).toEqual("Secure Note #1"); - expect(cipher.notes).toEqual( - "This is my secure note. \n\nLorem ipsum expecto patronum. \nThe quick brown fox jumped over the lazy dog." - ); - expect(cipher.secureNote.type).toEqual(SecureNoteType.Generic); - }); - - it("should parse category 113 - Medical Record", async () => { - const importer = new Importer(); - const jsonString = JSON.stringify(MedicalRecordData); - const result = await importer.parse(jsonString); - expect(result != null).toBe(true); - const cipher = result.ciphers.shift(); - expect(cipher.type).toEqual(CipherType.SecureNote); - expect(cipher.name).toEqual("Some Health Record"); - expect(cipher.notes).toEqual("Some notes about my medical history"); - expect(cipher.secureNote.type).toEqual(SecureNoteType.Generic); - - expect(cipher.fields.length).toEqual(8); - validateCustomField(cipher.fields, "date", "Sat, 01 Jan 2022 12:01:00 GMT"); - validateCustomField(cipher.fields, "location", "some hospital/clinic"); - validateCustomField(cipher.fields, "healthcareprofessional", "Some Doctor"); - validateCustomField(cipher.fields, "patient", "Me"); - validateCustomField(cipher.fields, "reason", "unwell"); - validateCustomField(cipher.fields, "medication", "Insuline"); - validateCustomField(cipher.fields, "dosage", "1"); - validateCustomField(cipher.fields, "notes", "multiple times a day"); - }); - - it("should create folders", async () => { - const importer = new Importer(); - const result = await importer.parse(SanitizedExportJson); - expect(result != null).toBe(true); - - const folders = result.folders; - expect(folders.length).toBe(5); - expect(folders[0].name).toBe("Movies"); - expect(folders[1].name).toBe("Finance"); - expect(folders[2].name).toBe("Travel"); - expect(folders[3].name).toBe("Education"); - expect(folders[4].name).toBe("Starter Kit"); - - // Check that ciphers have a folder assigned to them - expect(result.ciphers.filter((c) => c.folderId === folders[0].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[1].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[2].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[3].id).length).toBeGreaterThan(0); - expect(result.ciphers.filter((c) => c.folderId === folders[4].id).length).toBeGreaterThan(0); - }); - - it("should create collections if part of an organization", async () => { - const importer = new Importer(); - importer.organizationId = Utils.newGuid(); - const result = await importer.parse(SanitizedExportJson); - expect(result != null).toBe(true); - - const collections = result.collections; - expect(collections.length).toBe(5); - expect(collections[0].name).toBe("Movies"); - expect(collections[1].name).toBe("Finance"); - expect(collections[2].name).toBe("Travel"); - expect(collections[3].name).toBe("Education"); - expect(collections[4].name).toBe("Starter Kit"); - }); -}); diff --git a/jslib/common/spec/importers/onepasswordMacCsvImporter.spec.ts b/jslib/common/spec/importers/onepasswordMacCsvImporter.spec.ts deleted file mode 100644 index a9c53a52a..000000000 --- a/jslib/common/spec/importers/onepasswordMacCsvImporter.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { OnePasswordMacCsvImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepasswordMacCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; - -import { data as creditCardData } from "./testData/onePasswordCsv/creditCard.mac.csv"; -import { data as identityData } from "./testData/onePasswordCsv/identity.mac.csv"; -import { data as multiTypeData } from "./testData/onePasswordCsv/multipleItems.mac.csv"; - -function expectIdentity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - - expect(cipher.identity).toEqual( - expect.objectContaining({ - firstName: "first name", - middleName: "mi", - lastName: "last name", - username: "userNam3", - company: "bitwarden", - phone: "8005555555", - email: "email@bitwarden.com", - }) - ); - - expect(cipher.notes).toContain("address\ncity state zip\nUnited States"); -} - -function expectCreditCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Card); - - expect(cipher.card).toEqual( - expect.objectContaining({ - number: "4111111111111111", - code: "111", - cardholderName: "test", - expMonth: "1", - expYear: "2030", - }) - ); -} - -describe("1Password mac CSV Importer", () => { - it("should parse identity records", async () => { - const importer = new Importer(); - const result = await importer.parse(identityData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectIdentity(cipher); - }); - - it("should parse credit card records", async () => { - const importer = new Importer(); - const result = await importer.parse(creditCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectCreditCard(cipher); - }); - - it("should parse csv's with multiple record type", async () => { - const importer = new Importer(); - const result = await importer.parse(multiTypeData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(4); - expectIdentity(result.ciphers[1]); - expectCreditCard(result.ciphers[2]); - }); -}); diff --git a/jslib/common/spec/importers/onepasswordWinCsvImporter.spec.ts b/jslib/common/spec/importers/onepasswordWinCsvImporter.spec.ts deleted file mode 100644 index 49693f3c5..000000000 --- a/jslib/common/spec/importers/onepasswordWinCsvImporter.spec.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { FieldType } from "@/jslib/common/src/enums/fieldType"; -import { OnePasswordWinCsvImporter as Importer } from "@/jslib/common/src/importers/onepasswordImporters/onepasswordWinCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { FieldView } from "@/jslib/common/src/models/view/fieldView"; - -import { data as creditCardData } from "./testData/onePasswordCsv/creditCard.windows.csv"; -import { data as identityData } from "./testData/onePasswordCsv/identity.windows.csv"; -import { data as multiTypeData } from "./testData/onePasswordCsv/multipleItems.windows.csv"; - -function expectIdentity(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Identity); - - expect(cipher.identity).toEqual( - expect.objectContaining({ - firstName: "first name", - middleName: "mi", - lastName: "last name", - username: "userNam3", - company: "bitwarden", - phone: "8005555555", - email: "email@bitwarden.com", - }) - ); - - expect(cipher.fields).toEqual( - expect.arrayContaining([ - Object.assign(new FieldView(), { - type: FieldType.Text, - name: "address", - value: "address city state zip us", - }), - ]) - ); -} - -function expectCreditCard(cipher: CipherView) { - expect(cipher.type).toBe(CipherType.Card); - - expect(cipher.card).toEqual( - expect.objectContaining({ - number: "4111111111111111", - code: "111", - cardholderName: "test", - expMonth: "1", - expYear: "1970", - }) - ); -} - -describe("1Password windows CSV Importer", () => { - let importer: Importer; - beforeEach(() => { - importer = new Importer(); - }); - - it("should parse identity records", async () => { - const result = await importer.parse(identityData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectIdentity(cipher); - }); - - it("should parse credit card records", async () => { - const result = await importer.parse(creditCardData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(1); - const cipher = result.ciphers[0]; - expectCreditCard(cipher); - }); - - it("should parse csv's with multiple record types", async () => { - const result = await importer.parse(multiTypeData); - - expect(result).not.toBeNull(); - expect(result.success).toBe(true); - expect(result.ciphers.length).toBe(4); - - expectIdentity(result.ciphers[1]); - expectCreditCard(result.ciphers[2]); - }); -}); diff --git a/jslib/common/spec/importers/safariCsvImporter.spec.ts b/jslib/common/spec/importers/safariCsvImporter.spec.ts deleted file mode 100644 index 4cbc56f8f..000000000 --- a/jslib/common/spec/importers/safariCsvImporter.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { SafariCsvImporter as Importer } from "@/jslib/common/src/importers/safariCsvImporter"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { LoginUriView } from "@/jslib/common/src/models/view/loginUriView"; -import { LoginView } from "@/jslib/common/src/models/view/loginView"; - -import { data as oldSimplePasswordData } from "./testData/safariCsv/oldSimplePasswordData.csv"; -import { data as simplePasswordData } from "./testData/safariCsv/simplePasswordData.csv"; - -const CipherData = [ - { - title: "should parse URLs in new CSV format", - csv: simplePasswordData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com (example_user)", - login: Object.assign(new LoginView(), { - username: "example_user", - password: "example_p@ssword", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - totp: "otpauth://totp/test?secret=examplesecret", - }), - notes: "Example note\nMore notes on new line", - type: 1, - }), - }, - { - title: "should parse URLs in old CSV format", - csv: oldSimplePasswordData, - expected: Object.assign(new CipherView(), { - id: null, - organizationId: null, - folderId: null, - name: "example.com (example_user)", - login: Object.assign(new LoginView(), { - username: "example_user", - password: "example_p@ssword", - uris: [ - Object.assign(new LoginUriView(), { - uri: "https://example.com", - }), - ], - }), - type: 1, - }), - }, -]; - -describe("Safari CSV Importer", () => { - CipherData.forEach((data) => { - it(data.title, async () => { - const importer = new Importer(); - const result = await importer.parse(data.csv); - expect(result != null).toBe(true); - expect(result.ciphers.length).toBeGreaterThan(0); - - const cipher = result.ciphers.shift(); - let property: keyof typeof data.expected; - for (property in data.expected) { - // eslint-disable-next-line - if (data.expected.hasOwnProperty(property)) { - // eslint-disable-next-line - expect(cipher.hasOwnProperty(property)).toBe(true); - expect(cipher[property]).toEqual(data.expected[property]); - } - } - }); - }); -}); diff --git a/jslib/common/spec/importers/testData/bitwardenJson/empty.json.ts b/jslib/common/spec/importers/testData/bitwardenJson/empty.json.ts deleted file mode 100644 index 43ab8c763..000000000 --- a/jslib/common/spec/importers/testData/bitwardenJson/empty.json.ts +++ /dev/null @@ -1 +0,0 @@ -export const data = '{"encrypted":false,"folders":[],"items":[]}'; diff --git a/jslib/common/spec/importers/testData/bitwardenJson/passwordProtected.json.ts b/jslib/common/spec/importers/testData/bitwardenJson/passwordProtected.json.ts deleted file mode 100644 index 0462e8342..000000000 --- a/jslib/common/spec/importers/testData/bitwardenJson/passwordProtected.json.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const data = `{ - "encrypted": true, - "passwordProtected": true, - "salt": "Oy0xcgVRzxQ+9NpB5GLehw==", - "kdfIterations": 100000, - "kdfType": 0, - "encKeyValidation_DO_NOT_EDIT": "2.sZs4Jc1HW9rhABzRRYR/gQ==|8kTDaDxafulnybpWoqVX8RAybhVRTr+dffNjms271Y7amQmIE1VSMwLbk+b2vxZb|IqOo6oXQtmv/Xb/GHDi42XG9c9ILePYtP5qq584VWcg=", - "data": "2.D0AXAf7G/XIwq6EC7A0Suw==|4w+m0wHRo25y1T1Syh5wdAUyF8voqEy54waMEsbnK0Nzee959w54ru5D1NntvxZL4HFqkQLyR6jCFkn5g40f+MGJgihS/wvf4NcJJfLiiFo6MEDOQNBkxw7ZBGuHiKfVuBO5u36JgzQtZ8lyFaduGxFszuF5c+URiE9PDh9jY0//poVgHKwuLZuYFIW+f7h6T+shUWK0ya11lcHn/B/CA2xiI+YiKdNZreJrwN0yslpJ/f+MrOzagvftRjt0GNkwveCtwcYUw/zFvqvibUpKeHcRiXs8SaGoHJ5RTm69FbJ7C5tnLwoVT89Af156uvRAXV7yAC4oPcbU/3TGb6hqYosvi1QNyaqG3M9gxS6+AK0C4yWuNbMLDEr+MWiw0SWLVMKQEkCZ4oM+oTCx52otW3+2V9I8Pv3KmmhkvVvE4wBdweOJeRX53Tf5ySkmpIhCfzj6JMmxO+nmTXIhWnJChr4hPVh+ixv1GQK5thIPTCMXmAtXoTIFUx1KWjS6LjOdi2hKQueVI+XZjf0qnY2vTMxRg0ZsLBA2znQTx+DSEqumORb5T/lV73pWZiCNePSAE2msOm7tep+lm4O/VCViCfXjITAY196syhOK0XnhxJvPALchZY8sYRAfuw6hHoDiVr+JUieRoI7eUrhXBp+D6Py9TL/dS/rHe+C2Zhx+xwx2NfGt+xEp8ZAOOCxgZ0UTeSA/abm0Oz7tJIK1n26acQrgbr7rMeBymAX+5L5OWlwI1hGgEBfj6W0rrbSXf3VMfaFXZ5UsXi1VhzQmU3LyWENoDeImXFQj6zMbUSfcVwLsG5Fg8Ee/kO/wJPfG5BO51+/vFqQj6AkaMEcwg5xNrObHYfQ/DMhIn7YDM2zdzbNTdhnobGkz6YRKFPCgFe3EmIEPEpeh9S3eKE9C7MQsrR8jVSiseR/FipJLsN+W7iOwzeXdwxUFlC/0a98bTKvdrbMgNi6ZVXykHY/t2UyEGpxZGTHoZwhX01kiQrwzC4/+v/676ldxPluO9GY7MtrLveCDsiyBz15u43IGHayDEBNT0rqrOKLYmfzwCWoahRLZQrSmepe/FXqgPqRfyWc/Ro+w3sT9dXUkx3B5xxWgSyABowPV48yBUSJuefhKTpqgzkU+LzhNnWHjnxJzzQ2/|IhlRjnyhIoDM85qHX/bY2zaIU5YaRO/iFVTQDd3uFDo=" -}`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/credentials.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/credentials.csv.ts deleted file mode 100644 index 78e42cb1a..000000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/credentials.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const credentialsData = `username,username2,username3,title,password,note,url,category,otpSecret -jdoe,,,example.com,somePassword,some note for example.com,https://www.example.com,Entertainment,someTOTPSeed`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/id.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/id.csv.ts deleted file mode 100644 index 1c939557b..000000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/id.csv.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const identityData = `type,number,name,issue_date,expiration_date,place_of_issue,state -card,123123123,John Doe,2022-1-30,2032-1-30,, -passport,123123123,John Doe,2022-1-30,2032-1-30,somewhere in Germany, -license,1234556,John Doe,2022-8-10,2022-10-10,,DC -social_security,123123123,John Doe,,,, -tax_number,123123123,,,,,`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/multiplePersonalInfo.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/multiplePersonalInfo.csv.ts deleted file mode 100644 index cca5748b4..000000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/multiplePersonalInfo.csv.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const multiplePersonalInfoData = `type,title,first_name,middle_name,last_name,login,date_of_birth,place_of_birth,email,email_type,item_name,phone_number,address,country,state,city,zip,address_recipient,address_building,address_apartment,address_floor,address_door_code,job_title,url -name,MR,John,,Doe,jdoe,2022-01-30,world,,,,,,,,,,,,,,,, -email,,,,,,,,jdoe@example.com,personal,Johns email,,,,,,,,,,,,, -number,,,,,,,,,,John's number,+49123123123,,,,,,,,,,,, -address,,,,,,,,,,John's home address,,1 some street,de,DE-0-NW,some city,123123,John,1,1,1,123,, -website,,,,,,,,,,Website,,,,,,,,,,,,,website.com -name,Mrs,Jane,,Doe,jdoe,2022-01-30,earth,,,,,,,,,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/payments.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/payments.csv.ts deleted file mode 100644 index 336986c1c..000000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/payments.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const paymentsData = `type,account_name,account_holder,cc_number,code,expiration_month,expiration_year,routing_number,account_number,country,issuing_bank -bank,John's savings account,John Doe,,,,,routingNumber,accountNumber,US,US-ALLY -credit_card,John Doe,,41111111111111111,123,01,2023,,,US,`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/personalInfo.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/personalInfo.csv.ts deleted file mode 100644 index ec99f8006..000000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/personalInfo.csv.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const personalInfoData = `type,title,first_name,middle_name,last_name,login,date_of_birth,place_of_birth,email,email_type,item_name,phone_number,address,country,state,city,zip,address_recipient,address_building,address_apartment,address_floor,address_door_code,job_title,url -name,MR,John,,Doe,jdoe,2022-01-30,world,,,,,,,,,,,,,,,, -email,,,,,,,,jdoe@example.com,personal,Johns email,,,,,,,,,,,,, -number,,,,,,,,,,John's number,+49123123123,,,,,,,,,,,, -address,,,,,,,,,,John's home address,,1 some street,de,DE-0-NW,some city,123123,John,1,1,1,123,, -website,,,,,,,,,,Website,,,,,,,,,,,,,website.com`; diff --git a/jslib/common/spec/importers/testData/dashlaneCsv/securenotes.csv.ts b/jslib/common/spec/importers/testData/dashlaneCsv/securenotes.csv.ts deleted file mode 100644 index 22a3b904f..000000000 --- a/jslib/common/spec/importers/testData/dashlaneCsv/securenotes.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const secureNoteData = `title,note -01,test`; diff --git a/jslib/common/spec/importers/testData/firefoxCsv/firefoxAccountsData.csv.ts b/jslib/common/spec/importers/testData/firefoxCsv/firefoxAccountsData.csv.ts deleted file mode 100644 index 2f2c1b55e..000000000 --- a/jslib/common/spec/importers/testData/firefoxCsv/firefoxAccountsData.csv.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const data = `"url","username","password","httpRealm","formActionOrigin","guid","timeCreated","timeLastUsed","timePasswordChanged" -"chrome://FirefoxAccounts","bla-bla-foo-bar","{""version"":1,""accountData"":{""kSync"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kXCS"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kExtSync"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kExtKbHash"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""scopedKeys"":{""https://identity.mozilla.com/apps/oldsync"":{""kid"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",""k"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kty"":""xxx""},""sync:addon_storage"":{""kid"":""xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""k"":""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"",""kty"":""xxx""}}}}","Firefox Accounts credentials",,"{d61e37fa-2bc4-469a-bd66-41fd3b0005e0}","1612345678900","1612345678900","1612345678900" -"https://example.com","foo","bar",,"","{d61e37fa-2bc4-469a-bd66-41fd3b0005e0}","1612345678900","1612345678900","1612345678900" -`; diff --git a/jslib/common/spec/importers/testData/firefoxCsv/simplePasswordData.csv.ts b/jslib/common/spec/importers/testData/firefoxCsv/simplePasswordData.csv.ts deleted file mode 100644 index 90e19f199..000000000 --- a/jslib/common/spec/importers/testData/firefoxCsv/simplePasswordData.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `"url","username","password","httpRealm","formActionOrigin","guid","timeCreated","timeLastUsed","timePasswordChanged" -"https://example.com","foo","bar",,"","{d61e37fa-2bc4-469a-bd66-41fd3b0005e0}","1612345678900","1612345678900","1612345678900"`; diff --git a/jslib/common/spec/importers/testData/keeperJson/testData.ts b/jslib/common/spec/importers/testData/keeperJson/testData.ts deleted file mode 100644 index d537c1ee4..000000000 --- a/jslib/common/spec/importers/testData/keeperJson/testData.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { KeeperJsonExport } from "@/jslib/common/src/importers/keeperImporters/types/keeperJsonTypes"; - -export const testData: KeeperJsonExport = { - shared_folders: [ - { - path: "My Customer 1", - manage_users: true, - manage_records: true, - can_edit: true, - can_share: true, - permissions: [ - { - uid: "kVM96KGEoGxhskZoSTd_jw", - manage_users: true, - manage_records: true, - }, - { - name: "user@mycompany.com", - manage_users: true, - manage_records: true, - }, - ], - }, - { - path: "Testing\\My Customer 2", - manage_users: true, - manage_records: true, - can_edit: true, - can_share: true, - permissions: [ - { - uid: "ih1CggiQ-3ENXcn4G0sl-g", - manage_users: true, - manage_records: true, - }, - { - name: "user@mycompany.com", - manage_users: true, - manage_records: true, - }, - ], - }, - ], - records: [ - { - title: "Bank Account 1", - login: "customer1234", - password: "4813fJDHF4239fdk", - login_url: "https://chase.com", - notes: "These are some notes.", - custom_fields: { - "Account Number": "123-456-789", - }, - folders: [ - { - folder: "Optional Private Folder 1", - }, - ], - }, - { - title: "Bank Account 2", - login: "mybankusername", - password: "w4k4k193f$^&@#*%2", - login_url: "https://amex.com", - notes: "Some great information here.", - custom_fields: { - "Security Group": "Public", - "IP Address": "12.45.67.8", - "TFC:Keeper": - "otpauth://totp/Amazon:me@company.com?secret=JBSWY3DPEHPK3PXP&issuer=Amazon&algorithm=SHA1&digits=6&period=30", - }, - folders: [ - { - folder: "Optional Private Folder 1", - }, - { - shared_folder: "My Customer 1", - can_edit: true, - can_share: true, - }, - ], - }, - { - title: "Some Account", - login: "someUserName", - password: "w4k4k1wergf$^&@#*%2", - login_url: "https://example.com", - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserAccount.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserAccount.csv.ts deleted file mode 100644 index 5ccf0971d..000000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserAccount.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userAccountData = `nickname,url,username,password,additionalInfo,twofaSecret,status,tags -PasswordNickname,www.google.com,user.name@email.com,abc123,This is the additional information text.,someTOTPSeed,active,someTag`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserCreditCard.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserCreditCard.csv.ts deleted file mode 100644 index 0b127627a..000000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserCreditCard.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userCreditCardData = `nickname,status,tags,cardNumber,cardName,exp_month,exp_year,cvv,additionalInfo -Visa test card,active,someTag,4111111111111111,Joe User,04,24,222,This is the additional information field`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserIdCard.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserIdCard.csv.ts deleted file mode 100644 index 8f3fa600e..000000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserIdCard.csv.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable */ -export const userIdCardData = `nickname,status,tags,idType,idNumber,idName,idIssuanceDate,idExpirationDate,idCountry,additionalInfo -Joe User's nickname,active,someTag,Driver's License,123456,Joe M User,02/02/2022,02/02/2024,United States,Additional information -Passport ID card,active,someTag,Passport,1234567,Joe M User,03/07/2022,03/07/2028,United States,Additional information field -Social Security ID card,active,someTag,Social Security,123455678,Joe M User,03/07/2022,03/07/2028,United States,Additional information field text -ID card type ID card,active,someTag,ID Card,1234566,Joe M User,03/07/2022,03/07/2028,United States,Additional Information field text -Tax number ID card,active,someTag,Tax Number,12345678,Joe M User,03/07/2022,03/07/2028,United States,Additinoal information text field -Bank account ID card,active,someTag,Bank Account,12344556677,Joe M User,03/07/2022,03/07/2028,United States,Additional text information here -Insurance card ID card,active,someTag,Insurance Card,123456677,Joe M User,03/07/2022,03/07/2022,United States,Additional information text goes here -Health card Id card,active,someTag,Health Card,1234670,Joe M User,03/07/2022,03/07/2028,United States,More info -Membership ID card,active,someTag,Membership,12345709,Joe M User,03/07/2022,03/07/2028,United States,Add'l info -Database ID card,active,someTag,Database,12345089u,Joe M User,03/07/2022,03/07/2028,United States,Addin't info -Outdoor license ID card,active,someTag,Outdoor License,123890090,Joe M User,03/07/2022,03/07/2028,United States,Additional info -Reward program Id card,active,someTag,Reward Program,12345890b,Joe M User,03/07/2022,03/07/2028,United States,1234890 -Software license ID card,active,someTag,Software License,1234567c,Joe M User,03/07/2022,03/07/2028,United States,"It seems like the fields don't change, which makes it pretty useless that they have so many ID card types." -Tour visa ID card,active,someTag,Tour Visa,123456lkhj,Joe M User,03/07/2022,03/07/2028,United States,Additional Informaion text`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserIdentity.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserIdentity.csv.ts deleted file mode 100644 index 13afb16da..000000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserIdentity.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userIdentityData = `nickname,status,tags,firstName,middleName,lastName,email,firstAddressLine,secondAddressLine,title,gender,number,city,country,zipCode,additionalInfo -Joe User's nickname,active,someTag,Joe,M,User,joe.user@email.com,1 Example House,Suite 300,Mr,Male,2223334444,Portland,United States,04101,Additional information field`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserNote.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserNote.csv.ts deleted file mode 100644 index 8094c92f2..000000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserNote.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userNoteData = `nickname,status,content -The title of a secure note,active,"The content of a secure note. Lorem ipsum, etc."`; diff --git a/jslib/common/spec/importers/testData/mykiCsv/UserTwofa.csv.ts b/jslib/common/spec/importers/testData/mykiCsv/UserTwofa.csv.ts deleted file mode 100644 index 68cfd44f3..000000000 --- a/jslib/common/spec/importers/testData/mykiCsv/UserTwofa.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable */ -export const userTwoFaData = `nickname,status,tags,authToken,additionalInfo -2FA nickname,active,someTag,someTOTPSeed,"Additional information field content. "`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.card.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.card.csv.ts deleted file mode 100644 index 8d79d2b1b..000000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.card.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -SomeVisa,,,,,SomeHolder,4024007103939509,123,01 / 22,12345,,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.identity.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.identity.csv.ts deleted file mode 100644 index 4dde389c7..000000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.identity.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -SomeTitle,,,,SomeNoteToMyIdentity,,,,,123456,,#fullName,123456789,hello@bitwarden.com,Test street 123,additional addressinfo,Cologne,Germany,North-Rhine-Westphalia`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.login.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.login.csv.ts deleted file mode 100644 index e2af76b0f..000000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.login.csv.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -SomeVaultItemName,https://example.com,hello@bitwarden.com,someStrongPassword,Some note for the VaultItem,,,,,,SomeFolderForVaultItem,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.secureNote.csv.ts b/jslib/common/spec/importers/testData/nordpassCsv/nordpass.secureNote.csv.ts deleted file mode 100644 index 0e4dcb2ef..000000000 --- a/jslib/common/spec/importers/testData/nordpassCsv/nordpass.secureNote.csv.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const data = `name,url,username,password,note,cardholdername,cardnumber,cvc,expirydate,zipcode,folder,full_name,phone_number,email,address1,address2,city,country,state -notesFolder,,,,,,,,,,,,,,,,,, -MySuperSecureNoteTitle,,,,MySuperSecureNote,,,,,,notesFolder,,,,,,,,`; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/APICredentials.ts b/jslib/common/spec/importers/testData/onePassword1Pux/APICredentials.ts deleted file mode 100644 index fb44e7c52..000000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/APICredentials.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const APICredentialsData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "6nqnjdqyk5mwvqbdgbdr47oabe", - favIndex: 0, - createdAt: 1619465969, - updatedAt: 1619466052, - trashed: false, - categoryUuid: "112", - details: { - loginFields: [], - notesPlain: "My API Credential", - sections: [ - { - title: "", - fields: [ - { - title: "username", - id: "username", - value: { - string: "apiuser@nullvalue.test", - }, - indexAtSource: 0, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "credential", - id: "credential", - value: { - concealed: "apiapiapiapiapiapiappy", - }, - indexAtSource: 1, - guarded: true, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "default", - }, - }, - { - title: "type", - id: "type", - value: { - menu: "jwt", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "filename", - id: "filename", - value: { - string: "filename.jwt", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "valid from", - id: "validFrom", - value: { - date: 1301918460, - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "expires", - id: "expires", - value: { - date: 1932811260, - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "hostname", - id: "hostname", - value: { - string: "not.your.everyday.hostname", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "uRL", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "", - title: "API Credential", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/BankAccount.ts b/jslib/common/spec/importers/testData/onePassword1Pux/BankAccount.ts deleted file mode 100644 index 8278e2e6d..000000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/BankAccount.ts +++ /dev/null @@ -1,224 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const BankAccountData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "u2l4sjbencvsowwjuj3dfpt73q", - favIndex: 0, - createdAt: 1619466056, - updatedAt: 1619466187, - trashed: false, - categoryUuid: "101", - details: { - loginFields: [], - notesPlain: "My Bank Account", - sections: [ - { - title: "", - fields: [ - { - title: "bank name", - id: "bankName", - value: { - string: "Super Credit Union", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "name on account", - id: "owner", - value: { - string: "Cool Guy", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "type", - id: "accountType", - value: { - menu: "checking", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "routing number", - id: "routingNo", - value: { - string: "111000999", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "account number", - id: "accountNo", - value: { - string: "192837465918273645", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "SWIFT", - id: "swift", - value: { - string: "123456", - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "IBAN", - id: "iban", - value: { - string: "DE12 123456", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "PIN", - id: "telephonePin", - value: { - concealed: "5555", - }, - indexAtSource: 7, - guarded: false, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - { - title: "Branch Information", - name: "branchInfo", - fields: [ - { - title: "phone", - id: "branchPhone", - value: { - phone: "9399399933", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "address", - id: "branchAddress", - value: { - string: "1 Fifth Avenue", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "sentences", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "Super Credit Union", - tags: ["Finance"], - title: "Bank Account", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/CreditCard.ts b/jslib/common/spec/importers/testData/onePassword1Pux/CreditCard.ts deleted file mode 100644 index 8b24d1b91..000000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/CreditCard.ts +++ /dev/null @@ -1,343 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const CreditCardData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "vpxi2esuujz7nrbojp34rd5aja", - favIndex: 0, - createdAt: 1619465282, - updatedAt: 1619465447, - trashed: false, - categoryUuid: "002", - details: { - loginFields: [], - notesPlain: "My parents' credit card. ", - sections: [ - { - title: "", - fields: [ - { - title: "cardholder name", - id: "cardholder", - value: { - string: "Fred Engels", - }, - indexAtSource: 0, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "type", - id: "type", - value: { - creditCardType: "discover", - }, - indexAtSource: 1, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "number", - id: "ccnum", - value: { - creditCardNumber: "6011111111111117", - }, - indexAtSource: 2, - guarded: true, - clipboardFilter: "0123456789", - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "verification number", - id: "cvv", - value: { - concealed: "1312", - }, - indexAtSource: 3, - guarded: true, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "expiry date", - id: "expiry", - value: { - monthYear: 209912, - }, - indexAtSource: 4, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "valid from", - id: "validFrom", - value: { - monthYear: 200101, - }, - indexAtSource: 5, - guarded: true, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "", - id: "txbzvwzpck7ejhfres3733rbpm", - value: { - string: "card", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - { - title: "Contact Information", - name: "contactInfo", - fields: [ - { - title: "issuing bank", - id: "bank", - value: { - string: "Some bank", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "phone (local)", - id: "phoneLocal", - value: { - phone: "123456", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "phone (toll free)", - id: "phoneTollFree", - value: { - phone: "0800123456", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "phone (intl)", - id: "phoneIntl", - value: { - phone: "+49123456", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "namePhonePad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "website", - id: "website", - value: { - url: "somebank.com", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - { - title: "Additional Details", - name: "details", - fields: [ - { - title: "PIN", - id: "pin", - value: { - concealed: "1234", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: true, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "credit limit", - id: "creditLimit", - value: { - string: "$1312", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "cash withdrawal limit", - id: "cashLimit", - value: { - string: "$500", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "interest rate", - id: "interest", - value: { - string: "1%", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numbersAndPunctuation", - correction: "default", - capitalization: "default", - }, - }, - { - title: "issue number", - id: "issuenumber", - value: { - string: "123456", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "1234 **** 6789", - tags: ["Finance"], - title: "Parent's Credit Card", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/Database.ts b/jslib/common/spec/importers/testData/onePassword1Pux/Database.ts deleted file mode 100644 index 8e80874c2..000000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/Database.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const DatabaseData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "ospvepl3ex2y6hjwwqwyvtf2sy", - favIndex: 0, - createdAt: 1619466193, - updatedAt: 1619466276, - trashed: false, - categoryUuid: "102", - details: { - loginFields: [], - notesPlain: "My Database", - sections: [ - { - title: "", - fields: [ - { - title: "type", - id: "database_type", - value: { - menu: "postgresql", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "server", - id: "hostname", - value: { - string: "my.secret.db.server", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "uRL", - correction: "default", - capitalization: "default", - }, - }, - { - title: "port", - id: "port", - value: { - string: "1337", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "database", - id: "database", - value: { - string: "user_database", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "username", - id: "username", - value: { - string: "cooldbuser", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "password", - id: "password", - value: { - concealed: "^+kTjhLaN7wVPAhGU)*J", - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "SID", - id: "sid", - value: { - string: "ASDIUFU-283234", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "alias", - id: "alias", - value: { - string: "cdbu", - }, - indexAtSource: 7, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "connection options", - id: "options", - value: { - string: "ssh", - }, - indexAtSource: 8, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "my.secret.db.server", - title: "Database", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/DriversLicense.ts b/jslib/common/spec/importers/testData/onePassword1Pux/DriversLicense.ts deleted file mode 100644 index e35aed1e4..000000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/DriversLicense.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const DriversLicenseData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "nntuge2g7s2wrlokyfhea354ay", - favIndex: 0, - createdAt: 1619466279, - updatedAt: 1619466425, - trashed: false, - categoryUuid: "103", - details: { - loginFields: [], - notesPlain: "My Driver's License", - sections: [ - { - title: "", - fields: [ - { - title: "full name", - id: "fullname", - value: { - string: "Michael Scarn", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "words", - }, - }, - { - title: "address", - id: "address", - value: { - string: "2120 Mifflin Rd.", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "sentences", - }, - }, - { - title: "date of birth", - id: "birthdate", - value: { - date: 252504060, - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "sex", - id: "sex", - value: { - gender: "male", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "height", - id: "height", - value: { - string: "5'11\"", - }, - indexAtSource: 4, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "number", - id: "number", - value: { - string: "12345678901", - }, - indexAtSource: 5, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "license class", - id: "class", - value: { - string: "C", - }, - indexAtSource: 6, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "conditions / restrictions", - id: "conditions", - value: { - string: "B", - }, - indexAtSource: 7, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "state", - id: "state", - value: { - string: "Pennsylvania", - }, - indexAtSource: 8, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "country", - id: "country", - value: { - string: "United States", - }, - indexAtSource: 9, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "expiry date", - id: "expiry_date", - value: { - monthYear: 203012, - }, - indexAtSource: 10, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - ], - }, - ], - passwordHistory: [], - }, - overview: { - subtitle: "12345678901", - title: "Michael Scarn", - url: "", - ps: 0, - pbe: 0.0, - pgrng: false, - }, - }, - ], - }, - ], - }, - ], -}; diff --git a/jslib/common/spec/importers/testData/onePassword1Pux/EmailAccount.ts b/jslib/common/spec/importers/testData/onePassword1Pux/EmailAccount.ts deleted file mode 100644 index e345891d7..000000000 --- a/jslib/common/spec/importers/testData/onePassword1Pux/EmailAccount.ts +++ /dev/null @@ -1,341 +0,0 @@ -import { ExportData } from "@/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes"; - -export const EmailAccountData: ExportData = { - accounts: [ - { - attrs: { - accountName: "1Password Customer", - name: "1Password Customer", - avatar: "", - email: "username123123123@gmail.com", - uuid: "TRIZ3XV4JJFRXJ3BARILLTUA6E", - domain: "https://my.1password.com/", - }, - vaults: [ - { - attrs: { - uuid: "pqcgbqjxr4tng2hsqt5ffrgwju", - desc: "Just test entries", - avatar: "ke7i5rxnjrh3tj6uesstcosspu.png", - name: "T's Test Vault", - type: "U", - }, - items: [ - { - uuid: "p3hohdgwpt4u2ra2fc3tvzomsm", - favIndex: 0, - createdAt: 1619466428, - updatedAt: 1619466585, - trashed: false, - categoryUuid: "111", - details: { - loginFields: [], - notesPlain: "My Email Config", - sections: [ - { - title: "", - fields: [ - { - title: "type", - id: "pop_type", - value: { - menu: "either", - }, - indexAtSource: 0, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "default", - capitalization: "default", - }, - }, - { - title: "username", - id: "pop_username", - value: { - string: "someuser@nullvalue.test", - }, - indexAtSource: 1, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "default", - correction: "no", - capitalization: "none", - }, - }, - { - title: "server", - id: "pop_server", - value: { - string: "mailserver.nullvalue.test", - }, - indexAtSource: 2, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "uRL", - correction: "default", - capitalization: "default", - }, - }, - { - title: "port number", - id: "pop_port", - value: { - string: "587", - }, - indexAtSource: 3, - guarded: false, - multiline: false, - dontGenerate: false, - inputTraits: { - keyboard: "numberPad", - correction: "default", - capitalization: "default", - }, - }, - { - title: "password", - id: "pop_password", - value: { - concealed: "u1jsf - - - - - - - - - - - - This is a sample note. - 3 - - - - 5555123456789000 - John Smith - 01/23 - 555 - 1111 - 555-0153 - 1 - - - john555@gmail.com - early91*Fail* - https://www.facebook.com - 3 - - - john555@gmail.com - plain79{Area{ - https://www.google.com - 3 - thisisanotp - thisshouldbehidden - - - 555111111 - John Smith - 05/05/1980 - 01/01/2018 - 01/01/2028 - 3 - This is a note attached to a card - - - john555@gmail.com - https://twitter.com - 3 - shouldbepassword - - - john555 - Save63\apple\ - 3 - - -`; diff --git a/jslib/common/spec/services/export.service.spec.ts b/jslib/common/spec/services/export.service.spec.ts deleted file mode 100644 index 7361e2923..000000000 --- a/jslib/common/spec/services/export.service.spec.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { CipherService } from "@/jslib/common/src/abstractions/cipher.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { CryptoFunctionService } from "@/jslib/common/src/abstractions/cryptoFunction.service"; -import { FolderService } from "@/jslib/common/src/abstractions/folder.service"; -import { CipherType } from "@/jslib/common/src/enums/cipherType"; -import { KdfType } from "@/jslib/common/src/enums/kdfType"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { Cipher } from "@/jslib/common/src/models/domain/cipher"; -import { EncString } from "@/jslib/common/src/models/domain/encString"; -import { Login } from "@/jslib/common/src/models/domain/login"; -import { CipherWithIds as CipherExport } from "@/jslib/common/src/models/export/cipherWithIds"; -import { CipherView } from "@/jslib/common/src/models/view/cipherView"; -import { LoginView } from "@/jslib/common/src/models/view/loginView"; -import { ExportService } from "@/jslib/common/src/services/export.service"; - -import { BuildTestObject, GetUniqueString } from "../utils"; - -const UserCipherViews = [ - generateCipherView(false), - generateCipherView(false), - generateCipherView(true), -]; - -const UserCipherDomains = [ - generateCipherDomain(false), - generateCipherDomain(false), - generateCipherDomain(true), -]; - -function generateCipherView(deleted: boolean) { - return BuildTestObject( - { - id: GetUniqueString("id"), - notes: GetUniqueString("notes"), - type: CipherType.Login, - login: BuildTestObject( - { - username: GetUniqueString("username"), - password: GetUniqueString("password"), - }, - LoginView - ), - collectionIds: null, - deletedDate: deleted ? new Date() : null, - }, - CipherView - ); -} - -function generateCipherDomain(deleted: boolean) { - return BuildTestObject( - { - id: GetUniqueString("id"), - notes: new EncString(GetUniqueString("notes")), - type: CipherType.Login, - login: BuildTestObject( - { - username: new EncString(GetUniqueString("username")), - password: new EncString(GetUniqueString("password")), - }, - Login - ), - collectionIds: null, - deletedDate: deleted ? new Date() : null, - }, - Cipher - ); -} - -function expectEqualCiphers(ciphers: CipherView[] | Cipher[], jsonResult: string) { - const actual = JSON.stringify(JSON.parse(jsonResult).items); - const items: CipherExport[] = []; - ciphers.forEach((c: CipherView | Cipher) => { - const item = new CipherExport(); - item.build(c); - items.push(item); - }); - - expect(actual).toEqual(JSON.stringify(items)); -} - -describe("ExportService", () => { - let exportService: ExportService; - let apiService: SubstituteOf; - let cryptoFunctionService: SubstituteOf; - let cipherService: SubstituteOf; - let folderService: SubstituteOf; - let cryptoService: SubstituteOf; - - beforeEach(() => { - apiService = Substitute.for(); - cryptoFunctionService = Substitute.for(); - cipherService = Substitute.for(); - folderService = Substitute.for(); - cryptoService = Substitute.for(); - - folderService.getAllDecrypted().resolves([]); - folderService.getAll().resolves([]); - - exportService = new ExportService( - folderService, - cipherService, - apiService, - cryptoService, - cryptoFunctionService - ); - }); - - it("exports unecrypted user ciphers", async () => { - cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); - - const actual = await exportService.getExport("json"); - - expectEqualCiphers(UserCipherViews.slice(0, 1), actual); - }); - - it("exports encrypted json user ciphers", async () => { - cipherService.getAll().resolves(UserCipherDomains.slice(0, 1)); - - const actual = await exportService.getExport("encrypted_json"); - - expectEqualCiphers(UserCipherDomains.slice(0, 1), actual); - }); - - it("does not unecrypted export trashed user items", async () => { - cipherService.getAllDecrypted().resolves(UserCipherViews); - - const actual = await exportService.getExport("json"); - - expectEqualCiphers(UserCipherViews.slice(0, 2), actual); - }); - - it("does not encrypted export trashed user items", async () => { - cipherService.getAll().resolves(UserCipherDomains); - - const actual = await exportService.getExport("encrypted_json"); - - expectEqualCiphers(UserCipherDomains.slice(0, 2), actual); - }); - - describe("password protected export", () => { - let exportString: string; - let exportObject: any; - let mac: SubstituteOf; - let data: SubstituteOf; - const password = "password"; - const salt = "salt"; - - describe("export json object", () => { - beforeEach(async () => { - mac = Substitute.for(); - data = Substitute.for(); - - mac.encryptedString.returns("mac"); - data.encryptedString.returns("encData"); - - jest.spyOn(Utils, "fromBufferToB64").mockReturnValue(salt); - cipherService.getAllDecrypted().resolves(UserCipherViews.slice(0, 1)); - - exportString = await exportService.getPasswordProtectedExport(password); - exportObject = JSON.parse(exportString); - }); - - it("specifies it is encrypted", () => { - expect(exportObject.encrypted).toBe(true); - }); - - it("specifies it's password protected", () => { - expect(exportObject.passwordProtected).toBe(true); - }); - - it("specifies salt", () => { - expect(exportObject.salt).toEqual("salt"); - }); - - it("specifies kdfIterations", () => { - expect(exportObject.kdfIterations).toEqual(100000); - }); - - it("has kdfType", () => { - expect(exportObject.kdfType).toEqual(KdfType.PBKDF2_SHA256); - }); - - it("has a mac property", async () => { - cryptoService.encrypt(Arg.any(), Arg.any()).resolves(mac); - exportString = await exportService.getPasswordProtectedExport(password); - exportObject = JSON.parse(exportString); - - expect(exportObject.encKeyValidation_DO_NOT_EDIT).toEqual(mac.encryptedString); - }); - - it("has data property", async () => { - cryptoService.encrypt(Arg.any(), Arg.any()).resolves(data); - exportString = await exportService.getPasswordProtectedExport(password); - exportObject = JSON.parse(exportString); - - expect(exportObject.data).toEqual(data.encryptedString); - }); - - it("encrypts the data property", async () => { - const unencrypted = await exportService.getExport(); - expect(exportObject.data).not.toEqual(unencrypted); - }); - }); - }); -}); diff --git a/jslib/common/spec/services/import.service.spec.ts b/jslib/common/spec/services/import.service.spec.ts deleted file mode 100644 index 6feaf2c46..000000000 --- a/jslib/common/spec/services/import.service.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; - -import { ApiService } from "@/jslib/common/src/abstractions/api.service"; -import { CipherService } from "@/jslib/common/src/abstractions/cipher.service"; -import { CollectionService } from "@/jslib/common/src/abstractions/collection.service"; -import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service"; -import { FolderService } from "@/jslib/common/src/abstractions/folder.service"; -import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; -import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service"; -import { BitwardenPasswordProtectedImporter } from "@/jslib/common/src/importers/bitwardenPasswordProtectedImporter"; -import { Importer } from "@/jslib/common/src/importers/importer"; -import { Utils } from "@/jslib/common/src/misc/utils"; -import { ImportService } from "@/jslib/common/src/services/import.service"; - -describe("ImportService", () => { - let importService: ImportService; - let cipherService: SubstituteOf; - let folderService: SubstituteOf; - let apiService: SubstituteOf; - let i18nService: SubstituteOf; - let collectionService: SubstituteOf; - let platformUtilsService: SubstituteOf; - let cryptoService: SubstituteOf; - - beforeEach(() => { - cipherService = Substitute.for(); - folderService = Substitute.for(); - apiService = Substitute.for(); - i18nService = Substitute.for(); - collectionService = Substitute.for(); - platformUtilsService = Substitute.for(); - cryptoService = Substitute.for(); - - importService = new ImportService( - cipherService, - folderService, - apiService, - i18nService, - collectionService, - platformUtilsService, - cryptoService - ); - }); - - describe("getImporterInstance", () => { - describe("Get bitPasswordProtected importer", () => { - let importer: Importer; - const organizationId = Utils.newGuid(); - const password = Utils.newGuid(); - - beforeEach(() => { - importer = importService.getImporter( - "bitwardenpasswordprotected", - organizationId, - password - ); - }); - - it("returns an instance of BitwardenPasswordProtectedImporter", () => { - expect(importer).toBeInstanceOf(BitwardenPasswordProtectedImporter); - }); - - it("has the appropriate organization Id", () => { - expect(importer.organizationId).toEqual(organizationId); - }); - - it("has the appropriate password", () => { - expect(Object.entries(importer)).toEqual(expect.arrayContaining([["password", password]])); - }); - }); - }); -}); diff --git a/jslib/common/src/abstractions/export.service.ts b/jslib/common/src/abstractions/export.service.ts deleted file mode 100644 index b0266530b..000000000 --- a/jslib/common/src/abstractions/export.service.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { EventView } from "../models/view/eventView"; - -export type ExportFormat = "csv" | "json" | "encrypted_json"; - -export abstract class ExportService { - getExport: (format?: ExportFormat, organizationId?: string) => Promise; - getPasswordProtectedExport: (password: string, organizationId?: string) => Promise; - getOrganizationExport: (organizationId: string, format?: ExportFormat) => Promise; - getEventExport: (events: EventView[]) => Promise; - getFileName: (prefix?: string, extension?: string) => string; -} diff --git a/jslib/common/src/abstractions/import.service.ts b/jslib/common/src/abstractions/import.service.ts deleted file mode 100644 index 01f099b31..000000000 --- a/jslib/common/src/abstractions/import.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ImportOption, ImportType } from "../enums/importOptions"; -import { ImportError } from "../importers/importError"; -import { Importer } from "../importers/importer"; - -export abstract class ImportService { - featuredImportOptions: readonly ImportOption[]; - regularImportOptions: readonly ImportOption[]; - getImportOptions: () => ImportOption[]; - import: ( - importer: Importer, - fileContents: string, - organizationId?: string - ) => Promise; - getImporter: ( - format: ImportType | "bitwardenpasswordprotected", - organizationId: string, - password?: string - ) => Importer; -} diff --git a/jslib/common/src/enums/importOptions.ts b/jslib/common/src/enums/importOptions.ts deleted file mode 100644 index 28181db4b..000000000 --- a/jslib/common/src/enums/importOptions.ts +++ /dev/null @@ -1,74 +0,0 @@ -export interface ImportOption { - id: string; - name: string; -} - -export const featuredImportOptions = [ - { id: "bitwardenjson", name: "Bitwarden (json)" }, - { id: "bitwardencsv", name: "Bitwarden (csv)" }, - { id: "chromecsv", name: "Chrome (csv)" }, - { id: "dashlanecsv", name: "Dashlane (csv)" }, - { id: "firefoxcsv", name: "Firefox (csv)" }, - { id: "keepass2xml", name: "KeePass 2 (xml)" }, - { id: "lastpasscsv", name: "LastPass (csv)" }, - { id: "safaricsv", name: "Safari and macOS (csv)" }, - { id: "1password1pux", name: "1Password (1pux)" }, -] as const; - -export const regularImportOptions = [ - { id: "keepassxcsv", name: "KeePassX (csv)" }, - { id: "1password1pif", name: "1Password (1pif)" }, - { id: "1passwordwincsv", name: "1Password 6 and 7 Windows (csv)" }, - { id: "1passwordmaccsv", name: "1Password 6 and 7 Mac (csv)" }, - { id: "dashlanejson", name: "Dashlane (json)" }, - { id: "roboformcsv", name: "RoboForm (csv)" }, - { id: "keepercsv", name: "Keeper (csv)" }, - // Temporarily remove this option for the Feb release - // { id: "keeperjson", name: "Keeper (json)" }, - { id: "enpasscsv", name: "Enpass (csv)" }, - { id: "enpassjson", name: "Enpass (json)" }, - { id: "safeincloudxml", name: "SafeInCloud (xml)" }, - { id: "pwsafexml", name: "Password Safe (xml)" }, - { id: "stickypasswordxml", name: "Sticky Password (xml)" }, - { id: "msecurecsv", name: "mSecure (csv)" }, - { id: "truekeycsv", name: "True Key (csv)" }, - { id: "passwordbossjson", name: "Password Boss (json)" }, - { id: "zohovaultcsv", name: "Zoho Vault (csv)" }, - { id: "splashidcsv", name: "SplashID (csv)" }, - { id: "passworddragonxml", name: "Password Dragon (xml)" }, - { id: "padlockcsv", name: "Padlock (csv)" }, - { id: "passboltcsv", name: "Passbolt (csv)" }, - { id: "clipperzhtml", name: "Clipperz (html)" }, - { id: "aviracsv", name: "Avira (csv)" }, - { id: "saferpasscsv", name: "SaferPass (csv)" }, - { id: "upmcsv", name: "Universal Password Manager (csv)" }, - { id: "ascendocsv", name: "Ascendo DataVault (csv)" }, - { id: "meldiumcsv", name: "Meldium (csv)" }, - { id: "passkeepcsv", name: "PassKeep (csv)" }, - { id: "operacsv", name: "Opera (csv)" }, - { id: "vivaldicsv", name: "Vivaldi (csv)" }, - { id: "gnomejson", name: "GNOME Passwords and Keys/Seahorse (json)" }, - { id: "blurcsv", name: "Blur (csv)" }, - { id: "passwordagentcsv", name: "Password Agent (csv)" }, - { id: "passpackcsv", name: "Passpack (csv)" }, - { id: "passmanjson", name: "Passman (json)" }, - { id: "avastcsv", name: "Avast Passwords (csv)" }, - { id: "avastjson", name: "Avast Passwords (json)" }, - { id: "fsecurefsk", name: "F-Secure KEY (fsk)" }, - { id: "kasperskytxt", name: "Kaspersky Password Manager (txt)" }, - { id: "remembearcsv", name: "RememBear (csv)" }, - { id: "passwordwallettxt", name: "PasswordWallet (txt)" }, - { id: "mykicsv", name: "Myki (csv)" }, - { id: "securesafecsv", name: "SecureSafe (csv)" }, - { id: "logmeoncecsv", name: "LogMeOnce (csv)" }, - { id: "blackberrycsv", name: "BlackBerry Password Keeper (csv)" }, - { id: "buttercupcsv", name: "Buttercup (csv)" }, - { id: "codebookcsv", name: "Codebook (csv)" }, - { id: "encryptrcsv", name: "Encryptr (csv)" }, - { id: "yoticsv", name: "Yoti (csv)" }, - { id: "nordpasscsv", name: "Nordpass (csv)" }, -] as const; - -export type ImportType = - | (typeof featuredImportOptions)[number]["id"] - | (typeof regularImportOptions)[number]["id"]; diff --git a/jslib/common/src/importers/ascendoCsvImporter.ts b/jslib/common/src/importers/ascendoCsvImporter.ts deleted file mode 100644 index 75191a1cb..000000000 --- a/jslib/common/src/importers/ascendoCsvImporter.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class AscendoCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.length < 2) { - return; - } - - const cipher = this.initLoginCipher(); - cipher.notes = this.getValueOrDefault(value[value.length - 1]); - cipher.name = this.getValueOrDefault(value[0], "--"); - - if (value.length > 2 && value.length % 2 === 0) { - for (let i = 0; i < value.length - 2; i += 2) { - const val: string = value[i + 2]; - const field: string = value[i + 1]; - if (this.isNullOrWhitespace(val) || this.isNullOrWhitespace(field)) { - continue; - } - - const fieldLower = field.toLowerCase(); - if (cipher.login.password == null && this.passwordFieldNames.indexOf(fieldLower) > -1) { - cipher.login.password = this.getValueOrDefault(val); - } else if ( - cipher.login.username == null && - this.usernameFieldNames.indexOf(fieldLower) > -1 - ) { - cipher.login.username = this.getValueOrDefault(val); - } else if ( - (cipher.login.uris == null || cipher.login.uris.length === 0) && - this.uriFieldNames.indexOf(fieldLower) > -1 - ) { - cipher.login.uris = this.makeUriArray(val); - } else { - this.processKvp(cipher, field, val); - } - } - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/avastCsvImporter.ts b/jslib/common/src/importers/avastCsvImporter.ts deleted file mode 100644 index 9bf106395..000000000 --- a/jslib/common/src/importers/avastCsvImporter.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class AvastCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.name); - cipher.login.uris = this.makeUriArray(value.web); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.username = this.getValueOrDefault(value.login); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/avastJsonImporter.ts b/jslib/common/src/importers/avastJsonImporter.ts deleted file mode 100644 index 0d424a718..000000000 --- a/jslib/common/src/importers/avastJsonImporter.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class AvastJsonImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = JSON.parse(data); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - if (results.logins != null) { - results.logins.forEach((value: any) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.custName); - cipher.notes = this.getValueOrDefault(value.note); - cipher.login.uris = this.makeUriArray(value.url); - cipher.login.password = this.getValueOrDefault(value.pwd); - cipher.login.username = this.getValueOrDefault(value.loginName); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - } - - if (results.notes != null) { - results.notes.forEach((value: any) => { - const cipher = this.initLoginCipher(); - cipher.type = CipherType.SecureNote; - cipher.secureNote.type = SecureNoteType.Generic; - cipher.name = this.getValueOrDefault(value.label); - cipher.notes = this.getValueOrDefault(value.text); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - } - - if (results.cards != null) { - results.cards.forEach((value: any) => { - const cipher = this.initLoginCipher(); - cipher.type = CipherType.Card; - cipher.name = this.getValueOrDefault(value.custName); - cipher.notes = this.getValueOrDefault(value.note); - cipher.card.cardholderName = this.getValueOrDefault(value.holderName); - cipher.card.number = this.getValueOrDefault(value.cardNumber); - cipher.card.code = this.getValueOrDefault(value.cvv); - cipher.card.brand = this.getCardBrand(cipher.card.number); - if (value.expirationDate != null) { - if (value.expirationDate.month != null) { - cipher.card.expMonth = value.expirationDate.month + ""; - } - if (value.expirationDate.year != null) { - cipher.card.expYear = value.expirationDate.year + ""; - } - } - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/aviraCsvImporter.ts b/jslib/common/src/importers/aviraCsvImporter.ts deleted file mode 100644 index f4c578b01..000000000 --- a/jslib/common/src/importers/aviraCsvImporter.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class AviraCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault( - value.name, - this.getValueOrDefault(this.nameFromUrl(value.website), "--") - ); - cipher.login.uris = this.makeUriArray(value.website); - cipher.login.password = this.getValueOrDefault(value.password); - - if ( - this.isNullOrWhitespace(value.username) && - !this.isNullOrWhitespace(value.secondary_username) - ) { - cipher.login.username = value.secondary_username; - } else { - cipher.login.username = this.getValueOrDefault(value.username); - cipher.notes = this.getValueOrDefault(value.secondary_username); - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/baseImporter.ts b/jslib/common/src/importers/baseImporter.ts deleted file mode 100644 index 122b34724..000000000 --- a/jslib/common/src/importers/baseImporter.ts +++ /dev/null @@ -1,466 +0,0 @@ -import * as papa from "papaparse"; - -import { LogService } from "../abstractions/log.service"; -import { CipherType } from "../enums/cipherType"; -import { FieldType } from "../enums/fieldType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { Utils } from "../misc/utils"; -import { ImportResult } from "../models/domain/importResult"; -import { CipherView } from "../models/view/cipherView"; -import { CollectionView } from "../models/view/collectionView"; -import { FieldView } from "../models/view/fieldView"; -import { FolderView } from "../models/view/folderView"; -import { LoginUriView } from "../models/view/loginUriView"; -import { LoginView } from "../models/view/loginView"; -import { SecureNoteView } from "../models/view/secureNoteView"; -import { ConsoleLogService } from "../services/consoleLog.service"; - -export abstract class BaseImporter { - organizationId: string = null; - - protected logService: LogService = new ConsoleLogService(false); - - protected newLineRegex = /(?:\r\n|\r|\n)/; - - protected passwordFieldNames = [ - "password", - "pass word", - "passphrase", - "pass phrase", - "pass", - "code", - "code word", - "codeword", - "secret", - "secret word", - "personpwd", - "key", - "keyword", - "key word", - "keyphrase", - "key phrase", - "form_pw", - "wppassword", - "pin", - "pwd", - "pw", - "pword", - "passwd", - "p", - "serial", - "serial#", - "license key", - "reg #", - - // Non-English names - "passwort", - ]; - - protected usernameFieldNames = [ - "user", - "name", - "user name", - "username", - "login name", - "email", - "e-mail", - "id", - "userid", - "user id", - "login", - "form_loginname", - "wpname", - "mail", - "loginid", - "login id", - "log", - "personlogin", - "first name", - "last name", - "card#", - "account #", - "member", - "member #", - - // Non-English names - "nom", - "benutzername", - ]; - - protected notesFieldNames = [ - "note", - "notes", - "comment", - "comments", - "memo", - "description", - "free form", - "freeform", - "free text", - "freetext", - "free", - - // Non-English names - "kommentar", - ]; - - protected uriFieldNames: string[] = [ - "url", - "hyper link", - "hyperlink", - "link", - "host", - "hostname", - "host name", - "server", - "address", - "hyper ref", - "href", - "web", - "website", - "web site", - "site", - "web-site", - "uri", - - // Non-English names - "ort", - "adresse", - ]; - - protected parseCsvOptions = { - encoding: "UTF-8", - skipEmptyLines: false, - }; - - protected get organization() { - return this.organizationId != null; - } - - protected parseXml(data: string): Document { - const parser = new DOMParser(); - const doc = parser.parseFromString(data, "application/xml"); - return doc != null && doc.querySelector("parsererror") == null ? doc : null; - } - - protected parseCsv(data: string, header: boolean, options: any = {}): any[] { - const parseOptions: papa.ParseConfig = Object.assign( - { header: header }, - this.parseCsvOptions, - options - ); - data = this.splitNewLine(data).join("\n").trim(); - const result = papa.parse(data, parseOptions); - if (result.errors != null && result.errors.length > 0) { - result.errors.forEach((e) => { - if (e.row != null) { - this.logService.warning("Error parsing row " + e.row + ": " + e.message); - } - }); - } - return result.data && result.data.length > 0 ? result.data : null; - } - - protected parseSingleRowCsv(rowData: string) { - if (this.isNullOrWhitespace(rowData)) { - return null; - } - const parsedRow = this.parseCsv(rowData, false); - if (parsedRow != null && parsedRow.length > 0 && parsedRow[0].length > 0) { - return parsedRow[0]; - } - return null; - } - - protected makeUriArray(uri: string | string[]): LoginUriView[] { - if (uri == null) { - return null; - } - - if (typeof uri === "string") { - const loginUri = new LoginUriView(); - loginUri.uri = this.fixUri(uri); - if (this.isNullOrWhitespace(loginUri.uri)) { - return null; - } - loginUri.match = null; - return [loginUri]; - } - - if (uri.length > 0) { - const returnArr: LoginUriView[] = []; - uri.forEach((u) => { - const loginUri = new LoginUriView(); - loginUri.uri = this.fixUri(u); - if (this.isNullOrWhitespace(loginUri.uri)) { - return; - } - loginUri.match = null; - returnArr.push(loginUri); - }); - return returnArr.length === 0 ? null : returnArr; - } - - return null; - } - - protected fixUri(uri: string) { - if (uri == null) { - return null; - } - uri = uri.trim(); - if (uri.indexOf("://") === -1 && uri.indexOf(".") >= 0) { - uri = "http://" + uri; - } - if (uri.length > 1000) { - return uri.substring(0, 1000); - } - return uri; - } - - protected nameFromUrl(url: string) { - const hostname = Utils.getHostname(url); - if (this.isNullOrWhitespace(hostname)) { - return null; - } - return hostname.startsWith("www.") ? hostname.replace("www.", "") : hostname; - } - - protected isNullOrWhitespace(str: string): boolean { - return Utils.isNullOrWhitespace(str); - } - - protected getValueOrDefault(str: string, defaultValue: string = null): string { - if (this.isNullOrWhitespace(str)) { - return defaultValue; - } - return str; - } - - protected splitNewLine(str: string): string[] { - return str.split(this.newLineRegex); - } - - // ref https://stackoverflow.com/a/5911300 - protected getCardBrand(cardNum: string) { - if (this.isNullOrWhitespace(cardNum)) { - return null; - } - - // Visa - let re = new RegExp("^4"); - if (cardNum.match(re) != null) { - return "Visa"; - } - - // Mastercard - // Updated for Mastercard 2017 BINs expansion - if ( - /^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/.test( - cardNum - ) - ) { - return "Mastercard"; - } - - // AMEX - re = new RegExp("^3[47]"); - if (cardNum.match(re) != null) { - return "Amex"; - } - - // Discover - re = new RegExp( - "^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)" - ); - if (cardNum.match(re) != null) { - return "Discover"; - } - - // Diners - re = new RegExp("^36"); - if (cardNum.match(re) != null) { - return "Diners Club"; - } - - // Diners - Carte Blanche - re = new RegExp("^30[0-5]"); - if (cardNum.match(re) != null) { - return "Diners Club"; - } - - // JCB - re = new RegExp("^35(2[89]|[3-8][0-9])"); - if (cardNum.match(re) != null) { - return "JCB"; - } - - // Visa Electron - re = new RegExp("^(4026|417500|4508|4844|491(3|7))"); - if (cardNum.match(re) != null) { - return "Visa"; - } - - return null; - } - - protected setCardExpiration(cipher: CipherView, expiration: string): boolean { - if (!this.isNullOrWhitespace(expiration)) { - expiration = expiration.replace(/\s/g, ""); - const parts = expiration.split("/"); - if (parts.length === 2) { - let month: string = null; - let year: string = null; - if (parts[0].length === 1 || parts[0].length === 2) { - month = parts[0]; - if (month.length === 2 && month[0] === "0") { - month = month.substr(1, 1); - } - } - if (parts[1].length === 2 || parts[1].length === 4) { - year = month.length === 2 ? "20" + parts[1] : parts[1]; - } - if (month != null && year != null) { - cipher.card.expMonth = month; - cipher.card.expYear = year; - return true; - } - } - } - return false; - } - - protected moveFoldersToCollections(result: ImportResult) { - result.folderRelationships.forEach((r) => result.collectionRelationships.push(r)); - result.collections = result.folders.map((f) => { - const collection = new CollectionView(); - collection.name = f.name; - return collection; - }); - result.folderRelationships = []; - result.folders = []; - } - - protected querySelectorDirectChild(parentEl: Element, query: string) { - const els = this.querySelectorAllDirectChild(parentEl, query); - return els.length === 0 ? null : els[0]; - } - - protected querySelectorAllDirectChild(parentEl: Element, query: string) { - return Array.from(parentEl.querySelectorAll(query)).filter((el) => el.parentNode === parentEl); - } - - protected initLoginCipher() { - const cipher = new CipherView(); - cipher.favorite = false; - cipher.notes = ""; - cipher.fields = []; - cipher.login = new LoginView(); - cipher.type = CipherType.Login; - return cipher; - } - - protected cleanupCipher(cipher: CipherView) { - if (cipher == null) { - return; - } - if (cipher.type !== CipherType.Login) { - cipher.login = null; - } - if (this.isNullOrWhitespace(cipher.name)) { - cipher.name = "--"; - } - if (this.isNullOrWhitespace(cipher.notes)) { - cipher.notes = null; - } else { - cipher.notes = cipher.notes.trim(); - } - if (cipher.fields != null && cipher.fields.length === 0) { - cipher.fields = null; - } - } - - protected processKvp( - cipher: CipherView, - key: string, - value: string, - type: FieldType = FieldType.Text - ) { - if (this.isNullOrWhitespace(value)) { - return; - } - if (this.isNullOrWhitespace(key)) { - key = ""; - } - if (value.length > 200 || value.trim().search(this.newLineRegex) > -1) { - if (cipher.notes == null) { - cipher.notes = ""; - } - cipher.notes += key + ": " + this.splitNewLine(value).join("\n") + "\n"; - } else { - if (cipher.fields == null) { - cipher.fields = []; - } - const field = new FieldView(); - field.type = type; - field.name = key; - field.value = value; - cipher.fields.push(field); - } - } - - protected processFolder(result: ImportResult, folderName: string) { - let folderIndex = result.folders.length; - const hasFolder = !this.isNullOrWhitespace(folderName); - let addFolder = hasFolder; - - if (hasFolder) { - for (let i = 0; i < result.folders.length; i++) { - if (result.folders[i].name === folderName) { - addFolder = false; - folderIndex = i; - break; - } - } - } - - if (addFolder) { - const f = new FolderView(); - f.name = folderName; - result.folders.push(f); - } - if (hasFolder) { - result.folderRelationships.push([result.ciphers.length, folderIndex]); - } - } - - protected convertToNoteIfNeeded(cipher: CipherView) { - if ( - cipher.type === CipherType.Login && - this.isNullOrWhitespace(cipher.login.username) && - this.isNullOrWhitespace(cipher.login.password) && - (cipher.login.uris == null || cipher.login.uris.length === 0) - ) { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - } - } - - protected processFullName(cipher: CipherView, fullName: string) { - if (this.isNullOrWhitespace(fullName)) { - return; - } - - const nameParts = fullName.split(" "); - if (nameParts.length > 0) { - cipher.identity.firstName = this.getValueOrDefault(nameParts[0]); - } - if (nameParts.length === 2) { - cipher.identity.lastName = this.getValueOrDefault(nameParts[1]); - } else if (nameParts.length >= 3) { - cipher.identity.middleName = this.getValueOrDefault(nameParts[1]); - cipher.identity.lastName = nameParts.slice(2, nameParts.length).join(" "); - } - } -} diff --git a/jslib/common/src/importers/bitwardenCsvImporter.ts b/jslib/common/src/importers/bitwardenCsvImporter.ts deleted file mode 100644 index cc5419c30..000000000 --- a/jslib/common/src/importers/bitwardenCsvImporter.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { CipherRepromptType } from "../enums/cipherRepromptType"; -import { CipherType } from "../enums/cipherType"; -import { FieldType } from "../enums/fieldType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { CipherView } from "../models/view/cipherView"; -import { CollectionView } from "../models/view/collectionView"; -import { FieldView } from "../models/view/fieldView"; -import { LoginView } from "../models/view/loginView"; -import { SecureNoteView } from "../models/view/secureNoteView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class BitwardenCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (this.organization && !this.isNullOrWhitespace(value.collections)) { - const collections = (value.collections as string).split(","); - collections.forEach((col) => { - let addCollection = true; - let collectionIndex = result.collections.length; - - for (let i = 0; i < result.collections.length; i++) { - if (result.collections[i].name === col) { - addCollection = false; - collectionIndex = i; - break; - } - } - - if (addCollection) { - const collection = new CollectionView(); - collection.name = col; - result.collections.push(collection); - } - - result.collectionRelationships.push([result.ciphers.length, collectionIndex]); - }); - } else if (!this.organization) { - this.processFolder(result, value.folder); - } - - const cipher = new CipherView(); - cipher.favorite = - !this.organization && this.getValueOrDefault(value.favorite, "0") !== "0" ? true : false; - cipher.type = CipherType.Login; - cipher.notes = this.getValueOrDefault(value.notes); - cipher.name = this.getValueOrDefault(value.name, "--"); - try { - cipher.reprompt = parseInt( - this.getValueOrDefault(value.reprompt, CipherRepromptType.None.toString()), - 10 - ); - } catch (e) { - // eslint-disable-next-line - console.error("Unable to parse reprompt value", e); - cipher.reprompt = CipherRepromptType.None; - } - - if (!this.isNullOrWhitespace(value.fields)) { - const fields = this.splitNewLine(value.fields); - for (let i = 0; i < fields.length; i++) { - if (this.isNullOrWhitespace(fields[i])) { - continue; - } - - const delimPosition = fields[i].lastIndexOf(": "); - if (delimPosition === -1) { - continue; - } - - if (cipher.fields == null) { - cipher.fields = []; - } - - const field = new FieldView(); - field.name = fields[i].substr(0, delimPosition); - field.value = null; - field.type = FieldType.Text; - if (fields[i].length > delimPosition + 2) { - field.value = fields[i].substr(delimPosition + 2); - } - cipher.fields.push(field); - } - } - - const valueType = value.type != null ? value.type.toLowerCase() : null; - switch (valueType) { - case "note": - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - break; - default: { - cipher.type = CipherType.Login; - cipher.login = new LoginView(); - cipher.login.totp = this.getValueOrDefault(value.login_totp || value.totp); - cipher.login.username = this.getValueOrDefault(value.login_username || value.username); - cipher.login.password = this.getValueOrDefault(value.login_password || value.password); - const uris = this.parseSingleRowCsv(value.login_uri || value.uri); - cipher.login.uris = this.makeUriArray(uris); - break; - } - } - - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/bitwardenJsonImporter.ts b/jslib/common/src/importers/bitwardenJsonImporter.ts deleted file mode 100644 index 6caf185ef..000000000 --- a/jslib/common/src/importers/bitwardenJsonImporter.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { CryptoService } from "../abstractions/crypto.service"; -import { I18nService } from "../abstractions/i18n.service"; -import { EncString } from "../models/domain/encString"; -import { ImportResult } from "../models/domain/importResult"; -import { CipherWithIds } from "../models/export/cipherWithIds"; -import { CollectionWithId } from "../models/export/collectionWithId"; -import { FolderWithId } from "../models/export/folderWithId"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class BitwardenJsonImporter extends BaseImporter implements Importer { - private results: any; - private result: ImportResult; - - constructor(protected cryptoService: CryptoService, protected i18nService: I18nService) { - super(); - } - - async parse(data: string): Promise { - this.result = new ImportResult(); - this.results = JSON.parse(data); - if (this.results == null || this.results.items == null) { - if (this.results?.passwordProtected) { - this.result.success = false; - this.result.missingPassword = true; - this.result.errorMessage = this.i18nService.t("importPasswordRequired"); - return this.result; - } - - this.result.success = false; - return this.result; - } - - if (this.results.encrypted) { - await this.parseEncrypted(); - } else { - this.parseDecrypted(); - } - - return this.result; - } - - private async parseEncrypted() { - if (this.results.encKeyValidation_DO_NOT_EDIT != null) { - const orgKey = await this.cryptoService.getOrgKey(this.organizationId); - const encKeyValidation = new EncString(this.results.encKeyValidation_DO_NOT_EDIT); - const encKeyValidationDecrypt = await this.cryptoService.decryptToUtf8( - encKeyValidation, - orgKey - ); - if (encKeyValidationDecrypt === null) { - this.result.success = false; - this.result.errorMessage = this.i18nService.t("importEncKeyError"); - return; - } - } - - const groupingsMap = new Map(); - - if (this.organization && this.results.collections != null) { - for (const c of this.results.collections as CollectionWithId[]) { - const collection = CollectionWithId.toDomain(c); - if (collection != null) { - collection.id = null; - collection.organizationId = this.organizationId; - const view = await collection.decrypt(); - groupingsMap.set(c.id, this.result.collections.length); - this.result.collections.push(view); - } - } - } else if (!this.organization && this.results.folders != null) { - for (const f of this.results.folders as FolderWithId[]) { - const folder = FolderWithId.toDomain(f); - if (folder != null) { - folder.id = null; - const view = await folder.decrypt(); - groupingsMap.set(f.id, this.result.folders.length); - this.result.folders.push(view); - } - } - } - - for (const c of this.results.items as CipherWithIds[]) { - const cipher = CipherWithIds.toDomain(c); - // reset ids incase they were set for some reason - cipher.id = null; - cipher.folderId = null; - cipher.organizationId = this.organizationId; - cipher.collectionIds = null; - - // make sure password history is limited - if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) { - cipher.passwordHistory = cipher.passwordHistory.slice(0, 5); - } - - if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) { - this.result.folderRelationships.push([ - this.result.ciphers.length, - groupingsMap.get(c.folderId), - ]); - } else if (this.organization && c.collectionIds != null) { - c.collectionIds.forEach((cId) => { - if (groupingsMap.has(cId)) { - this.result.collectionRelationships.push([ - this.result.ciphers.length, - groupingsMap.get(cId), - ]); - } - }); - } - - const view = await cipher.decrypt(); - this.cleanupCipher(view); - this.result.ciphers.push(view); - } - - this.result.success = true; - } - - private parseDecrypted() { - const groupingsMap = new Map(); - if (this.organization && this.results.collections != null) { - this.results.collections.forEach((c: CollectionWithId) => { - const collection = CollectionWithId.toView(c); - if (collection != null) { - collection.id = null; - collection.organizationId = null; - groupingsMap.set(c.id, this.result.collections.length); - this.result.collections.push(collection); - } - }); - } else if (!this.organization && this.results.folders != null) { - this.results.folders.forEach((f: FolderWithId) => { - const folder = FolderWithId.toView(f); - if (folder != null) { - folder.id = null; - groupingsMap.set(f.id, this.result.folders.length); - this.result.folders.push(folder); - } - }); - } - - this.results.items.forEach((c: CipherWithIds) => { - const cipher = CipherWithIds.toView(c); - // reset ids incase they were set for some reason - cipher.id = null; - cipher.folderId = null; - cipher.organizationId = null; - cipher.collectionIds = null; - - // make sure password history is limited - if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) { - cipher.passwordHistory = cipher.passwordHistory.slice(0, 5); - } - - if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) { - this.result.folderRelationships.push([ - this.result.ciphers.length, - groupingsMap.get(c.folderId), - ]); - } else if (this.organization && c.collectionIds != null) { - c.collectionIds.forEach((cId) => { - if (groupingsMap.has(cId)) { - this.result.collectionRelationships.push([ - this.result.ciphers.length, - groupingsMap.get(cId), - ]); - } - }); - } - - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - - this.result.success = true; - } -} diff --git a/jslib/common/src/importers/bitwardenPasswordProtectedImporter.ts b/jslib/common/src/importers/bitwardenPasswordProtectedImporter.ts deleted file mode 100644 index 54da71b5e..000000000 --- a/jslib/common/src/importers/bitwardenPasswordProtectedImporter.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { CryptoService } from "../abstractions/crypto.service"; -import { I18nService } from "../abstractions/i18n.service"; -import { KdfType } from "../enums/kdfType"; -import { EncString } from "../models/domain/encString"; -import { ImportResult } from "../models/domain/importResult"; -import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey"; - -import { BitwardenJsonImporter } from "./bitwardenJsonImporter"; -import { Importer } from "./importer"; - -interface BitwardenPasswordProtectedFileFormat { - encrypted: boolean; - passwordProtected: boolean; - salt: string; - kdfIterations: number; - kdfType: number; - encKeyValidation_DO_NOT_EDIT: string; - data: string; -} - -export class BitwardenPasswordProtectedImporter extends BitwardenJsonImporter implements Importer { - private key: SymmetricCryptoKey; - - constructor(cryptoService: CryptoService, i18nService: I18nService, private password: string) { - super(cryptoService, i18nService); - } - - async parse(data: string): Promise { - const result = new ImportResult(); - const parsedData = JSON.parse(data); - if (this.cannotParseFile(parsedData)) { - result.success = false; - return result; - } - - if (!(await this.checkPassword(parsedData))) { - result.success = false; - result.errorMessage = this.i18nService.t("importEncKeyError"); - return result; - } - - const encData = new EncString(parsedData.data); - const clearTextData = await this.cryptoService.decryptToUtf8(encData, this.key); - return await super.parse(clearTextData); - } - - private async checkPassword(jdoc: BitwardenPasswordProtectedFileFormat): Promise { - this.key = await this.cryptoService.makePinKey( - this.password, - jdoc.salt, - KdfType.PBKDF2_SHA256, - jdoc.kdfIterations - ); - - const encKeyValidation = new EncString(jdoc.encKeyValidation_DO_NOT_EDIT); - - const encKeyValidationDecrypt = await this.cryptoService.decryptToUtf8( - encKeyValidation, - this.key - ); - if (encKeyValidationDecrypt === null) { - return false; - } - return true; - } - - private cannotParseFile(jdoc: BitwardenPasswordProtectedFileFormat): boolean { - return ( - !jdoc || - !jdoc.encrypted || - !jdoc.passwordProtected || - !jdoc.salt || - !jdoc.kdfIterations || - typeof jdoc.kdfIterations !== "number" || - jdoc.kdfType == null || - KdfType[jdoc.kdfType] == null || - !jdoc.encKeyValidation_DO_NOT_EDIT || - !jdoc.data - ); - } -} diff --git a/jslib/common/src/importers/blackBerryCsvImporter.ts b/jslib/common/src/importers/blackBerryCsvImporter.ts deleted file mode 100644 index ea3d08ebc..000000000 --- a/jslib/common/src/importers/blackBerryCsvImporter.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class BlackBerryCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.grouping === "list") { - return; - } - const cipher = this.initLoginCipher(); - cipher.favorite = value.fav === "1"; - cipher.name = this.getValueOrDefault(value.name); - cipher.notes = this.getValueOrDefault(value.extra); - if (value.grouping !== "note") { - cipher.login.uris = this.makeUriArray(value.url); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.username = this.getValueOrDefault(value.username); - } - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/blurCsvImporter.ts b/jslib/common/src/importers/blurCsvImporter.ts deleted file mode 100644 index ca9ecd1cd..000000000 --- a/jslib/common/src/importers/blurCsvImporter.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class BlurCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.label === "null") { - value.label = null; - } - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault( - value.label, - this.getValueOrDefault(this.nameFromUrl(value.domain), "--") - ); - cipher.login.uris = this.makeUriArray(value.domain); - cipher.login.password = this.getValueOrDefault(value.password); - - if (this.isNullOrWhitespace(value.email) && !this.isNullOrWhitespace(value.username)) { - cipher.login.username = value.username; - } else { - cipher.login.username = this.getValueOrDefault(value.email); - cipher.notes = this.getValueOrDefault(value.username); - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/buttercupCsvImporter.ts b/jslib/common/src/importers/buttercupCsvImporter.ts deleted file mode 100644 index aa3dda2d4..000000000 --- a/jslib/common/src/importers/buttercupCsvImporter.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -const OfficialProps = ["!group_id", "!group_name", "title", "username", "password", "URL", "id"]; - -export class ButtercupCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - this.processFolder(result, this.getValueOrDefault(value["!group_name"])); - - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.title, "--"); - cipher.login.username = this.getValueOrDefault(value.username); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.uris = this.makeUriArray(value.URL); - - let processingCustomFields = false; - for (const prop in value) { - // eslint-disable-next-line - if (value.hasOwnProperty(prop)) { - if (!processingCustomFields && OfficialProps.indexOf(prop) === -1) { - processingCustomFields = true; - } - if (processingCustomFields) { - this.processKvp(cipher, prop, value[prop]); - } - } - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/chromeCsvImporter.ts b/jslib/common/src/importers/chromeCsvImporter.ts deleted file mode 100644 index 35c72ac34..000000000 --- a/jslib/common/src/importers/chromeCsvImporter.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class ChromeCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.name, "--"); - cipher.login.username = this.getValueOrDefault(value.username); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.uris = this.makeUriArray(value.url); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/clipperzHtmlImporter.ts b/jslib/common/src/importers/clipperzHtmlImporter.ts deleted file mode 100644 index c4f0402c5..000000000 --- a/jslib/common/src/importers/clipperzHtmlImporter.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class ClipperzHtmlImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const doc = this.parseXml(data); - if (doc == null) { - result.success = false; - return Promise.resolve(result); - } - - const textarea = doc.querySelector("textarea"); - if (textarea == null || this.isNullOrWhitespace(textarea.textContent)) { - result.errorMessage = "Missing textarea."; - result.success = false; - return Promise.resolve(result); - } - - const entries = JSON.parse(textarea.textContent); - entries.forEach((entry: any) => { - const cipher = this.initLoginCipher(); - if (!this.isNullOrWhitespace(entry.label)) { - cipher.name = entry.label.split(" ")[0]; - } - if (entry.data != null && !this.isNullOrWhitespace(entry.data.notes)) { - cipher.notes = entry.data.notes.split("\\n").join("\n"); - } - - if (entry.currentVersion != null && entry.currentVersion.fields != null) { - for (const property in entry.currentVersion.fields) { - // eslint-disable-next-line - if (!entry.currentVersion.fields.hasOwnProperty(property)) { - continue; - } - - const field = entry.currentVersion.fields[property]; - const actionType = field.actionType != null ? field.actionType.toLowerCase() : null; - switch (actionType) { - case "password": - cipher.login.password = this.getValueOrDefault(field.value); - break; - case "email": - case "username": - case "user": - case "name": - cipher.login.username = this.getValueOrDefault(field.value); - break; - case "url": - cipher.login.uris = this.makeUriArray(field.value); - break; - default: { - const labelLower = field.label != null ? field.label.toLowerCase() : null; - if ( - cipher.login.password == null && - this.passwordFieldNames.indexOf(labelLower) > -1 - ) { - cipher.login.password = this.getValueOrDefault(field.value); - } else if ( - cipher.login.username == null && - this.usernameFieldNames.indexOf(labelLower) > -1 - ) { - cipher.login.username = this.getValueOrDefault(field.value); - } else if ( - (cipher.login.uris == null || cipher.login.uris.length === 0) && - this.uriFieldNames.indexOf(labelLower) > -1 - ) { - cipher.login.uris = this.makeUriArray(field.value); - } else { - this.processKvp(cipher, field.label, field.value); - } - break; - } - } - } - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/codebookCsvImporter.ts b/jslib/common/src/importers/codebookCsvImporter.ts deleted file mode 100644 index f842f21c0..000000000 --- a/jslib/common/src/importers/codebookCsvImporter.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class CodebookCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - this.processFolder(result, this.getValueOrDefault(value.Category)); - - const cipher = this.initLoginCipher(); - cipher.favorite = this.getValueOrDefault(value.Favorite) === "True"; - cipher.name = this.getValueOrDefault(value.Entry, "--"); - cipher.notes = this.getValueOrDefault(value.Note); - cipher.login.username = this.getValueOrDefault(value.Username, value.Email); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.totp = this.getValueOrDefault(value.TOTP); - cipher.login.uris = this.makeUriArray(value.Website); - - if (!this.isNullOrWhitespace(value.Username)) { - this.processKvp(cipher, "Email", value.Email); - } - this.processKvp(cipher, "Phone", value.Phone); - this.processKvp(cipher, "PIN", value.PIN); - this.processKvp(cipher, "Account", value.Account); - this.processKvp(cipher, "Date", value.Date); - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/dashlaneImporters/dashlaneCsvImporter.ts b/jslib/common/src/importers/dashlaneImporters/dashlaneCsvImporter.ts deleted file mode 100644 index 2bb6ce14f..000000000 --- a/jslib/common/src/importers/dashlaneImporters/dashlaneCsvImporter.ts +++ /dev/null @@ -1,271 +0,0 @@ -import { CipherType } from "../../enums/cipherType"; -import { SecureNoteType } from "../../enums/secureNoteType"; -import { ImportResult } from "../../models/domain/importResult"; -import { CardView } from "../../models/view/cardView"; -import { CipherView } from "../../models/view/cipherView"; -import { IdentityView } from "../../models/view/identityView"; -import { LoginView } from "../../models/view/loginView"; -import { BaseImporter } from "../baseImporter"; -import { Importer } from "../importer"; - -import { - CredentialsRecord, - IdRecord, - PaymentsRecord, - PersonalInformationRecord, - SecureNoteRecord, -} from "./types/dashlaneCsvTypes"; - -const _mappedCredentialsColums = new Set([ - "title", - "note", - "username", - "password", - "url", - "otpSecret", - "category", -]); - -const _mappedPersonalInfoAsIdentiyColumns = new Set([ - "type", - "title", - "first_name", - "middle_name", - "last_name", - "login", - "email", - "phone_number", - "address", - "country", - "state", - "city", - "zip", - // Skip item_name as we already have set a combined name - "item_name", -]); - -const _mappedSecureNoteColumns = new Set(["title", "note"]); - -export class DashlaneCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - if (results[0].type != null && results[0].title != null) { - const personalRecords = results as PersonalInformationRecord[]; - - // If personalRecords has only one "name" then create an Identity-Cipher - if (personalRecords.filter((x) => x.type === "name").length === 1) { - const cipher = this.initLoginCipher(); - cipher.type = CipherType.Identity; - cipher.identity = new IdentityView(); - results.forEach((row) => { - this.parsePersonalInformationRecordAsIdentity(cipher, row); - }); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - result.success = true; - return Promise.resolve(result); - } - } - - results.forEach((row) => { - const cipher = this.initLoginCipher(); - - const rowKeys = Object.keys(row); - if (rowKeys[0] === "username") { - this.processFolder(result, row.category); - this.parseCredentialsRecord(cipher, row); - } - - if (rowKeys[0] === "type" && rowKeys[1] === "account_name") { - this.parsePaymentRecord(cipher, row); - } - - if (rowKeys[0] === "type" && rowKeys[1] === "number") { - this.parseIdRecord(cipher, row); - } - - if ((rowKeys[0] === "type") != null && rowKeys[1] === "title") { - this.parsePersonalInformationRecord(cipher, row); - } - - if (rowKeys[0] === "title" && rowKeys[1] === "note") { - this.parseSecureNoteRecords(cipher, row); - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - parseCredentialsRecord(cipher: CipherView, row: CredentialsRecord) { - cipher.type = CipherType.Login; - cipher.login = new LoginView(); - - cipher.name = row.title; - cipher.notes = row.note; - cipher.login.username = row.username; - cipher.login.password = row.password; - cipher.login.totp = row.otpSecret; - cipher.login.uris = this.makeUriArray(row.url); - - this.importUnmappedFields(cipher, row, _mappedCredentialsColums); - } - - parsePaymentRecord(cipher: CipherView, row: PaymentsRecord) { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - - cipher.name = row.account_name; - let mappedValues: string[] = []; - switch (row.type) { - case "credit_card": - cipher.card.cardholderName = row.account_name; - cipher.card.number = row.cc_number; - cipher.card.brand = this.getCardBrand(cipher.card.number); - cipher.card.code = row.code; - cipher.card.expMonth = row.expiration_month; - cipher.card.expYear = row.expiration_year.substring(2, 4); - - // If you add more mapped fields please extend this - mappedValues = [ - "account_name", - "account_holder", - "cc_number", - "code", - "expiration_month", - "expiration_year", - ]; - break; - case "bank": - cipher.card.cardholderName = row.account_holder; - cipher.card.number = row.account_number; - - // If you add more mapped fields please extend this - mappedValues = ["account_name", "account_holder", "account_number"]; - break; - default: - break; - } - - this.importUnmappedFields(cipher, row, new Set(mappedValues)); - } - - parseIdRecord(cipher: CipherView, row: IdRecord) { - cipher.type = CipherType.Identity; - cipher.identity = new IdentityView(); - - const mappedValues: string[] = ["name", "number"]; - switch (row.type) { - case "card": - cipher.name = `${row.name} ${row.type}`; - this.processFullName(cipher, row.name); - cipher.identity.licenseNumber = row.number; - break; - case "passport": - cipher.name = `${row.name} ${row.type}`; - this.processFullName(cipher, row.name); - cipher.identity.passportNumber = row.number; - break; - case "license": - cipher.name = `${row.name} ${row.type}`; - this.processFullName(cipher, row.name); - cipher.identity.licenseNumber = row.number; - cipher.identity.state = row.state; - - mappedValues.push("state"); - break; - case "social_security": - cipher.name = `${row.name} ${row.type}`; - this.processFullName(cipher, row.name); - cipher.identity.ssn = row.number; - break; - case "tax_number": - cipher.name = row.type; - cipher.identity.licenseNumber = row.number; - break; - - default: - break; - } - - // If you add more mapped fields please extend this - this.importUnmappedFields(cipher, row, new Set(mappedValues)); - } - - parsePersonalInformationRecord(cipher: CipherView, row: PersonalInformationRecord) { - cipher.type = CipherType.SecureNote; - cipher.secureNote.type = SecureNoteType.Generic; - if (row.type === "name") { - cipher.name = `${row.title} ${row.first_name} ${row.middle_name} ${row.last_name}` - .replace(" ", " ") - .trim(); - } else { - cipher.name = row.item_name; - } - - const dataRow = row as any; - Object.keys(row).forEach((key) => { - this.processKvp(cipher, key, dataRow[key]); - }); - } - - parsePersonalInformationRecordAsIdentity(cipher: CipherView, row: PersonalInformationRecord) { - switch (row.type) { - case "name": - this.processFullName(cipher, `${row.first_name} ${row.middle_name} ${row.last_name}`); - cipher.identity.title = row.title; - cipher.name = cipher.identity.fullName; - - cipher.identity.username = row.login; - break; - case "email": - cipher.identity.email = row.email; - break; - case "number": - cipher.identity.phone = row.phone_number; - break; - case "address": - cipher.identity.address1 = row.address; - cipher.identity.city = row.city; - cipher.identity.postalCode = row.zip; - cipher.identity.state = row.state; - cipher.identity.country = row.country; - break; - default: - break; - } - - this.importUnmappedFields(cipher, row, _mappedPersonalInfoAsIdentiyColumns); - } - - parseSecureNoteRecords(cipher: CipherView, row: SecureNoteRecord) { - cipher.type = CipherType.SecureNote; - cipher.secureNote.type = SecureNoteType.Generic; - cipher.name = row.title; - cipher.notes = row.note; - - this.importUnmappedFields(cipher, row, _mappedSecureNoteColumns); - } - - importUnmappedFields(cipher: CipherView, row: any, mappedValues: Set) { - const unmappedFields = Object.keys(row).filter((x) => !mappedValues.has(x)); - unmappedFields.forEach((key) => { - const item = row as any; - this.processKvp(cipher, key, item[key]); - }); - } -} diff --git a/jslib/common/src/importers/dashlaneImporters/dashlaneJsonImporter.ts b/jslib/common/src/importers/dashlaneImporters/dashlaneJsonImporter.ts deleted file mode 100644 index cb7db59da..000000000 --- a/jslib/common/src/importers/dashlaneImporters/dashlaneJsonImporter.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { CipherType } from "../../enums/cipherType"; -import { SecureNoteType } from "../../enums/secureNoteType"; -import { ImportResult } from "../../models/domain/importResult"; -import { CardView } from "../../models/view/cardView"; -import { CipherView } from "../../models/view/cipherView"; -import { IdentityView } from "../../models/view/identityView"; -import { SecureNoteView } from "../../models/view/secureNoteView"; -import { BaseImporter } from "../baseImporter"; -import { Importer } from "../importer"; - -const HandledResults = new Set([ - "ADDRESS", - "AUTHENTIFIANT", - "BANKSTATEMENT", - "IDCARD", - "IDENTITY", - "PAYMENTMEANS_CREDITCARD", - "PAYMENTMEAN_PAYPAL", - "EMAIL", -]); - -export class DashlaneJsonImporter extends BaseImporter implements Importer { - private result: ImportResult; - - parse(data: string): Promise { - this.result = new ImportResult(); - const results = JSON.parse(data); - if (results == null || results.length === 0) { - this.result.success = false; - return Promise.resolve(this.result); - } - - if (results.ADDRESS != null) { - this.processAddress(results.ADDRESS); - } - if (results.AUTHENTIFIANT != null) { - this.processAuth(results.AUTHENTIFIANT); - } - if (results.BANKSTATEMENT != null) { - this.processNote(results.BANKSTATEMENT, "BankAccountName"); - } - if (results.IDCARD != null) { - this.processNote(results.IDCARD, "Fullname"); - } - if (results.PAYMENTMEANS_CREDITCARD != null) { - this.processCard(results.PAYMENTMEANS_CREDITCARD); - } - if (results.IDENTITY != null) { - this.processIdentity(results.IDENTITY); - } - - for (const key in results) { - // eslint-disable-next-line - if (results.hasOwnProperty(key) && !HandledResults.has(key)) { - this.processNote(results[key], null, "Generic Note"); - } - } - - this.result.success = true; - return Promise.resolve(this.result); - } - - private processAuth(results: any[]) { - results.forEach((credential: any) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(credential.title); - - cipher.login.username = this.getValueOrDefault( - credential.login, - this.getValueOrDefault(credential.secondaryLogin) - ); - if (this.isNullOrWhitespace(cipher.login.username)) { - cipher.login.username = this.getValueOrDefault(credential.email); - } else if (!this.isNullOrWhitespace(credential.email)) { - cipher.notes = "Email: " + credential.email + "\n"; - } - - cipher.login.password = this.getValueOrDefault(credential.password); - cipher.login.uris = this.makeUriArray(credential.domain); - cipher.notes += this.getValueOrDefault(credential.note, ""); - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - } - - private processIdentity(results: any[]) { - results.forEach((obj: any) => { - const cipher = new CipherView(); - cipher.identity = new IdentityView(); - cipher.type = CipherType.Identity; - cipher.name = this.getValueOrDefault(obj.fullName, ""); - const nameParts = cipher.name.split(" "); - if (nameParts.length > 0) { - cipher.identity.firstName = this.getValueOrDefault(nameParts[0]); - } - if (nameParts.length === 2) { - cipher.identity.lastName = this.getValueOrDefault(nameParts[1]); - } else if (nameParts.length === 3) { - cipher.identity.middleName = this.getValueOrDefault(nameParts[1]); - cipher.identity.lastName = this.getValueOrDefault(nameParts[2]); - } - cipher.identity.username = this.getValueOrDefault(obj.pseudo); - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - } - - private processAddress(results: any[]) { - results.forEach((obj: any) => { - const cipher = new CipherView(); - cipher.identity = new IdentityView(); - cipher.type = CipherType.Identity; - cipher.name = this.getValueOrDefault(obj.addressName); - cipher.identity.address1 = this.getValueOrDefault(obj.addressFull); - cipher.identity.city = this.getValueOrDefault(obj.city); - cipher.identity.state = this.getValueOrDefault(obj.state); - cipher.identity.postalCode = this.getValueOrDefault(obj.zipcode); - cipher.identity.country = this.getValueOrDefault(obj.country); - if (cipher.identity.country != null) { - cipher.identity.country = cipher.identity.country.toUpperCase(); - } - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - } - - private processCard(results: any[]) { - results.forEach((obj: any) => { - const cipher = new CipherView(); - cipher.card = new CardView(); - cipher.type = CipherType.Card; - cipher.name = this.getValueOrDefault(obj.bank); - cipher.card.number = this.getValueOrDefault(obj.cardNumber); - cipher.card.brand = this.getCardBrand(cipher.card.number); - cipher.card.cardholderName = this.getValueOrDefault(obj.owner); - if (!this.isNullOrWhitespace(cipher.card.brand)) { - if (this.isNullOrWhitespace(cipher.name)) { - cipher.name = cipher.card.brand; - } else { - cipher.name += " - " + cipher.card.brand; - } - } - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - } - - private processNote(results: any[], nameProperty: string, name: string = null) { - results.forEach((obj: any) => { - const cipher = new CipherView(); - cipher.secureNote = new SecureNoteView(); - cipher.type = CipherType.SecureNote; - cipher.secureNote.type = SecureNoteType.Generic; - if (name != null) { - cipher.name = name; - } else { - cipher.name = this.getValueOrDefault(obj[nameProperty]); - } - for (const key in obj) { - // eslint-disable-next-line - if (obj.hasOwnProperty(key) && key !== nameProperty) { - this.processKvp(cipher, key, obj[key].toString()); - } - } - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - } -} diff --git a/jslib/common/src/importers/dashlaneImporters/types/dashlaneCsvTypes.ts b/jslib/common/src/importers/dashlaneImporters/types/dashlaneCsvTypes.ts deleted file mode 100644 index cb321c56d..000000000 --- a/jslib/common/src/importers/dashlaneImporters/types/dashlaneCsvTypes.ts +++ /dev/null @@ -1,68 +0,0 @@ -// tslint:disable -export class CredentialsRecord { - username: string; - username2: string; - username3: string; - title: string; - password: string; - note: string; - url: string; - category: string; - otpSecret: string; -} - -export class PaymentsRecord { - type: string; - account_name: string; - account_holder: string; - cc_number: string; - code: string; - expiration_month: string; - expiration_year: string; - routing_number: string; - account_number: string; - country: string; - issuing_bank: string; -} - -export class IdRecord { - type: string; - number: string; - name: string; - issue_date: string; - expiration_date: string; - place_of_issue: string; - state: string; -} - -export class PersonalInformationRecord { - type: string; - title: string; - first_name: string; - middle_name: string; - last_name: string; - login: string; - date_of_birth: string; - place_of_birth: string; - email: string; - email_type: string; - item_name: string; - phone_number: string; - address: string; - country: string; - state: string; - city: string; - zip: string; - address_recipient: string; - address_building: string; - address_apartment: string; - address_floor: string; - address_door_code: string; - job_title: string; - url: string; -} - -export class SecureNoteRecord { - title: string; - note: string; -} diff --git a/jslib/common/src/importers/encryptrCsvImporter.ts b/jslib/common/src/importers/encryptrCsvImporter.ts deleted file mode 100644 index 8c3e9e08a..000000000 --- a/jslib/common/src/importers/encryptrCsvImporter.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class EncryptrCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.Label, "--"); - cipher.notes = this.getValueOrDefault(value.Notes); - const text = this.getValueOrDefault(value.Text); - if (!this.isNullOrWhitespace(text)) { - if (this.isNullOrWhitespace(cipher.notes)) { - cipher.notes = text; - } else { - cipher.notes += "\n\n" + text; - } - } - - const type = value["Entry Type"]; - if (type === "Password") { - cipher.login.username = this.getValueOrDefault(value.Username); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.uris = this.makeUriArray(value["Site URL"]); - } else if (type === "Credit Card") { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - cipher.card.cardholderName = this.getValueOrDefault(value["Name on card"]); - cipher.card.number = this.getValueOrDefault(value["Card Number"]); - cipher.card.brand = this.getCardBrand(cipher.card.number); - cipher.card.code = this.getValueOrDefault(value.CVV); - const expiry = this.getValueOrDefault(value.Expiry); - if (!this.isNullOrWhitespace(expiry)) { - const expParts = expiry.split("/"); - if (expParts.length > 1) { - cipher.card.expMonth = parseInt(expParts[0], null).toString(); - cipher.card.expYear = (2000 + parseInt(expParts[1], null)).toString(); - } - } - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/enpassCsvImporter.ts b/jslib/common/src/importers/enpassCsvImporter.ts deleted file mode 100644 index b5eb0b602..000000000 --- a/jslib/common/src/importers/enpassCsvImporter.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; -import { SecureNoteView } from "../models/view/secureNoteView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class EnpassCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - let firstRow = true; - results.forEach((value) => { - if (value.length < 2 || (firstRow && (value[0] === "Title" || value[0] === "title"))) { - firstRow = false; - return; - } - - const cipher = this.initLoginCipher(); - cipher.notes = this.getValueOrDefault(value[value.length - 1]); - cipher.name = this.getValueOrDefault(value[0], "--"); - - if ( - value.length === 2 || - (!this.containsField(value, "username") && - !this.containsField(value, "password") && - !this.containsField(value, "email") && - !this.containsField(value, "url")) - ) { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - } - - if ( - this.containsField(value, "cardholder") && - this.containsField(value, "number") && - this.containsField(value, "expiry date") - ) { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - } - - if (value.length > 2 && value.length % 2 === 0) { - for (let i = 0; i < value.length - 2; i += 2) { - const fieldValue: string = value[i + 2]; - if (this.isNullOrWhitespace(fieldValue)) { - continue; - } - - const fieldName: string = value[i + 1]; - const fieldNameLower = fieldName.toLowerCase(); - - if (cipher.type === CipherType.Login) { - if ( - fieldNameLower === "url" && - (cipher.login.uris == null || cipher.login.uris.length === 0) - ) { - cipher.login.uris = this.makeUriArray(fieldValue); - continue; - } else if ( - (fieldNameLower === "username" || fieldNameLower === "email") && - this.isNullOrWhitespace(cipher.login.username) - ) { - cipher.login.username = fieldValue; - continue; - } else if ( - fieldNameLower === "password" && - this.isNullOrWhitespace(cipher.login.password) - ) { - cipher.login.password = fieldValue; - continue; - } else if (fieldNameLower === "totp" && this.isNullOrWhitespace(cipher.login.totp)) { - cipher.login.totp = fieldValue; - continue; - } - } else if (cipher.type === CipherType.Card) { - if ( - fieldNameLower === "cardholder" && - this.isNullOrWhitespace(cipher.card.cardholderName) - ) { - cipher.card.cardholderName = fieldValue; - continue; - } else if (fieldNameLower === "number" && this.isNullOrWhitespace(cipher.card.number)) { - cipher.card.number = fieldValue; - cipher.card.brand = this.getCardBrand(fieldValue); - continue; - } else if (fieldNameLower === "cvc" && this.isNullOrWhitespace(cipher.card.code)) { - cipher.card.code = fieldValue; - continue; - } else if ( - fieldNameLower === "expiry date" && - this.isNullOrWhitespace(cipher.card.expMonth) && - this.isNullOrWhitespace(cipher.card.expYear) - ) { - if (this.setCardExpiration(cipher, fieldValue)) { - continue; - } - } else if (fieldNameLower === "type") { - // Skip since brand was determined from number above - continue; - } - } - - this.processKvp(cipher, fieldName, fieldValue); - } - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } - - private containsField(fields: any[], name: string) { - if (fields == null || name == null) { - return false; - } - return ( - fields.filter((f) => !this.isNullOrWhitespace(f) && f.toLowerCase() === name.toLowerCase()) - .length > 0 - ); - } -} diff --git a/jslib/common/src/importers/enpassJsonImporter.ts b/jslib/common/src/importers/enpassJsonImporter.ts deleted file mode 100644 index 033c5995b..000000000 --- a/jslib/common/src/importers/enpassJsonImporter.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { FieldType } from "../enums/fieldType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; -import { CipherView } from "../models/view/cipherView"; -import { FolderView } from "../models/view/folderView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class EnpassJsonImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = JSON.parse(data); - if (results == null || results.items == null || results.items.length === 0) { - result.success = false; - return Promise.resolve(result); - } - - const foldersMap = new Map(); - const foldersIndexMap = new Map(); - const folderTree = this.buildFolderTree(results.folders); - this.flattenFolderTree(null, folderTree, foldersMap); - foldersMap.forEach((val, key) => { - foldersIndexMap.set(key, result.folders.length); - const f = new FolderView(); - f.name = val; - result.folders.push(f); - }); - - results.items.forEach((item: any) => { - if (item.folders != null && item.folders.length > 0 && foldersIndexMap.has(item.folders[0])) { - result.folderRelationships.push([ - result.ciphers.length, - foldersIndexMap.get(item.folders[0]), - ]); - } - - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(item.title); - cipher.favorite = item.favorite > 0; - - if (item.template_type != null && item.fields != null && item.fields.length > 0) { - if ( - item.template_type.indexOf("login.") === 0 || - item.template_type.indexOf("password.") === 0 - ) { - this.processLogin(cipher, item.fields); - } else if (item.template_type.indexOf("creditcard.") === 0) { - this.processCard(cipher, item.fields); - } else if ( - item.template_type.indexOf("identity.") < 0 && - item.fields.some((f: any) => f.type === "password" && !this.isNullOrWhitespace(f.value)) - ) { - this.processLogin(cipher, item.fields); - } else { - this.processNote(cipher, item.fields); - } - } - - cipher.notes += "\n" + this.getValueOrDefault(item.note, ""); - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } - - private processLogin(cipher: CipherView, fields: any[]) { - const urls: string[] = []; - fields.forEach((field: any) => { - if (this.isNullOrWhitespace(field.value) || field.type === "section") { - return; - } - - if ( - (field.type === "username" || field.type === "email") && - this.isNullOrWhitespace(cipher.login.username) - ) { - cipher.login.username = field.value; - } else if (field.type === "password" && this.isNullOrWhitespace(cipher.login.password)) { - cipher.login.password = field.value; - } else if (field.type === "totp" && this.isNullOrWhitespace(cipher.login.totp)) { - cipher.login.totp = field.value; - } else if (field.type === "url") { - urls.push(field.value); - } else { - this.processKvp( - cipher, - field.label, - field.value, - field.sensitive === 1 ? FieldType.Hidden : FieldType.Text - ); - } - }); - cipher.login.uris = this.makeUriArray(urls); - } - - private processCard(cipher: CipherView, fields: any[]) { - cipher.card = new CardView(); - cipher.type = CipherType.Card; - fields.forEach((field: any) => { - if ( - this.isNullOrWhitespace(field.value) || - field.type === "section" || - field.type === "ccType" - ) { - return; - } - - if (field.type === "ccName" && this.isNullOrWhitespace(cipher.card.cardholderName)) { - cipher.card.cardholderName = field.value; - } else if (field.type === "ccNumber" && this.isNullOrWhitespace(cipher.card.number)) { - cipher.card.number = field.value; - cipher.card.brand = this.getCardBrand(cipher.card.number); - } else if (field.type === "ccCvc" && this.isNullOrWhitespace(cipher.card.code)) { - cipher.card.code = field.value; - } else if (field.type === "ccExpiry" && this.isNullOrWhitespace(cipher.card.expYear)) { - if (!this.setCardExpiration(cipher, field.value)) { - this.processKvp( - cipher, - field.label, - field.value, - field.sensitive === 1 ? FieldType.Hidden : FieldType.Text - ); - } - } else { - this.processKvp( - cipher, - field.label, - field.value, - field.sensitive === 1 ? FieldType.Hidden : FieldType.Text - ); - } - }); - } - - private processNote(cipher: CipherView, fields: any[]) { - fields.forEach((field: any) => { - if (this.isNullOrWhitespace(field.value) || field.type === "section") { - return; - } - this.processKvp( - cipher, - field.label, - field.value, - field.sensitive === 1 ? FieldType.Hidden : FieldType.Text - ); - }); - } - - private buildFolderTree(folders: any[]): any[] { - if (folders == null) { - return []; - } - const folderTree: any[] = []; - const map = new Map([]); - folders.forEach((obj: any) => { - map.set(obj.uuid, obj); - obj.children = []; - }); - folders.forEach((obj: any) => { - if (obj.parent_uuid != null && obj.parent_uuid !== "" && map.has(obj.parent_uuid)) { - map.get(obj.parent_uuid).children.push(obj); - } else { - folderTree.push(obj); - } - }); - return folderTree; - } - - private flattenFolderTree(titlePrefix: string, tree: any[], map: Map) { - if (tree == null) { - return; - } - tree.forEach((f: any) => { - if (f.title != null && f.title.trim() !== "") { - let title = f.title.trim(); - if (titlePrefix != null && titlePrefix.trim() !== "") { - title = titlePrefix + "/" + title; - } - map.set(f.uuid, title); - if (f.children != null && f.children.length !== 0) { - this.flattenFolderTree(title, f.children, map); - } - } - }); - } -} diff --git a/jslib/common/src/importers/firefoxCsvImporter.ts b/jslib/common/src/importers/firefoxCsvImporter.ts deleted file mode 100644 index 1b71aac96..000000000 --- a/jslib/common/src/importers/firefoxCsvImporter.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class FirefoxCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results - .filter((value) => { - return value.url !== "chrome://FirefoxAccounts"; - }) - .forEach((value) => { - const cipher = this.initLoginCipher(); - const url = this.getValueOrDefault(value.url, this.getValueOrDefault(value.hostname)); - cipher.name = this.getValueOrDefault(this.nameFromUrl(url), "--"); - cipher.login.username = this.getValueOrDefault(value.username); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.uris = this.makeUriArray(url); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/fsecureFskImporter.ts b/jslib/common/src/importers/fsecureFskImporter.ts deleted file mode 100644 index c81a0820f..000000000 --- a/jslib/common/src/importers/fsecureFskImporter.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class FSecureFskImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = JSON.parse(data); - if (results == null || results.data == null) { - result.success = false; - return Promise.resolve(result); - } - - for (const key in results.data) { - // eslint-disable-next-line - if (!results.data.hasOwnProperty(key)) { - continue; - } - - const value = results.data[key]; - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.service); - cipher.notes = this.getValueOrDefault(value.notes); - - if (value.style === "website" || value.style === "globe") { - cipher.login.username = this.getValueOrDefault(value.username); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.uris = this.makeUriArray(value.url); - } else if (value.style === "creditcard") { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - cipher.card.cardholderName = this.getValueOrDefault(value.username); - cipher.card.number = this.getValueOrDefault(value.creditNumber); - cipher.card.brand = this.getCardBrand(cipher.card.number); - cipher.card.code = this.getValueOrDefault(value.creditCvv); - if (!this.isNullOrWhitespace(value.creditExpiry)) { - if (!this.setCardExpiration(cipher, value.creditExpiry)) { - this.processKvp(cipher, "Expiration", value.creditExpiry); - } - } - if (!this.isNullOrWhitespace(value.password)) { - this.processKvp(cipher, "PIN", value.password); - } - } else { - continue; - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/gnomeJsonImporter.ts b/jslib/common/src/importers/gnomeJsonImporter.ts deleted file mode 100644 index 1dfac6754..000000000 --- a/jslib/common/src/importers/gnomeJsonImporter.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class GnomeJsonImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = JSON.parse(data); - if (results == null || Object.keys(results).length === 0) { - result.success = false; - return Promise.resolve(result); - } - - for (const keyRing in results) { - if ( - !results.hasOwnProperty(keyRing) || // eslint-disable-line - this.isNullOrWhitespace(keyRing) || - results[keyRing].length === 0 - ) { - continue; - } - - results[keyRing].forEach((value: any) => { - if ( - this.isNullOrWhitespace(value.display_name) || - value.display_name.indexOf("http") !== 0 - ) { - return; - } - - this.processFolder(result, keyRing); - const cipher = this.initLoginCipher(); - cipher.name = value.display_name.replace("http://", "").replace("https://", ""); - if (cipher.name.length > 30) { - cipher.name = cipher.name.substring(0, 30); - } - cipher.login.password = this.getValueOrDefault(value.secret); - cipher.login.uris = this.makeUriArray(value.display_name); - - if (value.attributes != null) { - cipher.login.username = - value.attributes != null - ? this.getValueOrDefault(value.attributes.username_value) - : null; - for (const attr in value.attributes) { - if ( - !value.attributes.hasOwnProperty(attr) || // eslint-disable-line - attr === "username_value" || - attr === "xdg:schema" - ) { - continue; - } - this.processKvp(cipher, attr, value.attributes[attr]); - } - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - } - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/importError.ts b/jslib/common/src/importers/importError.ts deleted file mode 100644 index 6a74d66e9..000000000 --- a/jslib/common/src/importers/importError.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class ImportError extends Error { - constructor(message?: string, public passwordRequired: boolean = false) { - super(message); - } -} diff --git a/jslib/common/src/importers/importer.ts b/jslib/common/src/importers/importer.ts deleted file mode 100644 index a62cc6c13..000000000 --- a/jslib/common/src/importers/importer.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -export interface Importer { - organizationId: string; - parse(data: string): Promise; -} diff --git a/jslib/common/src/importers/kasperskyTxtImporter.ts b/jslib/common/src/importers/kasperskyTxtImporter.ts deleted file mode 100644 index b049f2bb1..000000000 --- a/jslib/common/src/importers/kasperskyTxtImporter.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -const NotesHeader = "Notes\n\n"; -const ApplicationsHeader = "Applications\n\n"; -const WebsitesHeader = "Websites\n\n"; -const Delimiter = "\n---\n"; - -export class KasperskyTxtImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - - let notesData: string; - let applicationsData: string; - let websitesData: string; - let workingData = this.splitNewLine(data).join("\n"); - - if (workingData.indexOf(NotesHeader) !== -1) { - const parts = workingData.split(NotesHeader); - if (parts.length > 1) { - workingData = parts[0]; - notesData = parts[1]; - } - } - if (workingData.indexOf(ApplicationsHeader) !== -1) { - const parts = workingData.split(ApplicationsHeader); - if (parts.length > 1) { - workingData = parts[0]; - applicationsData = parts[1]; - } - } - if (workingData.indexOf(WebsitesHeader) === 0) { - const parts = workingData.split(WebsitesHeader); - if (parts.length > 1) { - workingData = parts[0]; - websitesData = parts[1]; - } - } - - const notes = this.parseDataCategory(notesData); - const applications = this.parseDataCategory(applicationsData); - const websites = this.parseDataCategory(websitesData); - - notes.forEach((n) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(n.get("Name")); - cipher.notes = this.getValueOrDefault(n.get("Text")); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - websites.concat(applications).forEach((w) => { - const cipher = this.initLoginCipher(); - const nameKey = w.has("Website name") ? "Website name" : "Application"; - cipher.name = this.getValueOrDefault(w.get(nameKey), ""); - if (!this.isNullOrWhitespace(w.get("Login name"))) { - if (!this.isNullOrWhitespace(cipher.name)) { - cipher.name += ": "; - } - cipher.name += w.get("Login name"); - } - cipher.notes = this.getValueOrDefault(w.get("Comment")); - if (w.has("Website URL")) { - cipher.login.uris = this.makeUriArray(w.get("Website URL")); - } - cipher.login.username = this.getValueOrDefault(w.get("Login")); - cipher.login.password = this.getValueOrDefault(w.get("Password")); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } - - private parseDataCategory(data: string): Map[] { - if (this.isNullOrWhitespace(data) || data.indexOf(Delimiter) === -1) { - return []; - } - const items: Map[] = []; - data.split(Delimiter).forEach((p) => { - if (p.indexOf("\n") === -1) { - return; - } - const item = new Map(); - let itemComment: string; - let itemCommentKey: string; - p.split("\n").forEach((l) => { - if (itemComment != null) { - itemComment += "\n" + l; - return; - } - const colonIndex = l.indexOf(":"); - let key: string; - let val: string; - if (colonIndex === -1) { - return; - } else { - key = l.substring(0, colonIndex); - if (l.length > colonIndex + 1) { - val = l.substring(colonIndex + 2); - } - } - if (key != null) { - item.set(key, val); - } - if (key === "Comment" || key === "Text") { - itemComment = val; - itemCommentKey = key; - } - }); - if (itemComment != null && itemCommentKey != null) { - item.set(itemCommentKey, itemComment); - } - if (item.size === 0) { - return; - } - items.push(item); - }); - return items; - } -} diff --git a/jslib/common/src/importers/keepass2XmlImporter.ts b/jslib/common/src/importers/keepass2XmlImporter.ts deleted file mode 100644 index 2ed5d0f96..000000000 --- a/jslib/common/src/importers/keepass2XmlImporter.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { FieldType } from "../enums/fieldType"; -import { ImportResult } from "../models/domain/importResult"; -import { FolderView } from "../models/view/folderView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class KeePass2XmlImporter extends BaseImporter implements Importer { - result = new ImportResult(); - - parse(data: string): Promise { - const doc = this.parseXml(data); - if (doc == null) { - this.result.success = false; - return Promise.resolve(this.result); - } - - const rootGroup = doc.querySelector("KeePassFile > Root > Group"); - if (rootGroup == null) { - this.result.errorMessage = "Missing `KeePassFile > Root > Group` node."; - this.result.success = false; - return Promise.resolve(this.result); - } - - this.traverse(rootGroup, true, ""); - - if (this.organization) { - this.moveFoldersToCollections(this.result); - } - - this.result.success = true; - return Promise.resolve(this.result); - } - - traverse(node: Element, isRootNode: boolean, groupPrefixName: string) { - const folderIndex = this.result.folders.length; - let groupName = groupPrefixName; - - if (!isRootNode) { - if (groupName !== "") { - groupName += "/"; - } - const nameEl = this.querySelectorDirectChild(node, "Name"); - groupName += nameEl == null ? "-" : nameEl.textContent; - const folder = new FolderView(); - folder.name = groupName; - this.result.folders.push(folder); - } - - this.querySelectorAllDirectChild(node, "Entry").forEach((entry) => { - const cipherIndex = this.result.ciphers.length; - - const cipher = this.initLoginCipher(); - this.querySelectorAllDirectChild(entry, "String").forEach((entryString) => { - const valueEl = this.querySelectorDirectChild(entryString, "Value"); - const value = valueEl != null ? valueEl.textContent : null; - if (this.isNullOrWhitespace(value)) { - return; - } - const keyEl = this.querySelectorDirectChild(entryString, "Key"); - const key = keyEl != null ? keyEl.textContent : null; - - if (key === "URL") { - cipher.login.uris = this.makeUriArray(value); - } else if (key === "UserName") { - cipher.login.username = value; - } else if (key === "Password") { - cipher.login.password = value; - } else if (key === "otp") { - cipher.login.totp = value.replace("key=", ""); - } else if (key === "Title") { - cipher.name = value; - } else if (key === "Notes") { - cipher.notes += value + "\n"; - } else { - let type = FieldType.Text; - const attrs = valueEl.attributes as any; - if ( - attrs.length > 0 && - attrs.ProtectInMemory != null && - attrs.ProtectInMemory.value === "True" - ) { - type = FieldType.Hidden; - } - this.processKvp(cipher, key, value, type); - } - }); - - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - - if (!isRootNode) { - this.result.folderRelationships.push([cipherIndex, folderIndex]); - } - }); - - this.querySelectorAllDirectChild(node, "Group").forEach((group) => { - this.traverse(group, false, groupName); - }); - } -} diff --git a/jslib/common/src/importers/keepassxCsvImporter.ts b/jslib/common/src/importers/keepassxCsvImporter.ts deleted file mode 100644 index 58640d5ae..000000000 --- a/jslib/common/src/importers/keepassxCsvImporter.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class KeePassXCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (this.isNullOrWhitespace(value.Title)) { - return; - } - - value.Group = - !this.isNullOrWhitespace(value.Group) && value.Group.startsWith("Root/") - ? value.Group.replace("Root/", "") - : value.Group; - const groupName = !this.isNullOrWhitespace(value.Group) ? value.Group : null; - this.processFolder(result, groupName); - - const cipher = this.initLoginCipher(); - cipher.notes = this.getValueOrDefault(value.Notes); - cipher.name = this.getValueOrDefault(value.Title, "--"); - cipher.login.username = this.getValueOrDefault(value.Username); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.uris = this.makeUriArray(value.URL); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/keeperImporters/keeperCsvImporter.ts b/jslib/common/src/importers/keeperImporters/keeperCsvImporter.ts deleted file mode 100644 index e9c65d715..000000000 --- a/jslib/common/src/importers/keeperImporters/keeperCsvImporter.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ImportResult } from "../../models/domain/importResult"; -import { BaseImporter } from "../baseImporter"; -import { Importer } from "../importer"; - -export class KeeperCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.length < 6) { - return; - } - - this.processFolder(result, value[0]); - const cipher = this.initLoginCipher(); - cipher.notes = this.getValueOrDefault(value[5]) + "\n"; - cipher.name = this.getValueOrDefault(value[1], "--"); - cipher.login.username = this.getValueOrDefault(value[2]); - cipher.login.password = this.getValueOrDefault(value[3]); - cipher.login.uris = this.makeUriArray(value[4]); - - if (value.length > 7) { - // we have some custom fields. - for (let i = 7; i < value.length; i = i + 2) { - this.processKvp(cipher, value[i], value[i + 1]); - } - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/keeperImporters/keeperJsonImporter.ts b/jslib/common/src/importers/keeperImporters/keeperJsonImporter.ts deleted file mode 100644 index 7ee80b08e..000000000 --- a/jslib/common/src/importers/keeperImporters/keeperJsonImporter.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ImportResult } from "../../models/domain/importResult"; -import { BaseImporter } from "../baseImporter"; -import { Importer } from "../importer"; - -import { KeeperJsonExport, RecordsEntity } from "./types/keeperJsonTypes"; - -export class KeeperJsonImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const keeperExport: KeeperJsonExport = JSON.parse(data); - if (keeperExport == null || keeperExport.records == null || keeperExport.records.length === 0) { - result.success = false; - return Promise.resolve(result); - } - - keeperExport.records.forEach((record) => { - this.parseFolders(result, record); - - const cipher = this.initLoginCipher(); - cipher.name = record.title; - cipher.login.username = record.login; - cipher.login.password = record.password; - - cipher.login.uris = this.makeUriArray(record.login_url); - cipher.notes = record.notes; - - if (record.custom_fields != null) { - let customfieldKeys = Object.keys(record.custom_fields); - if (record.custom_fields["TFC:Keeper"] != null) { - customfieldKeys = customfieldKeys.filter((item) => item !== "TFC:Keeper"); - cipher.login.totp = record.custom_fields["TFC:Keeper"]; - } - - customfieldKeys.forEach((key) => { - this.processKvp(cipher, key, record.custom_fields[key]); - }); - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - private parseFolders(result: ImportResult, record: RecordsEntity) { - if (record.folders == null || record.folders.length === 0) { - return; - } - - record.folders.forEach((item) => { - if (item.folder != null) { - this.processFolder(result, item.folder); - return; - } - - if (item.shared_folder != null) { - this.processFolder(result, item.shared_folder); - return; - } - }); - } -} diff --git a/jslib/common/src/importers/keeperImporters/types/keeperJsonTypes.ts b/jslib/common/src/importers/keeperImporters/types/keeperJsonTypes.ts deleted file mode 100644 index 1f6d2ea4c..000000000 --- a/jslib/common/src/importers/keeperImporters/types/keeperJsonTypes.ts +++ /dev/null @@ -1,41 +0,0 @@ -export interface KeeperJsonExport { - shared_folders?: SharedFoldersEntity[] | null; - records?: RecordsEntity[] | null; -} - -export interface SharedFoldersEntity { - path: string; - manage_users: boolean; - manage_records: boolean; - can_edit: boolean; - can_share: boolean; - permissions?: PermissionsEntity[] | null; -} - -export interface PermissionsEntity { - uid?: string | null; - manage_users: boolean; - manage_records: boolean; - name?: string | null; -} - -export interface RecordsEntity { - title: string; - login: string; - password: string; - login_url: string; - notes?: string; - custom_fields?: CustomFields; - folders?: FoldersEntity[] | null; -} - -export type CustomFields = { - [key: string]: string | null; -}; - -export interface FoldersEntity { - folder?: string | null; - shared_folder?: string | null; - can_edit?: boolean | null; - can_share?: boolean | null; -} diff --git a/jslib/common/src/importers/lastpassCsvImporter.ts b/jslib/common/src/importers/lastpassCsvImporter.ts deleted file mode 100644 index 5c0160280..000000000 --- a/jslib/common/src/importers/lastpassCsvImporter.ts +++ /dev/null @@ -1,285 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; -import { CipherView } from "../models/view/cipherView"; -import { FolderView } from "../models/view/folderView"; -import { IdentityView } from "../models/view/identityView"; -import { LoginView } from "../models/view/loginView"; -import { SecureNoteView } from "../models/view/secureNoteView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class LastPassCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipherIndex = result.ciphers.length; - let folderIndex = result.folders.length; - let grouping = value.grouping; - if (grouping != null) { - // eslint-disable-next-line - grouping = grouping.replace(/\\/g, "/").replace(/[\x00-\x1F\x7F-\x9F]/g, ""); - } - const hasFolder = this.getValueOrDefault(grouping, "(none)") !== "(none)"; - let addFolder = hasFolder; - - if (hasFolder) { - for (let i = 0; i < result.folders.length; i++) { - if (result.folders[i].name === grouping) { - addFolder = false; - folderIndex = i; - break; - } - } - } - - const cipher = this.buildBaseCipher(value); - if (cipher.type === CipherType.Login) { - cipher.notes = this.getValueOrDefault(value.extra); - cipher.login = new LoginView(); - cipher.login.uris = this.makeUriArray(value.url); - cipher.login.username = this.getValueOrDefault(value.username); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.totp = this.getValueOrDefault(value.totp); - } else if (cipher.type === CipherType.SecureNote) { - this.parseSecureNote(value, cipher); - } else if (cipher.type === CipherType.Card) { - cipher.card = this.parseCard(value); - cipher.notes = this.getValueOrDefault(value.notes); - } else if (cipher.type === CipherType.Identity) { - cipher.identity = this.parseIdentity(value); - cipher.notes = this.getValueOrDefault(value.notes); - if (!this.isNullOrWhitespace(value.ccnum)) { - // there is a card on this identity too - const cardCipher = this.buildBaseCipher(value); - cardCipher.identity = null; - cardCipher.type = CipherType.Card; - cardCipher.card = this.parseCard(value); - result.ciphers.push(cardCipher); - } - } - - result.ciphers.push(cipher); - - if (addFolder) { - const f = new FolderView(); - f.name = grouping; - result.folders.push(f); - } - if (hasFolder) { - result.folderRelationships.push([cipherIndex, folderIndex]); - } - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - private buildBaseCipher(value: any) { - const cipher = new CipherView(); - // eslint-disable-next-line - if (value.hasOwnProperty("profilename") && value.hasOwnProperty("profilelanguage")) { - // form fill - cipher.favorite = false; - cipher.name = this.getValueOrDefault(value.profilename, "--"); - cipher.type = CipherType.Card; - - if ( - !this.isNullOrWhitespace(value.title) || - !this.isNullOrWhitespace(value.firstname) || - !this.isNullOrWhitespace(value.lastname) || - !this.isNullOrWhitespace(value.address1) || - !this.isNullOrWhitespace(value.phone) || - !this.isNullOrWhitespace(value.username) || - !this.isNullOrWhitespace(value.email) - ) { - cipher.type = CipherType.Identity; - } - } else { - // site or secure note - cipher.favorite = !this.organization && this.getValueOrDefault(value.fav, "0") === "1"; - cipher.name = this.getValueOrDefault(value.name, "--"); - cipher.type = value.url === "http://sn" ? CipherType.SecureNote : CipherType.Login; - } - return cipher; - } - - private parseCard(value: any): CardView { - const card = new CardView(); - card.cardholderName = this.getValueOrDefault(value.ccname); - card.number = this.getValueOrDefault(value.ccnum); - card.code = this.getValueOrDefault(value.cccsc); - card.brand = this.getCardBrand(value.ccnum); - - if (!this.isNullOrWhitespace(value.ccexp) && value.ccexp.indexOf("-") > -1) { - const ccexpParts = (value.ccexp as string).split("-"); - if (ccexpParts.length > 1) { - card.expYear = ccexpParts[0]; - card.expMonth = ccexpParts[1]; - if (card.expMonth.length === 2 && card.expMonth[0] === "0") { - card.expMonth = card.expMonth[1]; - } - } - } - - return card; - } - - private parseIdentity(value: any): IdentityView { - const identity = new IdentityView(); - identity.title = this.getValueOrDefault(value.title); - identity.firstName = this.getValueOrDefault(value.firstname); - identity.middleName = this.getValueOrDefault(value.middlename); - identity.lastName = this.getValueOrDefault(value.lastname); - identity.username = this.getValueOrDefault(value.username); - identity.company = this.getValueOrDefault(value.company); - identity.ssn = this.getValueOrDefault(value.ssn); - identity.address1 = this.getValueOrDefault(value.address1); - identity.address2 = this.getValueOrDefault(value.address2); - identity.address3 = this.getValueOrDefault(value.address3); - identity.city = this.getValueOrDefault(value.city); - identity.state = this.getValueOrDefault(value.state); - identity.postalCode = this.getValueOrDefault(value.zip); - identity.country = this.getValueOrDefault(value.country); - identity.email = this.getValueOrDefault(value.email); - identity.phone = this.getValueOrDefault(value.phone); - - if (!this.isNullOrWhitespace(identity.title)) { - identity.title = identity.title.charAt(0).toUpperCase() + identity.title.slice(1); - } - - return identity; - } - - private parseSecureNote(value: any, cipher: CipherView) { - const extraParts = this.splitNewLine(value.extra); - let processedNote = false; - - if (extraParts.length) { - const typeParts = extraParts[0].split(":"); - if ( - typeParts.length > 1 && - typeParts[0] === "NoteType" && - (typeParts[1] === "Credit Card" || typeParts[1] === "Address") - ) { - if (typeParts[1] === "Credit Card") { - const mappedData = this.parseSecureNoteMapping(cipher, extraParts, { - Number: "number", - "Name on Card": "cardholderName", - "Security Code": "code", - // LP provides date in a format like 'June,2020' - // Store in expMonth, then parse and modify - "Expiration Date": "expMonth", - }); - - if (this.isNullOrWhitespace(mappedData.expMonth) || mappedData.expMonth === ",") { - // No expiration data - mappedData.expMonth = undefined; - } else { - const [monthString, year] = mappedData.expMonth.split(","); - // Parse month name into number - if (!this.isNullOrWhitespace(monthString)) { - const month = new Date(Date.parse(monthString.trim() + " 1, 2012")).getMonth() + 1; - if (isNaN(month)) { - mappedData.expMonth = undefined; - } else { - mappedData.expMonth = month.toString(); - } - } else { - mappedData.expMonth = undefined; - } - if (!this.isNullOrWhitespace(year)) { - mappedData.expYear = year; - } - } - - cipher.type = CipherType.Card; - cipher.card = mappedData; - } else if (typeParts[1] === "Address") { - const mappedData = this.parseSecureNoteMapping(cipher, extraParts, { - Title: "title", - "First Name": "firstName", - "Last Name": "lastName", - "Middle Name": "middleName", - Company: "company", - "Address 1": "address1", - "Address 2": "address2", - "Address 3": "address3", - "City / Town": "city", - State: "state", - "Zip / Postal Code": "postalCode", - Country: "country", - "Email Address": "email", - Username: "username", - }); - cipher.type = CipherType.Identity; - cipher.identity = mappedData; - } - processedNote = true; - } - } - - if (!processedNote) { - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - cipher.notes = this.getValueOrDefault(value.extra); - } - } - - private parseSecureNoteMapping(cipher: CipherView, extraParts: string[], map: any): T { - const dataObj: any = {}; - - let processingNotes = false; - extraParts.forEach((extraPart) => { - let key: string = null; - let val: string = null; - if (!processingNotes) { - if (this.isNullOrWhitespace(extraPart)) { - return; - } - const colonIndex = extraPart.indexOf(":"); - if (colonIndex === -1) { - key = extraPart; - } else { - key = extraPart.substring(0, colonIndex); - if (extraPart.length > colonIndex) { - val = extraPart.substring(colonIndex + 1); - } - } - if (this.isNullOrWhitespace(key) || this.isNullOrWhitespace(val) || key === "NoteType") { - return; - } - } - - if (processingNotes) { - cipher.notes += "\n" + extraPart; - } else if (key === "Notes") { - if (!this.isNullOrWhitespace(cipher.notes)) { - cipher.notes += "\n" + val; - } else { - cipher.notes = val; - } - processingNotes = true; - // eslint-disable-next-line - } else if (map.hasOwnProperty(key)) { - dataObj[map[key]] = val; - } else { - this.processKvp(cipher, key, val); - } - }); - - return dataObj; - } -} diff --git a/jslib/common/src/importers/logMeOnceCsvImporter.ts b/jslib/common/src/importers/logMeOnceCsvImporter.ts deleted file mode 100644 index 698ebc802..000000000 --- a/jslib/common/src/importers/logMeOnceCsvImporter.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class LogMeOnceCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.length < 4) { - return; - } - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value[0], "--"); - cipher.login.username = this.getValueOrDefault(value[2]); - cipher.login.password = this.getValueOrDefault(value[3]); - cipher.login.uris = this.makeUriArray(value[1]); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/meldiumCsvImporter.ts b/jslib/common/src/importers/meldiumCsvImporter.ts deleted file mode 100644 index 79835a90b..000000000 --- a/jslib/common/src/importers/meldiumCsvImporter.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class MeldiumCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.DisplayName, "--"); - cipher.notes = this.getValueOrDefault(value.Notes); - cipher.login.username = this.getValueOrDefault(value.UserName); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.uris = this.makeUriArray(value.Url); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/msecureCsvImporter.ts b/jslib/common/src/importers/msecureCsvImporter.ts deleted file mode 100644 index 583d13d7d..000000000 --- a/jslib/common/src/importers/msecureCsvImporter.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { SecureNoteView } from "../models/view/secureNoteView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class MSecureCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.length < 3) { - return; - } - - const folderName = - this.getValueOrDefault(value[0], "Unassigned") !== "Unassigned" ? value[0] : null; - this.processFolder(result, folderName); - - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value[2], "--"); - - if (value[1] === "Web Logins" || value[1] === "Login") { - cipher.login.uris = this.makeUriArray(value[4]); - cipher.login.username = this.getValueOrDefault(value[5]); - cipher.login.password = this.getValueOrDefault(value[6]); - cipher.notes = !this.isNullOrWhitespace(value[3]) ? value[3].split("\\n").join("\n") : null; - } else if (value.length > 3) { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - for (let i = 3; i < value.length; i++) { - if (!this.isNullOrWhitespace(value[i])) { - cipher.notes += value[i] + "\n"; - } - } - } - - if (!this.isNullOrWhitespace(value[1]) && cipher.type !== CipherType.Login) { - cipher.name = value[1] + ": " + cipher.name; - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/mykiCsvImporter.ts b/jslib/common/src/importers/mykiCsvImporter.ts deleted file mode 100644 index d9a05e1eb..000000000 --- a/jslib/common/src/importers/mykiCsvImporter.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; -import { CipherView } from "../models/view/cipherView"; -import { IdentityView } from "../models/view/identityView"; -import { SecureNoteView } from "../models/view/secureNoteView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -const mappedBaseColumns = ["nickname", "additionalInfo"]; -const _mappedUserAccountColumns = new Set( - mappedBaseColumns.concat(["url", "username", "password", "twofaSecret"]) -); -const _mappedCreditCardColumns = new Set( - mappedBaseColumns.concat(["cardNumber", "cardName", "exp_month", "exp_year", "cvv"]) -); - -const _mappedIdentityColumns = new Set( - mappedBaseColumns.concat([ - "title", - "firstName", - "middleName", - "lastName", - "email", - "firstAddressLine", - "secondAddressLine", - "city", - "country", - "zipCode", - ]) -); - -const _mappedIdCardColumns = new Set(mappedBaseColumns.concat(["idName", "idNumber", "idCountry"])); - -const _mappedTwoFaColumns = new Set(mappedBaseColumns.concat(["authToken"])); - -const _mappedUserNoteColumns = new Set(mappedBaseColumns.concat(["content"])); - -export class MykiCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.nickname, "--"); - cipher.notes = this.getValueOrDefault(value.additionalInfo); - - if (value.url !== undefined) { - // Accounts - cipher.login.uris = this.makeUriArray(value.url); - cipher.login.username = this.getValueOrDefault(value.username); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.totp = this.getValueOrDefault(value.twofaSecret); - - this.importUnmappedFields(cipher, value, _mappedUserAccountColumns); - } else if (value.authToken !== undefined) { - // TwoFA - cipher.login.totp = this.getValueOrDefault(value.authToken); - - this.importUnmappedFields(cipher, value, _mappedTwoFaColumns); - } else if (value.cardNumber !== undefined) { - // Cards - cipher.card = new CardView(); - cipher.type = CipherType.Card; - cipher.card.cardholderName = this.getValueOrDefault(value.cardName); - cipher.card.number = this.getValueOrDefault(value.cardNumber); - cipher.card.brand = this.getCardBrand(cipher.card.number); - cipher.card.expMonth = this.getValueOrDefault(value.exp_month); - cipher.card.expYear = this.getValueOrDefault(value.exp_year); - cipher.card.code = this.getValueOrDefault(value.cvv); - - this.importUnmappedFields(cipher, value, _mappedCreditCardColumns); - } else if (value.firstName !== undefined) { - // Identities - cipher.identity = new IdentityView(); - cipher.type = CipherType.Identity; - cipher.identity.title = this.getValueOrDefault(value.title); - cipher.identity.firstName = this.getValueOrDefault(value.firstName); - cipher.identity.middleName = this.getValueOrDefault(value.middleName); - cipher.identity.lastName = this.getValueOrDefault(value.lastName); - cipher.identity.phone = this.getValueOrDefault(value.number); - cipher.identity.email = this.getValueOrDefault(value.email); - cipher.identity.address1 = this.getValueOrDefault(value.firstAddressLine); - cipher.identity.address2 = this.getValueOrDefault(value.secondAddressLine); - cipher.identity.city = this.getValueOrDefault(value.city); - cipher.identity.country = this.getValueOrDefault(value.country); - cipher.identity.postalCode = this.getValueOrDefault(value.zipCode); - - this.importUnmappedFields(cipher, value, _mappedIdentityColumns); - } else if (value.idType !== undefined) { - // IdCards - - cipher.identity = new IdentityView(); - cipher.type = CipherType.Identity; - this.processFullName(cipher, value.idName); - cipher.identity.country = this.getValueOrDefault(value.idCountry); - - switch (value.idType) { - // case "Driver's License": - // case "ID Card": - // case "Outdoor License": - // case "Software License": - // case "Tax Number": - // case "Bank Account": - // case "Insurance Card": - // case "Health Card": - // case "Membership": - // case "Database": - // case "Reward Program": - // case "Tour Visa": - case "Passport": - cipher.identity.passportNumber = value.idNumber; - break; - case "Social Security": - cipher.identity.ssn = value.idNumber; - break; - default: - cipher.identity.licenseNumber = value.idNumber; - break; - } - - this.importUnmappedFields(cipher, value, _mappedIdCardColumns); - } else if (value.content !== undefined) { - // Notes - cipher.secureNote = new SecureNoteView(); - cipher.type = CipherType.SecureNote; - cipher.secureNote.type = SecureNoteType.Generic; - cipher.notes = this.getValueOrDefault(value.content); - - this.importUnmappedFields(cipher, value, _mappedUserNoteColumns); - } else { - return; - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } - - importUnmappedFields(cipher: CipherView, row: any, mappedValues: Set) { - const unmappedFields = Object.keys(row).filter((x) => !mappedValues.has(x)); - unmappedFields.forEach((key) => { - const item = row as any; - this.processKvp(cipher, key, item[key]); - }); - } -} diff --git a/jslib/common/src/importers/nordpassCsvImporter.ts b/jslib/common/src/importers/nordpassCsvImporter.ts deleted file mode 100644 index 225e7ec2a..000000000 --- a/jslib/common/src/importers/nordpassCsvImporter.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { CipherView } from "../models/view/cipherView"; -import { LoginView } from "../models/view/loginView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -type nodePassCsvParsed = { - name: string; - url: string; - username: string; - password: string; - note: string; - cardholdername: string; - cardnumber: string; - cvc: string; - expirydate: string; - zipcode: string; - folder: string; - full_name: string; - phone_number: string; - email: string; - address1: string; - address2: string; - city: string; - country: string; - state: string; -}; - -export class NordPassCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results: nodePassCsvParsed[] = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((record) => { - const recordType = this.evaluateType(record); - if (recordType === undefined) { - return; - } - - if (!this.organization) { - this.processFolder(result, record.folder); - } - - const cipher = new CipherView(); - cipher.name = this.getValueOrDefault(record.name, "--"); - cipher.notes = this.getValueOrDefault(record.note); - - switch (recordType) { - case CipherType.Login: - cipher.type = CipherType.Login; - cipher.login = new LoginView(); - cipher.login.username = this.getValueOrDefault(record.username); - cipher.login.password = this.getValueOrDefault(record.password); - cipher.login.uris = this.makeUriArray(record.url); - break; - case CipherType.Card: - cipher.type = CipherType.Card; - cipher.card.cardholderName = this.getValueOrDefault(record.cardholdername); - cipher.card.number = this.getValueOrDefault(record.cardnumber); - cipher.card.code = this.getValueOrDefault(record.cvc); - cipher.card.brand = this.getCardBrand(cipher.card.number); - this.setCardExpiration(cipher, record.expirydate); - break; - - case CipherType.Identity: - cipher.type = CipherType.Identity; - - this.processFullName(cipher, this.getValueOrDefault(record.full_name)); - cipher.identity.address1 = this.getValueOrDefault(record.address1); - cipher.identity.address2 = this.getValueOrDefault(record.address2); - cipher.identity.city = this.getValueOrDefault(record.city); - cipher.identity.state = this.getValueOrDefault(record.state); - cipher.identity.postalCode = this.getValueOrDefault(record.zipcode); - cipher.identity.country = this.getValueOrDefault(record.country); - if (cipher.identity.country != null) { - cipher.identity.country = cipher.identity.country.toUpperCase(); - } - cipher.identity.email = this.getValueOrDefault(record.email); - cipher.identity.phone = this.getValueOrDefault(record.phone_number); - break; - case CipherType.SecureNote: - cipher.type = CipherType.SecureNote; - cipher.secureNote.type = SecureNoteType.Generic; - break; - default: - break; - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - private evaluateType(record: nodePassCsvParsed): CipherType { - if (!this.isNullOrWhitespace(record.username)) { - return CipherType.Login; - } - - if (!this.isNullOrWhitespace(record.cardnumber)) { - return CipherType.Card; - } - - if (!this.isNullOrWhitespace(record.full_name)) { - return CipherType.Identity; - } - - if (!this.isNullOrWhitespace(record.note)) { - return CipherType.SecureNote; - } - - return undefined; - } -} diff --git a/jslib/common/src/importers/onepasswordImporters/cipherImportContext.ts b/jslib/common/src/importers/onepasswordImporters/cipherImportContext.ts deleted file mode 100644 index 560f5c013..000000000 --- a/jslib/common/src/importers/onepasswordImporters/cipherImportContext.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CipherView } from "../../models/view/cipherView"; - -export class CipherImportContext { - lowerProperty: string; - constructor(public importRecord: any, public property: string, public cipher: CipherView) { - this.lowerProperty = property.toLowerCase(); - } -} diff --git a/jslib/common/src/importers/onepasswordImporters/onepassword1PifImporter.ts b/jslib/common/src/importers/onepasswordImporters/onepassword1PifImporter.ts deleted file mode 100644 index f261140e2..000000000 --- a/jslib/common/src/importers/onepasswordImporters/onepassword1PifImporter.ts +++ /dev/null @@ -1,276 +0,0 @@ -import { CipherType } from "../../enums/cipherType"; -import { FieldType } from "../../enums/fieldType"; -import { SecureNoteType } from "../../enums/secureNoteType"; -import { ImportResult } from "../../models/domain/importResult"; -import { CardView } from "../../models/view/cardView"; -import { CipherView } from "../../models/view/cipherView"; -import { IdentityView } from "../../models/view/identityView"; -import { PasswordHistoryView } from "../../models/view/passwordHistoryView"; -import { SecureNoteView } from "../../models/view/secureNoteView"; -import { BaseImporter } from "../baseImporter"; -import { Importer } from "../importer"; - -export class OnePassword1PifImporter extends BaseImporter implements Importer { - result = new ImportResult(); - - parse(data: string): Promise { - data.split(this.newLineRegex).forEach((line) => { - if (this.isNullOrWhitespace(line) || line[0] !== "{") { - return; - } - const item = JSON.parse(line); - if (item.trashed === true) { - return; - } - const cipher = this.initLoginCipher(); - - if (this.isNullOrWhitespace(item.hmac)) { - this.processStandardItem(item, cipher); - } else { - this.processWinOpVaultItem(item, cipher); - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - - this.result.success = true; - return Promise.resolve(this.result); - } - - private processWinOpVaultItem(item: any, cipher: CipherView) { - if (item.overview != null) { - cipher.name = this.getValueOrDefault(item.overview.title); - if (item.overview.URLs != null) { - const urls: string[] = []; - item.overview.URLs.forEach((url: any) => { - if (!this.isNullOrWhitespace(url.u)) { - urls.push(url.u); - } - }); - cipher.login.uris = this.makeUriArray(urls); - } - } - - if (item.details != null) { - if (item.details.passwordHistory != null) { - this.parsePasswordHistory(item.details.passwordHistory, cipher); - } - if ( - !this.isNullOrWhitespace(item.details.ccnum) || - !this.isNullOrWhitespace(item.details.cvv) - ) { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - } else if ( - !this.isNullOrWhitespace(item.details.firstname) || - !this.isNullOrWhitespace(item.details.address1) - ) { - cipher.type = CipherType.Identity; - cipher.identity = new IdentityView(); - } - if (cipher.type === CipherType.Login && !this.isNullOrWhitespace(item.details.password)) { - cipher.login.password = item.details.password; - } - if (!this.isNullOrWhitespace(item.details.notesPlain)) { - cipher.notes = item.details.notesPlain.split(this.newLineRegex).join("\n") + "\n"; - } - if (item.details.fields != null) { - this.parseFields(item.details.fields, cipher, "designation", "value", "name"); - } - if (item.details.sections != null) { - item.details.sections.forEach((section: any) => { - if (section.fields != null) { - this.parseFields(section.fields, cipher, "n", "v", "t"); - } - }); - } - } - } - - private processStandardItem(item: any, cipher: CipherView) { - cipher.favorite = item.openContents && item.openContents.faveIndex ? true : false; - cipher.name = this.getValueOrDefault(item.title); - - if (item.typeName === "securenotes.SecureNote") { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - } else if (item.typeName === "wallet.financial.CreditCard") { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - } else if (item.typeName === "identities.Identity") { - cipher.type = CipherType.Identity; - cipher.identity = new IdentityView(); - } else { - cipher.login.uris = this.makeUriArray(item.location); - } - - if (item.secureContents != null) { - if (item.secureContents.passwordHistory != null) { - this.parsePasswordHistory(item.secureContents.passwordHistory, cipher); - } - if (!this.isNullOrWhitespace(item.secureContents.notesPlain)) { - cipher.notes = item.secureContents.notesPlain.split(this.newLineRegex).join("\n") + "\n"; - } - if (cipher.type === CipherType.Login) { - if (!this.isNullOrWhitespace(item.secureContents.password)) { - cipher.login.password = item.secureContents.password; - } - if (item.secureContents.URLs != null) { - const urls: string[] = []; - item.secureContents.URLs.forEach((u: any) => { - if (!this.isNullOrWhitespace(u.url)) { - urls.push(u.url); - } - }); - if (urls.length > 0) { - cipher.login.uris = this.makeUriArray(urls); - } - } - } - if (item.secureContents.fields != null) { - this.parseFields(item.secureContents.fields, cipher, "designation", "value", "name"); - } - if (item.secureContents.sections != null) { - item.secureContents.sections.forEach((section: any) => { - if (section.fields != null) { - this.parseFields(section.fields, cipher, "n", "v", "t"); - } - }); - } - } - } - - private parsePasswordHistory(items: any[], cipher: CipherView) { - const maxSize = items.length > 5 ? 5 : items.length; - cipher.passwordHistory = items - .filter((h: any) => !this.isNullOrWhitespace(h.value) && h.time != null) - .sort((a, b) => b.time - a.time) - .slice(0, maxSize) - .map((h: any) => { - const ph = new PasswordHistoryView(); - ph.password = h.value; - ph.lastUsedDate = new Date(("" + h.time).length >= 13 ? h.time : h.time * 1000); - return ph; - }); - } - - private parseFields( - fields: any[], - cipher: CipherView, - designationKey: string, - valueKey: string, - nameKey: string - ) { - fields.forEach((field: any) => { - if (field[valueKey] == null || field[valueKey].toString().trim() === "") { - return; - } - - // TODO: when date FieldType exists, store this as a date field type instead of formatted Text if k is 'date' - const fieldValue = - field.k === "date" - ? new Date(field[valueKey] * 1000).toUTCString() - : field[valueKey].toString(); - const fieldDesignation = - field[designationKey] != null ? field[designationKey].toString() : null; - - if (cipher.type === CipherType.Login) { - if (this.isNullOrWhitespace(cipher.login.username) && fieldDesignation === "username") { - cipher.login.username = fieldValue; - return; - } else if ( - this.isNullOrWhitespace(cipher.login.password) && - fieldDesignation === "password" - ) { - cipher.login.password = fieldValue; - return; - } else if ( - this.isNullOrWhitespace(cipher.login.totp) && - fieldDesignation != null && - fieldDesignation.startsWith("TOTP_") - ) { - cipher.login.totp = fieldValue; - return; - } - } else if (cipher.type === CipherType.Card) { - if (this.isNullOrWhitespace(cipher.card.number) && fieldDesignation === "ccnum") { - cipher.card.number = fieldValue; - cipher.card.brand = this.getCardBrand(fieldValue); - return; - } else if (this.isNullOrWhitespace(cipher.card.code) && fieldDesignation === "cvv") { - cipher.card.code = fieldValue; - return; - } else if ( - this.isNullOrWhitespace(cipher.card.cardholderName) && - fieldDesignation === "cardholder" - ) { - cipher.card.cardholderName = fieldValue; - return; - } else if ( - this.isNullOrWhitespace(cipher.card.expiration) && - fieldDesignation === "expiry" && - fieldValue.length === 6 - ) { - cipher.card.expMonth = (fieldValue as string).substr(4, 2); - if (cipher.card.expMonth[0] === "0") { - cipher.card.expMonth = cipher.card.expMonth.substr(1, 1); - } - cipher.card.expYear = (fieldValue as string).substr(0, 4); - return; - } else if (fieldDesignation === "type") { - // Skip since brand was determined from number above - return; - } - } else if (cipher.type === CipherType.Identity) { - const identity = cipher.identity; - if (this.isNullOrWhitespace(identity.firstName) && fieldDesignation === "firstname") { - identity.firstName = fieldValue; - return; - } else if (this.isNullOrWhitespace(identity.lastName) && fieldDesignation === "lastname") { - identity.lastName = fieldValue; - return; - } else if (this.isNullOrWhitespace(identity.middleName) && fieldDesignation === "initial") { - identity.middleName = fieldValue; - return; - } else if (this.isNullOrWhitespace(identity.phone) && fieldDesignation === "defphone") { - identity.phone = fieldValue; - return; - } else if (this.isNullOrWhitespace(identity.company) && fieldDesignation === "company") { - identity.company = fieldValue; - return; - } else if (this.isNullOrWhitespace(identity.email) && fieldDesignation === "email") { - identity.email = fieldValue; - return; - } else if (this.isNullOrWhitespace(identity.username) && fieldDesignation === "username") { - identity.username = fieldValue; - return; - } else if (fieldDesignation === "address") { - // fieldValue is an object casted into a string, so access the plain value instead - const { street, city, country, zip } = field[valueKey]; - identity.address1 = this.getValueOrDefault(street); - identity.city = this.getValueOrDefault(city); - if (!this.isNullOrWhitespace(country)) { - identity.country = country.toUpperCase(); - } - identity.postalCode = this.getValueOrDefault(zip); - return; - } - } - - const fieldName = this.isNullOrWhitespace(field[nameKey]) ? "no_name" : field[nameKey]; - if ( - fieldName === "password" && - cipher.passwordHistory != null && - cipher.passwordHistory.some((h) => h.password === fieldValue) - ) { - return; - } - - const fieldType = field.k === "concealed" ? FieldType.Hidden : FieldType.Text; - this.processKvp(cipher, fieldName, fieldValue, fieldType); - }); - } -} diff --git a/jslib/common/src/importers/onepasswordImporters/onepassword1PuxImporter.ts b/jslib/common/src/importers/onepasswordImporters/onepassword1PuxImporter.ts deleted file mode 100644 index 67f4bb259..000000000 --- a/jslib/common/src/importers/onepasswordImporters/onepassword1PuxImporter.ts +++ /dev/null @@ -1,637 +0,0 @@ -import { CipherRepromptType } from "../../enums/cipherRepromptType"; -import { CipherType } from "../../enums/cipherType"; -import { FieldType } from "../../enums/fieldType"; -import { SecureNoteType } from "../../enums/secureNoteType"; -import { ImportResult } from "../../models/domain/importResult"; -import { CardView } from "../../models/view/cardView"; -import { CipherView } from "../../models/view/cipherView"; -import { IdentityView } from "../../models/view/identityView"; -import { LoginView } from "../../models/view/loginView"; -import { PasswordHistoryView } from "../../models/view/passwordHistoryView"; -import { SecureNoteView } from "../../models/view/secureNoteView"; -import { BaseImporter } from "../baseImporter"; -import { Importer } from "../importer"; - -import { - CategoryEnum, - Details, - ExportData, - FieldsEntity, - Item, - LoginFieldTypeEnum, - Overview, - PasswordHistoryEntity, - SectionsEntity, - UrlsEntity, - Value, - VaultsEntity, -} from "./types/onepassword1PuxImporterTypes"; - -export class OnePassword1PuxImporter extends BaseImporter implements Importer { - result = new ImportResult(); - - parse(data: string): Promise { - const exportData: ExportData = JSON.parse(data); - - const account = exportData.accounts[0]; - // TODO Add handling of multiple vaults - // const personalVaults = account.vaults[0].filter((v) => v.attrs.type === VaultAttributeTypeEnum.Personal); - account.vaults.forEach((vault: VaultsEntity) => { - vault.items.forEach((item: Item) => { - if (item.trashed === true) { - return; - } - - const cipher = this.initLoginCipher(); - - const category = item.categoryUuid as CategoryEnum; - switch (category) { - case CategoryEnum.Login: - case CategoryEnum.Database: - case CategoryEnum.Password: - case CategoryEnum.WirelessRouter: - case CategoryEnum.Server: - case CategoryEnum.API_Credential: - cipher.type = CipherType.Login; - cipher.login = new LoginView(); - break; - case CategoryEnum.CreditCard: - case CategoryEnum.BankAccount: - cipher.type = CipherType.Card; - cipher.card = new CardView(); - break; - case CategoryEnum.SecureNote: - case CategoryEnum.SoftwareLicense: - case CategoryEnum.EmailAccount: - case CategoryEnum.MedicalRecord: - // case CategoryEnum.Document: - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - break; - case CategoryEnum.Identity: - case CategoryEnum.DriversLicense: - case CategoryEnum.OutdoorLicense: - case CategoryEnum.Membership: - case CategoryEnum.Passport: - case CategoryEnum.RewardsProgram: - case CategoryEnum.SocialSecurityNumber: - cipher.type = CipherType.Identity; - cipher.identity = new IdentityView(); - break; - default: - break; - } - - cipher.favorite = item.favIndex === 1 ? true : false; - - this.processOverview(item.overview, cipher); - - this.processLoginFields(item, cipher); - - this.processDetails(category, item.details, cipher); - - this.parsePasswordHistory(item.details.passwordHistory, cipher); - - this.processSections(category, item.details.sections, cipher); - - if (!this.isNullOrWhitespace(item.details.notesPlain)) { - cipher.notes = item.details.notesPlain.split(this.newLineRegex).join("\n") + "\n"; - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - this.result.ciphers.push(cipher); - }); - }); - - if (this.organization) { - this.moveFoldersToCollections(this.result); - } - - this.result.success = true; - return Promise.resolve(this.result); - } - - private processOverview(overview: Overview, cipher: CipherView) { - if (overview == null) { - return; - } - - cipher.name = this.getValueOrDefault(overview.title); - - if (overview.urls != null) { - const urls: string[] = []; - overview.urls.forEach((url: UrlsEntity) => { - if (!this.isNullOrWhitespace(url.url)) { - urls.push(url.url); - } - }); - cipher.login.uris = this.makeUriArray(urls); - } - - if (overview.tags != null && overview.tags.length > 0) { - const folderName = this.capitalize(overview.tags[0]); - this.processFolder(this.result, folderName); - } - } - - private capitalize(inputString: string): string { - return inputString.trim().replace(/\w\S*/g, (w) => w.replace(/^\w/, (c) => c.toUpperCase())); - } - - private processLoginFields(item: Item, cipher: CipherView) { - if (item.details == null) { - return; - } - - if (item.details.loginFields == null || item.details.loginFields.length === 0) { - return; - } - - item.details.loginFields.forEach((loginField) => { - if (loginField.designation === "username" && loginField.value !== "") { - cipher.type = CipherType.Login; - cipher.login.username = loginField.value; - return; - } - - if (loginField.designation === "password" && loginField.value !== "") { - cipher.type = CipherType.Login; - cipher.login.password = loginField.value; - return; - } - - let fieldValue = loginField.value; - let fieldType: FieldType = FieldType.Text; - switch (loginField.fieldType) { - case LoginFieldTypeEnum.Password: - fieldType = FieldType.Hidden; - break; - case LoginFieldTypeEnum.CheckBox: - fieldValue = loginField.value !== "" ? "true" : "false"; - fieldType = FieldType.Boolean; - break; - default: - break; - } - this.processKvp(cipher, loginField.name, fieldValue, fieldType); - }); - } - - private processDetails(category: CategoryEnum, details: Details, cipher: CipherView) { - if (category !== CategoryEnum.Password) { - return; - } - - if (details == null) { - return; - } - cipher.login.password = details.password; - } - - private processSections(category: CategoryEnum, sections: SectionsEntity[], cipher: CipherView) { - if (sections == null || sections.length === 0) { - return; - } - - sections.forEach((section: SectionsEntity) => { - if (section.fields == null) { - return; - } - - this.parseSectionFields(category, section.fields, cipher); - }); - } - - private parseSectionFields(category: CategoryEnum, fields: FieldsEntity[], cipher: CipherView) { - fields.forEach((field: FieldsEntity) => { - const valueKey = Object.keys(field.value)[0]; - const anyField = field as any; - - if ( - anyField.value == null || - anyField.value[valueKey] == null || - anyField.value[valueKey] === "" - ) { - return; - } - - const fieldName = this.getFieldName(field.id, field.title); - const fieldValue = this.extractValue(field.value, valueKey); - - if (cipher.type === CipherType.Login) { - if (this.fillLogin(field, fieldValue, cipher)) { - return; - } - - switch (category) { - case CategoryEnum.Login: - case CategoryEnum.Database: - case CategoryEnum.EmailAccount: - case CategoryEnum.WirelessRouter: - break; - - case CategoryEnum.Server: - if (this.isNullOrWhitespace(cipher.login.uri) && field.id === "url") { - cipher.login.uris = this.makeUriArray(fieldValue); - return; - } - break; - - case CategoryEnum.API_Credential: - if (this.fillApiCredentials(field, fieldValue, cipher)) { - return; - } - break; - default: - break; - } - } else if (cipher.type === CipherType.Card) { - if (this.fillCreditCard(field, fieldValue, cipher)) { - return; - } - - if (category === CategoryEnum.BankAccount) { - if (this.fillBankAccount(field, fieldValue, cipher)) { - return; - } - } - } else if (cipher.type === CipherType.Identity) { - if (this.fillIdentity(field, fieldValue, cipher, valueKey)) { - return; - } - if (valueKey === "address") { - // fieldValue is an object casted into a string, so access the plain value instead - const { street, city, country, zip, state } = field.value.address; - cipher.identity.address1 = this.getValueOrDefault(street); - cipher.identity.city = this.getValueOrDefault(city); - if (!this.isNullOrWhitespace(country)) { - cipher.identity.country = country.toUpperCase(); - } - cipher.identity.postalCode = this.getValueOrDefault(zip); - cipher.identity.state = this.getValueOrDefault(state); - return; - } - - switch (category) { - case CategoryEnum.Identity: - break; - case CategoryEnum.DriversLicense: - if (this.fillDriversLicense(field, fieldValue, cipher)) { - return; - } - break; - case CategoryEnum.OutdoorLicense: - if (this.fillOutdoorLicense(field, fieldValue, cipher)) { - return; - } - break; - case CategoryEnum.Membership: - if (this.fillMembership(field, fieldValue, cipher)) { - return; - } - break; - case CategoryEnum.Passport: - if (this.fillPassport(field, fieldValue, cipher)) { - return; - } - break; - case CategoryEnum.RewardsProgram: - if (this.fillRewardsProgram(field, fieldValue, cipher)) { - return; - } - break; - case CategoryEnum.SocialSecurityNumber: - if (this.fillSSN(field, fieldValue, cipher)) { - return; - } - break; - default: - break; - } - } - - if (valueKey === "email") { - // fieldValue is an object casted into a string, so access the plain value instead - const { email_address, provider } = field.value.email; - this.processKvp(cipher, fieldName, email_address, FieldType.Text); - this.processKvp(cipher, "provider", provider, FieldType.Text); - return; - } - - // Do not include a password field if it's already in the history - if ( - field.title === "password" && - cipher.passwordHistory != null && - cipher.passwordHistory.some((h) => h.password === fieldValue) - ) { - return; - } - - // TODO ?? If one of the fields is marked as guarded, then activate Password-Reprompt for the entire item - if (field.guarded && cipher.reprompt === CipherRepromptType.None) { - cipher.reprompt = CipherRepromptType.Password; - } - - const fieldType = valueKey === "concealed" ? FieldType.Hidden : FieldType.Text; - this.processKvp(cipher, fieldName, fieldValue, fieldType); - }); - } - - private getFieldName(id: string, title: string): string { - if (this.isNullOrWhitespace(title)) { - return id; - } - - // Naive approach of checking if the fields id is usable - if (id.length > 25 && RegExp(/[0-9]{2}[A-Z]{2}/, "i").test(id)) { - return title; - } - return id; - } - - private extractValue(value: Value, valueKey: string): string { - if (valueKey === "date") { - return new Date(value.date * 1000).toUTCString(); - } - - if (valueKey === "monthYear") { - return value.monthYear.toString(); - } - - return (value as any)[valueKey]; - } - - private fillLogin(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - const fieldName = this.getFieldName(field.id, field.title); - - if (this.isNullOrWhitespace(cipher.login.username) && fieldName === "username") { - cipher.login.username = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.login.password) && fieldName === "password") { - cipher.login.password = fieldValue; - return true; - } - - if ( - this.isNullOrWhitespace(cipher.login.totp) && - field.id != null && - field.id.startsWith("TOTP_") - ) { - cipher.login.totp = fieldValue; - return true; - } - - return false; - } - - private fillApiCredentials(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - const fieldName = this.getFieldName(field.id, field.title); - - if (this.isNullOrWhitespace(cipher.login.password) && fieldName === "credential") { - cipher.login.password = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.login.uri) && fieldName === "hostname") { - cipher.login.uris = this.makeUriArray(fieldValue); - return true; - } - - return false; - } - - private fillCreditCard(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.card.number) && field.id === "ccnum") { - cipher.card.number = fieldValue; - cipher.card.brand = this.getCardBrand(fieldValue); - return true; - } - - if (this.isNullOrWhitespace(cipher.card.code) && field.id === "cvv") { - cipher.card.code = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.card.cardholderName) && field.id === "cardholder") { - cipher.card.cardholderName = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.card.expiration) && field.id === "expiry") { - const monthYear: string = fieldValue.toString().trim(); - cipher.card.expMonth = monthYear.substring(4, 6); - if (cipher.card.expMonth[0] === "0") { - cipher.card.expMonth = cipher.card.expMonth.substring(1, 2); - } - cipher.card.expYear = monthYear.substring(0, 4); - return true; - } - - if (field.id === "type") { - // Skip since brand was determined from number above - return true; - } - - return false; - } - - private fillBankAccount(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.card.cardholderName) && field.id === "owner") { - cipher.card.cardholderName = fieldValue; - return true; - } - - return false; - } - - private fillIdentity( - field: FieldsEntity, - fieldValue: string, - cipher: CipherView, - valueKey: string - ): boolean { - if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "firstname") { - cipher.identity.firstName = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.lastName) && field.id === "lastname") { - cipher.identity.lastName = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.middleName) && field.id === "initial") { - cipher.identity.middleName = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.phone) && field.id === "defphone") { - cipher.identity.phone = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.company) && field.id === "company") { - cipher.identity.company = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.email)) { - if (valueKey === "email") { - const { email_address, provider } = field.value.email; - cipher.identity.email = this.getValueOrDefault(email_address); - this.processKvp(cipher, "provider", provider, FieldType.Text); - return true; - } - - if (field.id === "email") { - cipher.identity.email = fieldValue; - return true; - } - } - - if (this.isNullOrWhitespace(cipher.identity.username) && field.id === "username") { - cipher.identity.username = fieldValue; - return true; - } - return false; - } - - private fillDriversLicense(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "fullname") { - this.processFullName(cipher, fieldValue); - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.address1) && field.id === "address") { - cipher.identity.address1 = fieldValue; - return true; - } - - // TODO ISO code - if (this.isNullOrWhitespace(cipher.identity.country) && field.id === "country") { - cipher.identity.country = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.state) && field.id === "state") { - cipher.identity.state = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.licenseNumber) && field.id === "number") { - cipher.identity.licenseNumber = fieldValue; - return true; - } - - return false; - } - - private fillOutdoorLicense(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "name") { - this.processFullName(cipher, fieldValue); - return true; - } - - // TODO ISO code - if (this.isNullOrWhitespace(cipher.identity.country) && field.id === "country") { - cipher.identity.country = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.state) && field.id === "state") { - cipher.identity.state = fieldValue; - return true; - } - - return false; - } - - private fillMembership(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "member_name") { - this.processFullName(cipher, fieldValue); - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.company) && field.id === "org_name") { - cipher.identity.company = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.phone) && field.id === "phone") { - cipher.identity.phone = fieldValue; - return true; - } - - return false; - } - - private fillPassport(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "fullname") { - this.processFullName(cipher, fieldValue); - return true; - } - - // TODO Iso - if (this.isNullOrWhitespace(cipher.identity.country) && field.id === "issuing_country") { - cipher.identity.country = fieldValue; - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.passportNumber) && field.id === "number") { - cipher.identity.passportNumber = fieldValue; - return true; - } - - return false; - } - - private fillRewardsProgram(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "member_name") { - this.processFullName(cipher, fieldValue); - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.company) && field.id === "company_name") { - cipher.identity.company = fieldValue; - return true; - } - - return false; - } - - private fillSSN(field: FieldsEntity, fieldValue: string, cipher: CipherView): boolean { - if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "name") { - this.processFullName(cipher, fieldValue); - return true; - } - - if (this.isNullOrWhitespace(cipher.identity.ssn) && field.id === "number") { - cipher.identity.ssn = fieldValue; - return true; - } - - return false; - } - - private parsePasswordHistory(historyItems: PasswordHistoryEntity[], cipher: CipherView) { - if (historyItems == null || historyItems.length === 0) { - return; - } - - const maxSize = historyItems.length > 5 ? 5 : historyItems.length; - cipher.passwordHistory = historyItems - .filter((h: any) => !this.isNullOrWhitespace(h.value) && h.time != null) - .sort((a, b) => b.time - a.time) - .slice(0, maxSize) - .map((h: any) => { - const ph = new PasswordHistoryView(); - ph.password = h.value; - ph.lastUsedDate = new Date(("" + h.time).length >= 13 ? h.time : h.time * 1000); - return ph; - }); - } -} diff --git a/jslib/common/src/importers/onepasswordImporters/onepasswordCsvImporter.ts b/jslib/common/src/importers/onepasswordImporters/onepasswordCsvImporter.ts deleted file mode 100644 index d28bdcccc..000000000 --- a/jslib/common/src/importers/onepasswordImporters/onepasswordCsvImporter.ts +++ /dev/null @@ -1,383 +0,0 @@ -import { CipherType } from "../../enums/cipherType"; -import { FieldType } from "../../enums/fieldType"; -import { ImportResult } from "../../models/domain/importResult"; -import { CipherView } from "../../models/view/cipherView"; -import { BaseImporter } from "../baseImporter"; -import { Importer } from "../importer"; - -import { CipherImportContext } from "./cipherImportContext"; - -export const IgnoredProperties = [ - "ainfo", - "autosubmit", - "notesplain", - "ps", - "scope", - "tags", - "title", - "uuid", - "notes", -]; - -export abstract class OnePasswordCsvImporter extends BaseImporter implements Importer { - protected loginPropertyParsers = [ - this.setLoginUsername, - this.setLoginPassword, - this.setLoginUris, - ]; - protected creditCardPropertyParsers = [ - this.setCreditCardNumber, - this.setCreditCardVerification, - this.setCreditCardCardholderName, - this.setCreditCardExpiry, - ]; - protected identityPropertyParsers = [ - this.setIdentityFirstName, - this.setIdentityInitial, - this.setIdentityLastName, - this.setIdentityUserName, - this.setIdentityEmail, - this.setIdentityPhone, - this.setIdentityCompany, - ]; - - abstract setCipherType(value: any, cipher: CipherView): void; - - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true, { - quoteChar: '"', - escapeChar: "\\", - }); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (this.isNullOrWhitespace(this.getProp(value, "title"))) { - return; - } - - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(this.getProp(value, "title"), "--"); - - this.setNotes(value, cipher); - - this.setCipherType(value, cipher); - - let altUsername: string = null; - for (const property in value) { - // eslint-disable-next-line - if (!value.hasOwnProperty(property) || this.isNullOrWhitespace(value[property])) { - continue; - } - - const context = new CipherImportContext(value, property, cipher); - if (cipher.type === CipherType.Login && this.setKnownLoginValue(context)) { - continue; - } else if (cipher.type === CipherType.Card && this.setKnownCreditCardValue(context)) { - continue; - } else if (cipher.type === CipherType.Identity && this.setKnownIdentityValue(context)) { - continue; - } - - altUsername = this.setUnknownValue(context, altUsername); - } - - if ( - cipher.type === CipherType.Login && - !this.isNullOrWhitespace(altUsername) && - this.isNullOrWhitespace(cipher.login.username) && - altUsername.indexOf("://") === -1 - ) { - cipher.login.username = altUsername; - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } - - protected getProp(obj: any, name: string): any { - const lowerObj = Object.entries(obj).reduce((agg: any, entry: [string, any]) => { - agg[entry[0].toLowerCase()] = entry[1]; - return agg; - }, {}); - return lowerObj[name.toLowerCase()]; - } - - protected getPropByRegexp(obj: any, regexp: RegExp): any { - const matchingKeys = Object.keys(obj).reduce((agg: string[], key: string) => { - if (key.match(regexp)) { - agg.push(key); - } - return agg; - }, []); - if (matchingKeys.length === 0) { - return null; - } else { - return obj[matchingKeys[0]]; - } - } - - protected getPropIncluding(obj: any, name: string): any { - const includesMap = Object.keys(obj).reduce((agg: string[], entry: string) => { - if (entry.toLowerCase().includes(name.toLowerCase())) { - agg.push(entry); - } - return agg; - }, []); - if (includesMap.length === 0) { - return null; - } else { - return obj[includesMap[0]]; - } - } - - protected setNotes(importRecord: any, cipher: CipherView) { - cipher.notes = - this.getValueOrDefault(this.getProp(importRecord, "notesPlain"), "") + - "\n" + - this.getValueOrDefault(this.getProp(importRecord, "notes"), "") + - "\n"; - cipher.notes.trim(); - } - - protected setKnownLoginValue(context: CipherImportContext): boolean { - return this.loginPropertyParsers.reduce((agg: boolean, func) => { - if (!agg) { - agg = func.bind(this)(context); - } - return agg; - }, false); - } - - protected setKnownCreditCardValue(context: CipherImportContext): boolean { - return this.creditCardPropertyParsers.reduce((agg: boolean, func) => { - if (!agg) { - agg = func.bind(this)(context); - } - return agg; - }, false); - } - - protected setKnownIdentityValue(context: CipherImportContext): boolean { - return this.identityPropertyParsers.reduce((agg: boolean, func) => { - if (!agg) { - agg = func.bind(this)(context); - } - return agg; - }, false); - } - - protected setUnknownValue(context: CipherImportContext, altUsername: string): string { - if ( - IgnoredProperties.indexOf(context.lowerProperty) === -1 && - !context.lowerProperty.startsWith("section:") && - !context.lowerProperty.startsWith("section ") - ) { - if (altUsername == null && context.lowerProperty === "email") { - return context.importRecord[context.property]; - } else if ( - context.lowerProperty === "created date" || - context.lowerProperty === "modified date" - ) { - const readableDate = new Date( - parseInt(context.importRecord[context.property], 10) * 1000 - ).toUTCString(); - this.processKvp(context.cipher, "1Password " + context.property, readableDate); - return null; - } - if ( - context.lowerProperty.includes("password") || - context.lowerProperty.includes("key") || - context.lowerProperty.includes("secret") - ) { - this.processKvp( - context.cipher, - context.property, - context.importRecord[context.property], - FieldType.Hidden - ); - } else { - this.processKvp(context.cipher, context.property, context.importRecord[context.property]); - } - } - return null; - } - - protected setIdentityFirstName(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.identity.firstName) && - context.lowerProperty.includes("first name") - ) { - context.cipher.identity.firstName = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setIdentityInitial(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.identity.middleName) && - context.lowerProperty.includes("initial") - ) { - context.cipher.identity.middleName = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setIdentityLastName(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.identity.lastName) && - context.lowerProperty.includes("last name") - ) { - context.cipher.identity.lastName = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setIdentityUserName(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.identity.username) && - context.lowerProperty.includes("username") - ) { - context.cipher.identity.username = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setIdentityCompany(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.identity.company) && - context.lowerProperty.includes("company") - ) { - context.cipher.identity.company = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setIdentityPhone(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.identity.phone) && - context.lowerProperty.includes("default phone") - ) { - context.cipher.identity.phone = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setIdentityEmail(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.identity.email) && - context.lowerProperty.includes("email") - ) { - context.cipher.identity.email = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setCreditCardNumber(context: CipherImportContext): boolean { - if ( - this.isNullOrWhitespace(context.cipher.card.number) && - context.lowerProperty.includes("number") - ) { - context.cipher.card.number = context.importRecord[context.property]; - context.cipher.card.brand = this.getCardBrand(context.cipher.card.number); - return true; - } - return false; - } - - protected setCreditCardVerification(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.card.code) && - context.lowerProperty.includes("verification number") - ) { - context.cipher.card.code = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setCreditCardCardholderName(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.card.cardholderName) && - context.lowerProperty.includes("cardholder name") - ) { - context.cipher.card.cardholderName = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setCreditCardExpiry(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.card.expiration) && - context.lowerProperty.includes("expiry date") && - context.importRecord[context.property].length === 7 - ) { - context.cipher.card.expMonth = (context.importRecord[context.property] as string).substr( - 0, - 2 - ); - if (context.cipher.card.expMonth[0] === "0") { - context.cipher.card.expMonth = context.cipher.card.expMonth.substr(1, 1); - } - context.cipher.card.expYear = (context.importRecord[context.property] as string).substr(3, 4); - return true; - } - return false; - } - - protected setLoginPassword(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.login.password) && - context.lowerProperty === "password" - ) { - context.cipher.login.password = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setLoginUsername(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.login.username) && - context.lowerProperty === "username" - ) { - context.cipher.login.username = context.importRecord[context.property]; - return true; - } - return false; - } - - protected setLoginUris(context: CipherImportContext) { - if ( - (context.cipher.login.uris == null || context.cipher.login.uris.length === 0) && - context.lowerProperty === "urls" - ) { - const urls = context.importRecord[context.property].split(this.newLineRegex); - context.cipher.login.uris = this.makeUriArray(urls); - return true; - } else if (context.lowerProperty === "url") { - if (context.cipher.login.uris == null) { - context.cipher.login.uris = []; - } - context.cipher.login.uris.concat(this.makeUriArray(context.importRecord[context.property])); - return true; - } - return false; - } -} diff --git a/jslib/common/src/importers/onepasswordImporters/onepasswordMacCsvImporter.ts b/jslib/common/src/importers/onepasswordImporters/onepasswordMacCsvImporter.ts deleted file mode 100644 index 2135c80a3..000000000 --- a/jslib/common/src/importers/onepasswordImporters/onepasswordMacCsvImporter.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { CipherType } from "../../enums/cipherType"; -import { CardView } from "../../models/view/cardView"; -import { CipherView } from "../../models/view/cipherView"; -import { IdentityView } from "../../models/view/identityView"; -import { Importer } from "../importer"; - -import { IgnoredProperties, OnePasswordCsvImporter } from "./onepasswordCsvImporter"; - -export class OnePasswordMacCsvImporter extends OnePasswordCsvImporter implements Importer { - setCipherType(value: any, cipher: CipherView) { - const onePassType = this.getValueOrDefault(this.getProp(value, "type"), "Login"); - switch (onePassType) { - case "Credit Card": - cipher.type = CipherType.Card; - cipher.card = new CardView(); - IgnoredProperties.push("type"); - break; - case "Identity": - cipher.type = CipherType.Identity; - cipher.identity = new IdentityView(); - IgnoredProperties.push("type"); - break; - case "Login": - case "Secure Note": - IgnoredProperties.push("type"); - break; - default: - break; - } - } -} diff --git a/jslib/common/src/importers/onepasswordImporters/onepasswordWinCsvImporter.ts b/jslib/common/src/importers/onepasswordImporters/onepasswordWinCsvImporter.ts deleted file mode 100644 index 3b3d6454f..000000000 --- a/jslib/common/src/importers/onepasswordImporters/onepasswordWinCsvImporter.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { CipherType } from "../../enums/cipherType"; -import { CardView } from "../../models/view/cardView"; -import { CipherView } from "../../models/view/cipherView"; -import { IdentityView } from "../../models/view/identityView"; -import { LoginView } from "../../models/view/loginView"; -import { Importer } from "../importer"; - -import { CipherImportContext } from "./cipherImportContext"; -import { OnePasswordCsvImporter } from "./onepasswordCsvImporter"; - -export class OnePasswordWinCsvImporter extends OnePasswordCsvImporter implements Importer { - constructor() { - super(); - this.identityPropertyParsers.push(this.setIdentityAddress); - } - - setCipherType(value: any, cipher: CipherView) { - cipher.type = CipherType.Login; - cipher.login = new LoginView(); - - if ( - !this.isNullOrWhitespace(this.getPropByRegexp(value, /\d+: number/i)) && - !this.isNullOrWhitespace(this.getPropByRegexp(value, /\d+: expiry date/i)) - ) { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - } - - if ( - !this.isNullOrWhitespace(this.getPropByRegexp(value, /name \d+: first name/i)) || - !this.isNullOrWhitespace(this.getPropByRegexp(value, /name \d+: initial/i)) || - !this.isNullOrWhitespace(this.getPropByRegexp(value, /name \d+: last name/i)) || - !this.isNullOrWhitespace(this.getPropByRegexp(value, /internet \d+: email/i)) - ) { - cipher.type = CipherType.Identity; - cipher.identity = new IdentityView(); - } - } - - setIdentityAddress(context: CipherImportContext) { - if (context.lowerProperty.match(/address \d+: address/i)) { - this.processKvp(context.cipher, "address", context.importRecord[context.property]); - return true; - } - return false; - } - - setCreditCardExpiry(context: CipherImportContext) { - if ( - this.isNullOrWhitespace(context.cipher.card.expiration) && - context.lowerProperty.includes("expiry date") - ) { - const expSplit = (context.importRecord[context.property] as string).split("/"); - context.cipher.card.expMonth = expSplit[0]; - if (context.cipher.card.expMonth[0] === "0" && context.cipher.card.expMonth.length === 2) { - context.cipher.card.expMonth = context.cipher.card.expMonth.substr(1, 1); - } - context.cipher.card.expYear = expSplit[2].length > 4 ? expSplit[2].substr(0, 4) : expSplit[2]; - return true; - } - return false; - } -} diff --git a/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes.ts b/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes.ts deleted file mode 100644 index 46ee06197..000000000 --- a/jslib/common/src/importers/onepasswordImporters/types/onepassword1PuxImporterTypes.ts +++ /dev/null @@ -1,160 +0,0 @@ -export interface ExportData { - accounts?: AccountsEntity[] | null; -} -export interface AccountsEntity { - attrs: AccountAttributes; - vaults?: VaultsEntity[] | null; -} -export interface AccountAttributes { - accountName: string; - name: string; - avatar: string; - email: string; - uuid: string; - domain: string; -} -export interface VaultsEntity { - attrs: VaultAttributes; - items?: Item[] | null; -} -export interface VaultAttributes { - uuid: string; - desc: string; - avatar: string; - name: string; - type: string; -} - -export enum CategoryEnum { - Login = "001", - CreditCard = "002", - SecureNote = "003", - Identity = "004", - Password = "005", - Document = "006", - SoftwareLicense = "100", - BankAccount = "101", - Database = "102", - DriversLicense = "103", - OutdoorLicense = "104", - Membership = "105", - Passport = "106", - RewardsProgram = "107", - SocialSecurityNumber = "108", - WirelessRouter = "109", - Server = "110", - EmailAccount = "111", - API_Credential = "112", - MedicalRecord = "113", -} - -export interface Item { - uuid: string; - favIndex: number; - createdAt: number; - updatedAt: number; - trashed?: boolean; - categoryUuid: string; - details: Details; - overview: Overview; -} -export interface Details { - loginFields?: (LoginFieldsEntity | null)[] | null; - notesPlain?: string | null; - sections?: (SectionsEntity | null)[] | null; - passwordHistory?: (PasswordHistoryEntity | null)[] | null; - documentAttributes?: DocumentAttributes | null; - password?: string | null; -} - -export enum LoginFieldTypeEnum { - TextOrHtml = "T", - EmailAddress = "E", - URL = "U", - Number = "N", - Password = "P", - TextArea = "A", - PhoneNumber = "T", - CheckBox = "C", -} -export interface LoginFieldsEntity { - value: string; - id: string; - name: string; - fieldType: LoginFieldTypeEnum | string; - designation?: string | null; -} -export interface SectionsEntity { - title: string; - name?: string | null; - fields?: FieldsEntity[] | null; -} -export interface FieldsEntity { - title: string; - id: string; - value: Value; - indexAtSource: number; - guarded: boolean; - multiline: boolean; - dontGenerate: boolean; - placeholder?: string; - inputTraits: InputTraits; - clipboardFilter?: string | null; -} -export interface Value { - totp?: string | null; - date?: number | null; - string?: string | null; - concealed?: string | null; - email?: Email | null; - phone?: string | null; - menu?: string | null; - gender?: string | null; - monthYear?: number | null; - url?: string | null; - address?: Address | null; - creditCardType?: string | null; - creditCardNumber?: string | null; - reference?: string | null; -} - -export interface Email { - email_address: string; - provider: string; -} - -export interface Address { - street: string; - city: string; - country: string; - zip: string; - state: string; -} -export interface InputTraits { - keyboard: string; - correction: string; - capitalization: string; -} -export interface PasswordHistoryEntity { - value: string; - time: number; -} -export interface DocumentAttributes { - fileName: string; - documentId: string; - decryptedSize: number; -} -export interface Overview { - subtitle: string; - title: string; - url: string; - urls?: UrlsEntity[] | null; - ps?: number | null; - pbe?: number | null; - pgrng?: boolean | null; - tags?: string[] | null; -} -export interface UrlsEntity { - label: string; - url: string; -} diff --git a/jslib/common/src/importers/padlockCsvImporter.ts b/jslib/common/src/importers/padlockCsvImporter.ts deleted file mode 100644 index 821391cff..000000000 --- a/jslib/common/src/importers/padlockCsvImporter.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; -import { CollectionView } from "../models/view/collectionView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PadlockCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - let headers: string[] = null; - results.forEach((value) => { - if (headers == null) { - headers = value.map((v: string) => v); - return; - } - - if (value.length < 2 || value.length !== headers.length) { - return; - } - - if (!this.isNullOrWhitespace(value[1])) { - if (this.organization) { - const tags = (value[1] as string).split(","); - tags.forEach((tag) => { - tag = tag.trim(); - let addCollection = true; - let collectionIndex = result.collections.length; - - for (let i = 0; i < result.collections.length; i++) { - if (result.collections[i].name === tag) { - addCollection = false; - collectionIndex = i; - break; - } - } - - if (addCollection) { - const collection = new CollectionView(); - collection.name = tag; - result.collections.push(collection); - } - - result.collectionRelationships.push([result.ciphers.length, collectionIndex]); - }); - } else { - const tags = (value[1] as string).split(","); - const tag = tags.length > 0 ? tags[0].trim() : null; - this.processFolder(result, tag); - } - } - - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value[0], "--"); - - for (let i = 2; i < value.length; i++) { - const header = headers[i].trim().toLowerCase(); - if (this.isNullOrWhitespace(value[i]) || this.isNullOrWhitespace(header)) { - continue; - } - - if (this.usernameFieldNames.indexOf(header) > -1) { - cipher.login.username = value[i]; - } else if (this.passwordFieldNames.indexOf(header) > -1) { - cipher.login.password = value[i]; - } else if (this.uriFieldNames.indexOf(header) > -1) { - cipher.login.uris = this.makeUriArray(value[i]); - } else { - this.processKvp(cipher, headers[i], value[i]); - } - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/passkeepCsvImporter.ts b/jslib/common/src/importers/passkeepCsvImporter.ts deleted file mode 100644 index c93b3a42e..000000000 --- a/jslib/common/src/importers/passkeepCsvImporter.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PassKeepCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - this.processFolder(result, this.getValue("category", value)); - const cipher = this.initLoginCipher(); - cipher.notes = this.getValue("description", value); - cipher.name = this.getValueOrDefault(this.getValue("title", value), "--"); - cipher.login.username = this.getValue("username", value); - cipher.login.password = this.getValue("password", value); - cipher.login.uris = this.makeUriArray(this.getValue("site", value)); - this.processKvp(cipher, "Password 2", this.getValue("password2", value)); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - private getValue(key: string, value: any) { - return this.getValueOrDefault(value[key], this.getValueOrDefault(value[" " + key])); - } -} diff --git a/jslib/common/src/importers/passmanJsonImporter.ts b/jslib/common/src/importers/passmanJsonImporter.ts deleted file mode 100644 index f8bc7106b..000000000 --- a/jslib/common/src/importers/passmanJsonImporter.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PassmanJsonImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = JSON.parse(data); - if (results == null || results.length === 0) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((credential: any) => { - if (credential.tags != null && credential.tags.length > 0) { - const folderName = credential.tags[0].text; - this.processFolder(result, folderName); - } - - const cipher = this.initLoginCipher(); - cipher.name = credential.label; - - cipher.login.username = this.getValueOrDefault(credential.username); - if (this.isNullOrWhitespace(cipher.login.username)) { - cipher.login.username = this.getValueOrDefault(credential.email); - } else if (!this.isNullOrWhitespace(credential.email)) { - cipher.notes = "Email: " + credential.email + "\n"; - } - - cipher.login.password = this.getValueOrDefault(credential.password); - cipher.login.uris = this.makeUriArray(credential.url); - cipher.notes += this.getValueOrDefault(credential.description, ""); - if (credential.otp != null) { - cipher.login.totp = this.getValueOrDefault(credential.otp.secret); - } - - if (credential.custom_fields != null) { - credential.custom_fields.forEach((customField: any) => { - switch (customField.field_type) { - case "text": - case "password": - this.processKvp(cipher, customField.label, customField.value); - break; - } - }); - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/passpackCsvImporter.ts b/jslib/common/src/importers/passpackCsvImporter.ts deleted file mode 100644 index 8efaa3c3e..000000000 --- a/jslib/common/src/importers/passpackCsvImporter.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; -import { CollectionView } from "../models/view/collectionView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PasspackCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const tagsJson = !this.isNullOrWhitespace(value.Tags) ? JSON.parse(value.Tags) : null; - const tags: string[] = - tagsJson != null && tagsJson.tags != null && tagsJson.tags.length > 0 - ? tagsJson.tags - .map((tagJson: string) => { - try { - const t = JSON.parse(tagJson); - return this.getValueOrDefault(t.tag); - } catch { - // Ignore error - } - return null; - }) - .filter((t: string) => !this.isNullOrWhitespace(t)) - : null; - - if (this.organization && tags != null && tags.length > 0) { - tags.forEach((tag) => { - let addCollection = true; - let collectionIndex = result.collections.length; - - for (let i = 0; i < result.collections.length; i++) { - if (result.collections[i].name === tag) { - addCollection = false; - collectionIndex = i; - break; - } - } - - if (addCollection) { - const collection = new CollectionView(); - collection.name = tag; - result.collections.push(collection); - } - - result.collectionRelationships.push([result.ciphers.length, collectionIndex]); - }); - } else if (!this.organization && tags != null && tags.length > 0) { - this.processFolder(result, tags[0]); - } - - const cipher = this.initLoginCipher(); - cipher.notes = this.getValueOrDefault(value.Notes, ""); - cipher.notes += "\n\n" + this.getValueOrDefault(value["Shared Notes"], "") + "\n"; - cipher.name = this.getValueOrDefault(value["Entry Name"], "--"); - cipher.login.username = this.getValueOrDefault(value["User ID"]); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.uris = this.makeUriArray(value.URL); - - if (value.__parsed_extra != null && value.__parsed_extra.length > 0) { - value.__parsed_extra.forEach((extra: string) => { - if (!this.isNullOrWhitespace(extra)) { - cipher.notes += "\n" + extra; - } - }); - } - - const fieldsJson = !this.isNullOrWhitespace(value["Extra Fields"]) - ? JSON.parse(value["Extra Fields"]) - : null; - const fields = - fieldsJson != null && fieldsJson.extraFields != null && fieldsJson.extraFields.length > 0 - ? fieldsJson.extraFields.map((fieldJson: string) => { - try { - return JSON.parse(fieldJson); - } catch { - // Ignore error - } - return null; - }) - : null; - if (fields != null) { - fields.forEach((f: any) => { - if (f != null) { - this.processKvp(cipher, f.name, f.data); - } - }); - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/passwordAgentCsvImporter.ts b/jslib/common/src/importers/passwordAgentCsvImporter.ts deleted file mode 100644 index cc37f5dd3..000000000 --- a/jslib/common/src/importers/passwordAgentCsvImporter.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PasswordAgentCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - let newVersion = true; - results.forEach((value) => { - if (value.length !== 5 && value.length < 9) { - return; - } - const altFormat = value.length === 10 && value[0] === "0"; - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value[altFormat ? 1 : 0], "--"); - cipher.login.username = this.getValueOrDefault(value[altFormat ? 2 : 1]); - cipher.login.password = this.getValueOrDefault(value[altFormat ? 3 : 2]); - if (value.length === 5) { - newVersion = false; - cipher.notes = this.getValueOrDefault(value[4]); - cipher.login.uris = this.makeUriArray(value[3]); - } else { - const folder = this.getValueOrDefault(value[altFormat ? 9 : 8], "(None)"); - let folderName = folder !== "(None)" ? folder.split("\\").join("/") : null; - if (folderName != null) { - folderName = folder.split(" > ").join("/"); - folderName = folder.split(">").join("/"); - } - this.processFolder(result, folderName); - cipher.notes = this.getValueOrDefault(value[altFormat ? 5 : 3]); - cipher.login.uris = this.makeUriArray(value[4]); - } - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (newVersion && this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/passwordBossJsonImporter.ts b/jslib/common/src/importers/passwordBossJsonImporter.ts deleted file mode 100644 index d60a84fb0..000000000 --- a/jslib/common/src/importers/passwordBossJsonImporter.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; -import { FolderView } from "../models/view/folderView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PasswordBossJsonImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = JSON.parse(data); - if (results == null || results.items == null) { - result.success = false; - return Promise.resolve(result); - } - - const foldersMap = new Map(); - results.folders.forEach((value: any) => { - foldersMap.set(value.id, value.name); - }); - const foldersIndexMap = new Map(); - foldersMap.forEach((val, key) => { - foldersIndexMap.set(key, result.folders.length); - const f = new FolderView(); - f.name = val; - result.folders.push(f); - }); - - results.items.forEach((value: any) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.name, "--"); - cipher.login.uris = this.makeUriArray(value.login_url); - - if (value.folder != null && foldersIndexMap.has(value.folder)) { - result.folderRelationships.push([result.ciphers.length, foldersIndexMap.get(value.folder)]); - } - - if (value.identifiers == null) { - return; - } - - if (!this.isNullOrWhitespace(value.identifiers.notes)) { - cipher.notes = value.identifiers.notes.split("\\r\\n").join("\n").split("\\n").join("\n"); - } - - if (value.type === "CreditCard") { - cipher.card = new CardView(); - cipher.type = CipherType.Card; - } - - for (const property in value.identifiers) { - // eslint-disable-next-line - if (!value.identifiers.hasOwnProperty(property)) { - continue; - } - const valObj = value.identifiers[property]; - const val = valObj != null ? valObj.toString() : null; - if ( - this.isNullOrWhitespace(val) || - property === "notes" || - property === "ignoreItemInSecurityScore" - ) { - continue; - } - - if (property === "custom_fields") { - valObj.forEach((cf: any) => { - this.processKvp(cipher, cf.name, cf.value); - }); - continue; - } - - if (cipher.type === CipherType.Card) { - if (property === "cardNumber") { - cipher.card.number = val; - cipher.card.brand = this.getCardBrand(val); - continue; - } else if (property === "nameOnCard") { - cipher.card.cardholderName = val; - continue; - } else if (property === "security_code") { - cipher.card.code = val; - continue; - } else if (property === "expires") { - try { - const expDate = new Date(val); - cipher.card.expYear = expDate.getFullYear().toString(); - cipher.card.expMonth = (expDate.getMonth() + 1).toString(); - } catch { - // Ignore error - } - continue; - } else if (property === "cardType") { - continue; - } - } else { - if ( - (property === "username" || property === "email") && - this.isNullOrWhitespace(cipher.login.username) - ) { - cipher.login.username = val; - continue; - } else if (property === "password") { - cipher.login.password = val; - continue; - } else if (property === "totp") { - cipher.login.totp = val; - continue; - } else if ( - (cipher.login.uris == null || cipher.login.uris.length === 0) && - this.uriFieldNames.indexOf(property) > -1 - ) { - cipher.login.uris = this.makeUriArray(val); - continue; - } - } - - this.processKvp(cipher, property, val); - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/passwordDragonXmlImporter.ts b/jslib/common/src/importers/passwordDragonXmlImporter.ts deleted file mode 100644 index 433950ad5..000000000 --- a/jslib/common/src/importers/passwordDragonXmlImporter.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PasswordDragonXmlImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const doc = this.parseXml(data); - if (doc == null) { - result.success = false; - return Promise.resolve(result); - } - - const records = doc.querySelectorAll("PasswordManager > record"); - Array.from(records).forEach((record) => { - const category = this.querySelectorDirectChild(record, "Category"); - const categoryText = - category != null && - !this.isNullOrWhitespace(category.textContent) && - category.textContent !== "Unfiled" - ? category.textContent - : null; - this.processFolder(result, categoryText); - - const accountName = this.querySelectorDirectChild(record, "Account-Name"); - const userId = this.querySelectorDirectChild(record, "User-Id"); - const password = this.querySelectorDirectChild(record, "Password"); - const url = this.querySelectorDirectChild(record, "URL"); - const notes = this.querySelectorDirectChild(record, "Notes"); - const cipher = this.initLoginCipher(); - cipher.name = - accountName != null ? this.getValueOrDefault(accountName.textContent, "--") : "--"; - cipher.notes = notes != null ? this.getValueOrDefault(notes.textContent) : ""; - cipher.login.username = userId != null ? this.getValueOrDefault(userId.textContent) : null; - cipher.login.password = - password != null ? this.getValueOrDefault(password.textContent) : null; - cipher.login.uris = url != null ? this.makeUriArray(url.textContent) : null; - - const attributes: string[] = []; - for (let i = 1; i <= 10; i++) { - attributes.push("Attribute-" + i); - } - - this.querySelectorAllDirectChild(record, attributes.join(",")).forEach((attr) => { - if (this.isNullOrWhitespace(attr.textContent) || attr.textContent === "null") { - return; - } - this.processKvp(cipher, attr.tagName, attr.textContent); - }); - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/passwordSafeXmlImporter.ts b/jslib/common/src/importers/passwordSafeXmlImporter.ts deleted file mode 100644 index b7aa93587..000000000 --- a/jslib/common/src/importers/passwordSafeXmlImporter.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PasswordSafeXmlImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const doc = this.parseXml(data); - if (doc == null) { - result.success = false; - return Promise.resolve(result); - } - - const passwordSafe = doc.querySelector("passwordsafe"); - if (passwordSafe == null) { - result.errorMessage = "Missing `passwordsafe` node."; - result.success = false; - return Promise.resolve(result); - } - - const notesDelimiter = passwordSafe.getAttribute("delimiter"); - const entries = doc.querySelectorAll("passwordsafe > entry"); - Array.from(entries).forEach((entry) => { - const group = this.querySelectorDirectChild(entry, "group"); - const groupText = - group != null && !this.isNullOrWhitespace(group.textContent) - ? group.textContent.split(".").join("/") - : null; - this.processFolder(result, groupText); - - const title = this.querySelectorDirectChild(entry, "title"); - const username = this.querySelectorDirectChild(entry, "username"); - const email = this.querySelectorDirectChild(entry, "email"); - const password = this.querySelectorDirectChild(entry, "password"); - const url = this.querySelectorDirectChild(entry, "url"); - const notes = this.querySelectorDirectChild(entry, "notes"); - const cipher = this.initLoginCipher(); - cipher.name = title != null ? this.getValueOrDefault(title.textContent, "--") : "--"; - cipher.notes = - notes != null - ? this.getValueOrDefault(notes.textContent, "").split(notesDelimiter).join("\n") - : null; - cipher.login.username = - username != null ? this.getValueOrDefault(username.textContent) : null; - cipher.login.password = - password != null ? this.getValueOrDefault(password.textContent) : null; - cipher.login.uris = url != null ? this.makeUriArray(url.textContent) : null; - - if (this.isNullOrWhitespace(cipher.login.username) && email != null) { - cipher.login.username = this.getValueOrDefault(email.textContent); - } else if (email != null && !this.isNullOrWhitespace(email.textContent)) { - cipher.notes = this.isNullOrWhitespace(cipher.notes) - ? "Email: " + email.textContent - : cipher.notes + "\n" + "Email: " + email.textContent; - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/passwordWalletTxtImporter.ts b/jslib/common/src/importers/passwordWalletTxtImporter.ts deleted file mode 100644 index b5940372a..000000000 --- a/jslib/common/src/importers/passwordWalletTxtImporter.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class PasswordWalletTxtImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.length < 1) { - return; - } - if (value.length > 5) { - this.processFolder(result, value[5]); - } - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value[0], "--"); - if (value.length > 4) { - cipher.notes = this.getValueOrDefault(value[4], "").split("¬").join("\n"); - } - if (value.length > 2) { - cipher.login.username = this.getValueOrDefault(value[2]); - } - if (value.length > 3) { - cipher.login.password = this.getValueOrDefault(value[3]); - } - if (value.length > 1) { - cipher.login.uris = this.makeUriArray(value[1]); - } - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/rememBearCsvImporter.ts b/jslib/common/src/importers/rememBearCsvImporter.ts deleted file mode 100644 index 3f7dc464f..000000000 --- a/jslib/common/src/importers/rememBearCsvImporter.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class RememBearCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.trash === "true") { - return; - } - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.name); - cipher.notes = this.getValueOrDefault(value.notes); - if (value.type === "LoginItem") { - cipher.login.uris = this.makeUriArray(value.website); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.username = this.getValueOrDefault(value.username); - } else if (value.type === "CreditCardItem") { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - cipher.card.cardholderName = this.getValueOrDefault(value.cardholder); - cipher.card.number = this.getValueOrDefault(value.number); - cipher.card.brand = this.getCardBrand(cipher.card.number); - cipher.card.code = this.getValueOrDefault(value.verification); - - try { - const expMonth = this.getValueOrDefault(value.expiryMonth); - if (expMonth != null) { - const expMonthNumber = parseInt(expMonth, null); - if (expMonthNumber != null && expMonthNumber >= 1 && expMonthNumber <= 12) { - cipher.card.expMonth = expMonthNumber.toString(); - } - } - } catch { - // Ignore error - } - try { - const expYear = this.getValueOrDefault(value.expiryYear); - if (expYear != null) { - const expYearNumber = parseInt(expYear, null); - if (expYearNumber != null) { - cipher.card.expYear = expYearNumber.toString(); - } - } - } catch { - // Ignore error - } - - const pin = this.getValueOrDefault(value.pin); - if (pin != null) { - this.processKvp(cipher, "PIN", pin); - } - const zip = this.getValueOrDefault(value.zipCode); - if (zip != null) { - this.processKvp(cipher, "Zip Code", zip); - } - } - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/roboformCsvImporter.ts b/jslib/common/src/importers/roboformCsvImporter.ts deleted file mode 100644 index c5279e2b1..000000000 --- a/jslib/common/src/importers/roboformCsvImporter.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class RoboFormCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - let i = 1; - results.forEach((value) => { - const folder = - !this.isNullOrWhitespace(value.Folder) && value.Folder.startsWith("/") - ? value.Folder.replace("/", "") - : value.Folder; - const folderName = !this.isNullOrWhitespace(folder) ? folder : null; - this.processFolder(result, folderName); - - const cipher = this.initLoginCipher(); - cipher.notes = this.getValueOrDefault(value.Note); - cipher.name = this.getValueOrDefault(value.Name, "--"); - cipher.login.username = this.getValueOrDefault(value.Login); - cipher.login.password = this.getValueOrDefault(value.Pwd); - cipher.login.uris = this.makeUriArray(value.Url); - - if (!this.isNullOrWhitespace(value.Rf_fields)) { - let fields: string[] = [value.Rf_fields]; - if (value.__parsed_extra != null && value.__parsed_extra.length > 0) { - fields = fields.concat(value.__parsed_extra); - } - fields.forEach((field: string) => { - const parts = field.split(":"); - if (parts.length < 3) { - return; - } - const key = parts[0] === "-no-name-" ? null : parts[0]; - const val = parts.length === 4 && parts[2] === "rck" ? parts[1] : parts[2]; - this.processKvp(cipher, key, val); - }); - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - - if ( - i === results.length && - cipher.name === "--" && - this.isNullOrWhitespace(cipher.login.password) - ) { - return; - } - - result.ciphers.push(cipher); - i++; - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/safariCsvImporter.ts b/jslib/common/src/importers/safariCsvImporter.ts deleted file mode 100644 index 786b28278..000000000 --- a/jslib/common/src/importers/safariCsvImporter.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class SafariCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.Title, "--"); - cipher.login.username = this.getValueOrDefault(value.Username); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.uris = this.makeUriArray(value.Url ?? value.URL); - cipher.login.totp = this.getValueOrDefault(value.OTPAuth); - cipher.notes = this.getValueOrDefault(value.Notes); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/safeInCloudXmlImporter.ts b/jslib/common/src/importers/safeInCloudXmlImporter.ts deleted file mode 100644 index 3e5a81993..000000000 --- a/jslib/common/src/importers/safeInCloudXmlImporter.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { FieldType } from "../enums/fieldType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { CipherView } from "../models/view/cipherView"; -import { FieldView } from "../models/view/fieldView"; -import { FolderView } from "../models/view/folderView"; -import { SecureNoteView } from "../models/view/secureNoteView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class SafeInCloudXmlImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const doc = this.parseXml(data); - if (doc == null) { - result.success = false; - return Promise.resolve(result); - } - - const db = doc.querySelector("database"); - if (db == null) { - result.errorMessage = "Missing `database` node."; - result.success = false; - return Promise.resolve(result); - } - - const foldersMap = new Map(); - - Array.from(doc.querySelectorAll("database > label")).forEach((labelEl) => { - const name = labelEl.getAttribute("name"); - const id = labelEl.getAttribute("id"); - if (!this.isNullOrWhitespace(name) && !this.isNullOrWhitespace(id)) { - foldersMap.set(id, result.folders.length); - const folder = new FolderView(); - folder.name = name; - result.folders.push(folder); - } - }); - - Array.from(doc.querySelectorAll("database > card")).forEach((cardEl) => { - if (cardEl.getAttribute("template") === "true" || cardEl.getAttribute("deleted") === "true") { - return; - } - - const labelIdEl = this.querySelectorDirectChild(cardEl, "label_id"); - if (labelIdEl != null) { - const labelId = labelIdEl.textContent; - if (!this.isNullOrWhitespace(labelId) && foldersMap.has(labelId)) { - result.folderRelationships.push([result.ciphers.length, foldersMap.get(labelId)]); - } - } - - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(cardEl.getAttribute("title"), "--"); - - if (cardEl.getAttribute("star") === "true") { - cipher.favorite = true; - } - - const cardType = cardEl.getAttribute("type"); - if (cardType === "note") { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - } else { - Array.from(this.querySelectorAllDirectChild(cardEl, "field")).forEach((fieldEl) => { - const text = fieldEl.textContent; - if (this.isNullOrWhitespace(text)) { - return; - } - const name = fieldEl.getAttribute("name"); - const fieldType = this.getValueOrDefault(fieldEl.getAttribute("type"), "").toLowerCase(); - if (fieldType === "login") { - cipher.login.username = text; - } else if (fieldType === "password" || fieldType === "secret") { - // safeInCloud allows for more than one password. we just insert them here and find the one used as password later - this.processKvp(cipher, name, text, FieldType.Hidden); - } else if (fieldType === "one_time_password") { - cipher.login.totp = text; - } else if (fieldType === "notes") { - cipher.notes += text + "\n"; - } else if (fieldType === "weblogin" || fieldType === "website") { - cipher.login.uris = this.makeUriArray(text); - } else { - this.processKvp(cipher, name, text); - } - }); - } - - Array.from(this.querySelectorAllDirectChild(cardEl, "notes")).forEach((notesEl) => { - cipher.notes += notesEl.textContent + "\n"; - }); - - this.setPassword(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - // Choose a password from all passwords. Take one that has password in its name, or the first one if there is no such entry - // if its name is password, we can safely remove it form the fields. otherwise, it would maybe be best to keep it as a hidden field - setPassword(cipher: CipherView) { - const candidates = cipher.fields.filter((field) => field.type === FieldType.Hidden); - if (!candidates.length) { - return; - } - - let choice: FieldView; - for (const field of candidates) { - if (this.passwordFieldNames.includes(field.name.toLowerCase())) { - choice = field; - cipher.fields = cipher.fields.filter((f) => f !== choice); - break; - } - } - - if (!choice) { - choice = candidates[0]; - } - - cipher.login.password = choice.value; - } -} diff --git a/jslib/common/src/importers/saferpassCsvImport.ts b/jslib/common/src/importers/saferpassCsvImport.ts deleted file mode 100644 index 6d962ba1b..000000000 --- a/jslib/common/src/importers/saferpassCsvImport.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class SaferPassCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(this.nameFromUrl(value.url), "--"); - cipher.notes = this.getValueOrDefault(value.notes); - cipher.login.username = this.getValueOrDefault(value.username); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.uris = this.makeUriArray(value.url); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/secureSafeCsvImporter.ts b/jslib/common/src/importers/secureSafeCsvImporter.ts deleted file mode 100644 index 8d0ac1fee..000000000 --- a/jslib/common/src/importers/secureSafeCsvImporter.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class SecureSafeCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.Title); - cipher.notes = this.getValueOrDefault(value.Comment); - cipher.login.uris = this.makeUriArray(value.Url); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.username = this.getValueOrDefault(value.Username); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/splashIdCsvImporter.ts b/jslib/common/src/importers/splashIdCsvImporter.ts deleted file mode 100644 index df1118d17..000000000 --- a/jslib/common/src/importers/splashIdCsvImporter.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; -import { CipherView } from "../models/view/cipherView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class SplashIdCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.length < 3) { - return; - } - - this.processFolder(result, this.getValueOrDefault(value[value.length - 1])); - const cipher = this.initLoginCipher(); - cipher.notes = this.getValueOrDefault(value[value.length - 2], ""); - cipher.name = this.getValueOrDefault(value[1], "--"); - - if (value[0] === "Web Logins" || value[0] === "Servers" || value[0] === "Email Accounts") { - cipher.login.username = this.getValueOrDefault(value[2]); - cipher.login.password = this.getValueOrDefault(value[3]); - cipher.login.uris = this.makeUriArray(value[4]); - this.parseFieldsToNotes(cipher, 5, value); - } else { - this.parseFieldsToNotes(cipher, 2, value); - } - - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - private parseFieldsToNotes(cipher: CipherView, startIndex: number, value: any) { - // last 3 rows do not get parsed - for (let i = startIndex; i < value.length - 3; i++) { - if (this.isNullOrWhitespace(value[i])) { - continue; - } - cipher.notes += value[i] + "\n"; - } - } -} diff --git a/jslib/common/src/importers/stickyPasswordXmlImporter.ts b/jslib/common/src/importers/stickyPasswordXmlImporter.ts deleted file mode 100644 index caaa33702..000000000 --- a/jslib/common/src/importers/stickyPasswordXmlImporter.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class StickyPasswordXmlImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const doc = this.parseXml(data); - if (doc == null) { - result.success = false; - return Promise.resolve(result); - } - - const loginNodes = doc.querySelectorAll("root > Database > Logins > Login"); - Array.from(loginNodes).forEach((loginNode) => { - const accountId = loginNode.getAttribute("ID"); - if (this.isNullOrWhitespace(accountId)) { - return; - } - - const usernameText = loginNode.getAttribute("Name"); - const passwordText = loginNode.getAttribute("Password"); - let titleText: string = null; - let linkText: string = null; - let notesText: string = null; - let groupId: string = null; - let groupText: string = null; - - const accountLogin = doc.querySelector( - "root > Database > Accounts > Account > " + - 'LoginLinks > Login[SourceLoginID="' + - accountId + - '"]' - ); - if (accountLogin != null) { - const account = accountLogin.parentElement.parentElement; - if (account != null) { - titleText = account.getAttribute("Name"); - linkText = account.getAttribute("Link"); - groupId = account.getAttribute("ParentID"); - notesText = account.getAttribute("Comments"); - if (!this.isNullOrWhitespace(notesText)) { - notesText = notesText.split("/n").join("\n"); - } - } - } - - if (!this.isNullOrWhitespace(groupId)) { - groupText = this.buildGroupText(doc, groupId, ""); - this.processFolder(result, groupText); - } - - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(titleText, "--"); - cipher.notes = this.getValueOrDefault(notesText); - cipher.login.username = this.getValueOrDefault(usernameText); - cipher.login.password = this.getValueOrDefault(passwordText); - cipher.login.uris = this.makeUriArray(linkText); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - buildGroupText(doc: Document, groupId: string, groupText: string): string { - const group = doc.querySelector('root > Database > Groups > Group[ID="' + groupId + '"]'); - if (group == null) { - return groupText; - } - if (!this.isNullOrWhitespace(groupText)) { - groupText = "/" + groupText; - } - groupText = group.getAttribute("Name") + groupText; - return this.buildGroupText(doc, group.getAttribute("ParentID"), groupText); - } -} diff --git a/jslib/common/src/importers/truekeyCsvImporter.ts b/jslib/common/src/importers/truekeyCsvImporter.ts deleted file mode 100644 index d28af7af0..000000000 --- a/jslib/common/src/importers/truekeyCsvImporter.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { CipherType } from "../enums/cipherType"; -import { SecureNoteType } from "../enums/secureNoteType"; -import { ImportResult } from "../models/domain/importResult"; -import { CardView } from "../models/view/cardView"; -import { SecureNoteView } from "../models/view/secureNoteView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -const PropertiesToIgnore = [ - "kind", - "autologin", - "favorite", - "hexcolor", - "protectedwithpassword", - "subdomainonly", - "type", - "tk_export_version", - "note", - "title", - "document_content", -]; - -export class TrueKeyCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.favorite = this.getValueOrDefault(value.favorite, "").toLowerCase() === "true"; - cipher.name = this.getValueOrDefault(value.name, "--"); - cipher.notes = this.getValueOrDefault(value.memo, ""); - cipher.login.username = this.getValueOrDefault(value.login); - cipher.login.password = this.getValueOrDefault(value.password); - cipher.login.uris = this.makeUriArray(value.url); - - if (value.kind !== "login") { - cipher.name = this.getValueOrDefault(value.title, "--"); - cipher.notes = this.getValueOrDefault(value.note, ""); - } - - if (value.kind === "cc") { - cipher.type = CipherType.Card; - cipher.card = new CardView(); - cipher.card.cardholderName = this.getValueOrDefault(value.cardholder); - cipher.card.number = this.getValueOrDefault(value.number); - cipher.card.brand = this.getCardBrand(cipher.card.number); - if (!this.isNullOrWhitespace(value.expiryDate)) { - try { - const expDate = new Date(value.expiryDate); - cipher.card.expYear = expDate.getFullYear().toString(); - cipher.card.expMonth = (expDate.getMonth() + 1).toString(); - } catch { - // Ignore error - } - } - } else if (value.kind !== "login") { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - if (!this.isNullOrWhitespace(cipher.notes)) { - cipher.notes = this.getValueOrDefault(value.document_content, ""); - } - for (const property in value) { - if ( - value.hasOwnProperty(property) && // eslint-disable-line - PropertiesToIgnore.indexOf(property.toLowerCase()) < 0 && - !this.isNullOrWhitespace(value[property]) - ) { - this.processKvp(cipher, property, value[property]); - } - } - } - - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/upmCsvImporter.ts b/jslib/common/src/importers/upmCsvImporter.ts deleted file mode 100644 index ea092ffcb..000000000 --- a/jslib/common/src/importers/upmCsvImporter.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class UpmCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, false); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if (value.length !== 5) { - return; - } - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value[0], "--"); - cipher.notes = this.getValueOrDefault(value[4]); - cipher.login.username = this.getValueOrDefault(value[1]); - cipher.login.password = this.getValueOrDefault(value[2]); - cipher.login.uris = this.makeUriArray(value[3]); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/yotiCsvImporter.ts b/jslib/common/src/importers/yotiCsvImporter.ts deleted file mode 100644 index 526f7d692..000000000 --- a/jslib/common/src/importers/yotiCsvImporter.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class YotiCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - const cipher = this.initLoginCipher(); - cipher.name = this.getValueOrDefault(value.Name, "--"); - cipher.login.username = this.getValueOrDefault(value["User name"]); - cipher.login.password = this.getValueOrDefault(value.Password); - cipher.login.uris = this.makeUriArray(value.URL); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - result.success = true; - return Promise.resolve(result); - } -} diff --git a/jslib/common/src/importers/zohoVaultCsvImporter.ts b/jslib/common/src/importers/zohoVaultCsvImporter.ts deleted file mode 100644 index 18008e807..000000000 --- a/jslib/common/src/importers/zohoVaultCsvImporter.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { ImportResult } from "../models/domain/importResult"; -import { CipherView } from "../models/view/cipherView"; - -import { BaseImporter } from "./baseImporter"; -import { Importer } from "./importer"; - -export class ZohoVaultCsvImporter extends BaseImporter implements Importer { - parse(data: string): Promise { - const result = new ImportResult(); - const results = this.parseCsv(data, true); - if (results == null) { - result.success = false; - return Promise.resolve(result); - } - - results.forEach((value) => { - if ( - this.isNullOrWhitespace(value["Password Name"]) && - this.isNullOrWhitespace(value["Secret Name"]) - ) { - return; - } - this.processFolder(result, this.getValueOrDefault(value.ChamberName)); - const cipher = this.initLoginCipher(); - cipher.favorite = this.getValueOrDefault(value.Favorite, "0") === "1"; - cipher.notes = this.getValueOrDefault(value.Notes); - cipher.name = this.getValueOrDefault( - value["Password Name"], - this.getValueOrDefault(value["Secret Name"], "--") - ); - cipher.login.uris = this.makeUriArray( - this.getValueOrDefault(value["Password URL"], this.getValueOrDefault(value["Secret URL"])) - ); - this.parseData(cipher, value.SecretData); - this.parseData(cipher, value.CustomData); - this.convertToNoteIfNeeded(cipher); - this.cleanupCipher(cipher); - result.ciphers.push(cipher); - }); - - if (this.organization) { - this.moveFoldersToCollections(result); - } - - result.success = true; - return Promise.resolve(result); - } - - private parseData(cipher: CipherView, data: string) { - if (this.isNullOrWhitespace(data)) { - return; - } - const dataLines = this.splitNewLine(data); - dataLines.forEach((line) => { - const delimPosition = line.indexOf(":"); - if (delimPosition < 0) { - return; - } - const field = line.substring(0, delimPosition); - const value = line.length > delimPosition ? line.substring(delimPosition + 1) : null; - if ( - this.isNullOrWhitespace(field) || - this.isNullOrWhitespace(value) || - field === "SecretType" - ) { - return; - } - const fieldLower = field.toLowerCase(); - if (cipher.login.username == null && this.usernameFieldNames.indexOf(fieldLower) > -1) { - cipher.login.username = value; - } else if ( - cipher.login.password == null && - this.passwordFieldNames.indexOf(fieldLower) > -1 - ) { - cipher.login.password = value; - } else { - this.processKvp(cipher, field, value); - } - }); - } -} diff --git a/jslib/common/src/models/domain/importResult.ts b/jslib/common/src/models/domain/importResult.ts deleted file mode 100644 index 695dbf9d4..000000000 --- a/jslib/common/src/models/domain/importResult.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CipherView } from "../view/cipherView"; -import { CollectionView } from "../view/collectionView"; -import { FolderView } from "../view/folderView"; - -export class ImportResult { - success = false; - missingPassword = false; - errorMessage: string; - ciphers: CipherView[] = []; - folders: FolderView[] = []; - folderRelationships: [number, number][] = []; - collections: CollectionView[] = []; - collectionRelationships: [number, number][] = []; -} diff --git a/jslib/common/src/models/export/card.ts b/jslib/common/src/models/export/card.ts deleted file mode 100644 index b320ec8b7..000000000 --- a/jslib/common/src/models/export/card.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Card as CardDomain } from "../domain/card"; -import { EncString } from "../domain/encString"; -import { CardView } from "../view/cardView"; - -export class Card { - static template(): Card { - const req = new Card(); - req.cardholderName = "John Doe"; - req.brand = "visa"; - req.number = "4242424242424242"; - req.expMonth = "04"; - req.expYear = "2023"; - req.code = "123"; - return req; - } - - static toView(req: Card, view = new CardView()) { - view.cardholderName = req.cardholderName; - view.brand = req.brand; - view.number = req.number; - view.expMonth = req.expMonth; - view.expYear = req.expYear; - view.code = req.code; - return view; - } - - static toDomain(req: Card, domain = new CardDomain()) { - domain.cardholderName = req.cardholderName != null ? new EncString(req.cardholderName) : null; - domain.brand = req.brand != null ? new EncString(req.brand) : null; - domain.number = req.number != null ? new EncString(req.number) : null; - domain.expMonth = req.expMonth != null ? new EncString(req.expMonth) : null; - domain.expYear = req.expYear != null ? new EncString(req.expYear) : null; - domain.code = req.code != null ? new EncString(req.code) : null; - return domain; - } - - cardholderName: string; - brand: string; - number: string; - expMonth: string; - expYear: string; - code: string; - - constructor(o?: CardView | CardDomain) { - if (o == null) { - return; - } - - if (o instanceof CardView) { - this.cardholderName = o.cardholderName; - this.brand = o.brand; - this.number = o.number; - this.expMonth = o.expMonth; - this.expYear = o.expYear; - this.code = o.code; - } else { - this.cardholderName = o.cardholderName?.encryptedString; - this.brand = o.brand?.encryptedString; - this.number = o.number?.encryptedString; - this.expMonth = o.expMonth?.encryptedString; - this.expYear = o.expYear?.encryptedString; - this.code = o.code?.encryptedString; - } - } -} diff --git a/jslib/common/src/models/export/cipher.ts b/jslib/common/src/models/export/cipher.ts deleted file mode 100644 index 5d6506663..000000000 --- a/jslib/common/src/models/export/cipher.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { CipherRepromptType } from "../../enums/cipherRepromptType"; -import { CipherType } from "../../enums/cipherType"; -import { Cipher as CipherDomain } from "../domain/cipher"; -import { EncString } from "../domain/encString"; -import { CipherView } from "../view/cipherView"; - -import { Card } from "./card"; -import { Field } from "./field"; -import { Identity } from "./identity"; -import { Login } from "./login"; -import { SecureNote } from "./secureNote"; - -export class Cipher { - static template(): Cipher { - const req = new Cipher(); - req.organizationId = null; - req.collectionIds = null; - req.folderId = null; - req.type = CipherType.Login; - req.name = "Item name"; - req.notes = "Some notes about this item."; - req.favorite = false; - req.fields = []; - req.login = null; - req.secureNote = null; - req.card = null; - req.identity = null; - req.reprompt = CipherRepromptType.None; - return req; - } - - static toView(req: Cipher, view = new CipherView()) { - view.type = req.type; - view.folderId = req.folderId; - if (view.organizationId == null) { - view.organizationId = req.organizationId; - } - if (view.collectionIds || req.collectionIds) { - const set = new Set((view.collectionIds ?? []).concat(req.collectionIds ?? [])); - view.collectionIds = Array.from(set.values()); - } - view.name = req.name; - view.notes = req.notes; - view.favorite = req.favorite; - view.reprompt = req.reprompt ?? CipherRepromptType.None; - - if (req.fields != null) { - view.fields = req.fields.map((f) => Field.toView(f)); - } - - switch (req.type) { - case CipherType.Login: - view.login = Login.toView(req.login); - break; - case CipherType.SecureNote: - view.secureNote = SecureNote.toView(req.secureNote); - break; - case CipherType.Card: - view.card = Card.toView(req.card); - break; - case CipherType.Identity: - view.identity = Identity.toView(req.identity); - break; - } - - return view; - } - - static toDomain(req: Cipher, domain = new CipherDomain()) { - domain.type = req.type; - domain.folderId = req.folderId; - if (domain.organizationId == null) { - domain.organizationId = req.organizationId; - } - domain.name = req.name != null ? new EncString(req.name) : null; - domain.notes = req.notes != null ? new EncString(req.notes) : null; - domain.favorite = req.favorite; - domain.reprompt = req.reprompt ?? CipherRepromptType.None; - - if (req.fields != null) { - domain.fields = req.fields.map((f) => Field.toDomain(f)); - } - - switch (req.type) { - case CipherType.Login: - domain.login = Login.toDomain(req.login); - break; - case CipherType.SecureNote: - domain.secureNote = SecureNote.toDomain(req.secureNote); - break; - case CipherType.Card: - domain.card = Card.toDomain(req.card); - break; - case CipherType.Identity: - domain.identity = Identity.toDomain(req.identity); - break; - } - - return domain; - } - - type: CipherType; - folderId: string; - organizationId: string; - collectionIds: string[]; - name: string; - notes: string; - favorite: boolean; - fields: Field[]; - login: Login; - secureNote: SecureNote; - card: Card; - identity: Identity; - reprompt: CipherRepromptType; - - // Use build method instead of ctor so that we can control order of JSON stringify for pretty print - build(o: CipherView | CipherDomain) { - this.organizationId = o.organizationId; - this.folderId = o.folderId; - this.type = o.type; - this.reprompt = o.reprompt; - - if (o instanceof CipherView) { - this.name = o.name; - this.notes = o.notes; - } else { - this.name = o.name?.encryptedString; - this.notes = o.notes?.encryptedString; - } - - this.favorite = o.favorite; - - if (o.fields != null) { - if (o instanceof CipherView) { - this.fields = o.fields.map((f) => new Field(f)); - } else { - this.fields = o.fields.map((f) => new Field(f)); - } - } - - switch (o.type) { - case CipherType.Login: - this.login = new Login(o.login); - break; - case CipherType.SecureNote: - this.secureNote = new SecureNote(o.secureNote); - break; - case CipherType.Card: - this.card = new Card(o.card); - break; - case CipherType.Identity: - this.identity = new Identity(o.identity); - break; - } - } -} diff --git a/jslib/common/src/models/export/cipherWithIds.ts b/jslib/common/src/models/export/cipherWithIds.ts deleted file mode 100644 index a5698c6dc..000000000 --- a/jslib/common/src/models/export/cipherWithIds.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Cipher as CipherDomain } from "../domain/cipher"; -import { CipherView } from "../view/cipherView"; - -import { Cipher } from "./cipher"; - -export class CipherWithIds extends Cipher { - id: string; - collectionIds: string[]; - - // Use build method instead of ctor so that we can control order of JSON stringify for pretty print - build(o: CipherView | CipherDomain) { - this.id = o.id; - super.build(o); - this.collectionIds = o.collectionIds; - } -} diff --git a/jslib/common/src/models/export/collection.ts b/jslib/common/src/models/export/collection.ts deleted file mode 100644 index fba9af15c..000000000 --- a/jslib/common/src/models/export/collection.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Collection as CollectionDomain } from "../domain/collection"; -import { EncString } from "../domain/encString"; -import { CollectionView } from "../view/collectionView"; - -export class Collection { - static template(): Collection { - const req = new Collection(); - req.organizationId = "00000000-0000-0000-0000-000000000000"; - req.name = "Collection name"; - req.externalId = null; - return req; - } - - static toView(req: Collection, view = new CollectionView()) { - view.name = req.name; - view.externalId = req.externalId; - if (view.organizationId == null) { - view.organizationId = req.organizationId; - } - return view; - } - - static toDomain(req: Collection, domain = new CollectionDomain()) { - domain.name = req.name != null ? new EncString(req.name) : null; - domain.externalId = req.externalId; - if (domain.organizationId == null) { - domain.organizationId = req.organizationId; - } - return domain; - } - - organizationId: string; - name: string; - externalId: string; - - // Use build method instead of ctor so that we can control order of JSON stringify for pretty print - build(o: CollectionView | CollectionDomain) { - this.organizationId = o.organizationId; - if (o instanceof CollectionView) { - this.name = o.name; - } else { - this.name = o.name?.encryptedString; - } - this.externalId = o.externalId; - } -} diff --git a/jslib/common/src/models/export/collectionWithId.ts b/jslib/common/src/models/export/collectionWithId.ts deleted file mode 100644 index 7bc0707a8..000000000 --- a/jslib/common/src/models/export/collectionWithId.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Collection as CollectionDomain } from "../domain/collection"; -import { CollectionView } from "../view/collectionView"; - -import { Collection } from "./collection"; - -export class CollectionWithId extends Collection { - id: string; - - // Use build method instead of ctor so that we can control order of JSON stringify for pretty print - build(o: CollectionView | CollectionDomain) { - this.id = o.id; - super.build(o); - } -} diff --git a/jslib/common/src/models/export/event.ts b/jslib/common/src/models/export/event.ts deleted file mode 100644 index 09975f2ff..000000000 --- a/jslib/common/src/models/export/event.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { EventType } from "../../enums/eventType"; -import { EventView } from "../view/eventView"; - -export class Event { - message: string; - appIcon: string; - appName: string; - userId: string; - userName: string; - userEmail: string; - date: string; - ip: string; - type: string; - - constructor(event: EventView) { - this.message = event.humanReadableMessage; - this.appIcon = event.appIcon; - this.appName = event.appName; - this.userId = event.userId; - this.userName = event.userName; - this.userEmail = event.userEmail; - this.date = event.date; - this.ip = event.ip; - this.type = EventType[event.type]; - } -} diff --git a/jslib/common/src/models/export/field.ts b/jslib/common/src/models/export/field.ts deleted file mode 100644 index c8ce7581e..000000000 --- a/jslib/common/src/models/export/field.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { FieldType } from "../../enums/fieldType"; -import { LinkedIdType } from "../../enums/linkedIdType"; -import { EncString } from "../domain/encString"; -import { Field as FieldDomain } from "../domain/field"; -import { FieldView } from "../view/fieldView"; - -export class Field { - static template(): Field { - const req = new Field(); - req.name = "Field name"; - req.value = "Some value"; - req.type = FieldType.Text; - return req; - } - - static toView(req: Field, view = new FieldView()) { - view.type = req.type; - view.value = req.value; - view.name = req.name; - view.linkedId = req.linkedId; - return view; - } - - static toDomain(req: Field, domain = new FieldDomain()) { - domain.type = req.type; - domain.value = req.value != null ? new EncString(req.value) : null; - domain.name = req.name != null ? new EncString(req.name) : null; - domain.linkedId = req.linkedId; - return domain; - } - - name: string; - value: string; - type: FieldType; - linkedId: LinkedIdType; - - constructor(o?: FieldView | FieldDomain) { - if (o == null) { - return; - } - - if (o instanceof FieldView) { - this.name = o.name; - this.value = o.value; - } else { - this.name = o.name?.encryptedString; - this.value = o.value?.encryptedString; - } - this.type = o.type; - this.linkedId = o.linkedId; - } -} diff --git a/jslib/common/src/models/export/folder.ts b/jslib/common/src/models/export/folder.ts deleted file mode 100644 index e770f326e..000000000 --- a/jslib/common/src/models/export/folder.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { EncString } from "../domain/encString"; -import { Folder as FolderDomain } from "../domain/folder"; -import { FolderView } from "../view/folderView"; - -export class Folder { - static template(): Folder { - const req = new Folder(); - req.name = "Folder name"; - return req; - } - - static toView(req: Folder, view = new FolderView()) { - view.name = req.name; - return view; - } - - static toDomain(req: Folder, domain = new FolderDomain()) { - domain.name = req.name != null ? new EncString(req.name) : null; - return domain; - } - - name: string; - - // Use build method instead of ctor so that we can control order of JSON stringify for pretty print - build(o: FolderView | FolderDomain) { - if (o instanceof FolderView) { - this.name = o.name; - } else { - this.name = o.name?.encryptedString; - } - } -} diff --git a/jslib/common/src/models/export/folderWithId.ts b/jslib/common/src/models/export/folderWithId.ts deleted file mode 100644 index a5507d514..000000000 --- a/jslib/common/src/models/export/folderWithId.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Folder as FolderDomain } from "../domain/folder"; -import { FolderView } from "../view/folderView"; - -import { Folder } from "./folder"; - -export class FolderWithId extends Folder { - id: string; - - // Use build method instead of ctor so that we can control order of JSON stringify for pretty print - build(o: FolderView | FolderDomain) { - this.id = o.id; - super.build(o); - } -} diff --git a/jslib/common/src/models/export/identity.ts b/jslib/common/src/models/export/identity.ts deleted file mode 100644 index 144732db2..000000000 --- a/jslib/common/src/models/export/identity.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { EncString } from "../domain/encString"; -import { Identity as IdentityDomain } from "../domain/identity"; -import { IdentityView } from "../view/identityView"; - -export class Identity { - static template(): Identity { - const req = new Identity(); - req.title = "Mr"; - req.firstName = "John"; - req.middleName = "William"; - req.lastName = "Doe"; - req.address1 = "123 Any St"; - req.address2 = "Apt #123"; - req.address3 = null; - req.city = "New York"; - req.state = "NY"; - req.postalCode = "10001"; - req.country = "US"; - req.company = "Acme Inc."; - req.email = "john@company.com"; - req.phone = "5555551234"; - req.ssn = "000-123-4567"; - req.username = "jdoe"; - req.passportNumber = "US-123456789"; - req.licenseNumber = "D123-12-123-12333"; - return req; - } - - static toView(req: Identity, view = new IdentityView()) { - view.title = req.title; - view.firstName = req.firstName; - view.middleName = req.middleName; - view.lastName = req.lastName; - view.address1 = req.address1; - view.address2 = req.address2; - view.address3 = req.address3; - view.city = req.city; - view.state = req.state; - view.postalCode = req.postalCode; - view.country = req.country; - view.company = req.company; - view.email = req.email; - view.phone = req.phone; - view.ssn = req.ssn; - view.username = req.username; - view.passportNumber = req.passportNumber; - view.licenseNumber = req.licenseNumber; - return view; - } - - static toDomain(req: Identity, domain = new IdentityDomain()) { - domain.title = req.title != null ? new EncString(req.title) : null; - domain.firstName = req.firstName != null ? new EncString(req.firstName) : null; - domain.middleName = req.middleName != null ? new EncString(req.middleName) : null; - domain.lastName = req.lastName != null ? new EncString(req.lastName) : null; - domain.address1 = req.address1 != null ? new EncString(req.address1) : null; - domain.address2 = req.address2 != null ? new EncString(req.address2) : null; - domain.address3 = req.address3 != null ? new EncString(req.address3) : null; - domain.city = req.city != null ? new EncString(req.city) : null; - domain.state = req.state != null ? new EncString(req.state) : null; - domain.postalCode = req.postalCode != null ? new EncString(req.postalCode) : null; - domain.country = req.country != null ? new EncString(req.country) : null; - domain.company = req.company != null ? new EncString(req.company) : null; - domain.email = req.email != null ? new EncString(req.email) : null; - domain.phone = req.phone != null ? new EncString(req.phone) : null; - domain.ssn = req.ssn != null ? new EncString(req.ssn) : null; - domain.username = req.username != null ? new EncString(req.username) : null; - domain.passportNumber = req.passportNumber != null ? new EncString(req.passportNumber) : null; - domain.licenseNumber = req.licenseNumber != null ? new EncString(req.licenseNumber) : null; - return domain; - } - - title: string; - firstName: string; - middleName: string; - lastName: string; - address1: string; - address2: string; - address3: string; - city: string; - state: string; - postalCode: string; - country: string; - company: string; - email: string; - phone: string; - ssn: string; - username: string; - passportNumber: string; - licenseNumber: string; - - constructor(o?: IdentityView | IdentityDomain) { - if (o == null) { - return; - } - - if (o instanceof IdentityView) { - this.title = o.title; - this.firstName = o.firstName; - this.middleName = o.middleName; - this.lastName = o.lastName; - this.address1 = o.address1; - this.address2 = o.address2; - this.address3 = o.address3; - this.city = o.city; - this.state = o.state; - this.postalCode = o.postalCode; - this.country = o.country; - this.company = o.company; - this.email = o.email; - this.phone = o.phone; - this.ssn = o.ssn; - this.username = o.username; - this.passportNumber = o.passportNumber; - this.licenseNumber = o.licenseNumber; - } else { - this.title = o.title?.encryptedString; - this.firstName = o.firstName?.encryptedString; - this.middleName = o.middleName?.encryptedString; - this.lastName = o.lastName?.encryptedString; - this.address1 = o.address1?.encryptedString; - this.address2 = o.address2?.encryptedString; - this.address3 = o.address3?.encryptedString; - this.city = o.city?.encryptedString; - this.state = o.state?.encryptedString; - this.postalCode = o.postalCode?.encryptedString; - this.country = o.country?.encryptedString; - this.company = o.company?.encryptedString; - this.email = o.email?.encryptedString; - this.phone = o.phone?.encryptedString; - this.ssn = o.ssn?.encryptedString; - this.username = o.username?.encryptedString; - this.passportNumber = o.passportNumber?.encryptedString; - this.licenseNumber = o.licenseNumber?.encryptedString; - } - } -} diff --git a/jslib/common/src/models/export/login.ts b/jslib/common/src/models/export/login.ts deleted file mode 100644 index 6a07ff748..000000000 --- a/jslib/common/src/models/export/login.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { EncString } from "../domain/encString"; -import { Login as LoginDomain } from "../domain/login"; -import { LoginView } from "../view/loginView"; - -import { LoginUri } from "./loginUri"; - -export class Login { - static template(): Login { - const req = new Login(); - req.uris = []; - req.username = "jdoe"; - req.password = "myp@ssword123"; - req.totp = "JBSWY3DPEHPK3PXP"; - return req; - } - - static toView(req: Login, view = new LoginView()) { - if (req.uris != null) { - view.uris = req.uris.map((u) => LoginUri.toView(u)); - } - view.username = req.username; - view.password = req.password; - view.totp = req.totp; - return view; - } - - static toDomain(req: Login, domain = new LoginDomain()) { - if (req.uris != null) { - domain.uris = req.uris.map((u) => LoginUri.toDomain(u)); - } - domain.username = req.username != null ? new EncString(req.username) : null; - domain.password = req.password != null ? new EncString(req.password) : null; - domain.totp = req.totp != null ? new EncString(req.totp) : null; - return domain; - } - - uris: LoginUri[]; - username: string; - password: string; - totp: string; - - constructor(o?: LoginView | LoginDomain) { - if (o == null) { - return; - } - - if (o.uris != null) { - if (o instanceof LoginView) { - this.uris = o.uris.map((u) => new LoginUri(u)); - } else { - this.uris = o.uris.map((u) => new LoginUri(u)); - } - } - - if (o instanceof LoginView) { - this.username = o.username; - this.password = o.password; - this.totp = o.totp; - } else { - this.username = o.username?.encryptedString; - this.password = o.password?.encryptedString; - this.totp = o.totp?.encryptedString; - } - } -} diff --git a/jslib/common/src/models/export/loginUri.ts b/jslib/common/src/models/export/loginUri.ts deleted file mode 100644 index 3e6d588bf..000000000 --- a/jslib/common/src/models/export/loginUri.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { UriMatchType } from "../../enums/uriMatchType"; -import { EncString } from "../domain/encString"; -import { LoginUri as LoginUriDomain } from "../domain/loginUri"; -import { LoginUriView } from "../view/loginUriView"; - -export class LoginUri { - static template(): LoginUri { - const req = new LoginUri(); - req.uri = "https://google.com"; - req.match = null; - return req; - } - - static toView(req: LoginUri, view = new LoginUriView()) { - view.uri = req.uri; - view.match = req.match; - return view; - } - - static toDomain(req: LoginUri, domain = new LoginUriDomain()) { - domain.uri = req.uri != null ? new EncString(req.uri) : null; - domain.match = req.match; - return domain; - } - - uri: string; - match: UriMatchType = null; - - constructor(o?: LoginUriView | LoginUriDomain) { - if (o == null) { - return; - } - - if (o instanceof LoginUriView) { - this.uri = o.uri; - } else { - this.uri = o.uri?.encryptedString; - } - this.match = o.match; - } -} diff --git a/jslib/common/src/models/export/secureNote.ts b/jslib/common/src/models/export/secureNote.ts deleted file mode 100644 index 851ba8e40..000000000 --- a/jslib/common/src/models/export/secureNote.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { SecureNoteType } from "../../enums/secureNoteType"; -import { SecureNote as SecureNoteDomain } from "../domain/secureNote"; -import { SecureNoteView } from "../view/secureNoteView"; - -export class SecureNote { - static template(): SecureNote { - const req = new SecureNote(); - req.type = SecureNoteType.Generic; - return req; - } - - static toView(req: SecureNote, view = new SecureNoteView()) { - view.type = req.type; - return view; - } - - static toDomain(req: SecureNote, view = new SecureNoteDomain()) { - view.type = req.type; - return view; - } - - type: SecureNoteType; - - constructor(o?: SecureNoteView | SecureNoteDomain) { - if (o == null) { - return; - } - - this.type = o.type; - } -} diff --git a/jslib/common/src/services/export.service.ts b/jslib/common/src/services/export.service.ts deleted file mode 100644 index 55f9206f6..000000000 --- a/jslib/common/src/services/export.service.ts +++ /dev/null @@ -1,444 +0,0 @@ -import * as papa from "papaparse"; - -import { ApiService } from "../abstractions/api.service"; -import { CipherService } from "../abstractions/cipher.service"; -import { CryptoService } from "../abstractions/crypto.service"; -import { CryptoFunctionService } from "../abstractions/cryptoFunction.service"; -import { - ExportFormat, - ExportService as ExportServiceAbstraction, -} from "../abstractions/export.service"; -import { FolderService } from "../abstractions/folder.service"; -import { CipherType } from "../enums/cipherType"; -import { DEFAULT_KDF_ITERATIONS, KdfType } from "../enums/kdfType"; -import { Utils } from "../misc/utils"; -import { CipherData } from "../models/data/cipherData"; -import { CollectionData } from "../models/data/collectionData"; -import { Cipher } from "../models/domain/cipher"; -import { Collection } from "../models/domain/collection"; -import { Folder } from "../models/domain/folder"; -import { CipherWithIds as CipherExport } from "../models/export/cipherWithIds"; -import { CollectionWithId as CollectionExport } from "../models/export/collectionWithId"; -import { Event } from "../models/export/event"; -import { FolderWithId as FolderExport } from "../models/export/folderWithId"; -import { CollectionDetailsResponse } from "../models/response/collectionResponse"; -import { CipherView } from "../models/view/cipherView"; -import { CollectionView } from "../models/view/collectionView"; -import { EventView } from "../models/view/eventView"; -import { FolderView } from "../models/view/folderView"; - -export class ExportService implements ExportServiceAbstraction { - constructor( - private folderService: FolderService, - private cipherService: CipherService, - private apiService: ApiService, - private cryptoService: CryptoService, - private cryptoFunctionService: CryptoFunctionService - ) {} - - async getExport(format: ExportFormat = "csv", organizationId?: string): Promise { - if (organizationId) { - return await this.getOrganizationExport(organizationId, format); - } - - if (format === "encrypted_json") { - return this.getEncryptedExport(); - } else { - return this.getDecryptedExport(format); - } - } - - async getPasswordProtectedExport(password: string, organizationId?: string): Promise { - const clearText = organizationId - ? await this.getOrganizationExport(organizationId, "json") - : await this.getExport("json"); - - const salt = Utils.fromBufferToB64(await this.cryptoFunctionService.randomBytes(16)); - const kdfIterations = DEFAULT_KDF_ITERATIONS; - const key = await this.cryptoService.makePinKey( - password, - salt, - KdfType.PBKDF2_SHA256, - kdfIterations - ); - - const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid(), key); - const encText = await this.cryptoService.encrypt(clearText, key); - - const jsonDoc: any = { - encrypted: true, - passwordProtected: true, - salt: salt, - kdfIterations: kdfIterations, - kdfType: KdfType.PBKDF2_SHA256, - encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString, - data: encText.encryptedString, - }; - - return JSON.stringify(jsonDoc, null, " "); - } - - async getOrganizationExport( - organizationId: string, - format: ExportFormat = "csv" - ): Promise { - if (format === "encrypted_json") { - return this.getOrganizationEncryptedExport(organizationId); - } else { - return this.getOrganizationDecryptedExport(organizationId, format); - } - } - - async getEventExport(events: EventView[]): Promise { - return papa.unparse(events.map((e) => new Event(e))); - } - - getFileName(prefix: string = null, extension = "csv"): string { - const now = new Date(); - const dateString = - now.getFullYear() + - "" + - this.padNumber(now.getMonth() + 1, 2) + - "" + - this.padNumber(now.getDate(), 2) + - this.padNumber(now.getHours(), 2) + - "" + - this.padNumber(now.getMinutes(), 2) + - this.padNumber(now.getSeconds(), 2); - - return "bitwarden" + (prefix ? "_" + prefix : "") + "_export_" + dateString + "." + extension; - } - - private async getDecryptedExport(format: "json" | "csv"): Promise { - let decFolders: FolderView[] = []; - let decCiphers: CipherView[] = []; - const promises = []; - - promises.push( - this.folderService.getAllDecrypted().then((folders) => { - decFolders = folders; - }) - ); - - promises.push( - this.cipherService.getAllDecrypted().then((ciphers) => { - decCiphers = ciphers.filter((f) => f.deletedDate == null); - }) - ); - - await Promise.all(promises); - - if (format === "csv") { - const foldersMap = new Map(); - decFolders.forEach((f) => { - if (f.id != null) { - foldersMap.set(f.id, f); - } - }); - - const exportCiphers: any[] = []; - decCiphers.forEach((c) => { - // only export logins and secure notes - if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) { - return; - } - if (c.organizationId != null) { - return; - } - - const cipher: any = {}; - cipher.folder = - c.folderId != null && foldersMap.has(c.folderId) ? foldersMap.get(c.folderId).name : null; - cipher.favorite = c.favorite ? 1 : null; - this.buildCommonCipher(cipher, c); - exportCiphers.push(cipher); - }); - - return papa.unparse(exportCiphers); - } else { - const jsonDoc: any = { - encrypted: false, - folders: [], - items: [], - }; - - decFolders.forEach((f) => { - if (f.id == null) { - return; - } - const folder = new FolderExport(); - folder.build(f); - jsonDoc.folders.push(folder); - }); - - decCiphers.forEach((c) => { - if (c.organizationId != null) { - return; - } - const cipher = new CipherExport(); - cipher.build(c); - cipher.collectionIds = null; - jsonDoc.items.push(cipher); - }); - - return JSON.stringify(jsonDoc, null, " "); - } - } - - private async getEncryptedExport(): Promise { - let folders: Folder[] = []; - let ciphers: Cipher[] = []; - const promises = []; - - promises.push( - this.folderService.getAll().then((f) => { - folders = f; - }) - ); - - promises.push( - this.cipherService.getAll().then((c) => { - ciphers = c.filter((f) => f.deletedDate == null); - }) - ); - - await Promise.all(promises); - - const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid()); - - const jsonDoc: any = { - encrypted: true, - encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString, - folders: [], - items: [], - }; - - folders.forEach((f) => { - if (f.id == null) { - return; - } - const folder = new FolderExport(); - folder.build(f); - jsonDoc.folders.push(folder); - }); - - ciphers.forEach((c) => { - if (c.organizationId != null) { - return; - } - const cipher = new CipherExport(); - cipher.build(c); - cipher.collectionIds = null; - jsonDoc.items.push(cipher); - }); - - return JSON.stringify(jsonDoc, null, " "); - } - - private async getOrganizationDecryptedExport( - organizationId: string, - format: "json" | "csv" - ): Promise { - const decCollections: CollectionView[] = []; - const decCiphers: CipherView[] = []; - const promises = []; - - promises.push( - this.apiService.getCollections(organizationId).then((collections) => { - const collectionPromises: any = []; - if (collections != null && collections.data != null && collections.data.length > 0) { - collections.data.forEach((c) => { - const collection = new Collection(new CollectionData(c as CollectionDetailsResponse)); - collectionPromises.push( - collection.decrypt().then((decCol) => { - decCollections.push(decCol); - }) - ); - }); - } - return Promise.all(collectionPromises); - }) - ); - - promises.push( - this.apiService.getCiphersOrganization(organizationId).then((ciphers) => { - const cipherPromises: any = []; - if (ciphers != null && ciphers.data != null && ciphers.data.length > 0) { - ciphers.data - .filter((c) => c.deletedDate === null) - .forEach((c) => { - const cipher = new Cipher(new CipherData(c)); - cipherPromises.push( - cipher.decrypt().then((decCipher) => { - decCiphers.push(decCipher); - }) - ); - }); - } - return Promise.all(cipherPromises); - }) - ); - - await Promise.all(promises); - - if (format === "csv") { - const collectionsMap = new Map(); - decCollections.forEach((c) => { - collectionsMap.set(c.id, c); - }); - - const exportCiphers: any[] = []; - decCiphers.forEach((c) => { - // only export logins and secure notes - if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) { - return; - } - - const cipher: any = {}; - cipher.collections = []; - if (c.collectionIds != null) { - cipher.collections = c.collectionIds - .filter((id) => collectionsMap.has(id)) - .map((id) => collectionsMap.get(id).name); - } - this.buildCommonCipher(cipher, c); - exportCiphers.push(cipher); - }); - - return papa.unparse(exportCiphers); - } else { - const jsonDoc: any = { - encrypted: false, - collections: [], - items: [], - }; - - decCollections.forEach((c) => { - const collection = new CollectionExport(); - collection.build(c); - jsonDoc.collections.push(collection); - }); - - decCiphers.forEach((c) => { - const cipher = new CipherExport(); - cipher.build(c); - jsonDoc.items.push(cipher); - }); - return JSON.stringify(jsonDoc, null, " "); - } - } - - private async getOrganizationEncryptedExport(organizationId: string): Promise { - const collections: Collection[] = []; - const ciphers: Cipher[] = []; - const promises = []; - - promises.push( - this.apiService.getCollections(organizationId).then((c) => { - const collectionPromises: any = []; - if (c != null && c.data != null && c.data.length > 0) { - c.data.forEach((r) => { - const collection = new Collection(new CollectionData(r as CollectionDetailsResponse)); - collections.push(collection); - }); - } - return Promise.all(collectionPromises); - }) - ); - - promises.push( - this.apiService.getCiphersOrganization(organizationId).then((c) => { - const cipherPromises: any = []; - if (c != null && c.data != null && c.data.length > 0) { - c.data - .filter((item) => item.deletedDate === null) - .forEach((item) => { - const cipher = new Cipher(new CipherData(item)); - ciphers.push(cipher); - }); - } - return Promise.all(cipherPromises); - }) - ); - - await Promise.all(promises); - - const orgKey = await this.cryptoService.getOrgKey(organizationId); - const encKeyValidation = await this.cryptoService.encrypt(Utils.newGuid(), orgKey); - - const jsonDoc: any = { - encrypted: true, - encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString, - collections: [], - items: [], - }; - - collections.forEach((c) => { - const collection = new CollectionExport(); - collection.build(c); - jsonDoc.collections.push(collection); - }); - - ciphers.forEach((c) => { - const cipher = new CipherExport(); - cipher.build(c); - jsonDoc.items.push(cipher); - }); - return JSON.stringify(jsonDoc, null, " "); - } - - private padNumber(num: number, width: number, padCharacter = "0"): string { - const numString = num.toString(); - return numString.length >= width - ? numString - : new Array(width - numString.length + 1).join(padCharacter) + numString; - } - - private buildCommonCipher(cipher: any, c: CipherView) { - cipher.type = null; - cipher.name = c.name; - cipher.notes = c.notes; - cipher.fields = null; - cipher.reprompt = c.reprompt; - // Login props - cipher.login_uri = null; - cipher.login_username = null; - cipher.login_password = null; - cipher.login_totp = null; - - if (c.fields) { - c.fields.forEach((f: any) => { - if (!cipher.fields) { - cipher.fields = ""; - } else { - cipher.fields += "\n"; - } - - cipher.fields += (f.name || "") + ": " + f.value; - }); - } - - switch (c.type) { - case CipherType.Login: - cipher.type = "login"; - cipher.login_username = c.login.username; - cipher.login_password = c.login.password; - cipher.login_totp = c.login.totp; - - if (c.login.uris) { - cipher.login_uri = []; - c.login.uris.forEach((u) => { - cipher.login_uri.push(u.uri); - }); - } - break; - case CipherType.SecureNote: - cipher.type = "note"; - break; - default: - return; - } - - return cipher; - } -} diff --git a/jslib/common/src/services/import.service.ts b/jslib/common/src/services/import.service.ts deleted file mode 100644 index 86226d7d6..000000000 --- a/jslib/common/src/services/import.service.ts +++ /dev/null @@ -1,382 +0,0 @@ -import { ApiService } from "../abstractions/api.service"; -import { CipherService } from "../abstractions/cipher.service"; -import { CollectionService } from "../abstractions/collection.service"; -import { CryptoService } from "../abstractions/crypto.service"; -import { FolderService } from "../abstractions/folder.service"; -import { I18nService } from "../abstractions/i18n.service"; -import { ImportService as ImportServiceAbstraction } from "../abstractions/import.service"; -import { PlatformUtilsService } from "../abstractions/platformUtils.service"; -import { CipherType } from "../enums/cipherType"; -import { - featuredImportOptions, - ImportOption, - ImportType, - regularImportOptions, -} from "../enums/importOptions"; -import { AscendoCsvImporter } from "../importers/ascendoCsvImporter"; -import { AvastCsvImporter } from "../importers/avastCsvImporter"; -import { AvastJsonImporter } from "../importers/avastJsonImporter"; -import { AviraCsvImporter } from "../importers/aviraCsvImporter"; -import { BitwardenCsvImporter } from "../importers/bitwardenCsvImporter"; -import { BitwardenJsonImporter } from "../importers/bitwardenJsonImporter"; -import { BitwardenPasswordProtectedImporter } from "../importers/bitwardenPasswordProtectedImporter"; -import { BlackBerryCsvImporter } from "../importers/blackBerryCsvImporter"; -import { BlurCsvImporter } from "../importers/blurCsvImporter"; -import { ButtercupCsvImporter } from "../importers/buttercupCsvImporter"; -import { ChromeCsvImporter } from "../importers/chromeCsvImporter"; -import { ClipperzHtmlImporter } from "../importers/clipperzHtmlImporter"; -import { CodebookCsvImporter } from "../importers/codebookCsvImporter"; -import { DashlaneCsvImporter } from "../importers/dashlaneImporters/dashlaneCsvImporter"; -import { DashlaneJsonImporter } from "../importers/dashlaneImporters/dashlaneJsonImporter"; -import { EncryptrCsvImporter } from "../importers/encryptrCsvImporter"; -import { EnpassCsvImporter } from "../importers/enpassCsvImporter"; -import { EnpassJsonImporter } from "../importers/enpassJsonImporter"; -import { FirefoxCsvImporter } from "../importers/firefoxCsvImporter"; -import { FSecureFskImporter } from "../importers/fsecureFskImporter"; -import { GnomeJsonImporter } from "../importers/gnomeJsonImporter"; -import { ImportError } from "../importers/importError"; -import { Importer } from "../importers/importer"; -import { KasperskyTxtImporter } from "../importers/kasperskyTxtImporter"; -import { KeePass2XmlImporter } from "../importers/keepass2XmlImporter"; -import { KeePassXCsvImporter } from "../importers/keepassxCsvImporter"; -import { KeeperCsvImporter } from "../importers/keeperImporters/keeperCsvImporter"; -import { LastPassCsvImporter } from "../importers/lastpassCsvImporter"; -import { LogMeOnceCsvImporter } from "../importers/logMeOnceCsvImporter"; -import { MeldiumCsvImporter } from "../importers/meldiumCsvImporter"; -import { MSecureCsvImporter } from "../importers/msecureCsvImporter"; -import { MykiCsvImporter } from "../importers/mykiCsvImporter"; -import { NordPassCsvImporter } from "../importers/nordpassCsvImporter"; -import { OnePassword1PifImporter } from "../importers/onepasswordImporters/onepassword1PifImporter"; -import { OnePassword1PuxImporter } from "../importers/onepasswordImporters/onepassword1PuxImporter"; -import { OnePasswordMacCsvImporter } from "../importers/onepasswordImporters/onepasswordMacCsvImporter"; -import { OnePasswordWinCsvImporter } from "../importers/onepasswordImporters/onepasswordWinCsvImporter"; -import { PadlockCsvImporter } from "../importers/padlockCsvImporter"; -import { PassKeepCsvImporter } from "../importers/passkeepCsvImporter"; -import { PassmanJsonImporter } from "../importers/passmanJsonImporter"; -import { PasspackCsvImporter } from "../importers/passpackCsvImporter"; -import { PasswordAgentCsvImporter } from "../importers/passwordAgentCsvImporter"; -import { PasswordBossJsonImporter } from "../importers/passwordBossJsonImporter"; -import { PasswordDragonXmlImporter } from "../importers/passwordDragonXmlImporter"; -import { PasswordSafeXmlImporter } from "../importers/passwordSafeXmlImporter"; -import { PasswordWalletTxtImporter } from "../importers/passwordWalletTxtImporter"; -import { RememBearCsvImporter } from "../importers/rememBearCsvImporter"; -import { RoboFormCsvImporter } from "../importers/roboformCsvImporter"; -import { SafariCsvImporter } from "../importers/safariCsvImporter"; -import { SafeInCloudXmlImporter } from "../importers/safeInCloudXmlImporter"; -import { SaferPassCsvImporter } from "../importers/saferpassCsvImport"; -import { SecureSafeCsvImporter } from "../importers/secureSafeCsvImporter"; -import { SplashIdCsvImporter } from "../importers/splashIdCsvImporter"; -import { StickyPasswordXmlImporter } from "../importers/stickyPasswordXmlImporter"; -import { TrueKeyCsvImporter } from "../importers/truekeyCsvImporter"; -import { UpmCsvImporter } from "../importers/upmCsvImporter"; -import { YotiCsvImporter } from "../importers/yotiCsvImporter"; -import { ZohoVaultCsvImporter } from "../importers/zohoVaultCsvImporter"; -import { Utils } from "../misc/utils"; -import { ImportResult } from "../models/domain/importResult"; -import { CipherRequest } from "../models/request/cipherRequest"; -import { CollectionRequest } from "../models/request/collectionRequest"; -import { FolderRequest } from "../models/request/folderRequest"; -import { ImportCiphersRequest } from "../models/request/importCiphersRequest"; -import { ImportOrganizationCiphersRequest } from "../models/request/importOrganizationCiphersRequest"; -import { KvpRequest } from "../models/request/kvpRequest"; -import { ErrorResponse } from "../models/response/errorResponse"; -import { CipherView } from "../models/view/cipherView"; - -export class ImportService implements ImportServiceAbstraction { - featuredImportOptions = featuredImportOptions as readonly ImportOption[]; - - regularImportOptions = regularImportOptions as readonly ImportOption[]; - - constructor( - private cipherService: CipherService, - private folderService: FolderService, - private apiService: ApiService, - private i18nService: I18nService, - private collectionService: CollectionService, - private platformUtilsService: PlatformUtilsService, - private cryptoService: CryptoService - ) {} - - getImportOptions(): ImportOption[] { - return this.featuredImportOptions.concat(this.regularImportOptions); - } - - async import( - importer: Importer, - fileContents: string, - organizationId: string = null - ): Promise { - const importResult = await importer.parse(fileContents); - if (importResult.success) { - if (importResult.folders.length === 0 && importResult.ciphers.length === 0) { - return new ImportError(this.i18nService.t("importNothingError")); - } else if (importResult.ciphers.length > 0) { - const halfway = Math.floor(importResult.ciphers.length / 2); - const last = importResult.ciphers.length - 1; - - if ( - this.badData(importResult.ciphers[0]) && - this.badData(importResult.ciphers[halfway]) && - this.badData(importResult.ciphers[last]) - ) { - return new ImportError(this.i18nService.t("importFormatError")); - } - } - try { - await this.postImport(importResult, organizationId); - } catch (error) { - const errorResponse = new ErrorResponse(error, 400); - return this.handleServerError(errorResponse, importResult); - } - return null; - } else { - if (!Utils.isNullOrWhitespace(importResult.errorMessage)) { - return new ImportError(importResult.errorMessage, importResult.missingPassword); - } else { - return new ImportError( - this.i18nService.t("importFormatError"), - importResult.missingPassword - ); - } - } - } - - getImporter( - format: ImportType | "bitwardenpasswordprotected", - organizationId: string = null, - password: string = null - ): Importer { - const importer = this.getImporterInstance(format, password); - if (importer == null) { - return null; - } - importer.organizationId = organizationId; - return importer; - } - - private getImporterInstance(format: ImportType | "bitwardenpasswordprotected", password: string) { - if (format == null) { - return null; - } - - switch (format) { - case "bitwardencsv": - return new BitwardenCsvImporter(); - case "bitwardenjson": - return new BitwardenJsonImporter(this.cryptoService, this.i18nService); - case "bitwardenpasswordprotected": - return new BitwardenPasswordProtectedImporter( - this.cryptoService, - this.i18nService, - password - ); - case "lastpasscsv": - case "passboltcsv": - return new LastPassCsvImporter(); - case "keepassxcsv": - return new KeePassXCsvImporter(); - case "aviracsv": - return new AviraCsvImporter(); - case "blurcsv": - return new BlurCsvImporter(); - case "safeincloudxml": - return new SafeInCloudXmlImporter(); - case "padlockcsv": - return new PadlockCsvImporter(); - case "keepass2xml": - return new KeePass2XmlImporter(); - case "chromecsv": - case "operacsv": - case "vivaldicsv": - return new ChromeCsvImporter(); - case "firefoxcsv": - return new FirefoxCsvImporter(); - case "upmcsv": - return new UpmCsvImporter(); - case "saferpasscsv": - return new SaferPassCsvImporter(); - case "safaricsv": - return new SafariCsvImporter(); - case "meldiumcsv": - return new MeldiumCsvImporter(); - case "1password1pif": - return new OnePassword1PifImporter(); - case "1password1pux": - return new OnePassword1PuxImporter(); - case "1passwordwincsv": - return new OnePasswordWinCsvImporter(); - case "1passwordmaccsv": - return new OnePasswordMacCsvImporter(); - case "keepercsv": - return new KeeperCsvImporter(); - // case "keeperjson": - // return new KeeperJsonImporter(); - case "passworddragonxml": - return new PasswordDragonXmlImporter(); - case "enpasscsv": - return new EnpassCsvImporter(); - case "enpassjson": - return new EnpassJsonImporter(); - case "pwsafexml": - return new PasswordSafeXmlImporter(); - case "dashlanecsv": - return new DashlaneCsvImporter(); - case "dashlanejson": - return new DashlaneJsonImporter(); - case "msecurecsv": - return new MSecureCsvImporter(); - case "stickypasswordxml": - return new StickyPasswordXmlImporter(); - case "truekeycsv": - return new TrueKeyCsvImporter(); - case "clipperzhtml": - return new ClipperzHtmlImporter(); - case "roboformcsv": - return new RoboFormCsvImporter(); - case "ascendocsv": - return new AscendoCsvImporter(); - case "passwordbossjson": - return new PasswordBossJsonImporter(); - case "zohovaultcsv": - return new ZohoVaultCsvImporter(); - case "splashidcsv": - return new SplashIdCsvImporter(); - case "passkeepcsv": - return new PassKeepCsvImporter(); - case "gnomejson": - return new GnomeJsonImporter(); - case "passwordagentcsv": - return new PasswordAgentCsvImporter(); - case "passpackcsv": - return new PasspackCsvImporter(); - case "passmanjson": - return new PassmanJsonImporter(); - case "avastcsv": - return new AvastCsvImporter(); - case "avastjson": - return new AvastJsonImporter(); - case "fsecurefsk": - return new FSecureFskImporter(); - case "kasperskytxt": - return new KasperskyTxtImporter(); - case "remembearcsv": - return new RememBearCsvImporter(); - case "passwordwallettxt": - return new PasswordWalletTxtImporter(); - case "mykicsv": - return new MykiCsvImporter(); - case "securesafecsv": - return new SecureSafeCsvImporter(); - case "logmeoncecsv": - return new LogMeOnceCsvImporter(); - case "blackberrycsv": - return new BlackBerryCsvImporter(); - case "buttercupcsv": - return new ButtercupCsvImporter(); - case "codebookcsv": - return new CodebookCsvImporter(); - case "encryptrcsv": - return new EncryptrCsvImporter(); - case "yoticsv": - return new YotiCsvImporter(); - case "nordpasscsv": - return new NordPassCsvImporter(); - default: - return null; - } - } - - private async postImport(importResult: ImportResult, organizationId: string = null) { - if (organizationId == null) { - const request = new ImportCiphersRequest(); - for (let i = 0; i < importResult.ciphers.length; i++) { - const c = await this.cipherService.encrypt(importResult.ciphers[i]); - request.ciphers.push(new CipherRequest(c)); - } - if (importResult.folders != null) { - for (let i = 0; i < importResult.folders.length; i++) { - const f = await this.folderService.encrypt(importResult.folders[i]); - request.folders.push(new FolderRequest(f)); - } - } - if (importResult.folderRelationships != null) { - importResult.folderRelationships.forEach((r) => - request.folderRelationships.push(new KvpRequest(r[0], r[1])) - ); - } - return await this.apiService.postImportCiphers(request); - } else { - const request = new ImportOrganizationCiphersRequest(); - for (let i = 0; i < importResult.ciphers.length; i++) { - importResult.ciphers[i].organizationId = organizationId; - const c = await this.cipherService.encrypt(importResult.ciphers[i]); - request.ciphers.push(new CipherRequest(c)); - } - if (importResult.collections != null) { - for (let i = 0; i < importResult.collections.length; i++) { - importResult.collections[i].organizationId = organizationId; - const c = await this.collectionService.encrypt(importResult.collections[i]); - request.collections.push(new CollectionRequest(c)); - } - } - if (importResult.collectionRelationships != null) { - importResult.collectionRelationships.forEach((r) => - request.collectionRelationships.push(new KvpRequest(r[0], r[1])) - ); - } - return await this.apiService.postImportOrganizationCiphers(organizationId, request); - } - } - - private badData(c: CipherView) { - return ( - (c.name == null || c.name === "--") && - c.type === CipherType.Login && - c.login != null && - Utils.isNullOrWhitespace(c.login.password) - ); - } - - private handleServerError(errorResponse: ErrorResponse, importResult: ImportResult): ImportError { - if (errorResponse.validationErrors == null) { - return new ImportError(errorResponse.message); - } - - let errorMessage = ""; - - Object.entries(errorResponse.validationErrors).forEach(([key, value], index) => { - let item; - let itemType; - const i = Number(key.match(/[0-9]+/)[0]); - - switch (key.match(/^\w+/)[0]) { - case "Ciphers": - item = importResult.ciphers[i]; - itemType = CipherType[item.type]; - break; - case "Folders": - item = importResult.folders[i]; - itemType = "Folder"; - break; - case "Collections": - item = importResult.collections[i]; - itemType = "Collection"; - break; - default: - return; - } - - if (index > 0) { - errorMessage += "\n\n"; - } - - if (itemType !== "Folder" && itemType !== "Collection") { - errorMessage += "[" + (i + 1) + "] "; - } - - errorMessage += "[" + itemType + '] "' + item.name + '": ' + value; - }); - - return new ImportError(errorMessage); - } -} diff --git a/package-lock.json b/package-lock.json index 1c4910393..b1a761f3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,6 @@ "ngx-toastr": "16.2.0", "node-fetch": "2.7.0", "open": "8.4.2", - "papaparse": "5.4.1", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", "tldjs": "2.3.1", @@ -64,7 +63,6 @@ "@types/node": "18.17.12", "@types/node-fetch": "^2.6.10", "@types/node-forge": "^1.3.11", - "@types/papaparse": "^5.3.14", "@types/proper-lockfile": "^4.1.4", "@types/tldjs": "^2.3.4", "@types/zxcvbn": "^4.4.4", @@ -97,7 +95,6 @@ "husky": "8.0.3", "jest": "29.6.4", "jest-preset-angular": "13.1.1", - "jsdom": "22.1.0", "lint-staged": "12.5.0", "mini-css-extract-plugin": "^2.7.7", "node-forge": "1.3.1", @@ -5378,15 +5375,6 @@ "@types/node": "*" } }, - "node_modules/@types/papaparse": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.14.tgz", - "integrity": "sha512-LxJ4iEFcpqc6METwp9f6BV6VVc43m6MfH0VqFosHvrUgfXiFe6ww7R3itkOQ+TCK6Y+Iv/+RnnvtRZnkc5Kc9g==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -8713,32 +8701,6 @@ "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", "dev": true }, - "node_modules/cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", - "dev": true, - "dependencies": { - "rrweb-cssom": "^0.6.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/data-urls": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", - "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -14182,69 +14144,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsdom": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", - "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "cssstyle": "^3.0.0", - "data-urls": "^4.0.0", - "decimal.js": "^10.4.3", - "domexception": "^4.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.4", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.1", - "ws": "^8.13.0", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -16400,11 +16299,6 @@ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, - "node_modules/papaparse": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", - "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==" - }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -18033,12 +17927,6 @@ "dev": true, "optional": true }, - "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true - }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -19723,27 +19611,6 @@ "node": ">= 4.0.0" } }, - "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "dev": true, - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/tr46/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -20881,19 +20748,6 @@ "node": ">=12" } }, - "node_modules/whatwg-url": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", - "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", - "dev": true, - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index aac1cb033..2ffbd6024 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,6 @@ "@types/node": "18.17.12", "@types/node-fetch": "2.6.10", "@types/node-forge": "1.3.11", - "@types/papaparse": "5.3.14", "@types/proper-lockfile": "4.1.4", "@types/tldjs": "2.3.4", "@types/zxcvbn": "4.4.4", @@ -119,7 +118,6 @@ "husky": "8.0.3", "jest": "29.6.4", "jest-preset-angular": "13.1.1", - "jsdom": "22.1.0", "lint-staged": "12.5.0", "mini-css-extract-plugin": "2.7.7", "node-forge": "1.3.1", @@ -173,7 +171,6 @@ "ngx-toastr": "16.2.0", "node-fetch": "2.7.0", "open": "8.4.2", - "papaparse": "5.4.1", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", "tldjs": "2.3.1",