JavaScript Webhook ReceiverΒΆ
Download webhook.js
/*
* Debugging webhook receiver endpoint.
*
* $ openssl req -x509 -newkey rsa:4096 -keyout sslkey.pem -out sslcert.pem -nodes -subj '/CN=localhost'
* $ node webhook.js SECRET sslkey.pem sslcert.pem
*
* To test using api key "SECRET":
* $ curl -k -v --header "X-Signature: 3q8QXTAGaey18yL8FWTqdVlbMr6hcuNvM4tefa0o9nA=" --data '{}' https://localhost:8443/sent
*/
var https = require('https');
var fs = require('fs');
var crypto = require('crypto');
const PORT = 8443;
function handleRequest(request, response){
console.log("Request %s", request.url);
var body = [];
request.on('data', function (chunk) {
body.push(chunk);
})
.on('end', function () {
body = Buffer.concat(body);
console.log("Body: %s", body.toString());
var signature = request.headers["x-signature"];
if (!signature) {
console.warn("No signature supplied, forbidden");
response.writeHead(403);
response.end();
return;
}
var hmac = crypto.createHmac('sha256', apiKey);
hmac.update(body);
var computedSignature = hmac.digest('base64');
if (signature != computedSignature) {
console.warn("Signature does not match, forbidden (%s != %s)", signature, computedSignature);
response.writeHead(403);
response.end();
return;
}
console.log("Signature validated");
response.writeHead(204);
response.end();
});
}
if (process.argv.length <= 4) {
console.error("Usage: node webhook.js <api-key> <sslkey-path> <sslcert-path>");
process.exit(1);
}
var apiKey = process.argv[2];
const options = {
key: fs.readFileSync(process.argv[3]),
cert: fs.readFileSync(process.argv[4])
};
var server = https.createServer(options, handleRequest);
server.listen(PORT, function(){
console.log("Server listening on port %s api key %s", PORT, apiKey);
});