1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-13 14:53:33 +00:00
Files
browser/src/services/syncService.js
2017-09-21 10:43:33 -04:00

236 lines
7.4 KiB
JavaScript

function SyncService(loginService, folderService, userService, apiService, settingsService,
cryptoService, logoutCallback) {
this.loginService = loginService;
this.folderService = folderService;
this.userService = userService;
this.apiService = apiService;
this.settingsService = settingsService;
this.cryptoService = cryptoService;
this.syncInProgress = false;
this.logoutCallback = logoutCallback;
initSyncService();
}
function initSyncService() {
SyncService.prototype.fullSync = function (forceSync, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
var self = this;
self.syncStarted();
self.userService.isAuthenticated(function (isAuthenticated) {
if (!isAuthenticated) {
self.syncCompleted(false);
callback(false);
return;
}
var now = new Date();
needsSyncing(self, forceSync, function (needsSync, skipped) {
if (skipped) {
self.syncCompleted(false);
callback(false);
return;
}
if (!needsSync) {
self.setLastSync(now, function () {
self.syncCompleted(false);
callback(false);
});
return;
}
self.userService.getUserId(function (userId) {
self.apiService.getSync(function (response) {
syncProfile(self, response.profile).then(function () {
return syncFolders(self, userId, response.folders);
}).then(function () {
return syncCiphers(self, userId, response.ciphers);
}).then(function () {
return syncSettings(self, userId, response.domains);
}).then(function () {
self.setLastSync(now, function () {
self.syncCompleted(true);
callback(true);
});
}, function () {
self.syncCompleted(false);
callback(false);
});
}, function () {
self.syncCompleted(false);
callback(false);
});
});
});
});
};
function needsSyncing(self, forceSync, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
if (forceSync) {
callback(true, false);
return;
}
self.apiService.getAccountRevisionDate(function (response) {
var accountRevisionDate = new Date(response);
self.getLastSync(function (lastSync) {
if (lastSync && accountRevisionDate <= lastSync) {
callback(false, false);
return;
}
callback(true, false);
});
}, function () {
callback(false, true);
});
}
function syncProfile(self, response) {
var deferred = Q.defer();
self.userService.getSecurityStamp().then(function (stamp) {
if (stamp && stamp !== response.securityStamp) {
if (self.logoutCallback) {
self.logoutCallback(true, function () { });
}
deferred.reject();
return;
}
return self.cryptoService.setEncKey(response.key);
}).then(function () {
return self.cryptoService.setEncPrivateKey(response.privateKey);
}, function () {
deferred.reject();
}).then(function () {
return self.cryptoService.setOrgKeys(response.organizations);
}, function () {
deferred.reject();
}).then(function () {
return self.userService.setSecurityStamp(response.securityStamp);
}, function () {
deferred.reject();
}).then(function () {
deferred.resolve();
}, function () {
deferred.reject();
});
return deferred.promise;
}
function syncFolders(self, userId, response) {
var deferred = Q.defer();
var folders = {};
for (var i = 0; i < response.length; i++) {
folders[response[i].id] = new FolderData(response[i], userId);
}
self.folderService.replace(folders, function () {
deferred.resolve();
});
return deferred.promise;
}
function syncCiphers(self, userId, response) {
var deferred = Q.defer();
var logins = {};
for (var i = 0; i < response.length; i++) {
var data = response[i];
if (data.type === 1) {
logins[data.id] = new LoginData(data, userId);
}
}
self.loginService.replace(logins, function () {
deferred.resolve();
});
return deferred.promise;
}
function syncSettings(self, userId, response) {
var deferred = Q.defer();
var eqDomains = [];
if (response && response.equivalentDomains) {
eqDomains = eqDomains.concat(response.equivalentDomains);
}
if (response && response.globalEquivalentDomains) {
for (var i = 0; i < response.globalEquivalentDomains.length; i++) {
if (response.globalEquivalentDomains[i].domains.length) {
eqDomains.push(response.globalEquivalentDomains[i].domains);
}
}
}
self.settingsService.setEquivalentDomains(eqDomains, function () {
deferred.resolve();
});
return deferred.promise;
}
SyncService.prototype.getLastSync = function (callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
this.userService.getUserId(function (userId) {
var lastSyncKey = 'lastSync_' + userId;
chrome.storage.local.get(lastSyncKey, function (obj) {
var lastSync = obj[lastSyncKey];
if (lastSync) {
callback(new Date(lastSync));
}
else {
callback(null);
}
});
});
};
SyncService.prototype.setLastSync = function (date, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
this.userService.getUserId(function (userId) {
var lastSyncKey = 'lastSync_' + userId;
var obj = {};
obj[lastSyncKey] = date.toJSON();
chrome.storage.local.set(obj, function () {
callback();
});
});
};
SyncService.prototype.syncStarted = function () {
this.syncInProgress = true;
chrome.runtime.sendMessage({ command: 'syncStarted' });
};
SyncService.prototype.syncCompleted = function (successfully) {
this.syncInProgress = false;
chrome.runtime.sendMessage({ command: 'syncCompleted', successfully: successfully });
};
}