-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
103 lines (89 loc) · 2.83 KB
/
index.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const
/**
* Parse Basic authentication header and return decoded credentials
* @param {string} digest
* @returns {{username: string, password: string}}
*/
basicAuthParser = (digest) => {
const [username, password] = Buffer.from(digest, 'base64')
.toString('utf8')
.split(':');
return {username, password};
},
/**
* Parse Bearer authentication header
* (in this case we just return the token since it is already in a plain text)
* @param {string} digest
* @returns {{token: string}}
*/
bearerAuthParser = (digest) => {
return {token: digest};
},
/**
* Parse Digest authentication header
* Return credentials and vault with all parsed values
* @param {string} digest
* @returns {{username: string, password: string, vault: Object}}
*/
digestAuthParser = (digest) => {
const params = digest.split(','),
vault = params.reduce((result, param) => {
const [key, value] = param.trim().split('=');
result[key] = value.replace(/"/g, '');
return result;
}, {});
return {
username: vault.username,
password: vault.password,
vault
};
},
/**
* If the method is unknown, just return the digest
* @param {string} digest
* @returns {{digest: string}}
*/
defaultParser = (digest) => {
return {digest};
},
PARSERS = {
'basic': basicAuthParser,
'bearer': bearerAuthParser,
'digest': digestAuthParser
},
/**
* Split the given auth string into scheme and digest
* @param {string} auth
* @returns {{scheme: string, digest: string}}
*/
splitAuthHeader = (auth) => {
const pattern = /^\s*(\w+)\s+(.*)$/,
[, scheme, digest] = pattern.exec(auth) || [];
return {scheme, digest};
},
/**
* Auth parsing middleware
* @param {{propName: string}} config
* @returns {func}
*/
authParseMiddleware = (config) => {
const {propName = 'auth'} = config || {};
return (ctx, next) => {
if (ctx.header && ctx.header.authorization) {
const {authorization: auth} = ctx.header,
{scheme, digest} = splitAuthHeader(auth);
if (scheme) {
const parser = PARSERS[scheme.toLowerCase()] || defaultParser,
props = parser(digest);
ctx.state[propName] = {
digest,
scheme,
...props
};
}
}
return next();
};
};
const Module = module.exports = authParseMiddleware;
Module.splitAuthHeader = splitAuthHeader;