aboutsummaryrefslogtreecommitdiff
path: root/lib/handlers/auth.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/handlers/auth.js')
-rw-r--r--lib/handlers/auth.js113
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;
+ });
+ }
+};