mirror of
https://github.com/jambonz/jambonz-node.git
synced 2025-12-19 05:17:49 +00:00
cleanup for readability
This commit is contained in:
@@ -18,19 +18,7 @@ function secureCompare(a, b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// use crypto.timingSafeEqual if available (since Node.js v6.6.0),
|
||||
// otherwise use our own scmp-internal function.
|
||||
if (crypto.timingSafeEqual) {
|
||||
return crypto.timingSafeEqual(a, b);
|
||||
}
|
||||
|
||||
const len = a.length;
|
||||
let result = 0;
|
||||
|
||||
for (let i = 0; i < len; ++i) {
|
||||
result |= a[i] ^ b[i];
|
||||
}
|
||||
return result === 0;
|
||||
return crypto.timingSafeEqual(a, b);
|
||||
}
|
||||
|
||||
function parseHeader(header, scheme) {
|
||||
@@ -38,19 +26,15 @@ function parseHeader(header, scheme) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const keyActions = {
|
||||
t: (accum, value) => (accum.timestamp = value, accum),
|
||||
[scheme]: (accum, value) => (accum.signatures.push(value), accum)
|
||||
};
|
||||
|
||||
return header.split(',').reduce(
|
||||
(accum, item) => {
|
||||
const kv = item.split('=');
|
||||
|
||||
if (kv[0] === 't') {
|
||||
accum.timestamp = kv[1];
|
||||
}
|
||||
|
||||
if (kv[0] === scheme) {
|
||||
accum.signatures.push(kv[1]);
|
||||
}
|
||||
|
||||
return accum;
|
||||
const [key, value] = item.split('=');
|
||||
return keyActions[key] ? keyActions[key](accum, value) : accum;
|
||||
},
|
||||
{
|
||||
timestamp: -1,
|
||||
@@ -93,7 +77,7 @@ class WebhookResponse {
|
||||
static verifyJambonzSignature(secret) {
|
||||
return (req, res, next) => {
|
||||
const header = req.get('Jambonz-Signature');
|
||||
if (!header) throw new Error(`missing Jambonz-Signature in ${req.url}`);
|
||||
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');
|
||||
@@ -105,9 +89,7 @@ class WebhookResponse {
|
||||
let signatureFound = false;
|
||||
for (const secret of secrets) {
|
||||
const expectedSignature = computeSignature(req.body, details.timestamp, secret);
|
||||
signatureFound = details.signatures.filter(
|
||||
secureCompare.bind(null, expectedSignature)
|
||||
).length > 0;
|
||||
signatureFound = details.signatures.some((sig) => secureCompare(expectedSignature, sig));
|
||||
if (signatureFound) break;
|
||||
}
|
||||
if (!signatureFound) {
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
const assert = require('assert');
|
||||
const parseurl = require('parseurl');
|
||||
|
||||
function matchesPath(match, path) {
|
||||
if ('*' === match) return true;
|
||||
|
||||
const urlChunks = path.split('/').filter((c) => c.length);
|
||||
const matchChunks = match.split('/').filter((c) => c.length);
|
||||
|
||||
if (urlChunks.length >= matchChunks.length) {
|
||||
return matchChunks.every((chunk, idx) => chunk === urlChunks[idx]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class WsRouter {
|
||||
constructor() {
|
||||
this.routes = [];
|
||||
@@ -13,6 +26,7 @@ class WsRouter {
|
||||
}
|
||||
assert.ok(typeof callback === 'function' || callback instanceof WsRouter,
|
||||
'WsRouter.use - callback must be a function or a WsRouter instance');
|
||||
assert.ok(typeof match === 'string', 'WsRouter.use - match must be a string');
|
||||
this.routes.push({match, callback});
|
||||
}
|
||||
|
||||
@@ -22,27 +36,7 @@ class WsRouter {
|
||||
const path = parsed.pathname;
|
||||
|
||||
const route = this.routes.find(({match}) => {
|
||||
/* wildcard */
|
||||
if ('*' === match) return true;
|
||||
|
||||
/* try matching by path */
|
||||
const urlChunks = path.split('/').filter((c) => c.length);
|
||||
const matchChunks = match.split('/').filter((c) => c.length);
|
||||
if (urlChunks.length >= matchChunks.length) {
|
||||
let idx = 0;
|
||||
do {
|
||||
if (urlChunks[idx] !== matchChunks[idx]) break;
|
||||
idx++;
|
||||
} while (idx < matchChunks.length);
|
||||
if (idx > 0) {
|
||||
req.url = urlChunks.slice(idx).join('/') + '/' + (parsed.search || '');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: try matching by param */
|
||||
|
||||
/* TODO : try matching by query args */
|
||||
return matchesPath(match, path);
|
||||
});
|
||||
|
||||
if (!route) return false;
|
||||
|
||||
Reference in New Issue
Block a user