mirror of
https://github.com/moparisthebest/mail
synced 2024-11-26 02:42:17 -05:00
[WO-300] Wrap chrome notifications and identity apis in modules
This commit is contained in:
parent
0143db7f0b
commit
a2f3e86545
@ -4,22 +4,24 @@
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
var ImapClient = require('imap-client'),
|
||||
mailreader = require('mailreader'),
|
||||
var Auth = require('js/bo/auth'),
|
||||
PGP = require('js/crypto/pgp'),
|
||||
PgpMailer = require('pgpmailer'),
|
||||
EmailDAO = require('js/dao/email-dao'),
|
||||
EmailSync = require('js/dao/email-sync'),
|
||||
OAuth = require('js/util/oauth'),
|
||||
PgpBuilder = require('pgpbuilder'),
|
||||
OutboxBO = require('js/bo/outbox'),
|
||||
mailreader = require('mailreader'),
|
||||
ImapClient = require('imap-client'),
|
||||
RestDAO = require('js/dao/rest-dao'),
|
||||
EmailDAO = require('js/dao/email-dao'),
|
||||
config = require('js/app-config').config,
|
||||
EmailSync = require('js/dao/email-sync'),
|
||||
KeychainDAO = require('js/dao/keychain-dao'),
|
||||
PublicKeyDAO = require('js/dao/publickey-dao'),
|
||||
LawnchairDAO = require('js/dao/lawnchair-dao'),
|
||||
KeychainDAO = require('js/dao/keychain-dao'),
|
||||
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
||||
InvitationDAO = require('js/dao/invitation-dao'),
|
||||
OutboxBO = require('js/bo/outbox'),
|
||||
PGP = require('js/crypto/pgp'),
|
||||
PgpBuilder = require('pgpbuilder'),
|
||||
UpdateHandler = require('js/util/update/update-handler'),
|
||||
config = require('js/app-config').config;
|
||||
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
||||
UpdateHandler = require('js/util/update/update-handler');
|
||||
|
||||
var self = {};
|
||||
|
||||
@ -41,64 +43,74 @@ define(function(require) {
|
||||
function onDeviceReady() {
|
||||
console.log('Starting app.');
|
||||
|
||||
self.buildModules();
|
||||
|
||||
// Handle offline and online gracefully
|
||||
window.addEventListener('online', self.onConnect.bind(self, options.onError));
|
||||
window.addEventListener('offline', self.onDisconnect.bind(self, options.onError));
|
||||
|
||||
// init app config storage
|
||||
self._appConfigStore = new DeviceStorageDAO(new LawnchairDAO());
|
||||
self._appConfigStore.init('app-config', callback);
|
||||
}
|
||||
};
|
||||
|
||||
self.onDisconnect = function(callback) {
|
||||
if (!self._emailDao) {
|
||||
// the following code only makes sense if the email dao has been initialized
|
||||
return;
|
||||
}
|
||||
self.buildModules = function() {
|
||||
var lawnchairDao, restDao, pubkeyDao, emailDao, emailSync, keychain, pgp, userStorage, pgpbuilder, oauth, appConfigStore;
|
||||
|
||||
// start the mailreader's worker thread
|
||||
mailreader.startWorker(config.workerPath + '/../lib/mailreader-parser-worker.js');
|
||||
|
||||
// init objects and inject dependencies
|
||||
restDao = new RestDAO();
|
||||
lawnchairDao = new LawnchairDAO();
|
||||
pubkeyDao = new PublicKeyDAO(restDao);
|
||||
oauth = new OAuth(new RestDAO('https://www.googleapis.com'));
|
||||
|
||||
self._appConfigStore = appConfigStore = new DeviceStorageDAO(new LawnchairDAO());
|
||||
self._auth = new Auth(appConfigStore, oauth, new RestDAO('/ca'));
|
||||
self._userStorage = userStorage = new DeviceStorageDAO(lawnchairDao);
|
||||
self._invitationDao = new InvitationDAO(restDao);
|
||||
self._keychain = keychain = new KeychainDAO(lawnchairDao, pubkeyDao);
|
||||
self._crypto = pgp = new PGP();
|
||||
self._pgpbuilder = pgpbuilder = new PgpBuilder();
|
||||
emailSync = new EmailSync(keychain, userStorage);
|
||||
self._emailDao = emailDao = new EmailDAO(keychain, pgp, userStorage, pgpbuilder, mailreader, emailSync);
|
||||
self._outboxBo = new OutboxBO(emailDao, keychain, userStorage);
|
||||
self._updateHandler = new UpdateHandler(appConfigStore, userStorage);
|
||||
};
|
||||
|
||||
self.isOnline = function() {
|
||||
return navigator.onLine;
|
||||
};
|
||||
|
||||
self.onDisconnect = function(callback) {
|
||||
self._emailDao.onDisconnect(null, callback);
|
||||
};
|
||||
|
||||
self.onConnect = function(callback) {
|
||||
if (!self._emailDao) {
|
||||
// the following code only makes sense if the email dao has been initialized
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self.isOnline()) {
|
||||
if (!self.isOnline() || !self._emailDao._account) {
|
||||
// prevent connection infinite loop
|
||||
console.log('Not connecting since user agent is offline.');
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// fetch pinned local ssl certificate
|
||||
self.getCertficate(function(err, certificate) {
|
||||
self._auth.getCredentials({}, function(err, credentials) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// get a fresh oauth token
|
||||
self.fetchOAuthToken(function(err, oauth) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
initClients(oauth, certificate);
|
||||
});
|
||||
initClients(credentials);
|
||||
});
|
||||
|
||||
function initClients(oauth, certificate) {
|
||||
function initClients(credentials) {
|
||||
var auth, imapOptions, imapClient, smtpOptions, pgpMailer;
|
||||
|
||||
auth = {
|
||||
XOAuth2: {
|
||||
user: oauth.emailAddress,
|
||||
user: credentials.emailAddress,
|
||||
clientId: config.gmail.clientId,
|
||||
accessToken: oauth.token
|
||||
accessToken: credentials.oauthToken
|
||||
}
|
||||
};
|
||||
imapOptions = {
|
||||
@ -106,7 +118,7 @@ define(function(require) {
|
||||
port: config.gmail.imap.port,
|
||||
host: config.gmail.imap.host,
|
||||
auth: auth,
|
||||
ca: [certificate]
|
||||
ca: [credentials.sslCert]
|
||||
};
|
||||
smtpOptions = {
|
||||
secureConnection: config.gmail.smtp.secure,
|
||||
@ -114,15 +126,23 @@ define(function(require) {
|
||||
host: config.gmail.smtp.host,
|
||||
auth: auth,
|
||||
tls: {
|
||||
ca: [certificate]
|
||||
ca: [credentials.sslCert]
|
||||
},
|
||||
onError: console.error
|
||||
};
|
||||
|
||||
imapClient = new ImapClient(imapOptions, mailreader);
|
||||
pgpMailer = new PgpMailer(smtpOptions, self._pgpbuilder);
|
||||
imapClient = new ImapClient(imapOptions, mailreader);
|
||||
imapClient.onError = onImapError;
|
||||
|
||||
imapClient.onError = function(err) {
|
||||
// connect to clients
|
||||
self._emailDao.onConnect({
|
||||
imapClient: imapClient,
|
||||
pgpMailer: pgpMailer
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function onImapError(err) {
|
||||
console.log('IMAP error.', err);
|
||||
console.log('IMAP reconnecting...');
|
||||
// re-init client modules on error
|
||||
@ -134,50 +154,11 @@ define(function(require) {
|
||||
|
||||
console.log('IMAP reconnect attempt complete.');
|
||||
});
|
||||
};
|
||||
|
||||
// connect to clients
|
||||
self._emailDao.onConnect({
|
||||
imapClient: imapClient,
|
||||
pgpMailer: pgpMailer
|
||||
}, callback);
|
||||
}
|
||||
};
|
||||
|
||||
self.getCertficate = function(localCallback) {
|
||||
if (self.certificate) {
|
||||
localCallback(null, self.certificate);
|
||||
return;
|
||||
}
|
||||
|
||||
// fetch pinned local ssl certificate
|
||||
var ca = new RestDAO({
|
||||
baseUri: '/ca'
|
||||
});
|
||||
|
||||
ca.get({
|
||||
uri: '/Google_Internet_Authority_G2.pem',
|
||||
type: 'text'
|
||||
}, function(err, cert) {
|
||||
if (err || !cert) {
|
||||
localCallback({
|
||||
errMsg: 'Could not fetch pinned certificate!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
self.certificate = cert;
|
||||
localCallback(null, self.certificate);
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
self.isOnline = function() {
|
||||
return navigator.onLine;
|
||||
};
|
||||
|
||||
self.checkForUpdate = function() {
|
||||
if (!chrome || !chrome.runtime || !chrome.runtime.onUpdateAvailable) {
|
||||
if (!window.chrome || !chrome.runtime || !chrome.runtime.onUpdateAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -197,167 +178,10 @@ define(function(require) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gracefully try to fetch the user's email address from local storage.
|
||||
* If not yet stored, handle online/offline cases on first use.
|
||||
*/
|
||||
self.getEmailAddress = function(callback) {
|
||||
// try to fetch email address from local storage
|
||||
self.getEmailAddressFromConfig(function(err, cachedEmailAddress) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cachedEmailAddress && !self.isOnline()) {
|
||||
// first time login... must be online
|
||||
callback({
|
||||
errMsg: 'The app must be online on first use!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cachedEmailAddress);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the user's email address from local storage
|
||||
*/
|
||||
self.getEmailAddressFromConfig = function(callback) {
|
||||
self._appConfigStore.listItems('emailaddress', 0, null, function(err, cachedItems) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// no email address is cached yet
|
||||
if (!cachedItems || cachedItems.length < 1) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cachedItems[0]);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Lookup the user's email address. Check local cache if available
|
||||
* otherwise query google's token info api to learn the user's email address
|
||||
*/
|
||||
self.queryEmailAddress = function(token, callback) {
|
||||
var itemKey = 'emailaddress';
|
||||
|
||||
self.getEmailAddressFromConfig(function(err, cachedEmailAddress) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// do roundtrip to google api if no email address is cached yet
|
||||
if (!cachedEmailAddress) {
|
||||
queryGoogleApi();
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cachedEmailAddress);
|
||||
});
|
||||
|
||||
function queryGoogleApi() {
|
||||
if (!token) {
|
||||
callback({
|
||||
errMsg: 'Invalid OAuth token!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// fetch gmail user's email address from the Google Authorization Server endpoint
|
||||
var googleEndpoint = new RestDAO({
|
||||
baseUri: 'https://www.googleapis.com'
|
||||
});
|
||||
|
||||
googleEndpoint.get({
|
||||
uri: '/oauth2/v1/tokeninfo?access_token=' + token
|
||||
}, function(err, info) {
|
||||
if (err || !info || !info.email) {
|
||||
callback({
|
||||
errMsg: 'Error looking up email address on google api!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// cache the email address on the device
|
||||
self._appConfigStore.storeList([info.email], itemKey, function(err) {
|
||||
callback(err, info.email);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Request an OAuth token from chrome for gmail users
|
||||
*/
|
||||
self.fetchOAuthToken = function(callback) {
|
||||
// get OAuth Token from chrome
|
||||
chrome.identity.getAuthToken({
|
||||
'interactive': true
|
||||
}, onToken);
|
||||
|
||||
function onToken(token) {
|
||||
if ((chrome && chrome.runtime && chrome.runtime.lastError) || !token) {
|
||||
callback({
|
||||
errMsg: 'Error fetching an OAuth token for the user!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// get email address for the token
|
||||
self.queryEmailAddress(token, function(err, emailAddress) {
|
||||
if (err || !emailAddress) {
|
||||
callback({
|
||||
errMsg: 'Error looking up email address on login!',
|
||||
err: err
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// init the email dao
|
||||
callback(null, {
|
||||
emailAddress: emailAddress,
|
||||
token: token
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
self.buildModules = function() {
|
||||
var lawnchairDao, restDao, pubkeyDao, emailDao, emailSync, keychain, pgp, userStorage, pgpbuilder;
|
||||
|
||||
// start the mailreader's worker thread
|
||||
mailreader.startWorker(config.workerPath + '/../lib/mailreader-parser-worker.js');
|
||||
|
||||
// init objects and inject dependencies
|
||||
restDao = new RestDAO();
|
||||
pubkeyDao = new PublicKeyDAO(restDao);
|
||||
lawnchairDao = new LawnchairDAO();
|
||||
|
||||
self._userStorage = userStorage = new DeviceStorageDAO(lawnchairDao);
|
||||
self._invitationDao = new InvitationDAO(restDao);
|
||||
self._keychain = keychain = new KeychainDAO(lawnchairDao, pubkeyDao);
|
||||
self._crypto = pgp = new PGP();
|
||||
self._pgpbuilder = pgpbuilder = new PgpBuilder();
|
||||
emailSync = new EmailSync(keychain, userStorage);
|
||||
self._emailDao = emailDao = new EmailDAO(keychain, pgp, userStorage, pgpbuilder, mailreader, emailSync);
|
||||
self._outboxBo = new OutboxBO(emailDao, keychain, userStorage);
|
||||
self._updateHandler = new UpdateHandler(self._appConfigStore, userStorage);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instanciate the mail email data access object and its dependencies. Login to imap on init.
|
||||
*/
|
||||
self.init = function(options, callback) {
|
||||
self.buildModules();
|
||||
|
||||
// init user's local database
|
||||
self._userStorage.init(options.emailAddress, function(err) {
|
||||
if (err) {
|
||||
|
139
src/js/bo/auth.js
Normal file
139
src/js/bo/auth.js
Normal file
@ -0,0 +1,139 @@
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var emailItemKey = 'emailaddress';
|
||||
|
||||
var Auth = function(appConfigStore, oauth, ca) {
|
||||
this._appConfigStore = appConfigStore;
|
||||
this._oauth = oauth;
|
||||
this._ca = ca;
|
||||
};
|
||||
|
||||
Auth.prototype.getCredentials = function(options, callback) {
|
||||
var self = this;
|
||||
|
||||
// fetch pinned local ssl certificate
|
||||
self.getCertificate(function(err, certificate) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// get a fresh oauth token
|
||||
self._oauth.getOAuthToken(function(err, token) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// get email address for the token
|
||||
self.queryEmailAddress(token, function(err, emailAddress) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, {
|
||||
emailAddress: emailAddress,
|
||||
oauthToken: token,
|
||||
sslCert: certificate
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the pinned ssl certificate for the corresponding mail server.
|
||||
*/
|
||||
Auth.prototype.getCertificate = function(callback) {
|
||||
this._ca.get({
|
||||
uri: '/Google_Internet_Authority_G2.pem',
|
||||
type: 'text'
|
||||
}, function(err, cert) {
|
||||
if (err || !cert) {
|
||||
callback({
|
||||
errMsg: 'Could not fetch pinned certificate!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cert);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gracefully try to fetch the user's email address from local storage.
|
||||
* If not yet stored, handle online/offline cases on first use.
|
||||
*/
|
||||
Auth.prototype.getEmailAddress = function(callback) {
|
||||
// try to fetch email address from local storage
|
||||
this.getEmailAddressFromConfig(function(err, cachedEmailAddress) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cachedEmailAddress);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the user's email address from local storage
|
||||
*/
|
||||
Auth.prototype.getEmailAddressFromConfig = function(callback) {
|
||||
this._appConfigStore.listItems(emailItemKey, 0, null, function(err, cachedItems) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// no email address is cached yet
|
||||
if (!cachedItems || cachedItems.length < 1) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cachedItems[0]);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Lookup the user's email address. Check local cache if available
|
||||
* otherwise query google's token info api to learn the user's email address
|
||||
*/
|
||||
Auth.prototype.queryEmailAddress = function(token, callback) {
|
||||
var self = this;
|
||||
|
||||
self.getEmailAddressFromConfig(function(err, cachedEmailAddress) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// do roundtrip to google api if no email address is cached yet
|
||||
if (!cachedEmailAddress) {
|
||||
queryOAuthApi();
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, cachedEmailAddress);
|
||||
});
|
||||
|
||||
function queryOAuthApi() {
|
||||
self._oauth.queryEmailAddress(token, function(err, emailAddress) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// cache the email address on the device
|
||||
self._appConfigStore.storeList([emailAddress], emailItemKey, function(err) {
|
||||
callback(err, emailAddress);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return Auth;
|
||||
});
|
@ -11,7 +11,7 @@ define(function(require) {
|
||||
errorUtil.attachHandler($scope);
|
||||
|
||||
$scope.connectToGoogle = function() {
|
||||
appController.fetchOAuthToken(function(err) {
|
||||
appController._auth.getCredentials({}, function(err) {
|
||||
if (err) {
|
||||
$scope.onError(err);
|
||||
return;
|
||||
|
@ -32,7 +32,7 @@ define(function(require) {
|
||||
|
||||
function unlockCrypto() {
|
||||
var userId = emailDao._account.emailAddress;
|
||||
appController._emailDao._keychain.getUserKeyPair(userId, function(err, keypair) {
|
||||
emailDao._keychain.getUserKeyPair(userId, function(err, keypair) {
|
||||
if (err) {
|
||||
handleError(err);
|
||||
return;
|
||||
|
@ -27,7 +27,7 @@ define(function(require) {
|
||||
|
||||
function initializeUser() {
|
||||
// get OAuth token from chrome
|
||||
appController.getEmailAddress(function(err, emailAddress) {
|
||||
appController._auth.getEmailAddress(function(err, emailAddress) {
|
||||
if (err) {
|
||||
$scope.onError(err);
|
||||
return;
|
||||
|
@ -6,7 +6,7 @@ define(function(require) {
|
||||
appController = require('js/app-controller'),
|
||||
IScroll = require('iscroll'),
|
||||
str = require('js/app-config').string,
|
||||
cfg = require('js/app-config').config,
|
||||
notification = require('js/util/notification'),
|
||||
emailDao, outboxBo;
|
||||
|
||||
var MailListCtrl = function($scope) {
|
||||
@ -26,7 +26,7 @@ define(function(require) {
|
||||
notificationForEmail(email);
|
||||
});
|
||||
};
|
||||
chrome.notifications.onClicked.addListener(notificationClicked);
|
||||
notification.setOnClickedListener(notificationClicked);
|
||||
}
|
||||
|
||||
//
|
||||
@ -38,7 +38,7 @@ define(function(require) {
|
||||
folder: getFolder().path,
|
||||
message: email
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
if (err && err.code !== 42) {
|
||||
$scope.onError(err);
|
||||
return;
|
||||
}
|
||||
@ -244,11 +244,10 @@ define(function(require) {
|
||||
}
|
||||
|
||||
function notificationForEmail(email) {
|
||||
chrome.notifications.create('' + email.uid, {
|
||||
type: 'basic',
|
||||
notification.create({
|
||||
id: '' + email.uid,
|
||||
title: email.from[0].name || email.from[0].address,
|
||||
message: email.subject.replace(str.subjectPrefix, ''),
|
||||
iconUrl: chrome.runtime.getURL(cfg.iconPath)
|
||||
message: email.subject.replace(str.subjectPrefix, '')
|
||||
}, function() {});
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,9 @@ define(function(require) {
|
||||
|
||||
var angular = require('angular'),
|
||||
str = require('js/app-config').string,
|
||||
cfg = require('js/app-config').config,
|
||||
appController = require('js/app-controller'),
|
||||
errorUtil = require('js/util/error'),
|
||||
notification = require('js/util/notification'),
|
||||
_ = require('underscore'),
|
||||
emailDao, outboxBo;
|
||||
|
||||
@ -126,11 +126,10 @@ define(function(require) {
|
||||
}
|
||||
|
||||
function sentNotification(email) {
|
||||
chrome.notifications.create('o' + email.id, {
|
||||
type: 'basic',
|
||||
notification.create({
|
||||
id: 'o' + email.id,
|
||||
title: 'Message sent',
|
||||
message: email.subject.replace(str.subjectPrefix, ''),
|
||||
iconUrl: chrome.runtime.getURL(cfg.iconPath)
|
||||
message: email.subject.replace(str.subjectPrefix, '')
|
||||
}, function() {});
|
||||
}
|
||||
};
|
||||
|
@ -3,9 +3,9 @@ define(function(require) {
|
||||
|
||||
var config = require('js/app-config').config;
|
||||
|
||||
var RestDAO = function(options) {
|
||||
if (options && options.baseUri) {
|
||||
this._baseUri = options.baseUri;
|
||||
var RestDAO = function(baseUri) {
|
||||
if (baseUri) {
|
||||
this._baseUri = baseUri;
|
||||
} else {
|
||||
this._baseUri = config.cloudUrl;
|
||||
}
|
||||
|
26
src/js/util/notification.js
Normal file
26
src/js/util/notification.js
Normal file
@ -0,0 +1,26 @@
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
var cfg = require('js/app-config').config;
|
||||
|
||||
var self = {};
|
||||
|
||||
self.create = function(options, callback) {
|
||||
if (window.chrome && chrome.notifications) {
|
||||
chrome.notifications.create(options.id, {
|
||||
type: 'basic',
|
||||
title: options.title,
|
||||
message: options.message,
|
||||
iconUrl: chrome.runtime.getURL(cfg.iconPath)
|
||||
}, callback);
|
||||
}
|
||||
};
|
||||
|
||||
self.setOnClickedListener = function(listener) {
|
||||
if (window.chrome && chrome.notifications) {
|
||||
chrome.notifications.onClicked.addListener(listener);
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
});
|
55
src/js/util/oauth.js
Normal file
55
src/js/util/oauth.js
Normal file
@ -0,0 +1,55 @@
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var OAuth = function(googleApi) {
|
||||
this._googleApi = googleApi;
|
||||
};
|
||||
|
||||
OAuth.prototype.isSupported = function() {
|
||||
return !!(window.chrome && chrome.identity);
|
||||
};
|
||||
|
||||
/**
|
||||
* Request an OAuth token from chrome for gmail users
|
||||
*/
|
||||
OAuth.prototype.getOAuthToken = function(callback) {
|
||||
// get OAuth Token from chrome
|
||||
chrome.identity.getAuthToken({
|
||||
'interactive': true
|
||||
}, function(token) {
|
||||
if ((chrome && chrome.runtime && chrome.runtime.lastError) || !token) {
|
||||
callback({
|
||||
errMsg: 'Error fetching an OAuth token for the user!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, token);
|
||||
});
|
||||
};
|
||||
|
||||
OAuth.prototype.queryEmailAddress = function(token, callback) {
|
||||
if (!token) {
|
||||
callback({
|
||||
errMsg: 'Invalid OAuth token!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// fetch gmail user's email address from the Google Authorization Server
|
||||
this._googleApi.get({
|
||||
uri: '/oauth2/v1/tokeninfo?access_token=' + token
|
||||
}, function(err, info) {
|
||||
if (err || !info || !info.email) {
|
||||
callback({
|
||||
errMsg: 'Error looking up email address on google api!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, info.email);
|
||||
});
|
||||
};
|
||||
|
||||
return OAuth;
|
||||
});
|
@ -5,22 +5,21 @@ define(function(require) {
|
||||
angular = require('angular'),
|
||||
mocks = require('angularMocks'),
|
||||
AddAccountCtrl = require('js/controller/add-account'),
|
||||
Auth = require('js/bo/auth'),
|
||||
appController = require('js/app-controller');
|
||||
|
||||
describe('Add Account Controller unit test', function() {
|
||||
var scope, location, ctrl,
|
||||
fetchOAuthTokenStub;
|
||||
var scope, location, ctrl, authStub;
|
||||
|
||||
describe('connectToGoogle', function() {
|
||||
beforeEach(function() {
|
||||
// remember original module to restore later, then replace it
|
||||
fetchOAuthTokenStub = sinon.stub(appController, 'fetchOAuthToken');
|
||||
appController._auth = authStub = sinon.createStubInstance(Auth);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
// restore the app controller module
|
||||
location && location.path && location.path.restore && location.path.restore();
|
||||
fetchOAuthTokenStub.restore();
|
||||
});
|
||||
|
||||
it('should fail on fetchOAuthToken error', function(done) {
|
||||
@ -37,10 +36,10 @@ define(function(require) {
|
||||
|
||||
scope.onError = function(err) {
|
||||
expect(err).to.equal(42);
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
expect(authStub.getCredentials.calledOnce).to.be.true;
|
||||
done();
|
||||
};
|
||||
fetchOAuthTokenStub.yields(42);
|
||||
authStub.getCredentials.yields(42);
|
||||
|
||||
scope.connectToGoogle();
|
||||
});
|
||||
@ -55,7 +54,7 @@ define(function(require) {
|
||||
|
||||
sinon.stub(location, 'path', function(path) {
|
||||
expect(path).to.equal('/login');
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
expect(authStub.getCredentials.calledOnce).to.be.true;
|
||||
|
||||
location.path.restore();
|
||||
scope.$apply.restore();
|
||||
@ -70,7 +69,7 @@ define(function(require) {
|
||||
});
|
||||
});
|
||||
|
||||
fetchOAuthTokenStub.yields();
|
||||
authStub.getCredentials.yields();
|
||||
|
||||
scope.connectToGoogle();
|
||||
});
|
||||
|
@ -6,11 +6,11 @@ define(function(require) {
|
||||
OutboxBO = require('js/bo/outbox'),
|
||||
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
||||
UpdateHandler = require('js/util/update/update-handler'),
|
||||
Auth = require('js/bo/auth'),
|
||||
expect = chai.expect;
|
||||
|
||||
describe('App Controller unit tests', function() {
|
||||
var emailDaoStub, outboxStub, updateHandlerStub, appConfigStoreStub, devicestorageStub, isOnlineStub,
|
||||
identityStub;
|
||||
var emailDaoStub, outboxStub, updateHandlerStub, appConfigStoreStub, devicestorageStub, isOnlineStub, authStub;
|
||||
|
||||
beforeEach(function() {
|
||||
controller._emailDao = emailDaoStub = sinon.createStubInstance(EmailDAO);
|
||||
@ -18,22 +18,31 @@ define(function(require) {
|
||||
controller._appConfigStore = appConfigStoreStub = sinon.createStubInstance(DeviceStorageDAO);
|
||||
controller._userStorage = devicestorageStub = sinon.createStubInstance(DeviceStorageDAO);
|
||||
controller._updateHandler = updateHandlerStub = sinon.createStubInstance(UpdateHandler);
|
||||
controller._auth = authStub = sinon.createStubInstance(Auth);
|
||||
|
||||
isOnlineStub = sinon.stub(controller, 'isOnline');
|
||||
|
||||
window.chrome = window.chrome || {};
|
||||
window.chrome.identity = window.chrome.identity || {};
|
||||
if (typeof window.chrome.identity.getAuthToken !== 'function') {
|
||||
window.chrome.identity.getAuthToken = function() {};
|
||||
}
|
||||
identityStub = sinon.stub(window.chrome.identity, 'getAuthToken');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
identityStub.restore();
|
||||
isOnlineStub.restore();
|
||||
});
|
||||
|
||||
describe('buildModules', function() {
|
||||
it('should work', function() {
|
||||
controller.buildModules();
|
||||
expect(controller._appConfigStore).to.exist;
|
||||
expect(controller._auth).to.exist;
|
||||
expect(controller._userStorage).to.exist;
|
||||
expect(controller._invitationDao).to.exist;
|
||||
expect(controller._keychain).to.exist;
|
||||
expect(controller._crypto).to.exist;
|
||||
expect(controller._pgpbuilder).to.exist;
|
||||
expect(controller._emailDao).to.exist;
|
||||
expect(controller._outboxBo).to.exist;
|
||||
expect(controller._updateHandler).to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe('start', function() {
|
||||
it('should not explode', function(done) {
|
||||
controller.start({
|
||||
@ -57,17 +66,8 @@ define(function(require) {
|
||||
});
|
||||
|
||||
describe('onConnect', function() {
|
||||
var fetchOAuthTokenStub, getCertficateStub;
|
||||
|
||||
beforeEach(function() {
|
||||
// buildModules
|
||||
fetchOAuthTokenStub = sinon.stub(controller, 'fetchOAuthToken');
|
||||
getCertficateStub = sinon.stub(controller, 'getCertficate');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
fetchOAuthTokenStub.restore();
|
||||
getCertficateStub.restore();
|
||||
controller._emailDao._account = {};
|
||||
});
|
||||
|
||||
it('should not connect if offline', function(done) {
|
||||
@ -79,171 +79,55 @@ define(function(require) {
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in certificate', function(done) {
|
||||
isOnlineStub.returns(true);
|
||||
getCertficateStub.yields({});
|
||||
it('should not connect if account is not initialized', function(done) {
|
||||
controller._emailDao._account = null;
|
||||
|
||||
controller.onConnect(function(err) {
|
||||
expect(err).to.exist;
|
||||
expect(getCertficateStub.calledOnce).to.be.true;
|
||||
expect(err).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in fetch oauth', function(done) {
|
||||
it('should fail due to error in auth.getCredentials', function(done) {
|
||||
isOnlineStub.returns(true);
|
||||
getCertficateStub.yields(null, 'PEM');
|
||||
fetchOAuthTokenStub.yields({});
|
||||
authStub.getCredentials.withArgs({}).yields(new Error());
|
||||
|
||||
controller.onConnect(function(err) {
|
||||
expect(err).to.exist;
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
expect(getCertficateStub.calledOnce).to.be.true;
|
||||
expect(authStub.getCredentials.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should work', function(done) {
|
||||
isOnlineStub.returns(true);
|
||||
fetchOAuthTokenStub.yields(null, {
|
||||
emailAddress: 'asfd@example.com'
|
||||
authStub.getCredentials.withArgs({}).yields(null, {
|
||||
emailAddress: 'asdf@example.com',
|
||||
oauthToken: 'token',
|
||||
sslCert: 'cert'
|
||||
});
|
||||
getCertficateStub.yields(null, 'PEM');
|
||||
emailDaoStub.onConnect.yields();
|
||||
|
||||
controller.onConnect(function(err) {
|
||||
expect(err).to.not.exist;
|
||||
expect(fetchOAuthTokenStub.calledOnce).to.be.true;
|
||||
expect(getCertficateStub.calledOnce).to.be.true;
|
||||
expect(authStub.getCredentials.calledOnce).to.be.true;
|
||||
expect(emailDaoStub.onConnect.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getEmailAddress', function() {
|
||||
var fetchOAuthTokenStub;
|
||||
|
||||
beforeEach(function() {
|
||||
// buildModules
|
||||
fetchOAuthTokenStub = sinon.stub(controller, 'fetchOAuthToken');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
fetchOAuthTokenStub.restore();
|
||||
});
|
||||
|
||||
it('should fail due to error in config list items', function(done) {
|
||||
appConfigStoreStub.listItems.yields({});
|
||||
|
||||
controller.getEmailAddress(function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should work if address is already cached', function(done) {
|
||||
appConfigStoreStub.listItems.yields(null, ['asdf']);
|
||||
|
||||
controller.getEmailAddress(function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail first time if app is offline', function(done) {
|
||||
appConfigStoreStub.listItems.yields(null, []);
|
||||
isOnlineStub.returns(false);
|
||||
|
||||
controller.getEmailAddress(function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
expect(isOnlineStub.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchOAuthToken', function() {
|
||||
var queryEmailAddressStub;
|
||||
|
||||
beforeEach(function() {
|
||||
// buildModules
|
||||
queryEmailAddressStub = sinon.stub(controller, 'queryEmailAddress');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
queryEmailAddressStub.restore();
|
||||
});
|
||||
|
||||
it('should work', function(done) {
|
||||
identityStub.yields('token42');
|
||||
queryEmailAddressStub.yields(null, 'bob@asdf.com');
|
||||
|
||||
controller.fetchOAuthToken(function(err, res) {
|
||||
expect(err).to.not.exist;
|
||||
expect(res.emailAddress).to.equal('bob@asdf.com');
|
||||
expect(res.token).to.equal('token42');
|
||||
expect(queryEmailAddressStub.calledOnce).to.be.true;
|
||||
expect(identityStub.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to chrome api error', function(done) {
|
||||
identityStub.yields();
|
||||
|
||||
controller.fetchOAuthToken(function(err) {
|
||||
expect(err).to.exist;
|
||||
expect(identityStub.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due error querying email address', function(done) {
|
||||
identityStub.yields('token42');
|
||||
queryEmailAddressStub.yields();
|
||||
|
||||
controller.fetchOAuthToken(function(err) {
|
||||
expect(err).to.exist;
|
||||
expect(queryEmailAddressStub.calledOnce).to.be.true;
|
||||
expect(identityStub.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildModules', function() {
|
||||
it('should work', function() {
|
||||
controller.buildModules();
|
||||
expect(controller._userStorage).to.exist;
|
||||
expect(controller._invitationDao).to.exist;
|
||||
expect(controller._keychain).to.exist;
|
||||
expect(controller._crypto).to.exist;
|
||||
expect(controller._pgpbuilder).to.exist;
|
||||
expect(controller._emailDao).to.exist;
|
||||
expect(controller._outboxBo).to.exist;
|
||||
expect(controller._updateHandler).to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe('init', function() {
|
||||
var buildModulesStub, onConnectStub, emailAddress;
|
||||
var onConnectStub, emailAddress;
|
||||
|
||||
beforeEach(function() {
|
||||
emailAddress = 'alice@bob.com';
|
||||
|
||||
// buildModules
|
||||
buildModulesStub = sinon.stub(controller, 'buildModules');
|
||||
buildModulesStub.returns();
|
||||
// onConnect
|
||||
onConnectStub = sinon.stub(controller, 'onConnect');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
buildModulesStub.restore();
|
||||
onConnectStub.restore();
|
||||
});
|
||||
|
||||
|
224
test/new-unit/auth-test.js
Normal file
224
test/new-unit/auth-test.js
Normal file
@ -0,0 +1,224 @@
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
var Auth = require('js/bo/auth'),
|
||||
OAuth = require('js/util/oauth'),
|
||||
RestDAO = require('js/dao/rest-dao'),
|
||||
DeviceStorageDAO = require('js/dao/devicestorage-dao'),
|
||||
expect = chai.expect;
|
||||
|
||||
describe('Auth unit tests', function() {
|
||||
var auth, appConfigStoreStub, oauthStub, caStub;
|
||||
|
||||
beforeEach(function() {
|
||||
appConfigStoreStub = sinon.createStubInstance(DeviceStorageDAO);
|
||||
oauthStub = sinon.createStubInstance(OAuth);
|
||||
caStub = sinon.createStubInstance(RestDAO);
|
||||
auth = new Auth(appConfigStoreStub, oauthStub, caStub);
|
||||
});
|
||||
|
||||
afterEach(function() {});
|
||||
|
||||
describe('getCredentials', function() {
|
||||
var getCertificateStub, queryEmailAddressStub;
|
||||
|
||||
beforeEach(function() {
|
||||
getCertificateStub = sinon.stub(auth, 'getCertificate');
|
||||
queryEmailAddressStub = sinon.stub(auth, 'queryEmailAddress');
|
||||
});
|
||||
|
||||
it('should work', function(done) {
|
||||
getCertificateStub.yields(null, 'cert');
|
||||
queryEmailAddressStub.withArgs('token').yields(null, 'asdf@example.com');
|
||||
oauthStub.getOAuthToken.yields(null, 'token');
|
||||
|
||||
auth.getCredentials({}, function(err, credentials) {
|
||||
expect(err).to.not.exist;
|
||||
expect(credentials.emailAddress).to.equal('asdf@example.com');
|
||||
expect(credentials.oauthToken).to.equal('token');
|
||||
expect(credentials.sslCert).to.equal('cert');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in getCertificate', function(done) {
|
||||
getCertificateStub.yields(new Error());
|
||||
|
||||
auth.getCredentials({}, function(err, credentials) {
|
||||
expect(err).to.exist;
|
||||
expect(credentials).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in getOAuthToken', function(done) {
|
||||
getCertificateStub.yields(null, 'cert');
|
||||
oauthStub.getOAuthToken.yields(new Error());
|
||||
|
||||
auth.getCredentials({}, function(err, credentials) {
|
||||
expect(err).to.exist;
|
||||
expect(credentials).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in queryEmailAddress', function(done) {
|
||||
getCertificateStub.yields(null, 'cert');
|
||||
queryEmailAddressStub.withArgs('token').yields(new Error());
|
||||
oauthStub.getOAuthToken.yields(null, 'token');
|
||||
|
||||
auth.getCredentials({}, function(err, credentials) {
|
||||
expect(err).to.exist;
|
||||
expect(credentials).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCertificate', function() {
|
||||
it('should work', function(done) {
|
||||
caStub.get.yields(null, 'cert');
|
||||
|
||||
auth.getCertificate(function(err, cert) {
|
||||
expect(err).to.not.exist;
|
||||
expect(cert).to.equal('cert');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail', function(done) {
|
||||
caStub.get.yields(null, '');
|
||||
|
||||
auth.getCertificate(function(err, cert) {
|
||||
expect(err).to.exist;
|
||||
expect(cert).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getEmailAddress', function() {
|
||||
var getEmailAddressFromConfigStub;
|
||||
|
||||
beforeEach(function() {
|
||||
getEmailAddressFromConfigStub = sinon.stub(auth, 'getEmailAddressFromConfig');
|
||||
});
|
||||
|
||||
it('should work', function(done) {
|
||||
getEmailAddressFromConfigStub.yields(null, 'asdf@example.com');
|
||||
|
||||
auth.getEmailAddress(function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.equal('asdf@example.com');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail', function(done) {
|
||||
getEmailAddressFromConfigStub.yields(new Error());
|
||||
|
||||
auth.getEmailAddress(function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getEmailAddressFromConfig', function() {
|
||||
it('should work', function(done) {
|
||||
appConfigStoreStub.listItems.withArgs('emailaddress', 0, null).yields(null, ['asdf@example.com']);
|
||||
|
||||
auth.getEmailAddressFromConfig(function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.equal('asdf@example.com');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return empty result', function(done) {
|
||||
appConfigStoreStub.listItems.withArgs('emailaddress', 0, null).yields(null, []);
|
||||
|
||||
auth.getEmailAddressFromConfig(function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail', function(done) {
|
||||
appConfigStoreStub.listItems.withArgs('emailaddress', 0, null).yields(new Error());
|
||||
|
||||
auth.getEmailAddressFromConfig(function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('queryEmailAddress', function() {
|
||||
var getEmailAddressFromConfigStub;
|
||||
|
||||
beforeEach(function() {
|
||||
getEmailAddressFromConfigStub = sinon.stub(auth, 'getEmailAddressFromConfig');
|
||||
});
|
||||
|
||||
it('should if already cached', function(done) {
|
||||
getEmailAddressFromConfigStub.yields(null, 'asdf@example.com');
|
||||
|
||||
auth.queryEmailAddress('token', function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.equal('asdf@example.com');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should when querying oauth api', function(done) {
|
||||
getEmailAddressFromConfigStub.yields();
|
||||
oauthStub.queryEmailAddress.withArgs('token').yields(null, 'asdf@example.com');
|
||||
appConfigStoreStub.storeList.withArgs(['asdf@example.com'], 'emailaddress').yields();
|
||||
|
||||
auth.queryEmailAddress('token', function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.equal('asdf@example.com');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in cache lookup', function(done) {
|
||||
getEmailAddressFromConfigStub.yields(new Error());
|
||||
|
||||
auth.queryEmailAddress('token', function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in oauth api', function(done) {
|
||||
getEmailAddressFromConfigStub.yields();
|
||||
oauthStub.queryEmailAddress.withArgs('token').yields(new Error());
|
||||
|
||||
auth.queryEmailAddress('token', function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in oauth api', function(done) {
|
||||
getEmailAddressFromConfigStub.yields();
|
||||
oauthStub.queryEmailAddress.withArgs('token').yields(null, 'asdf@example.com');
|
||||
appConfigStoreStub.storeList.withArgs(['asdf@example.com'], 'emailaddress').yields(new Error());
|
||||
|
||||
auth.queryEmailAddress('token', function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
@ -6,6 +6,7 @@ define(function(require) {
|
||||
mocks = require('angularMocks'),
|
||||
LoginCtrl = require('js/controller/login'),
|
||||
EmailDAO = require('js/dao/email-dao'),
|
||||
Auth = require('js/bo/auth'),
|
||||
appController = require('js/app-controller');
|
||||
|
||||
describe('Login Controller unit test', function() {
|
||||
@ -13,7 +14,7 @@ define(function(require) {
|
||||
emailAddress = 'fred@foo.com',
|
||||
startAppStub,
|
||||
checkForUpdateStub,
|
||||
getEmailAddressStub,
|
||||
authStub,
|
||||
initStub;
|
||||
|
||||
describe('initialization', function() {
|
||||
@ -27,12 +28,11 @@ define(function(require) {
|
||||
|
||||
// remember original module to restore later, then replace it
|
||||
origEmailDao = appController._emailDao;
|
||||
emailDaoMock = sinon.createStubInstance(EmailDAO);
|
||||
appController._emailDao = emailDaoMock;
|
||||
appController._emailDao = emailDaoMock = sinon.createStubInstance(EmailDAO);
|
||||
appController._auth = authStub = sinon.createStubInstance(Auth);
|
||||
|
||||
startAppStub = sinon.stub(appController, 'start');
|
||||
checkForUpdateStub = sinon.stub(appController, 'checkForUpdate');
|
||||
getEmailAddressStub = sinon.stub(appController, 'getEmailAddress');
|
||||
initStub = sinon.stub(appController, 'init');
|
||||
});
|
||||
|
||||
@ -50,13 +50,11 @@ define(function(require) {
|
||||
appController._emailDao = origEmailDao;
|
||||
appController.start.restore && appController.start.restore();
|
||||
appController.checkForUpdate.restore && appController.checkForUpdate.restore();
|
||||
appController.fetchOAuthToken.restore && appController.fetchOAuthToken.restore();
|
||||
appController.init.restore && appController.init.restore();
|
||||
location.path.restore && location.path.restore();
|
||||
|
||||
startAppStub.restore();
|
||||
checkForUpdateStub.restore();
|
||||
getEmailAddressStub.restore();
|
||||
initStub.restore();
|
||||
});
|
||||
|
||||
@ -67,7 +65,7 @@ define(function(require) {
|
||||
};
|
||||
|
||||
startAppStub.yields();
|
||||
getEmailAddressStub.yields(null, emailAddress);
|
||||
authStub.getEmailAddress.yields(null, emailAddress);
|
||||
initStub.yields(null, testKeys);
|
||||
|
||||
emailDaoMock.unlock.withArgs({
|
||||
@ -83,7 +81,7 @@ define(function(require) {
|
||||
expect(path).to.equal('/desktop');
|
||||
expect(startAppStub.calledOnce).to.be.true;
|
||||
expect(checkForUpdateStub.calledOnce).to.be.true;
|
||||
expect(getEmailAddressStub.calledOnce).to.be.true;
|
||||
expect(authStub.getEmailAddress.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
scope = $rootScope.$new();
|
||||
@ -102,7 +100,7 @@ define(function(require) {
|
||||
};
|
||||
|
||||
startAppStub.yields();
|
||||
getEmailAddressStub.yields(null, emailAddress);
|
||||
authStub.getEmailAddress.yields(null, emailAddress);
|
||||
initStub.yields(null, testKeys);
|
||||
|
||||
emailDaoMock.unlock.withArgs({
|
||||
@ -118,7 +116,7 @@ define(function(require) {
|
||||
expect(path).to.equal('/login-existing');
|
||||
expect(startAppStub.calledOnce).to.be.true;
|
||||
expect(checkForUpdateStub.calledOnce).to.be.true;
|
||||
expect(getEmailAddressStub.calledOnce).to.be.true;
|
||||
expect(authStub.getEmailAddress.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
scope = $rootScope.$new();
|
||||
@ -132,7 +130,7 @@ define(function(require) {
|
||||
|
||||
it('should forward to new device login', function(done) {
|
||||
startAppStub.yields();
|
||||
getEmailAddressStub.yields(null, emailAddress);
|
||||
authStub.getEmailAddress.yields(null, emailAddress);
|
||||
initStub.yields(null, {
|
||||
publicKey: 'b'
|
||||
});
|
||||
@ -145,7 +143,7 @@ define(function(require) {
|
||||
expect(path).to.equal('/login-new-device');
|
||||
expect(startAppStub.calledOnce).to.be.true;
|
||||
expect(checkForUpdateStub.calledOnce).to.be.true;
|
||||
expect(getEmailAddressStub.calledOnce).to.be.true;
|
||||
expect(authStub.getEmailAddress.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
scope = $rootScope.$new();
|
||||
@ -159,7 +157,7 @@ define(function(require) {
|
||||
|
||||
it('should forward to initial login', function(done) {
|
||||
startAppStub.yields();
|
||||
getEmailAddressStub.yields(null, emailAddress);
|
||||
authStub.getEmailAddress.yields(null, emailAddress);
|
||||
initStub.yields();
|
||||
|
||||
angular.module('logintest', []);
|
||||
@ -170,7 +168,7 @@ define(function(require) {
|
||||
expect(path).to.equal('/login-initial');
|
||||
expect(startAppStub.calledOnce).to.be.true;
|
||||
expect(checkForUpdateStub.calledOnce).to.be.true;
|
||||
expect(getEmailAddressStub.calledOnce).to.be.true;
|
||||
expect(authStub.getEmailAddress.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
scope = $rootScope.$new();
|
||||
|
@ -28,6 +28,8 @@ function startTests() {
|
||||
|
||||
require(
|
||||
[
|
||||
'test/new-unit/oauth-test',
|
||||
'test/new-unit/auth-test',
|
||||
'test/new-unit/email-dao-test',
|
||||
'test/new-unit/email-sync-test',
|
||||
'test/new-unit/app-controller-test',
|
||||
|
92
test/new-unit/oauth-test.js
Normal file
92
test/new-unit/oauth-test.js
Normal file
@ -0,0 +1,92 @@
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
var OAuth = require('js/util/oauth'),
|
||||
RestDAO = require('js/dao/rest-dao'),
|
||||
expect = chai.expect;
|
||||
|
||||
describe('OAuth unit tests', function() {
|
||||
var oauth, googleApiStub, identityStub;
|
||||
|
||||
beforeEach(function() {
|
||||
googleApiStub = sinon.createStubInstance(RestDAO);
|
||||
oauth = new OAuth(googleApiStub);
|
||||
|
||||
window.chrome = window.chrome || {};
|
||||
window.chrome.identity = window.chrome.identity || {};
|
||||
if (typeof window.chrome.identity.getAuthToken !== 'function') {
|
||||
window.chrome.identity.getAuthToken = function() {};
|
||||
}
|
||||
identityStub = sinon.stub(window.chrome.identity, 'getAuthToken');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
identityStub.restore();
|
||||
});
|
||||
|
||||
describe('isSupported', function() {
|
||||
it('should work', function() {
|
||||
expect(oauth.isSupported()).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOAuthToken', function() {
|
||||
it('should work', function(done) {
|
||||
identityStub.yields('token');
|
||||
|
||||
oauth.getOAuthToken(function(err, token) {
|
||||
expect(err).to.not.exist;
|
||||
expect(token).to.equal('token');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail', function(done) {
|
||||
identityStub.yields();
|
||||
|
||||
oauth.getOAuthToken(function(err, token) {
|
||||
expect(err).to.exist;
|
||||
expect(token).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('queryEmailAddress', function() {
|
||||
it('should work', function(done) {
|
||||
googleApiStub.get.withArgs({
|
||||
uri: '/oauth2/v1/tokeninfo?access_token=token'
|
||||
}).yields(null, {
|
||||
email: 'asdf@example.com'
|
||||
});
|
||||
|
||||
oauth.queryEmailAddress('token', function(err, emailAddress) {
|
||||
expect(err).to.not.exist;
|
||||
expect(emailAddress).to.equal('asdf@example.com');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to invalid token', function(done) {
|
||||
oauth.queryEmailAddress('', function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail due to error in rest api', function(done) {
|
||||
googleApiStub.get.withArgs({
|
||||
uri: '/oauth2/v1/tokeninfo?access_token=token'
|
||||
}).yields(new Error());
|
||||
|
||||
oauth.queryEmailAddress('token', function(err, emailAddress) {
|
||||
expect(err).to.exist;
|
||||
expect(emailAddress).to.not.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
@ -32,9 +32,7 @@ define(function(require) {
|
||||
it('should accept default base uri', function() {
|
||||
var baseUri = 'http://custom.com';
|
||||
|
||||
restDao = new RestDAO({
|
||||
baseUri: baseUri
|
||||
});
|
||||
restDao = new RestDAO(baseUri);
|
||||
expect(restDao).to.exist;
|
||||
expect(restDao._baseUri).to.equal(baseUri);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user