diff --git a/src/importers/ascendoCsvImporter.ts b/src/importers/ascendoCsvImporter.ts index c007d9f931..52b9f0808b 100644 --- a/src/importers/ascendoCsvImporter.ts +++ b/src/importers/ascendoCsvImporter.ts @@ -3,11 +3,6 @@ import { Importer } from './importer'; import { ImportResult } from '../models/domain/importResult'; -import { SecureNoteView } from '../models/view/secureNoteView'; - -import { CipherType } from '../enums/cipherType'; -import { SecureNoteType } from '../enums/secureNoteType'; - export class AscendoCsvImporter extends BaseImporter implements Importer { parse(data: string): ImportResult { const result = new ImportResult(); @@ -49,13 +44,7 @@ export class AscendoCsvImporter extends BaseImporter implements Importer { } } - if (this.isNullOrWhitespace(cipher.login.username) && this.isNullOrWhitespace(cipher.login.password) && - (cipher.login.uris == null || cipher.login.uris.length === 0)) { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - } - + this.convertToNoteIfNeeded(cipher); this.cleanupCipher(cipher); result.ciphers.push(cipher); }); diff --git a/src/importers/baseImporter.ts b/src/importers/baseImporter.ts index c00564c315..291d558c5e 100644 --- a/src/importers/baseImporter.ts +++ b/src/importers/baseImporter.ts @@ -7,12 +7,15 @@ import { CollectionView } from '../models/view/collectionView'; import { LoginUriView } from '../models/view/loginUriView'; import { Utils } from '../misc/utils'; + import { FieldView } from '../models/view/fieldView'; import { FolderView } from '../models/view/folderView'; import { LoginView } from '../models/view/loginView'; +import { SecureNoteView } from '../models/view/secureNoteView'; import { CipherType } from '../enums/cipherType'; import { FieldType } from '../enums/fieldType'; +import { SecureNoteType } from '../enums/secureNoteType'; export abstract class BaseImporter { organization = false; @@ -313,4 +316,14 @@ export abstract class BaseImporter { result.folderRelationships.push([result.ciphers.length, folderIndex]); } } + + protected convertToNoteIfNeeded(cipher: CipherView) { + if (cipher.type === CipherType.Login && this.isNullOrWhitespace(cipher.login.username) && + this.isNullOrWhitespace(cipher.login.password) && + (cipher.login.uris == null || cipher.login.uris.length === 0)) { + cipher.type = CipherType.SecureNote; + cipher.secureNote = new SecureNoteView(); + cipher.secureNote.type = SecureNoteType.Generic; + } + } } diff --git a/src/importers/clipperzHtmlImporter.ts b/src/importers/clipperzHtmlImporter.ts index 5e8d78d50b..0443114811 100644 --- a/src/importers/clipperzHtmlImporter.ts +++ b/src/importers/clipperzHtmlImporter.ts @@ -2,10 +2,6 @@ import { BaseImporter } from './baseImporter'; import { Importer } from './importer'; import { ImportResult } from '../models/domain/importResult'; -import { SecureNoteView } from '../models/view/secureNoteView'; - -import { CipherType } from '../enums/cipherType'; -import { SecureNoteType } from '../enums/secureNoteType'; export class ClipperzHtmlImporter extends BaseImporter implements Importer { parse(data: string): ImportResult { @@ -72,13 +68,7 @@ export class ClipperzHtmlImporter extends BaseImporter implements Importer { } } - if (this.isNullOrWhitespace(cipher.login.username) && this.isNullOrWhitespace(cipher.login.password) && - (cipher.login.uris == null || cipher.login.uris.length === 0)) { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - } - + this.convertToNoteIfNeeded(cipher); this.cleanupCipher(cipher); result.ciphers.push(cipher); }); diff --git a/src/importers/onepasswordWinCsvImporter.ts b/src/importers/onepasswordWinCsvImporter.ts index eaed7dd83a..5b1a433704 100644 --- a/src/importers/onepasswordWinCsvImporter.ts +++ b/src/importers/onepasswordWinCsvImporter.ts @@ -3,10 +3,7 @@ import { Importer } from './importer'; import { ImportResult } from '../models/domain/importResult'; -import { SecureNoteView } from '../models/view/secureNoteView'; - import { CipherType } from '../enums/cipherType'; -import { SecureNoteType } from '../enums/secureNoteType'; import { CardView } from '../models/view'; const IgnoredProperties = ['ainfo', 'autosubmit', 'notesPlain', 'ps', 'scope', 'tags', 'title', 'uuid']; @@ -89,14 +86,8 @@ export class OnePasswordWinCsvImporter extends BaseImporter implements Importer this.isNullOrWhitespace(cipher.login.username) && altUsername.indexOf('://') === -1) { cipher.login.username = altUsername; } - if (cipher.type === CipherType.Login && this.isNullOrWhitespace(cipher.login.username) && - this.isNullOrWhitespace(cipher.login.password) && - (cipher.login.uris == null || cipher.login.uris.length === 0)) { - cipher.type = CipherType.SecureNote; - cipher.secureNote = new SecureNoteView(); - cipher.secureNote.type = SecureNoteType.Generic; - } + this.convertToNoteIfNeeded(cipher); this.cleanupCipher(cipher); result.ciphers.push(cipher); }); diff --git a/src/importers/passwordBossJsonImporter.ts b/src/importers/passwordBossJsonImporter.ts new file mode 100644 index 0000000000..843fcdfb1b --- /dev/null +++ b/src/importers/passwordBossJsonImporter.ts @@ -0,0 +1,93 @@ +import { BaseImporter } from './baseImporter'; +import { Importer } from './importer'; + +import { ImportResult } from '../models/domain/importResult'; + +import { CardView } from '../models/view/cardView'; + +import { CipherType } from '../enums/cipherType'; + +export class PasswordBossJsonImporter extends BaseImporter implements Importer { + parse(data: string): ImportResult { + const result = new ImportResult(); + const results = JSON.parse(data); + if (results == null) { + result.success = false; + return result; + } + + results.forEach((value) => { + const cipher = this.initLoginCipher(); + cipher.name = this.getValueOrDefault(value.name, '--'); + cipher.login.uris = this.makeUriArray(value.login_url); + + if (value.identifiers == null) { + return; + } + + if (!this.isNullOrWhitespace(value.identifiers.notes)) { + cipher.notes = value.identifiers.notes.split('\\r\\n').join('\n').split('\\n').join('\n'); + } + + if (value.type === 'CreditCard') { + cipher.card = new CardView(); + cipher.type = CipherType.Card; + } + + for (const property in value.identifiers) { + if (!value.identifiers.hasOwnProperty(property)) { + continue; + } + const valObj = value.identifiers[property]; + const val = valObj != null ? valObj.toString() : null; + if (this.isNullOrWhitespace(val) || property === 'notes' || property === 'ignoreItemInSecurityScore') { + continue; + } + + if (cipher.type === CipherType.Card) { + if (property === 'cardNumber') { + cipher.card.number = val; + cipher.card.brand = this.getCardBrand(val); + continue; + } else if (property === 'nameOnCard') { + cipher.card.cardholderName = val; + continue; + } else if (property === 'security_code') { + cipher.card.code = val; + continue; + } else if (property === 'expires') { + try { + const expDate = new Date(val); + cipher.card.expYear = expDate.getFullYear().toString(); + cipher.card.expMonth = (expDate.getMonth() + 1).toString(); + } catch { } + continue; + } else if (property === 'cardType') { + continue; + } + } else { + if (property === 'username') { + cipher.login.username = val; + continue; + } else if (property === 'password') { + cipher.login.password = val; + continue; + } else if ((cipher.login.uris == null || cipher.login.uris.length === 0) && + this.uriFieldNames.indexOf(property) > -1) { + cipher.login.uris = this.makeUriArray(val); + continue; + } + } + + this.processKvp(cipher, property, val); + } + + this.convertToNoteIfNeeded(cipher); + this.cleanupCipher(cipher); + result.ciphers.push(cipher); + }); + + result.success = true; + return result; + } +}