1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-21 16:18:28 +01:00

Created sync service and supported folder/site service methods

This commit is contained in:
Kyle Spearrin 2016-09-06 20:41:17 -04:00
parent 0402ec648d
commit 5a39d4c73e
4 changed files with 379 additions and 42 deletions

View File

@ -9,7 +9,7 @@
$scope.createSite = function (model) { $scope.createSite = function (model) {
cipherService.encryptSite(model, function (siteModel) { cipherService.encryptSite(model, function (siteModel) {
var site = new Site(siteModel, true); var site = new Site(siteModel, true);
siteService.save(site, function () { siteService.saveWithServer(site, function () {
$scope.close(); $scope.close();
}); });
}); });

View File

@ -48,7 +48,113 @@ function initFolderService() {
}); });
}; };
function handleError() { FolderService.prototype.saveWithServer = function (folder, callback) {
// TODO: check for unauth or forbidden and logout if (!callback || typeof callback !== 'function') {
throw 'callback function required';
} }
var self = this,
request = new FolderRequest(folder);
if (!folder.id) {
self.apiService.postFolder(request, apiSuccess, handleError);
}
else {
self.apiService.putFolder(folder.id, request, apiSuccess, handleError);
}
function apiSuccess(response) {
folder.id = response.id;
userService.getUserId(function (userId) {
var data = new FolderData(response, userId);
self.upsert(data, function () {
callback(folder);
});
});
}
};
FolderService.prototype.upsert = function (folder, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
userService.getUserId(function (userId) {
var foldersKey = 'folders_' + userId;
chrome.storage.local.get(foldersKey, function (obj) {
var folders = obj[foldersKey];
if (!folders) {
folders = {};
}
if (folder.constructor === Array) {
for (var i = 0; i < folder.length; i++) {
folders[folder[i].id] = folder[i];
}
}
else {
folders[folder.id] = folder;
}
obj[foldersKey] = folders;
chrome.storage.local.set(obj, function () {
callback();
});
});
});
};
FolderService.prototype.replace = function (folders, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
userService.getUserId(function (userId) {
var obj = {};
obj['folders_' + userId] = folders;
chrome.storage.local.set(obj, function () {
callback();
});
});
};
FolderService.prototype.delete = function (id, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
userService.getUserId(function (userId) {
var foldersKey = 'folders_' + userId;
chrome.storage.local.get(foldersKey, function (obj) {
var folders = obj[foldersKey];
if (!folders) {
callback();
return;
}
if (id.constructor === Array) {
for (var i = 0; i < id.length; i++) {
if (id[i] in folders) {
delete folders[id[i]];
}
}
}
else if (id in folders) {
delete folders[id];
}
else {
callback();
return;
}
obj[foldersKey] = folders;
chrome.storage.local.set(obj, function () {
callback();
});
});
});
};
}; };

View File

