diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 105372752f..11fbd7a7ce 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -427,6 +427,10 @@ "message": "4 hours", "description": "4 hours" }, + "onLocked": { + "message": "On Locked", + "description": "On Locked" + }, "onRestart": { "message": "On Restart", "description": "On Restart" diff --git a/src/background.js b/src/background.js index 1f689e76a1..3ef629f096 100644 --- a/src/background.js +++ b/src/background.js @@ -11,23 +11,26 @@ var userService = new UserService(tokenService, apiService, cryptoService); var settingsService = new SettingsService(userService); var loginService = new LoginService(cryptoService, userService, apiService, settingsService); var folderService = new FolderService(cryptoService, userService, apiService); +var lockService = new LockService(constantsService, cryptoService, folderService, loginService, setIcon, refreshBadgeAndMenu); var syncService = new SyncService(loginService, folderService, userService, apiService, settingsService, cryptoService, logout); var autofillService = new AutofillService(); var passwordGenerationService = new PasswordGenerationService(); -chrome.commands.onCommand.addListener(function (command) { - if (command === 'generate_password') { - ga('send', { - hitType: 'event', - eventAction: 'Generated Password From Command' - }); - passwordGenerationService.getOptions().then(function (options) { - var password = passwordGenerationService.generatePassword(options); - copyToClipboard(password); - }); - } -}); +if (chrome.commands) { + chrome.commands.onCommand.addListener(function (command) { + if (command === 'generate_password') { + ga('send', { + hitType: 'event', + eventAction: 'Generated Password From Command' + }); + passwordGenerationService.getOptions().then(function (options) { + var password = passwordGenerationService.generatePassword(options); + copyToClipboard(password); + }); + } + }); +} var loginToAutoFill = null, pageDetailsToAutoFill = [], @@ -738,57 +741,3 @@ function fullSync(override) { } }); } - -// Locking - -var lastLockCheck = null; -checkLock(); -setInterval(checkLock, 10 * 1000); // check every 10 seconds - -function checkLock() { - var now = new Date(); - if (lastLockCheck && (now - lastLockCheck) < 5000) { - // can only check lock every 5 seconds - return; - } - lastLockCheck = now; - - if (chrome.extension.getViews({ type: 'popup' }).length > 0) { - // popup is open, do not lock - return; - } - - cryptoService.getKey().then(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) || - obj[constantsService.lockOptionKey] === -1)) { - // 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 - Q.all([cryptoService.clearKey(), cryptoService.clearOrgKeys(true)]).then(function () { - cryptoService.clearPrivateKey(); - setIcon(); - folderService.clearCache(); - loginService.clearCache(); - refreshBadgeAndMenu(); - }); - } - } - }); - }); - }); -}; diff --git a/src/manifest.json b/src/manifest.json index 5e2e1ed957..4a44edd6f0 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -58,6 +58,7 @@ "storage", "unlimitedStorage", "clipboardWrite", + "idle", "http://*/*", "https://*/*" ], diff --git a/src/popup/app/settings/views/settings.html b/src/popup/app/settings/views/settings.html index cc78573350..9f832fa50e 100644 --- a/src/popup/app/settings/views/settings.html +++ b/src/popup/app/settings/views/settings.html @@ -18,6 +18,7 @@ + diff --git a/src/services/lockService.js b/src/services/lockService.js new file mode 100644 index 0000000000..bdfe06458a --- /dev/null +++ b/src/services/lockService.js @@ -0,0 +1,125 @@ +function LockService(constantsService, cryptoService, folderService, loginService, setIcon, refreshBadgeAndMenu) { + this.lastLockCheck = null; + this.constantsService = constantsService; + this.cryptoService = cryptoService; + this.folderService = folderService; + this.loginService = loginService; + this.setIcon = setIcon; + this.refreshBadgeAndMenu = refreshBadgeAndMenu; + + initLockService(this); +}; + +function initLockService(self) { + checkLock(); + setInterval(checkLock, 10 * 1000); // check every 10 seconds + + function checkLock() { + var now = new Date(); + if (self.lastLockCheck && (now - self.lastLockCheck) < 5000) { + // can only check lock every 5 seconds + return; + } + self.lastLockCheck = now; + + if (chrome.extension.getViews({ type: 'popup' }).length > 0) { + // popup is open, do not lock + return; + } + + var lockOptionSeconds = null; + self.cryptoService.getKey().then(function (key) { + if (!key) { + // no key so no need to lock + return false; + } + + return getLockOption(); + }).then(function (lockOption) { + if (lockOption === false || lockOption < 0) { + return; + } + + lockOptionSeconds = lockOption * 60; + return getLastActive(); + }).then(function (lastActive) { + if (lockOptionSeconds === null) { + return; + } + + var diffSeconds = ((new Date()).getTime() - lastActive) / 1000; + if (diffSeconds >= lockOptionSeconds) { + // need to lock now + self.lock(); + } + }); + } + + if (chrome.idle && chrome.idle.onStateChanged) { + chrome.idle.onStateChanged.addListener(function (newState) { + if (newState === 'locked') { + getLockOption().then(function (lockOption) { + if (lockOption === -2) { + self.lock(); + } + }); + } + }); + } + + LockService.prototype.lock = function () { + Q.all([self.cryptoService.clearKey(), self.cryptoService.clearOrgKeys(true)]).then(function () { + self.cryptoService.clearPrivateKey(); + self.setIcon(); + self.folderService.clearCache(); + self.loginService.clearCache(); + self.refreshBadgeAndMenu(); + }); + }; + + function getLockOption() { + var deferred = Q.defer(); + + chrome.storage.local.get(self.constantsService.lockOptionKey, function (obj) { + if (obj && obj[constantsService.lockOptionKey] === 0 || obj[constantsService.lockOptionKey]) { + deferred.resolve(parseInt(obj[self.constantsService.lockOptionKey])); + } + else { + deferred.reject(); + } + }); + + return deferred.promise; + } + + function getLastActive() { + var deferred = Q.defer(); + + chrome.storage.local.get(self.constantsService.lastActiveKey, function (obj) { + if (obj && obj[constantsService.lastActiveKey]) { + deferred.resolve(obj[constantsService.lastActiveKey]); + } + else { + deferred.reject(); + } + }); + + return deferred.promise; + } + + function getIdleState(detectionInterval) { + detectionInterval = detectionInterval || (60 * 5); + var deferred = Q.defer(); + + if (chrome.idle && chrome.idle.queryState) { + chrome.idle.queryState(detectionInterval, function (state) { + deferred.resolve(state); + }); + } + else { + deferred.resolve('active'); + } + + return deferred.promise; + } +};