1
0
mirror of https://github.com/moparisthebest/mail synced 2024-11-26 19:02:20 -05:00

implement feedback on keygen and login

This commit is contained in:
Tankred Hase 2013-11-04 14:20:14 +01:00
parent 2b06c3146e
commit 24f97db09e
11 changed files with 121 additions and 102 deletions

View File

@ -22,7 +22,7 @@ require([
// set router paths // set router paths
app.config(function($routeProvider) { app.config(function($routeProvider) {
$routeProvider.when('/login', { $routeProvider.when('/login', {
templateUrl: 'tpl/loading.html', templateUrl: 'tpl/login.html',
controller: LoginCtrl controller: LoginCtrl
}); });
$routeProvider.when('/login-existing', { $routeProvider.when('/login-existing', {

View File

@ -4,49 +4,42 @@ define(function(require) {
var appController = require('js/app-controller'); var appController = require('js/app-controller');
var LoginExistingCtrl = function($scope, $location) { var LoginExistingCtrl = function($scope, $location) {
var emailDao = appController._emailDao;
$scope.buttonEnabled = true; $scope.buttonEnabled = true;
$scope.incorrect = false; $scope.incorrect = false;
$scope.confirmPassphrase = function() { $scope.confirmPassphrase = function() {
var passphrase = $scope.passphrase, if (!$scope.passphrase) {
emailDao = appController._emailDao;
if (!passphrase) {
return; return;
} }
// disable button once loggin has started // disable button once loggin has started
$scope.buttonEnabled = false; $scope.buttonEnabled = false;
$scope.incorrect = false; $scope.incorrect = false;
unlockCrypto(imapLogin); unlockCrypto();
};
function unlockCrypto(callback) { function unlockCrypto() {
var userId = emailDao._account.emailAddress; var userId = emailDao._account.emailAddress;
emailDao._keychain.getUserKeyPair(userId, function(err, keypair) { appController._emailDao._keychain.getUserKeyPair(userId, function(err, keypair) {
if (err) {
callback(err);
return;
}
emailDao.unlock(keypair, passphrase, callback);
});
}
function imapLogin(err) {
if (err) { if (err) {
handleError(err); handleError(err);
return; return;
} }
emailDao.unlock(keypair, $scope.passphrase, onUnlock);
});
}
// login to imap backend function onUnlock(err) {
appController._emailDao.imapLogin(function(err) { if (err) {
if (err) { handleError(err);
handleError(err); return;
return;
}
onLogin();
});
} }
};
$location.path('/desktop');
$scope.$apply();
}
function handleError(err) { function handleError(err) {
$scope.incorrect = true; $scope.incorrect = true;
@ -54,11 +47,6 @@ define(function(require) {
$scope.$apply(); $scope.$apply();
console.error(err); console.error(err);
} }
function onLogin() {
$location.path('/desktop');
$scope.$apply();
}
}; };
return LoginExistingCtrl; return LoginExistingCtrl;

View File

@ -51,26 +51,26 @@ define(function(require) {
} }
var id = keys.keyId.substring(8, keys.keyId.length); var id = keys.keyId.substring(8, keys.keyId.length);
dl.createDownload(keys.publicKeyArmored + keys.privateKeyArmored, id + '.asc', 'text/plain'); dl.createDownload({
$scope.exported = true; content: keys.publicKeyArmored + keys.privateKeyArmored,
filename: id + '.asc',
contentType: 'text/plain'
}, onSave);
}); });
};
$scope.proceed = function() { function onSave(err) {
// login to imap backend
appController._emailDao.imapLogin(function(err) {
if (err) { if (err) {
console.error(err); console.error(err);
return; return;
} }
onLogin(); $scope.proceed();
}); $scope.$apply();
}
}; };
function onLogin() { $scope.proceed = function() {
$location.path('/desktop'); $location.path('/desktop');
$scope.$apply(); };
}
function setState(state, async) { function setState(state, async) {
$scope.state = state; $scope.state = state;

View File

@ -5,64 +5,53 @@ define(function(require) {
appController = require('js/app-controller'); appController = require('js/app-controller');
var LoginExistingCtrl = function($scope, $location) { var LoginExistingCtrl = function($scope, $location) {
var emailDao = appController._emailDao;
$scope.incorrect = false; $scope.incorrect = false;
$scope.confirmPassphrase = function() { $scope.confirmPassphrase = function() {
var passphrase = $scope.passphrase, if (!$scope.passphrase) {
emailDao = appController._emailDao;
if (!passphrase) {
$scope.incorrect = true; $scope.incorrect = true;
return; return;
} }
$scope.incorrect = false; $scope.incorrect = false;
unlockCrypto(imapLogin); unlockCrypto();
};
function unlockCrypto(callback) { function unlockCrypto() {
var userId = emailDao._account.emailAddress; var userId = emailDao._account.emailAddress;
emailDao._keychain.getUserKeyPair(userId, function(err, keypair) { emailDao._keychain.getUserKeyPair(userId, function(err, keypair) {
if (err) {
callback(err);
return;
}
keypair.privateKey = {
_id: keypair.publicKey._id,
userId: userId,
encryptedKey: $scope.key.privateKeyArmored
};
emailDao.unlock(keypair, passphrase, function(err) {
if (err) {
$scope.incorrect = true;
$scope.$apply();
callback(err);
return;
}
emailDao._keychain.putUserKeyPair(keypair, callback);
});
});
}
function imapLogin(err) {
if (err) { if (err) {
console.error(err); console.error(err);
return; return;
} }
// login to imap backend keypair.privateKey = {
appController._emailDao.imapLogin(function(err) { _id: keypair.publicKey._id,
userId: userId,
encryptedKey: $scope.key.privateKeyArmored
};
emailDao.unlock(keypair, $scope.passphrase, function(err) {
if (err) { if (err) {
$scope.incorrect = true;
$scope.$apply();
console.error(err); console.error(err);
return; return;
} }
onLogin();
});
}
};
function onLogin() { emailDao._keychain.putUserKeyPair(keypair, onUnlock);
});
});
}
function onUnlock(err) {
if (err) {
console.error(err);
return;
}
$location.path('/desktop'); $location.path('/desktop');
$scope.$apply(); $scope.$apply();
} }

View File

@ -27,13 +27,22 @@ define(function(require) {
return; return;
} }
// initiate controller by creating email dao
appController.init(auth.emailAddress, auth.token, function(err, availableKeys) { appController.init(auth.emailAddress, auth.token, function(err, availableKeys) {
if (err) { if (err) {
console.error(err); console.error(err);
return; return;
} }
redirect(availableKeys); // login to imap backend
appController._emailDao.imapLogin(function(err) {
if (err) {
console.error(err);
console.log('Error logging into IMAP... proceeding in offline mode.');
}
redirect(availableKeys);
});
}); });
}); });
} }

View File

@ -3,23 +3,40 @@ define(function() {
var dl = {}; var dl = {};
dl.createDownload = function(content, filename, contentType) { dl.createDownload = function(options, callback) {
contentType = contentType || 'application/octet-stream'; var contentType = options.contentType || 'application/octet-stream';
chrome.fileSystem.chooseEntry({ chrome.fileSystem.chooseEntry({
type: 'saveFile', type: 'saveFile',
suggestedName: filename suggestedName: options.filename
}, function(file) { }, onEntry);
function onEntry(file) {
if (!file) { if (!file) {
callback();
return; return;
} }
file.createWriter(function(writer) { file.createWriter(onWriter, onError);
writer.onerror = console.error; }
writer.onwriteend = function() {};
writer.write(new Blob([content], { function onWriter(writer) {
type: contentType writer.onerror = onError;
})); writer.onwriteend = onEnd;
}, console.error); writer.write(new Blob([options.content], {
}); type: contentType
}));
}
function onError(e) {
console.error(e);
callback({
errMsg: 'Error exporting keypair to file!'
});
}
function onEnd() {
callback();
}
}; };
return dl; return dl;

View File

@ -19,6 +19,7 @@
@import "components/layout"; @import "components/layout";
// Views // Views
@import "views/shared";
@import "views/navigation"; @import "views/navigation";
@import "views/mail-list"; @import "views/mail-list";
@import "views/read"; @import "views/read";

View File

@ -0,0 +1,3 @@
.waiting-cursor {
cursor: wait;
}

View File

@ -1 +0,0 @@
<p>loading...</p>

View File

@ -1,4 +1,4 @@
<div class="view-login"> <div class="view-login" ng-class="{'waiting-cursor': state === states.PROCESSING}">
<div class="logo-wrapper"> <div class="logo-wrapper">
<div class="logo"></div> <div class="logo"></div>
@ -7,7 +7,7 @@
<div class="content" ng-show="state === states.IDLE"> <div class="content" ng-show="state === states.IDLE">
<h1>Set passphrase</h1> <h1>Set passphrase</h1>
<p>If you forget your passphrase, there is no way to restore your data. So it might be a good idea to write it down and keep it in a safe place.</p> <p>This is used to protect your keypair. If you forget your passphrase, there is no way to restore your data.</p>
<form> <form>
<div> <div>
@ -23,15 +23,15 @@
<div class="content" ng-show="state === states.PROCESSING"> <div class="content" ng-show="state === states.PROCESSING">
<h1>Generating keypair</h1> <h1>Generating keypair</h1>
<p>A batch of highly trained monkeys has been dispatched to collect entropy for your personal keypair. Please stand by...</p> <p>Please stand by. This can take a while...</p>
</div><!--/content--> </div><!--/content-->
<div class="content" ng-show="state === states.DONE"> <div class="content" ng-show="state === states.DONE">
<h1>Keypair generated</h1> <h1>Keypair generated</h1>
<p>A keypair has been generated for you. Please store this key pair in a safe location before you proceed.</p> <p>Your personal keypair has been generated. You can export it (e.g. to a USB flash drive) to setup whiteout on another computer or as a backup.</p>
<button ng-click="exportKeypair()" class="btn" tabindex="4">Export keypair</button> <button ng-click="exportKeypair()" class="btn" tabindex="4">Export now</button>
<button ng-click="proceed()" ng-disabled="!exported" class="btn" tabindex="4">Proceed</button> <button ng-click="proceed()" class="btn" tabindex="5">Do it later</button>
</div><!--/content--> </div><!--/content-->
</div> </div>

13
src/tpl/login.html Normal file
View File

@ -0,0 +1,13 @@
<div class="view-login waiting-cursor">
<div class="logo-wrapper">
<div class="logo"></div>
</div><!--/logo-->
<div class="content">
<h1>Login</h1>
<p>Authenticating with the mail server...</p>
</div><!--/content-->
</div>