@ -51,16 +51,15 @@ function initSiteService() {
}); });
}; };
SiteService.prototype.save = function (site, callback) { SiteService.prototype.saveWithServer = function (site, callback) {
if (!callback || typeof callback !== 'function') { if (!callback || typeof callback !== 'function') {
throw 'callback function required'; throw 'callback function required';
} }
var newRecord = site.id ? false : true, var self = this,
self = this; request = new SiteRequest(site);
var request = new SiteRequest(site); if (!site.id) {
if (newRecord) {
self.apiService.postSite(request, apiSuccess, handleError); self.apiService.postSite(request, apiSuccess, handleError);
} }
else { else {
@ -69,9 +68,21 @@ function initSiteService() {
function apiSuccess(response) { function apiSuccess(response) {
site.id = response.id; site.id = response.id;
userService.getUserId(function (userId) { userService.getUserId(function (userId) {
var data = new SiteData(response, userId); var data = new SiteData(response, userId);
self.upsert(data, function () {
callback(site);
});
});
}
};
SiteService.prototype.upsert = function (site, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
userService.getUserId(function (userId) {
var sitesKey = 'sites_' + userId; var sitesKey = 'sites_' + userId;
chrome.storage.local.get(sitesKey, function (obj) { chrome.storage.local.get(sitesKey, function (obj) {
@ -80,16 +91,36 @@ function initSiteService() {
sites = {}; sites = {};
} }
sites[site.id] = data; if (site.constructor === Array) {
site.id = data.id; for (var i = 0; i < site.length; i++) {
sites[site[i].id] = site[i];
}
}
else {
sites[site.id] = site;
}
obj[sitesKey] = sites; obj[sitesKey] = sites;
chrome.storage.local.set(obj, function () { chrome.storage.local.set(obj, function () {
callback(site); callback();
}); });
}); });
}); });
};
SiteService.prototype.replace = function (sites, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
} }
userService.getUserId(function (userId) {
var obj = {};
obj['sites_' + userId] = sites;
chrome.storage.local.set(obj, function () {
callback();
});
});
}; };
SiteService.prototype.delete = function (id, callback) { SiteService.prototype.delete = function (id, callback) {
@ -97,29 +128,48 @@ function initSiteService() {
throw 'callback function required'; throw 'callback function required';
} }
self.apiService.deleteCipher(id, apiSuccess, handleError);
function apiSuccess(response) {
userService.getUserId(function (userId) { userService.getUserId(function (userId) {
var sitesKey = 'sites_' + userId; var sitesKey = 'sites_' + userId;
chrome.storage.local.get(sitesKey, function (obj) { chrome.storage.local.get(sitesKey, function (obj) {
var sites = obj[sitesKey]; var sites = obj[sitesKey];
if (!sites) { if (!sites) {
sites = {};
}
if (id in sites) {
delete obj[sitesKey];
chrome.storage.local.set(obj, function () {
callback(); callback();
}); return;
}
if (id.constructor === Array) {
for (var i = 0; i < id.length; i++) {
if (id[i] in sites) {
delete sites[id[i]];
}
}
}
else if (id in sites) {
delete sites[id];
} }
else { else {
callback(); callback();
return;
} }
obj[sitesKey] = sites;
chrome.storage.local.set(obj, function () {
callback();
}); });
}); });
});
};
SiteService.prototype.deleteWithServer = function (id, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
} }
var self = this;
self.apiService.deleteCipher(id, function (response) {
self.delete(id, callback);
}, handleError);
}; };
function handleError() { function handleError() {

181
src/services/syncService.js Normal file
View File

@ -0,0 +1,181 @@
function SyncService(siteService, folderService, userService, apiService) {
this.siteService = siteService;
this.folderService = folderService;
this.userService = userService;
this.apiService = apiService;
this.syncInProgress = false;
initSyncService();
};
function initSyncService() {
SyncService.prototype.fullSync = function (callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
var self = this;
this.userService.isAuthenticated(function (isAuthenticated) {
if (!isAuthenticated) {
callback(false);
return;
}
syncStarted();
var now = new Date();
var ciphers = self.apiService.getCiphers(function (response) {
var sites = {};
var folders = {};
for (var i = 0; i < response.Data.lenth; i++) {
var data = response.Data[i];
if (data.type === 1) {
sites[data.id] = new SiteData(data);
}
else if (data.type === 0) {
folders[data.id] = new FolderData(data);
}
}
folderService.replace(folders, function () {
siteService.replace(sites, function () {
setLastSync(now, function () {
syncCompleted(true);
callback(true);
});
});
});
}, handleError);
});
};
SyncService.prototype.incrementalSync = function (callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
// TODO
};
function syncFolders(serverFolders, callback) {
var self = this;
self.userService.isAuthenticated(function (isAuthenticated) {
if (!isAuthenticated) {
callback();
return;
}
self.userService.getUserId(function (userId) {
self.folderService.getAll(function (folders) {
var localFolders = {};
for (var i = 0; i < folders.lenth; i++) {
localFolders[folders[i].id] = folders[i];
}
var data = [];
for (var j = 0; j < serverFolders.lenth; j++) {
var serverFolder = serverFolders[j];
var existingLocalFolder = localFolders[serverFolder.id];
if (!existingLocalFolder || existingLocalFolder.RevisionDate !== serverFolder.RevisionDate) {
data.push(new FolderData(serverFolder, userId));
}
}
self.folderService.upsert(data, function () {
callback();
});
});
});
});
}
function syncSites(serverSites, callback) {
var self = this;
self.userService.isAuthenticated(function (isAuthenticated) {
if (!isAuthenticated) {
callback();
return;
}
self.userService.getUserId(function (userId) {
self.siteService.getAll(function (sites) {
var localSites = {};
for (var i = 0; i < sites.lenth; i++) {
localSites[sites[i].id] = sites[i];
}
var data = [];
for (var j = 0; j < serverSites.lenth; j++) {
var serverSite = serverSites[j];
var existingLocalSite = localSites[serverSite.id];
if (!existingLocalSite || existingLocalSite.RevisionDate !== serverSite.RevisionDate) {
data.push(new SiteData(serverSite, userId));
}
}
self.siteService.upsert(data, function () {
callback();
});
});
});
});
}
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';
}
if (!(date instanceof Date)) {
throw 'date must be a Date object';
}
this.userService.getUserId(function (userId) {
var lastSyncKey = 'lastSync_' + userId;
var obj = {};
obj[lastSyncKey] = date.toJSON();
chrome.storage.local.set(obj, function () {
callback();
});
});
};
function syncStarted() {
this.syncInProgress = true;
}
function syncCompleted(successfully) {
this.syncInProgress = false;
}
function handleError() {
// TODO: check for unauth or forbidden and logout
}
};