persist user profile information

This commit is contained in:
Kyle Spearrin 2016-09-20 23:30:16 -04:00
parent 34c2340a4d
commit 8b76668f1f
5 changed files with 139 additions and 72 deletions

View File

@ -1,7 +1,7 @@
var cryptoService = new CryptoService(); var cryptoService = new CryptoService();
var tokenService = new TokenService(); var tokenService = new TokenService();
var apiService = new ApiService(tokenService); var apiService = new ApiService(tokenService);
var userService = new UserService(tokenService, apiService); var userService = new UserService(tokenService, apiService, cryptoService);
var siteService = new SiteService(cryptoService, userService, apiService); var siteService = new SiteService(cryptoService, userService, apiService);
var folderService = new FolderService(cryptoService, userService, apiService); var folderService = new FolderService(cryptoService, userService, apiService);
var syncService = new SyncService(siteService, folderService, userService, apiService); var syncService = new SyncService(siteService, folderService, userService, apiService);

View File

@ -32,9 +32,9 @@ var PasswordHintRequest = function (email) {
this.email = email; this.email = email;
}; };
var TokenTwoFactorRequest = function () { var TokenTwoFactorRequest = function (code) {
this.code = null; this.code = code;
this.provider = null; this.provider = "Authenticator";
this.device = null; this.device = null;
}; };

View File

