]>
Commit | Line | Data |
---|---|---|
287fa13b RBR |
1 | 'use strict'; |
2 | ||
3 | const Co = require('co'); | |
287fa13b RBR |
4 | const JsonWebToken = require('jsonwebtoken'); |
5 | const Pify = require('pify'); | |
a6ccda0f | 6 | const TwitterHelper = require('../twitter_helper'); |
287fa13b RBR |
7 | |
8 | const internals = {}; | |
9 | ||
10 | internals.kRedirectUrl = 'https://api.twitter.com/oauth/authenticate?oauth_token='; | |
a6ccda0f | 11 | internals.kLoginRedirect = '/login'; |
287fa13b RBR |
12 | |
13 | internals.signJsonWebToken = Pify(JsonWebToken.sign); | |
14 | ||
a6ccda0f RBR |
15 | /** |
16 | * Handles the HTTP requests for auth related operations. | |
17 | * | |
18 | * @class AuthHandler | |
19 | * @param {Dasein.tConfiguration} config The configuration to | |
20 | * initialize. | |
21 | */ | |
287fa13b RBR |
22 | module.exports = internals.AuthHandler = class AuthHandler { |
23 | ||
24 | constructor(config) { | |
25 | ||
26 | this._twitterHelper = new TwitterHelper(config.twitter); | |
27 | this._jwtConfig = config.jwt; | |
287fa13b RBR |
28 | } |
29 | ||
a6ccda0f RBR |
30 | /** |
31 | * Triggers the twitter login flow. Redirects to twitter's oauth | |
32 | * request page | |
33 | * | |
34 | * @function login | |
35 | * @memberof AuthHandler | |
36 | * @instance | |
37 | * @return {generator} a koa compatible handler generator function | |
38 | */ | |
287fa13b RBR |
39 | login() { |
40 | ||
41 | const twitterHelper = this._twitterHelper; | |
42 | ||
43 | return function *handleLogin() { | |
44 | ||
287fa13b | 45 | const requestToken = yield twitterHelper.getRequestToken(); |
a6ccda0f RBR |
46 | const loginUrl = `${internals.kRedirectUrl}${requestToken.oAuthToken}`; |
47 | ||
48 | this.body = { loginUrl }; | |
287fa13b RBR |
49 | }; |
50 | } | |
51 | ||
a6ccda0f RBR |
52 | /** |
53 | * Handles twitter's callback. Fetches the oAuth Verifier, attempts to | |
54 | * obtain a user object and responds with the JWT | |
55 | * | |
56 | * @function callback | |
57 | * @memberof AuthHandler | |
58 | * @instance | |
59 | * @return {generator} a koa compatible handler generator function | |
60 | */ | |
287fa13b RBR |
61 | callback() { |
62 | ||
63 | const self = this; | |
64 | ||
65 | return function *handleCallback() { | |
66 | ||
67 | if (this.request.query.denied) { | |
68 | return this.throw(401); | |
69 | } | |
70 | ||
a6ccda0f RBR |
71 | const oAuthToken = this.request.body.oAuthToken; |
72 | const oAuthVerifier = this.request.body.oAuthVerifier; | |
287fa13b RBR |
73 | let user; |
74 | ||
75 | try { | |
76 | const accessToken = yield self._twitterHelper.getAccessToken(oAuthToken, oAuthVerifier); | |
77 | user = yield self._twitterHelper.getUser(accessToken.oAuthAccessToken, accessToken.oAuthAccessTokenSecret); | |
78 | } | |
79 | catch (err) { | |
80 | console.error(err.stack || err.message || err); | |
81 | return this.throw(401); | |
82 | } | |
83 | ||
a6ccda0f | 84 | const expiresAt = Date.now() + self._jwtConfig.duration * 1000; |
287fa13b | 85 | |
a6ccda0f | 86 | const token = yield self._getToken(user); |
287fa13b | 87 | |
a6ccda0f RBR |
88 | const response = { |
89 | expiresAt, | |
90 | user, | |
91 | token | |
92 | }; | |
287fa13b | 93 | |
a6ccda0f | 94 | this.body = response; |
287fa13b RBR |
95 | }; |
96 | } | |
97 | ||
a6ccda0f RBR |
98 | // Generates a JSON Web Token |
99 | ||
100 | _getToken(payload) { | |
287fa13b RBR |
101 | |
102 | const self = this; | |
103 | ||
104 | return Co(function * () { | |
105 | ||
106 | const token = yield internals.signJsonWebToken(payload, self._jwtConfig.secret, { | |
107 | expiresIn: self._jwtConfig.duration | |
108 | }); | |
109 | ||
a6ccda0f | 110 | return token; |
287fa13b RBR |
111 | }); |
112 | } | |
113 | }; |