From 8b76668f1f18f852468451c5d7800e4f05558cac Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 20 Sep 2016 23:30:16 -0400 Subject: [PATCH] persist user profile information --- src/background.js | 2 +- src/models/api/requestModels.js | 6 +- .../app/accounts/accountsLoginController.js | 6 +- src/popup/app/services/loginService.js | 39 +++-- src/services/userService.js | 158 ++++++++++++------ 5 files changed, 139 insertions(+), 72 deletions(-) diff --git a/src/background.js b/src/background.js index bb4c7a44a5..2fcf8d4392 100644 --- a/src/background.js +++ b/src/background.js @@ -1,7 +1,7 @@ var cryptoService = new CryptoService(); var tokenService = new 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 folderService = new FolderService(cryptoService, userService, apiService); var syncService = new SyncService(siteService, folderService, userService, apiService); diff --git a/src/models/api/requestModels.js b/src/models/api/requestModels.js index 6ae456c21d..7d03388e5d 100644 --- a/src/models/api/requestModels.js +++ b/src/models/api/requestModels.js @@ -32,9 +32,9 @@ var PasswordHintRequest = function (email) { this.email = email; }; -var TokenTwoFactorRequest = function () { - this.code = null; - this.provider = null; +var TokenTwoFactorRequest = function (code) { + this.code = code; + this.provider = "Authenticator"; this.device = null; }; diff --git a/src/popup/app/accounts/accountsLoginController.js b/src/popup/app/accounts/accountsLoginController.js index 5acf79a3e3..7ce42b4ea8 100644 --- a/src/popup/app/accounts/accountsLoginController.js +++ b/src/popup/app/accounts/accountsLoginController.js @@ -20,11 +20,13 @@ $scope.loginPromise = loginService.logIn(model.email, model.masterPassword); $scope.loginPromise.then(function () { - userService.getUserProfile(function (profile) { - if (false && profile.twoFactor) { + userService.isTwoFactorAuthenticated(function (isTwoFactorAuthenticated) { + if (isTwoFactorAuthenticated) { $state.go('login.twoFactor'); } else { + // TODO: do full sync + $state.go('tabs.current', { animation: 'in-slide-left' }); } }); diff --git a/src/popup/app/services/loginService.js b/src/popup/app/services/loginService.js index 1c403b9911..93a5c66097 100644 --- a/src/popup/app/services/loginService.js +++ b/src/popup/app/services/loginService.js @@ -5,6 +5,7 @@ var _service = {}; _service.logIn = function (email, masterPassword) { + email = email.toLowerCase(); var key = cryptoService.makeKey(masterPassword, email); var deferred = $q.defer(); cryptoService.hashPassword(masterPassword, key, function (hashedPassword) { @@ -17,9 +18,16 @@ tokenService.setToken(response.token, 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); - }); + } }); }); }, function (error) { @@ -29,21 +37,21 @@ return deferred.promise; }; - _service.logInTwoFactor = function (code, provider) { - var request = { - code: code, - provider: provider - }; + _service.logInTwoFactor = function (code) { + var request = new TokenTwoFactorRequest(code); var deferred = $q.defer(); - apiService.auth.tokenTwoFactor(request, function (response) { - if (!response || !response.Token) { + apiService.auth.postTokenTwoFactor(request, function (response) { + if (!response || !response.token) { + deferred.reject(); return; } - tokenService.setToken(response.Token, function () { - userService.setUserProfile(response.Profile, function () { - deferred.resolve(response); + tokenService.setToken(response.token, function () { + userService.setUserId(response.profile.id, function () { + userService.setEmail(response.profile.email, function () { + deferred.resolve(response); + }); }); }); }, function (error) { @@ -56,8 +64,11 @@ _service.logOut = function (callback) { tokenService.clearToken(function () { cryptoService.clearKey(function () { - userService.clearUserProfile(); - callback(); + userService.clearUserId(function () { + userService.clearEmail(function () { + callback(); + }); + }); }); }); }; diff --git a/src/services/userService.js b/src/services/userService.js index e3e8dde931..548e598204 100644 --- a/src/services/userService.js +++ b/src/services/userService.js @@ -1,76 +1,100 @@ -function UserService(tokenService, apiService) { +function UserService(tokenService, apiService, cryptoService) { this.tokenService = tokenService; this.apiService = apiService; + this.cryptoService = cryptoService; 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) { - this.getUserProfile(function (profile) { - callback(profile.id); - }); - }; - - UserService.prototype.getUserProfile = function (callback) { if (!callback || typeof callback !== 'function') { throw 'callback function required'; } - if (_userProfile) { - callback(_userProfile); - return; + if (_userId) { + return callback(_userId); } - this.setUserProfile(null, function () { - callback(_userProfile); + chrome.storage.local.get(userIdKey, function (obj) { + 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') { throw 'callback function required'; } - this.tokenService.getToken(function (token) { - if (!token) { - 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 - }; - + _userId = null; + chrome.storage.local.remove(userIdKey, function () { callback(); - } + }); }; - UserService.prototype.clearUserProfile = function () { - _userProfile = null; + UserService.prototype.setEmail = function (email, callback) { + 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) { @@ -78,8 +102,23 @@ function initUserService() { throw 'callback function required'; } - this.getUserProfile(function (profile) { - callback(profile !== null && !profile.twoFactor); + var self = this; + 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'; } - this.getUserProfile(function (profile) { - callback(profile !== null && profile.twoFactor); + var self = this; + 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); + }); + } + }); + } }); }; };