-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathdecapsulate.js
116 lines (96 loc) · 2.1 KB
/
decapsulate.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
104
105
106
107
108
109
110
111
112
113
114
115
116
const utils = require('./utils');
/***
* hvalidate
*
* validate (and remove) header
*
* @function
* @api private
*
* @param {String} token
* @param {Buffer} header
* @returns {String} token
*/
function hvalidate(token, header) {
const parsed = Buffer.from(token, 'utf-8');
const hlen = Buffer.byteLength(header);
const leading = parsed.slice(0, hlen);
if (!utils.cnstcomp(header, leading)) { throw new Error('Invalid message header'); }
return parsed.slice(hlen).toString('utf-8');
}
/***
* extract
*
* extract footer
*
* @function
* @api private
*
* @param {String} token
* @returns {Buffer} footer
*/
function extract(token) {
const pieces = token.split('.');
return (pieces.length > 3)
? utils.fromB64URLSafe(pieces.pop())
: Buffer.from('');
};
/***
* remove
*
* remove footer
*
* @function
* @api private
*
* @param {String} token
* @returns {String} token
*/
function remove(token) {
const pieces = token.split('.');
return (pieces.length > 3)
? pieces.slice(0, 3).join('.')
: token;
};
/***
* fvalidate
*
* validate (and remove) footer
*
* @function
* @api private
*
* @param {String} token
* @param {Buffer} footer
* @returns {String} token
*/
function fvalidate(token, footer) {
if (!footer) { return token; }
footer = Buffer.concat([ Buffer.from('.', 'utf-8'), footer ]);
const trailing = Buffer.concat([ Buffer.from('.', 'utf-8'), extract(token) ]);
if (!utils.cnstcomp(footer, trailing)) { throw new Error('Invalid message footer'); }
return remove(token);
}
/***
* decapsulate
*
* validate and remove headers and footers
*
* @param {Buffer} header
* @param {String} token
* @param {String|Buffer} footer
* @returns {Array} parsed
*/
module.exports = decapsulate;
function decapsulate(header, token, footer) {
if (!footer) {
footer = extract(token);
token = remove(token);
} else {
[ footer ] = (utils.parse('utf-8'))(footer);
token = fvalidate(token, footer);
}
let payload = hvalidate(token, header);
[ payload ] = (utils.parse('base64'))(payload);
return [ header, payload, footer ];
}