-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
54 lines (49 loc) · 1.7 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
var crypto = require('crypto');
var qs = require('qs');
var SLACK_SIGNING_SECRET = process.env.SLACK_SIGNING_SECRET;
var DEFAULT_RESPONSE = {
code: 'unauthorized',
text: 'Unable to verify Slack request'
};
function verifySignature(signature, timestamp, body, secret) {
if (signature.length !== 67) {
return false;
}
var givenSignature = Buffer.from(signature);
var computedSignature = Buffer.from('v0=' + crypto
.createHmac('sha256', secret || SLACK_SIGNING_SECRET)
.update('v0:' + timestamp + ':')
.update(qs.stringify(body, { format: 'RFC1738' }))
.digest('hex')
);
return crypto.timingSafeEqual(givenSignature, computedSignature);
}
function slackVerification(options) {
var opts = options || {};
var secret = opts.secret || SLACK_SIGNING_SECRET;
var unauthorizedResponse = opts.unauthorizedResponse || DEFAULT_RESPONSE;
var status = opts.status || 403;
var maxSecondsOld = opts.maxSecondsOld || 300;
if (!secret) {
throw new Error("simple-slack-verification: No secret given.");
}
return function(req, res, next) {
var timestamp = req.headers['x-slack-request-timestamp'];
var signature = req.headers['x-slack-signature'];
// missing headers
if (!timestamp || !signature) {
return res.status(status).send(unauthorizedResponse);
}
// old timestamp
if (Math.floor(new Date() / 1000) - timestamp > maxSecondsOld) {
return res.status(status).send(unauthorizedResponse);
}
// invalid signature
if (!verifySignature(signature, timestamp, req.body, secret)) {
return res.status(status).send(unauthorizedResponse);
}
next();
};
};
module.exports = slackVerification;
module.exports.verifySignature = verifySignature;