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,62 +25,94 @@
$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);
var reencryptedLogins = []; }
var loginsPromise = apiService.logins.list({}, function (encryptedLogins) { else {
var filteredEncryptedLogins = []; // User is not using an enc key, let's make them one
for (var i = 0; i < encryptedLogins.Data.length; i++) { $scope.savePromise = updateKey(model);
if (encryptedLogins.Data[i].OrganizationId) { }
continue; };
}
filteredEncryptedLogins.push(encryptedLogins.Data[i]); function updateKey(model) {
var madeEncKey = cryptoService.makeEncKey(null);
encKey = madeEncKey.encKey;
var encKeyEnc = madeEncKey.encKeyEnc;
var reencryptedLogins = [];
var loginsPromise = apiService.logins.list({}, function (encryptedLogins) {
var filteredEncryptedLogins = [];
for (var i = 0; i < encryptedLogins.Data.length; i++) {
if (encryptedLogins.Data[i].OrganizationId) {
continue;
} }
var unencryptedLogins = cipherService.decryptLogins(filteredEncryptedLogins); filteredEncryptedLogins.push(encryptedLogins.Data[i]);
reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, newKey);
}).$promise;
var reencryptedFolders = [];
var foldersPromise = apiService.folders.list({}, function (encryptedFolders) {
var unencryptedFolders = cipherService.decryptFolders(encryptedFolders.Data);
reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, newKey);
}).$promise;
var privateKey = cryptoService.getPrivateKey('raw'),
reencryptedPrivateKey = null;
if (privateKey) {
reencryptedPrivateKey = cryptoService.encrypt(privateKey, newKey, 'raw');
} }
$q.all([loginsPromise, foldersPromise]).then(function () { var unencryptedLogins = cipherService.decryptLogins(filteredEncryptedLogins);
var request = { reencryptedLogins = cipherService.encryptLogins(unencryptedLogins, encKey);
masterPasswordHash: cryptoService.hashPassword(model.masterPassword), }).$promise;
newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey),
data: {
ciphers: reencryptedLogins,
folders: reencryptedFolders,
privateKey: reencryptedPrivateKey
}
};
$scope.savePromise = apiService.accounts.putPassword(request, function () { var reencryptedFolders = [];
$uibModalInstance.dismiss('cancel'); var foldersPromise = apiService.folders.list({}, function (encryptedFolders) {
authService.logOut(); var unencryptedFolders = cipherService.decryptFolders(encryptedFolders.Data);
$analytics.eventTrack('Changed Password'); reencryptedFolders = cipherService.encryptFolders(unencryptedFolders, encKey);
$state.go('frontend.login.info').then(function () { }).$promise;
toastr.success('Please log back in.', 'Master Password Changed');
});
}, function () {
$uibModalInstance.dismiss('cancel');
toastr.error('Something went wrong.', 'Oh No!');
}).$promise;
});
var privateKey = cryptoService.getPrivateKey('raw'),
reencryptedPrivateKey = null;
if (privateKey) {
reencryptedPrivateKey = cryptoService.encrypt(privateKey, encKey, 'raw');
}
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 = {
masterPasswordHash: cryptoService.hashPassword(model.masterPassword),
newMasterPasswordHash: cryptoService.hashPassword(model.newMasterPassword, newKey),
key: newEncKey
};
return apiService.accounts.putPassword(request).$promise;
}, error).then(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');
});
}, error);
}
function error() {
$uibModalInstance.dismiss('cancel');
toastr.error('Something went wrong.', 'Oh No!');
}
$scope.close = function () { $scope.close = function () {
$uibModalInstance.dismiss('cancel'); $uibModalInstance.dismiss('cancel');