From bedb69973cbb758ef963c38f02d1888900dd7bac Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Fri, 26 Sep 2014 19:14:53 +0200 Subject: [PATCH] [WO-587] implement user logout --- src/js/app-controller.js | 141 ++++++++++++++++++++----------- src/js/bo/auth.js | 23 +++++ src/js/controller/navigation.js | 13 +++ src/js/dao/email-dao.js | 23 +++-- src/tpl/navigation.html | 1 + test/unit/app-controller-test.js | 16 ++++ test/unit/auth-test.js | 24 ++++++ test/unit/email-dao-test.js | 8 +- 8 files changed, 190 insertions(+), 59 deletions(-) diff --git a/src/js/app-controller.js b/src/js/app-controller.js index 0535017..5745371 100644 --- a/src/js/app-controller.js +++ b/src/js/app-controller.js @@ -32,7 +32,7 @@ define(function(require) { var self = {}; /** - * Start the application + * Start the application. */ self.start = function(options, callback) { if (self.started) { @@ -66,6 +66,9 @@ define(function(require) { } }; + /** + * Initialize the dependency tree. + */ self.buildModules = function() { var lawnchairDao, restDao, pubkeyDao, privkeyDao, crypto, emailDao, keychain, pgp, userStorage, pgpbuilder, oauth, appConfigStore, auth; @@ -110,14 +113,101 @@ define(function(require) { emailDao.onError = self.onError; }; + /** + * Calls runtime hooks to check if an app update is available. + */ + self.checkForUpdate = function() { + self._updateHandler.checkForUpdate(self.onError); + }; + + /** + * Instanciate the mail email data access object and its dependencies. Login to imap on init. + */ + self.init = function(options, callback) { + // init user's local database + self._userStorage.init(options.emailAddress, function(err) { + if (err) { + callback(err); + return; + } + + // Migrate the databases if necessary + self._updateHandler.update(onUpdate); + }); + + function onUpdate(err) { + if (err) { + callback({ + errMsg: 'Update failed, please reinstall the app.', + err: err + }); + return; + } + + // account information for the email dao + var account = { + realname: options.realname, + emailAddress: options.emailAddress, + asymKeySize: config.asymKeySize + }; + + // init email dao + self._emailDao.init({ + account: account + }, function(err, keypair) { + if (err) { + callback(err); + return; + } + + callback(null, keypair); + }); + } + }; + + /** + * Check if the user agent is online. + */ self.isOnline = function() { return navigator.onLine; }; + /** + * Event handler that is called when the user agent goes offline. + */ self.onDisconnect = function() { self._emailDao.onDisconnect(); }; + /** + * Log the current user out by clear the app config store and deleting instances of imap-client and pgp-mailer. + */ + self.logout = function() { + var self = this; + + // clear app config store + self._auth.logout(function(err) { + if (err) { + self.onError(err); + return; + } + + // delete instance of imap-client and pgp-mailer + self._emailDao.onDisconnect(function(err) { + if (err) { + self.onError(err); + return; + } + + // navigate to login + window.location.href = '/'; + }); + }); + }; + + /** + * Event that is called when the user agent goes online. This create new instances of the imap-client and pgp-mailer and connects to the mail server. + */ self.onConnect = function(callback) { if (!self.isOnline() || !self._emailDao || !self._emailDao._account) { // prevent connection infinite loop @@ -174,54 +264,5 @@ define(function(require) { } }; - self.checkForUpdate = function() { - self._updateHandler.checkForUpdate(self.onError); - }; - - /** - * Instanciate the mail email data access object and its dependencies. Login to imap on init. - */ - self.init = function(options, callback) { - // init user's local database - self._userStorage.init(options.emailAddress, function(err) { - if (err) { - callback(err); - return; - } - - // Migrate the databases if necessary - self._updateHandler.update(onUpdate); - }); - - function onUpdate(err) { - if (err) { - callback({ - errMsg: 'Update failed, please reinstall the app.', - err: err - }); - return; - } - - // account information for the email dao - var account = { - realname: options.realname, - emailAddress: options.emailAddress, - asymKeySize: config.asymKeySize - }; - - // init email dao - self._emailDao.init({ - account: account - }, function(err, keypair) { - if (err) { - callback(err); - return; - } - - callback(null, keypair); - }); - } - }; - return self; }); \ No newline at end of file diff --git a/src/js/bo/auth.js b/src/js/bo/auth.js index 8d60560..be7d46d 100644 --- a/src/js/bo/auth.js +++ b/src/js/bo/auth.js @@ -426,5 +426,28 @@ define(function(require) { }); }; + /** + * Logout of the app by clearing the app config store and in memory credentials + */ + Auth.prototype.logout = function(callback) { + var self = this; + + // clear app config db + self._appConfigStore.clear(function(err) { + if (err) { + callback(err); + return; + } + + // clear in memory cache + self.setCredentials({}); + self.initialized = undefined; + self.credentialsDirty = undefined; + self.passwordNeedsDecryption = undefined; + + callback(); + }); + }; + return Auth; }); \ No newline at end of file diff --git a/src/js/controller/navigation.js b/src/js/controller/navigation.js index 11f2041..70bd878 100644 --- a/src/js/controller/navigation.js +++ b/src/js/controller/navigation.js @@ -56,6 +56,19 @@ define(function(require) { }, $scope.onError); }; + $scope.logout = function() { + $scope.onError({ + title: 'Logout', + message: 'Are you sure you want to logout?', + callback: function(confirm) { + if (confirm) { + appController.logout(); + } + }, + sync: true + }); + }; + // // Start // diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js index ddfa315..3207882 100644 --- a/src/js/dao/email-dao.js +++ b/src/js/dao/email-dao.js @@ -1206,13 +1206,24 @@ define(function(require) { }; /** - * This handler should be invoked when navigator.onLine === false. It will discard - * the imap client and pgp mailer + * This handler should be invoked when navigator.onLine === false. + * It will discard the imap client and pgp mailer */ - EmailDAO.prototype.onDisconnect = function() { - this._account.online = false; - this._imapClient = undefined; - this._pgpMailer = undefined; + EmailDAO.prototype.onDisconnect = function(callback) { + var self = this; + + // logout of imap-client + self._imapClient.logout(function() { + // ignore error, because it's not problem if logout fails + if (callback) { + callback(); + } + }); + + // discard clients + self._account.online = false; + self._imapClient = undefined; + self._pgpMailer = undefined; }; /** diff --git a/src/tpl/navigation.html b/src/tpl/navigation.html index 32f9f5c..7267f3a 100644 --- a/src/tpl/navigation.html +++ b/src/tpl/navigation.html @@ -20,6 +20,7 @@
  • Key sync (experimental)
  • Report a bug
  • About
  • +
  • Logout