From db221dee05e404b89870e073491e3f56913b7942 Mon Sep 17 00:00:00 2001 From: ttalty <144813356+ttalty@users.noreply.github.com> Date: Thu, 2 Nov 2023 10:00:58 -0400 Subject: [PATCH] [PM 1672] SecureSafe Import Url Header Fix (#6623) * Get the url field name ignoring the case format * Adding test cases for the SecureSafe importer * Updating test cases and the way the url field is selected * updating the variable name from url to urlField --- .../spec/securesafe-csv-importer.spec.ts | 74 +++++++++++++++++++ .../securesafe-csv/securesafe-example.csv.ts | 5 ++ .../src/importers/securesafe-csv-importer.ts | 4 +- 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 libs/importer/spec/securesafe-csv-importer.spec.ts create mode 100644 libs/importer/spec/test-data/securesafe-csv/securesafe-example.csv.ts diff --git a/libs/importer/spec/securesafe-csv-importer.spec.ts b/libs/importer/spec/securesafe-csv-importer.spec.ts new file mode 100644 index 0000000000..85aa8d6bb9 --- /dev/null +++ b/libs/importer/spec/securesafe-csv-importer.spec.ts @@ -0,0 +1,74 @@ +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; +import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; + +import { SecureSafeCsvImporter } from "../src/importers"; + +import { data_upperUrl, data_lowerUrl } from "./test-data/securesafe-csv/securesafe-example.csv"; + +const CipherData = [ + { + title: "should parse upper case url", + csv: data_upperUrl, + expected: Object.assign(new CipherView(), { + id: null, + organizationId: null, + folderId: null, + name: "Gmail", + login: Object.assign(new LoginView(), { + username: "test@gmail.com", + password: "test", + uris: [ + Object.assign(new LoginUriView(), { + uri: "https://gmail.com", + }), + ], + }), + notes: null, + type: 1, + }), + }, + { + title: "should parse lower case url", + csv: data_lowerUrl, + expected: Object.assign(new CipherView(), { + id: null, + organizationId: null, + folderId: null, + name: "Gmail", + login: Object.assign(new LoginView(), { + username: "test@gmail.com", + password: "test", + uris: [ + Object.assign(new LoginUriView(), { + uri: "https://gmail.com", + }), + ], + }), + notes: null, + type: 1, + }), + }, +]; + +describe("SecureSafe CSV Importer", () => { + CipherData.forEach((data) => { + it(data.title, async () => { + const importer = new SecureSafeCsvImporter(); + const result = await importer.parse(data.csv); + expect(result != null).toBe(true); + expect(result.ciphers.length).toBeGreaterThan(0); + + const cipher = result.ciphers.shift(); + expect(cipher.name).toEqual(data.expected.name); + expect(cipher.login).toEqual( + expect.objectContaining({ + username: data.expected.login.username, + password: data.expected.login.password, + }) + ); + expect(cipher.login.uris.length).toEqual(1); + expect(cipher.login.uris[0].uri).toEqual(data.expected.login.uris[0].uri); + }); + }); +}); diff --git a/libs/importer/spec/test-data/securesafe-csv/securesafe-example.csv.ts b/libs/importer/spec/test-data/securesafe-csv/securesafe-example.csv.ts new file mode 100644 index 0000000000..75bf5127bf --- /dev/null +++ b/libs/importer/spec/test-data/securesafe-csv/securesafe-example.csv.ts @@ -0,0 +1,5 @@ +export const data_upperUrl = `"Title","Username","Password","URL","Comment" +"Gmail","test@gmail.com","test","https://gmail.com"`; + +export const data_lowerUrl = `"Title","Username","Password","url","Comment" +"Gmail","test@gmail.com","test","https://gmail.com"`; diff --git a/libs/importer/src/importers/securesafe-csv-importer.ts b/libs/importer/src/importers/securesafe-csv-importer.ts index cb5aab503d..1664932cf5 100644 --- a/libs/importer/src/importers/securesafe-csv-importer.ts +++ b/libs/importer/src/importers/securesafe-csv-importer.ts @@ -12,11 +12,13 @@ export class SecureSafeCsvImporter extends BaseImporter implements Importer { return Promise.resolve(result); } + // The url field can be in different case formats. + const urlField = Object.keys(results[0]).find((k) => /url/i.test(k)); 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.uris = this.makeUriArray(value[urlField]); cipher.login.password = this.getValueOrDefault(value.Password); cipher.login.username = this.getValueOrDefault(value.Username); this.cleanupCipher(cipher);