1 | const httpError = require('http-errors')
|
2 | const XHubSignature = require('x-hub-signature')
|
3 |
|
4 | const defaults = {
|
5 | require: true,
|
6 | algorithm: 'sha1',
|
7 | header: 'X-Hub-Signature',
|
8 | getRawBody: req => req.rawBody
|
9 | }
|
10 |
|
11 | module.exports = function verifyXHubSignature (options) {
|
12 | const config = Object.assign({}, defaults, options)
|
13 | const x = new XHubSignature(config.algorithm, config.secret)
|
14 |
|
15 | if (typeof config.getRawBody !== 'function') {
|
16 | throw new Error('x-hub-signature middleware: "getRawBody" must be a function')
|
17 | }
|
18 |
|
19 | return function (req, res, next) {
|
20 | const rawBody = config.getRawBody(req)
|
21 | if (!rawBody) {
|
22 | return next(httpError(500, 'Missing req.rawBody, see the x-hub-signature readme'))
|
23 | }
|
24 |
|
25 | const signature = req.header(config.header)
|
26 |
|
27 | if (config.require && !signature) {
|
28 | return next(httpError(400, `Missing ${config.header} header`))
|
29 | }
|
30 |
|
31 | if (signature) {
|
32 | const body = Buffer.from(rawBody)
|
33 |
|
34 | if (!x.verify(signature, body)) {
|
35 | return next(httpError(400, `Invalid ${config.header}`))
|
36 | }
|
37 | }
|
38 |
|
39 | next()
|
40 | }
|
41 | }
|