@ -20,11 +20,13 @@
$scope.loginPromise = loginService.logIn(model.email, model.masterPassword); $scope.loginPromise = loginService.logIn(model.email, model.masterPassword);
$scope.loginPromise.then(function () { $scope.loginPromise.then(function () {
userService.getUserProfile(function (profile) { userService.isTwoFactorAuthenticated(function (isTwoFactorAuthenticated) {
if (false && profile.twoFactor) { if (isTwoFactorAuthenticated) {
$state.go('login.twoFactor'); $state.go('login.twoFactor');
} }
else { else {
// TODO: do full sync
$state.go('tabs.current', { animation: 'in-slide-left' }); $state.go('tabs.current', { animation: 'in-slide-left' });
} }
}); });

View File

@ -5,6 +5,7 @@
var _service = {}; var _service = {};
_service.logIn = function (email, masterPassword) { _service.logIn = function (email, masterPassword) {
email = email.toLowerCase();
var key = cryptoService.makeKey(masterPassword, email); var key = cryptoService.makeKey(masterPassword, email);
var deferred = $q.defer(); var deferred = $q.defer();
cryptoService.hashPassword(masterPassword, key, function (hashedPassword) { cryptoService.hashPassword(masterPassword, key, function (hashedPassword) {
@ -17,9 +18,16 @@
tokenService.setToken(response.token, function () { tokenService.setToken(response.token, function () {
cryptoService.setKey(key, function () { cryptoService.setKey(key, function () {
userService.setUserProfile(response.profile, function () { if (response.profile) {
userService.setUserId(response.profile.id, function () {
userService.setEmail(response.profile.email, function () {
deferred.resolve(response);
});
});
}
else {
deferred.resolve(response); deferred.resolve(response);
}); }
}); });
}); });
}, function (error) { }, function (error) {
@ -29,21 +37,21 @@
return deferred.promise; return deferred.promise;
}; };
_service.logInTwoFactor = function (code, provider) { _service.logInTwoFactor = function (code) {
var request = { var request = new TokenTwoFactorRequest(code);
code: code,
provider: provider
};
var deferred = $q.defer(); var deferred = $q.defer();
apiService.auth.tokenTwoFactor(request, function (response) { apiService.auth.postTokenTwoFactor(request, function (response) {
if (!response || !response.Token) { if (!response || !response.token) {
deferred.reject();
return; return;
} }
tokenService.setToken(response.Token, function () { tokenService.setToken(response.token, function () {
userService.setUserProfile(response.Profile, function () { userService.setUserId(response.profile.id, function () {
deferred.resolve(response); userService.setEmail(response.profile.email, function () {
deferred.resolve(response);
});
}); });
}); });
}, function (error) { }, function (error) {
@ -56,8 +64,11 @@
_service.logOut = function (callback) { _service.logOut = function (callback) {
tokenService.clearToken(function () { tokenService.clearToken(function () {
cryptoService.clearKey(function () { cryptoService.clearKey(function () {
userService.clearUserProfile(); userService.clearUserId(function () {
callback(); userService.clearEmail(function () {
callback();
});
});
}); });
}); });
}; };

View File

@ -1,76 +1,100 @@
function UserService(tokenService, apiService) { function UserService(tokenService, apiService, cryptoService) {
this.tokenService = tokenService; this.tokenService = tokenService;
this.apiService = apiService; this.apiService = apiService;
this.cryptoService = cryptoService;
initUserService(); initUserService();
}; };
function initUserService() { function initUserService() {
var _userProfile = null; var userIdKey = 'userId',
userEmailKey = 'userEmail';
var _userId = null,
_email = null;
UserService.prototype.setUserId = function (userId, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
_userId = userId;
var obj = {};
obj[userIdKey] = userId;
chrome.storage.local.set(obj, function () {
callback();
});
};
UserService.prototype.getUserId = function (callback) { UserService.prototype.getUserId = function (callback) {
this.getUserProfile(function (profile) {
callback(profile.id);
});
};
UserService.prototype.getUserProfile = function (callback) {
if (!callback || typeof callback !== 'function') { if (!callback || typeof callback !== 'function') {
throw 'callback function required'; throw 'callback function required';
} }
if (_userProfile) { if (_userId) {
callback(_userProfile); return callback(_userId);
return;
} }
this.setUserProfile(null, function () { chrome.storage.local.get(userIdKey, function (obj) {
callback(_userProfile); if (obj && obj[userIdKey]) {
_userId = obj[userIdKey];
}
return callback(_userId);
}); });
}; };
UserService.prototype.setUserProfile = function (profile, callback) { UserService.prototype.clearUserId = function (callback) {
if (!callback || typeof callback !== 'function') { if (!callback || typeof callback !== 'function') {
throw 'callback function required'; throw 'callback function required';
} }
this.tokenService.getToken(function (token) { _userId = null;
if (!token) { chrome.storage.local.remove(userIdKey, function () {
return;
}
var decodedToken = this.tokenService.decodeToken(token);
var twoFactor = decodedToken.authmethod === 'TwoFactor';
_userProfile = {
id: decodedToken.nameid,
email: decodedToken.email,
twoFactor: twoFactor
};
if (!twoFactor && profile) {
loadProfile(profile, callback);
}
else if (!twoFactor && !profile) {
this.apiService.getProfile(function (response) {
loadProfile(response, callback);
});
}
});
function loadProfile(profile, callback) {
_userProfile.extended = {
name: profile.name,
twoFactorEnabled: profile.twoFactorEnabled,
culture: profile.culture
};
callback(); callback();
} });
}; };
UserService.prototype.clearUserProfile = function () { UserService.prototype.setEmail = function (email, callback) {
_userProfile = null; if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
_email = email;
var obj = {};
obj[userEmailKey] = email;
chrome.storage.local.set(obj, function () {
callback();
});
};
UserService.prototype.getEmail = function (callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
if (_email) {
return callback(_email);
}
chrome.storage.local.get(userEmailKey, function (obj) {
if (obj && obj[userEmailKey]) {
_email = obj[userEmailKey];
}
return callback(_email);
});
};
UserService.prototype.clearEmail = function (callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
_email = null;
chrome.storage.local.remove(userEmailKey, function () {
callback();
});
}; };
UserService.prototype.isAuthenticated = function (callback) { UserService.prototype.isAuthenticated = function (callback) {
@ -78,8 +102,23 @@ function initUserService() {
throw 'callback function required'; throw 'callback function required';
} }
this.getUserProfile(function (profile) { var self = this;
callback(profile !== null && !profile.twoFactor); self.cryptoService.getKey(false, function (key) {
if (!key) {
callback(false);
}
else {
self.tokenService.getToken(function (token) {
if (!token) {
callback(false);
}
else {
self.getUserId(function (userId) {
callback(userId !== null);
});
}
});
}
}); });
}; };
@ -88,8 +127,23 @@ function initUserService() {
throw 'callback function required'; throw 'callback function required';
} }
this.getUserProfile(function (profile) { var self = this;
callback(profile !== null && profile.twoFactor); self.cryptoService.getKey(false, function (key) {
if (!key) {
callback(false);
}
else {
self.tokenService.getToken(function (token) {
if (!token) {
callback(false);
}
else {
self.getUserId(function (userId) {
callback(userId === null);
});
}
});
}
}); });
}; };
}; };