Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Commit

Permalink
Changes to recovery
Browse files Browse the repository at this point in the history
  • Loading branch information
bartekn committed Nov 5, 2014
1 parent 37389c5 commit 898613f
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 99 deletions.
3 changes: 2 additions & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"jquery": true,
"predef": [
"_",
"angular",
"angular",
"bs58",
"BigNumber",
"iso4217",
"Modernizr",
Expand Down
1 change: 1 addition & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ <h1>Loading...</h1>
<script src="scripts/data/currencies.js"></script>
<script src="scripts/utilities/web.js"></script>
<script src="scripts/libraries/setImmediate.js"></script>
<script src="scripts/libraries/bs58.js"></script>


<script src="scripts/filters/filters.js"></script>
Expand Down
53 changes: 49 additions & 4 deletions app/scripts/controllers/recovery-v2-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ angular.module('stellarClient').controller('RecoveryV2Ctrl', function($scope, $s

return $q.when(params)
.then(validate)
.then(getServerRecoveryCode)
.then(recover)
.then(function (params) {
$state.go('change_password_v2', {
Expand All @@ -61,19 +62,63 @@ angular.module('stellarClient').controller('RecoveryV2Ctrl', function($scope, $s
return $q.reject();
}

// Append suffix
params.username = params.username+'@stellar.org';

return params;
}

function getServerRecoveryCode(params) {
var deferred = $q.defer();

var data = {
username: params.username,
userRecoveryCode: params.recoveryCode
};

$http.post(Options.API_SERVER + '/user/recover', data)
.success(function(body) {
if (body.data && body.data.serverRecoveryCode) {
params.serverRecoveryCode = body.data.serverRecoveryCode;
deferred.resolve(params);
} else {
$scope.recoveryError = 'An error occurred.';
deferred.reject();
}
})
.error(function(body, status) {
switch(status) {
case 400:
if (body.code === 'invalid') {
$scope.recoveryError = 'Invalid username or recovery code.';
} else if (body.code === 'disabled') {
$scope.recoveryError = 'Recovery has been disabled for this account.';
}
break;
case 0:
$scope.recoveryError = 'Unable to contact the server.';
break;
default:
$scope.recoveryError = 'An error occurred.';
}
deferred.reject();
});

return deferred.promise;
}

function recover(params) {
var deferred = $q.defer();

// Append domain
params.username += '@stellar.org';

This comment has been minimized.

Copy link
@matschaffer

matschaffer Feb 24, 2015

Pretty sure this is what's causing @stellar.org to be appended to the username in the UI. Could be the root source of confusion on https://stellartalk.org/topic/6979-i-have-a-problem/

screen shot 2015-02-24 at 12 03 09 pm

This comment has been minimized.

Copy link
@bartekn

bartekn Feb 24, 2015

Author Contributor

There are 2 possible reasons of this problem. The first one is: stellar-deprecated/stellar-wallet#61 The other is we had a bug in stellar-client now fixed) but it makes users affected by it (who changed password during the time bug was there) blocked from recovering and we really can do anything about it. The problem is their recoveryData contains old master key instead of a new one and their wallet data is encrypted by keys derived from a new master key.

When it comes to appending a domain in this input field, we can remove it if it causes confusion but it's not a reason of this problem.


var userPartBytes = bs58.decode(params.recoveryCode);
var serverPartBytes = bs58.decode(params.serverRecoveryCode);
var fullRecoveryCodeBytes = userPartBytes.concat(serverPartBytes);
var fullRecoveryCode = bs58.encode(fullRecoveryCodeBytes);

var data = {
server: Options.WALLET_SERVER+'/v2',
username: params.username,
recoveryCode: params.recoveryCode
recoveryCode: fullRecoveryCode
};

if ($scope.totpRequired) {
Expand Down
2 changes: 1 addition & 1 deletion app/scripts/controllers/settings-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ angular.module('stellarClient').controller('SettingsCtrl', function($scope, $htt

$scope.handleServerError = function (element) {
return function (error) {
var message = error.status === 'fail' ? error.message : 'Server error';
var message = error.data.status === 'fail' ? error.data.message : 'Server error';
Util.showTooltip(element, message, 'error', 'top');
};
};
Expand Down
61 changes: 39 additions & 22 deletions app/scripts/controllers/settings-email-controller.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
angular.module('stellarClient').controller('SettingsEmailCtrl', function($scope, $http, session, singletonPromise) {
angular.module('stellarClient').controller('SettingsEmailCtrl', function($scope, $http, $q, session, singletonPromise) {

$scope.$on('settings-refresh', function () {
$scope.email = session.getUser().getEmailAddress();
$scope.emailVerified = session.getUser().isEmailVerified();
$scope.verifyToken = null;
$scope.resetEmailState();
});

Expand All @@ -27,36 +28,52 @@ angular.module('stellarClient').controller('SettingsEmailCtrl', function($scope,
return changeEmail();
} else if ($scope.emailState === 'verify') {
return verifyEmail();
} else {
return;
}
});

function verifyEmail () {
var verifyToken = $scope.verifyToken;
return session.getUser().verifyEmail(verifyToken)
.then(function (response) {
if (response.data.data && response.data.data.serverRecoveryCode) {
return session.get('wallet').storeRecoveryData(verifyToken, response.data.data.serverRecoveryCode);
}
})
.then(function () {
return $scope.refreshAndInitialize();
})
.then(function () {
$scope.verifyToken = null;
})
.catch($scope.handleServerError($('#email-input')));
.then(function (response) {
if (response.data.data && response.data.data.serverRecoveryCode) {
var userPartBytes = bs58.decode(verifyToken);
var serverPartBytes = bs58.decode(response.data.data.serverRecoveryCode);
var fullRecoveryCodeBytes = userPartBytes.concat(serverPartBytes);
return bs58.encode(fullRecoveryCodeBytes);
} else {
return $q.reject();
}
})
.then(function(fullRecoveryCode) {
var wallet = session.get('wallet');
return wallet.walletV2.enableRecovery({
recoveryCode: fullRecoveryCode,
secretKey: wallet.keychainData.signingKeys.secretKey
});
})
.then(function () {
return $scope.$parent.refreshAndInitialize();
})
.then(function () {
$scope.verifyToken = null;
})
.catch(StellarWallet.errors.ConnectionError, function(e) {
Util.showTooltip($('#verify-input'), 'Error connecting wallet server.', 'error', 'top');
})
.catch($scope.$parent.handleServerError($('#verify-input')))
.finally(function() {
$scope.$apply();
});
}

function changeEmail () {
return session.getUser().changeEmail($scope.newEmail)
.then(function () {
return $scope.refreshAndInitialize();
})
.then(function () {
$scope.newEmail = null;
})
.catch($scope.handleServerError($('#verify-input')));
.then(function () {
return $scope.$parent.refreshAndInitialize();
})
.then(function () {
$scope.newEmail = null;
})
.catch($scope.$parent.handleServerError($('#email-input')));
}
});
147 changes: 111 additions & 36 deletions app/scripts/controllers/settings-recovery-controller.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,133 @@
'use strict';

angular.module('stellarClient').controller('SettingsRecoveryCtrl', function($scope, session) {
var wallet = session.get('wallet').walletV2;
angular.module('stellarClient').controller('SettingsRecoveryCtrl', function($scope, $http, session, stellarApi, UserPrivateInfo, FlashMessages) {
var wallet = session.get('wallet');
var params = {
username: session.get('username'),
updateToken: wallet.keychainData.updateToken
};

var userRecoveryCode = null;
var serverRecoveryCode = null;

$scope.reset = function () {
$scope.error = null;
$scope.enabling = false;
$scope.resetting = false;
$scope.sendingRecoveryCode = false;
$scope.code = null;

stellarApi.User.getNewRecoveryCode(params)
.then(function(response) {
if (response.data.status === 'success') {
$scope.resetting = true;
userRecoveryCode = response.data.userRecoveryCode;
serverRecoveryCode = response.data.serverRecoveryCode;
} else {
$scope.resetting = false;
}
});
};
$scope.reset();
$scope.$on('settings-refresh', $scope.reset);

$scope.$on('settings-recovery-clicked', function($event, toggle) {
if (toggle.on) {
disableRecovery();
} else {
enableRecovery();
}
toggleRecovery(!toggle.on);
});

function disableRecovery() {
$scope.enabling = false;
$scope.$emit('settings-recovery-toggled', false);
function toggleRecovery(value) {
$http.post(Options.API_SERVER+'/user/setrecover', _.extend(params, {
recover: value
})).success(function () {
$scope.$emit('settings-recovery-toggled', value);
}).error(function () {
FlashMessages.add({
title: 'Server error',
info: 'There was an error contacting server. Please try again later.',
type: 'error'
});
});
}

var recoveryCode = null;
$scope.recoveryCode = null; // Temp
$scope.resetRecovery = function($event) {
$event.preventDefault();
$scope.sendingRecoveryCode = true;

function enableRecovery() {
$scope.enabling = true;
recoveryCode = StellarWallet.util.generateRandomRecoveryCode();
$scope.recoveryCode = recoveryCode; // temp
}
stellarApi.User.changeRecoveryToken(params)
.success(function() {
stellarApi.User.getNewRecoveryCode(params)
.then(function(response) {
if (response.data.status === 'success') {
$scope.resetting = true;
userRecoveryCode = response.data.userRecoveryCode;
serverRecoveryCode = response.data.serverRecoveryCode;
}
});
}).error(function (response){
$scope.resetting = false;
if (response.code === 'no_email') {
FlashMessages.add({
title: 'No email added',
info: 'Add and verify your email first. Recovery token will be sent to your email inbox.'
});
} else {
FlashMessages.add({
title: 'Recovery Error',
info: 'There was error trying to generate recovery token. Please try again later.',
type: 'error'
});
}
}).finally(function() {
$scope.sendingRecoveryCode = false;
});
};

$scope.confirmEnableRecovery = function($event) {
$scope.confirmResetRecovery = function($event) {
$event.preventDefault();
if ($scope.code === recoveryCode) {
wallet.enableRecovery({
secretKey: session.get('wallet').keychainData.signingKeys.secretKey,
recoveryCode: $scope.code
}).then(function() {
recoveryCode = null;
$scope.code = null;
$scope.recoveryCode = null; // Temp
$scope.enabling = false;
$scope.$emit('settings-recovery-toggled', true);
if (session.isPersistent()) {
session.get('wallet').saveLocal(); // We need to rewrite wallet object because lockVersion has changed
}
}).finally(function() {
$scope.$apply();
}); // TODO handle errors
} else {

if ($scope.code !== userRecoveryCode) {
$scope.error = 'Incorrect recovery code. Please try again.';
return;
}

var userPartBytes = bs58.decode($scope.code);
var serverPartBytes = bs58.decode(serverRecoveryCode);
var fullRecoveryCodeBytes = userPartBytes.concat(serverPartBytes);
var fullRecoveryCode = bs58.encode(fullRecoveryCodeBytes);
wallet.walletV2.enableRecovery({
recoveryCode: fullRecoveryCode,
secretKey: wallet.keychainData.signingKeys.secretKey
}).then(function() {
return stellarApi.User.finishChangeRecoveryToken(_.extend(params, {
userRecoveryCode: $scope.code
}));
}).then(function() {
$scope.code = null;
$scope.resetting = false;
FlashMessages.add({
title: 'Success',
info: 'Your recovery token has been reset!'
});
if (session.isPersistent()) {
session.get('wallet').saveLocal(); // We need to rewrite wallet object because lockVersion has changed
}
}).catch(StellarWallet.errors.ConnectionError, function(e) {
$scope.error = 'Connection error. Please try again.';
}).catch(function(e) {
$scope.error = 'Unknown error. Please try again.';
// TODO add logging
}).finally(function() {
$scope.$apply();
});
};

$scope.cancelResetRecovery = function($event) {
$event.preventDefault();

stellarApi.User.cancelChangingRecoveryCode(params)
.success(function() {
$scope.resetting = false;
}).error(function() {
$scope.error = 'Cannot cancel changing recovery code now. Please try again.';
});
};
});
Loading

0 comments on commit 898613f

Please sign in to comment.