UNPKG

3.31 kBJavaScriptView Raw
1/**
2 * Module dependencies
3 */
4
5var qs = require('qs');
6var URL = require('url');
7var debug = require('debug')('poe-ui:oauth');
8
9module.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
23function 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 // we're already logged-in
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 // TODO sign the state
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
53function error() {
54 return function oauthError(req, res, next) {
55 if (!req.query.error) return next();
56 // TODO where should we redirect?
57 res.redirect(req.base);
58 };
59}
60
61function 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
90function 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
103function 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