]>
Commit | Line | Data |
---|---|---|
287fa13b RBR |
1 | 'use strict'; |
2 | ||
3 | const Co = require('co'); | |
4 | const TwitterHelper = require('../twitter_helper'); | |
5 | const JsonWebToken = require('jsonwebtoken'); | |
6 | const Pify = require('pify'); | |
7 | ||
8 | const internals = {}; | |
9 | ||
10 | internals.kRedirectUrl = 'https://api.twitter.com/oauth/authenticate?oauth_token='; | |
11 | internals.kMainLocation = '/'; | |
12 | ||
13 | internals.signJsonWebToken = Pify(JsonWebToken.sign); | |
14 | ||
15 | module.exports = internals.AuthHandler = class AuthHandler { | |
16 | ||
17 | constructor(config) { | |
18 | ||
19 | this._twitterHelper = new TwitterHelper(config.twitter); | |
20 | this._jwtConfig = config.jwt; | |
21 | this._hostname = config.hostname; | |
22 | } | |
23 | ||
24 | login() { | |
25 | ||
26 | const twitterHelper = this._twitterHelper; | |
27 | ||
28 | return function *handleLogin() { | |
29 | ||
30 | if (this.state.user) { | |
31 | return this.redirect(internals.kMainLocation); | |
32 | } | |
33 | ||
34 | const requestToken = yield twitterHelper.getRequestToken(); | |
35 | this.redirect(`${internals.kRedirectUrl}${requestToken.oAuthToken}`); | |
36 | }; | |
37 | } | |
38 | ||
39 | callback() { | |
40 | ||
41 | const self = this; | |
42 | ||
43 | return function *handleCallback() { | |
44 | ||
45 | if (this.request.query.denied) { | |
46 | return this.throw(401); | |
47 | } | |
48 | ||
49 | const oAuthToken = this.request.query.oauth_token; | |
50 | const oAuthVerifier = this.request.query.oauth_verifier; | |
51 | let user; | |
52 | ||
53 | try { | |
54 | const accessToken = yield self._twitterHelper.getAccessToken(oAuthToken, oAuthVerifier); | |
55 | user = yield self._twitterHelper.getUser(accessToken.oAuthAccessToken, accessToken.oAuthAccessTokenSecret); | |
56 | } | |
57 | catch (err) { | |
58 | console.error(err.stack || err.message || err); | |
59 | return this.throw(401); | |
60 | } | |
61 | ||
62 | yield self._setJWT(user, this); | |
63 | ||
64 | this.redirect(internals.kMainLocation); | |
65 | }; | |
66 | } | |
67 | ||
68 | logout() { | |
69 | ||
70 | const self = this; | |
71 | ||
72 | return function * () { | |
73 | ||
74 | this.cookies.set(self._jwtConfig.cookieName, null); | |
75 | this.redirect(internals.kMainLocation); | |
76 | }; | |
77 | } | |
78 | ||
79 | // Sets a JSON Web Token Cookie | |
80 | _setJWT(payload, context) { | |
81 | ||
82 | const self = this; | |
83 | ||
84 | return Co(function * () { | |
85 | ||
86 | const token = yield internals.signJsonWebToken(payload, self._jwtConfig.secret, { | |
87 | expiresIn: self._jwtConfig.duration | |
88 | }); | |
89 | ||
90 | context.cookies.set(self._jwtConfig.cookieName, token, { | |
91 | maxAge: self._jwtConfig.duration * 1000, | |
92 | signed: true, | |
93 | domain: self._hostname, | |
94 | overwrite: true | |
95 | }); | |
96 | }); | |
97 | } | |
98 | }; |