diff --git a/src/app/directives/masterPasswordDirective.js b/src/app/directives/masterPasswordDirective.js index 271a9108..8cf2defb 100644 --- a/src/app/directives/masterPasswordDirective.js +++ b/src/app/directives/masterPasswordDirective.js @@ -6,34 +6,31 @@ angular require: 'ngModel', restrict: 'A', link: function (scope, elem, attr, ngModel) { - var profile = authService.getUserProfile(); - if (!profile) { - return; - } + authService.getUserProfile().then(function (profile) { + // For DOM -> model validation + ngModel.$parsers.unshift(function (value) { + if (!value) { + return undefined; + } - // For DOM -> model validation - ngModel.$parsers.unshift(function (value) { - if (!value) { - return undefined; - } + var key = cryptoService.makeKey(value, profile.email, true); + var valid = key === cryptoService.getKey(true); + ngModel.$setValidity('masterPassword', valid); + return valid ? value : undefined; + }); - var key = cryptoService.makeKey(value, profile.email, true); - var valid = key === cryptoService.getKey(true); - ngModel.$setValidity('masterPassword', valid); - return valid ? value : undefined; - }); + // For model -> DOM validation + ngModel.$formatters.unshift(function (value) { + if (!value) { + return undefined; + } - // For model -> DOM validation - ngModel.$formatters.unshift(function (value) { - if (!value) { - return undefined; - } + var key = cryptoService.makeKey(value, profile.email, true); + var valid = key === cryptoService.getKey(true); - var key = cryptoService.makeKey(value, profile.email, true); - var valid = key === cryptoService.getKey(true); - - ngModel.$setValidity('masterPassword', valid); - return value; + ngModel.$setValidity('masterPassword', valid); + return value; + }); }); } }; diff --git a/src/app/global/mainController.js b/src/app/global/mainController.js index 79e66c78..e3ec1a55 100644 --- a/src/app/global/mainController.js +++ b/src/app/global/mainController.js @@ -10,7 +10,9 @@ angular $scope.currentYear = new Date().getFullYear(); $scope.$on('$viewContentLoaded', function () { - vm.userProfile = authService.getUserProfile(); + authService.getUserProfile().then(function (profile) { + vm.userProfile = profile; + }); if ($.AdminLTE) { if ($.AdminLTE.layout) { diff --git a/src/app/global/sideNavController.js b/src/app/global/sideNavController.js index 20953dd3..eae2e35f 100644 --- a/src/app/global/sideNavController.js +++ b/src/app/global/sideNavController.js @@ -6,16 +6,17 @@ angular $scope.params = $state.params; if ($state.includes('backend.org')) { - var userProfile = authService.getUserProfile(); - if (!userProfile.organizations || !userProfile.organizations.length) { - return; - } - - for (var i = 0; i < userProfile.organizations.length; i++) { - if (userProfile.organizations[i].id === $state.params.orgId) { - $scope.orgProfile = userProfile.organizations[i]; - break; + authService.getUserProfile().then(function (userProfile) { + if (!userProfile.organizations || !userProfile.organizations.length) { + return; } - } + + for (var i = 0; i < userProfile.organizations.length; i++) { + if (userProfile.organizations[i].id === $state.params.orgId) { + $scope.orgProfile = userProfile.organizations[i]; + break; + } + } + }); } }); diff --git a/src/app/services/authService.js b/src/app/services/authService.js index 82de919f..55a29f09 100644 --- a/src/app/services/authService.js +++ b/src/app/services/authService.js @@ -58,16 +58,21 @@ angular _service.getUserProfile = function () { if (!_userProfile) { - _service.setUserProfile(); + return _service.setUserProfile(); } - return _userProfile; + var deferred = $q.defer(); + deferred.resolve(_userProfile); + return deferred.promise; }; _service.setUserProfile = function () { + var deferred = $q.defer(); + var token = tokenService.getToken(); if (!token) { - return; + deferred.reject(); + return deferred.promise; } var decodedToken = jwtHelper.decodeToken(token); @@ -77,52 +82,56 @@ angular email: decodedToken.email }; - apiService.accounts.getProfile({}, loadProfile); + apiService.accounts.getProfile({}, function (profile) { + _userProfile.extended = { + name: profile.Name, + twoFactorEnabled: profile.TwoFactorEnabled, + culture: profile.Culture + }; + + if (profile.Organizations) { + var orgs = []; + for (var i = 0; i < profile.Organizations.length; i++) { + orgs.push({ + id: profile.Organizations[i].Id, + name: profile.Organizations[i].Name, + key: profile.Organizations[i].Key, + status: profile.Organizations[i].Status + }); + } + + _userProfile.organizations = orgs; + cryptoService.setOrgKeys(orgs); + deferred.resolve(_userProfile); + } + }, function () { + deferred.reject(); + }); + + return deferred.promise; }; _service.addProfileOrganization = function (org) { - var profile = _service.getUserProfile(); - if (profile) { - if (!profile.Organizations) { - profile.Organizations = []; + return _service.getUserProfile().then(function (profile) { + if (profile) { + if (!profile.Organizations) { + profile.Organizations = []; + } + + var o = { + id: org.Id, + name: org.Name, + key: org.Key, + status: org.Status + }; + profile.organizations.push(o); + + _userProfile = profile; + cryptoService.addOrgKey(o); } - - var o = { - id: org.Id, - name: org.Name, - key: org.Key, - status: org.Status - }; - profile.organizations.push(o); - - _userProfile = profile; - cryptoService.addOrgKey(o); - } + }); }; - function loadProfile(profile) { - _userProfile.extended = { - name: profile.Name, - twoFactorEnabled: profile.TwoFactorEnabled, - culture: profile.Culture - }; - - if (profile.Organizations) { - var orgs = []; - for (var i = 0; i < profile.Organizations.length; i++) { - orgs.push({ - id: profile.Organizations[i].Id, - name: profile.Organizations[i].Name, - key: profile.Organizations[i].Key, - status: profile.Organizations[i].Status - }); - } - - _userProfile.organizations = orgs; - cryptoService.setOrgKeys(orgs); - } - } - _service.isAuthenticated = function () { return tokenService.getToken() !== null; }; diff --git a/src/app/settings/settingsChangePasswordController.js b/src/app/settings/settingsChangePasswordController.js index 419b5811..a660b308 100644 --- a/src/app/settings/settingsChangePasswordController.js +++ b/src/app/settings/settingsChangePasswordController.js @@ -24,40 +24,42 @@ $scope.processing = true; - var profile = authService.getUserProfile(); - var newKey = cryptoService.makeKey(model.newMasterPassword, profile.email.toLowerCase()); - - var reencryptedLogins = []; - var loginsPromise = apiService.logins.list({ dirty: false }, function (encryptedLogins) { - var unencryptedLogins = cipherService.decryptLogins(encryptedLogins.Data); - reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, newKey); - }).$promise; - - var reencryptedFolders = []; - var foldersPromise = apiService.folders.list({ dirty: false }, function (encryptedFolders) { - var unencryptedFolders = cipherService.decryptFolders(encryptedFolders.Data); - reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, newKey); - }).$promise; - - $q.all([loginsPromise, foldersPromise]).then(function () { - var request = { - masterPasswordHash: cryptoService.hashPassword(model.masterPassword), - newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey), - ciphers: reencryptedLogins.concat(reencryptedFolders) - }; - - $scope.savePromise = apiService.accounts.putPassword(request, function () { - $uibModalInstance.dismiss('cancel'); - authService.logOut(); - $analytics.eventTrack('Changed Password'); - $state.go('frontend.login.info').then(function () { - toastr.success('Please log back in.', 'Master Password Changed'); - }); - }, function () { - // TODO: recovery mode - $uibModalInstance.dismiss('cancel'); - toastr.error('Something went wrong.', 'Oh No!'); + authService.getUserProfile().then(function (profile) { + return cryptoService.makeKey(model.newMasterPassword, profile.email.toLowerCase()); + }).then(function (newKey) { + var reencryptedLogins = []; + var loginsPromise = apiService.logins.list({ dirty: false }, function (encryptedLogins) { + var unencryptedLogins = cipherService.decryptLogins(encryptedLogins.Data); + reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, newKey); }).$promise; + + var reencryptedFolders = []; + var foldersPromise = apiService.folders.list({ dirty: false }, function (encryptedFolders) { + var unencryptedFolders = cipherService.decryptFolders(encryptedFolders.Data); + reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, newKey); + }).$promise; + + $q.all([loginsPromise, foldersPromise]).then(function () { + var request = { + masterPasswordHash: cryptoService.hashPassword(model.masterPassword), + newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey), + ciphers: reencryptedLogins.concat(reencryptedFolders) + }; + + $scope.savePromise = apiService.accounts.putPassword(request, function () { + $uibModalInstance.dismiss('cancel'); + authService.logOut(); + $analytics.eventTrack('Changed Password'); + $state.go('frontend.login.info').then(function () { + toastr.success('Please log back in.', 'Master Password Changed'); + }); + }, function () { + // TODO: recovery mode + $uibModalInstance.dismiss('cancel'); + toastr.error('Something went wrong.', 'Oh No!'); + }).$promise; + }); + }); }; diff --git a/src/app/settings/settingsController.js b/src/app/settings/settingsController.js index f71329d0..ea5cb0d0 100644 --- a/src/app/settings/settingsController.js +++ b/src/app/settings/settingsController.js @@ -36,15 +36,17 @@ $scope.generalSave = function () { $scope.generalPromise = apiService.accounts.putProfile({}, $scope.model.profile, function (profile) { - authService.setUserProfile(profile); - toastr.success('Account has been updated.', 'Success!'); + authService.setUserProfile(profile).then(function (updatedProfile) { + toastr.success('Account has been updated.', 'Success!'); + }); }).$promise; }; $scope.passwordHintSave = function () { $scope.passwordHintPromise = apiService.accounts.putProfile({}, $scope.model.profile, function (profile) { - authService.setUserProfile(profile); - toastr.success('Account has been updated.', 'Success!'); + authService.setUserProfile(profile).then(function (updatedProfile) { + toastr.success('Account has been updated.', 'Success!'); + }); }).$promise; }; diff --git a/src/app/settings/settingsTwoFactorController.js b/src/app/settings/settingsTwoFactorController.js index fbf68561..5f9f70fb 100644 --- a/src/app/settings/settingsTwoFactorController.js +++ b/src/app/settings/settingsTwoFactorController.js @@ -4,13 +4,16 @@ .controller('settingsTwoFactorController', function ($scope, apiService, $uibModalInstance, cryptoService, authService, $q, toastr, $analytics) { $analytics.eventTrack('settingsTwoFactorController', { category: 'Modal' }); var _issuer = 'bitwarden', - _profile = authService.getUserProfile(), + _profile = null, _masterPasswordHash; - $scope.account = _profile.email; - $scope.enabled = function () { - return _profile.extended && _profile.extended.twoFactorEnabled; - }; + authService.getUserProfile().then(function (profile) { + _profile = profile; + $scope.account = _profile.email; + $scope.enabled = function () { + return _profile.extended && _profile.extended.twoFactorEnabled; + }; + }); $scope.auth = function (model) { _masterPasswordHash = cryptoService.hashPassword(model.masterPassword); diff --git a/src/app/vault/vaultShareController.js b/src/app/vault/vaultShareController.js index 7190cb2d..81313f34 100644 --- a/src/app/vault/vaultShareController.js +++ b/src/app/vault/vaultShareController.js @@ -12,33 +12,34 @@ $scope.login = cipherService.decryptLogin(login); }); - var profile = authService.getUserProfile(); - if (profile && profile.organizations) { - var orgs = []; - for (var i = 0; i < profile.organizations.length; i++) { - orgs.push({ - id: profile.organizations[i].id, - name: profile.organizations[i].name + authService.getUserProfile().then(function (profile) { + if (profile && profile.organizations) { + var orgs = []; + for (var i = 0; i < profile.organizations.length; i++) { + orgs.push({ + id: profile.organizations[i].id, + name: profile.organizations[i].name + }); + + if (i === 0) { + $scope.model.organizationId = profile.organizations[i].id; + } + } + + $scope.organizations = orgs; + + apiService.subvaults.listMe(function (response) { + var subvaults = []; + for (var i = 0; i < response.Data.length; i++) { + var decSubvault = cipherService.decryptSubvault(response.Data[i]); + decSubvault.organizationId = response.Data[i].OrganizationId; + subvaults.push(decSubvault); + } + + $scope.subvaults = subvaults; }); - - if (i === 0) { - $scope.model.organizationId = profile.organizations[i].id; - } } - - $scope.organizations = orgs; - - apiService.subvaults.listMe(function (response) { - var subvaults = []; - for (var i = 0; i < response.Data.length; i++) { - var decSubvault = cipherService.decryptSubvault(response.Data[i]); - decSubvault.organizationId = response.Data[i].OrganizationId; - subvaults.push(decSubvault); - } - - $scope.subvaults = subvaults; - }); - } + }); $scope.submitPromise = null; $scope.submit = function (model) {