mirror of
https://github.com/moparisthebest/mail
synced 2025-01-30 22:50:17 -05:00
[WO-587] implement user logout
This commit is contained in:
parent
f66fbf592c
commit
bedb69973c
@ -32,7 +32,7 @@ define(function(require) {
|
|||||||
var self = {};
|
var self = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the application
|
* Start the application.
|
||||||
*/
|
*/
|
||||||
self.start = function(options, callback) {
|
self.start = function(options, callback) {
|
||||||
if (self.started) {
|
if (self.started) {
|
||||||
@ -66,6 +66,9 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the dependency tree.
|
||||||
|
*/
|
||||||
self.buildModules = function() {
|
self.buildModules = function() {
|
||||||
var lawnchairDao, restDao, pubkeyDao, privkeyDao, crypto, emailDao, keychain, pgp, userStorage, pgpbuilder, oauth, appConfigStore, auth;
|
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;
|
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() {
|
self.isOnline = function() {
|
||||||
return navigator.onLine;
|
return navigator.onLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler that is called when the user agent goes offline.
|
||||||
|
*/
|
||||||
self.onDisconnect = function() {
|
self.onDisconnect = function() {
|
||||||
self._emailDao.onDisconnect();
|
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) {
|
self.onConnect = function(callback) {
|
||||||
if (!self.isOnline() || !self._emailDao || !self._emailDao._account) {
|
if (!self.isOnline() || !self._emailDao || !self._emailDao._account) {
|
||||||
// prevent connection infinite loop
|
// 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;
|
return self;
|
||||||
});
|
});
|
@ -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;
|
return Auth;
|
||||||
});
|
});
|
@ -56,6 +56,19 @@ define(function(require) {
|
|||||||
}, $scope.onError);
|
}, $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
|
// Start
|
||||||
//
|
//
|
||||||
|
@ -1206,13 +1206,24 @@ define(function(require) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handler should be invoked when navigator.onLine === false. It will discard
|
* This handler should be invoked when navigator.onLine === false.
|
||||||
* the imap client and pgp mailer
|
* It will discard the imap client and pgp mailer
|
||||||
*/
|
*/
|
||||||
EmailDAO.prototype.onDisconnect = function() {
|
EmailDAO.prototype.onDisconnect = function(callback) {
|
||||||
this._account.online = false;
|
var self = this;
|
||||||
this._imapClient = undefined;
|
|
||||||
this._pgpMailer = undefined;
|
// 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
<li><a href="#" wo-touch="state.privateKeyUpload.toggle(true); $event.preventDefault()">Key sync (experimental)</a></li>
|
<li><a href="#" wo-touch="state.privateKeyUpload.toggle(true); $event.preventDefault()">Key sync (experimental)</a></li>
|
||||||
<li><a href="#" wo-touch="state.writer.reportBug(); $event.preventDefault()">Report a bug</a></li>
|
<li><a href="#" wo-touch="state.writer.reportBug(); $event.preventDefault()">Report a bug</a></li>
|
||||||
<li><a href="#" wo-touch="state.about.toggle(true); $event.preventDefault()">About</a></li>
|
<li><a href="#" wo-touch="state.about.toggle(true); $event.preventDefault()">About</a></li>
|
||||||
|
<li><a href="#" wo-touch="logout(); $event.preventDefault()">Logout</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -64,6 +64,22 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('logout', function() {
|
||||||
|
it('should work', function(done) {
|
||||||
|
authStub.logout.yields();
|
||||||
|
emailDaoStub.onDisconnect.yields(new Error());
|
||||||
|
|
||||||
|
controller.onError = function(err) {
|
||||||
|
expect(err).to.exist;
|
||||||
|
expect(authStub.logout.calledOnce).to.be.true;
|
||||||
|
expect(emailDaoStub.onDisconnect.calledOnce).to.be.true;
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.logout();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('onConnect', function() {
|
describe('onConnect', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
controller._emailDao._account = {};
|
controller._emailDao._account = {};
|
||||||
|
@ -350,5 +350,29 @@ define(function(require) {
|
|||||||
auth.handleCertificateUpdate('imap', onConnect, callback, dummyCert);
|
auth.handleCertificateUpdate('imap', onConnect, callback, dummyCert);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#logout', function() {
|
||||||
|
it('should fail to to error in calling db clear', function(done) {
|
||||||
|
storageStub.clear.yields(new Error());
|
||||||
|
|
||||||
|
auth.logout(function(err) {
|
||||||
|
expect(err).to.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work', function(done) {
|
||||||
|
storageStub.clear.yields();
|
||||||
|
|
||||||
|
auth.logout(function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(auth.password).to.be.undefined;
|
||||||
|
expect(auth.initialized).to.be.undefined;
|
||||||
|
expect(auth.credentialsDirty).to.be.undefined;
|
||||||
|
expect(auth.passwordNeedsDecryption).to.be.undefined;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -1774,8 +1774,10 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#onDisconnect', function() {
|
describe('#onDisconnect', function() {
|
||||||
it('should discard imapClient and pgpMailer', function() {
|
it('should discard imapClient and pgpMailer', function(done) {
|
||||||
dao.onDisconnect();
|
imapClientStub.logout.yieldsAsync();
|
||||||
|
|
||||||
|
dao.onDisconnect(done);
|
||||||
|
|
||||||
expect(dao._account.online).to.be.false;
|
expect(dao._account.online).to.be.false;
|
||||||
expect(dao._imapClient).to.not.exist;
|
expect(dao._imapClient).to.not.exist;
|
||||||
|
Loading…
Reference in New Issue
Block a user