mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 02:42:17 -05:00
Remove cached OAuth token before reconnect
This commit is contained in:
parent
eb0002c8d5
commit
c4337fba30
@ -13,7 +13,7 @@
|
|||||||
"crypto-lib": "~0.2.1",
|
"crypto-lib": "~0.2.1",
|
||||||
"imap-client": "~0.3.7",
|
"imap-client": "~0.3.7",
|
||||||
"mailreader": "~0.3.5",
|
"mailreader": "~0.3.5",
|
||||||
"pgpmailer": "~0.3.10",
|
"pgpmailer": "~0.3.11",
|
||||||
"pgpbuilder": "~0.3.7",
|
"pgpbuilder": "~0.3.7",
|
||||||
"requirejs": "2.1.14",
|
"requirejs": "2.1.14",
|
||||||
"axe-logger": "~0.0.2",
|
"axe-logger": "~0.0.2",
|
||||||
|
@ -133,7 +133,8 @@ define(function(require) {
|
|||||||
function initClients(credentials) {
|
function initClients(credentials) {
|
||||||
var pgpMailer = new PgpMailer(credentials.smtp, self._pgpbuilder);
|
var pgpMailer = new PgpMailer(credentials.smtp, self._pgpbuilder);
|
||||||
var imapClient = new ImapClient(credentials.imap);
|
var imapClient = new ImapClient(credentials.imap);
|
||||||
imapClient.onError = onImapError;
|
imapClient.onError = onConnectionError;
|
||||||
|
pgpMailer.onError = onConnectionError;
|
||||||
|
|
||||||
// certificate update handling
|
// certificate update handling
|
||||||
imapClient.onCert = self._auth.handleCertificateUpdate.bind(self._auth, 'imap', self.onConnect, self.onError);
|
imapClient.onCert = self._auth.handleCertificateUpdate.bind(self._auth, 'imap', self.onConnect, self.onError);
|
||||||
@ -151,19 +152,19 @@ define(function(require) {
|
|||||||
}, callback);
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onImapError(error) {
|
function onConnectionError(error) {
|
||||||
axe.debug('IMAP connection error. Attempting reconnect in ' + config.reconnectInterval + ' ms. Error: ' + (error.errMsg || error.message) + (error.stack ? ('\n' + error.stack) : ''));
|
axe.debug('Connection error. Attempting reconnect in ' + config.reconnectInterval + ' ms. Error: ' + (error.errMsg || error.message) + (error.stack ? ('\n' + error.stack) : ''));
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
axe.debug('IMAP reconnecting...');
|
axe.debug('Reconnecting...');
|
||||||
// re-init client modules on error
|
// re-init client modules on error
|
||||||
self.onConnect(function(err) {
|
self.onConnect(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
axe.error('IMAP reconnect attempt failed! ' + (err.errMsg || err.message) + (err.stack ? ('\n' + err.stack) : ''));
|
axe.error('Reconnect attempt failed! ' + (err.errMsg || err.message) + (err.stack ? ('\n' + err.stack) : ''));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
axe.debug('IMAP reconnect attempt complete.');
|
axe.debug('Reconnect attempt complete.');
|
||||||
});
|
});
|
||||||
}, config.reconnectInterval);
|
}, config.reconnectInterval);
|
||||||
}
|
}
|
||||||
|
@ -256,8 +256,18 @@ define(function(require) {
|
|||||||
Auth.prototype.getOAuthToken = function(callback) {
|
Auth.prototype.getOAuthToken = function(callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// get a fresh oauth token
|
if (self.oauthToken) {
|
||||||
self._oauth.getOAuthToken(self.emailAddress, function(err, oauthToken) {
|
// removed cached token and get a new one
|
||||||
|
self._oauth.refreshToken({
|
||||||
|
emailAddress: self.emailAddress,
|
||||||
|
oldToken: self.oauthToken
|
||||||
|
}, onToken);
|
||||||
|
} else {
|
||||||
|
// get a fresh oauth token
|
||||||
|
self._oauth.getOAuthToken(self.emailAddress, onToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onToken(err, oauthToken) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
@ -278,7 +288,7 @@ define(function(require) {
|
|||||||
self.emailAddress = emailAddress;
|
self.emailAddress = emailAddress;
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,12 +5,17 @@ define(function() {
|
|||||||
this._googleApi = googleApi;
|
this._googleApi = googleApi;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if chrome.identity api is supported
|
||||||
|
* @return {Boolean} If is supported
|
||||||
|
*/
|
||||||
OAuth.prototype.isSupported = function() {
|
OAuth.prototype.isSupported = function() {
|
||||||
return !!(window.chrome && chrome.identity);
|
return !!(window.chrome && chrome.identity);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request an OAuth token from chrome for gmail users
|
* Request an OAuth token from chrome for gmail users
|
||||||
|
* @param {String} emailAddress The user's email address (optional)
|
||||||
*/
|
*/
|
||||||
OAuth.prototype.getOAuthToken = function(emailAddress, callback) {
|
OAuth.prototype.getOAuthToken = function(emailAddress, callback) {
|
||||||
var idOptions = {
|
var idOptions = {
|
||||||
@ -19,7 +24,7 @@ define(function() {
|
|||||||
|
|
||||||
// check which runtime the app is running under
|
// check which runtime the app is running under
|
||||||
chrome.runtime.getPlatformInfo(function(platformInfo) {
|
chrome.runtime.getPlatformInfo(function(platformInfo) {
|
||||||
if ((chrome && chrome.runtime && chrome.runtime.lastError) || !platformInfo) {
|
if (chrome.runtime.lastError || !platformInfo) {
|
||||||
callback(new Error('Error getting chrome platform info!'));
|
callback(new Error('Error getting chrome platform info!'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -31,7 +36,7 @@ define(function() {
|
|||||||
|
|
||||||
// get OAuth Token from chrome
|
// get OAuth Token from chrome
|
||||||
chrome.identity.getAuthToken(idOptions, function(token) {
|
chrome.identity.getAuthToken(idOptions, function(token) {
|
||||||
if ((chrome && chrome.runtime && chrome.runtime.lastError) || !token) {
|
if (chrome.runtime.lastError || !token) {
|
||||||
callback({
|
callback({
|
||||||
errMsg: 'Error fetching an OAuth token for the user!'
|
errMsg: 'Error fetching an OAuth token for the user!'
|
||||||
});
|
});
|
||||||
@ -43,6 +48,32 @@ define(function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an old OAuth token and get a new one.
|
||||||
|
* @param {String} options.oldToken The old token to be removed
|
||||||
|
* @param {String} options.emailAddress The user's email address (optional)
|
||||||
|
*/
|
||||||
|
OAuth.prototype.refreshToken = function(options, callback) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (!options.oldToken) {
|
||||||
|
callback(new Error('oldToken option not set!'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove cached token
|
||||||
|
chrome.identity.removeCachedAuthToken({
|
||||||
|
token: options.oldToken
|
||||||
|
}, function() {
|
||||||
|
// get a new token
|
||||||
|
self.getOAuthToken(options.emailAddress, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get email address from google api
|
||||||
|
* @param {String} token The oauth token
|
||||||
|
*/
|
||||||
OAuth.prototype.queryEmailAddress = function(token, callback) {
|
OAuth.prototype.queryEmailAddress = function(token, callback) {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
callback({
|
callback({
|
||||||
|
@ -146,6 +146,26 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#getOAuthToken', function() {
|
describe('#getOAuthToken', function() {
|
||||||
|
it('should refresh token with known email address', function(done) {
|
||||||
|
auth.emailAddress = emailAddress;
|
||||||
|
auth.oauthToken = 'oldToken';
|
||||||
|
|
||||||
|
oauthStub.refreshToken.withArgs({
|
||||||
|
emailAddress: emailAddress,
|
||||||
|
oldToken: 'oldToken'
|
||||||
|
}).yieldsAsync(null, oauthToken);
|
||||||
|
|
||||||
|
auth.getOAuthToken(function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(auth.emailAddress).to.equal(emailAddress);
|
||||||
|
expect(auth.oauthToken).to.equal(oauthToken);
|
||||||
|
|
||||||
|
expect(oauthStub.refreshToken.calledOnce).to.be.true;
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should fetch token with known email address', function(done) {
|
it('should fetch token with known email address', function(done) {
|
||||||
auth.emailAddress = emailAddress;
|
auth.emailAddress = emailAddress;
|
||||||
oauthStub.getOAuthToken.withArgs(emailAddress).yieldsAsync(null, oauthToken);
|
oauthStub.getOAuthToken.withArgs(emailAddress).yieldsAsync(null, oauthToken);
|
||||||
|
@ -6,7 +6,7 @@ define(function(require) {
|
|||||||
expect = chai.expect;
|
expect = chai.expect;
|
||||||
|
|
||||||
describe('OAuth unit tests', function() {
|
describe('OAuth unit tests', function() {
|
||||||
var oauth, googleApiStub, identityStub, getPlatformInfoStub,
|
var oauth, googleApiStub, identityStub, getPlatformInfoStub, removeCachedStub,
|
||||||
testEmail = 'test@example.com';
|
testEmail = 'test@example.com';
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@ -21,6 +21,11 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
identityStub = sinon.stub(window.chrome.identity, 'getAuthToken');
|
identityStub = sinon.stub(window.chrome.identity, 'getAuthToken');
|
||||||
|
|
||||||
|
if (typeof window.chrome.identity.removeCachedAuthToken !== 'function') {
|
||||||
|
window.chrome.identity.removeCachedAuthToken = function() {};
|
||||||
|
}
|
||||||
|
removeCachedStub = sinon.stub(window.chrome.identity, 'removeCachedAuthToken');
|
||||||
|
|
||||||
window.chrome.runtime = window.chrome.runtime || {};
|
window.chrome.runtime = window.chrome.runtime || {};
|
||||||
if (typeof window.chrome.runtime.getPlatformInfo !== 'function') {
|
if (typeof window.chrome.runtime.getPlatformInfo !== 'function') {
|
||||||
window.chrome.runtime.getPlatformInfo = function() {};
|
window.chrome.runtime.getPlatformInfo = function() {};
|
||||||
@ -31,6 +36,7 @@ define(function(require) {
|
|||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
identityStub.restore();
|
identityStub.restore();
|
||||||
getPlatformInfoStub.restore();
|
getPlatformInfoStub.restore();
|
||||||
|
removeCachedStub.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isSupported', function() {
|
describe('isSupported', function() {
|
||||||
@ -39,6 +45,61 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('refreshToken', function() {
|
||||||
|
var getOAuthTokenStub;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
getOAuthTokenStub = sinon.stub(oauth, 'getOAuthToken');
|
||||||
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
getOAuthTokenStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work', function() {
|
||||||
|
removeCachedStub.withArgs({
|
||||||
|
token: 'oldToken'
|
||||||
|
}).yields();
|
||||||
|
|
||||||
|
getOAuthTokenStub.withArgs(testEmail).yields();
|
||||||
|
|
||||||
|
oauth.refreshToken({
|
||||||
|
oldToken: 'oldToken',
|
||||||
|
emailAddress: testEmail
|
||||||
|
}, function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(removeCachedStub.calledOnce).to.be.true;
|
||||||
|
expect(getOAuthTokenStub.calledOnce).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work without email', function() {
|
||||||
|
removeCachedStub.withArgs({
|
||||||
|
token: 'oldToken'
|
||||||
|
}).yields();
|
||||||
|
|
||||||
|
getOAuthTokenStub.withArgs(undefined).yields();
|
||||||
|
|
||||||
|
oauth.refreshToken({
|
||||||
|
oldToken: 'oldToken',
|
||||||
|
}, function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(removeCachedStub.calledOnce).to.be.true;
|
||||||
|
expect(getOAuthTokenStub.calledOnce).to.be.true;
|
||||||
|
expect(getOAuthTokenStub.calledWith(undefined)).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail without all options', function() {
|
||||||
|
oauth.refreshToken({
|
||||||
|
emailAddress: testEmail
|
||||||
|
}, function(err) {
|
||||||
|
expect(err).to.exist;
|
||||||
|
expect(removeCachedStub.called).to.be.false;
|
||||||
|
expect(getOAuthTokenStub.called).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getOAuthToken', function() {
|
describe('getOAuthToken', function() {
|
||||||
it('should work for empty emailAddress', function(done) {
|
it('should work for empty emailAddress', function(done) {
|
||||||
getPlatformInfoStub.yields({
|
getPlatformInfoStub.yields({
|
||||||
|
Loading…
Reference in New Issue
Block a user