diff options
author | binsky <timo@binsky.org> | 2021-08-17 17:47:19 +0300 |
---|---|---|
committer | binsky <timo@binsky.org> | 2021-08-17 18:08:45 +0300 |
commit | 39a712ca428ada4244c24a569afb4bfba1f91e03 (patch) | |
tree | 795561a3e6a15b7615338292e42b8bd9cdb18a88 | |
parent | cb0ae9374f51572a0e4b560b61c258be97dea205 (diff) |
fix blocking vault export if a download or decryption failed
Signed-off-by: binsky <timo@binsky.org>
-rw-r--r-- | controller/translationcontroller.php | 1 | ||||
-rw-r--r-- | js/app/controllers/export.js | 20 | ||||
-rw-r--r-- | js/exporters/exporter-csv.js | 4 | ||||
-rw-r--r-- | js/exporters/exporter-json.js | 4 | ||||
-rw-r--r-- | js/exporters/exporter-main.js | 177 |
5 files changed, 114 insertions, 92 deletions
diff --git a/controller/translationcontroller.php b/controller/translationcontroller.php index f740e155..221bf6ec 100644 --- a/controller/translationcontroller.php +++ b/controller/translationcontroller.php @@ -65,6 +65,7 @@ class TranslationController extends ApiController { // js/app/controllers/export.js 'export.starting' => $this->trans->t('Starting export'), 'export.decrypt' => $this->trans->t('Decrypting credentials'), + 'export.decrypt.error' => $this->trans->t('Failed to decrypt {{credential}}'), 'done' => $this->trans->t('Done'), // js/app/controllers/import.js diff --git a/js/app/controllers/export.js b/js/app/controllers/export.js index b284048c..f152b506 100644 --- a/js/app/controllers/export.js +++ b/js/app/controllers/export.js @@ -72,15 +72,19 @@ if (vault.hasOwnProperty('credentials')) { if (vault.credentials.length > 0) { for (var i = 0; i < vault.credentials.length; i++) { - var _credential = angular.copy(vault.credentials[i]); - if (_credential.hidden === 0) { - var key = CredentialService.getSharedKeyFromCredential(_credential); - _credential = CredentialService.decryptCredential(_credential, key); - _credential.vault_key = key; - _credentials.push(_credential); + try { + var _credential = angular.copy(vault.credentials[i]); + if (_credential.hidden === 0) { + var key = CredentialService.getSharedKeyFromCredential(_credential); + _credential = CredentialService.decryptCredential(_credential, key); + _credential.vault_key = key; + _credentials.push(_credential); + } + } catch (e) { + _log($translate.instant('export.decrypt.error', {credential: (vault.credentials[i].label !== undefined) ? vault.credentials[i].label : i})); } } - $window.PassmanExporter[$scope.selectedExporter.id].export(_credentials, FileService, EncryptService).then(function () { + $window.PassmanExporter[$scope.selectedExporter.id].export(_credentials, FileService, EncryptService, $scope.log, $translate).then(function () { _log($translate.instant('done')); }); } @@ -92,4 +96,4 @@ }]); -}());
\ No newline at end of file +}()); diff --git a/js/exporters/exporter-csv.js b/js/exporters/exporter-csv.js index 25fbc67c..0d348406 100644 --- a/js/exporters/exporter-csv.js +++ b/js/exporters/exporter-csv.js @@ -30,10 +30,10 @@ PassmanExporter.csv = { } }; -PassmanExporter.csv.export = function (credentials, FileService, EncryptService) { +PassmanExporter.csv.export = function (credentials, FileService, EncryptService, _log, $translate) { /** global: C_Promise */ return new C_Promise(function () { - PassmanExporter.getCredentialsWithFiles(credentials, FileService, EncryptService).then((function(){ + PassmanExporter.getCredentialsWithFiles(credentials, FileService, EncryptService, _log, $translate).then((function(){ var headers = ['label', 'username', 'password', 'email', 'description', 'tags', 'url', 'custom_fields', 'files']; var file_data = '"' + headers.join('","') + '"\n'; for (var i = 0; i < credentials.length; i++) { diff --git a/js/exporters/exporter-json.js b/js/exporters/exporter-json.js index dc20b68b..17a29259 100644 --- a/js/exporters/exporter-json.js +++ b/js/exporters/exporter-json.js @@ -30,10 +30,10 @@ PassmanExporter.json = { } }; -PassmanExporter.json.export = function (credentials, FileService, EncryptService) { +PassmanExporter.json.export = function (credentials, FileService, EncryptService, _log, $translate) { /** global: C_Promise */ return new C_Promise(function () { - PassmanExporter.getCredentialsWithFiles(credentials, FileService, EncryptService).then((function(){ + PassmanExporter.getCredentialsWithFiles(credentials, FileService, EncryptService, _log, $translate).then((function(){ var _output = []; for (var i = 0; i < credentials.length; i++) { var _credential = angular.copy(credentials[i]); diff --git a/js/exporters/exporter-main.js b/js/exporters/exporter-main.js index 48cccc5f..296cce11 100644 --- a/js/exporters/exporter-main.js +++ b/js/exporters/exporter-main.js @@ -23,87 +23,104 @@ // Importers should always start with this if (!window['PassmanExporter']) { var PassmanExporter = { - getCredentialsWithFiles: function(credentials, FileService, EncryptService) { - var t = { - cred: credentials, - FS: FileService, - ES: EncryptService - }; - /** global: C_Promise */ - return new C_Promise(function() { - var _this = this.parent; - var credentials = _this.cred; - this.parent.total = 0; - this.parent.finished = 0; - this.parent.fileGUID_cred = []; - this.parent.files = []; - this.parent.step = (function(file) { - this.parent.finished ++; - this.call_progress({ - total: this.parent.total, - finished: this.parent.finished - }); - - var dta = this.parent.fileGUID_cred[file.guid]; - - file.filename = this.parent.ES.decryptString(file.filename, this.parent.cred[dta.cred_pos].vault_key); - file.file_data = this.parent.ES.decryptString(file.file_data, this.parent.cred[dta.cred_pos].vault_key); - - // Files and custom_fields have different field structure - if (dta.on === 'files') { - this.parent.cred[dta.cred_pos][dta.on][dta.at] = file; - } - else { - this.parent.cred[dta.cred_pos][dta.on][dta.at].value = file; - } - - // We have finished downloading everything, so let's hand over job to somewhere else! - if (this.parent.total === this.parent.finished) { - this.call_then(this.parent.cred); - } - }).bind(this); + getCredentialsWithFiles: function (credentials, FileService, EncryptService, _log, $translate) { + var t = { + cred: credentials, + FS: FileService, + ES: EncryptService + }; + /** global: C_Promise */ + return new C_Promise(function () { + var _this = this.parent; + var credentials = _this.cred; + this.parent.total = 0; + this.parent.finished = 0; + this.parent.fileGUID_cred = []; + this.parent.files = []; + this.parent.step = (function (file) { + this.parent.finished++; + this.call_progress({ + total: this.parent.total, + finished: this.parent.finished + }); - for (var i = 0; i < credentials.length; i++) { - - var item = credentials[i]; - - // Custom fields - for (c = 0; c < item.custom_fields.length; c++) { - var cf = item.custom_fields[c]; - if (cf.field_type === 'file') { - this.parent.total ++; - this.parent.fileGUID_cred[cf.value.guid] = { - cred_pos: i, - on: 'custom_fields', - at: c - }; + var dta = this.parent.fileGUID_cred[file.guid]; - this.parent.FS.getFile(cf.value).then((function(data){ - this.parent.step(data); - }).bind(this)); - } - } - - // Also get all files - for (var c = 0; c < item.files.length; c++) { - this.parent.total ++; - this.parent.fileGUID_cred[item.files[c].guid] = { - cred_pos: i, - on: 'files', - at: c - }; + file.filename = this.parent.ES.decryptString(file.filename, this.parent.cred[dta.cred_pos].vault_key); + file.file_data = this.parent.ES.decryptString(file.file_data, this.parent.cred[dta.cred_pos].vault_key); - this.parent.FS.getFile(item.files[c]).then((function(data){ - this.parent.step(data); - }).bind(this)); - } - } - - // We have finished downloading everything, so let's hand over job to somewhere else! - if (this.parent.total === 0) { - this.call_then(this.parent.cred); - } - }, t); - } + // Files and custom_fields have different field structure + if (dta.on === 'files') { + this.parent.cred[dta.cred_pos][dta.on][dta.at] = file; + } else { + this.parent.cred[dta.cred_pos][dta.on][dta.at].value = file; + } + + // We have finished downloading everything, so let's hand over job to somewhere else! + if (this.parent.total === this.parent.finished) { + this.call_then(this.parent.cred); + } + }).bind(this); + this.parent.stepFailed = (function (error) { + _log.push($translate.instant('export.decrypt.error', {credential: error.config.filename})); + this.parent.finished++; + this.call_progress({ + total: this.parent.total, + finished: this.parent.finished + }); + + // We have finished downloading everything, so let's hand over job to somewhere else! + if (this.parent.total === this.parent.finished) { + this.call_then(this.parent.cred); + } + }).bind(this); + + for (var i = 0; i < credentials.length; i++) { + + var item = credentials[i]; + + // Custom fields + for (c = 0; c < item.custom_fields.length; c++) { + var cf = item.custom_fields[c]; + if (cf.field_type === 'file') { + this.parent.total++; + this.parent.fileGUID_cred[cf.value.guid] = { + cred_pos: i, + on: 'custom_fields', + at: c + }; + + this.parent.FS.getFile(cf.value).then((function (data) { + this.parent.step(data); + }).bind(this), (function (error) { + this.parent.stepFailed(error); + }).bind(this)); + } + } + + // Also get all files + for (var c = 0; c < item.files.length; c++) { + this.parent.total++; + this.parent.fileGUID_cred[item.files[c].guid] = { + cred_pos: i, + on: 'files', + at: c + }; + + this.parent.FS.getFile(item.files[c]).then((function (data) { + this.parent.step(data); + }).bind(this), (function (error) { + this.parent.stepFailed(error); + }).bind(this)); + } + } + + // We have finished downloading everything, so let's hand over job to somewhere else! + console.warn("parent.total " + this.parent.total); + if (this.parent.total === 0) { + this.call_then(this.parent.cred); + } + }, t); + } }; -}
\ No newline at end of file +} |