From 852363cb773084b54b4cb345ca93968f34f4a6c6 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 11 Oct 2017 16:41:09 -0400 Subject: [PATCH] import/export/updatekey fixes for ciphers --- .../organizationSettingsExportController.js | 53 +++---- .../organizationSettingsImportController.js | 19 +-- src/app/services/cipherService.js | 132 +----------------- src/app/services/importService.js | 68 +++++---- .../settings/settingsUpdateKeyController.js | 20 +-- src/app/tools/toolsExportController.js | 49 ++++--- src/app/tools/toolsImportController.js | 21 +-- 7 files changed, 132 insertions(+), 230 deletions(-) diff --git a/src/app/organization/organizationSettingsExportController.js b/src/app/organization/organizationSettingsExportController.js index 9288e42492..e5ef62c288 100644 --- a/src/app/organization/organizationSettingsExportController.js +++ b/src/app/organization/organizationSettingsExportController.js @@ -2,11 +2,11 @@ .module('bit.organization') .controller('organizationSettingsExportController', function ($scope, apiService, $uibModalInstance, cipherService, - $q, toastr, $analytics, $state) { + $q, toastr, $analytics, $state, constants) { $analytics.eventTrack('organizationSettingsExportController', { category: 'Modal' }); $scope.export = function (model) { $scope.startedExport = true; - var decLogins = [], + var decCiphers = [], decCollections = []; var collectionsPromise = apiService.collections.listOrganization({ orgId: $state.params.orgId }, @@ -14,18 +14,18 @@ decCollections = cipherService.decryptCollections(collections.Data, $state.params.orgId, true); }).$promise; - var loginsPromise = apiService.ciphers.listOrganizationDetails({ organizationId: $state.params.orgId }, + var ciphersPromise = apiService.ciphers.listOrganizationDetails({ organizationId: $state.params.orgId }, function (ciphers) { for (var i = 0; i < ciphers.Data.length; i++) { if (ciphers.Data[i].Type === 1) { - var decLogin = cipherService.decryptLogin(ciphers.Data[i]); - decLogins.push(decLogin); + var decCipher = cipherService.decryptCipher(ciphers.Data[i]); + decCiphers.push(decCipher); } } }).$promise; - $q.all([collectionsPromise, loginsPromise]).then(function () { - if (!decLogins.length) { + $q.all([collectionsPromise, ciphersPromise]).then(function () { + if (!decCiphers.length) { toastr.error('Nothing to export.', 'Error!'); $scope.close(); return; @@ -37,22 +37,27 @@ } try { - var exportLogins = []; - for (i = 0; i < decLogins.length; i++) { + var exportCiphers = []; + for (i = 0; i < decCiphers.length; i++) { + // only export logins for now + if (decCiphers[i].type !== constants.cipherType.login) { + continue; + } + var login = { - name: decLogins[i].name, - uri: decLogins[i].uri, - username: decLogins[i].username, - password: decLogins[i].password, - notes: decLogins[i].notes, - totp: decLogins[i].totp, + name: decCiphers[i].name, + uri: decCiphers[i].login.uri, + username: decCiphers[i].login.username, + password: decCiphers[i].login.password, + notes: decCiphers[i].notes, + totp: decCiphers[i].login.totp, collections: [], fields: null }; var j; - if (decLogins[i].fields) { - for (j = 0; j < decLogins[i].fields.length; j++) { + if (decCiphers[i].fields) { + for (j = 0; j < decCiphers[i].fields.length; j++) { if (!login.fields) { login.fields = ''; } @@ -60,22 +65,22 @@ login.fields += '\n'; } - login.fields += ((decLogins[i].fields[j].name || '') + ': ' + decLogins[i].fields[j].value); + login.fields += ((decCiphers[i].fields[j].name || '') + ': ' + decCiphers[i].fields[j].value); } } - if (decLogins[i].collectionIds) { - for (j = 0; j < decLogins[i].collectionIds.length; j++) { - if (collectionsDict.hasOwnProperty(decLogins[i].collectionIds[j])) { - login.collections.push(collectionsDict[decLogins[i].collectionIds[j]].name); + if (decCiphers[i].collectionIds) { + for (j = 0; j < decCiphers[i].collectionIds.length; j++) { + if (collectionsDict.hasOwnProperty(decCiphers[i].collectionIds[j])) { + login.collections.push(collectionsDict[decCiphers[i].collectionIds[j]].name); } } } - exportLogins.push(login); + exportCiphers.push(login); } - var csvString = Papa.unparse(exportLogins); + var csvString = Papa.unparse(exportCiphers); var csvBlob = new Blob([csvString]); // IE hack. ref http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx diff --git a/src/app/organization/organizationSettingsImportController.js b/src/app/organization/organizationSettingsImportController.js index 880534ed86..461553f5ba 100644 --- a/src/app/organization/organizationSettingsImportController.js +++ b/src/app/organization/organizationSettingsImportController.js @@ -55,15 +55,15 @@ importService.importOrg(model.source, file || model.fileContents, importSuccess, importError); }; - function importSuccess(collections, logins, collectionRelationships) { - if (!collections.length && !logins.length) { + function importSuccess(collections, ciphers, collectionRelationships) { + if (!collections.length && !ciphers.length) { importError('Nothing was imported.'); return; } - else if (logins.length) { - var halfway = Math.floor(logins.length / 2); - var last = logins.length - 1; - if (loginIsBadData(logins[0]) && loginIsBadData(logins[halfway]) && loginIsBadData(logins[last])) { + else if (ciphers.length) { + var halfway = Math.floor(ciphers.length / 2); + var last = ciphers.length - 1; + if (cipherIsBadData(ciphers[0]) && cipherIsBadData(ciphers[halfway]) && cipherIsBadData(ciphers[last])) { importError('CSV data is not formatted correctly. Please check your import file and try again.'); return; } @@ -71,7 +71,7 @@ apiService.ciphers.importOrg({ orgId: $state.params.orgId }, { collections: cipherService.encryptCollections(collections, $state.params.orgId), - ciphers: cipherService.encryptLogins(logins, cryptoService.getOrgKey($state.params.orgId)), + ciphers: cipherService.encryptCiphers(ciphers, cryptoService.getOrgKey($state.params.orgId)), collectionRelationships: collectionRelationships }, function () { $uibModalInstance.dismiss('cancel'); @@ -82,8 +82,9 @@ }, importError); } - function loginIsBadData(login) { - return (login.name === null || login.name === '--') && (login.password === null || login.password === ''); + function cipherIsBadData(cipher) { + return (cipher.name === null || cipher.name === '--') && + (cipher.login && (cipher.login.password === null || cipher.login.password === '')); } function importError(error) { diff --git a/src/app/services/cipherService.js b/src/app/services/cipherService.js index 7c4a7394f4..6763caa830 100644 --- a/src/app/services/cipherService.js +++ b/src/app/services/cipherService.js @@ -4,66 +4,12 @@ angular .factory('cipherService', function (cryptoService, apiService, $q, $window, constants) { var _service = {}; - _service.decryptLogins = function (encryptedLogins) { - if (!encryptedLogins) throw "encryptedLogins is undefined or null"; - - var unencryptedLogins = []; - for (var i = 0; i < encryptedLogins.length; i++) { - unencryptedLogins.push(_service.decryptLogin(encryptedLogins[i])); - } - - return unencryptedLogins; - }; - - _service.decryptLogin = function (encryptedLogin) { - if (!encryptedLogin) throw "encryptedLogin is undefined or null"; - - var key = null; - if (encryptedLogin.OrganizationId) { - key = cryptoService.getOrgKey(encryptedLogin.OrganizationId); - } - - var login = { - id: encryptedLogin.Id, - organizationId: encryptedLogin.OrganizationId, - collectionIds: encryptedLogin.CollectionIds || [], - 'type': 1, - folderId: encryptedLogin.FolderId, - favorite: encryptedLogin.Favorite, - edit: encryptedLogin.Edit, - organizationUseTotp: encryptedLogin.OrganizationUseTotp, - attachments: null - }; - - var loginData = encryptedLogin.Data; - if (loginData) { - login.name = cryptoService.decrypt(loginData.Name, key); - login.uri = loginData.Uri && loginData.Uri !== '' ? cryptoService.decrypt(loginData.Uri, key) : null; - login.username = loginData.Username && loginData.Username !== '' ? cryptoService.decrypt(loginData.Username, key) : null; - login.password = loginData.Password && loginData.Password !== '' ? cryptoService.decrypt(loginData.Password, key) : null; - login.notes = loginData.Notes && loginData.Notes !== '' ? cryptoService.decrypt(loginData.Notes, key) : null; - login.totp = loginData.Totp && loginData.Totp !== '' ? cryptoService.decrypt(loginData.Totp, key) : null; - login.fields = _service.decryptFields(key, loginData.Fields); - } - - if (!encryptedLogin.Attachments) { - return login; - } - - login.attachments = []; - for (var i = 0; i < encryptedLogin.Attachments.length; i++) { - login.attachments.push(_service.decryptAttachment(key, encryptedLogin.Attachments[i])); - } - - return login; - }; - _service.decryptCiphers = function (encryptedCiphers) { if (!encryptedCiphers) throw "encryptedCiphers is undefined or null"; var unencryptedCiphers = []; for (var i = 0; i < encryptedCiphers.length; i++) { - unencryptedCiphers.push(_service.decryptLogin(encryptedCiphers[i])); + unencryptedCiphers.push(_service.decryptCipher(encryptedCiphers[i])); } return unencryptedCiphers; @@ -160,35 +106,6 @@ angular return cipher; }; - _service.decryptLoginPreview = function (encryptedCipher) { - if (!encryptedCipher) throw "encryptedCipher is undefined or null"; - - var key = null; - if (encryptedCipher.OrganizationId) { - key = cryptoService.getOrgKey(encryptedCipher.OrganizationId); - } - - var login = { - id: encryptedCipher.Id, - organizationId: encryptedCipher.OrganizationId, - collectionIds: encryptedCipher.CollectionIds || [], - folderId: encryptedCipher.FolderId, - favorite: encryptedCipher.Favorite, - edit: encryptedCipher.Edit, - organizationUseTotp: encryptedCipher.OrganizationUseTotp, - hasAttachments: !!encryptedCipher.Attachments && encryptedCipher.Attachments.length > 0 - }; - - var loginData = encryptedCipher.Data; - if (loginData) { - login.name = _service.decryptProperty(loginData.Name, key, false, true); - login.username = _service.decryptProperty(loginData.Username, key, true, true); - login.password = _service.decryptProperty(loginData.Password, key, true, true); - } - - return login; - }; - _service.decryptCipherPreview = function (encryptedCipher) { if (!encryptedCipher) throw "encryptedCipher is undefined or null"; @@ -442,50 +359,15 @@ angular return property || (showError ? '[error: cannot decrypt]' : null); }; - _service.encryptLogins = function (unencryptedLogins, key) { - if (!unencryptedLogins) throw "unencryptedLogins is undefined or null"; + _service.encryptCiphers = function (unencryptedCiphers, key) { + if (!unencryptedCiphers) throw "unencryptedCiphers is undefined or null"; - var encryptedLogins = []; - for (var i = 0; i < unencryptedLogins.length; i++) { - encryptedLogins.push(_service.encryptLogin(unencryptedLogins[i], key)); + var encryptedCiphers = []; + for (var i = 0; i < unencryptedCiphers.length; i++) { + encryptedCiphers.push(_service.encryptCipher(unencryptedCiphers[i], null, key)); } - return encryptedLogins; - }; - - _service.encryptLogin = function (unencryptedLogin, key, attachments) { - if (!unencryptedLogin) throw "unencryptedLogin is undefined or null"; - - if (unencryptedLogin.organizationId) { - key = key || cryptoService.getOrgKey(unencryptedLogin.organizationId); - } - - var login = { - id: unencryptedLogin.id, - 'type': 1, - organizationId: unencryptedLogin.organizationId || null, - folderId: unencryptedLogin.folderId === '' ? null : unencryptedLogin.folderId, - favorite: unencryptedLogin.favorite !== null ? unencryptedLogin.favorite : false, - name: cryptoService.encrypt(unencryptedLogin.name, key), - notes: !unencryptedLogin.notes || unencryptedLogin.notes === '' ? null : cryptoService.encrypt(unencryptedLogin.notes, key), - login: { - uri: !unencryptedLogin.uri || unencryptedLogin.uri === '' ? null : cryptoService.encrypt(unencryptedLogin.uri, key), - username: !unencryptedLogin.username || unencryptedLogin.username === '' ? null : cryptoService.encrypt(unencryptedLogin.username, key), - password: !unencryptedLogin.password || unencryptedLogin.password === '' ? null : cryptoService.encrypt(unencryptedLogin.password, key), - totp: !unencryptedLogin.totp || unencryptedLogin.totp === '' ? null : cryptoService.encrypt(unencryptedLogin.totp, key) - }, - fields: _service.encryptFields(unencryptedLogin.fields, key) - }; - - if (unencryptedLogin.attachments && attachments) { - login.attachments = {}; - for (var i = 0; i < unencryptedLogin.attachments.length; i++) { - login.attachments[unencryptedLogin.attachments[i].id] = - cryptoService.encrypt(unencryptedLogin.attachments[i].fileName, key); - } - } - - return login; + return encryptedCiphers; }; _service.encryptCipher = function (unencryptedCipher, type, key, attachments) { diff --git a/src/app/services/importService.js b/src/app/services/importService.js index 8c43322524..dd76b1394f 100644 --- a/src/app/services/importService.js +++ b/src/app/services/importService.js @@ -128,6 +128,8 @@ } }; + // helpers + var _passwordFieldNames = [ 'password', 'pass word', 'passphrase', 'pass phrase', 'pass', 'code', 'code word', 'codeword', @@ -234,6 +236,8 @@ }, errorCallback); } + // importers + function importBitwardenCsv(file, success, error) { Papa.parse(file, { header: true, @@ -242,13 +246,13 @@ parseCsvErrors(results); var folders = [], - logins = [], + ciphers = [], folderRelationships = [], i = 0; angular.forEach(results.data, function (value, key) { var folderIndex = folders.length, - loginIndex = logins.length, + cipherIndex = ciphers.length, hasFolder = value.folder && value.folder !== '', addFolder = hasFolder; @@ -262,14 +266,16 @@ } } - var login = { + var cipher = { favorite: value.favorite && value.favorite !== '' && value.favorite !== '0' ? true : false, - uri: value.uri && value.uri !== '' ? trimUri(value.uri) : null, - username: value.username && value.username !== '' ? value.username : null, - password: value.password && value.password !== '' ? value.password : null, notes: value.notes && value.notes !== '' ? value.notes : null, name: value.name && value.name !== '' ? value.name : '--', - totp: value.totp && value.totp !== '' ? value.totp : null + login: { + totp: value.totp && value.totp !== '' ? value.totp : null, + uri: value.uri && value.uri !== '' ? trimUri(value.uri) : null, + username: value.username && value.username !== '' ? value.username : null, + password: value.password && value.password !== '' ? value.password : null + } }; if (value.fields && value.fields !== '') { @@ -284,8 +290,8 @@ continue; } - if (!login.fields) { - login.fields = []; + if (!cipher.fields) { + cipher.fields = []; } var field = { @@ -298,11 +304,11 @@ field.value = fields[i].substr(delimPosition + 2); } - login.fields.push(field); + cipher.fields.push(field); } } - logins.push(login); + ciphers.push(cipher); if (addFolder) { folders.push({ @@ -312,14 +318,14 @@ if (hasFolder) { var relationship = { - key: loginIndex, + key: cipherIndex, value: folderIndex }; folderRelationships.push(relationship); } }); - success(folders, logins, folderRelationships); + success(folders, ciphers, folderRelationships); } }); } @@ -332,22 +338,22 @@ parseCsvErrors(results); var collections = [], - logins = [], + ciphers = [], collectionRelationships = [], i; angular.forEach(results.data, function (value, key) { - var loginIndex = logins.length; + var cipherIndex = ciphers.length; if (value.collections && value.collections !== '') { - var loginCollections = value.collections.split(','); + var cipherCollections = value.collections.split(','); - for (i = 0; i < loginCollections.length; i++) { + for (i = 0; i < cipherCollections.length; i++) { var addCollection = true; var collectionIndex = collections.length; for (var j = 0; j < collections.length; j++) { - if (collections[j].name === loginCollections[i]) { + if (collections[j].name === cipherCollections[i]) { addCollection = false; collectionIndex = j; break; @@ -356,25 +362,27 @@ if (addCollection) { collections.push({ - name: loginCollections[i] + name: cipherCollections[i] }); } collectionRelationships.push({ - key: loginIndex, + key: cipherIndex, value: collectionIndex }); } } - var login = { + var cipher = { favorite: false, - uri: value.uri && value.uri !== '' ? trimUri(value.uri) : null, - username: value.username && value.username !== '' ? value.username : null, - password: value.password && value.password !== '' ? value.password : null, notes: value.notes && value.notes !== '' ? value.notes : null, name: value.name && value.name !== '' ? value.name : '--', - totp: value.totp && value.totp !== '' ? value.totp : null, + login: { + totp: value.totp && value.totp !== '' ? value.totp : null, + uri: value.uri && value.uri !== '' ? trimUri(value.uri) : null, + username: value.username && value.username !== '' ? value.username : null, + password: value.password && value.password !== '' ? value.password : null + } }; if (value.fields && value.fields !== '') { @@ -389,8 +397,8 @@ continue; } - if (!login.fields) { - login.fields = []; + if (!cipher.fields) { + cipher.fields = []; } var field = { @@ -403,14 +411,14 @@ field.value = fields[i].substr(delimPosition + 2); } - login.fields.push(field); + cipher.fields.push(field); } } - logins.push(login); + ciphers.push(cipher); }); - success(collections, logins, collectionRelationships); + success(collections, ciphers, collectionRelationships); } }); } diff --git a/src/app/settings/settingsUpdateKeyController.js b/src/app/settings/settingsUpdateKeyController.js index e72d8001b3..ef89443f05 100644 --- a/src/app/settings/settingsUpdateKeyController.js +++ b/src/app/settings/settingsUpdateKeyController.js @@ -31,19 +31,19 @@ function updateKey(masterPasswordHash) { var madeEncKey = cryptoService.makeEncKey(null); - var reencryptedLogins = []; - var loginsPromise = apiService.ciphers.list({}, function (encryptedLogins) { - var filteredEncryptedLogins = []; - for (var i = 0; i < encryptedLogins.Data.length; i++) { - if (encryptedLogins.Data[i].OrganizationId) { + var reencryptedCiphers = []; + var ciphersPromise = apiService.ciphers.list({}, function (encryptedCiphers) { + var filteredEncryptedCiphers = []; + for (var i = 0; i < encryptedCiphers.Data.length; i++) { + if (encryptedCiphers.Data[i].OrganizationId) { continue; } - filteredEncryptedLogins.push(encryptedLogins.Data[i]); + filteredEncryptedCiphers.push(encryptedCiphers.Data[i]); } - var unencryptedLogins = cipherService.decryptLogins(filteredEncryptedLogins); - reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, madeEncKey.encKey); + var unencryptedCiphers = cipherService.decryptCiphers(filteredEncryptedCiphers); + reencryptedCiphers = cipherService.encryptCiphers(unencryptedCiphers, madeEncKey.encKey); }).$promise; var reencryptedFolders = []; @@ -58,10 +58,10 @@ reencryptedPrivateKey = cryptoService.encrypt(privateKey, madeEncKey.encKey, 'raw'); } - return $q.all([loginsPromise, foldersPromise]).then(function () { + return $q.all([ciphersPromise, foldersPromise]).then(function () { var request = { masterPasswordHash: masterPasswordHash, - ciphers: reencryptedLogins, + ciphers: reencryptedCiphers, folders: reencryptedFolders, privateKey: reencryptedPrivateKey, key: madeEncKey.encKeyEnc diff --git a/src/app/tools/toolsExportController.js b/src/app/tools/toolsExportController.js index 2177f35bbd..424227450c 100644 --- a/src/app/tools/toolsExportController.js +++ b/src/app/tools/toolsExportController.js @@ -2,23 +2,23 @@ .module('bit.tools') .controller('toolsExportController', function ($scope, apiService, $uibModalInstance, cipherService, $q, - toastr, $analytics) { + toastr, $analytics, constants) { $analytics.eventTrack('toolsExportController', { category: 'Modal' }); $scope.export = function (model) { $scope.startedExport = true; - var decLogins = [], + var decCiphers = [], decFolders = []; var folderPromise = apiService.folders.list({}, function (folders) { decFolders = cipherService.decryptFolders(folders.Data); }).$promise; - var loginsPromise = apiService.ciphers.list({}, function (logins) { - decLogins = cipherService.decryptLogins(logins.Data); + var ciphersPromise = apiService.ciphers.list({}, function (ciphers) { + decCiphers = cipherService.decryptCiphers(ciphers.Data); }).$promise; - $q.all([folderPromise, loginsPromise]).then(function () { - if (!decLogins.length) { + $q.all([folderPromise, ciphersPromise]).then(function () { + if (!decCiphers.length) { toastr.error('Nothing to export.', 'Error!'); $scope.close(); return; @@ -30,23 +30,28 @@ } try { - var exportLogins = []; - for (i = 0; i < decLogins.length; i++) { + var exportCiphers = []; + for (i = 0; i < decCiphers.length; i++) { + // only export logins for now + if (decCiphers[i].type !== constants.cipherType.login) { + continue; + } + var login = { - name: decLogins[i].name, - uri: decLogins[i].uri, - username: decLogins[i].username, - password: decLogins[i].password, - notes: decLogins[i].notes, - folder: decLogins[i].folderId && (decLogins[i].folderId in foldersDict) ? - foldersDict[decLogins[i].folderId].name : null, - favorite: decLogins[i].favorite ? 1 : null, - totp: decLogins[i].totp, + name: decCiphers[i].name, + uri: decCiphers[i].login.uri, + username: decCiphers[i].login.username, + password: decCiphers[i].login.password, + notes: decCiphers[i].notes, + folder: decCiphers[i].folderId && (decCiphers[i].folderId in foldersDict) ? + foldersDict[decCiphers[i].folderId].name : null, + favorite: decCiphers[i].favorite ? 1 : null, + totp: decCiphers[i].login.totp, fields: null }; - if (decLogins[i].fields) { - for (var j = 0; j < decLogins[i].fields.length; j++) { + if (decCiphers[i].fields) { + for (var j = 0; j < decCiphers[i].fields.length; j++) { if (!login.fields) { login.fields = ''; } @@ -54,14 +59,14 @@ login.fields += '\n'; } - login.fields += ((decLogins[i].fields[j].name || '') + ': ' + decLogins[i].fields[j].value); + login.fields += ((decCiphers[i].fields[j].name || '') + ': ' + decCiphers[i].fields[j].value); } } - exportLogins.push(login); + exportCiphers.push(login); } - var csvString = Papa.unparse(exportLogins); + var csvString = Papa.unparse(exportCiphers); var csvBlob = new Blob([csvString]); // IE hack. ref http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx diff --git a/src/app/tools/toolsImportController.js b/src/app/tools/toolsImportController.js index e6f548cbda..602a37719b 100644 --- a/src/app/tools/toolsImportController.js +++ b/src/app/tools/toolsImportController.js @@ -237,7 +237,7 @@ { id: 'gnomejson', name: 'GNOME Passwords and Keys/Seahorse (json)', - instructions: $sce.trustAsHtml('Make sure you have python-keyring and python-gnomekeyring installed. ' + + instructions: $sce.trustAsHtml('Make sure you have python-keyring and python-gnomekeyring installed. ' + 'Save the GNOME Keyring Import/Export ' + 'python script by Luke Plant to your desktop as pw_helper.py. Open terminal and run ' + 'chmod +rx Desktop/pw_helper.py and then ' + @@ -272,15 +272,15 @@ importService.import(model.source, file || model.fileContents, importSuccess, importError); }; - function importSuccess(folders, logins, folderRelationships) { - if (!folders.length && !logins.length) { + function importSuccess(folders, ciphers, folderRelationships) { + if (!folders.length && !ciphers.length) { importError('Nothing was imported.'); return; } - else if (logins.length) { - var halfway = Math.floor(logins.length / 2); - var last = logins.length - 1; - if (loginIsBadData(logins[0]) && loginIsBadData(logins[halfway]) && loginIsBadData(logins[last])) { + else if (ciphers.length) { + var halfway = Math.floor(ciphers.length / 2); + var last = ciphers.length - 1; + if (cipherIsBadData(ciphers[0]) && cipherIsBadData(ciphers[halfway]) && cipherIsBadData(ciphers[last])) { importError('CSV data is not formatted correctly. Please check your import file and try again.'); return; } @@ -288,7 +288,7 @@ apiService.ciphers.import({ folders: cipherService.encryptFolders(folders), - ciphers: cipherService.encryptLogins(logins), + ciphers: cipherService.encryptCiphers(ciphers), folderRelationships: folderRelationships }, function () { $uibModalInstance.dismiss('cancel'); @@ -299,8 +299,9 @@ }, importError); } - function loginIsBadData(login) { - return (login.name === null || login.name === '--') && (login.password === null || login.password === ''); + function cipherIsBadData(cipher) { + return (cipher.name === null || cipher.name === '--') && + (cipher.login && (cipher.login.password === null || cipher.login.password === '')); } function importError(error) {