diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 5a682eb6b1..e32b13431d 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -99,6 +99,10 @@ "message": "Generate Password (copied)", "description": "Generate Password (copied)" }, + "noMatchingSites": { + "message": "No matching sites.", + "description": "No matching sites." + }, "autoFillInfo": { "message": "There are no sites available to auto-fill for the current browser tab.", "description": "There are no sites available to auto-fill for the current browser tab." diff --git a/src/background.js b/src/background.js index 314a9e9b09..c3e0af0c3c 100644 --- a/src/background.js +++ b/src/background.js @@ -188,6 +188,12 @@ function loadMenuAndUpdateBadge(url, tabId, loadContextMenuOptions) { tabId: tabId }); } + }, function () { + loadNoSitesContextMenuOptions(); + chrome.browserAction.setBadgeText({ + text: '', + tabId: tabId + }); }); } @@ -236,6 +242,8 @@ chrome.contextMenus.onClicked.addListener(function (info, tab) { return; } } + }, function () { + }); } }); @@ -313,38 +321,13 @@ function sortSites(sites) { }); } -function buildContextMenuOptions(url) { - var tabDomain = tldjs.getDomain(url); - if (!tabDomain) { - return; - } - - siteService.getAllDecrypted().then(function (sites) { - var count = 0; - if (sites && sites.length) { - sortSites(sites); - for (var i = 0; i < sites.length; i++) { - if (sites[i].domain && tabDomain === sites[i].domain) { - count++; - loadSiteContextMenuOptions(sites[i]); - } - } - } - - if (!count) { - loadNoSitesContextMenuOptions(); - } - }); -} - function loadSiteContextMenuOptions(site) { var title = site.name + (site.username && site.username !== '' ? ' (' + site.username + ')' : ''); loadContextMenuOptions(title, site.id, site); } function loadNoSitesContextMenuOptions() { - var title = 'No matching sites.'; - loadContextMenuOptions(title, 'noop', null); + loadContextMenuOptions(i18nService.noMatchingSites, 'noop', null); } function loadContextMenuOptions(title, idSuffix, site) { @@ -420,3 +403,46 @@ function fullSync(override) { } }); } + +// Locking + +checkLock(); +setInterval(checkLock, 10 * 1000); // check every 10 seconds + +function checkLock() { + if (chrome.extension.getViews({ type: 'popup' }).length > 0) { + // popup is open, do not lock + return; + } + + cryptoService.getKey(false, function (key) { + if (!key) { + // no key so no need to lock + return; + } + + chrome.storage.local.get(constantsService.lockOptionKey, function (obj) { + if (obj && !obj[constantsService.lockOptionKey] && obj[constantsService.lockOptionKey] !== 0) { + // no lock option set + return; + } + + chrome.storage.local.get(constantsService.lastActiveKey, function (obj2) { + if (obj2 && obj2[constantsService.lastActiveKey]) { + var lastActive = obj2[constantsService.lastActiveKey]; + var diffSeconds = ((new Date()).getTime() - lastActive) / 1000; + var lockOptionSeconds = parseInt(obj[constantsService.lockOptionKey]) * 60; + + if (diffSeconds >= lockOptionSeconds) { + // need to lock now + cryptoService.clearKey(function () { + folderService.clearCache(); + siteService.clearCache(); + refreshBadgeAndMenu(); + }); + } + } + }); + }); + }); +}; diff --git a/src/popup/app/config.js b/src/popup/app/config.js index 9976ee9bb2..1b4839e9c8 100644 --- a/src/popup/app/config.js +++ b/src/popup/app/config.js @@ -172,11 +172,17 @@ params: { animation: null } }); }) - .run(function ($rootScope, userService, loginService, cryptoService, tokenService, $state) { + .run(function ($rootScope, userService, loginService, cryptoService, tokenService, $state, constantsService) { $rootScope.$on('$stateChangeStart', function (event, toState, toParams) { cryptoService.getKey(false, function (key) { tokenService.getToken(function (token) { userService.isAuthenticated(function (isAuthenticated) { + if (isAuthenticated) { + var obj = {}; + obj[constantsService.lastActiveKey] = (new Date()).getTime(); + chrome.storage.local.set(obj, function () { }); + } + if (!toState.data || !toState.data.authorize) { if (isAuthenticated && !tokenService.isTokenExpired(token)) { event.preventDefault(); diff --git a/src/popup/app/settings/views/settings.html b/src/popup/app/settings/views/settings.html index 1471c5694c..ba5c9dbad7 100644 --- a/src/popup/app/settings/views/settings.html +++ b/src/popup/app/settings/views/settings.html @@ -14,7 +14,7 @@ - + diff --git a/src/services/constantsService.js b/src/services/constantsService.js index a2cc16335c..4a00b25470 100644 --- a/src/services/constantsService.js +++ b/src/services/constantsService.js @@ -1,6 +1,7 @@ function ConstantsService() { return { disableGaKey: 'disableGa', - lockOptionKey: 'lockOption' + lockOptionKey: 'lockOption', + lastActiveKey: 'lastActive' }; }; diff --git a/src/services/folderService.js b/src/services/folderService.js index f3ff7556cf..ce261e6d52 100644 --- a/src/services/folderService.js +++ b/src/services/folderService.js @@ -8,6 +8,10 @@ function FolderService(cryptoService, userService, apiService) { }; function initFolderService() { + FolderService.prototype.clearCache = function () { + this.decryptedFolderCache = null + }; + FolderService.prototype.encrypt = function (folder) { var model = { id: folder.id @@ -62,30 +66,37 @@ function initFolderService() { FolderService.prototype.getAllDecrypted = function () { var deferred = Q.defer(); - var self = this; - if (self.decryptedFolderCache) { - deferred.resolve(self.decryptedFolderCache); - return deferred.promise; - } - var promises = []; - var decFolders = [{ - id: null, - name: '(none)' - }]; - self.getAll(function (folders) { - for (var i = 0; i < folders.length; i++) { - promises.push(folders[i].decrypt().then(function (folder) { - decFolders.push(folder); - })); + cryptoService.getKey(false, function (key) { + if (!key) { + deferred.reject(); + return deferred.promise; } - Q.all(promises).then(function () { - if (decFolders.length > 0) { - self.decryptedFolderCache = decFolders; + if (self.decryptedFolderCache) { + deferred.resolve(self.decryptedFolderCache); + return deferred.promise; + } + + var promises = []; + var decFolders = [{ + id: null, + name: '(none)' + }]; + self.getAll(function (folders) { + for (var i = 0; i < folders.length; i++) { + promises.push(folders[i].decrypt().then(function (folder) { + decFolders.push(folder); + })); } - deferred.resolve(decFolders); + + Q.all(promises).then(function () { + if (decFolders.length > 0) { + self.decryptedFolderCache = decFolders; + } + deferred.resolve(decFolders); + }); }); }); diff --git a/src/services/i18nService.js b/src/services/i18nService.js index da86dba731..39ad962f11 100644 --- a/src/services/i18nService.js +++ b/src/services/i18nService.js @@ -22,6 +22,7 @@ function i18nService() { copyUsername: chrome.i18n.getMessage('copyUsername'), autoFill: chrome.i18n.getMessage('autoFill'), generatePasswordCopied: chrome.i18n.getMessage('generatePasswordCopied'), + noMatchingSites: chrome.i18n.getMessage('noMatchingSites'), autoFillInfo: chrome.i18n.getMessage('autoFillInfo'), addSite: chrome.i18n.getMessage('addSite'), passwordHint: chrome.i18n.getMessage('passwordHint'), diff --git a/src/services/siteService.js b/src/services/siteService.js index 712a1cb0eb..239d1f549e 100644 --- a/src/services/siteService.js +++ b/src/services/siteService.js @@ -8,6 +8,10 @@ function SiteService(cryptoService, userService, apiService) { }; function initSiteService() { + SiteService.prototype.clearCache = function () { + this.decryptedSiteCache = null + }; + SiteService.prototype.encrypt = function (site) { var model = { id: site.id, @@ -79,25 +83,32 @@ function initSiteService() { SiteService.prototype.getAllDecrypted = function () { var deferred = Q.defer(); - var self = this; - if (self.decryptedSiteCache) { - deferred.resolve(self.decryptedSiteCache); - return deferred.promise; - } - var promises = []; - var decSites = []; - self.getAll(function (sites) { - for (var i = 0; i < sites.length; i++) { - promises.push(sites[i].decrypt().then(function (site) { - decSites.push(site); - })); + cryptoService.getKey(false, function (key) { + if (!key) { + deferred.reject(); + return deferred.promise; } - Q.all(promises).then(function () { - self.decryptedSiteCache = decSites; + if (self.decryptedSiteCache) { deferred.resolve(self.decryptedSiteCache); + return deferred.promise; + } + + var promises = []; + var decSites = []; + self.getAll(function (sites) { + for (var i = 0; i < sites.length; i++) { + promises.push(sites[i].decrypt().then(function (site) { + decSites.push(site); + })); + } + + Q.all(promises).then(function () { + self.decryptedSiteCache = decSites; + deferred.resolve(self.decryptedSiteCache); + }); }); });