diff --git a/lib/expressHelper.js b/lib/expressHelper.js index 06aa7cda..89e1c742 100644 --- a/lib/expressHelper.js +++ b/lib/expressHelper.js @@ -1,5 +1,54 @@ -module.exports = function (app) { - var everyauth = this; +var everyauth = require('../'), + __pause = require('connect').utils.pause; + +function registerReqGettersAndMethods (req, res, next) { + var methods = everyauth._req._methods + , getters = everyauth._req._getters; + for (var name in methods) { + req[name] = methods[name]; + } + for (name in getters) { + Object.defineProperty(req, name, { + get: getters[name] + }); + } + next(); +} + +function fetchUserFromSession (req, res, next) { + var sess = req.session + , auth = sess && sess.auth + , everymodule, findUser; + if (!auth) return next(); + if (!auth.userId) return next(); + everymodule = everyauth.everymodule; + if (!everymodule._findUserById) return next(); + var pause = __pause(req); + everymodule._findUserById(auth.userId, function (err, user) { + if (err) throw err; // TODO Leverage everyauth's error handling + if (user) req.user = user; + else delete sess.auth; + next(); + pause.resume(); + }); +} + +module.exports = function (app, modules) { + var everyauth = this, + _module; + + // ensure we have modules + modules = modules || everyauth.enabled; + app.use(registerReqGettersAndMethods); + app.use(fetchUserFromSession); + + // attach the routes for each of the enabled modules + for (var _name in modules) { + _module = modules[_name]; + _module.validateSteps(); + _module.routeApp(app); + } // for + app.dynamicHelpers({ everyauth: function (req, res) { var ea = {} diff --git a/lib/modules/everymodule.js b/lib/modules/everymodule.js index 0181c055..8979b4d3 100644 --- a/lib/modules/everymodule.js +++ b/lib/modules/everymodule.js @@ -239,7 +239,7 @@ var everyModule = module.exports = { if (!path) throw new Error('You have not defined a path for the route alias ' + routeAlias + '.'); var seq = routes[method][routeAlias]; - + // This kicks off a sequence of steps based on a // route // Creates a new chain of promises and exposes the leading promise diff --git a/lib/modules/oauth.js b/lib/modules/oauth.js index dfbc0ff9..586b2447 100644 --- a/lib/modules/oauth.js +++ b/lib/modules/oauth.js @@ -41,7 +41,7 @@ everyModule.submodule('oauth') .promises(null) .step('redirectToProviderAuth') .description('sends the user to authorization on the OAuth provider site') - .accepts('res token') + .accepts('req res token') .promises(null) .get('callbackPath', @@ -93,14 +93,21 @@ everyModule.submodule('oauth') .promises(null) .getRequestToken( function (req, res) { + + var callbackPath = this._callbackPath; + // check for a route + if (req.app) { + callbackPath = (req.app.route == '/' ? '' : req.app.route) + callbackPath; + } // if + // Automatic hostname detection + assignment if (!this._myHostname || this._alwaysDetectHostname) { this.myHostname(extractHostname(req)); } var p = this.Promise(); - this.oauth.getOAuthRequestToken({ oauth_callback: this._myHostname + this._callbackPath }, function (err, token, tokenSecret, params) { + this.oauth.getOAuthRequestToken({ oauth_callback: this._myHostname + callbackPath }, function (err, token, tokenSecret, params) { if (err && !~(err.data.indexOf('Invalid / expired Token'))) { return p.fail(err); } @@ -115,14 +122,21 @@ everyModule.submodule('oauth') _provider.token = token; _provider.tokenSecret = tokenSecret; }) - .redirectToProviderAuth( function (res, token) { + .redirectToProviderAuth( function (req, res, token) { // Note: Not all oauth modules need oauth_callback as a uri query parameter. As far as I know, only readability's // module needs it as a uri query parameter. However, in cases such as twitter, it allows you to over-ride // the callback url settings at dev.twitter.com from one place, your app code, rather than in two places -- i.e., // your app code + dev.twitter.com app settings. - var redirectTo = this._oauthHost + this._authorizePath + '?oauth_token=' + token; + var redirectTo = this._oauthHost + this._authorizePath + '?oauth_token=' + token, + callbackPath = this._callbackPath; + + // check for a route + if (req.app) { + callbackPath = (req.app.route == '/' ? '' : req.app.route) + callbackPath; + } // if + if (this._sendCallbackWithAuthorize) { - redirectTo += '&oauth_callback=' + this._myHostname + this._callbackPath; + redirectTo += '&oauth_callback=' + this._myHostname + callbackPath; } res.writeHead(303, { 'Location': redirectTo }); res.end();