From e4ffdf68155dc4daf6e1eee502eebd37edf356d4 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 13 Apr 2017 18:18:32 -0400 Subject: [PATCH] promisify makekeypair and generate keys on login --- .../accounts/accountsRegisterController.js | 25 ++++++++++-------- src/app/services/apiService.js | 1 + src/app/services/authService.js | 26 ++++++++++++++++--- src/app/services/cryptoService.js | 17 ++++++++---- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/app/accounts/accountsRegisterController.js b/src/app/accounts/accountsRegisterController.js index 24b5b0f099..dc2f8032c4 100644 --- a/src/app/accounts/accountsRegisterController.js +++ b/src/app/accounts/accountsRegisterController.js @@ -32,27 +32,30 @@ angular var email = $scope.model.email.toLowerCase(); var key = cryptoService.makeKey($scope.model.masterPassword, email); - cryptoService.makeKeyPair(key, function (publicKey, privateKeyEnc, errors) { - if (errors) { - validationService.addError(form, null, 'Problem generating keys.', true); - return; - } + $scope.registerPromise = cryptoService.makeKeyPair(key).then(function (result) { var request = { name: $scope.model.name, email: email, masterPasswordHash: cryptoService.hashPassword($scope.model.masterPassword, key), masterPasswordHint: $scope.model.masterPasswordHint, keys: { - publicKey: publicKey, - encryptedPrivateKey: privateKeyEnc + publicKey: result.publicKey, + encryptedPrivateKey: result.privateKeyEnc } }; - $scope.registerPromise = apiService.accounts.register(request, function () { - $scope.success = true; - $analytics.eventTrack('Registered'); - }).$promise; + return apiService.accounts.register(request); + }, function (errors) { + validationService.addError(form, null, 'Problem generating keys.', true); + return false; + }).then(function (result) { + if (result === false) { + return; + } + + $scope.success = true; + $analytics.eventTrack('Registered'); }); }; }); diff --git a/src/app/services/apiService.js b/src/app/services/apiService.js index 77a27649b0..0c4f4a9e51 100644 --- a/src/app/services/apiService.js +++ b/src/app/services/apiService.js @@ -88,6 +88,7 @@ postTwoFactorRecover: { url: _apiUri + '/accounts/two-factor-recover', method: 'POST', params: {} }, postPasswordHint: { url: _apiUri + '/accounts/password-hint', method: 'POST', params: {} }, putSecurityStamp: { url: _apiUri + '/accounts/security-stamp', method: 'POST', params: {} }, + putKeys: { url: _apiUri + '/accounts/keys', method: 'POST', params: {} }, 'import': { url: _apiUri + '/accounts/import', method: 'POST', params: {} }, postDelete: { url: _apiUri + '/accounts/delete', method: 'POST', params: {} } }); diff --git a/src/app/services/authService.js b/src/app/services/authService.js index 2c0f36a748..52f7846247 100644 --- a/src/app/services/authService.js +++ b/src/app/services/authService.js @@ -25,7 +25,8 @@ angular // TODO: device information one day? var deferred = $q.defer(); - apiService.identity.token(request, function (response) { + + apiService.identity.token(request).$promise.then(function (response) { if (!response || !response.access_token) { return; } @@ -33,14 +34,31 @@ angular tokenService.setToken(response.access_token); tokenService.setRefreshToken(response.refresh_token); cryptoService.setKey(key); + if (response.PrivateKey) { cryptoService.setPrivateKey(response.PrivateKey, key); + return true; + } + else { + return cryptoService.makeKeyPair(key); + } + }).then(function (keyResults) { + if (keyResults === true) { + return; } - _service.setUserProfile().then(function () { - deferred.resolve(); - }); + cryptoService.setPrivateKey(keyResults.privateKeyEnc, key); + return apiService.accounts.putKeys({ + publicKey: keyResults.publicKey, + encryptedPrivateKey: keyResults.privateKeyEnc + }).$promise; + }).then(function () { + return _service.setUserProfile(); + }).then(function () { + deferred.resolve(); }, function (error) { + _service.logOut(); + if (error.status === 400 && error.data.TwoFactorProviders && error.data.TwoFactorProviders.length) { deferred.resolve(error.data.TwoFactorProviders); } diff --git a/src/app/services/cryptoService.js b/src/app/services/cryptoService.js index 482d053b04..97639f43d4 100644 --- a/src/app/services/cryptoService.js +++ b/src/app/services/cryptoService.js @@ -1,7 +1,7 @@ angular .module('bit.services') - .factory('cryptoService', function ($sessionStorage, constants) { + .factory('cryptoService', function ($sessionStorage, constants, $q) { var _service = {}, _key, _b64Key, @@ -220,23 +220,30 @@ angular return key; }; - _service.makeKeyPair = function (key, callback) { + _service.makeKeyPair = function (key) { + var deferred = $q.defer(); + forge.pki.rsa.generateKeyPair({ bits: 2048, workers: 2 }, function (error, keypair) { if (error) { - callback(null, null, error); + deferred.reject(error); return; } var privateKeyAsn1 = forge.pki.privateKeyToAsn1(keypair.privateKey); var privateKeyPkcs8 = forge.pki.wrapRsaPrivateKey(privateKeyAsn1); var privateKeyBytes = forge.asn1.toDer(privateKeyPkcs8).getBytes(); - var privateKeyEncBytes = _service.encrypt(privateKeyBytes, key, 'raw'); + var privateKeyEncCt = _service.encrypt(privateKeyBytes, key, 'raw'); var publicKeyAsn1 = forge.pki.publicKeyToAsn1(keypair.publicKey); var publicKeyBytes = forge.asn1.toDer(publicKeyAsn1).getBytes(); - callback(forge.util.encode64(publicKeyBytes), privateKeyEncBytes, null); + deferred.resolve({ + publicKey: forge.util.encode64(publicKeyBytes), + privateKeyEnc: privateKeyEncCt + }); }); + + return deferred.promise; }; _service.makeShareKey = function () {