diff --git a/src/importers/passpackCsvImporter.ts b/src/importers/passpackCsvImporter.ts new file mode 100644 index 00000000000..9b26d45c2b2 --- /dev/null +++ b/src/importers/passpackCsvImporter.ts @@ -0,0 +1,93 @@ +import { BaseImporter } from './baseImporter'; +import { Importer } from './importer'; + +import { ImportResult } from '../models/domain/importResult'; + +import { CollectionView } from '../models/view/collectionView'; + +export class PasspackCsvImporter extends BaseImporter implements Importer { + parse(data: string): ImportResult { + const result = new ImportResult(); + const results = this.parseCsv(data, true); + if (results == null) { + result.success = false; + return 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 { } + 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 { } + 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 result; + } +} diff --git a/src/services/import.service.ts b/src/services/import.service.ts index 40f744231e3..f6548989e56 100644 --- a/src/services/import.service.ts +++ b/src/services/import.service.ts @@ -40,6 +40,7 @@ import { OnePassword1PifImporter } from '../importers/onepassword1PifImporter'; import { OnePasswordWinCsvImporter } from '../importers/onepasswordWinCsvImporter'; import { PadlockCsvImporter } from '../importers/padlockCsvImporter'; import { PassKeepCsvImporter } from '../importers/passkeepCsvImporter'; +import { PasspackCsvImporter } from '../importers/passpackCsvImporter'; import { PasswordAgentCsvImporter } from '../importers/passwordAgentCsvImporter'; import { PasswordBossJsonImporter } from '../importers/passwordBossJsonImporter'; import { PasswordDragonXmlImporter } from '../importers/passwordDragonXmlImporter'; @@ -93,6 +94,7 @@ export class ImportService implements ImportServiceAbstraction { { 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)' }, ]; constructor(private cipherService: CipherService, private folderService: FolderService, @@ -207,6 +209,8 @@ export class ImportService implements ImportServiceAbstraction { return new GnomeJsonImporter(); case 'passwordagentcsv': return new PasswordAgentCsvImporter(); + case 'passpackcsv': + return new PasspackCsvImporter(); default: return null; }