Feat: jambonz clients (#104)

* authenticate user

* authenticate user

* update db helper

* update db helper

* fix jslint

* use digest-utils
This commit is contained in:
Hoan Luu Huu
2023-06-15 18:36:33 +07:00
committed by GitHub
parent f7b3815ee3
commit c37d417a69
4 changed files with 33 additions and 64 deletions

6
app.js
View File

@@ -76,7 +76,8 @@ const {
lookupAccountBySipRealm,
lookupAccountBySid,
lookupAccountCapacitiesBySid,
queryCallLimits
queryCallLimits,
lookupClientByAccountAndUsername
} = require('@jambonz/db-helpers')({
host: process.env.JAMBONES_MYSQL_HOST,
port: process.env.JAMBONES_MYSQL_PORT || 3306,
@@ -125,7 +126,8 @@ srf.locals = {...srf.locals,
lookupAccountBySid,
lookupAccountBySipRealm,
lookupAccountCapacitiesBySid,
queryCallLimits
queryCallLimits,
lookupClientByAccountAndUsername
},
realtimeDbHelpers: {
createSet,

View File

@@ -1,8 +1,8 @@
const debug = require('debug')('jambonz:sbc-inbound');
const assert = require('assert');
const Emitter = require('events');
const parseUri = require('drachtio-srf').parseUri;
const {nudgeCallCounts, roundTripTime} = require('./utils');
const digestChallenge = require('@jambonz/digest-utils');
const msProxyIps = process.env.MS_TEAMS_SIP_PROXY_IPS ?
process.env.MS_TEAMS_SIP_PROXY_IPS.split(',').map((i) => i.trim()) :
[];
@@ -22,42 +22,8 @@ const initCdr = (req) => {
};
module.exports = function(srf, logger) {
class AuthOutcomeReporter extends Emitter {
constructor(stats) {
super();
this
.on('regHookOutcome', ({rtt, status}) => {
stats.histogram('app.hook.response_time', rtt, ['hook_type:auth', `status:${status}`]);
})
.on('error', async(err, req) => {
const {account_sid, account} = req.locals;
const {writeAlerts, AlertType} = req.srf.locals;
if (account_sid) {
let opts = {account_sid, service_provider_sid: account.service_provider_sid};
if (err.code === 'ECONNREFUSED') {
opts = {...opts, alert_type: AlertType.WEBHOOK_CONNECTION_FAILURE, url: err.hook};
}
else if (err.code === 'ENOTFOUND') {
opts = {...opts, alert_type: AlertType.WEBHOOK_CONNECTION_FAILURE, url: err.hook};
}
else if (err.name === 'StatusError') {
opts = {...opts, alert_type: AlertType.WEBHOOK_STATUS_FAILURE, url: err.hook, status: err.statusCode};
}
if (opts.alert_type) {
try {
await writeAlerts(opts);
} catch (err) {
logger.error({err, opts}, 'Error writing alert');
}
}
}
});
}
}
const {
lookupAuthHook,
lookupAppByTeamsTenant,
lookupAccountBySipRealm,
lookupAccountBySid,
@@ -65,10 +31,6 @@ module.exports = function(srf, logger) {
queryCallLimits
} = srf.locals.dbHelpers;
const {stats, writeCdrs} = srf.locals;
const authenticator = require('@jambonz/http-authenticator')(lookupAuthHook, logger, {
blacklistUnknownRealms: true,
emitter: new AuthOutcomeReporter(stats)
});
const initLocals = (req, res, next) => {
const callId = req.get('Call-ID');
@@ -240,6 +202,13 @@ module.exports = function(srf, logger) {
account,
application_sid: account.device_calling_application_sid,
webhook_secret: account.webhook_secret,
realm: uri.host,
...(account.registration_hook && {
registration_hook_url: account.registration_hook.url,
registration_hook_method: account.registration_hook.method,
registration_hook_username: account.registration_hook.username,
registration_hook_password: account.registration_hook.password
}),
...req.locals
};
}
@@ -382,7 +351,7 @@ module.exports = function(srf, logger) {
try {
/* TODO: check if this is a gateway that we have an ACL for */
if (req.locals.originator !== 'user') return next();
return authenticator(req, res, next);
return digestChallenge(req, res, next);
} catch (err) {
stats.increment('sbc.terminations', ['sipStatus:500']);
logger.error(err, `${req.get('Call-ID')} Error looking up related info for inbound call`);

38
package-lock.json generated
View File

@@ -9,8 +9,8 @@
"version": "0.8.3",
"license": "MIT",
"dependencies": {
"@jambonz/db-helpers": "^0.9.0",
"@jambonz/http-authenticator": "^0.2.2",
"@jambonz/db-helpers": "^0.9.1",
"@jambonz/digest-utils": "^0.0.2",
"@jambonz/http-health-check": "^0.0.1",
"@jambonz/realtimedb-helpers": "^0.8.6",
"@jambonz/rtpengine-utils": "^0.4.3",
@@ -600,9 +600,9 @@
}
},
"node_modules/@jambonz/db-helpers": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.0.tgz",
"integrity": "sha512-4fvwONj4jQNIHyG76WGdE7AuMt9vDl4sfHmHrY3PSgOh+kf2BCtBEYqoxyJ96/NH9OeUYkuXoM6fjSvpS7GYVw==",
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.1.tgz",
"integrity": "sha512-asQQdeQEl1jCyQAxp2kMljZzExQbcG/mBxVYA2Jf0E1ReZctC206LWMWmY/rvbSHHXNZBzJlNxhD0dQB+FtJYA==",
"dependencies": {
"cidr-matcher": "^2.1.1",
"debug": "^4.3.4",
@@ -611,14 +611,13 @@
"uuid": "^8.3.2"
}
},
"node_modules/@jambonz/http-authenticator": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@jambonz/http-authenticator/-/http-authenticator-0.2.2.tgz",
"integrity": "sha512-yl6CajF8c8BOTrXEB/AbTXgqrT6XeymwVZbJWeJG8HZA21UXkKCcM26b8f0P9qqokSvFj0ObjCk22Ks2ytSLNg==",
"node_modules/@jambonz/digest-utils": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@jambonz/digest-utils/-/digest-utils-0.0.2.tgz",
"integrity": "sha512-TcUpHQZZ+69mnU6wA3pBcq17l9NbRZCQLJY7g/i9eaRONpAfw6vYkRWF7GtIaJat9Gu18tVs4idHvbfiqx40tA==",
"dependencies": {
"bent": "^7.3.12",
"debug": "^4.3.1",
"drachtio-srf": "^4.4.63",
"debug": "^4.3.4",
"nonce": "^1.0.4",
"qs": "^6.9.4"
}
@@ -5748,9 +5747,9 @@
"dev": true
},
"@jambonz/db-helpers": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.0.tgz",
"integrity": "sha512-4fvwONj4jQNIHyG76WGdE7AuMt9vDl4sfHmHrY3PSgOh+kf2BCtBEYqoxyJ96/NH9OeUYkuXoM6fjSvpS7GYVw==",
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.1.tgz",
"integrity": "sha512-asQQdeQEl1jCyQAxp2kMljZzExQbcG/mBxVYA2Jf0E1ReZctC206LWMWmY/rvbSHHXNZBzJlNxhD0dQB+FtJYA==",
"requires": {
"cidr-matcher": "^2.1.1",
"debug": "^4.3.4",
@@ -5759,14 +5758,13 @@
"uuid": "^8.3.2"
}
},
"@jambonz/http-authenticator": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@jambonz/http-authenticator/-/http-authenticator-0.2.2.tgz",
"integrity": "sha512-yl6CajF8c8BOTrXEB/AbTXgqrT6XeymwVZbJWeJG8HZA21UXkKCcM26b8f0P9qqokSvFj0ObjCk22Ks2ytSLNg==",
"@jambonz/digest-utils": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@jambonz/digest-utils/-/digest-utils-0.0.2.tgz",
"integrity": "sha512-TcUpHQZZ+69mnU6wA3pBcq17l9NbRZCQLJY7g/i9eaRONpAfw6vYkRWF7GtIaJat9Gu18tVs4idHvbfiqx40tA==",
"requires": {
"bent": "^7.3.12",
"debug": "^4.3.1",
"drachtio-srf": "^4.4.63",
"debug": "^4.3.4",
"nonce": "^1.0.4",
"qs": "^6.9.4"
}

View File

@@ -25,14 +25,14 @@
"jslint": "eslint app.js lib"
},
"dependencies": {
"@jambonz/db-helpers": "^0.9.0",
"@jambonz/http-authenticator": "^0.2.2",
"@jambonz/db-helpers": "^0.9.1",
"@jambonz/http-health-check": "^0.0.1",
"@jambonz/realtimedb-helpers": "^0.8.6",
"@jambonz/rtpengine-utils": "^0.4.3",
"@jambonz/siprec-client-utils": "^0.2.5",
"@jambonz/stats-collector": "^0.1.8",
"@jambonz/time-series": "^0.2.5",
"@jambonz/digest-utils": "^0.0.2",
"aws-sdk": "^2.1354.0",
"bent": "^7.3.12",
"cidr-matcher": "^2.1.1",