change pw wip

This commit is contained in:
Mo Bitar
2017-02-10 11:49:50 -06:00
parent ae9899dee1
commit 577f286352
7 changed files with 134 additions and 79 deletions

View File

@@ -73,13 +73,12 @@ angular.module('app.frontend')
}
Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: password}, authParams), function(keys){
var mk = keys.mk;
var requestUrl = url + "/auth/sign_in";
var request = Restangular.oneUrl(requestUrl, requestUrl);
var params = {password: keys.pw, email: email};
_.merge(request, params);
request.post().then(function(response){
this.handleAuthResponse(response, email, url, authParams, mk, keys.pw);
this.handleAuthResponse(response, email, url, authParams, keys.mk, keys.pw);
callback(response);
}.bind(this))
.catch(function(response){
@@ -91,7 +90,9 @@ angular.module('app.frontend')
}
this.handleAuthResponse = function(response, email, url, authParams, mk, pw) {
localStorage.setItem("server", url);
if(url) {
localStorage.setItem("server", url);
}
localStorage.setItem("user", JSON.stringify(response.plain().user));
localStorage.setItem("auth_params", JSON.stringify(_.omit(authParams, ["pw_nonce"])));
localStorage.setItem("mk", mk);
@@ -101,13 +102,12 @@ angular.module('app.frontend')
this.register = function(url, email, password, callback) {
Neeto.crypto.generateInitialEncryptionKeysForUser({password: password, email: email}, function(keys, authParams){
var mk = keys.mk;
var requestUrl = url + "/auth";
var request = Restangular.oneUrl(requestUrl, requestUrl);
var params = _.merge({password: keys.pw, email: email}, authParams);
_.merge(request, params);
request.post().then(function(response){
this.handleAuthResponse(response, email, url, authParams, mk, keys.pw);
this.handleAuthResponse(response, email, url, authParams, keys.mk, keys.pw);
callback(response);
}.bind(this))
.catch(function(response){
@@ -117,55 +117,26 @@ angular.module('app.frontend')
}.bind(this));
}
// this.changePassword = function(current_password, new_password) {
// this.getAuthParamsForEmail(email, function(authParams){
// if(!authParams) {
// callback(null);
// return;
// }
// Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: current_password, email: user.email}, authParams), function(currentKeys) {
// Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: new_password, email: user.email}, authParams), function(newKeys){
// var data = {};
// data.current_password = currentKeys.pw;
// data.password = newKeys.pw;
// data.password_confirmation = newKeys.pw;
//
// var user = this.user;
//
// this._performPasswordChange(currentKeys, newKeys, function(response){
// if(response && !response.error) {
// // this.showNewPasswordForm = false;
// // reencrypt data with new mk
// this.reencryptAllItemsAndSave(user, newKeys.mk, currentKeys.mk, function(success){
// if(success) {
// this.setMk(newKeys.mk);
// alert("Your password has been changed and your data re-encrypted.");
// } else {
// // rollback password
// this._performPasswordChange(newKeys, currentKeys, function(response){
// alert("There was an error changing your password. Your password has been rolled back.");
// window.location.reload();
// })
// }
// }.bind(this));
// } else {
// // this.showNewPasswordForm = false;
// alert("There was an error changing your password. Please try again.");
// }
// }.bind(this))
// }.bind(this));
// }.bind(this));
// }.bind(this));
// }
this.changePassword = function(email, new_password, callback) {
Neeto.crypto.generateInitialEncryptionKeysForUser({password: new_password, email: email}, function(keys, authParams){
var requestUrl = localStorage.getItem("server") + "/auth/change_pw";
var request = Restangular.oneUrl(requestUrl, requestUrl);
var params = _.merge({new_password: keys.pw}, authParams);
_.merge(request, params);
this._performPasswordChange = function(url, email, current_keys, new_keys, callback) {
var requestUrl = url + "/auth";
var request = Restangular.oneUrl(requestUrl, requestUrl);
var params = {password: new_keys.pw, password_confirmation: new_keys.pw, current_password: current_keys.pw, email: email};
_.merge(request, params);
request.patch().then(function(response){
callback(response);
})
request.post().then(function(response){
this.handleAuthResponse(response, email, null, authParams, keys.mk, keys.pw);
callback(response.plain());
}.bind(this))
.catch(function(response){
var error = response.data;
if(!error) {
error = {message: "Something went wrong while changing your password. Your password was not changed. Please try again."}
}
console.log("Change pw error", response);
callback({error: error});
})
}.bind(this));
}
this.staticifyObject = function(object) {

View File

@@ -15,10 +15,6 @@ class AccountMenu {
$scope.syncStatus = syncManager.syncStatus;
$scope.changePasswordPressed = function() {
$scope.showNewPasswordForm = !$scope.showNewPasswordForm;
}
$scope.encryptionKey = function() {
return syncManager.masterKey;
}
@@ -31,19 +27,50 @@ class AccountMenu {
return `${$scope.server}/dashboard/?server=${$scope.server}&id=${$scope.user.email}&pw=${$scope.serverPassword()}`;
}
$scope.submitPasswordChange = function() {
$scope.passwordChangeData.status = "Generating New Keys...";
$scope.newPasswordData = {};
$timeout(function(){
if(data.password != data.password_confirmation) {
alert("Your new password does not match its confirmation.");
$scope.showPasswordChangeForm = function() {
$scope.newPasswordData.showNewPasswordForm = true;
}
$scope.submitPasswordChange = function() {
if($scope.newPasswordData.newPassword != $scope.newPasswordData.newPasswordConfirmation) {
alert("Your new password does not match its confirmation.");
$scope.newPasswordData.status = null;
return;
}
var email = $scope.user.email;
if(!email) {
alert("We don't have your email stored. Please log out then log back in to fix this issue.");
$scope.newPasswordData.status = null;
return;
}
$scope.newPasswordData.status = "Generating New Keys...";
authManager.changePassword(email, $scope.newPasswordData.newPassword, function(response){
if(response.error) {
alert("There was an error changing your password. Please try again.");
$scope.newPasswordData.status = null;
return;
}
authManager.changePassword($scope.passwordChangeData.current_password, $scope.passwordChangeData.new_password, function(response){
})
// re-encrypt all items
$scope.newPasswordData.status = "Re-encrypting all items with your new key...";
modelManager.setAllItemsDirty();
syncManager.sync(function(response){
if(response.error) {
alert("There was an error re-encrypting your items. Your password was changed, but not all your items were properly re-encrypted and synced. You should try syncing again. If all else fails, you should restore your notes from backup.")
return;
}
$scope.newPasswordData.status = "Successfully changed password and re-encrypted all items.";
alert("Your password has been changed, and your items successfully re-encrypted and synced. Be sure to log out on all other signed in applications.")
$timeout(function(){
$scope.newPasswordData = {};
}, 1000)
});
})
}

View File

@@ -2,13 +2,13 @@ class EncryptionHelper {
static encryptItem(item, key) {
var item_key = null;
if(item.enc_item_key) {
// we reuse the key, but this is optional
item_key = Neeto.crypto.decryptText(item.enc_item_key, key);
} else {
// if(item.enc_item_key) {
// // we reuse the key, but this is optional
// item_key = Neeto.crypto.decryptText(item.enc_item_key, key);
// } else {
item_key = Neeto.crypto.generateRandomEncryptionKey();
item.enc_item_key = Neeto.crypto.encryptText(item_key, key);
}
// }
var ek = Neeto.crypto.firstHalfOfKey(item_key);
var ak = Neeto.crypto.secondHalfOfKey(item_key);

View File

@@ -225,6 +225,13 @@ class ModelManager {
item.removeAllRelationships();
}
/* Used when changing encryption key */
setAllItemsDirty() {
for(var item of this.allItems) {
item.setDirty(true);
}
}
removeItemLocally(item, callback) {
_.pull(this.items, item);

View File

@@ -98,10 +98,38 @@ class SyncManager {
return this._cursorToken;
}
get queuedCallbacks() {
if(!this._queuedCallbacks) {
this._queuedCallbacks = [];
}
return this._queuedCallbacks;
}
clearQueuedCallbacks() {
this._queuedCallbacks = [];
}
callQueuedCallbacksAndCurrent(currentCallback, response) {
var allCallbacks = this.queuedCallbacks;
if(currentCallback) {
allCallbacks.push(currentCallback);
}
if(allCallbacks.length) {
console.log(allCallbacks.length, "queued callbacks");
for(var eachCallback of allCallbacks) {
eachCallback(response);
}
this.clearQueuedCallbacks();
}
}
sync(callback, options = {}) {
if(this.syncStatus.syncOpInProgress) {
this.repeatOnCompletion = true;
if(callback) {
this.queuedCallbacks.push(callback);
}
console.log("Sync op in progress; returning.");
return;
}
@@ -118,7 +146,6 @@ class SyncManager {
var isContinuationSync = this.needsMoreSync;
this.repeatOnCompletion = false;
this.syncStatus.syncOpInProgress = true;
let submitLimit = 100;
@@ -172,14 +199,17 @@ class SyncManager {
this.syncToken = response.sync_token;
this.cursorToken = response.cursor_token;
if(this.cursorToken || this.repeatOnCompletion || this.needsMoreSync) {
if(this.cursorToken || this.needsMoreSync) {
setTimeout(function () {
this.sync(callback, options);
}.bind(this), 10); // wait 10ms to allow UI to update
} else if(this.repeatOnCompletion) {
this.repeatOnCompletion = false;
setTimeout(function () {
this.sync(null, options);
}.bind(this), 10); // wait 10ms to allow UI to update
} else {
if(callback) {
callback(response);
}
this.callQueuedCallbacksAndCurrent(callback, response);
}
}.bind(this))
@@ -193,9 +223,7 @@ class SyncManager {
this.$rootScope.$broadcast("sync:error", error);
if(callback) {
callback({error: "Sync error"});
}
this.callQueuedCallbacksAndCurrent(callback, {error: "Sync error"});
}.bind(this))
}