diff --git a/src/background.js b/src/background.js index 2941b84bff..76d2ae1228 100644 --- a/src/background.js +++ b/src/background.js @@ -57,10 +57,10 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { messageCurrentTab('closeOverlayPopup'); } else if (msg.command === 'bgOpenNotificationBar') { - messageCurrentTab('openNotificationBar', msg.data); + messageTab(sender.tab.id, 'openNotificationBar', msg.data); } else if (msg.command === 'bgCloseNotificationBar') { - messageCurrentTab('closeNotificationBar'); + messageTab(sender.tab.id, 'closeNotificationBar'); } else if (msg.command === 'bgCollectPageDetails') { collectPageDetailsForContentScript(sender.tab); @@ -68,6 +68,12 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { else if (msg.command === 'bgAddLogin') { addLogin(msg.login, sender.tab); } + else if (msg.command === 'bgAddClose') { + removeAddLogin(sender.tab); + } + else if (msg.command === 'bgAddSave') { + saveAddLogin(sender.tab); + } else if (msg.command === 'collectPageDetailsResponse') { // messageCurrentTab('openNotificationBar', { type: 'add', typeData: null }); if (msg.contentScript) { @@ -222,28 +228,23 @@ function loadMenuAndUpdateBadge(url, tabId, loadContextMenuOptions) { return; } - var count = 0; chrome.browserAction.setBadgeBackgroundColor({ color: '#294e5f' }); - siteService.getAllDecrypted().then(function (sites) { + siteService.getAllDecryptedForDomain(tabDomain).then(function (sites) { sortSites(sites); for (var i = 0; i < sites.length; i++) { - if (sites[i].domain && tabDomain === sites[i].domain) { - count++; - - if (loadContextMenuOptions) { - loadSiteContextMenuOptions(sites[i]); - } + if (loadContextMenuOptions) { + loadSiteContextMenuOptions(sites[i]); } } - if (count > 0 && count < 9) { + if (sites.length > 0 && sites.length < 9) { chrome.browserAction.setBadgeText({ - text: count.toString(), + text: sites.length.toString(), tabId: tabId }); } - else if (count > 0) { + else if (sites.length > 0) { chrome.browserAction.setBadgeText({ text: '9+', tabId: tabId @@ -356,14 +357,77 @@ function addLogin(login, tab) { return; } - loginsToAdd.push({ - username: login.username, - password: login.password, - name: loginDomain, - uri: login.url, - tabId: tab.id + siteService.getAllDecryptedForDomain(loginDomain).then(function (sites) { + var match = false; + for (var i = 0; i < sites.length; i++) { + if (sites[i] === login.username) { + match = true; + break; + } + } + + if (!match) { + // remove any old logins for this tab + removeAddLogin(tab); + + loginsToAdd.push({ + username: login.username, + password: login.password, + name: loginDomain, + uri: login.url, + tabId: tab.id, + expires: new Date((new Date()).getTime() + 30 * 60000) // 30 minutes + }); + checkLoginsToAdd(); + } }); - checkLoginsToAdd(); +} + +cleanupLoginsToAdd(); +setInterval(cleanupLoginsToAdd, 2 * 60 * 1000); // check every 2 minutes +function cleanupLoginsToAdd() { + var now = new Date(); + for (var i = loginsToAdd.length - 1; i >= 0 ; i--) { + if (loginsToAdd[i].expires < now) { + loginsToAdd.splice(i, 1); + } + } +} + +function removeAddLogin(tab) { + for (var i = loginsToAdd.length - 1; i >= 0 ; i--) { + if (loginsToAdd[i].tabId === tab.id) { + loginsToAdd.splice(i, 1); + } + } +} + +function saveAddLogin(tab) { + for (var i = loginsToAdd.length - 1; i >= 0 ; i--) { + if (loginsToAdd[i].tabId === tab.id) { + var loginToAdd = loginsToAdd[i]; + loginsToAdd.splice(i, 1); + siteService.encrypt({ + id: null, + folderId: null, + favorite: false, + name: loginToAdd.name, + uri: loginToAdd.uri, + username: loginToAdd.username, + password: loginToAdd.password, + notes: null + }).then(function (siteModel) { + var site = new Site(siteModel, true); + siteService.saveWithServer(site).then(function (site) { + ga('send', { + hitType: 'event', + eventAction: 'Added Site from Notification Bar' + }); + }); + }); + messageTab(tab.id, 'closeNotificationBar'); + } + } } function checkLoginsToAdd() { diff --git a/src/content/notificationBar.js b/src/content/notificationBar.js index 4ca3fbdd49..d691d3983d 100644 --- a/src/content/notificationBar.js +++ b/src/content/notificationBar.js @@ -1,24 +1,25 @@ !(function () { var pageDetails = [], - formData = []; + formData = [], + barType = null; + chrome.runtime.sendMessage({ command: 'bgCollectPageDetails' }); chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { if (msg.command === 'openNotificationBar') { - closeBar(); + closeBar(false); openBar(msg.data.type, msg.data.typeData); sendResponse(); return true; } else if (msg.command === 'closeNotificationBar') { - closeBar(); + closeBar(true); sendResponse(); return true; } else if (msg.command === 'pageDetails') { - console.log(msg.data); pageDetails.push(msg.data.details); watchForms(msg.data.forms); sendResponse(); @@ -58,20 +59,21 @@ var password = null, username = null, passwordId = formData[i].password ? formData[i].password.htmlID : null, - usernameId = formData[i].username ? formData[i].username.htmlID : null; + usernameId = formData[i].username ? formData[i].username.htmlID : null, + inputs = document.getElementsByTagName('input'); if (passwordId && passwordId !== '') { password = document.getElementById(passwordId); } else if (formData[i].password) { - password = document.getElementsByTagName('input')[formData[i].password.elementNumber]; + password = inputs[formData[i].password.elementNumber]; } if (usernameId && usernameId !== '') { username = document.getElementById(usernameId); } else if (formData[i].username) { - username = document.getElementsByTagName('input')[formData[i].username.elementNumber]; + username = inputs[formData[i].username.elementNumber]; } var login = { @@ -80,7 +82,7 @@ url: document.URL }; - if (login.password && login.password !== '') { + if (login.username && login.username !== '' && login.password && login.password !== '') { chrome.runtime.sendMessage({ command: 'bgAddLogin', login: login @@ -93,6 +95,7 @@ function openBar(type, typeData) { var barPage = 'notification/bar.html'; + barType = type; switch (type) { case 'info': barPage = barPage + '?info=' + typeData.text; @@ -108,10 +111,15 @@ break; case 'add': barPage = barPage + '?add=1'; + break; default: break; } + if (!document.body) { + return; + } + var iframe = document.createElement('iframe'); iframe.src = chrome.extension.getURL(barPage); iframe.style.cssText = 'height: 41px; width: 100%; border: 0;'; @@ -128,7 +136,7 @@ document.body.insertBefore(spacer, document.body.firstChild); } - function closeBar() { + function closeBar(explicitClose) { var el = document.getElementById('bit-notification-bar'); if (el) { el.parentElement.removeChild(el); @@ -138,5 +146,19 @@ if (el) { el.parentElement.removeChild(el); } + + if (!explicitClose) { + return; + } + + switch (barType) { + case 'add': + chrome.runtime.sendMessage({ + command: 'bgAddClose' + }); + break; + default: + break; + } } })(); diff --git a/src/notification/bar.html b/src/notification/bar.html index 6d8a273ed0..3cccc407ac 100644 --- a/src/notification/bar.html +++ b/src/notification/bar.html @@ -26,16 +26,13 @@ Should bitwarden remember this password for you? - - - + + -
- This is an alert. -
+
diff --git a/src/notification/bar.js b/src/notification/bar.js index fc34040757..94cb8186cc 100644 --- a/src/notification/bar.js +++ b/src/notification/bar.js @@ -7,8 +7,14 @@ setContent(template_add); var add = $('#template-add-clone'), - addButton = $('#template-add-clone.add-save'), - neverButton = $('#template-add-clone.add-never'); + addButton = $('#template-add-clone .add-save'); + + $(addButton).click(function (e) { + e.preventDefault(); + chrome.runtime.sendMessage({ + command: 'bgAddSave' + }); + }); } else if (getQueryVariable('info')) { setContent(template_alert); @@ -28,7 +34,7 @@ for (var i = 0; i < vars.length; i++) { var pair = vars[i].split('='); - if (pair[0] == variable) { + if (pair[0] === variable) { return pair[1]; } } diff --git a/src/services/siteService.js b/src/services/siteService.js index 41e12d9432..a0fa64dd09 100644 --- a/src/services/siteService.js +++ b/src/services/siteService.js @@ -130,6 +130,21 @@ function initSiteService() { }); }; + SiteService.prototype.getAllDecryptedForDomain = function (domain) { + var self = this; + + return self.getAllDecrypted().then(function (sites) { + var sitesToReturn = []; + for (var i = 0; i < sites.length; i++) { + if (sites[i].domain === domain) { + sitesToReturn.push(sites[i]); + } + } + + return sitesToReturn; + }); + }; + SiteService.prototype.saveWithServer = function (site) { var deferred = Q.defer();