From 2186d20a7ce3d784d375887c252089c67a629a85 Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Fri, 16 Aug 2013 20:31:18 +0200 Subject: [PATCH] login to imap and smtp via chrome identity api works --- .gitignore | 1 + package.json | 8 +++-- res/copy-deps.sh | 16 ++++++++- src/index.js | 11 +----- src/js/app-controller.js | 70 +++++++++++++++++++++++++++++---------- src/js/dao/email-dao.js | 51 ++++++++++++++++++---------- src/js/view/login-view.js | 2 +- src/manifest.json | 8 +++-- src/require-config.js | 4 ++- src/tpl/login.html | 4 +-- 10 files changed, 119 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index fd4f2b0..260610f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules .DS_Store +*-browserified.js diff --git a/package.json b/package.json index a40bc05..94f7716 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,13 @@ "start": "grunt prod" }, "dependencies": { - "grunt": "~0.4.1", - "grunt-contrib-connect": "~0.3.0", - "crypto-lib": "https://github.com/whiteout-io/crypto-lib/tarball/master" + "crypto-lib": "https://github.com/whiteout-io/crypto-lib/tarball/master", + "imap-client": "git+ssh://git@github.com:whiteout-io/imap-client.git#master", + "smtp-client": "git+ssh://git@github.com:whiteout-io/smtp-client.git#master" }, "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-connect": "~0.3.0", "grunt-contrib-jshint": "~0.5.3", "grunt-contrib-qunit": "~0.2.1" } diff --git a/res/copy-deps.sh b/res/copy-deps.sh index 8092387..8860815 100755 --- a/res/copy-deps.sh +++ b/res/copy-deps.sh @@ -6,5 +6,19 @@ echo "--> copying dependencies to src\n" cd `dirname $0` cd .. +# copy crypto lib cp ./node_modules/crypto-lib/src/*.js ./src/js/crypto/ -cp ./node_modules/crypto-lib/node_modules/node-forge/js/*.js ./src/lib/ \ No newline at end of file +cp ./node_modules/crypto-lib/node_modules/node-forge/js/*.js ./src/lib/ + +# build imap/smtp modules and copy +cd ./node_modules/imap-client/ +npm install && node build.js +cp ./src-gen/*.js ../../src/lib/ +cd ../../ + +cd ./node_modules/smtp-client/ +npm install && node build.js +cp ./src-gen/*.js ../../src/lib/ +cd ../../ + +echo "\n--> finished copying dependencies.\n" \ No newline at end of file diff --git a/src/index.js b/src/index.js index 3fbe653..1afc16c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,20 +1,11 @@ require(['jquery', 'js/app-controller', 'js/app-config'], function($, controller, app) { 'use strict'; - chrome.identity.getAuthToken({ - 'interactive': true - }, function(token) { - console.log(token); - // Use the token. - }); - /** * Load templates and start the application */ $(document).ready(function() { - controller.init(function() { - controller.start(startApp); - }); + controller.start(startApp); }); function startApp() { diff --git a/src/js/app-controller.js b/src/js/app-controller.js index 43fde2f..fa448cf 100644 --- a/src/js/app-controller.js +++ b/src/js/app-controller.js @@ -1,23 +1,13 @@ /** * The main application controller */ -define(['jquery', 'js/dao/email-dao', 'js/dao/keychain-dao', 'js/dao/cloudstorage-dao', - 'js/app-config', 'cordova' -], function($, EmailDAO, KeychainDAO, cloudstorage, app) { +define(['jquery', 'ImapClient', 'SmtpClient', 'js/dao/email-dao', 'js/dao/keychain-dao', + 'js/dao/cloudstorage-dao', 'js/app-config', 'cordova' +], function($, ImapClient, SmtpClient, EmailDAO, KeychainDAO, cloudstorage, app) { 'use strict'; - var self = {}; - - var emailDao; - - /** - * Initializes modules through dependecy injection - */ - self.init = function(callback) { - var keychain = new KeychainDAO(cloudstorage); - emailDao = new EmailDAO(cloudstorage, keychain); - callback(); - }; + var self = {}, + emailDao; /** * Start the application by loading the view templates @@ -25,7 +15,7 @@ define(['jquery', 'js/dao/email-dao', 'js/dao/keychain-dao', 'js/dao/cloudstorag self.start = function(callback) { // the views to load var views = ['login', 'compose', 'folderlist', 'messagelist', - 'messagelistitem', 'read' + 'messagelistitem', 'read' ]; // are we running in native app or in browser? @@ -49,7 +39,7 @@ define(['jquery', 'js/dao/email-dao', 'js/dao/keychain-dao', 'js/dao/cloudstorag self.execute = function(cmd, args, callback) { if (cmd === 'login') { // login user - login(args.userId, args.password, function(err) { + fetchOAuthToken(args.userId, args.password, function(err) { callback({ err: err }); @@ -102,8 +92,52 @@ define(['jquery', 'js/dao/email-dao', 'js/dao/keychain-dao', 'js/dao/cloudstorag // Helper methods // - function login(userId, password, callback) { + function fetchOAuthToken(userId, password, callback) { + // get OAuth Token from chrome + chrome.identity.getAuthToken({ + 'interactive': true + }, + function(token) { + login(userId, password, token, callback); + } + ); + } + + function login(userId, password, token, callback) { + var auth, imapOptions, smtpOptions, + keychain, imapClient, smtpClient; + + // create mail credentials objects for imap/smtp + auth = { + XOAuth2: { + user: userId, + clientId: '440907777130.apps.googleusercontent.com', + accessToken: token + } + }; + imapOptions = { + secure: true, + port: 993, + host: 'imap.gmail.com', + auth: auth + }; + smtpOptions = { + secure: true, + port: 465, + host: 'smtp.gmail.com', + auth: auth + }; + + // init objects and inject dependencies + keychain = new KeychainDAO(cloudstorage); + imapClient = new ImapClient(imapOptions); + smtpClient = new SmtpClient(smtpOptions); + emailDao = new EmailDAO(cloudstorage, keychain, imapClient, smtpClient); + + // init email dao var account = new app.model.Account({ + imapOptions: imapOptions, + smtpOptions: smtpOptions, emailAddress: userId, symKeySize: app.config.symKeySize, symIvSize: app.config.symIvSize, diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js index 645adfb..ea7b072 100644 --- a/src/js/dao/email-dao.js +++ b/src/js/dao/email-dao.js @@ -3,11 +3,11 @@ * between the cloud service and the device's local storage */ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-dao', - 'js/dao/devicestorage-dao', 'js/app-config', 'js/model/account-model' + 'js/dao/devicestorage-dao', 'js/app-config', 'js/model/account-model' ], function(_, util, crypto, jsonDB, devicestorage, app) { 'use strict'; - var EmailDAO = function(cloudstorage, keychain) { + var EmailDAO = function(cloudstorage, keychain, imapClient, smtpClient) { var self = this; /** @@ -25,18 +25,30 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da return; } - // init user's local database - jsonDB.init(emailAddress); + // login IMAP client if existent + if (imapClient) { + imapClient.login(function() { + console.log('logged into imap.'); + initKeychain(); + }); + } else { + initKeychain(); + } - // call getUserKeyPair to read/sync keypair with devicestorage/cloud - keychain.getUserKeyPair(emailAddress, function(err, storedKeypair) { - if (err) { - callback(err); - return; - } - // init crypto - initCrypto(storedKeypair); - }); + function initKeychain() { + // init user's local database + jsonDB.init(emailAddress); + + // call getUserKeyPair to read/sync keypair with devicestorage/cloud + keychain.getUserKeyPair(emailAddress, function(err, storedKeypair) { + if (err) { + callback(err); + return; + } + // init crypto + initCrypto(storedKeypair); + }); + } function initCrypto(storedKeypair) { crypto.init({ @@ -300,10 +312,15 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da } function send(email) { - // send email to cloud service - cloudstorage.deliverEmail(email, userId, recipient, function(err) { - callback(err); - }); + if (smtpClient) { + // send email directly client side + smtpClient.send(email, callback); + } else { + // send email via cloud service + cloudstorage.deliverEmail(email, userId, recipient, function(err) { + callback(err); + }); + } } }; }; diff --git a/src/js/view/login-view.js b/src/js/view/login-view.js index e58d1ba..db88cec 100644 --- a/src/js/view/login-view.js +++ b/src/js/view/login-view.js @@ -23,7 +23,7 @@ define(['jquery', 'underscore', 'backbone', 'js/app-config'], function($, _, Bac login: function() { var page = $(this.el), - userId = page.find('#userId').val() + '@mail.whiteout.io', + userId = page.find('#userId').val(), password = page.find('#password').val(); // show loading msg during init diff --git a/src/manifest.json b/src/manifest.json index 02ac0b0..a498e77 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -8,14 +8,16 @@ "128": "css/images/mail-128.png" }, "permissions": [ - "https://storage.whiteout.io/", - "identity" + "https://storage.whiteout.io/", + "identity", { + "socket": ["tcp-connect"] + } ], "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBXqC3/oX5fP/gLORcVN62Pf3Ph+pO4qEB+FynSMWMoqWUt7FDoaKuHrsP/KInuP/0PUZcqpij9kB9MytLTqYzGIoRsUd37i1Dt6R69fnNsIqAISgoWIRg4VyRdon9cTIniv3DVV45PPyNCvN+oQoBMv9NbojWnlL9W05bKYkABQIDAQAB", "oauth2": { "client_id": "440907777130.apps.googleusercontent.com", "scopes": [ - "https://mail.google.com/" + "https://mail.google.com/" ] }, "app": { diff --git a/src/require-config.js b/src/require-config.js index 5765809..656257f 100644 --- a/src/require-config.js +++ b/src/require-config.js @@ -14,7 +14,9 @@ lawnchair: 'lawnchair/lawnchair-git', lawnchairSQL: 'lawnchair/lawnchair-adapter-webkit-sqlite-git', lawnchairIDB: 'lawnchair/lawnchair-adapter-indexed-db-git', - cordova: 'cordova-2.5.0' + cordova: 'cordova-2.5.0', + ImapClient: 'imap-client-browserified', + SmtpClient: 'smtp-client-browserified' }, shim: { lawnchair: { diff --git a/src/tpl/login.html b/src/tpl/login.html index 2df8176..9bfb014 100644 --- a/src/tpl/login.html +++ b/src/tpl/login.html @@ -7,9 +7,9 @@

Please sign in

- + - +
\ No newline at end of file