mirror of
https://github.com/jambonz/jambonz-node.git
synced 2025-12-19 05:17:49 +00:00
add support for verifying jambonz signature
This commit is contained in:
24
README.md
24
README.md
@@ -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
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@jambonz/node-client",
|
||||
"version": "0.0.6",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user