diff --git a/src/background.js b/src/background.js index c6662a112c4..3cb3a985aa2 100644 --- a/src/background.js +++ b/src/background.js @@ -9,7 +9,8 @@ var apiService = new ApiService(tokenService); var userService = new UserService(tokenService, apiService, cryptoService); var loginService = new LoginService(cryptoService, userService, apiService); var folderService = new FolderService(cryptoService, userService, apiService); -var syncService = new SyncService(loginService, folderService, userService, apiService); +var settingsService = new SettingsService(userService); +var syncService = new SyncService(loginService, folderService, userService, apiService, settingsService); var autofillService = new AutofillService(); var passwordGenerationService = new PasswordGenerationService(); var appIdService = new AppIdService(); diff --git a/src/manifest.json b/src/manifest.json index bdba8462a88..5029eeb2300 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -45,6 +45,7 @@ "services/tokenService.js", "services/apiService.js", "services/userService.js", + "services/settingsService.js", "services/folderService.js", "services/loginService.js", "services/syncService.js", diff --git a/src/models/api/responseModels.js b/src/models/api/responseModels.js index cb3e4411ba8..6609303fe83 100644 --- a/src/models/api/responseModels.js +++ b/src/models/api/responseModels.js @@ -71,8 +71,27 @@ var CipherHistoryResponse = function (response) { var revised = response.Revised; for (var i = 0; i < revised.length; i++) { - revised.push(new CipherResponse(revised[i])); + this.revised.push(new CipherResponse(revised[i])); } this.deleted = response.Deleted; }; + +var DomainsResponse = function (response) { + var GlobalDomainResponse = function (response) { + this.type = response.Type; + this.domains = response.Domains; + this.excluded = response.Excluded; + }; + + this.equivalentDomains = response.EquivalentDomains; + this.globalEquivalentDomains = []; + + var globalEquivalentDomains = response.GlobalEquivalentDomains; + if (!globalEquivalentDomains) { + return; + } + for (var i = 0; i < globalEquivalentDomains.length; i++) { + this.globalEquivalentDomains.push(new GlobalDomainResponse(globalEquivalentDomains[i])); + } +}; diff --git a/src/services/apiService.js b/src/services/apiService.js index 7eb78c482cd..02799db0a8a 100644 --- a/src/services/apiService.js +++ b/src/services/apiService.js @@ -97,6 +97,25 @@ function initApiService() { }); }; + // Settings APIs + + ApiService.prototype.getIncludedDomains = function (success, error) { + var self = this; + this.tokenService.getToken(function (token) { + $.ajax({ + type: 'GET', + url: self.baseUrl + '/settings/domains?excluded=false&access_token=' + token, + dataType: 'json', + success: function (response) { + success(new DomainsResponse(response)); + }, + error: function (jqXHR, textStatus, errorThrown) { + handleError(error, jqXHR, textStatus, errorThrown); + } + }); + }); + }; + // Login APIs ApiService.prototype.getLogin = function (id, success, error) { diff --git a/src/services/settingsService.js b/src/services/settingsService.js new file mode 100644 index 00000000000..2268b6c2073 --- /dev/null +++ b/src/services/settingsService.js @@ -0,0 +1,100 @@ +function SettingsService(userService) { + this.userService = userService; + this.settingsCache = null; + + initSettingsService(); +}; + +function initSettingsService() { + SettingsService.prototype.clearCache = function () { + this.settingsCache = null + }; + + SettingsService.prototype.getSettings = function (callback) { + if (!callback || typeof callback !== 'function') { + throw 'callback function required'; + } + + var self = this; + + if (self.settingsCache) { + callback(self.settingsCache); + return; + } + + this.userService.getUserId(function (userId) { + var key = 'settings_' + userId; + chrome.storage.local.get(key, function (obj) { + self.settingsCache = obj[key]; + callback(self.settingsCache); + }); + }); + }; + + SettingsService.prototype.getEquivalentDomains = function (callback) { + getSettingsKey(this, 'equivalentDomains', callback); + }; + + function getSettingsKey(self, key, callback) { + if (!callback || typeof callback !== 'function') { + throw 'callback function required'; + } + + self.getSettings(function (settings) { + if (settings && settings[key]) { + callback(settings[key]); + return; + } + + callback(null); + }); + } + + SettingsService.prototype.setEquivalentDomains = function (equivalentDomains, callback) { + setSettingsKey(this, 'equivalentDomains', equivalentDomains, callback); + }; + + function setSettingsKey(self, key, value, callback) { + if (!callback || typeof callback !== 'function') { + throw 'callback function required'; + } + + self.userService.getUserId(function (userId) { + var settingsKey = 'settings_' + userId; + + self.getSettings(function (settings) { + if (!settings) { + settings = {}; + } + settings[key] = value; + + var obj = {}; + obj[settingsKey] = settings; + + chrome.storage.local.set(obj, function () { + self.settingsCache = settings; + callback(); + }); + }); + }); + } + + SettingsService.prototype.clear = function (callback) { + if (!callback || typeof callback !== 'function') { + throw 'callback function required'; + } + + var self = this; + + this.userService.getUserId(function (userId) { + chrome.storage.local.remove('settings_' + userId, function () { + self.settingsCache = null; + callback(); + }); + }); + }; + + function handleError(error, deferred) { + deferred.reject(error); + } +}; diff --git a/src/services/syncService.js b/src/services/syncService.js index 36dc34b7c17..9756b5c6ec3 100644 --- a/src/services/syncService.js +++ b/src/services/syncService.js @@ -1,8 +1,9 @@ -function SyncService(loginService, folderService, userService, apiService) { +function SyncService(loginService, folderService, userService, apiService, settingsService) { this.loginService = loginService; this.folderService = folderService; this.userService = userService; this.apiService = apiService; + this.settingsService = settingsService; this.syncInProgress = false; initSyncService(); @@ -26,40 +27,55 @@ function initSyncService() { self.userService.getUserId(function (userId) { var now = new Date(); - var ciphers = self.apiService.getCiphers(function (response) { - var logins = {}; - var folders = {}; - for (var i = 0; i < response.data.length; i++) { - var data = response.data[i]; - if (data.type === 1) { - logins[data.id] = new LoginData(data, userId); - } - else if (data.type === 0) { - folders[data.id] = new FolderData(data, userId); - } - } + var promises = []; + promises.push(syncVault(userId)); + promises.push(syncSettings(userId)); - self.folderService.replace(folders, function () { - self.loginService.replace(logins, function () { - self.setLastSync(now, function () { - self.syncCompleted(true); - callback(true); - }); - }); + Q.all(promises).then(function () { + self.setLastSync(now, function () { + self.syncCompleted(true); + callback(true); }); - }, handleError); + }, function () { + self.syncCompleted(false); + callback(false); + }); }); }); }; - SyncService.prototype.incrementalSync = function (callback) { - if (!callback || typeof callback !== 'function') { - throw 'callback function required'; - } + function syncVault(userId) { + var deferred = Q.defer(); + var self = this; - // TODO - }; + self.apiService.getCiphers(function (response) { + var logins = {}; + var folders = {}; + + for (var i = 0; i < response.data.length; i++) { + var data = response.data[i]; + if (data.type === 1) { + logins[data.id] = new LoginData(data, userId); + } + else if (data.type === 0) { + folders[data.id] = new FolderData(data, userId); + } + } + + self.folderService.replace(folders, function () { + self.loginService.replace(logins, function () { + deferred.resolve(); + return; + }); + }); + }, function () { + deferred.reject(); + return; + }); + + return deferred.promise + } function syncFolders(serverFolders, callback) { var self = this; @@ -129,6 +145,33 @@ function initSyncService() { }); } + function syncSettings(userId) { + var deferred = Q.defer(); + var self = this; + + var ciphers = self.apiService.getIncludedDomains(function (response) { + var eqDomains = []; + if (response && response.equivalentDomains) { + eqDomains = eqDomains.concat(response.equivalentDomains); + } + if (response && response.globalEquivalentDomains) { + for (var i = 0; i < response.globalEquivalentDomains.length; i++) { + eqDomains = eqDomains.concat(response.globalEquivalentDomains[i].domains); + } + } + + self.settingsService.setEquivalentDomains(eqDomains, function () { + deferred.resolve(); + return; + }); + }, function () { + deferred.reject(); + return; + }); + + return deferred.promise; + }; + SyncService.prototype.getLastSync = function (callback) { if (!callback || typeof callback !== 'function') { throw 'callback function required'; @@ -178,9 +221,4 @@ function initSyncService() { this.syncInProgress = false; chrome.runtime.sendMessage({ command: 'syncCompleted', successfully: successfully }); }; - - function handleError() { - syncCompleted(false); - // TODO: check for unauth or forbidden and logout - } };