mirror of
https://github.com/bitwarden/desktop.git
synced 2025-02-25 02:41:27 +01:00
Added lock timer and adjusted context menus and badge appropriately
This commit is contained in:
parent
80ed37ada6
commit
c982667338
@ -99,6 +99,10 @@
|
|||||||
"message": "Generate Password (copied)",
|
"message": "Generate Password (copied)",
|
||||||
"description": "Generate Password (copied)"
|
"description": "Generate Password (copied)"
|
||||||
},
|
},
|
||||||
|
"noMatchingSites": {
|
||||||
|
"message": "No matching sites.",
|
||||||
|
"description": "No matching sites."
|
||||||
|
},
|
||||||
"autoFillInfo": {
|
"autoFillInfo": {
|
||||||
"message": "There are no sites available to auto-fill for the current browser tab.",
|
"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."
|
"description": "There are no sites available to auto-fill for the current browser tab."
|
||||||
|
@ -188,6 +188,12 @@ function loadMenuAndUpdateBadge(url, tabId, loadContextMenuOptions) {
|
|||||||
tabId: tabId
|
tabId: tabId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}, function () {
|
||||||
|
loadNoSitesContextMenuOptions();
|
||||||
|
chrome.browserAction.setBadgeText({
|
||||||
|
text: '',
|
||||||
|
tabId: tabId
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +242,8 @@ chrome.contextMenus.onClicked.addListener(function (info, tab) {
|
|||||||
return;
|
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) {
|
function loadSiteContextMenuOptions(site) {
|
||||||
var title = site.name + (site.username && site.username !== '' ? ' (' + site.username + ')' : '');
|
var title = site.name + (site.username && site.username !== '' ? ' (' + site.username + ')' : '');
|
||||||
loadContextMenuOptions(title, site.id, site);
|
loadContextMenuOptions(title, site.id, site);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadNoSitesContextMenuOptions() {
|
function loadNoSitesContextMenuOptions() {
|
||||||
var title = 'No matching sites.';
|
loadContextMenuOptions(i18nService.noMatchingSites, 'noop', null);
|
||||||
loadContextMenuOptions(title, 'noop', null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadContextMenuOptions(title, idSuffix, site) {
|
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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -172,11 +172,17 @@
|
|||||||
params: { animation: null }
|
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) {
|
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
|
||||||
cryptoService.getKey(false, function (key) {
|
cryptoService.getKey(false, function (key) {
|
||||||
tokenService.getToken(function (token) {
|
tokenService.getToken(function (token) {
|
||||||
userService.isAuthenticated(function (isAuthenticated) {
|
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 (!toState.data || !toState.data.authorize) {
|
||||||
if (isAuthenticated && !tokenService.isTokenExpired(token)) {
|
if (isAuthenticated && !tokenService.isTokenExpired(token)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<option value="0">{{i18n.immediately}}</option>
|
<option value="0">{{i18n.immediately}}</option>
|
||||||
<option value="1">{{i18n.oneMinute}}</option>
|
<option value="1">{{i18n.oneMinute}}</option>
|
||||||
<option value="5">{{i18n.fiveMinutes}}</option>
|
<option value="5">{{i18n.fiveMinutes}}</option>
|
||||||
<option value="15">{{i18n.fifteedMinutes}}</option>
|
<option value="15">{{i18n.fifteenMinutes}}</option>
|
||||||
<option value="30">{{i18n.thirtyMinutes}}</option>
|
<option value="30">{{i18n.thirtyMinutes}}</option>
|
||||||
<option value="60">{{i18n.oneHour}}</option>
|
<option value="60">{{i18n.oneHour}}</option>
|
||||||
<option value="240">{{i18n.fourHours}}</option>
|
<option value="240">{{i18n.fourHours}}</option>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
function ConstantsService() {
|
function ConstantsService() {
|
||||||
return {
|
return {
|
||||||
disableGaKey: 'disableGa',
|
disableGaKey: 'disableGa',
|
||||||
lockOptionKey: 'lockOption'
|
lockOptionKey: 'lockOption',
|
||||||
|
lastActiveKey: 'lastActive'
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,10 @@ function FolderService(cryptoService, userService, apiService) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function initFolderService() {
|
function initFolderService() {
|
||||||
|
FolderService.prototype.clearCache = function () {
|
||||||
|
this.decryptedFolderCache = null
|
||||||
|
};
|
||||||
|
|
||||||
FolderService.prototype.encrypt = function (folder) {
|
FolderService.prototype.encrypt = function (folder) {
|
||||||
var model = {
|
var model = {
|
||||||
id: folder.id
|
id: folder.id
|
||||||
@ -62,30 +66,37 @@ function initFolderService() {
|
|||||||
|
|
||||||
FolderService.prototype.getAllDecrypted = function () {
|
FolderService.prototype.getAllDecrypted = function () {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
if (self.decryptedFolderCache) {
|
|
||||||
deferred.resolve(self.decryptedFolderCache);
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
var promises = [];
|
cryptoService.getKey(false, function (key) {
|
||||||
var decFolders = [{
|
if (!key) {
|
||||||
id: null,
|
deferred.reject();
|
||||||
name: '(none)'
|
return deferred.promise;
|
||||||
}];
|
|
||||||
self.getAll(function (folders) {
|
|
||||||
for (var i = 0; i < folders.length; i++) {
|
|
||||||
promises.push(folders[i].decrypt().then(function (folder) {
|
|
||||||
decFolders.push(folder);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q.all(promises).then(function () {
|
if (self.decryptedFolderCache) {
|
||||||
if (decFolders.length > 0) {
|
deferred.resolve(self.decryptedFolderCache);
|
||||||
self.decryptedFolderCache = decFolders;
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ function i18nService() {
|
|||||||
copyUsername: chrome.i18n.getMessage('copyUsername'),
|
copyUsername: chrome.i18n.getMessage('copyUsername'),
|
||||||
autoFill: chrome.i18n.getMessage('autoFill'),
|
autoFill: chrome.i18n.getMessage('autoFill'),
|
||||||
generatePasswordCopied: chrome.i18n.getMessage('generatePasswordCopied'),
|
generatePasswordCopied: chrome.i18n.getMessage('generatePasswordCopied'),
|
||||||
|
noMatchingSites: chrome.i18n.getMessage('noMatchingSites'),
|
||||||
autoFillInfo: chrome.i18n.getMessage('autoFillInfo'),
|
autoFillInfo: chrome.i18n.getMessage('autoFillInfo'),
|
||||||
addSite: chrome.i18n.getMessage('addSite'),
|
addSite: chrome.i18n.getMessage('addSite'),
|
||||||
passwordHint: chrome.i18n.getMessage('passwordHint'),
|
passwordHint: chrome.i18n.getMessage('passwordHint'),
|
||||||
|
@ -8,6 +8,10 @@ function SiteService(cryptoService, userService, apiService) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function initSiteService() {
|
function initSiteService() {
|
||||||
|
SiteService.prototype.clearCache = function () {
|
||||||
|
this.decryptedSiteCache = null
|
||||||
|
};
|
||||||
|
|
||||||
SiteService.prototype.encrypt = function (site) {
|
SiteService.prototype.encrypt = function (site) {
|
||||||
var model = {
|
var model = {
|
||||||
id: site.id,
|
id: site.id,
|
||||||
@ -79,25 +83,32 @@ function initSiteService() {
|
|||||||
|
|
||||||
SiteService.prototype.getAllDecrypted = function () {
|
SiteService.prototype.getAllDecrypted = function () {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
if (self.decryptedSiteCache) {
|
|
||||||
deferred.resolve(self.decryptedSiteCache);
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
var promises = [];
|
cryptoService.getKey(false, function (key) {
|
||||||
var decSites = [];
|
if (!key) {
|
||||||
self.getAll(function (sites) {
|
deferred.reject();
|
||||||
for (var i = 0; i < sites.length; i++) {
|
return deferred.promise;
|
||||||
promises.push(sites[i].decrypt().then(function (site) {
|
|
||||||
decSites.push(site);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q.all(promises).then(function () {
|
if (self.decryptedSiteCache) {
|
||||||
self.decryptedSiteCache = decSites;
|
|
||||||
deferred.resolve(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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user