From 30a5257671b2a10af0d68db575782ac2cb30c729 Mon Sep 17 00:00:00 2001 From: ServiusHack Date: Mon, 8 Oct 2018 21:41:32 +0200 Subject: [PATCH] Add importer for Passman (#13) * Add importer for Passman The importer reads JSON files generated by the Nextcloud app Passman. The first tag is used as the folder name. This works well if passwords have no or only one tag. If no username is set then the email address is used as the username. Files are not being imported. * Fix indentation * Remove unsettable revision date * Fix tslint findings * Add email to notes when there is also a username If a username is set, that will become the username. Otherwise the email will become the username. If a username and an email is set the email will be added to the notes. --- src/importers/passmanJsonImporter.ts | 63 ++++++++++++++++++++++++++++ src/services/import.service.ts | 4 ++ 2 files changed, 67 insertions(+) create mode 100644 src/importers/passmanJsonImporter.ts diff --git a/src/importers/passmanJsonImporter.ts b/src/importers/passmanJsonImporter.ts new file mode 100644 index 00000000000..8abe053b589 --- /dev/null +++ b/src/importers/passmanJsonImporter.ts @@ -0,0 +1,63 @@ +import { BaseImporter } from './baseImporter'; +import { Importer } from './importer'; + +import { ImportResult } from '../models/domain/importResult'; + +export class PassmanJsonImporter extends BaseImporter implements Importer { + parse(data: string): ImportResult { + const result = new ImportResult(); + const results = JSON.parse(data); + if (results == null || results.length === 0) { + result.success = false; + return result; + } + + results.forEach((credential: any) => { + if (credential.tags.length > 0) { + const folderName = credential.tags[0].text; + this.processFolder(result, folderName); + } + + const cipher = this.initLoginCipher(); + cipher.name = credential.label; + if (cipher.name.length > 30) { + cipher.name = cipher.name.substring(0, 30); + } + + cipher.login.username = this.getValueOrDefault(credential.username); + if (cipher.login.username === null) { + cipher.login.username = this.getValueOrDefault(credential.email); + } else if (credential.email !== '') { + cipher.notes += 'E-Mail: ' + credential.email; + } + + cipher.login.password = this.getValueOrDefault(credential.password); + cipher.login.uris = this.makeUriArray(credential.url); + cipher.notes = this.getValueOrDefault(credential.description); + + if (credential.otp) { + cipher.login.totp = credential.otp.secret; + } + + 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 result; + } +} diff --git a/src/services/import.service.ts b/src/services/import.service.ts index f6548989e56..d5dbed16f9b 100644 --- a/src/services/import.service.ts +++ b/src/services/import.service.ts @@ -41,6 +41,7 @@ import { OnePasswordWinCsvImporter } from '../importers/onepasswordWinCsvImporte import { PadlockCsvImporter } from '../importers/padlockCsvImporter'; import { PassKeepCsvImporter } from '../importers/passkeepCsvImporter'; import { PasspackCsvImporter } from '../importers/passpackCsvImporter'; +import { PassmanJsonImporter } from '../importers/passmanJsonImporter'; import { PasswordAgentCsvImporter } from '../importers/passwordAgentCsvImporter'; import { PasswordBossJsonImporter } from '../importers/passwordBossJsonImporter'; import { PasswordDragonXmlImporter } from '../importers/passwordDragonXmlImporter'; @@ -95,6 +96,7 @@ export class ImportService implements ImportServiceAbstraction { { id: 'blurcsv', name: 'Blur (csv)' }, { id: 'passwordagentcsv', name: 'Password Agent (csv)' }, { id: 'passpackcsv', name: 'Passpack (csv)' }, + { id: 'passmanjson', name: 'Passman (json)' }, ]; constructor(private cipherService: CipherService, private folderService: FolderService, @@ -211,6 +213,8 @@ export class ImportService implements ImportServiceAbstraction { return new PasswordAgentCsvImporter(); case 'passpackcsv': return new PasspackCsvImporter(); + case 'passmanjson': + return new PassmanJsonImporter(); default: return null; }