From 176b9a8ed045dbc1ec75927a0ac38db640ee91f5 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 16 Oct 2017 10:09:17 -0400 Subject: [PATCH] add/edit/view fixes for ciphers --- .../app/vault/vaultAddCipherController.js | 2 +- .../app/vault/vaultEditCipherController.js | 11 +- .../app/vault/vaultViewCipherController.js | 36 ++-- src/popup/app/vault/views/vaultAddCipher.html | 2 +- .../app/vault/views/vaultEditCipher.html | 182 ++++++++++++++++-- .../app/vault/views/vaultViewCipher.html | 131 ++++++++----- src/services/loginService.js | 126 ++++++------ 7 files changed, 347 insertions(+), 143 deletions(-) diff --git a/src/popup/app/vault/vaultAddCipherController.js b/src/popup/app/vault/vaultAddCipherController.js index 58377b90..67ee1f95 100644 --- a/src/popup/app/vault/vaultAddCipherController.js +++ b/src/popup/app/vault/vaultAddCipherController.js @@ -46,7 +46,7 @@ $scope.savePromise = null; $scope.save = function () { - if (!cipher.name || cipher.name === '') { + if (!$scope.cipher.name || $scope.cipher.name === '') { toastr.error(i18nService.nameRequired, i18nService.errorsOccurred); return; } diff --git a/src/popup/app/vault/vaultEditCipherController.js b/src/popup/app/vault/vaultEditCipherController.js index 1d6607fa..c4929ccc 100644 --- a/src/popup/app/vault/vaultEditCipherController.js +++ b/src/popup/app/vault/vaultEditCipherController.js @@ -7,6 +7,7 @@ angular $scope.constants = constantsService; $scope.showAttachments = !utilsService.isEdge(); $scope.addFieldType = constantsService.fieldType.text.toString(); + $scope.selectedType = constantsService.cipherType.login.toString(); var cipherId = $stateParams.cipherId; var fromView = $stateParams.fromView; var from = $stateParams.from; @@ -34,14 +35,18 @@ angular utilsService.initListSectionItemListeners($(document), angular); + $scope.typeChanged = function () { + $scope.cipher.type = parseInt($scope.selectedType); + }; + $scope.savePromise = null; - $scope.save = function (model) { - if (!model.name) { + $scope.save = function () { + if (!$scope.cipher.name || $scope.cipher.name === '') { toastr.error(i18nService.nameRequired, i18nService.errorsOccurred); return; } - $scope.savePromise = loginService.encrypt(model).then(function (cipherModel) { + $scope.savePromise = loginService.encrypt($scope.cipher).then(function (cipherModel) { var cipher = new Cipher(cipherModel, true); return loginService.saveWithServer(cipher).then(function (c) { $analytics.eventTrack('Edited Cipher'); diff --git a/src/popup/app/vault/vaultViewCipherController.js b/src/popup/app/vault/vaultViewCipherController.js index 83bf2200..e5486c75 100644 --- a/src/popup/app/vault/vaultViewCipherController.js +++ b/src/popup/app/vault/vaultViewCipherController.js @@ -12,34 +12,38 @@ angular $scope.isPremium = tokenService.getPremium(); $scope.cipher = null; + var cipherObj = null; loginService.get($stateParams.cipherId).then(function (cipher) { if (!cipher) { return; } + cipherObj = cipher; return cipher.decrypt(); }).then(function (model) { $scope.cipher = model; - if (model.password) { - $scope.cipher.maskedPassword = $scope.maskValue(model.password); - } + if (model.type == constantsService.cipherType.login && model.login) { + if (model.login.password) { + $scope.cipher.maskedPassword = $scope.maskValue(model.login.password); + } - if (model.uri) { - $scope.cipher.showLaunch = model.uri.startsWith('http://') || model.uri.startsWith('https://'); - var domain = utilsService.getDomain(model.uri); - if (domain) { - $scope.cipher.website = domain; + if (model.login.uri) { + $scope.cipher.showLaunch = model.login.uri.startsWith('http://') || model.login.uri.startsWith('https://'); + var domain = utilsService.getDomain(model.login.uri); + if (domain) { + $scope.cipher.login.website = domain; + } + else { + $scope.cipher.login.website = model.login.uri; + } } else { - $scope.cipher.website = model.uri; + $scope.cipher.showLaunch = false; } } - else { - $scope.cipher.showLaunch = false; - } - if (model.totp && (cipher.organizationUseTotp || tokenService.getPremium())) { + if (model.login.totp && (cipherObj.organizationUseTotp || tokenService.getPremium())) { totpUpdateCode(); totpTick(); @@ -87,7 +91,7 @@ angular $scope.launchWebsite = function (cipher) { if (cipher.showLaunch) { $analytics.eventTrack('Launched Website'); - chrome.tabs.create({ url: cipher.uri }); + chrome.tabs.create({ url: cipher.login.uri }); } }; @@ -192,11 +196,11 @@ angular }); function totpUpdateCode() { - if (!$scope.cipher.totp) { + if ($scope.cipher.type !== constantsService.cipherType.login || !$scope.cipher.login.totp) { return; } - totpService.getCode($scope.cipher.totp).then(function (code) { + totpService.getCode($scope.cipher.login.totp).then(function (code) { $timeout(function () { if (code) { $scope.totpCodeFormatted = code.substring(0, 3) + ' ' + code.substring(3); diff --git a/src/popup/app/vault/views/vaultAddCipher.html b/src/popup/app/vault/views/vaultAddCipher.html index 7855abe5..10e2d5e8 100644 --- a/src/popup/app/vault/views/vaultAddCipher.html +++ b/src/popup/app/vault/views/vaultAddCipher.html @@ -188,7 +188,7 @@
- +
diff --git a/src/popup/app/vault/views/vaultEditCipher.html b/src/popup/app/vault/views/vaultEditCipher.html index a9877988..c04a4d54 100644 --- a/src/popup/app/vault/views/vaultEditCipher.html +++ b/src/popup/app/vault/views/vaultEditCipher.html @@ -1,4 +1,4 @@ -
+
{{i18n.cancel}} @@ -21,29 +21,177 @@
-
- - + +
+
+ + +
+
+ + +
+
+ + +
+ + {{i18n.generatePassword}} + +
-
- - +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
-
- - +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
- - {{i18n.generatePassword}} - -
-
- - +
+
+ + +
diff --git a/src/popup/app/vault/views/vaultViewCipher.html b/src/popup/app/vault/views/vaultViewCipher.html index 7798ed8b..6cd5bcfd 100644 --- a/src/popup/app/vault/views/vaultViewCipher.html +++ b/src/popup/app/vault/views/vaultViewCipher.html @@ -19,52 +19,97 @@ {{i18n.name}} {{cipher.name}}
-
- - - - {{i18n.website}} - {{cipher.website}} +
+
+ + + + {{i18n.website}} + {{cipher.login.website}} +
+
+ + + + {{i18n.username}} + {{cipher.login.username}} +
+
+ + + + + + + {{i18n.password}} + {{cipher.maskedPassword}} + {{cipher.login.password}} +
+
+ + + + + {{totpSec}} + + + + + + + + {{i18n.verificationCodeTotp}} + {{totpCodeFormatted}} +
-
- - - - {{i18n.username}} - {{cipher.username}} +
+
+ + + + {{i18n.cardholderName}} + {{cipher.card.cardholderName}} +
+
+ + + + {{i18n.number}} + {{cipher.card.number}} +
-
- - - - - - - {{i18n.password}} - {{cipher.maskedPassword}} - {{cipher.password}} +
+
+ {{i18n.firstName}} + {{cipher.identity.firstName}} +
+
+ {{i18n.middleName}} + {{cipher.identity.middleName}} +
+
+ {{i18n.lastName}} + {{cipher.identity.lastName}} +
-
- - - - - {{totpSec}} - - - - - - - - {{i18n.verificationCodeTotp}} - {{totpCodeFormatted}} +
+
diff --git a/src/services/loginService.js b/src/services/loginService.js index 58b3677d..c6584518 100644 --- a/src/services/loginService.js +++ b/src/services/loginService.js @@ -28,62 +28,13 @@ function initLoginService() { type: login.type }; - function encryptCipherData(cipher, model, key, self) { - switch (cipher.type) { - case constantsService.cipherType.login: - return encryptObjProperty(cipher.login, model.login, { - uri: null, - username: null, - password: null, - totp: null - }, key, self); - case constantsService.cipherType.secureNote: - model.secureNote = { - type: cipher.secureNote.type - }; - return Q(); - case constantsService.cipherType.card: - return encryptObjProperty(cipher.card, model.card, { - cardholderName: null, - brand: null, - number: null, - expMonth: null, - expYear: null, - code: null - }, key, self); - case constantsService.cipherType.identity: - return encryptObjProperty(cipher.identity, model.identity, { - title: null, - firstName: null, - middleName: null, - lastName: null, - address1: null, - address2: null, - address3: null, - city: null, - state: null, - postalCode: null, - country: null, - company: null, - email: null, - phone: null, - ssn: null, - username: null, - passportNumber: null, - licenseNumber: null - }, key, self); - default: - throw 'Unknown type.'; - } - } - return self.cryptoService.getOrgKey(login.organizationId).then(function (key) { return Q.all([ encryptObjProperty(login, model, { name: null, notes: null }, key, self), - encryptCipherData(login, model, key), + encryptCipherData(login, model, key, self), self.encryptFields(login.fields, key).then(function (fields) { model.fields = fields; }) @@ -93,10 +44,62 @@ function initLoginService() { }); }; + function encryptCipherData(cipher, model, key, self) { + switch (cipher.type) { + case self.constantsService.cipherType.login: + model.login = {}; + return encryptObjProperty(cipher.login, model.login, { + uri: null, + username: null, + password: null, + totp: null + }, key, self); + case self.constantsService.cipherType.secureNote: + model.secureNote = { + type: cipher.secureNote.type + }; + return Q(); + case self.constantsService.cipherType.card: + model.card = {}; + return encryptObjProperty(cipher.card, model.card, { + cardholderName: null, + brand: null, + number: null, + expMonth: null, + expYear: null, + code: null + }, key, self); + case self.constantsService.cipherType.identity: + model.identity = {}; + return encryptObjProperty(cipher.identity, model.identity, { + title: null, + firstName: null, + middleName: null, + lastName: null, + address1: null, + address2: null, + address3: null, + city: null, + state: null, + postalCode: null, + country: null, + company: null, + email: null, + phone: null, + ssn: null, + username: null, + passportNumber: null, + licenseNumber: null + }, key, self); + default: + throw 'Unknown type.'; + } + } + LoginService.prototype.encryptFields = function (fields, key) { var self = this; if (!fields || !fields.length) { - return null; + return Q(null); } var encFields = []; @@ -132,20 +135,19 @@ function initLoginService() { for (var prop in map) { if (map.hasOwnProperty(prop)) { /* jshint ignore:start */ - (function (theProp) { + (function (theProp, theModel) { var promise = Q().then(function () { - var objProb = obj[(map[theProp] || theProp)]; - if (objProb && objProb !== '') { - return self.cryptoService.encrypt(objProb, key); + var objProp = obj[(map[theProp] || theProp)]; + if (objProp && objProp !== '') { + return self.cryptoService.encrypt(objProp, key); } return null; }).then(function (val) { - model[theProp] = val; - return; + theModel[theProp] = val; }); promises.push(promise); - })(prop); + })(prop, model); /* jshint ignore:end */ } } @@ -169,7 +171,7 @@ function initLoginService() { return self.utilsService.getObjFromStorage(key); }).then(function (ciphers) { if (ciphers && id in ciphers) { - return new Login(ciphers[id], false, localData[id]); + return new Cipher(ciphers[id], false, localData[id]); } return null; @@ -329,7 +331,7 @@ function initLoginService() { function apiSuccess(response) { cipher.id = response.id; self.userService.getUserIdPromise().then(function (userId) { - var data = new LoginData(response, userId); + var data = new CipherData(response, userId); return self.upsert(data); }).then(function () { deferred.resolve(cipher); @@ -514,11 +516,11 @@ function initLoginService() { return; } - data = new LoginData(response, userId); + data = new CipherData(response, userId); return self.upsert(data); }).then(function () { if (data) { - deferred.resolve(new Login(data)); + deferred.resolve(new CipherData(data)); } }); };