1 |
|
2 |
|
3 |
|
4 |
|
5 | var qs = require('qs');
|
6 | var URL = require('url');
|
7 | var debug = require('debug')('poe-ui:oauth');
|
8 |
|
9 | module.exports = function(r, app, opts) {
|
10 | if (!opts.oauthClientId) return;
|
11 |
|
12 | app.useBefore('router', '/auth/login', 'auth:login', login(opts, null, true));
|
13 | app.useBefore('router', '/auth/signup', 'auth:signup', login(opts, {signup: 1}, true));
|
14 | app.useBefore('router', '/auth/callback', 'auth:callback', callback(opts));
|
15 | app.useBefore('router', '/auth/logout', 'auth:logout', logout(opts));
|
16 | app.useBefore('router', '/auth', 'auth:root-redirect', function(req, res) {
|
17 | res.redirect(req.base);
|
18 | });
|
19 |
|
20 | if (opts.restricted) app.useBefore('router', '/', 'auth:restrict', login(opts));
|
21 | };
|
22 |
|
23 | function login(opts, additionalParams, explicitLogin) {
|
24 | var CLIENT_ID = opts.oauthClientId;
|
25 | var OAUTH_URL = opts.oauthUrl;
|
26 | additionalParams = additionalParams || {};
|
27 |
|
28 | return function oauthLogin(req, res, next) {
|
29 | var auth_url = req.get('x-auth-url') || OAUTH_URL;
|
30 |
|
31 |
|
32 | if (req.cookies._access_token || !CLIENT_ID || !auth_url) return explicitLogin ? res.redirect(req.base) : next();
|
33 |
|
34 | var params = {
|
35 | client_id: CLIENT_ID,
|
36 | redirect_uri: req.base + '/auth/callback',
|
37 | response_type: 'code',
|
38 | scope: Array.isArray(opts.scope) ? opts.scope.join(' ') : opts.scope,
|
39 |
|
40 | state: explicitLogin ? req.base : verifyState(req, req.get('referrer'))
|
41 | };
|
42 |
|
43 | for (var k in additionalParams) {
|
44 | params[k] = additionalParams[k];
|
45 | }
|
46 |
|
47 | debug('login', params);
|
48 |
|
49 | res.redirect(auth_url + '/authorize?' + qs.stringify(params));
|
50 | };
|
51 | }
|
52 |
|
53 | function error() {
|
54 | return function oauthError(req, res, next) {
|
55 | if (!req.query.error) return next();
|
56 |
|
57 | res.redirect(req.base);
|
58 | };
|
59 | }
|
60 |
|
61 | function callback(opts) {
|
62 | var CLIENT_ID = opts.oauthClientId;
|
63 | var CLIENT_SECRET = opts.oauthClientSecret;
|
64 |
|
65 | return function oauthCallback(req, res, next) {
|
66 | var code = req.query.code;
|
67 | if (!code || !CLIENT_ID || !CLIENT_SECRET || !req.hyperclient) return res.redirect(req.base);
|
68 |
|
69 | var params = {
|
70 | client_id: CLIENT_ID,
|
71 | client_secret: CLIENT_SECRET,
|
72 | code: code,
|
73 | redirect_uri: req.base + '/auth/callback'
|
74 | };
|
75 |
|
76 | req.hyperclient.submit('.oauth.authorization_code', params, function(err, body, resp) {
|
77 | debug('callback', err, body);
|
78 | if (err || !body || !body.access_token) return res.redirect(verifyState(req, req.query.state));
|
79 |
|
80 | res.cookie('_access_token', body.access_token, {
|
81 | secure: ~req.base.indexOf('https://'),
|
82 | maxAge: body.expires_in * 1000
|
83 | });
|
84 |
|
85 | res.redirect(verifyState(req, req.query.state));
|
86 | });
|
87 | };
|
88 | }
|
89 |
|
90 | function logout(opts) {
|
91 | var CLIENT_ID = opts.oauthClientId;
|
92 | var OAUTH_URL = opts.oauthUrl;
|
93 |
|
94 | return function oauthLogout(req, res, next) {
|
95 | res.clearCookie('_access_token', {
|
96 | secure: ~req.base.indexOf('https://')
|
97 | });
|
98 |
|
99 | res.redirect((req.get('x-auth-url') || OAUTH_URL) + '/logout?client_id=' + CLIENT_ID);
|
100 | };
|
101 | }
|
102 |
|
103 | function verifyState(req, location) {
|
104 | if (!location) return req.base;
|
105 | location = URL.parse(location);
|
106 | if (!location.host) return location.path;
|
107 | return URL.parse(req.base).host === location.host ?
|
108 | location.href :
|
109 | req.base;
|
110 | } |
\ | No newline at end of file |