diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index f39eac379e..ce80c65014 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -655,6 +655,10 @@ "message": "Yes, Save Now", "description": "Yes, Save Now" }, + "notificationNeverSave": { + "message": "Never for this website", + "description": "Never for this website" + }, "disableContextMenuItem": { "message": "Disable Context Menu Options", "description": "Disable Context Menu Options" diff --git a/src/background.js b/src/background.js index 3ef629f096..c1db42e928 100644 --- a/src/background.js +++ b/src/background.js @@ -72,6 +72,9 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { else if (msg.command === 'bgAddSave') { saveAddLogin(sender.tab); } + else if (msg.command === 'bgNeverSave') { + saveNever(sender.tab); + } else if (msg.command === 'collectPageDetailsResponse') { if (msg.contentScript) { var forms = autofillService.getFormsWithPasswordFields(msg.details); @@ -487,6 +490,22 @@ function saveAddLogin(tab) { } } +function saveNever(tab) { + for (var i = loginsToAdd.length - 1; i >= 0; i--) { + if (loginsToAdd[i].tabId === tab.id) { + var loginToAdd = loginsToAdd[i]; + + var tabDomain = utilsService.getDomain(tab.url); + if (tabDomain && tabDomain === loginToAdd.domain) { + loginsToAdd.splice(i, 1); + var hostname = utilsService.getHostname(tab.url); + loginService.saveNeverDomain(hostname); + messageTab(tab.id, 'closeNotificationBar'); + } + } + } +} + function checkLoginsToAdd(tab, callback) { if (!loginsToAdd.length) { if (callback) { diff --git a/src/content/notificationBar.js b/src/content/notificationBar.js index 964fe67b55..6edfd90069 100644 --- a/src/content/notificationBar.js +++ b/src/content/notificationBar.js @@ -4,12 +4,19 @@ barType = null; if (window.location.hostname.indexOf('bitwarden.com') === -1) { - chrome.storage.local.get('disableAddLoginNotification', function (obj) { - if (!obj || !obj['disableAddLoginNotification']) { - chrome.runtime.sendMessage({ - command: 'bgCollectPageDetails' - }); + chrome.storage.local.get('neverDomains', function (obj) { + var domains = obj['neverDomains']; + if (domains && domains.hasOwnProperty(window.location.hostname)) { + return; } + + chrome.storage.local.get('disableAddLoginNotification', function (obj) { + if (!obj || !obj['disableAddLoginNotification']) { + chrome.runtime.sendMessage({ + command: 'bgCollectPageDetails' + }); + } + }); }); } diff --git a/src/notification/bar.css b/src/notification/bar.css index 7b14c37f69..95e384fbf7 100644 --- a/src/notification/bar.css +++ b/src/notification/bar.css @@ -54,7 +54,7 @@ img { padding: 5px 0; } -button { +button:not(.link) { background-color: #3c8dbc; padding: 5px 15px; border-radius: 3px; @@ -62,7 +62,20 @@ button { border: 0; } - button:hover { + button:not(.link):hover { cursor: pointer; background-color: #3681ad; } + +button.link { + background: none; + padding: 5px 15px; + color: #3c8dbc; + border: 0; +} + + button.link:hover { + cursor: pointer; + background: none; + text-decoration: underline; + } diff --git a/src/notification/bar.html b/src/notification/bar.html index 55194ea5e5..73a108f069 100644 --- a/src/notification/bar.html +++ b/src/notification/bar.html @@ -28,7 +28,8 @@ - + + diff --git a/src/notification/bar.js b/src/notification/bar.js index 072ef71a14..10388aacd1 100644 --- a/src/notification/bar.js +++ b/src/notification/bar.js @@ -6,13 +6,15 @@ $('#logo-link').attr('title', chrome.i18n.getMessage('appName')); closeButton.attr('title', chrome.i18n.getMessage('close')); $('#template-add .add-save').text(chrome.i18n.getMessage('notificationAddSave')); + $('#template-add .never-save').text(chrome.i18n.getMessage('notificationNeverSave')); $('#template-add .add-text').text(chrome.i18n.getMessage('notificationAddDesc')); if (getQueryVariable('add')) { setContent(document.getElementById('template-add')); var add = $('#template-add-clone'), - addButton = $('#template-add-clone .add-save'); + addButton = $('#template-add-clone .add-save'), + neverButton = $('#template-add-clone .never-save'); $(addButton).click(function (e) { e.preventDefault(); @@ -20,6 +22,13 @@ command: 'bgAddSave' }); }); + + $(neverButton).click(function (e) { + e.preventDefault(); + chrome.runtime.sendMessage({ + command: 'bgNeverSave' + }); + }); } else if (getQueryVariable('info')) { setContent(document.getElementById('template-alert')); diff --git a/src/services/loginService.js b/src/services/loginService.js index cddfc06977..34a833316d 100644 --- a/src/services/loginService.js +++ b/src/services/loginService.js @@ -323,6 +323,32 @@ function initLoginService() { return deferred.promise; }; + LoginService.prototype.saveNeverDomain = function (domain) { + var deferred = Q.defer(); + var neverKey = 'neverDomains'; + + if (!domain) { + deferred.resolve(); + } + else { + chrome.storage.local.get(neverKey, function (obj) { + var domains = obj[neverKey]; + if (!domains) { + domains = {}; + } + + domains[domain] = null; + obj[neverKey] = domains; + + chrome.storage.local.set(obj, function () { + deferred.resolve(); + }); + }); + } + + return deferred.promise; + }; + function handleError(error, deferred) { deferred.reject(error); } diff --git a/src/services/utilsService.js b/src/services/utilsService.js index b3152a8138..fa4b8506ca 100644 --- a/src/services/utilsService.js +++ b/src/services/utilsService.js @@ -173,6 +173,33 @@ function initUtilsService() { return null; } + UtilsService.prototype.getHostname = function (uriString) { + if (!uriString) { + return null; + } + + uriString = uriString.trim(); + if (uriString === '') { + return null; + } + + if (uriString.startsWith('http://') || uriString.startsWith('https://')) { + try { + var url = new URL(uriString); + if (!url || !url.hostname) { + return null; + } + + return url.hostname; + } + catch (e) { + return null; + } + } + + return null; + } + function validIpAddress(ipString) { var ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; return ipRegex.test(ipString);