From 496d476d41fdee71791c27fdc4b92620b08c1611 Mon Sep 17 00:00:00 2001 From: Ben McFerren Date: Fri, 26 Jun 2026 13:51:33 -0400 Subject: [PATCH] PM-16780 SecureSafe export format --- .../importers/securesafe-csv-importer.spec.ts | 27 ++++++++++++++++++- .../src/importers/securesafe-csv-importer.ts | 4 +-- .../securesafe-csv/securesafe-example.csv.ts | 3 +++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/libs/importer/src/importers/securesafe-csv-importer.spec.ts b/libs/importer/src/importers/securesafe-csv-importer.spec.ts index e5ddbf753825..2ec1fa513059 100644 --- a/libs/importer/src/importers/securesafe-csv-importer.spec.ts +++ b/libs/importer/src/importers/securesafe-csv-importer.spec.ts @@ -3,7 +3,11 @@ import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; import { SecureSafeCsvImporter } from "./securesafe-csv-importer"; -import { data_upperUrl, data_lowerUrl } from "./spec-data/securesafe-csv/securesafe-example.csv"; +import { + data_upperUrl, + data_lowerUrl, + data_website, +} from "./spec-data/securesafe-csv/securesafe-example.csv"; const CipherData = [ { @@ -48,6 +52,27 @@ const CipherData = [ type: 1, }), }, + { + title: "should parse new format with Website column", + csv: data_website, + 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", () => { diff --git a/libs/importer/src/importers/securesafe-csv-importer.ts b/libs/importer/src/importers/securesafe-csv-importer.ts index 432327094f06..b16f42c7ac06 100644 --- a/libs/importer/src/importers/securesafe-csv-importer.ts +++ b/libs/importer/src/importers/securesafe-csv-importer.ts @@ -14,8 +14,8 @@ 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)); + // The url field can be in different case formats, and the new SecureSafe export uses "Website". + const urlField = Object.keys(results[0]).find((k) => /url|website/i.test(k)); results.forEach((value) => { const cipher = this.initLoginCipher(); cipher.name = this.getValueOrDefault(value.Title); diff --git a/libs/importer/src/importers/spec-data/securesafe-csv/securesafe-example.csv.ts b/libs/importer/src/importers/spec-data/securesafe-csv/securesafe-example.csv.ts index 75bf5127bf32..5fda56e81725 100644 --- a/libs/importer/src/importers/spec-data/securesafe-csv/securesafe-example.csv.ts +++ b/libs/importer/src/importers/spec-data/securesafe-csv/securesafe-example.csv.ts @@ -3,3 +3,6 @@ export const data_upperUrl = `"Title","Username","Password","URL","Comment" export const data_lowerUrl = `"Title","Username","Password","url","Comment" "Gmail","test@gmail.com","test","https://gmail.com"`; + +export const data_website = `"Title","Username","Password","Website","Comment" +"Gmail","test@gmail.com","test","https://gmail.com"`;