Compare commits

...

20 Commits

Author SHA1 Message Date
Dave Horton
5bfc451c85 when running on kubernetes, use sbc-sip service rather than pinging sbcs 2022-02-23 12:27:34 -05:00
Dave Horton
47478fd409 fix possible exception 2022-02-19 09:57:51 -05:00
Dave Horton
c16a2662f2 bugfix: rest outdial issue caused by req.srf not properly set 2022-02-14 09:14:13 -05:00
Dave Horton
c1130adf03 merge 2022-02-12 10:12:45 -05:00
Dave Horton
f982f6c7d8 update to latest realtimedb-helpers 2022-02-12 10:10:03 -05:00
Snyk bot
f20190b0fc fix: upgrade aws-sdk from 2.1061.0 to 2.1062.0 (#69)
Snyk has created this PR to upgrade aws-sdk from 2.1061.0 to 2.1062.0.

See this package in npm:
https://www.npmjs.com/package/aws-sdk

See this project in Snyk:
https://app.snyk.io/org/davehorton/project/cec90d0e-0ded-433e-a42e-fe78b28ae489?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-02-12 09:23:13 -05:00
Snyk bot
74e85e1b16 fix: upgrade aws-sdk from 2.1060.0 to 2.1061.0 (#68)
Snyk has created this PR to upgrade aws-sdk from 2.1060.0 to 2.1061.0.

See this package in npm:
https://www.npmjs.com/package/aws-sdk

See this project in Snyk:
https://app.snyk.io/org/davehorton/project/cec90d0e-0ded-433e-a42e-fe78b28ae489?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-02-11 07:48:02 -05:00
Dave Horton
63e9cb985e allow target-level headers on outdials (#29) 2022-02-10 14:34:21 -05:00
Dave Horton
2e88ab1f55 bugfix: race condition on hangup sometimes resulted in outbound call attempt even though caller had hung up 2022-02-10 12:15:25 -05:00
Dave Horton
7f75a35515 bugfix: race condition on hangup could cause us to send dup webhook 2022-02-10 11:16:57 -05:00
Dave Horton
941727e93f add fs_public_ip to webhook payload (only when running in ec2 autoscale group) 2022-02-10 09:51:48 -05:00
Dave Horton
d8bfa33a00 include fs_sip_address and api_base_url in webhook paylods 2022-02-10 09:19:33 -05:00
Dave Horton
30ed5b6a02 add support for vad to gather and transcribe (#67) 2022-02-10 08:45:16 -05:00
Dave Horton
bac1b7f2c6 bump version 2022-02-09 15:42:27 -05:00
Dave Horton
48deb3ae89 update to latest @jambonz/realtimedb-helpers with support for redis username / password auth 2022-02-09 15:21:55 -05:00
Dave Horton
de83f735ea memory leak fixes 2022-02-08 20:33:16 -05:00
Dave Horton
cfe9397502 lint 2022-02-03 07:36:01 -05:00
Dave Horton
dda3335060 update deps, add helmet middleware 2022-02-03 07:31:30 -05:00
Dave Horton
2329f0cda0 child tasks must remove reference to parent on kill or else entangled parent-child tasks will not be gc'ed 2022-02-01 11:00:12 -05:00
Dave Horton
36683dc151 bugfix: include custom jambonz headers on rest outdial 2022-01-28 13:36:06 -05:00
16 changed files with 215 additions and 124 deletions

3
app.js
View File

@@ -31,6 +31,7 @@ const {
// HTTP
const express = require('express');
const helmet = require('helmet');
const app = express();
Object.assign(app.locals, {
logger,
@@ -73,6 +74,8 @@ srf.invite((req, res) => {
});
// HTTP
app.use(helmet());
app.use(helmet.hidePoweredBy());
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use('/', httpRoutes);

View File

@@ -35,6 +35,8 @@ router.post('/', async(req, res) => {
opts.headers = {
...opts.headers,
'X-Jambonz-Routing': target.type,
'X-Jambonz-FS-UUID': srf.locals.fsUUID,
'X-Call-Sid': callSid,
'X-Account-Sid': req.body.account_sid
};
@@ -120,6 +122,7 @@ router.post('/', async(req, res) => {
res.status(500).send('Call Failure');
return;
}
inviteReq.srf = srf;
/* ok our outbound INVITE is in flight */
const tasks = [restDial];

View File

@@ -105,7 +105,7 @@ module.exports = function(srf, logger) {
}
else {
const uri = parseUri(req.uri);
const arr = /context-(.*)/.exec(uri.user);
const arr = /context-(.*)/.exec(uri?.user);
if (arr) {
// this is a transfer from another feature server
const {retrieveKey, deleteKey} = srf.locals.dbHelpers;

View File

@@ -1,7 +1,6 @@
const {CallDirection, CallStatus} = require('../utils/constants');
const parseUri = require('drachtio-srf').parseUri;
const { v4: uuidv4 } = require('uuid');
/**
* @classdesc Represents the common information for all calls
* that is provided in call status webhooks
@@ -9,6 +8,7 @@ const { v4: uuidv4 } = require('uuid');
class CallInfo {
constructor(opts) {
let from ;
let srf;
this.direction = opts.direction;
if (opts.req) {
const u = opts.req.getParsedHeader('from');
@@ -19,6 +19,7 @@ class CallInfo {
if (this.direction === CallDirection.Inbound) {
// inbound call
const {app, req} = opts;
srf = req.srf;
this.callSid = req.locals.callSid,
this.accountSid = app.account_sid,
this.applicationSid = app.application_sid;
@@ -33,6 +34,7 @@ class CallInfo {
else if (opts.parentCallInfo) {
// outbound call that is a child of an existing call
const {req, parentCallInfo, to, callSid} = opts;
srf = req.srf;
this.callSid = callSid || uuidv4();
this.parentCallSid = parentCallInfo.callSid;
this.accountSid = parentCallInfo.accountSid;
@@ -47,6 +49,7 @@ class CallInfo {
else if (this.direction === CallDirection.None) {
// outbound SMS
const {messageSid, accountSid, applicationSid, res} = opts;
srf = res.srf;
this.messageSid = messageSid;
this.accountSid = accountSid;
this.applicationSid = applicationSid;
@@ -55,6 +58,7 @@ class CallInfo {
else {
// outbound call triggered by REST
const {req, callSid, accountSid, applicationSid, to, tag} = opts;
srf = req.srf;
this.callSid = callSid;
this.accountSid = accountSid;
this.applicationSid = applicationSid;
@@ -65,6 +69,11 @@ class CallInfo {
this.to = to;
if (tag) this._customerData = tag;
}
this.localSipAddress = srf.locals.localSipAddress;
if (srf.locals.publicIp) {
this.publicIp = srf.locals.publicIp;
}
}
/**
@@ -100,7 +109,8 @@ class CallInfo {
callStatus: this.callStatus,
callerId: this.callerId,
accountSid: this.accountSid,
applicationSid: this.applicationSid
applicationSid: this.applicationSid,
fsSipAddress: this.localSipAddress
};
['parentCallSid', 'originatingSipIp', 'originatingSipTrunkName'].forEach((prop) => {
if (this[prop]) obj[prop] = this[prop];
@@ -110,6 +120,13 @@ class CallInfo {
if (this._customerData) {
Object.assign(obj, {customerData: this._customerData});
}
if (process.env.JAMBONES_API_BASE_URL) {
Object.assign(obj, {apiBaseUrl: process.env.JAMBONES_API_BASE_URL});
}
if (this.publicIp) {
Object.assign(obj, {fsPublicIp: this.publicIp});
}
return obj;
}

View File

@@ -48,6 +48,7 @@ class CallSession extends Emitter {
this.taskIdx = 0;
this.stackIdx = 0;
this.callGone = false;
this.notifiedComplete = false;
this.tmpFiles = new Set();
@@ -988,6 +989,12 @@ class CallSession extends Emitter {
_notifyCallStatusChange({callStatus, sipStatus, duration}) {
if (this.callMoved) return;
/* race condition: we hang up at the same time as the caller */
if (callStatus === CallStatus.Completed) {
if (this.notifiedComplete) return;
this.notifiedComplete = true;
}
assert((typeof duration === 'number' && callStatus === CallStatus.Completed) ||
(!duration && callStatus !== CallStatus.Completed),
'duration MUST be supplied when call completed AND ONLY when call completed');

View File

@@ -453,7 +453,7 @@ class Conference extends Task {
this._playSession = null;
break;
}
} while (!this.killed && !this.conf_hold_status === 'hold');
} while (!this.killed && this.conf_hold_status !== 'hold');
}
/**

View File

@@ -147,7 +147,7 @@ class TaskDial extends Task {
this.epOther.play(this.dialMusic).catch((err) => {});
}
}
await this._attemptCalls(cs);
if (!this.killed) await this._attemptCalls(cs);
await this.awaitTaskDone();
this.logger.debug({callSid: this.cs.callSid}, 'Dial:exec task is done, sending actionHook if any');
await this.performAction(this.results, this.killReason !== KillReason.Replaced);
@@ -179,6 +179,7 @@ class TaskDial extends Task {
this._killOutdials();
if (this.sd) {
this.sd.kill();
this.sd.removeAllListeners();
this.sd = null;
}
if (this.callSid) sessionTracker.remove(this.callSid);
@@ -366,6 +367,9 @@ class TaskDial extends Task {
opts.headers['X-Requested-Carrier-Sid'] = voip_carrier_sid;
}
}
if (this.killed) return;
const sd = placeCall({
logger: this.logger,
application: cs.application,
@@ -381,7 +385,9 @@ class TaskDial extends Task {
sd
.on('callCreateFail', () => {
clearTimeout(this.timerRing);
this.dials.delete(sd.callSid);
sd.removeAllListeners();
if (this.dials.size === 0 && !this.sd) {
this.logger.debug('Dial:_attemptCalls - all calls failed after call create err, ending task');
this.kill(cs);
@@ -423,6 +429,7 @@ class TaskDial extends Task {
})
.on('accept', async() => {
this.logger.debug(`Dial:_attemptCalls - we have a winner: ${sd.callSid}`);
clearTimeout(this.timerRing);
try {
await this._connectSingleDial(cs, sd);
} catch (err) {
@@ -431,7 +438,9 @@ class TaskDial extends Task {
})
.on('decline', () => {
this.logger.debug(`Dial:_attemptCalls - declined: ${sd.callSid}`);
clearTimeout(this.timerRing);
this.dials.delete(sd.callSid);
sd.removeAllListeners();
if (this.dials.size === 0 && !this.sd) {
this.logger.debug('Dial:_attemptCalls - all calls failed after decline, ending task');
this.kill(cs);

View File

@@ -30,6 +30,10 @@ class TaskGather extends Task {
this.hints = recognizer.hints || [];
this.altLanguages = recognizer.altLanguages || [];
/* vad: if provided, we dont connect to recognizer until voice activity is detected */
const {enable, voiceMs = 0, mode = -1} = recognizer.vad || {};
this.vad = {enable, voiceMs, mode};
/* aws options */
this.vocabularyName = recognizer.vocabularyName;
this.vocabularyFilterName = recognizer.vocabularyFilterName;
@@ -137,6 +141,12 @@ class TaskGather extends Task {
async _initSpeech(cs, ep) {
const opts = {};
if (this.vad.enable) {
opts.START_RECOGNIZING_ON_VAD = 1;
if (this.vad.voiceMs) opts.RECOGNIZER_VAD_VOICE_MS = this.vad.voiceMs;
if (this.vad.mode >= 0 && this.vad.mode <= 3) opts.RECOGNIZER_VAD_MODE = this.vad.mode;
}
if ('google' === this.vendor) {
if (this.sttCredentials) opts.GOOGLE_APPLICATION_CREDENTIALS = JSON.stringify(this.sttCredentials.credentials);
Object.assign(opts, {

View File

@@ -338,6 +338,7 @@
"type": "string",
"enum": ["GET", "POST"]
},
"headers": "object",
"name": "string",
"number": "string",
"sipUri": "string",
@@ -389,6 +390,7 @@
"enum": ["google", "aws", "microsoft", "default"]
},
"language": "string",
"vad": "#vad",
"hints": "array",
"altLanguages": "array",
"profanityFilter": "boolean",
@@ -457,5 +459,15 @@
"required": [
"name"
]
},
"vad": {
"properties": {
"enable": "boolean",
"voiceMs": "number",
"mode": "number"
},
"required": [
"enable"
]
}
}

View File

@@ -62,7 +62,9 @@ class Task extends Emitter {
kill(cs) {
if (this.cs && !this.cs.isConfirmCallSession) this.logger.debug(`${this.name} is being killed`);
this._killInProgress = true;
// no-op
/* remove reference to parent task or else entangled parent-child tasks will not be gc'ed */
setImmediate(() => this.parentTask = null);
}
/**

View File

@@ -22,6 +22,10 @@ class TaskTranscribe extends Task {
this.interim = !!recognizer.interim;
this.separateRecognitionPerChannel = recognizer.separateRecognitionPerChannel;
/* vad: if provided, we dont connect to recognizer until voice activity is detected */
const {enable, voiceMs = 0, mode = -1} = recognizer.vad || {};
this.vad = {enable, voiceMs, mode};
/* google-specific options */
this.hints = recognizer.hints || [];
this.profanityFilter = recognizer.profanityFilter;
@@ -105,6 +109,12 @@ class TaskTranscribe extends Task {
async _startTranscribing(cs, ep) {
const opts = {};
if (this.vad.enable) {
opts.START_RECOGNIZING_ON_VAD = 1;
if (this.vad.voiceMs) opts.RECOGNIZER_VAD_VOICE_MS = this.vad.voiceMs;
if (this.vad.mode >= 0 && this.vad.mode <= 3) opts.RECOGNIZER_VAD_MODE = this.vad.mode;
}
ep.addCustomEventListener(GoogleTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(GoogleTranscriptionEvents.NoAudioDetected, this._onNoAudio.bind(this, cs, ep));
ep.addCustomEventListener(GoogleTranscriptionEvents.MaxDurationExceeded,

View File

@@ -45,6 +45,7 @@ class SnsNotifier extends Emitter {
}, 'response from SNS SubscribeURL');
const data = await this.describeInstance();
this.lifecycleState = data.AutoScalingInstances[0].LifecycleState;
this.emit('SubscriptionConfirmation', {publicIp: this.publicIp});
break;
case 'Notification':

View File

@@ -60,10 +60,16 @@ class SingleDialer extends Emitter {
opts.headers = opts.headers || {};
opts.headers = {
...opts.headers,
...(this.target.headers || {}),
'X-Jambonz-Routing': this.target.type,
'X-Jambonz-FS-UUID': srf.locals.fsUUID,
'X-Call-Sid': this.callSid
};
if (srf.locals.fsUUID) {
opts.headers = {
...opts.headers,
'X-Jambonz-FS-UUID': srf.locals.fsUUID,
};
}
this.ms = ms;
let uri, to;
try {
@@ -144,6 +150,7 @@ class SingleDialer extends Emitter {
* (a) create a CallInfo for this call
* (a) create a logger for this call
*/
req.srf = srf;
this.callInfo = new CallInfo({
direction: CallDirection.Outbound,
parentCallInfo: this.parentCallInfo,
@@ -215,6 +222,7 @@ class SingleDialer extends Emitter {
if (this.confirmHook) this._executeApp(this.confirmHook);
else this.emit('accept');
} catch (err) {
this.inviteInProgress = null;
const status = {callStatus: CallStatus.Failed};
if (err instanceof SipError) {
status.sipStatus = err.status;

View File

@@ -17,6 +17,10 @@ module.exports = (logger) => {
assert.ok(sbcs.length, 'JAMBONES_SBCS env var is empty or misconfigured');
logger.info({sbcs}, 'SBC inventory');
}
else if (process.env.K8S && process.env.K8S_SBC_SIP_SERVICE_NAME) {
sbcs = [`${process.env.K8S_SBC_SIP_SERVICE_NAME}:5060`];
logger.info({sbcs}, 'SBC inventory');
}
// listen for SNS lifecycle changes
let lifecycleEmitter = new Emitter();
@@ -28,6 +32,10 @@ module.exports = (logger) => {
lifecycleEmitter = await require('./aws-sns-lifecycle')(logger);
lifecycleEmitter
.on('SubscriptionConfirmation', ({publicIp}) => {
const {srf} = require('../..');
srf.locals.publicIp = publicIp;
})
.on(LifeCycleEvents.ScaleIn, () => {
logger.info('AWS scale-in notification: begin drying up calls');
dryUpCalls = true;

222
package-lock.json generated
View File

@@ -1,33 +1,34 @@
{
"name": "jambonz-feature-server",
"version": "v0.7.2",
"version": "v0.7.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "jambonz-feature-server",
"version": "v0.7.2",
"version": "v0.7.3",
"license": "MIT",
"dependencies": {
"@cognigy/socket-client": "^4.5.5",
"@jambonz/db-helpers": "^0.6.16",
"@jambonz/http-health-check": "^0.0.1",
"@jambonz/mw-registrar": "^0.2.1",
"@jambonz/realtimedb-helpers": "^0.4.19",
"@jambonz/realtimedb-helpers": "^0.4.26",
"@jambonz/stats-collector": "^0.1.6",
"@jambonz/time-series": "^0.1.5",
"aws-sdk": "^2.1060.0",
"@jambonz/time-series": "^0.1.6",
"aws-sdk": "^2.1073.0",
"bent": "^7.3.12",
"cidr-matcher": "^2.1.1",
"debug": "^4.3.2",
"deepcopy": "^2.1.0",
"drachtio-fsmrf": "^2.0.13",
"drachtio-srf": "^4.4.55",
"drachtio-srf": "^4.4.61",
"express": "^4.17.1",
"helmet": "^5.0.2",
"ip": "^1.1.5",
"moment": "^2.29.1",
"parse-url": "^5.0.7",
"pino": "^6.13.2",
"pino": "^6.13.4",
"to-snake-case": "^1.0.0",
"uuid": "^8.3.2",
"verify-aws-sns-signature": "^0.0.6",
@@ -545,16 +546,16 @@
}
},
"node_modules/@jambonz/realtimedb-helpers": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.19.tgz",
"integrity": "sha512-wEc7OXogQ5SZ9mgLNxviBNY0WvUKGGztyDzze3oi44edsZp0vNneVHUmdZuDzuDvUMBqsvCa0fvri8LGaxovlw==",
"version": "0.4.26",
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.26.tgz",
"integrity": "sha512-vGNC5IsYj7Qj7mOfgfti0/ZouYs+9GHEX4v7w3JguPW1NqUbvFayPs3xo49di3NJsHV0NnKWx2rMgrZzvWTgTA==",
"dependencies": {
"@google-cloud/text-to-speech": "^3.4.0",
"@jambonz/promisify-redis": "^0.0.6",
"aws-sdk": "^2.1060.0",
"aws-sdk": "^2.1072.0",
"bent": "^7.3.12",
"debug": "^4.3.3",
"microsoft-cognitiveservices-speech-sdk": "^1.19.0",
"microsoft-cognitiveservices-speech-sdk": "^1.20.0",
"redis": "^3.1.2"
}
},
@@ -568,9 +569,9 @@
}
},
"node_modules/@jambonz/time-series": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.5.tgz",
"integrity": "sha512-JDkAshqq9VRdIY7S/Edz9iIyKNoyCoUMfn0IUVyUG4Hf53fmhYRCnFnDTdMFAs6Y4amE39m3968nrZRr+lVIqQ==",
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.6.tgz",
"integrity": "sha512-EFO1ZFUazHLCzDYkAbpke0IfmPRogLkGg+KGWwz3SGpnuiltfohQ3TsJ5KG8Gp9mXqdpkyAioWSdaJxGDquthQ==",
"dependencies": {
"debug": "^4.3.1",
"influx": "^5.8.0"
@@ -907,14 +908,14 @@
}
},
"node_modules/aws-sdk": {
"version": "2.1060.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1060.0.tgz",
"integrity": "sha512-c734/CZiVSsuVnEkx/7dodI8ndgOnxiCTwwlEFlMxdAZfLLJplteFwi6c/J2GZQktvz2ysV/HVtNKcJkasYJzw==",
"version": "2.1073.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1073.0.tgz",
"integrity": "sha512-TtyHDL4ZEs8Zh/DqWY/hv745DTWrIwOyBAvfjBJ45RE9h0TjpWqCIowEtb6gRPAKyPPyfGH4s+rEYu07vNK1Hg==",
"dependencies": {
"buffer": "4.9.2",
"events": "1.1.1",
"ieee754": "1.1.13",
"jmespath": "0.15.0",
"jmespath": "0.16.0",
"querystring": "0.2.0",
"sax": "1.2.1",
"url": "0.10.3",
@@ -1603,9 +1604,9 @@
}
},
"node_modules/drachtio-sip": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.2.tgz",
"integrity": "sha512-BkiRZq3Yq2WVSGY3M7Hv4yX4dIW/o0/4xNMcm26IxT71YIRy07UtbQUHaMI3P2HfPu5zK6RoQW2MHrxPXtz6ZQ==",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.3.tgz",
"integrity": "sha512-sQQ2JdRQ58z+WbkxORlWKZCeinu499tugfsdh7jRBWX6SO4odDevT5JL+42dMlwrL83CZUL6w2Xjgu0uaABoMQ==",
"dependencies": {
"debug": "^4.3.1",
"eslint-plugin-promise": "^5.1.0",
@@ -1613,9 +1614,9 @@
}
},
"node_modules/drachtio-sip/node_modules/eslint-plugin-promise": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz",
"integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz",
"integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==",
"engines": {
"node": "^10.12.0 || >=12.0.0"
},
@@ -1624,15 +1625,15 @@
}
},
"node_modules/drachtio-srf": {
"version": "4.4.59",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.59.tgz",
"integrity": "sha512-hrW9bZ8TZR9JQ3pqI+nyrI1eAzEOwHuvm1lNL1fbmZmRddKJzYdylkgVoyURs/OlT/nANy/M43GrQjcGP4psPw==",
"version": "4.4.61",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.61.tgz",
"integrity": "sha512-HZwKTAR6V7dc84BV50h5xAopkQ1k8wUy04JXDmq2/O+uryANFwaklICidg1oJkIrnYUPWQn/1IfZnqGSv9O2Sw==",
"dependencies": {
"async": "^1.4.2",
"debug": "^3.2.7",
"delegates": "^0.1.0",
"deprecate": "^1.1.1",
"drachtio-sip": "^0.6.2",
"drachtio-sip": "^0.6.3",
"node-noop": "0.0.1",
"only": "0.0.2",
"sdp-transform": "^2.14.1",
@@ -1640,7 +1641,7 @@
"sip-methods": "^0.3.0",
"sip-status": "^0.1.0",
"utils-merge": "1.0.0",
"uuid": "^3.4.0"
"uuid": "^8.3.2"
},
"engines": {
"node": ">= 6.9.3"
@@ -1659,15 +1660,6 @@
"ms": "^2.1.1"
}
},
"node_modules/drachtio-srf/node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
"bin": {
"uuid": "bin/uuid"
}
},
"node_modules/duplexify": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz",
@@ -2259,11 +2251,6 @@
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
"integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
},
"node_modules/fastify-warning": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/fastify-warning/-/fastify-warning-0.2.0.tgz",
"integrity": "sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw=="
},
"node_modules/file-entry-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz",
@@ -2719,6 +2706,14 @@
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz",
"integrity": "sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo="
},
"node_modules/helmet": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-5.0.2.tgz",
"integrity": "sha512-QWlwUZZ8BtlvwYVTSDTBChGf8EOcQ2LkGMnQJxSzD1mUu8CCjXJZq/BXP8eWw4kikRnzlhtYo3lCk0ucmYA3Vg==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/hot-shots": {
"version": "8.5.2",
"resolved": "https://registry.npmjs.org/hot-shots/-/hot-shots-8.5.2.tgz",
@@ -3311,9 +3306,9 @@
}
},
"node_modules/jmespath": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
"integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=",
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
"integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==",
"engines": {
"node": ">= 0.6.0"
}
@@ -3511,9 +3506,9 @@
}
},
"node_modules/microsoft-cognitiveservices-speech-sdk": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/microsoft-cognitiveservices-speech-sdk/-/microsoft-cognitiveservices-speech-sdk-1.19.0.tgz",
"integrity": "sha512-FYyXdJcTLX8Iunnn9XHzTfR+43YdEZn1q89KX6Vzqtaa4hz/LemdC9Zni50VIfkXMNtq2sJFYf5wKXvxm1wQHA==",
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/microsoft-cognitiveservices-speech-sdk/-/microsoft-cognitiveservices-speech-sdk-1.20.0.tgz",
"integrity": "sha512-/KWNHQb36nhIkBr6HClh+T+gHicgmC5JKJhCnQmL6XGAAndLtew0aRbh7cMK10IFNTgozGKiejhrfnwiYH3IBA==",
"hasInstallScript": true,
"dependencies": {
"agent-base": "^6.0.1",
@@ -3525,7 +3520,7 @@
"simple-lru-cache": "0.0.2",
"url-parse": "^1.4.7",
"uuid": "^8.3.0",
"ws": "^7.3.1"
"ws": "^7.5.6"
}
},
"node_modules/microsoft-cognitiveservices-speech-sdk/node_modules/https-proxy-agent": {
@@ -4047,15 +4042,15 @@
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"node_modules/pino": {
"version": "6.13.3",
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.3.tgz",
"integrity": "sha512-tJy6qVgkh9MwNgqX1/oYi3ehfl2Y9H0uHyEEMsBe74KinESIjdMrMQDWpcZPpPicg3VV35d/GLQZmo4QgU2Xkg==",
"version": "6.13.4",
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.4.tgz",
"integrity": "sha512-g4tHSISmQJYUEKEMVdaZ+ZokWwFnTwZL5JPn+lnBVZ1BuBbrSchrXwQINknkM5+Q4fF6U9NjiI8PWwwMDHt9zA==",
"dependencies": {
"fast-redact": "^3.0.0",
"fast-safe-stringify": "^2.0.8",
"fastify-warning": "^0.2.0",
"flatstr": "^1.0.12",
"pino-std-serializers": "^3.1.0",
"process-warning": "^1.0.0",
"quick-format-unescaped": "^4.0.3",
"sonic-boom": "^1.0.2"
},
@@ -4100,6 +4095,11 @@
"node": ">=8"
}
},
"node_modules/process-warning": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz",
"integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="
},
"node_modules/progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@@ -5114,9 +5114,9 @@
}
},
"node_modules/url-parse": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -5343,9 +5343,9 @@
}
},
"node_modules/ws": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
"integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==",
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
"integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==",
"engines": {
"node": ">=8.3.0"
},
@@ -5876,16 +5876,16 @@
}
},
"@jambonz/realtimedb-helpers": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.19.tgz",
"integrity": "sha512-wEc7OXogQ5SZ9mgLNxviBNY0WvUKGGztyDzze3oi44edsZp0vNneVHUmdZuDzuDvUMBqsvCa0fvri8LGaxovlw==",
"version": "0.4.26",
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.26.tgz",
"integrity": "sha512-vGNC5IsYj7Qj7mOfgfti0/ZouYs+9GHEX4v7w3JguPW1NqUbvFayPs3xo49di3NJsHV0NnKWx2rMgrZzvWTgTA==",
"requires": {
"@google-cloud/text-to-speech": "^3.4.0",
"@jambonz/promisify-redis": "^0.0.6",
"aws-sdk": "^2.1060.0",
"aws-sdk": "^2.1072.0",
"bent": "^7.3.12",
"debug": "^4.3.3",
"microsoft-cognitiveservices-speech-sdk": "^1.19.0",
"microsoft-cognitiveservices-speech-sdk": "^1.20.0",
"redis": "^3.1.2"
}
},
@@ -5899,9 +5899,9 @@
}
},
"@jambonz/time-series": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.5.tgz",
"integrity": "sha512-JDkAshqq9VRdIY7S/Edz9iIyKNoyCoUMfn0IUVyUG4Hf53fmhYRCnFnDTdMFAs6Y4amE39m3968nrZRr+lVIqQ==",
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.6.tgz",
"integrity": "sha512-EFO1ZFUazHLCzDYkAbpke0IfmPRogLkGg+KGWwz3SGpnuiltfohQ3TsJ5KG8Gp9mXqdpkyAioWSdaJxGDquthQ==",
"requires": {
"debug": "^4.3.1",
"influx": "^5.8.0"
@@ -6178,14 +6178,14 @@
}
},
"aws-sdk": {
"version": "2.1060.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1060.0.tgz",
"integrity": "sha512-c734/CZiVSsuVnEkx/7dodI8ndgOnxiCTwwlEFlMxdAZfLLJplteFwi6c/J2GZQktvz2ysV/HVtNKcJkasYJzw==",
"version": "2.1073.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1073.0.tgz",
"integrity": "sha512-TtyHDL4ZEs8Zh/DqWY/hv745DTWrIwOyBAvfjBJ45RE9h0TjpWqCIowEtb6gRPAKyPPyfGH4s+rEYu07vNK1Hg==",
"requires": {
"buffer": "4.9.2",
"events": "1.1.1",
"ieee754": "1.1.13",
"jmespath": "0.15.0",
"jmespath": "0.16.0",
"querystring": "0.2.0",
"sax": "1.2.1",
"url": "0.10.3",
@@ -6746,9 +6746,9 @@
}
},
"drachtio-sip": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.2.tgz",
"integrity": "sha512-BkiRZq3Yq2WVSGY3M7Hv4yX4dIW/o0/4xNMcm26IxT71YIRy07UtbQUHaMI3P2HfPu5zK6RoQW2MHrxPXtz6ZQ==",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/drachtio-sip/-/drachtio-sip-0.6.3.tgz",
"integrity": "sha512-sQQ2JdRQ58z+WbkxORlWKZCeinu499tugfsdh7jRBWX6SO4odDevT5JL+42dMlwrL83CZUL6w2Xjgu0uaABoMQ==",
"requires": {
"debug": "^4.3.1",
"eslint-plugin-promise": "^5.1.0",
@@ -6756,23 +6756,23 @@
},
"dependencies": {
"eslint-plugin-promise": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz",
"integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz",
"integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==",
"requires": {}
}
}
},
"drachtio-srf": {
"version": "4.4.59",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.59.tgz",
"integrity": "sha512-hrW9bZ8TZR9JQ3pqI+nyrI1eAzEOwHuvm1lNL1fbmZmRddKJzYdylkgVoyURs/OlT/nANy/M43GrQjcGP4psPw==",
"version": "4.4.61",
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.4.61.tgz",
"integrity": "sha512-HZwKTAR6V7dc84BV50h5xAopkQ1k8wUy04JXDmq2/O+uryANFwaklICidg1oJkIrnYUPWQn/1IfZnqGSv9O2Sw==",
"requires": {
"async": "^1.4.2",
"debug": "^3.2.7",
"delegates": "^0.1.0",
"deprecate": "^1.1.1",
"drachtio-sip": "^0.6.2",
"drachtio-sip": "^0.6.3",
"node-noop": "0.0.1",
"only": "0.0.2",
"sdp-transform": "^2.14.1",
@@ -6780,7 +6780,7 @@
"sip-methods": "^0.3.0",
"sip-status": "^0.1.0",
"utils-merge": "1.0.0",
"uuid": "^3.4.0"
"uuid": "^8.3.2"
},
"dependencies": {
"async": {
@@ -6795,11 +6795,6 @@
"requires": {
"ms": "^2.1.1"
}
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
}
}
},
@@ -7272,11 +7267,6 @@
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
"integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
},
"fastify-warning": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/fastify-warning/-/fastify-warning-0.2.0.tgz",
"integrity": "sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw=="
},
"file-entry-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz",
@@ -7628,6 +7618,11 @@
}
}
},
"helmet": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-5.0.2.tgz",
"integrity": "sha512-QWlwUZZ8BtlvwYVTSDTBChGf8EOcQ2LkGMnQJxSzD1mUu8CCjXJZq/BXP8eWw4kikRnzlhtYo3lCk0ucmYA3Vg=="
},
"hot-shots": {
"version": "8.5.2",
"resolved": "https://registry.npmjs.org/hot-shots/-/hot-shots-8.5.2.tgz",
@@ -8059,9 +8054,9 @@
}
},
"jmespath": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
"integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
"integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw=="
},
"js-tokens": {
"version": "4.0.0",
@@ -8217,9 +8212,9 @@
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"microsoft-cognitiveservices-speech-sdk": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/microsoft-cognitiveservices-speech-sdk/-/microsoft-cognitiveservices-speech-sdk-1.19.0.tgz",
"integrity": "sha512-FYyXdJcTLX8Iunnn9XHzTfR+43YdEZn1q89KX6Vzqtaa4hz/LemdC9Zni50VIfkXMNtq2sJFYf5wKXvxm1wQHA==",
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/microsoft-cognitiveservices-speech-sdk/-/microsoft-cognitiveservices-speech-sdk-1.20.0.tgz",
"integrity": "sha512-/KWNHQb36nhIkBr6HClh+T+gHicgmC5JKJhCnQmL6XGAAndLtew0aRbh7cMK10IFNTgozGKiejhrfnwiYH3IBA==",
"requires": {
"agent-base": "^6.0.1",
"asn1.js-rfc2560": "^5.0.1",
@@ -8230,7 +8225,7 @@
"simple-lru-cache": "0.0.2",
"url-parse": "^1.4.7",
"uuid": "^8.3.0",
"ws": "^7.3.1"
"ws": "^7.5.6"
},
"dependencies": {
"https-proxy-agent": {
@@ -8632,15 +8627,15 @@
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"pino": {
"version": "6.13.3",
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.3.tgz",
"integrity": "sha512-tJy6qVgkh9MwNgqX1/oYi3ehfl2Y9H0uHyEEMsBe74KinESIjdMrMQDWpcZPpPicg3VV35d/GLQZmo4QgU2Xkg==",
"version": "6.13.4",
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.4.tgz",
"integrity": "sha512-g4tHSISmQJYUEKEMVdaZ+ZokWwFnTwZL5JPn+lnBVZ1BuBbrSchrXwQINknkM5+Q4fF6U9NjiI8PWwwMDHt9zA==",
"requires": {
"fast-redact": "^3.0.0",
"fast-safe-stringify": "^2.0.8",
"fastify-warning": "^0.2.0",
"flatstr": "^1.0.12",
"pino-std-serializers": "^3.1.0",
"process-warning": "^1.0.0",
"quick-format-unescaped": "^4.0.3",
"sonic-boom": "^1.0.2"
}
@@ -8673,6 +8668,11 @@
"fromentries": "^1.2.0"
}
},
"process-warning": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz",
"integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@@ -9476,9 +9476,9 @@
}
},
"url-parse": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -9662,9 +9662,9 @@
}
},
"ws": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
"integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==",
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
"integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==",
"requires": {}
},
"xml2js": {

View File

@@ -1,6 +1,6 @@
{
"name": "jambonz-feature-server",
"version": "v0.7.2",
"version": "v0.7.3",
"main": "app.js",
"engines": {
"node": ">= 10.16.0"
@@ -30,21 +30,22 @@
"@jambonz/db-helpers": "^0.6.16",
"@jambonz/http-health-check": "^0.0.1",
"@jambonz/mw-registrar": "^0.2.1",
"@jambonz/realtimedb-helpers": "^0.4.19",
"@jambonz/realtimedb-helpers": "^0.4.26",
"@jambonz/stats-collector": "^0.1.6",
"@jambonz/time-series": "^0.1.5",
"aws-sdk": "^2.1060.0",
"@jambonz/time-series": "^0.1.6",
"aws-sdk": "^2.1073.0",
"bent": "^7.3.12",
"cidr-matcher": "^2.1.1",
"debug": "^4.3.2",
"deepcopy": "^2.1.0",
"drachtio-fsmrf": "^2.0.13",
"drachtio-srf": "^4.4.55",
"drachtio-srf": "^4.4.61",
"express": "^4.17.1",
"helmet": "^5.0.2",
"ip": "^1.1.5",
"moment": "^2.29.1",
"parse-url": "^5.0.7",
"pino": "^6.13.2",
"pino": "^6.13.4",
"to-snake-case": "^1.0.0",
"uuid": "^8.3.2",
"verify-aws-sns-signature": "^0.0.6",