-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
78 lines (66 loc) · 2.15 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
'use strict'
const fp = require('fastify-plugin')
const { Unauthorized, BadRequest } = require('http-errors')
const {
constructSignatureString,
extractSignature,
getAlgorithm,
getDigest
} = require('./lib')
const DEFAULT_ENCODING = 'base64'
const DEFAULT_ERROR_MESSAGE = 'Signature verification failed'
function fastifyHMAC (fastify, options, next) {
const pluginOptions = {
algorithmMap: {},
constructSignatureString,
digestEncoding: DEFAULT_ENCODING,
extractSignature,
getAlgorithm,
getDigest,
getSignatureEncoding: () => DEFAULT_ENCODING,
validateRequests: true,
sharedSecret: null,
verificationError: () => new Unauthorized(DEFAULT_ERROR_MESSAGE),
...options
}
if (pluginOptions.sharedSecret === null && pluginOptions.validateRequests) {
next(new Error('Must provide shared secret in plugin options when validateRequests hook enabled'))
}
function validateHMAC (argSharedSecret = null, callback) {
const request = this
const {
extractSignature,
constructSignatureString,
verificationError,
sharedSecret: configSharedSecret
} = pluginOptions
if (configSharedSecret === null && argSharedSecret === null) {
throw BadRequest('No shared secret provided')
}
// argSharedSecret takes precedence over configSharedSecret
const options = {
...pluginOptions,
...(configSharedSecret !== null ? { sharedSecret: configSharedSecret } : {}),
...(argSharedSecret !== null ? { sharedSecret: argSharedSecret } : {})
}
try {
if (extractSignature(request, pluginOptions) === constructSignatureString(request, options)) {
return callback ? callback() : true
}
throw Error(DEFAULT_ERROR_MESSAGE)
} catch (e) {
const error = verificationError(e.message)
return callback ? callback(error) : error
}
}
fastify.decorateRequest('validateHMAC', validateHMAC)
if (pluginOptions.validateRequests) {
fastify.addHook('preValidation', function (request, reply, next) {
request.validateHMAC(pluginOptions.sharedSecret, next)
})
}
next()
}
module.exports = fp(fastifyHMAC, {
name: 'fastify-hmac'
})