diff --git a/src/background.html b/src/background.html
index 6f9e86d4cb..820ba065e4 100644
--- a/src/background.html
+++ b/src/background.html
@@ -24,6 +24,7 @@
+
diff --git a/src/background.js b/src/background.js
index 18afd4e288..37e02436af 100644
--- a/src/background.js
+++ b/src/background.js
@@ -1,5 +1,11 @@
-var isBackground = true;
+var isBackground = true,
+ loginToAutoFill = null,
+ pageDetailsToAutoFill = [],
+ autofillTimeout = null,
+ menuOptionsLoaded = [];
+
var bg_loginsToAdd = [];
+
var bg_utilsService = new UtilsService();
var bg_i18nService = new i18nService(bg_utilsService);
var bg_constantsService = new ConstantsService(bg_i18nService);
@@ -7,6 +13,7 @@ var bg_cryptoService = new CryptoService(bg_constantsService);
var bg_tokenService = new TokenService();
var bg_appIdService = new AppIdService();
var bg_apiService = new ApiService(bg_tokenService, bg_appIdService, bg_utilsService, bg_constantsService, logout);
+var bg_environmentService = new EnvironmentService(bg_constantsService, bg_apiService);
var bg_userService = new UserService(bg_tokenService, bg_apiService, bg_cryptoService);
var bg_settingsService = new SettingsService(bg_userService);
var bg_loginService = new LoginService(bg_cryptoService, bg_userService, bg_apiService, bg_settingsService);
@@ -45,11 +52,6 @@ if (chrome.commands) {
});
}
-var loginToAutoFill = null,
- pageDetailsToAutoFill = [],
- autofillTimeout = null,
- menuOptionsLoaded = [];
-
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
if (msg.command === 'loggedIn' || msg.command === 'unlocked' || msg.command === 'locked') {
setIcon();
@@ -108,28 +110,6 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
}
});
-setIcon();
-function setIcon() {
- bg_userService.isAuthenticated(function (isAuthenticated) {
- bg_cryptoService.getKey().then(function (key) {
- var suffix = '';
- if (!isAuthenticated) {
- suffix = '_gray';
- }
- else if (!key) {
- suffix = '_locked';
- }
-
- chrome.browserAction.setIcon({
- path: {
- '19': 'images/icon19' + suffix + '.png',
- '38': 'images/icon38' + suffix + '.png',
- }
- });
- });
- });
-}
-
if (chrome.runtime.onInstalled) {
chrome.runtime.onInstalled.addListener(function (details) {
ga('send', {
@@ -143,6 +123,89 @@ if (chrome.runtime.onInstalled) {
});
}
+chrome.tabs.onActivated.addListener(function (activeInfo) {
+ refreshBadgeAndMenu();
+});
+
+var onReplacedRan = false;
+chrome.tabs.onReplaced.addListener(function (addedTabId, removedTabId) {
+ if (onReplacedRan) {
+ return;
+ }
+ onReplacedRan = true;
+ checkbg_loginsToAdd();
+ refreshBadgeAndMenu();
+});
+
+var onUpdatedRan = false;
+chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
+ if (onUpdatedRan) {
+ return;
+ }
+ onUpdatedRan = true;
+ checkbg_loginsToAdd();
+ refreshBadgeAndMenu();
+});
+
+chrome.windows.onFocusChanged.addListener(function (windowId) {
+ if (windowId === null || windowId < 0) {
+ return;
+ }
+
+ refreshBadgeAndMenu();
+});
+
+chrome.contextMenus.onClicked.addListener(function (info, tab) {
+ if (info.menuItemId === 'generate-password') {
+ ga('send', {
+ hitType: 'event',
+ eventAction: 'Generated Password From Context Menu'
+ });
+ bg_passwordGenerationService.getOptions().then(function (options) {
+ var password = bg_passwordGenerationService.generatePassword(options);
+ bg_utilsService.copyToClipboard(password);
+ });
+ }
+ else if (info.parentMenuItemId === 'autofill' || info.parentMenuItemId === 'copy-username' ||
+ info.parentMenuItemId === 'copy-password') {
+ var id = info.menuItemId.split('_')[1];
+ if (id === 'noop') {
+ return;
+ }
+
+ bg_loginService.getAllDecrypted().then(function (logins) {
+ for (var i = 0; i < logins.length; i++) {
+ if (logins[i].id === id) {
+ if (info.parentMenuItemId === 'autofill') {
+ ga('send', {
+ hitType: 'event',
+ eventAction: 'Autofilled From Context Menu'
+ });
+ startAutofillPage(logins[i]);
+ }
+ else if (info.parentMenuItemId === 'copy-username') {
+ ga('send', {
+ hitType: 'event',
+ eventAction: 'Copied Username From Context Menu'
+ });
+ bg_utilsService.copyToClipboard(logins[i].username);
+ }
+ else if (info.parentMenuItemId === 'copy-password') {
+ ga('send', {
+ hitType: 'event',
+ eventAction: 'Copied Password From Context Menu'
+ });
+ bg_utilsService.copyToClipboard(logins[i].password);
+ }
+ return;
+ }
+ }
+ }, function () {
+
+ });
+ }
+});
+
var buildingContextMenu = false;
function buildContextMenu(callback) {
if (buildingContextMenu) {
@@ -211,37 +274,26 @@ function buildContextMenu(callback) {
});
}
-chrome.tabs.onActivated.addListener(function (activeInfo) {
- refreshBadgeAndMenu();
-});
+function setIcon() {
+ bg_userService.isAuthenticated(function (isAuthenticated) {
+ bg_cryptoService.getKey().then(function (key) {
+ var suffix = '';
+ if (!isAuthenticated) {
+ suffix = '_gray';
+ }
+ else if (!key) {
+ suffix = '_locked';
+ }
-var onReplacedRan = false;
-chrome.tabs.onReplaced.addListener(function (addedTabId, removedTabId) {
- if (onReplacedRan) {
- return;
- }
- onReplacedRan = true;
- checkbg_loginsToAdd();
- refreshBadgeAndMenu();
-});
-
-var onUpdatedRan = false;
-chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
- if (onUpdatedRan) {
- return;
- }
- onUpdatedRan = true;
- checkbg_loginsToAdd();
- refreshBadgeAndMenu();
-});
-
-chrome.windows.onFocusChanged.addListener(function (windowId) {
- if (windowId === null || windowId < 0) {
- return;
- }
-
- refreshBadgeAndMenu();
-});
+ chrome.browserAction.setIcon({
+ path: {
+ '19': 'images/icon19' + suffix + '.png',
+ '38': 'images/icon38' + suffix + '.png',
+ }
+ });
+ });
+ });
+}
function refreshBadgeAndMenu() {
chrome.tabs.query({ active: true, windowId: chrome.windows.WINDOW_ID_CURRENT }, function (tabs) {
@@ -327,57 +379,6 @@ function loadMenuAndUpdateBadge(url, tabId, contextMenuEnabled) {
});
}
-chrome.contextMenus.onClicked.addListener(function (info, tab) {
- if (info.menuItemId === 'generate-password') {
- ga('send', {
- hitType: 'event',
- eventAction: 'Generated Password From Context Menu'
- });
- bg_passwordGenerationService.getOptions().then(function (options) {
- var password = bg_passwordGenerationService.generatePassword(options);
- bg_utilsService.copyToClipboard(password);
- });
- }
- else if (info.parentMenuItemId === 'autofill' || info.parentMenuItemId === 'copy-username' ||
- info.parentMenuItemId === 'copy-password') {
- var id = info.menuItemId.split('_')[1];
- if (id === 'noop') {
- return;
- }
-
- bg_loginService.getAllDecrypted().then(function (logins) {
- for (var i = 0; i < logins.length; i++) {
- if (logins[i].id === id) {
- if (info.parentMenuItemId === 'autofill') {
- ga('send', {
- hitType: 'event',
- eventAction: 'Autofilled From Context Menu'
- });
- startAutofillPage(logins[i]);
- }
- else if (info.parentMenuItemId === 'copy-username') {
- ga('send', {
- hitType: 'event',
- eventAction: 'Copied Username From Context Menu'
- });
- bg_utilsService.copyToClipboard(logins[i].username);
- }
- else if (info.parentMenuItemId === 'copy-password') {
- ga('send', {
- hitType: 'event',
- eventAction: 'Copied Password From Context Menu'
- });
- bg_utilsService.copyToClipboard(logins[i].password);
- }
- return;
- }
- }
- }, function () {
-
- });
- }
-});
-
function messageCurrentTab(command, data) {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
var tabId = null;
@@ -457,7 +458,6 @@ function addLogin(login, tab) {
});
}
-cleanupbg_loginsToAdd();
function cleanupbg_loginsToAdd() {
for (var i = bg_loginsToAdd.length - 1; i >= 0; i--) {
if (bg_loginsToAdd[i].expires < new Date()) {
@@ -679,9 +679,6 @@ function logout(expired, callback) {
});
}
-// Sync polling
-
-fullSync(true);
function fullSync(override) {
override = override || false;
bg_syncService.getLastSync(function (lastSync) {
@@ -695,3 +692,11 @@ function fullSync(override) {
});
setTimeout(fullSync, 5 * 60 * 1000); // check every 5 minutes
}
+
+// Bootstrap
+
+bg_environmentService.setUrlsFromStorage(function () {
+ setIcon();
+ cleanupbg_loginsToAdd();
+ fullSync(true);
+});
diff --git a/src/popup/app/accounts/accountsLoginTwoFactorController.js b/src/popup/app/accounts/accountsLoginTwoFactorController.js
index 04290c66c7..668f0fafde 100644
--- a/src/popup/app/accounts/accountsLoginTwoFactorController.js
+++ b/src/popup/app/accounts/accountsLoginTwoFactorController.js
@@ -2,20 +2,17 @@
.module('bit.accounts')
.controller('accountsLoginTwoFactorController', function ($scope, $state, authService, toastr, utilsService, SweetAlert,
- $analytics, i18nService, $stateParams, $filter, constantsService, $timeout, $window, cryptoService, apiService) {
+ $analytics, i18nService, $stateParams, $filter, constantsService, $timeout, $window, cryptoService, apiService,
+ environmentService) {
$scope.i18n = i18nService;
utilsService.initListSectionItemListeners($(document), angular);
var customWebVaultUrl = null;
- var storedBaseUrl = $window.localStorage.getItem(constantsService.baseUrlKey);
- if (storedBaseUrl) {
- customWebVaultUrl = storedBaseUrl;
+ if (environmentService.baseUrl) {
+ customWebVaultUrl = environmentService.baseUrl;
}
- else {
- var storedWebVaultUrl = $window.localStorage.getItem(constantsService.webVaultUrlKey);
- if (storedWebVaultUrl) {
- customWebVaultUrl = storedWebVaultUrl;
- }
+ else if (environmentService.webVaultUrl) {
+ customWebVaultUrl = environmentService.webVaultUrl;
}
var u2f = new U2f(customWebVaultUrl, function (data) {
diff --git a/src/popup/app/services/backgroundService.js b/src/popup/app/services/backgroundService.js
index 95ea4a7e43..06a1034220 100644
--- a/src/popup/app/services/backgroundService.js
+++ b/src/popup/app/services/backgroundService.js
@@ -48,4 +48,7 @@
})
.factory('totpService', function () {
return chrome.extension.getBackgroundPage().bg_totpService;
+ })
+ .factory('environmentService', function () {
+ return chrome.extension.getBackgroundPage().bg_environmentService;
});
diff --git a/src/popup/app/settings/settingsEnvironmentController.js b/src/popup/app/settings/settingsEnvironmentController.js
index 1fc6462df1..653f3c6356 100644
--- a/src/popup/app/settings/settingsEnvironmentController.js
+++ b/src/popup/app/settings/settingsEnvironmentController.js
@@ -1,60 +1,34 @@
angular
.module('bit.settings')
- .controller('settingsEnvironmentController', function ($scope, i18nService, $analytics, constantsService, utilsService,
- $window, apiService, toastr) {
+ .controller('settingsEnvironmentController', function ($scope, i18nService, $analytics, utilsService,
+ environmentService, toastr, $timeout) {
$scope.i18n = i18nService;
utilsService.initListSectionItemListeners($(document), angular);
- $scope.baseUrl = $window.localStorage.getItem(constantsService.baseUrlKey) || '';
- $scope.webVaultUrl = $window.localStorage.getItem(constantsService.webVaultUrlKey) || '';
- $scope.apiUrl = $window.localStorage.getItem(constantsService.apiUrlKey) || '';
- $scope.identityUrl = $window.localStorage.getItem(constantsService.identityUrlKey) || '';
+ $scope.baseUrl = environmentService.baseUrl || '';
+ $scope.webVaultUrl = environmentService.webVaultUrl || '';
+ $scope.apiUrl = environmentService.apiUrl || '';
+ $scope.identityUrl = environmentService.identityUrl || '';
$scope.save = function () {
- if ($scope.baseUrl && $scope.baseUrl !== '') {
- $scope.baseUrl = formatUrl($scope.baseUrl);
- $window.localStorage.setItem(constantsService.baseUrlKey, $scope.baseUrl);
- }
- else {
- $window.localStorage.removeItem(constantsService.baseUrlKey);
- }
+ environmentService.setUrls({
+ base: $scope.baseUrl,
+ api: $scope.apiUrl,
+ identity: $scope.identityUrl,
+ webVault: $scope.webVaultUrl
+ }, function (resUrls) {
+ $timeout(function () {
+ // re-set urls since service can change them, ex: prefixing https://
+ $scope.baseUrl = resUrls.base;
+ $scope.apiUrl = resUrls.api;
+ $scope.identityUrl = resUrls.identity;
+ $scope.webVaultUrl = resUrls.webVault;
- if ($scope.webVaultUrl && $scope.webVaultUrl !== '') {
- $scope.webVaultUrl = formatUrl($scope.webVaultUrl);
- $window.localStorage.setItem(constantsService.webVaultUrlKey, $scope.webVaultUrl);
- }
- else {
- $window.localStorage.removeItem(constantsService.webVaultUrlKey);
- }
-
- if ($scope.apiUrl && $scope.apiUrl !== '') {
- $scope.apiUrl = formatUrl($scope.apiUrl);
- $window.localStorage.setItem(constantsService.apiUrlKey, $scope.apiUrl);
- }
- else {
- $window.localStorage.removeItem(constantsService.apiUrlKey);
- }
-
- if ($scope.identityUrl && $scope.identityUrl !== '') {
- $scope.identityUrl = formatUrl($scope.identityUrl);
- $window.localStorage.setItem(constantsService.identityUrlKey, $scope.identityUrl);
- }
- else {
- $window.localStorage.removeItem(constantsService.identityUrlKey);
- }
-
- apiService.setUrls();
- $analytics.eventTrack('Set Environment URLs');
- toastr.success(i18nService.environmentSaved);
+ $analytics.eventTrack('Set Environment URLs');
+ toastr.success(i18nService.environmentSaved);
+ });
+ });
};
-
- function formatUrl(url) {
- url = url.replace(/\/+$/g, '');
- if (!url.startsWith("http://") && !url.startsWith('https://')) {
- url = 'https://' + url;
- }
- return url;
- }
});
diff --git a/src/services/apiService.js b/src/services/apiService.js
index 2d2bfbdd04..cfc43b1ef8 100644
--- a/src/services/apiService.js
+++ b/src/services/apiService.js
@@ -5,53 +5,49 @@ function ApiService(tokenService, appIdService, utilsService, constantsService,
this.utilsService = utilsService;
this.constantsService = constantsService;
+ this.urlsSet = false;
+ this.baseUrl = null;
+ this.identityBaseUrl = null;
+
initApiService();
- this.setUrls();
}
function initApiService() {
- ApiService.prototype.setUrls = function () {
- try {
- var storedBaseUrl = window.localStorage.getItem(this.constantsService.baseUrlKey);
+ ApiService.prototype.setUrls = function (urls) {
+ var self = this;
+ self.urlsSet = true;
- if (storedBaseUrl) {
- this.baseUrl = storedBaseUrl + '/api';
- this.identityBaseUrl = storedBaseUrl + '/identity';
- return;
- }
-
- var storedApiUrl = window.localStorage.getItem(this.constantsService.apiUrlKey);
- var storedIdentityUrl = window.localStorage.getItem(this.constantsService.identityUrlKey);
- if (storedApiUrl && storedIdentityUrl) {
- this.baseUrl = storedApiUrl;
- this.identityBaseUrl = storedIdentityUrl;
- return;
- }
+ if (urls.base) {
+ self.baseUrl = urls.base + '/api';
+ self.identityBaseUrl = urls.base + '/identity';
+ return;
}
- catch (e) {
- console.log('Unable to set custom environment URLs:');
- console.log(e);
+
+ if (urls.api && urls.identity) {
+ self.baseUrl = urls.api;
+ self.identityBaseUrl = urls.identity;
+ return;
}
// Desktop
- //this.baseUrl = 'http://localhost:4000';
- //this.identityBaseUrl = 'http://localhost:33656';
+ //self.baseUrl = 'http://localhost:4000';
+ //self.identityBaseUrl = 'http://localhost:33656';
// Desktop HTTPS
- //this.baseUrl = 'https://localhost:44377';
- //this.identityBaseUrl = 'https://localhost:44392';
+ //self.baseUrl = 'https://localhost:44377';
+ //self.identityBaseUrl = 'https://localhost:44392';
// Desktop external
- //this.baseUrl = 'http://192.168.1.4:4000';
- //this.identityBaseUrl = 'http://192.168.1.4:33656';
+ //self.baseUrl = 'http://192.168.1.4:4000';
+ //self.identityBaseUrl = 'http://192.168.1.4:33656';
// Preview
- //this.baseUrl = 'https://preview-api.bitwarden.com';
- //this.identityBaseUrl = 'https://preview-identity.bitwarden.com';
+ //self.baseUrl = 'https://preview-api.bitwarden.com';
+ //self.identityBaseUrl = 'https://preview-identity.bitwarden.com';
// Production
- this.baseUrl = 'https://api.bitwarden.com';
- this.identityBaseUrl = 'https://identity.bitwarden.com';
+ self.baseUrl = 'https://api.bitwarden.com';
+ self.identityBaseUrl = 'https://identity.bitwarden.com';
};
// Auth APIs
diff --git a/src/services/constantsService.js b/src/services/constantsService.js
index 12c05d954c..37a8e75a7e 100644
--- a/src/services/constantsService.js
+++ b/src/services/constantsService.js
@@ -1,9 +1,6 @@
function ConstantsService(i18nService) {
return {
- baseUrlKey: 'baseUrl',
- webVaultUrlKey: 'webVaultUrl',
- apiUrlKey: 'apiUrl',
- identityUrlKey: 'identityUrl',
+ environmentUrlsKey: 'environmentUrls',
disableGaKey: 'disableGa',
disableAddLoginNotificationKey: 'disableAddLoginNotification',
disableContextMenuItemKey: 'disableContextMenuItem',
diff --git a/src/services/environmentService.js b/src/services/environmentService.js
new file mode 100644
index 0000000000..9fffdd35c0
--- /dev/null
+++ b/src/services/environmentService.js
@@ -0,0 +1,96 @@
+function EnvironmentService(constantsService, apiService) {
+ this.constantsService = constantsService;
+ this.apiService = apiService;
+
+ this.baseUrl = null;
+ this.webVaultUrl = null;
+ this.apiUrl = null;
+ this.identityUrl = null;
+
+ initEnvironmentService();
+}
+
+function initEnvironmentService() {
+ EnvironmentService.prototype.setUrlsFromStorage = function (callback) {
+ var self = this;
+
+ chrome.storage.local.get(self.constantsService.environmentUrlsKey, function (urlsObj) {
+ var urls = urlsObj[self.constantsService.environmentUrlsKey] || {
+ base: null,
+ api: null,
+ identity: null,
+ webVault: null
+ };
+
+ self.baseUrl = urls.base;
+ if (self.baseUrl) {
+ self.apiService.setUrls({
+ base: self.baseUrl
+ });
+ callback();
+ return;
+ }
+
+ self.webVaultUrl = urls.webVault;
+ self.apiUrl = urls.api;
+ self.identityUrl = urls.identity;
+
+ self.apiService.setUrls({
+ api: self.apiUrl,
+ identity: self.identityUrl
+ });
+ callback();
+ return;
+ });
+ };
+
+ EnvironmentService.prototype.setUrls = function (urls, callback) {
+ var self = this;
+
+ urls.base = formatUrl(urls.base);
+ urls.webVault = formatUrl(urls.webVault);
+ urls.api = formatUrl(urls.api);
+ urls.identity = formatUrl(urls.identity);
+
+ var urlsObj = {};
+ urlsObj[self.constantsService.environmentUrlsKey] = {
+ base: urls.base,
+ api: urls.api,
+ identity: urls.identity,
+ webVault: urls.webVault
+ };
+
+ chrome.storage.local.set(urlsObj, function () {
+ self.baseUrl = urls.base;
+ self.webVaultUrl = urls.webVault;
+ self.apiUrl = urls.api;
+ self.identityUrl = urls.identity;
+
+ if (self.baseUrl) {
+ self.apiService.setUrls({
+ base: self.baseUrl
+ });
+ }
+ else {
+ self.apiService.setUrls({
+ api: self.apiUrl,
+ identity: self.identityUrl
+ });
+ }
+
+ callback(urls);
+ });
+ };
+
+ function formatUrl(url) {
+ if (!url || url === '') {
+ return null;
+ }
+
+ url = url.replace(/\/+$/g, '');
+ if (!url.startsWith("http://") && !url.startsWith('https://')) {
+ url = 'https://' + url;
+ }
+ return url;
+ }
+}