-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpress.js
55 lines (46 loc) · 2.18 KB
/
express.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const fetch = require('node-fetch');
const jwt = require('jsonwebtoken');
const url = require('url');
const HttpsProxyAgent = require('https-proxy-agent');
const CHECK_TOKEN_PATH = '/api/checkandrefreshtoken';
const LOGIN_PATH = '/login';
/**
* Express middleware to handle Authorization header, check token, and populate req.user with
* the user informations. It will use userFactory if provided with the token data, and wait
* for the result. The result or the token data will be populated into req.user field.
* If authentication fails, it won't block requests, but req.user will be undefined.
* If you want to protect route, use **requireAuth** middleware.
*
* @param {String} provider Linkapp URL
* @param {Function} [userFactory] method called with token user data, it should
* return a promise or an object with your extended user data
*/
module.exports.initialize = ({ provider, userFactory }) => async (req, res, next) => {
const authHeader = req.headers.authorization || '';
const response = await fetch(url.resolve(provider, CHECK_TOKEN_PATH), {
headers: { Authorization: authHeader },
agent: process.env.AUTH_PROXY ? new HttpsProxyAgent(process.env.AUTH_PROXY) : null
});
if (response.status !== 200) return next();
const { success, newToken: updatedToken } = await response.json();
if (!success) return next();
const [_, authToken] = updatedToken.split(' ');
const userData = jwt.decode(authToken);
const userFactoryResponse = typeof(userFactory) === 'function' && userFactory(userData);
Object.assign(req, {
user: userFactoryResponse ?
(typeof(userFactoryResponse.then) === 'function' ? await userFactoryResponse : userFactoryResponse) :
userData
});
return next();
};
/**
* Express middleware to protect routes from unauthenticated users. It will check for a
* req.user field, so you need to use **initialize** middleware before.
* If req.user is undefined, it will prevent next routes to load and send back a 401 response with
* the login route in the body.
*/
module.exports.requireAuth = ({ provider }) => (req, res, next) => {
if (req.user) return next();
return res.status(401).send({ login: url.resolve(provider, LOGIN_PATH) });
}