diff --git a/jslib b/jslib index 0d80216921..848f50afe7 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 0d80216921efa53dfc095fd25dde9b370a070da8 +Subproject commit 848f50afe7b9dc9e193a036c062ef2f0e4d93018 diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 1df3866af0..b80d588d3b 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -455,6 +455,9 @@ "uri": { "message": "URI" }, + "newUri": { + "message": "New URI" + }, "addedItem": { "message": "Added item" }, @@ -989,5 +992,33 @@ }, "passwordSafe": { "message": "This password was not found in any known data breaches. It should be safe to use." + }, + "baseDomain": { + "message": "Base domain" + }, + "host": { + "message": "Host", + "description": "A URL's host value. For example, the host of https://sub.domain.com:443 is 'sub.domain.com:443'." + }, + "exact": { + "message": "Exact" + }, + "startsWith": { + "message": "Starts with" + }, + "regEx": { + "message": "Regular expression", + "description": "A programming term, also known as 'RegEx'." + }, + "autofillDetection": { + "message": "Auto-fill Detection", + "description": "URI auto-fill match detection." + }, + "defaultAutofillDetection": { + "message": "Default auto-fill detection", + "description": "Default URI auto-fill match detection." + }, + "toggleOptions": { + "message": "Toggle Options" } } diff --git a/src/popup/app/vault/vaultAddCipherController.js b/src/popup/app/vault/vaultAddCipherController.js index 5845c48399..6a9d6e8362 100644 --- a/src/popup/app/vault/vaultAddCipherController.js +++ b/src/popup/app/vault/vaultAddCipherController.js @@ -14,7 +14,12 @@ angular folderId: folderId, name: $stateParams.name, type: constantsService.cipherType.login, - login: {}, + login: { + uris: [{ + uri: null, + match: null + }] + }, identity: {}, card: {}, secureNote: { @@ -23,13 +28,15 @@ angular }; if ($stateParams.uri) { - $scope.cipher.login.uri = $stateParams.uri; + $scope.cipher.login.uris[0].uri = $stateParams.uri; } if ($stateParams.cipher) { angular.extend($scope.cipher, $stateParams.cipher); } + setUriMatchValues(); + $timeout(function () { popupUtilsService.initListSectionItemListeners(document, angular); @@ -109,6 +116,50 @@ angular }); }; + $scope.addUri = function () { + if (!$scope.cipher.login) { + return; + } + + if (!$scope.cipher.login.uris) { + $scope.cipher.login.uris = []; + } + + $scope.cipher.login.uris.push({ + uri: null, + match: null, + }); + + $timeout(function () { + popupUtilsService.initListSectionItemListeners(document, angular); + }, 500); + }; + + $scope.removeUri = function (uri) { + if (!$scope.cipher.login || !$scope.cipher.login.uris) { + return; + } + + var index = $scope.cipher.login.uris.indexOf(uri); + if (index > -1) { + $scope.cipher.login.uris.splice(index, 1); + } + }; + + $scope.uriMatchChanged = function (uri) { + uri.showOptions = uri.showOptions == null ? true : uri.showOptions; + if ((!uri.matchValue && uri.matchValue !== 0) || uri.matchValue === '') { + uri.match = null; + } + else { + uri.match = parseInt(uri.matchValue); + } + }; + + $scope.toggleUriOptions = function (u) { + u.showOptions = u.showOptions == null && u.match != null ? false : !u.showOptions; + }; + $scope.addField = function (type) { if (!$scope.cipher.fields) { $scope.cipher.fields = []; @@ -142,4 +193,14 @@ angular } }); }; + + function setUriMatchValues() { + if ($scope.cipher.login && $scope.cipher.login.uris) { + for (var i = 0; i < $scope.cipher.login.uris.length; i++) { + $scope.cipher.login.uris[i].matchValue = + $scope.cipher.login.uris[i].match || $scope.cipher.login.uris[i].match === 0 ? + $scope.cipher.login.uris[i].match.toString() : ''; + } + } + } }); diff --git a/src/popup/app/vault/vaultEditCipherController.js b/src/popup/app/vault/vaultEditCipherController.js index 5890d72fa9..e8bbfc32e0 100644 --- a/src/popup/app/vault/vaultEditCipherController.js +++ b/src/popup/app/vault/vaultEditCipherController.js @@ -24,12 +24,14 @@ angular if ($stateParams.cipher) { angular.extend($scope.cipher, $stateParams.cipher); + setUriMatchValues(); } else { cipherService.get(cipherId).then(function (cipher) { return cipher.decrypt(); }).then(function (model) { $scope.cipher = model; + setUriMatchValues(); }); } @@ -127,6 +129,50 @@ angular }); }; + $scope.addUri = function () { + if (!$scope.cipher.login) { + return; + } + + if (!$scope.cipher.login.uris) { + $scope.cipher.login.uris = []; + } + + $scope.cipher.login.uris.push({ + uri: null, + match: null, + }); + + $timeout(function () { + popupUtilsService.initListSectionItemListeners(document, angular); + }, 500); + }; + + $scope.removeUri = function (uri) { + if (!$scope.cipher.login || !$scope.cipher.login.uris) { + return; + } + + var index = $scope.cipher.login.uris.indexOf(uri); + if (index > -1) { + $scope.cipher.login.uris.splice(index, 1); + } + }; + + $scope.uriMatchChanged = function (uri) { + uri.showOptions = uri.showOptions == null ? true : uri.showOptions; + if ((!uri.matchValue && uri.matchValue !== 0) || uri.matchValue === '') { + uri.match = null; + } + else { + uri.match = parseInt(uri.matchValue); + } + }; + + $scope.toggleUriOptions = function (u) { + u.showOptions = u.showOptions == null && u.match != null ? false : !u.showOptions; + }; + $scope.addField = function (type) { if (!$scope.cipher.fields) { $scope.cipher.fields = []; @@ -182,4 +228,14 @@ angular } }); } + + function setUriMatchValues() { + if ($scope.cipher.login && $scope.cipher.login.uris) { + for (var i = 0; i < $scope.cipher.login.uris.length; i++) { + $scope.cipher.login.uris[i].matchValue = + $scope.cipher.login.uris[i].match || $scope.cipher.login.uris[i].match === 0 ? + $scope.cipher.login.uris[i].match.toString() : ''; + } + } + } }); diff --git a/src/popup/app/vault/vaultViewCipherController.js b/src/popup/app/vault/vaultViewCipherController.js index 942fe05cc7..eaead5d496 100644 --- a/src/popup/app/vault/vaultViewCipherController.js +++ b/src/popup/app/vault/vaultViewCipherController.js @@ -28,20 +28,6 @@ angular if (model.login.password) { $scope.cipher.maskedPassword = $scope.maskValue(model.login.password); } - - if (model.login.uri) { - $scope.cipher.showLaunch = model.login.uri.startsWith('http://') || model.login.uri.startsWith('https://'); - var domain = platformUtilsService.getDomain(model.login.uri); - if (domain) { - $scope.cipher.login.website = domain; - } - else { - $scope.cipher.login.website = model.login.uri; - } - } - else { - $scope.cipher.showLaunch = false; - } } if (model.login && model.login.totp && (cipherObj.organizationUseTotp || tokenService.getPremium())) { @@ -90,11 +76,13 @@ angular } }; - $scope.launchWebsite = function (cipher) { - if (cipher.showLaunch) { - $analytics.eventTrack('Launched Website'); - BrowserApi.createNewTab(cipher.login.uri); + $scope.launch = function (uri) { + if (!uri.canLaunch) { + return; } + + $analytics.eventTrack('Launched Login URI'); + BrowserApi.createNewTab(uri.uri); }; $scope.clipboardError = function (e, password) { diff --git a/src/popup/app/vault/views/vaultAddCipher.html b/src/popup/app/vault/views/vaultAddCipher.html index 6aed1d396b..ab1910c043 100644 --- a/src/popup/app/vault/views/vaultAddCipher.html +++ b/src/popup/app/vault/views/vaultAddCipher.html @@ -30,10 +30,6 @@