mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2025-12-19 05:47:46 +00:00
validate call hook urls (#431)
This commit is contained in:
@@ -7,12 +7,13 @@ const {promisePool} = require('../../db');
|
||||
const decorate = require('./decorate');
|
||||
const sysError = require('../error');
|
||||
const { validate } = require('@jambonz/verb-specifications');
|
||||
const { parseApplicationSid } = require('./utils');
|
||||
const { parseApplicationSid, isInvalidUrl } = require('./utils');
|
||||
const preconditions = {
|
||||
'add': validateAdd,
|
||||
'update': validateUpdate
|
||||
};
|
||||
|
||||
|
||||
const validateRequest = async(req, account_sid) => {
|
||||
try {
|
||||
if (req.user.hasScope('admin')) {
|
||||
@@ -62,6 +63,14 @@ async function validateAdd(req) {
|
||||
if (req.body.call_status_hook && typeof req.body.call_hook !== 'object') {
|
||||
throw new DbErrorBadRequest('\'call_status_hook\' must be an object when adding an application');
|
||||
}
|
||||
let urlError = await isInvalidUrl(req.body.call_hook.url);
|
||||
if (urlError) {
|
||||
throw new DbErrorBadRequest(`call_hook ${urlError}`);
|
||||
}
|
||||
urlError = await isInvalidUrl(req.body.call_status_hook.url);
|
||||
if (urlError) {
|
||||
throw new DbErrorBadRequest(`call_status_hook ${urlError}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function validateUpdate(req, sid) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const { v4: uuid, validate } = require('uuid');
|
||||
const URL = require('url').URL;
|
||||
const isValidHostname = require('is-valid-hostname');
|
||||
const Account = require('../../models/account');
|
||||
const {promisePool} = require('../../db');
|
||||
const {cancelSubscription, detachPaymentMethod} = require('../../utils/stripe-utils');
|
||||
@@ -464,6 +466,28 @@ function hasValue(data) {
|
||||
}
|
||||
}
|
||||
|
||||
const isInvalidUrl = async(s) => {
|
||||
const protocols = ['https:', 'http:', 'ws:', 'wss:'];
|
||||
try {
|
||||
const url = new URL(s);
|
||||
if (s.length != s.trim().length) {
|
||||
return 'URL contains leading/trailing whitespace';
|
||||
}
|
||||
else if (!isValidHostname(url.hostname)) {
|
||||
return `URL has invalid hostname ${url.hostname}`;
|
||||
}
|
||||
else if (!protocols.includes(url.protocol)) {
|
||||
return `URL has missing or invalid protocol ${url.protocol}`;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
return 'URL is invalid';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = {
|
||||
setupFreeTrial,
|
||||
createTestCdrs,
|
||||
@@ -486,4 +510,5 @@ module.exports = {
|
||||
disableSubspace,
|
||||
validatePasswordSettings,
|
||||
hasValue,
|
||||
isInvalidUrl
|
||||
};
|
||||
|
||||
7
package-lock.json
generated
7
package-lock.json
generated
@@ -33,6 +33,7 @@
|
||||
"form-data": "^4.0.0",
|
||||
"helmet": "^7.1.0",
|
||||
"ibm-watson": "^9.0.1",
|
||||
"is-valid-hostname": "^1.0.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mailgun.js": "^10.2.1",
|
||||
"microsoft-cognitiveservices-speech-sdk": "1.36.0",
|
||||
@@ -8533,6 +8534,12 @@
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
||||
},
|
||||
"node_modules/is-valid-hostname": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-valid-hostname/-/is-valid-hostname-1.0.2.tgz",
|
||||
"integrity": "sha512-X/kiF3Xndj6WI7l/yLyzR7V1IbQd6L4S4cewSL0fRciemPmHbaXIKR2qtf+zseH+lbMG0vFp4HvCUe7amGZVhw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-weakmap": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
"form-data": "^4.0.0",
|
||||
"helmet": "^7.1.0",
|
||||
"ibm-watson": "^9.0.1",
|
||||
"is-valid-hostname": "^1.0.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mailgun.js": "^10.2.1",
|
||||
"microsoft-cognitiveservices-speech-sdk": "1.36.0",
|
||||
|
||||
Reference in New Issue
Block a user