add support for verifying jambonz signature

This commit is contained in:
Dave Horton
2021-04-19 10:52:20 -04:00
parent 93b29f51d8
commit 64fd092ae5
4 changed files with 30 additions and 8 deletions

View File

@@ -31,6 +31,30 @@ app.listen(port, () => {
```
[See here](https://docs.jambonz.org/jambonz/) for information on the available verbs you can use in a jambonz application, and for their associated properties.
#### Verifying webhook signature
If your jambonz server includes a Jambonz-Signature header on webhook requests, you can verify that the request was signed by jambonz using your webhook secret as follows:
```
const {WebhookResponse} = require('@jambonz/node-client');
if (process.env.WEBHOOK_SECRET) {
app.use(WebhookResponse.verifyJambonzSignature(process.env.WEBHOOK_SECRET));
}
const express = require('express');
const app = express();
app.use(express.json());
/* make sure this comes after the body has been converted to json */
if (process.env.WEBHOOK_SECRET) {
app.use(WebhookResponse.verifyJambonzSignature(process.env.WEBHOOK_SECRET));
}
/* if we get here we know the request was signed with our webhook secret */
app.post('/my-app', (req, res) => { ...})
```
### REST API calls
#### Creating a client

View File

@@ -57,14 +57,13 @@ function parseHeader(header, scheme) {
);
}
function computeSignature(payload, secret) {
function computeSignature(payload, timestamp, secret) {
const data = Buffer.isBuffer(payload) ?
payload.toString('utf8') :
(typeof payload === 'object' ? JSON.stringify(payload) : payload);
return crypto
.createHmac('sha256', secret)
.update(data, 'utf8')
.update(`${timestamp}.${data}`, 'utf8')
.digest('hex');
}
@@ -92,7 +91,7 @@ class WebhookResponse {
static verifyJambonzSignature(secret) {
return (req, res, next) => {
const header = req.get('Jambonz-Signature');
if (!header) throw new Error('missing Jambonz-Signature');
if (!header) throw new Error(`missing Jambonz-Signature in ${req.url}`);
const details = parseHeader(header, EXPECTED_SCHEME);
if (!details || details.timestamp === -1) {
throw new Error('unable to extract timestamp and signatures from header');
@@ -112,7 +111,6 @@ class WebhookResponse {
if (timestampAge > DEFAULT_TOLERANCE) {
throw new Error('timestamp outside of tolerance');
}
next();
};
}

View File

@@ -74,9 +74,9 @@ function validate(name, data) {
* Validate the payload for an updateCall request
*/
const validateCallUpdate = (opts) => {
const {call_hook, call_status, listen_status, mute_status, whisper} = opts;
const {call_hook, child_call_hook, call_status, listen_status, mute_status, whisper} = opts;
assert.ok(call_hook || call_status || listen_status || mute_status || whisper,
assert.ok(call_hook || child_call_hook || call_status || listen_status || mute_status || whisper,
`calls.update: invalid request ${JSON.stringify(opts)}`);
if (call_status) assert.ok(['completed', 'no-answer'].includes(call_status),

View File

@@ -1,6 +1,6 @@
{
"name": "@jambonz/node-client",
"version": "0.0.6",
"version": "0.1.0",
"description": "",
"main": "lib/index.js",
"scripts": {