[PS-2263] Keeper CSV import: import TOTP to correct field (#4478)
* Keeper CSV import: import TOTP to correct field * Fix small issue with notes import Notes field can be null, the ` + "\n"` coerces those to `"null"`. * Adds unit tests
This commit is contained in:
parent
f82a9f33bd
commit
a6308042b6
|
@ -0,0 +1,77 @@
|
|||
import { KeeperCsvImporter as Importer } from "@bitwarden/common/importers/keeper/keeper-csv-importer";
|
||||
|
||||
import { testData as TestData } from "./test-data/keeper-csv/testdata.csv";
|
||||
|
||||
describe("Keeper CSV Importer", () => {
|
||||
let importer: Importer;
|
||||
beforeEach(() => {
|
||||
importer = new Importer();
|
||||
});
|
||||
|
||||
it("should parse login data", async () => {
|
||||
const result = await importer.parse(TestData);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
const cipher = result.ciphers.shift();
|
||||
expect(cipher.name).toEqual("Bar");
|
||||
expect(cipher.login.username).toEqual("john.doe@example.com");
|
||||
expect(cipher.login.password).toEqual("1234567890abcdef");
|
||||
expect(cipher.login.uris.length).toEqual(1);
|
||||
const uriView = cipher.login.uris.shift();
|
||||
expect(uriView.uri).toEqual("https://example.com/");
|
||||
expect(cipher.notes).toEqual("These are some notes.");
|
||||
|
||||
const cipher2 = result.ciphers.shift();
|
||||
expect(cipher2.name).toEqual("Bar 1");
|
||||
expect(cipher2.login.username).toEqual("john.doe1@example.com");
|
||||
expect(cipher2.login.password).toEqual("234567890abcdef1");
|
||||
expect(cipher2.login.uris.length).toEqual(1);
|
||||
const uriView2 = cipher2.login.uris.shift();
|
||||
expect(uriView2.uri).toEqual("https://an.example.com/");
|
||||
expect(cipher2.notes).toBeNull();
|
||||
|
||||
const cipher3 = result.ciphers.shift();
|
||||
expect(cipher3.name).toEqual("Bar 2");
|
||||
expect(cipher3.login.username).toEqual("john.doe2@example.com");
|
||||
expect(cipher3.login.password).toEqual("34567890abcdef12");
|
||||
expect(cipher3.notes).toBeNull();
|
||||
expect(cipher3.login.uris.length).toEqual(1);
|
||||
const uriView3 = cipher3.login.uris.shift();
|
||||
expect(uriView3.uri).toEqual("https://another.example.com/");
|
||||
});
|
||||
|
||||
it("should import TOTP when present", async () => {
|
||||
const result = await importer.parse(TestData);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
const cipher = result.ciphers.shift();
|
||||
expect(cipher.login.totp).toBeNull();
|
||||
|
||||
const cipher2 = result.ciphers.shift();
|
||||
expect(cipher2.login.totp).toBeNull();
|
||||
|
||||
const cipher3 = result.ciphers.shift();
|
||||
expect(cipher3.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(TestData);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
const cipher = result.ciphers.shift();
|
||||
expect(cipher.fields).toBeNull();
|
||||
|
||||
const cipher2 = result.ciphers.shift();
|
||||
expect(cipher2.fields.length).toBe(2);
|
||||
expect(cipher2.fields[0].name).toEqual("Account ID");
|
||||
expect(cipher2.fields[0].value).toEqual("12345");
|
||||
expect(cipher2.fields[1].name).toEqual("Org ID");
|
||||
expect(cipher2.fields[1].value).toEqual("54321");
|
||||
|
||||
const cipher3 = result.ciphers.shift();
|
||||
expect(cipher3.fields[0].name).toEqual("Account ID");
|
||||
expect(cipher3.fields[0].value).toEqual("23456");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
export const testData = `"Foo","Bar","john.doe@example.com","1234567890abcdef","https://example.com/","These are some notes.",""
|
||||
"Foo","Bar 1","john.doe1@example.com","234567890abcdef1","https://an.example.com/","","","Account ID","12345","Org ID","54321"
|
||||
"Foo\\Baz","Bar 2","john.doe2@example.com","34567890abcdef12","https://another.example.com/","","","Account ID","23456","TFC:Keeper","otpauth://totp/Amazon:me@company.com?secret=JBSWY3DPEHPK3PXP&issuer=Amazon&algorithm=SHA1&digits=6&period=30"
|
||||
`;
|
|
@ -18,7 +18,12 @@ export class KeeperCsvImporter extends BaseImporter implements Importer {
|
|||
|
||||
this.processFolder(result, value[0]);
|
||||
const cipher = this.initLoginCipher();
|
||||
cipher.notes = this.getValueOrDefault(value[5]) + "\n";
|
||||
|
||||
const notes = this.getValueOrDefault(value[5]);
|
||||
if (notes) {
|
||||
cipher.notes = `${notes}\n`;
|
||||
}
|
||||
|
||||
cipher.name = this.getValueOrDefault(value[1], "--");
|
||||
cipher.login.username = this.getValueOrDefault(value[2]);
|
||||
cipher.login.password = this.getValueOrDefault(value[3]);
|
||||
|
@ -27,9 +32,13 @@ export class KeeperCsvImporter extends BaseImporter implements Importer {
|
|||
if (value.length > 7) {
|
||||
// we have some custom fields.
|
||||
for (let i = 7; i < value.length; i = i + 2) {
|
||||
if (value[i] == "TFC:Keeper") {
|
||||
cipher.login.totp = value[i + 1];
|
||||
} else {
|
||||
this.processKvp(cipher, value[i], value[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.cleanupCipher(cipher);
|
||||
result.ciphers.push(cipher);
|
||||
|
|
Loading…
Reference in New Issue