change password with new enc key

This commit is contained in:
Kyle Spearrin 2017-05-31 12:21:06 -04:00
parent 138b57b33d
commit 1dd9e459c6
2 changed files with 89 additions and 58 deletions

View File

@ -15,9 +15,15 @@ angular
$sessionStorage.key = _key.keyB64; $sessionStorage.key = _key.keyB64;
}; };
_service.setEncKey = function (encKeyCt, key) { _service.setEncKey = function (encKey, key, alreadyDecrypted) {
if (alreadyDecrypted) {
_encKey = encKey;
$sessionStorage.encKey = _encKey.keyB64;
return;
}
try { try {
var encKeyBytes = _service.decrypt(encKeyCt, key, 'raw'); var encKeyBytes = _service.decrypt(encKey, key, 'raw');
$sessionStorage.encKey = forge.util.encode64(encKeyBytes); $sessionStorage.encKey = forge.util.encode64(encKeyBytes);
_encKey = new SymmetricCryptoKey(encKeyBytes); _encKey = new SymmetricCryptoKey(encKeyBytes);
} }
@ -112,10 +118,6 @@ angular
_encKey = new SymmetricCryptoKey($sessionStorage.encKey, true); _encKey = new SymmetricCryptoKey($sessionStorage.encKey, true);
} }
if (!_encKey) {
throw 'enc key unavailable';
}
return _encKey; return _encKey;
}; };
@ -237,10 +239,6 @@ angular
}; };
_service.makeEncKey = function (key) { _service.makeEncKey = function (key) {
if (!key) {
throw 'Invalid parameters.';
}
var encKey = forge.random.getBytesSync(512 / 8); var encKey = forge.random.getBytesSync(512 / 8);
var encKeyEnc = _service.encrypt(encKey, key, 'raw'); var encKeyEnc = _service.encrypt(encKey, key, 'raw');
return { return {

View File

@ -4,6 +4,7 @@
.controller('settingsChangePasswordController', function ($scope, $state, apiService, $uibModalInstance, .controller('settingsChangePasswordController', function ($scope, $state, apiService, $uibModalInstance,
cryptoService, authService, cipherService, validationService, $q, toastr, $analytics) { cryptoService, authService, cipherService, validationService, $q, toastr, $analytics) {
$analytics.eventTrack('settingsChangePasswordController', { category: 'Modal' }); $analytics.eventTrack('settingsChangePasswordController', { category: 'Modal' });
$scope.save = function (model, form) { $scope.save = function (model, form) {
var error = false; var error = false;
@ -24,9 +25,21 @@
$scope.processing = true; $scope.processing = true;
authService.getUserProfile().then(function (profile) { var encKey = cryptoService.getEncKey();
return cryptoService.makeKey(model.newMasterPassword, profile.email.toLowerCase()); if (encKey) {
}).then(function (newKey) { $scope.savePromise = changePassword(model);
}
else {
// User is not using an enc key, let's make them one
$scope.savePromise = updateKey(model);
}
};
function updateKey(model) {
var madeEncKey = cryptoService.makeEncKey(null);
encKey = madeEncKey.encKey;
var encKeyEnc = madeEncKey.encKeyEnc;
var reencryptedLogins = []; var reencryptedLogins = [];
var loginsPromise = apiService.logins.list({}, function (encryptedLogins) { var loginsPromise = apiService.logins.list({}, function (encryptedLogins) {
var filteredEncryptedLogins = []; var filteredEncryptedLogins = [];
@ -39,47 +52,67 @@
} }
var unencryptedLogins = cipherService.decryptLogins(filteredEncryptedLogins); var unencryptedLogins = cipherService.decryptLogins(filteredEncryptedLogins);
reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, newKey); reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, encKey);
}).$promise; }).$promise;
var reencryptedFolders = []; var reencryptedFolders = [];
var foldersPromise = apiService.folders.list({}, function (encryptedFolders) { var foldersPromise = apiService.folders.list({}, function (encryptedFolders) {
var unencryptedFolders = cipherService.decryptFolders(encryptedFolders.Data); var unencryptedFolders = cipherService.decryptFolders(encryptedFolders.Data);
reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, newKey); reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, encKey);
}).$promise; }).$promise;
var privateKey = cryptoService.getPrivateKey('raw'), var privateKey = cryptoService.getPrivateKey('raw'),
reencryptedPrivateKey = null; reencryptedPrivateKey = null;
if (privateKey) { if (privateKey) {
reencryptedPrivateKey = cryptoService.encrypt(privateKey, newKey, 'raw'); reencryptedPrivateKey = cryptoService.encrypt(privateKey, encKey, 'raw');
} }
$q.all([loginsPromise, foldersPromise]).then(function () { return $q.all([loginsPromise, foldersPromise]).then(function () {
var request = {
masterPasswordHash: cryptoService.hashPassword(model.masterPassword),
ciphers: reencryptedLogins,
folders: reencryptedFolders,
privateKey: reencryptedPrivateKey,
key: encKeyEnc
};
return apiService.accounts.putKey(request).$promise;
}, error).then(function () {
cryptoService.setEncKey(encKey, null, true);
return changePassword(model);
}, function () {
cryptoService.clearEncKey();
error();
});
}
function changePassword(model) {
return authService.getUserProfile().then(function (profile) {
var newKey = cryptoService.makeKey(model.newMasterPassword, profile.email.toLowerCase());
var encKey = cryptoService.getEncKey();
var newEncKey = cryptoService.encrypt(encKey.key, newKey, 'raw');
var request = { var request = {
masterPasswordHash: cryptoService.hashPassword(model.masterPassword), masterPasswordHash: cryptoService.hashPassword(model.masterPassword),
newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey), newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey),
data: { key: newEncKey
ciphers: reencryptedLogins,
folders: reencryptedFolders,
privateKey: reencryptedPrivateKey
}
}; };
$scope.savePromise = apiService.accounts.putPassword(request, function () { return apiService.accounts.putPassword(request).$promise;
}, error).then(function () {
$uibModalInstance.dismiss('cancel'); $uibModalInstance.dismiss('cancel');
authService.logOut(); authService.logOut();
$analytics.eventTrack('Changed Password'); $analytics.eventTrack('Changed Password');
$state.go('frontend.login.info').then(function () { $state.go('frontend.login.info').then(function () {
toastr.success('Please log back in.', 'Master Password Changed'); toastr.success('Please log back in.', 'Master Password Changed');
}); });
}, function () { }, error);
}
function error() {
$uibModalInstance.dismiss('cancel'); $uibModalInstance.dismiss('cancel');
toastr.error('Something went wrong.', 'Oh No!'); toastr.error('Something went wrong.', 'Oh No!');
}).$promise; }
});
});
};
$scope.close = function () { $scope.close = function () {
$uibModalInstance.dismiss('cancel'); $uibModalInstance.dismiss('cancel');