diff options
Diffstat (limited to 'lib/handlers/auth.js')
| -rw-r--r-- | lib/handlers/auth.js | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/lib/handlers/auth.js b/lib/handlers/auth.js new file mode 100644 index 0000000..1db9494 --- /dev/null +++ b/lib/handlers/auth.js @@ -0,0 +1,113 @@ +'use strict'; + +const Co = require('co'); +const JsonWebToken = require('jsonwebtoken'); +const Pify = require('pify'); +const TwitterHelper = require('../twitter_helper'); + +const internals = {}; + +internals.kRedirectUrl = 'https://api.twitter.com/oauth/authenticate?oauth_token='; +internals.kLoginRedirect = '/login'; + +internals.signJsonWebToken = Pify(JsonWebToken.sign); + +/** + * Handles the HTTP requests for auth related operations. + * + * @class AuthHandler + * @param {Dasein.tConfiguration} config The configuration to + * initialize. + */ +module.exports = internals.AuthHandler = class AuthHandler { + + constructor(config) { + + this._twitterHelper = new TwitterHelper(config.twitter); + this._jwtConfig = config.jwt; + } + + /** + * Triggers the twitter login flow. Redirects to twitter's oauth + * request page + * + * @function login + * @memberof AuthHandler + * @instance + * @return {generator} a koa compatible handler generator function + */ + login() { + + const twitterHelper = this._twitterHelper; + + return function *handleLogin() { + + const requestToken = yield twitterHelper.getRequestToken(); + const loginUrl = `${internals.kRedirectUrl}${requestToken.oAuthToken}`; + + this.body = { loginUrl }; + }; + } + + /** + * Handles twitter's callback. Fetches the oAuth Verifier, attempts to + * obtain a user object and responds with the JWT + * + * @function callback + * @memberof AuthHandler + * @instance + * @return {generator} a koa compatible handler generator function + */ + callback() { + + const self = this; + + return function *handleCallback() { + + if (this.request.query.denied) { + return this.throw(401); + } + + const oAuthToken = this.request.body.oAuthToken; + const oAuthVerifier = this.request.body.oAuthVerifier; + let user; + + try { + const accessToken = yield self._twitterHelper.getAccessToken(oAuthToken, oAuthVerifier); + user = yield self._twitterHelper.getUser(accessToken.oAuthAccessToken, accessToken.oAuthAccessTokenSecret); + } + catch (err) { + console.error(err.stack || err.message || err); + return this.throw(401); + } + + const expiresAt = Date.now() + self._jwtConfig.duration * 1000; + + const token = yield self._getToken(user); + + const response = { + expiresAt, + user, + token + }; + + this.body = response; + }; + } + + // Generates a JSON Web Token + + _getToken(payload) { + + const self = this; + + return Co(function * () { + + const token = yield internals.signJsonWebToken(payload, self._jwtConfig.secret, { + expiresIn: self._jwtConfig.duration + }); + + return token; + }); + } +}; |