mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-30 13:03:53 +01:00
u2f fixes. bg vars with prefix
This commit is contained in:
parent
61c44ea4d9
commit
4e270cc1cb
@ -1,21 +1,22 @@
|
|||||||
var isBackground = true;
|
var isBackground = true;
|
||||||
var loginsToAdd = [];
|
var bg_loginsToAdd = [];
|
||||||
var i18nService = new i18nService();
|
var bg_i18nService = new i18nService();
|
||||||
var constantsService = new ConstantsService();
|
var bg_constantsService = new ConstantsService();
|
||||||
var utilsService = new UtilsService();
|
var bg_utilsService = new UtilsService();
|
||||||
var cryptoService = new CryptoService(constantsService);
|
var bg_cryptoService = new CryptoService(bg_constantsService);
|
||||||
var tokenService = new TokenService();
|
var bg_tokenService = new TokenService();
|
||||||
var appIdService = new AppIdService();
|
var bg_appIdService = new AppIdService();
|
||||||
var apiService = new ApiService(tokenService, appIdService, utilsService, logout);
|
var bg_apiService = new ApiService(bg_tokenService, bg_appIdService, bg_utilsService, logout);
|
||||||
var userService = new UserService(tokenService, apiService, cryptoService);
|
var bg_userService = new UserService(bg_tokenService, bg_apiService, bg_cryptoService);
|
||||||
var settingsService = new SettingsService(userService);
|
var bg_settingsService = new SettingsService(bg_userService);
|
||||||
var loginService = new LoginService(cryptoService, userService, apiService, settingsService);
|
var bg_loginService = new LoginService(bg_cryptoService, bg_userService, bg_apiService, bg_settingsService);
|
||||||
var folderService = new FolderService(cryptoService, userService, apiService);
|
var bg_folderService = new FolderService(bg_cryptoService, bg_userService, bg_apiService);
|
||||||
var lockService = new LockService(constantsService, cryptoService, folderService, loginService, setIcon, refreshBadgeAndMenu);
|
var bg_lockService = new LockService(bg_constantsService, bg_cryptoService, bg_folderService, bg_loginService, setIcon,
|
||||||
var syncService = new SyncService(loginService, folderService, userService, apiService, settingsService,
|
refreshBadgeAndMenu);
|
||||||
cryptoService, logout);
|
var bg_syncService = new SyncService(bg_loginService, bg_folderService, bg_userService, bg_apiService, bg_settingsService,
|
||||||
var autofillService = new AutofillService();
|
bg_cryptoService, logout);
|
||||||
var passwordGenerationService = new PasswordGenerationService();
|
var bg_autofillService = new AutofillService();
|
||||||
|
var bg_passwordGenerationService = new PasswordGenerationService();
|
||||||
|
|
||||||
if (chrome.commands) {
|
if (chrome.commands) {
|
||||||
chrome.commands.onCommand.addListener(function (command) {
|
chrome.commands.onCommand.addListener(function (command) {
|
||||||
@ -24,8 +25,8 @@ if (chrome.commands) {
|
|||||||
hitType: 'event',
|
hitType: 'event',
|
||||||
eventAction: 'Generated Password From Command'
|
eventAction: 'Generated Password From Command'
|
||||||
});
|
});
|
||||||
passwordGenerationService.getOptions().then(function (options) {
|
bg_passwordGenerationService.getOptions().then(function (options) {
|
||||||
var password = passwordGenerationService.generatePassword(options);
|
var password = bg_passwordGenerationService.generatePassword(options);
|
||||||
copyToClipboard(password);
|
copyToClipboard(password);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -77,7 +78,7 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
|
|||||||
}
|
}
|
||||||
else if (msg.command === 'collectPageDetailsResponse') {
|
else if (msg.command === 'collectPageDetailsResponse') {
|
||||||
if (msg.contentScript) {
|
if (msg.contentScript) {
|
||||||
var forms = autofillService.getFormsWithPasswordFields(msg.details);
|
var forms = bg_autofillService.getFormsWithPasswordFields(msg.details);
|
||||||
messageTab(msg.tabId, 'pageDetails', { details: msg.details, forms: forms });
|
messageTab(msg.tabId, 'pageDetails', { details: msg.details, forms: forms });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -92,8 +93,8 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
|
|||||||
|
|
||||||
setIcon();
|
setIcon();
|
||||||
function setIcon() {
|
function setIcon() {
|
||||||
userService.isAuthenticated(function (isAuthenticated) {
|
bg_userService.isAuthenticated(function (isAuthenticated) {
|
||||||
cryptoService.getKey().then(function (key) {
|
bg_cryptoService.getKey().then(function (key) {
|
||||||
var suffix = '';
|
var suffix = '';
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
suffix = '_gray';
|
suffix = '_gray';
|
||||||
@ -144,9 +145,9 @@ function buildContextMenu(callback) {
|
|||||||
id: 'autofill',
|
id: 'autofill',
|
||||||
parentId: 'root',
|
parentId: 'root',
|
||||||
contexts: ['all'],
|
contexts: ['all'],
|
||||||
title: i18nService.autoFill
|
title: bg_i18nService.autoFill
|
||||||
}, function () {
|
}, function () {
|
||||||
if (utilsService.isFirefox()) {
|
if (bg_utilsService.isFirefox()) {
|
||||||
// Firefox does not support writing to the clipboard from background
|
// Firefox does not support writing to the clipboard from background
|
||||||
buildingContextMenu = false;
|
buildingContextMenu = false;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
@ -160,14 +161,14 @@ function buildContextMenu(callback) {
|
|||||||
id: 'copy-username',
|
id: 'copy-username',
|
||||||
parentId: 'root',
|
parentId: 'root',
|
||||||
contexts: ['all'],
|
contexts: ['all'],
|
||||||
title: i18nService.copyUsername
|
title: bg_i18nService.copyUsername
|
||||||
}, function () {
|
}, function () {
|
||||||
chrome.contextMenus.create({
|
chrome.contextMenus.create({
|
||||||
type: 'normal',
|
type: 'normal',
|
||||||
id: 'copy-password',
|
id: 'copy-password',
|
||||||
parentId: 'root',
|
parentId: 'root',
|
||||||
contexts: ['all'],
|
contexts: ['all'],
|
||||||
title: i18nService.copyPassword
|
title: bg_i18nService.copyPassword
|
||||||
}, function () {
|
}, function () {
|
||||||
chrome.contextMenus.create({
|
chrome.contextMenus.create({
|
||||||
type: 'separator',
|
type: 'separator',
|
||||||
@ -179,7 +180,7 @@ function buildContextMenu(callback) {
|
|||||||
id: 'generate-password',
|
id: 'generate-password',
|
||||||
parentId: 'root',
|
parentId: 'root',
|
||||||
contexts: ['all'],
|
contexts: ['all'],
|
||||||
title: i18nService.generatePasswordCopied
|
title: bg_i18nService.generatePasswordCopied
|
||||||
}, function () {
|
}, function () {
|
||||||
buildingContextMenu = false;
|
buildingContextMenu = false;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
@ -203,7 +204,7 @@ chrome.tabs.onReplaced.addListener(function (addedTabId, removedTabId) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onReplacedRan = true;
|
onReplacedRan = true;
|
||||||
checkLoginsToAdd();
|
checkbg_loginsToAdd();
|
||||||
refreshBadgeAndMenu();
|
refreshBadgeAndMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -213,7 +214,7 @@ chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onUpdatedRan = true;
|
onUpdatedRan = true;
|
||||||
checkLoginsToAdd();
|
checkbg_loginsToAdd();
|
||||||
refreshBadgeAndMenu();
|
refreshBadgeAndMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -236,8 +237,8 @@ function refreshBadgeAndMenu() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.storage.local.get(constantsService.disableContextMenuItemKey, function (obj) {
|
chrome.storage.local.get(bg_constantsService.disableContextMenuItemKey, function (obj) {
|
||||||
if (!obj[constantsService.disableContextMenuItemKey]) {
|
if (!obj[bg_constantsService.disableContextMenuItemKey]) {
|
||||||
buildContextMenu(function () {
|
buildContextMenu(function () {
|
||||||
contextMenuReady(tab, true);
|
contextMenuReady(tab, true);
|
||||||
});
|
});
|
||||||
@ -260,7 +261,7 @@ function loadMenuAndUpdateBadge(url, tabId, contextMenuEnabled) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabDomain = utilsService.getDomain(url);
|
var tabDomain = bg_utilsService.getDomain(url);
|
||||||
if (!tabDomain) {
|
if (!tabDomain) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -268,7 +269,7 @@ function loadMenuAndUpdateBadge(url, tabId, contextMenuEnabled) {
|
|||||||
chrome.browserAction.setBadgeBackgroundColor({ color: '#294e5f' });
|
chrome.browserAction.setBadgeBackgroundColor({ color: '#294e5f' });
|
||||||
|
|
||||||
menuOptionsLoaded = [];
|
menuOptionsLoaded = [];
|
||||||
loginService.getAllDecryptedForDomain(tabDomain).then(function (logins) {
|
bg_loginService.getAllDecryptedForDomain(tabDomain).then(function (logins) {
|
||||||
sortLogins(logins);
|
sortLogins(logins);
|
||||||
|
|
||||||
if (contextMenuEnabled) {
|
if (contextMenuEnabled) {
|
||||||
@ -291,7 +292,7 @@ function loadMenuAndUpdateBadge(url, tabId, contextMenuEnabled) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (contextMenuEnabled) {
|
if (contextMenuEnabled) {
|
||||||
loadNoLoginsContextMenuOptions(i18nService.noMatchingLogins);
|
loadNoLoginsContextMenuOptions(bg_i18nService.noMatchingLogins);
|
||||||
}
|
}
|
||||||
chrome.browserAction.setBadgeText({
|
chrome.browserAction.setBadgeText({
|
||||||
text: '',
|
text: '',
|
||||||
@ -300,7 +301,7 @@ function loadMenuAndUpdateBadge(url, tabId, contextMenuEnabled) {
|
|||||||
}
|
}
|
||||||
}, function () {
|
}, function () {
|
||||||
if (contextMenuEnabled) {
|
if (contextMenuEnabled) {
|
||||||
loadNoLoginsContextMenuOptions(i18nService.vaultLocked);
|
loadNoLoginsContextMenuOptions(bg_i18nService.vaultLocked);
|
||||||
}
|
}
|
||||||
chrome.browserAction.setBadgeText({
|
chrome.browserAction.setBadgeText({
|
||||||
text: '',
|
text: '',
|
||||||
@ -315,8 +316,8 @@ chrome.contextMenus.onClicked.addListener(function (info, tab) {
|
|||||||
hitType: 'event',
|
hitType: 'event',
|
||||||
eventAction: 'Generated Password From Context Menu'
|
eventAction: 'Generated Password From Context Menu'
|
||||||
});
|
});
|
||||||
passwordGenerationService.getOptions().then(function (options) {
|
bg_passwordGenerationService.getOptions().then(function (options) {
|
||||||
var password = passwordGenerationService.generatePassword(options);
|
var password = bg_passwordGenerationService.generatePassword(options);
|
||||||
copyToClipboard(password);
|
copyToClipboard(password);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -327,7 +328,7 @@ chrome.contextMenus.onClicked.addListener(function (info, tab) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginService.getAllDecrypted().then(function (logins) {
|
bg_loginService.getAllDecrypted().then(function (logins) {
|
||||||
for (var i = 0; i < logins.length; i++) {
|
for (var i = 0; i < logins.length; i++) {
|
||||||
if (logins[i].id === id) {
|
if (logins[i].id === id) {
|
||||||
if (info.parentMenuItemId === 'autofill') {
|
if (info.parentMenuItemId === 'autofill') {
|
||||||
@ -400,12 +401,12 @@ function collectPageDetailsForContentScript(tab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addLogin(login, tab) {
|
function addLogin(login, tab) {
|
||||||
var loginDomain = utilsService.getDomain(login.url);
|
var loginDomain = bg_utilsService.getDomain(login.url);
|
||||||
if (!loginDomain) {
|
if (!loginDomain) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginService.getAllDecryptedForDomain(loginDomain).then(function (logins) {
|
bg_loginService.getAllDecryptedForDomain(loginDomain).then(function (logins) {
|
||||||
var match = false;
|
var match = false;
|
||||||
for (var i = 0; i < logins.length; i++) {
|
for (var i = 0; i < logins.length; i++) {
|
||||||
if (logins[i].username === login.username) {
|
if (logins[i].username === login.username) {
|
||||||
@ -418,7 +419,7 @@ function addLogin(login, tab) {
|
|||||||
// remove any old logins for this tab
|
// remove any old logins for this tab
|
||||||
removeAddLogin(tab);
|
removeAddLogin(tab);
|
||||||
|
|
||||||
loginsToAdd.push({
|
bg_loginsToAdd.push({
|
||||||
username: login.username,
|
username: login.username,
|
||||||
password: login.password,
|
password: login.password,
|
||||||
name: loginDomain,
|
name: loginDomain,
|
||||||
@ -427,15 +428,15 @@ function addLogin(login, tab) {
|
|||||||
tabId: tab.id,
|
tabId: tab.id,
|
||||||
expires: new Date((new Date()).getTime() + 30 * 60000) // 30 minutes
|
expires: new Date((new Date()).getTime() + 30 * 60000) // 30 minutes
|
||||||
});
|
});
|
||||||
checkLoginsToAdd(tab);
|
checkbg_loginsToAdd(tab);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastCleanupLoginCheck = null;
|
var lastCleanupLoginCheck = null;
|
||||||
cleanupLoginsToAdd();
|
cleanupbg_loginsToAdd();
|
||||||
setInterval(cleanupLoginsToAdd, 2 * 60 * 1000); // check every 2 minutes
|
setInterval(cleanupbg_loginsToAdd, 2 * 60 * 1000); // check every 2 minutes
|
||||||
function cleanupLoginsToAdd() {
|
function cleanupbg_loginsToAdd() {
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
if (lastCleanupLoginCheck && (now - lastCleanupLoginCheck) < 10000) {
|
if (lastCleanupLoginCheck && (now - lastCleanupLoginCheck) < 10000) {
|
||||||
// can only check cleanup every 10 seconds
|
// can only check cleanup every 10 seconds
|
||||||
@ -443,30 +444,30 @@ function cleanupLoginsToAdd() {
|
|||||||
}
|
}
|
||||||
lastCleanupLoginCheck = now;
|
lastCleanupLoginCheck = now;
|
||||||
|
|
||||||
for (var i = loginsToAdd.length - 1; i >= 0; i--) {
|
for (var i = bg_loginsToAdd.length - 1; i >= 0; i--) {
|
||||||
if (loginsToAdd[i].expires < now) {
|
if (bg_loginsToAdd[i].expires < now) {
|
||||||
loginsToAdd.splice(i, 1);
|
bg_loginsToAdd.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAddLogin(tab) {
|
function removeAddLogin(tab) {
|
||||||
for (var i = loginsToAdd.length - 1; i >= 0; i--) {
|
for (var i = bg_loginsToAdd.length - 1; i >= 0; i--) {
|
||||||
if (loginsToAdd[i].tabId === tab.id) {
|
if (bg_loginsToAdd[i].tabId === tab.id) {
|
||||||
loginsToAdd.splice(i, 1);
|
bg_loginsToAdd.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveAddLogin(tab) {
|
function saveAddLogin(tab) {
|
||||||
for (var i = loginsToAdd.length - 1; i >= 0; i--) {
|
for (var i = bg_loginsToAdd.length - 1; i >= 0; i--) {
|
||||||
if (loginsToAdd[i].tabId === tab.id) {
|
if (bg_loginsToAdd[i].tabId === tab.id) {
|
||||||
var loginToAdd = loginsToAdd[i];
|
var loginToAdd = bg_loginsToAdd[i];
|
||||||
|
|
||||||
var tabDomain = utilsService.getDomain(tab.url);
|
var tabDomain = bg_utilsService.getDomain(tab.url);
|
||||||
if (tabDomain && tabDomain === loginToAdd.domain) {
|
if (tabDomain && tabDomain === loginToAdd.domain) {
|
||||||
loginsToAdd.splice(i, 1);
|
bg_loginsToAdd.splice(i, 1);
|
||||||
loginService.encrypt({
|
bg_loginService.encrypt({
|
||||||
id: null,
|
id: null,
|
||||||
folderId: null,
|
folderId: null,
|
||||||
favorite: false,
|
favorite: false,
|
||||||
@ -477,7 +478,7 @@ function saveAddLogin(tab) {
|
|||||||
notes: null
|
notes: null
|
||||||
}).then(function (loginModel) {
|
}).then(function (loginModel) {
|
||||||
var login = new Login(loginModel, true);
|
var login = new Login(loginModel, true);
|
||||||
loginService.saveWithServer(login).then(function (login) {
|
bg_loginService.saveWithServer(login).then(function (login) {
|
||||||
ga('send', {
|
ga('send', {
|
||||||
hitType: 'event',
|
hitType: 'event',
|
||||||
eventAction: 'Added Login from Notification Bar'
|
eventAction: 'Added Login from Notification Bar'
|
||||||
@ -491,23 +492,23 @@ function saveAddLogin(tab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveNever(tab) {
|
function saveNever(tab) {
|
||||||
for (var i = loginsToAdd.length - 1; i >= 0; i--) {
|
for (var i = bg_loginsToAdd.length - 1; i >= 0; i--) {
|
||||||
if (loginsToAdd[i].tabId === tab.id) {
|
if (bg_loginsToAdd[i].tabId === tab.id) {
|
||||||
var loginToAdd = loginsToAdd[i];
|
var loginToAdd = bg_loginsToAdd[i];
|
||||||
|
|
||||||
var tabDomain = utilsService.getDomain(tab.url);
|
var tabDomain = bg_utilsService.getDomain(tab.url);
|
||||||
if (tabDomain && tabDomain === loginToAdd.domain) {
|
if (tabDomain && tabDomain === loginToAdd.domain) {
|
||||||
loginsToAdd.splice(i, 1);
|
bg_loginsToAdd.splice(i, 1);
|
||||||
var hostname = utilsService.getHostname(tab.url);
|
var hostname = bg_utilsService.getHostname(tab.url);
|
||||||
loginService.saveNeverDomain(hostname);
|
bg_loginService.saveNeverDomain(hostname);
|
||||||
messageTab(tab.id, 'closeNotificationBar');
|
messageTab(tab.id, 'closeNotificationBar');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkLoginsToAdd(tab, callback) {
|
function checkbg_loginsToAdd(tab, callback) {
|
||||||
if (!loginsToAdd.length) {
|
if (!bg_loginsToAdd.length) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
@ -534,7 +535,7 @@ function checkLoginsToAdd(tab, callback) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabDomain = utilsService.getDomain(tab.url);
|
var tabDomain = bg_utilsService.getDomain(tab.url);
|
||||||
if (!tabDomain) {
|
if (!tabDomain) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
@ -542,8 +543,8 @@ function checkLoginsToAdd(tab, callback) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < loginsToAdd.length; i++) {
|
for (var i = 0; i < bg_loginsToAdd.length; i++) {
|
||||||
if (loginsToAdd[i].tabId === tab.id && loginsToAdd[i].domain === tabDomain) {
|
if (bg_loginsToAdd[i].tabId === tab.id && bg_loginsToAdd[i].domain === tabDomain) {
|
||||||
messageTab(tab.id, 'openNotificationBar', {
|
messageTab(tab.id, 'openNotificationBar', {
|
||||||
type: 'add'
|
type: 'add'
|
||||||
}, function () {
|
}, function () {
|
||||||
@ -598,8 +599,8 @@ function autofillPage() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fillScript = autofillService.generateFillScript(pageDetailsToAutoFill[i].details, loginToAutoFill.username,
|
var fillScript = bg_autofillService.generateFillScript(pageDetailsToAutoFill[i].details,
|
||||||
loginToAutoFill.password);
|
loginToAutoFill.username, loginToAutoFill.password);
|
||||||
if (tabId && fillScript && fillScript.script && fillScript.script.length) {
|
if (tabId && fillScript && fillScript.script && fillScript.script.length) {
|
||||||
chrome.tabs.sendMessage(tabId, {
|
chrome.tabs.sendMessage(tabId, {
|
||||||
command: 'fillForm',
|
command: 'fillForm',
|
||||||
@ -658,7 +659,7 @@ function loadContextMenuOptions(title, idSuffix, login) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utilsService.isFirefox()) {
|
if (bg_utilsService.isFirefox()) {
|
||||||
// Firefox does not support writing to the clipboard from background
|
// Firefox does not support writing to the clipboard from background
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -686,14 +687,14 @@ function loadContextMenuOptions(title, idSuffix, login) {
|
|||||||
|
|
||||||
// TODO: Fix callback hell by moving to promises
|
// TODO: Fix callback hell by moving to promises
|
||||||
function logout(expired, callback) {
|
function logout(expired, callback) {
|
||||||
userService.getUserId(function (userId) {
|
bg_userService.getUserId(function (userId) {
|
||||||
syncService.setLastSync(new Date(0), function () {
|
bg_syncService.setLastSync(new Date(0), function () {
|
||||||
settingsService.clear(function () {
|
bg_settingsService.clear(function () {
|
||||||
tokenService.clearToken(function () {
|
bg_tokenService.clearToken(function () {
|
||||||
cryptoService.clearKeys(function () {
|
bg_cryptoService.clearKeys(function () {
|
||||||
userService.clear(function () {
|
bg_userService.clear(function () {
|
||||||
loginService.clear(userId, function () {
|
bg_loginService.clear(userId, function () {
|
||||||
folderService.clear(userId, function () {
|
bg_folderService.clear(userId, function () {
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
command: 'doneLoggingOut', expired: expired
|
command: 'doneLoggingOut', expired: expired
|
||||||
});
|
});
|
||||||
@ -753,9 +754,9 @@ function fullSync(override) {
|
|||||||
lastSyncCheck = now;
|
lastSyncCheck = now;
|
||||||
|
|
||||||
override = override || false;
|
override = override || false;
|
||||||
syncService.getLastSync(function (lastSync) {
|
bg_syncService.getLastSync(function (lastSync) {
|
||||||
if (override || !lastSync || (now - lastSync) >= syncInternal) {
|
if (override || !lastSync || (now - lastSync) >= syncInternal) {
|
||||||
syncService.fullSync(override || false, function () {
|
bg_syncService.fullSync(override || false, function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,7 @@ var CipherString = function () {
|
|||||||
this.initializationVector = null;
|
this.initializationVector = null;
|
||||||
this.mac = null;
|
this.mac = null;
|
||||||
|
|
||||||
var constants = chrome.extension.getBackgroundPage().constantsService;
|
var constants = chrome.extension.getBackgroundPage().bg_constantsService;
|
||||||
|
|
||||||
if (arguments.length >= 2) {
|
if (arguments.length >= 2) {
|
||||||
// ct and header
|
// ct and header
|
||||||
@ -130,7 +130,7 @@ var Folder = function (obj, alreadyEncrypted) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var cryptoService = chrome.extension.getBackgroundPage().cryptoService;
|
var cryptoService = chrome.extension.getBackgroundPage().bg_cryptoService;
|
||||||
return cryptoService.getOrgKey(orgId).then(function (orgKey) {
|
return cryptoService.getOrgKey(orgId).then(function (orgKey) {
|
||||||
return cryptoService.decrypt(self, orgKey);
|
return cryptoService.decrypt(self, orgKey);
|
||||||
}).then(function (decValue) {
|
}).then(function (decValue) {
|
||||||
@ -162,7 +162,7 @@ var Folder = function (obj, alreadyEncrypted) {
|
|||||||
}).then(function (val) {
|
}).then(function (val) {
|
||||||
model.uri = val;
|
model.uri = val;
|
||||||
|
|
||||||
var utilsService = chrome.extension.getBackgroundPage().utilsService;
|
var utilsService = chrome.extension.getBackgroundPage().bg_utilsService;
|
||||||
model.domain = utilsService.getDomain(val);
|
model.domain = utilsService.getDomain(val);
|
||||||
|
|
||||||
if (self.username) {
|
if (self.username) {
|
||||||
|
@ -6,6 +6,19 @@
|
|||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
utilsService.initListSectionItemListeners($(document), angular);
|
utilsService.initListSectionItemListeners($(document), angular);
|
||||||
|
|
||||||
|
var u2f = new U2f(function (data) {
|
||||||
|
$scope.login(data);
|
||||||
|
$scope.$apply();
|
||||||
|
}, function (error) {
|
||||||
|
toastr.error(error, i18nService.errorsOccurred);
|
||||||
|
$scope.$apply();
|
||||||
|
}, function (info) {
|
||||||
|
if (info === 'ready') {
|
||||||
|
$scope.u2fReady = true;
|
||||||
|
}
|
||||||
|
$scope.$apply();
|
||||||
|
});
|
||||||
|
|
||||||
var constants = constantsService;
|
var constants = constantsService;
|
||||||
var email = $stateParams.email;
|
var email = $stateParams.email;
|
||||||
var masterPassword = $stateParams.masterPassword;
|
var masterPassword = $stateParams.masterPassword;
|
||||||
@ -31,7 +44,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scope.providerType === constants.twoFactorProvider.email ||
|
if ($scope.providerType === constants.twoFactorProvider.u2f) {
|
||||||
|
if (u2f) {
|
||||||
|
u2f.stop();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ($scope.providerType === constants.twoFactorProvider.email ||
|
||||||
$scope.providerType === constants.twoFactorProvider.authenticator) {
|
$scope.providerType === constants.twoFactorProvider.authenticator) {
|
||||||
token = token.replace(' ', '')
|
token = token.replace(' ', '')
|
||||||
}
|
}
|
||||||
@ -40,6 +61,9 @@
|
|||||||
$scope.loginPromise.then(function () {
|
$scope.loginPromise.then(function () {
|
||||||
$analytics.eventTrack('Logged In From Two-step');
|
$analytics.eventTrack('Logged In From Two-step');
|
||||||
$state.go('tabs.vault', { animation: 'in-slide-left', syncOnLoad: true });
|
$state.go('tabs.vault', { animation: 'in-slide-left', syncOnLoad: true });
|
||||||
|
u2f = null;
|
||||||
|
}, function () {
|
||||||
|
u2f.start();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,7 +91,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.anotherMethod = function () {
|
$scope.anotherMethod = function () {
|
||||||
$analytics.eventTrack('Selected Another Two Factor Method');
|
u2f.stop();
|
||||||
|
u2f = null;
|
||||||
$state.go('twoFactorMethods', {
|
$state.go('twoFactorMethods', {
|
||||||
animation: 'in-slide-up',
|
animation: 'in-slide-up',
|
||||||
email: email,
|
email: email,
|
||||||
@ -77,6 +102,14 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.back = function () {
|
||||||
|
u2f.stop();
|
||||||
|
u2f = null;
|
||||||
|
$state.go('login', {
|
||||||
|
animation: 'out-slide-right'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function getDefaultProvider(twoFactorProviders) {
|
function getDefaultProvider(twoFactorProviders) {
|
||||||
var keys = Object.keys(twoFactorProviders);
|
var keys = Object.keys(twoFactorProviders);
|
||||||
var providerType = null;
|
var providerType = null;
|
||||||
@ -97,6 +130,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
u2f.stop();
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
$('#code').focus();
|
$('#code').focus();
|
||||||
|
|
||||||
@ -116,19 +151,6 @@
|
|||||||
var params = providers[constants.twoFactorProvider.u2f];
|
var params = providers[constants.twoFactorProvider.u2f];
|
||||||
var challenges = JSON.parse(params.Challenges);
|
var challenges = JSON.parse(params.Challenges);
|
||||||
|
|
||||||
var u2f = new U2f(function (data) {
|
|
||||||
$scope.login(data);
|
|
||||||
$scope.$apply();
|
|
||||||
}, function (error) {
|
|
||||||
toastr.error(error, i18nService.errorsOccurred);
|
|
||||||
$scope.$apply();
|
|
||||||
}, function (info) {
|
|
||||||
if (info === 'ready') {
|
|
||||||
$scope.u2fReady = true;
|
|
||||||
}
|
|
||||||
$scope.$apply();
|
|
||||||
});
|
|
||||||
|
|
||||||
u2f.init({
|
u2f.init({
|
||||||
appId: challenges[0].appId,
|
appId: challenges[0].appId,
|
||||||
challenge: challenges[0].challenge,
|
challenge: challenges[0].challenge,
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
if (providers.hasOwnProperty(constants.twoFactorProvider.duo)) {
|
if (providers.hasOwnProperty(constants.twoFactorProvider.duo)) {
|
||||||
add(constants.twoFactorProvider.duo);
|
add(constants.twoFactorProvider.duo);
|
||||||
}
|
}
|
||||||
if (providers.hasOwnProperty(constants.twoFactorProvider.u2f) && (utilsService.isChrome() || !utilsService.isOpera())) {
|
if (providers.hasOwnProperty(constants.twoFactorProvider.u2f) && (utilsService.isChrome() || utilsService.isOpera())) {
|
||||||
add(constants.twoFactorProvider.u2f);
|
add(constants.twoFactorProvider.u2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
ng-if="providerType === constantsProvider.authenticator || providerType === constantsProvider.email">
|
ng-if="providerType === constantsProvider.authenticator || providerType === constantsProvider.email">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<a ui-sref="login({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> {{i18n.login}}</a>
|
<a href="#" ng-click="back()"><i class="fa fa-chevron-left"></i> {{i18n.login}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{i18n.continue}}</button>
|
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{i18n.continue}}</button>
|
||||||
@ -106,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="two-factor-key-page">
|
<div class="two-factor-key-page">
|
||||||
<iframe id="u2f_iframe" class="hide"></iframe>
|
<iframe id="u2f_iframe"></iframe>
|
||||||
<p ng-if="!u2fReady">Loading...</p>
|
<p ng-if="!u2fReady">Loading...</p>
|
||||||
<div ng-if="u2fReady">
|
<div ng-if="u2fReady">
|
||||||
<p>
|
<p>
|
||||||
|
@ -2,47 +2,47 @@
|
|||||||
.module('bit.services')
|
.module('bit.services')
|
||||||
|
|
||||||
.factory('tokenService', function () {
|
.factory('tokenService', function () {
|
||||||
return chrome.extension.getBackgroundPage().tokenService;
|
return chrome.extension.getBackgroundPage().bg_tokenService;
|
||||||
})
|
})
|
||||||
.factory('cryptoService', function () {
|
.factory('cryptoService', function () {
|
||||||
return chrome.extension.getBackgroundPage().cryptoService;
|
return chrome.extension.getBackgroundPage().bg_cryptoService;
|
||||||
})
|
})
|
||||||
.factory('userService', function () {
|
.factory('userService', function () {
|
||||||
return chrome.extension.getBackgroundPage().userService;
|
return chrome.extension.getBackgroundPage().bg_userService;
|
||||||
})
|
})
|
||||||
.factory('apiService', function () {
|
.factory('apiService', function () {
|
||||||
return chrome.extension.getBackgroundPage().apiService;
|
return chrome.extension.getBackgroundPage().bg_apiService;
|
||||||
})
|
})
|
||||||
.factory('folderService', function () {
|
.factory('folderService', function () {
|
||||||
return chrome.extension.getBackgroundPage().folderService;
|
return chrome.extension.getBackgroundPage().bg_folderService;
|
||||||
})
|
})
|
||||||
.factory('loginService', function () {
|
.factory('loginService', function () {
|
||||||
return chrome.extension.getBackgroundPage().loginService;
|
return chrome.extension.getBackgroundPage().bg_loginService;
|
||||||
})
|
})
|
||||||
.factory('syncService', function () {
|
.factory('syncService', function () {
|
||||||
return chrome.extension.getBackgroundPage().syncService;
|
return chrome.extension.getBackgroundPage().bg_syncService;
|
||||||
})
|
})
|
||||||
.factory('autofillService', function () {
|
.factory('autofillService', function () {
|
||||||
return chrome.extension.getBackgroundPage().autofillService;
|
return chrome.extension.getBackgroundPage().bg_autofillService;
|
||||||
})
|
})
|
||||||
.factory('passwordGenerationService', function () {
|
.factory('passwordGenerationService', function () {
|
||||||
return chrome.extension.getBackgroundPage().passwordGenerationService;
|
return chrome.extension.getBackgroundPage().bg_passwordGenerationService;
|
||||||
})
|
})
|
||||||
.factory('utilsService', function () {
|
.factory('utilsService', function () {
|
||||||
return chrome.extension.getBackgroundPage().utilsService;
|
return chrome.extension.getBackgroundPage().bg_utilsService;
|
||||||
})
|
})
|
||||||
.factory('appIdService', function () {
|
.factory('appIdService', function () {
|
||||||
return chrome.extension.getBackgroundPage().appIdService;
|
return chrome.extension.getBackgroundPage().bg_appIdService;
|
||||||
})
|
})
|
||||||
.factory('i18nService', function () {
|
.factory('i18nService', function () {
|
||||||
return chrome.extension.getBackgroundPage().i18nService;
|
return chrome.extension.getBackgroundPage().bg_i18nService;
|
||||||
})
|
})
|
||||||
.factory('constantsService', function () {
|
.factory('constantsService', function () {
|
||||||
return chrome.extension.getBackgroundPage().constantsService;
|
return chrome.extension.getBackgroundPage().bg_constantsService;
|
||||||
})
|
})
|
||||||
.factory('settingsService', function () {
|
.factory('settingsService', function () {
|
||||||
return chrome.extension.getBackgroundPage().settingsService;
|
return chrome.extension.getBackgroundPage().bg_settingsService;
|
||||||
})
|
})
|
||||||
.factory('lockService', function () {
|
.factory('lockService', function () {
|
||||||
return chrome.extension.getBackgroundPage().lockService;
|
return chrome.extension.getBackgroundPage().bg_lockService;
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
var gaTrackingId = chrome.extension.getBackgroundPage().utilsService.analyticsId();
|
var gaTrackingId = chrome.extension.getBackgroundPage().bg_utilsService.analyticsId();
|
||||||
var gaFunc = null;
|
var gaFunc = null;
|
||||||
var isFirefox = chrome.extension.getBackgroundPage().utilsService.isFirefox();
|
var isFirefox = chrome.extension.getBackgroundPage().bg_utilsService.isFirefox();
|
||||||
|
|
||||||
window.GoogleAnalyticsObject = 'ga';
|
window.GoogleAnalyticsObject = 'ga';
|
||||||
window[window.GoogleAnalyticsObject] = function (action, param1, param2, param3, param4) {
|
window[window.GoogleAnalyticsObject] = function (action, param1, param2, param3, param4) {
|
||||||
@ -30,7 +30,7 @@ function gaTrackPageView(pagePath) {
|
|||||||
return '&t=pageview&dp=' + encodeURIComponent(pagePath);
|
return '&t=pageview&dp=' + encodeURIComponent(pagePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.extension.getBackgroundPage().appIdService.getAnonymousAppId(function (gaAnonAppId) {
|
chrome.extension.getBackgroundPage().bg_appIdService.getAnonymousAppId(function (gaAnonAppId) {
|
||||||
gaFunc = function (action, param1, param2, param3, param4) {
|
gaFunc = function (action, param1, param2, param3, param4) {
|
||||||
if (action !== 'send' || !param1) {
|
if (action !== 'send' || !param1) {
|
||||||
return;
|
return;
|
||||||
|
@ -17,7 +17,7 @@ function initFolderService() {
|
|||||||
id: folder.id
|
id: folder.id
|
||||||
};
|
};
|
||||||
|
|
||||||
return cryptoService.encrypt(folder.name).then(function (cs) {
|
return self.cryptoService.encrypt(folder.name).then(function (cs) {
|
||||||
model.name = cs;
|
model.name = cs;
|
||||||
return model;
|
return model;
|
||||||
});
|
});
|
||||||
@ -68,7 +68,7 @@ function initFolderService() {
|
|||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
cryptoService.getKey().then(function (key) {
|
self.cryptoService.getKey().then(function (key) {
|
||||||
if (!key) {
|
if (!key) {
|
||||||
deferred.reject();
|
deferred.reject();
|
||||||
return;
|
return;
|
||||||
@ -122,7 +122,7 @@ function initFolderService() {
|
|||||||
|
|
||||||
function apiSuccess(response) {
|
function apiSuccess(response) {
|
||||||
folder.id = response.id;
|
folder.id = response.id;
|
||||||
userService.getUserId(function (userId) {
|
self.userService.getUserId(function (userId) {
|
||||||
var data = new FolderData(response, userId);
|
var data = new FolderData(response, userId);
|
||||||
self.upsert(data, function () {
|
self.upsert(data, function () {
|
||||||
deferred.resolve(folder);
|
deferred.resolve(folder);
|
||||||
@ -140,7 +140,7 @@ function initFolderService() {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
userService.getUserId(function (userId) {
|
self.userService.getUserId(function (userId) {
|
||||||
var foldersKey = 'folders_' + userId;
|
var foldersKey = 'folders_' + userId;
|
||||||
|
|
||||||
chrome.storage.local.get(foldersKey, function (obj) {
|
chrome.storage.local.get(foldersKey, function (obj) {
|
||||||
@ -175,7 +175,7 @@ function initFolderService() {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
userService.getUserId(function (userId) {
|
self.userService.getUserId(function (userId) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj['folders_' + userId] = folders;
|
obj['folders_' + userId] = folders;
|
||||||
chrome.storage.local.set(obj, function () {
|
chrome.storage.local.set(obj, function () {
|
||||||
@ -205,7 +205,7 @@ function initFolderService() {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
userService.getUserId(function (userId) {
|
self.userService.getUserId(function (userId) {
|
||||||
var foldersKey = 'folders_' + userId;
|
var foldersKey = 'folders_' + userId;
|
||||||
|
|
||||||
chrome.storage.local.get(foldersKey, function (obj) {
|
chrome.storage.local.get(foldersKey, function (obj) {
|
||||||
|
@ -87,7 +87,7 @@ function initLockService(self) {
|
|||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
|
||||||
chrome.storage.local.get(self.constantsService.lockOptionKey, function (obj) {
|
chrome.storage.local.get(self.constantsService.lockOptionKey, function (obj) {
|
||||||
if (obj && obj[constantsService.lockOptionKey] === 0 || obj[constantsService.lockOptionKey]) {
|
if (obj && obj[self.constantsService.lockOptionKey] === 0 || obj[self.constantsService.lockOptionKey]) {
|
||||||
deferred.resolve(parseInt(obj[self.constantsService.lockOptionKey]));
|
deferred.resolve(parseInt(obj[self.constantsService.lockOptionKey]));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -102,8 +102,8 @@ function initLockService(self) {
|
|||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
|
||||||
chrome.storage.local.get(self.constantsService.lastActiveKey, function (obj) {
|
chrome.storage.local.get(self.constantsService.lastActiveKey, function (obj) {
|
||||||
if (obj && obj[constantsService.lastActiveKey]) {
|
if (obj && obj[self.constantsService.lastActiveKey]) {
|
||||||
deferred.resolve(obj[constantsService.lastActiveKey]);
|
deferred.resolve(obj[self.constantsService.lastActiveKey]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
deferred.reject();
|
deferred.reject();
|
||||||
|
@ -14,6 +14,8 @@ function initLoginService() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
LoginService.prototype.encrypt = function (login) {
|
LoginService.prototype.encrypt = function (login) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
var model = {
|
var model = {
|
||||||
id: login.id,
|
id: login.id,
|
||||||
folderId: login.folderId,
|
folderId: login.folderId,
|
||||||
@ -22,21 +24,21 @@ function initLoginService() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var orgKey = null;
|
var orgKey = null;
|
||||||
return cryptoService.getOrgKey(login.organizationId).then(function (key) {
|
return self.cryptoService.getOrgKey(login.organizationId).then(function (key) {
|
||||||
orgKey = key;
|
orgKey = key;
|
||||||
return cryptoService.encrypt(login.name, orgKey);
|
return self.cryptoService.encrypt(login.name, orgKey);
|
||||||
}).then(function (cs) {
|
}).then(function (cs) {
|
||||||
model.name = cs;
|
model.name = cs;
|
||||||
return cryptoService.encrypt(login.uri, orgKey);
|
return self.cryptoService.encrypt(login.uri, orgKey);
|
||||||
}).then(function (cs) {
|
}).then(function (cs) {
|
||||||
model.uri = cs;
|
model.uri = cs;
|
||||||
return cryptoService.encrypt(login.username, orgKey);
|
return self.cryptoService.encrypt(login.username, orgKey);
|
||||||
}).then(function (cs) {
|
}).then(function (cs) {
|
||||||
model.username = cs;
|
model.username = cs;
|
||||||
return cryptoService.encrypt(login.password, orgKey);
|
return self.cryptoService.encrypt(login.password, orgKey);
|
||||||
}).then(function (cs) {
|
}).then(function (cs) {
|
||||||
model.password = cs;
|
model.password = cs;
|
||||||
return cryptoService.encrypt(login.notes, orgKey);
|
return self.cryptoService.encrypt(login.notes, orgKey);
|
||||||
}).then(function (cs) {
|
}).then(function (cs) {
|
||||||
model.notes = cs;
|
model.notes = cs;
|
||||||
return model;
|
return model;
|
||||||
@ -91,7 +93,7 @@ function initLoginService() {
|
|||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
cryptoService.getKey().then(function (key) {
|
self.cryptoService.getKey().then(function (key) {
|
||||||
if (!key) {
|
if (!key) {
|
||||||
deferred.reject();
|
deferred.reject();
|
||||||
return;
|
return;
|
||||||
@ -209,7 +211,7 @@ function initLoginService() {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
userService.getUserId(function (userId) {
|
self.userService.getUserId(function (userId) {
|
||||||
var loginsKey = 'sites_' + userId;
|
var loginsKey = 'sites_' + userId;
|
||||||
|
|
||||||
chrome.storage.local.get(loginsKey, function (obj) {
|
chrome.storage.local.get(loginsKey, function (obj) {
|
||||||
@ -244,7 +246,7 @@ function initLoginService() {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
userService.getUserId(function (userId) {
|
self.userService.getUserId(function (userId) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj['sites_' + userId] = logins;
|
obj['sites_' + userId] = logins;
|
||||||
chrome.storage.local.set(obj, function () {
|
chrome.storage.local.set(obj, function () {
|
||||||
@ -274,7 +276,7 @@ function initLoginService() {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
userService.getUserId(function (userId) {
|
self.userService.getUserId(function (userId) {
|
||||||
var loginsKey = 'sites_' + userId;
|
var loginsKey = 'sites_' + userId;
|
||||||
|
|
||||||
chrome.storage.local.get(loginsKey, function (obj) {
|
chrome.storage.local.get(loginsKey, function (obj) {
|
||||||
|
Loading…
Reference in New Issue
Block a user