replace bent by native node fetch (#401)

* replace bent by native node fetch

* wip

* wip

* wip
This commit is contained in:
Hoan Luu Huu
2025-04-24 17:50:15 +07:00
committed by GitHub
parent b05b32d73e
commit ffda2398f4
41 changed files with 678 additions and 667 deletions
+41 -36
View File
@@ -1,6 +1,5 @@
const router = require('express').Router(); const router = require('express').Router();
const assert = require('assert'); const assert = require('assert');
const request = require('request');
const {DbErrorBadRequest, DbErrorForbidden, DbErrorUnprocessableRequest} = require('../../utils/errors'); const {DbErrorBadRequest, DbErrorForbidden, DbErrorUnprocessableRequest} = require('../../utils/errors');
const Account = require('../../models/account'); const Account = require('../../models/account');
const Application = require('../../models/application'); const Application = require('../../models/application');
@@ -940,24 +939,25 @@ router.post('/:sid/Calls', async(req, res) => {
await validateCreateCall(logger, sid, req); await validateCreateCall(logger, sid, req);
updateLastUsed(logger, sid, req).catch((err) => {}); updateLastUsed(logger, sid, req).catch((err) => {});
request({ const response = await fetch(serviceUrl, {
url: serviceUrl,
method: 'POST', method: 'POST',
json: true, headers: {
body: Object.assign(req.body, {account_sid: sid}) 'Content-Type': 'application/json'
}, (err, response, body) => { },
if (err) { body: JSON.stringify(Object.assign(req.body, {account_sid: sid}))
logger.error(err, `Error sending createCall POST to ${serviceUrl}`);
return res.sendStatus(500);
}
if (response.statusCode !== 201) {
logger.error({statusCode: response.statusCode}, `Non-success response returned by createCall ${serviceUrl}`);
return res.sendStatus(500);
}
return res.status(201).json(body);
}); });
if (!response.ok) {
logger.error(`Error sending createCall POST to ${serviceUrl}`);
return res.sendStatus(500);
}
if (response.status !== 201) {
logger.error(`Non-success response returned by createCall ${serviceUrl}`);
return res.sendStatus(500);
}
const body = await response.json();
return res.status(201).json(body);
} catch (err) { } catch (err) {
sysError(logger, res, err); sysError(logger, res, err);
} }
@@ -1052,12 +1052,20 @@ const updateCall = async(req, res) => {
if (call) { if (call) {
const url = `${call.serviceUrl}/${process.env.JAMBONES_API_VERSION || 'v1'}/updateCall/${callSid}`; const url = `${call.serviceUrl}/${process.env.JAMBONES_API_VERSION || 'v1'}/updateCall/${callSid}`;
logger.debug({call, url, payload: req.body}, `updateCall: retrieved call info for call sid ${callSid}`); logger.debug({call, url, payload: req.body}, `updateCall: retrieved call info for call sid ${callSid}`);
request({ const response = await fetch(url, {
url: url,
method: 'POST', method: 'POST',
json: true, headers: {
body: req.body 'Content-Type': 'application/json'
}).pipe(res); },
body: JSON.stringify(req.body)
});
if (!response.ok) {
logger.error(`Error sending updateCall POST to ${url}`);
return res.sendStatus(500);
}
const body = await response.json();
return res.status(200).json(body);
} }
else { else {
logger.debug(`updateCall: call not found for call sid ${callSid}`); logger.debug(`updateCall: call not found for call sid ${callSid}`);
@@ -1100,22 +1108,19 @@ router.post('/:sid/Messages', async(req, res) => {
}; };
logger.debug({payload}, `sending createMessage API request to to ${serviceUrl}`); logger.debug({payload}, `sending createMessage API request to to ${serviceUrl}`);
updateLastUsed(logger, account_sid, req).catch(() => {}); updateLastUsed(logger, account_sid, req).catch(() => {});
request({ const response = await fetch(serviceUrl, {
url: serviceUrl,
method: 'POST', method: 'POST',
json: true, headers: {
body: payload 'Content-Type': 'application/json'
}, (err, response, body) => { },
if (err) { body: JSON.stringify(payload)
logger.error(err, `Error sending createMessage POST to ${serviceUrl}`);
return res.sendStatus(500);
}
if (response.statusCode !== 200) {
logger.error({statusCode: response.statusCode}, `Non-success response returned by createMessage ${serviceUrl}`);
return body ? res.status(response.statusCode).json(body) : res.sendStatus(response.statusCode);
}
res.status(201).json(body);
}); });
if (!response.ok) {
logger.error(`Error sending createMessage POST to ${serviceUrl}`);
return res.sendStatus(500);
}
const body = await response.json();
return res.status(response.status).json(body);
} catch (err) { } catch (err) {
sysError(logger, res, err); sysError(logger, res, err);
} }
+11 -18
View File
@@ -1,5 +1,4 @@
const router = require('express').Router(); const router = require('express').Router();
const request = require('request');
const getProvider = require('../../utils/sms-provider'); const getProvider = require('../../utils/sms-provider');
const { v4: uuidv4 } = require('uuid'); const { v4: uuidv4 } = require('uuid');
const sysError = require('../error'); const sysError = require('../error');
@@ -122,25 +121,19 @@ router.post('/:provider', async(req, res) => {
logger.info({payload, url: serviceUrl}, `sending incomingSms API request to FS at ${serviceUrl}`); logger.info({payload, url: serviceUrl}, `sending incomingSms API request to FS at ${serviceUrl}`);
request({ const response = await fetch(serviceUrl, {
url: serviceUrl,
method: 'POST', method: 'POST',
json: true, body: JSON.stringify(payload),
body: payload, headers: {'Content-Type': 'application/json'},
},
async(err, response, body) => {
if (err) {
logger.error(err, `Error sending incomingSms POST to ${serviceUrl}`);
return res.sendStatus(500);
}
if (200 === response.statusCode) {
// success
logger.info({body}, 'sending response to provider for incomingSMS');
return doSendResponse(res, respondFn, body);
}
logger.error({statusCode: response.statusCode}, `Non-success response returned by incomingSms ${serviceUrl}`);
return res.sendStatus(500);
}); });
if (!response.ok) {
logger.error({response}, `Error sending incomingSms POST to ${serviceUrl}`);
return res.sendStatus(500);
}
const body = await response.json();
logger.info({body}, 'sending response to provider for incomingSMS');
return doSendResponse(res, respondFn, body);
} catch (err) { } catch (err) {
sysError(logger, res, err); sysError(logger, res, err);
} }
+32 -24
View File
@@ -1,5 +1,4 @@
const { v4: uuid, validate } = require('uuid'); const { v4: uuid, validate } = require('uuid');
const bent = require('bent');
const Account = require('../../models/account'); const Account = require('../../models/account');
const {promisePool} = require('../../db'); const {promisePool} = require('../../db');
const {cancelSubscription, detachPaymentMethod} = require('../../utils/stripe-utils'); const {cancelSubscription, detachPaymentMethod} = require('../../utils/stripe-utils');
@@ -11,8 +10,6 @@ values (?, ?)`;
const replaceOldSubscriptionSql = `UPDATE account_subscriptions const replaceOldSubscriptionSql = `UPDATE account_subscriptions
SET effective_end_date = CURRENT_TIMESTAMP, change_reason = ? SET effective_end_date = CURRENT_TIMESTAMP, change_reason = ?
WHERE account_subscription_sid = ?`; WHERE account_subscription_sid = ?`;
//const request = require('request');
//require('request-debug')(request);
const setupFreeTrial = async(logger, account_sid, isReturningUser) => { const setupFreeTrial = async(logger, account_sid, isReturningUser) => {
const sid = uuid(); const sid = uuid();
@@ -370,35 +367,44 @@ const checkLimits = async(req, res, next) => {
}; };
const getSubspaceJWT = async(id, secret) => { const getSubspaceJWT = async(id, secret) => {
const postJwt = bent('https://id.subspace.com', 'POST', 'json', 200); const response = await fetch('https://id.subspace.com/oauth/token', {
const jwt = await postJwt('/oauth/token', method: 'POST',
{ headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
client_id: id, client_id: id,
client_secret: secret, client_secret: secret,
audience: 'https://api.subspace.com/', audience: 'https://api.subspace.com/',
grant_type: 'client_credentials', grant_type: 'client_credentials',
} })
); });
if (!response.ok) {
throw new Error(`Failed to get JWT: ${response.status} ${response.statusText}`);
}
const jwt = await response.json();
return jwt.access_token; return jwt.access_token;
}; };
const enableSubspace = async(opts) => { const enableSubspace = async(opts) => {
const {subspace_client_id, subspace_client_secret, destination} = opts; const {subspace_client_id, subspace_client_secret, destination} = opts;
const accessToken = await getSubspaceJWT(subspace_client_id, subspace_client_secret); const accessToken = await getSubspaceJWT(subspace_client_id, subspace_client_secret);
const postTeleport = bent('https://api.subspace.com', 'POST', 'json', 200); const response = await fetch('https://api.subspace.com/v1/sipteleport', {
method: 'POST',
const teleport = await postTeleport('/v1/sipteleport', headers: {
{ 'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`
},
body: JSON.stringify({
name: 'Jambonz', name: 'Jambonz',
destination, destination,
status: 'ENABLED' status: 'ENABLED'
}, })
{ });
'Content-Type': 'application/json', if (!response.ok) {
Authorization: `Bearer ${accessToken}` throw new Error(`Failed to enable teleport: ${response.status} ${response.statusText}`);
} }
); const teleport = await response.json();
return teleport; return teleport;
}; };
@@ -406,13 +412,15 @@ const disableSubspace = async(opts) => {
const {subspace_client_id, subspace_client_secret, subspace_sip_teleport_id} = opts; const {subspace_client_id, subspace_client_secret, subspace_sip_teleport_id} = opts;
const accessToken = await getSubspaceJWT(subspace_client_id, subspace_client_secret); const accessToken = await getSubspaceJWT(subspace_client_id, subspace_client_secret);
const relativeUrl = `/v1/sipteleport/${subspace_sip_teleport_id}`; const relativeUrl = `/v1/sipteleport/${subspace_sip_teleport_id}`;
const deleteTeleport = bent('https://api.subspace.com', 'DELETE', 'json', 200); const response = await fetch(`https://api.subspace.com${relativeUrl}`, {
await deleteTeleport(relativeUrl, {}, method: 'DELETE',
{ headers: {
Authorization: `Bearer ${accessToken}` Authorization: `Bearer ${accessToken}`
} }
); });
return; if (!response.ok) {
throw new Error(`Failed to delete teleport: ${response.status} ${response.statusText}`);
}
}; };
const validatePasswordSettings = async(password) => { const validatePasswordSettings = async(password) => {
+30 -27
View File
@@ -1,6 +1,5 @@
if (!process.env.JAMBONES_HOSTING) return; if (!process.env.JAMBONES_HOSTING) return;
const bent = require('bent');
const crypto = require('crypto'); const crypto = require('crypto');
const assert = require('assert'); const assert = require('assert');
const domains = new Map(); const domains = new Map();
@@ -26,17 +25,20 @@ const createAuthHeaders = () => {
const getDnsDomainId = async(logger, name) => { const getDnsDomainId = async(logger, name) => {
checkAsserts(); checkAsserts();
const headers = createAuthHeaders(); const headers = createAuthHeaders();
const get = bent(process.env.DME_BASE_URL, 'GET', 'json', headers); const response = await fetch(`${process.env.DME_BASE_URL}/dns/managed`, {
try { method: 'GET',
const result = await get('/dns/managed'); headers
debug(result, 'getDnsDomainId: all domains'); });
if (Array.isArray(result.data)) { if (!response.ok) {
const domain = result.data.find((o) => o.name === name); logger.error({response}, 'Error retrieving domains');
if (domain) return domain.id; return;
debug(`getDnsDomainId: failed to find domain ${name}`); }
} const result = await response.json();
} catch (err) { debug(result, 'getDnsDomainId: all domains');
logger.error({err}, 'Error retrieving domains'); if (Array.isArray(result.data)) {
const domain = result.data.find((o) => o.name === name);
if (domain) return domain.id;
debug(`getDnsDomainId: failed to find domain ${name}`);
} }
}; };
@@ -80,21 +82,20 @@ const createDnsRecords = async(logger, domain, name, value, ttl = 3600) => {
]; ];
const headers = createAuthHeaders(); const headers = createAuthHeaders();
const records = [...a_records, ...srv_records]; const records = [...a_records, ...srv_records];
const post = bent(process.env.DME_BASE_URL, 'POST', 201, 400, headers); const response = await fetch(`${process.env.DME_BASE_URL}/dns/managed/${domainId}/records/createMulti`, {
logger.debug({records}, 'Attemting to create dns records'); method: 'POST',
const res = await post(`/dns/managed/${domainId}/records/createMulti`, headers,
[...a_records, ...srv_records]); body: JSON.stringify(records)
});
if (201 === res.statusCode) { if (!response.ok) {
const str = await res.text(); logger.error({response}, 'Error creating records');
return JSON.parse(str); return;
} }
let body; const result = await response.json();
try { logger.debug({result}, 'createDnsRecords: created records');
body = await res.json(); if (201 === response.status) {
} catch (err) { return result;
} }
logger.error({headers: res.headers, body}, `Error creating records, status ${res.statusCode}`);
} catch (err) { } catch (err) {
logger.error({err}, 'Error retrieving domains'); logger.error({err}, 'Error retrieving domains');
} }
@@ -103,7 +104,6 @@ const createDnsRecords = async(logger, domain, name, value, ttl = 3600) => {
const deleteDnsRecords = async(logger, domain, recIds) => { const deleteDnsRecords = async(logger, domain, recIds) => {
checkAsserts(); checkAsserts();
const headers = createAuthHeaders(); const headers = createAuthHeaders();
const del = bent(process.env.DME_BASE_URL, 'DELETE', 200, headers);
try { try {
if (!domains.has(domain)) { if (!domains.has(domain)) {
const domainId = await getDnsDomainId(logger, domain); const domainId = await getDnsDomainId(logger, domain);
@@ -112,7 +112,10 @@ const deleteDnsRecords = async(logger, domain, recIds) => {
} }
const domainId = domains.get(domain); const domainId = domains.get(domain);
const url = `/dns/managed/${domainId}/records?${recIds.map((r) => `ids=${r}`).join('&')}`; const url = `/dns/managed/${domainId}/records?${recIds.map((r) => `ids=${r}`).join('&')}`;
await del(url); await fetch(`${process.env.DME_BASE_URL}${url}`, {
method: 'DELETE',
headers
});
return true; return true;
} catch (err) { } catch (err) {
console.error(err); console.error(err);
+14 -14
View File
@@ -1,7 +1,6 @@
const formData = require('form-data'); const formData = require('form-data');
const Mailgun = require('mailgun.js'); const Mailgun = require('mailgun.js');
const mailgun = new Mailgun(formData); const mailgun = new Mailgun(formData);
const bent = require('bent');
const validateEmail = (email) => { const validateEmail = (email) => {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
@@ -19,8 +18,9 @@ const emailSimpleText = async(logger, to, subject, text) => {
}; };
const sendEmailByCustomVendor = async(logger, from, to, subject, text) => { const sendEmailByCustomVendor = async(logger, from, to, subject, text) => {
try { const response = await fetch(process.env.CUSTOM_EMAIL_VENDOR_URL, {
const post = bent('POST', { method: 'POST',
headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...((process.env.CUSTOM_EMAIL_VENDOR_USERNAME && process.env.CUSTOM_EMAIL_VENDOR_PASSWORD) && ...((process.env.CUSTOM_EMAIL_VENDOR_USERNAME && process.env.CUSTOM_EMAIL_VENDOR_PASSWORD) &&
({ ({
@@ -28,22 +28,22 @@ const sendEmailByCustomVendor = async(logger, from, to, subject, text) => {
`${process.env.CUSTOM_EMAIL_VENDOR_USERNAME}:${process.env.CUSTOM_EMAIL_VENDOR_PASSWORD}` `${process.env.CUSTOM_EMAIL_VENDOR_USERNAME}:${process.env.CUSTOM_EMAIL_VENDOR_PASSWORD}`
).toString('base64')}` ).toString('base64')}`
})) }))
}); },
body: JSON.stringify({
const res = await post(process.env.CUSTOM_EMAIL_VENDOR_URL, {
from, from,
to, to,
subject, subject,
text text
}); })
logger.debug({ });
res if (!response.ok) {
}, 'sent email to custom vendor.'); logger.error({response}, 'Error sending email to custom vendor');
} catch (err) { return;
logger.info({
err
}, 'Error sending email From Custom email vendor');
} }
const res = await response.json();
logger.debug({
res
}, 'sent email to custom vendor.');
}; };
const sendEmailByMailgun = async(logger, from, to, subject, text) => { const sendEmailByMailgun = async(logger, from, to, subject, text) => {
+87 -58
View File
@@ -1,15 +1,11 @@
const debug = require('debug')('jambonz:api-server'); const debug = require('debug')('jambonz:api-server');
const bent = require('bent');
const basicAuth = (apiKey) => { const basicAuth = (apiKey) => {
const header = `Bearer ${apiKey}`; const header = `Bearer ${apiKey}`;
return {Authorization: header}; return {Authorization: header};
}; };
const postJSON = bent(process.env.HOMER_BASE_URL || 'http://127.0.0.1', 'POST', 'json', 200, 201);
const postPcap = bent(process.env.HOMER_BASE_URL || 'http://127.0.0.1', 'POST', 200, {
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*',
});
const SEVEN_DAYS_IN_MS = (1000 * 3600 * 24 * 7); const SEVEN_DAYS_IN_MS = (1000 * 3600 * 24 * 7);
const HOMER_BASE_URL = process.env.HOMER_BASE_URL || 'http://127.0.0.1';
const getHomerApiKey = async(logger) => { const getHomerApiKey = async(logger) => {
if (!process.env.HOMER_BASE_URL || !process.env.HOMER_USERNAME || !process.env.HOMER_PASSWORD) { if (!process.env.HOMER_BASE_URL || !process.env.HOMER_USERNAME || !process.env.HOMER_PASSWORD) {
@@ -17,11 +13,21 @@ const getHomerApiKey = async(logger) => {
} }
try { try {
const obj = await postJSON('/api/v3/auth', { const response = await fetch(`${HOMER_BASE_URL}/api/v3/auth`, {
username: process.env.HOMER_USERNAME, method: 'POST',
password: process.env.HOMER_PASSWORD headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: process.env.HOMER_USERNAME,
password: process.env.HOMER_PASSWORD
})
}); });
debug(obj); if (!response.ok) {
logger.error({response}, 'Error retrieving apikey');
return;
}
const obj = await response.json();
logger.debug({obj}, `getHomerApiKey for user ${process.env.HOMER_USERNAME}`); logger.debug({obj}, `getHomerApiKey for user ${process.env.HOMER_USERNAME}`);
return obj.token; return obj.token;
} catch (err) { } catch (err) {
@@ -36,28 +42,40 @@ const getHomerSipTrace = async(logger, apiKey, callId) => {
} }
try { try {
const now = Date.now(); const now = Date.now();
const obj = await postJSON('/api/v3/call/transaction', { const response = await fetch(`${HOMER_BASE_URL}/api/v3/call/transaction`, {
param: { method: 'POST',
transaction: { headers: {
call: true, 'Content-Type': 'application/json',
registration: true, ...basicAuth(apiKey)
rest: false
},
orlogic: true,
search: {
'1_call': {
callid: [callId]
},
'1_registration': {
callid: [callId]
}
},
}, },
timestamp: { body: JSON.stringify({
from: now - SEVEN_DAYS_IN_MS, param: {
to: now transaction: {
} call: true,
}, basicAuth(apiKey)); registration: true,
rest: false
},
orlogic: true,
search: {
'1_call': {
callid: [callId]
},
'1_registration': {
callid: [callId]
}
},
},
timestamp: {
from: now - SEVEN_DAYS_IN_MS,
to: now
}
})
});
if (!response.ok) {
logger.error({response}, 'Error retrieving messages');
return;
}
const obj = await response.json();
return obj; return obj;
} catch (err) { } catch (err) {
logger.info({err}, `getHomerSipTrace: Error retrieving messages for callid ${callId}`); logger.info({err}, `getHomerSipTrace: Error retrieving messages for callid ${callId}`);
@@ -70,34 +88,45 @@ const getHomerPcap = async(logger, apiKey, callIds, method) => {
} }
try { try {
const now = Date.now(); const now = Date.now();
const stream = await postPcap('/api/v3/export/call/messages/pcap', { const response = await fetch(`${HOMER_BASE_URL}/api/v3/export/call/messages/pcap`, {
param: { method: 'POST',
transaction: { headers: {
call: method === 'invite', 'Content-Type': 'application/json',
registration: method === 'register', ...basicAuth(apiKey)
rest: false
},
orlogic: true,
search: {
...(method === 'invite' && {
'1_call': {
callid: callIds
}
})
,
...(method === 'register' && {
'1_registration': {
callid: callIds
}
})
},
}, },
timestamp: { body: JSON.stringify({
from: now - SEVEN_DAYS_IN_MS, param: {
to: now transaction: {
} call: method === 'invite',
}, basicAuth(apiKey)); registration: method === 'register',
return stream; rest: false
},
orlogic: true,
search: {
...(method === 'invite' && {
'1_call': {
callid: callIds
}
})
,
...(method === 'register' && {
'1_registration': {
callid: callIds
}
})
},
},
timestamp: {
from: now - SEVEN_DAYS_IN_MS,
to: now
}
})
});
if (!response.ok) {
logger.error({response}, 'Error retrieving messages');
return;
}
return response.body;
} catch (err) { } catch (err) {
logger.info({err}, `getHomerPcap: Error retrieving messages for callid ${callIds}`); logger.info({err}, `getHomerPcap: Error retrieving messages for callid ${callIds}`);
} }
+7 -3
View File
@@ -1,5 +1,4 @@
const bent = require('bent'); const JAEGER_BASE_URL = process.env.JAEGER_BASE_URL || 'http://127.0.0.1';
const getJSON = bent(process.env.JAEGER_BASE_URL || 'http://127.0.0.1', 'GET', 'json', 200);
const getJaegerTrace = async(logger, traceId) => { const getJaegerTrace = async(logger, traceId) => {
if (!process.env.JAEGER_BASE_URL) { if (!process.env.JAEGER_BASE_URL) {
@@ -7,7 +6,12 @@ const getJaegerTrace = async(logger, traceId) => {
return null; return null;
} }
try { try {
return await getJSON(`/api/v3/traces/${traceId}`); const response = await fetch(`${JAEGER_BASE_URL}/api/traces/${traceId}`);
if (!response.ok) {
logger.error({response}, 'Error retrieving spans');
return;
}
return await response.json();
} catch (err) { } catch (err) {
const url = `${process.env.JAEGER_BASE_URL}/api/traces/${traceId}`; const url = `${process.env.JAEGER_BASE_URL}/api/traces/${traceId}`;
logger.error({err, traceId}, `getJaegerTrace: Error retrieving spans from ${url}`); logger.error({err, traceId}, `getJaegerTrace: Error retrieving spans from ${url}`);
+71 -29
View File
@@ -1,7 +1,4 @@
const assert = require('assert'); const assert = require('assert');
const bent = require('bent');
const postJSON = bent('POST', 'json', 200);
const getJSON = bent('GET', 'json', 200);
const {emailSimpleText} = require('./email-utils'); const {emailSimpleText} = require('./email-utils');
const {DbErrorForbidden} = require('../utils/errors'); const {DbErrorForbidden} = require('../utils/errors');
@@ -10,13 +7,26 @@ const doGithubAuth = async(logger, payload) => {
try { try {
/* exchange the code for an access token */ /* exchange the code for an access token */
const obj = await postJSON('https://github.com/login/oauth/access_token', { const response = await fetch('https://github.com/login/oauth/access_token', {
client_id: payload.oauth2_client_id, method: 'POST',
client_secret: process.env.GITHUB_CLIENT_SECRET, headers: {
code: payload.oauth2_code, 'Content-Type': 'application/json',
state: payload.oauth2_state, Accept: 'application/json'
redirect_uri: payload.oauth2_redirect_uri },
body: JSON.stringify({
client_id: payload.oauth2_client_id,
client_secret: process.env.GITHUB_CLIENT_SECRET,
code: payload.oauth2_code,
state: payload.oauth2_state,
redirect_uri: payload.oauth2_redirect_uri
})
}); });
if (!response.ok) {
logger.error({response}, 'Error retrieving access_token from github');
throw new DbErrorForbidden(await response.text());
}
const obj = await response.json();
if (!obj.access_token) { if (!obj.access_token) {
logger.error({obj}, 'Error retrieving access_token from github'); logger.error({obj}, 'Error retrieving access_token from github');
if (obj.error === 'bad_verification_code') throw new Error('bad verification code'); if (obj.error === 'bad_verification_code') throw new Error('bad verification code');
@@ -25,17 +35,31 @@ const doGithubAuth = async(logger, payload) => {
logger.debug({obj}, 'got response from github for access_token'); logger.debug({obj}, 'got response from github for access_token');
/* use the access token to get basic public info as well as primary email */ /* use the access token to get basic public info as well as primary email */
const userDetails = await getJSON('https://api.github.com/user', null, { const userResponse = await fetch('https://api.github.com/user', {
Authorization: `Bearer ${obj.access_token}`, headers: {
Accept: 'application/json', Authorization: `Bearer ${obj.access_token}`,
'User-Agent': 'jambonz 1.0' Accept: 'application/json',
'User-Agent': 'jambonz 1.0'
}
}); });
if (!userResponse.ok) {
logger.error({userResponse}, 'Error retrieving user details from github');
throw new DbErrorForbidden(await userResponse.text());
}
const userDetails = await userResponse.json();
const emails = await getJSON('https://api.github.com/user/emails', null, { const emailsResponse = await fetch('https://api.github.com/user/emails', {
Authorization: `Bearer ${obj.access_token}`, headers: {
Accept: 'application/json', Authorization: `Bearer ${obj.access_token}`,
'User-Agent': 'jambonz 1.0' Accept: 'application/json',
'User-Agent': 'jambonz 1.0'
}
}); });
if (!emailsResponse.ok) {
logger.error({emailsResponse}, 'Error retrieving emails from github');
throw new DbErrorForbidden(await emailsResponse.text());
}
const emails = await emailsResponse.json();
const primary = emails.find((e) => e.primary); const primary = emails.find((e) => e.primary);
if (primary) Object.assign(userDetails, { if (primary) Object.assign(userDetails, {
email: primary.email, email: primary.email,
@@ -55,14 +79,26 @@ const doGoogleAuth = async(logger, payload) => {
try { try {
/* exchange the code for an access token */ /* exchange the code for an access token */
const obj = await postJSON('https://oauth2.googleapis.com/token', { const response = await fetch('https://oauth2.googleapis.com/token', {
client_id: payload.oauth2_client_id, method: 'POST',
client_secret: process.env.GOOGLE_OAUTH_CLIENT_SECRET, headers: {
code: payload.oauth2_code, 'Content-Type': 'application/json',
state: payload.oauth2_state, Accept: 'application/json'
redirect_uri: payload.oauth2_redirect_uri, },
grant_type: 'authorization_code' body: JSON.stringify({
client_id: payload.oauth2_client_id,
client_secret: process.env.GOOGLE_OAUTH_CLIENT_SECRET,
code: payload.oauth2_code,
state: payload.oauth2_state,
redirect_uri: payload.oauth2_redirect_uri,
grant_type: 'authorization_code'
})
}); });
if (!response.ok) {
logger.error({response}, 'Error retrieving access_token from google');
throw new DbErrorForbidden(await response.text());
}
const obj = await response.json();
if (!obj.access_token) { if (!obj.access_token) {
logger.error({obj}, 'Error retrieving access_token from github'); logger.error({obj}, 'Error retrieving access_token from github');
if (obj.error === 'bad_verification_code') throw new Error('bad verification code'); if (obj.error === 'bad_verification_code') throw new Error('bad verification code');
@@ -71,12 +107,18 @@ const doGoogleAuth = async(logger, payload) => {
logger.debug({obj}, 'got response from google for access_token'); logger.debug({obj}, 'got response from google for access_token');
/* use the access token to get basic public info as well as primary email */ /* use the access token to get basic public info as well as primary email */
const userDetails = await getJSON('https://www.googleapis.com/oauth2/v2/userinfo', null, { const userDetailsResponse = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {
Authorization: `Bearer ${obj.access_token}`, headers: {
Accept: 'application/json', Authorization: `Bearer ${obj.access_token}`,
'User-Agent': 'jambonz 1.0' Accept: 'application/json',
'User-Agent': 'jambonz 1.0'
}
}); });
if (!userDetailsResponse.ok) {
logger.error({userDetailsResponse}, 'Error retrieving user details from google');
throw new DbErrorForbidden(await userDetailsResponse.text());
}
const userDetails = await userDetailsResponse.json();
logger.info({userDetails}, 'retrieved user details from google'); logger.info({userDetails}, 'retrieved user details from google');
return userDetails; return userDetails;
} catch (err) { } catch (err) {
+100 -65
View File
@@ -3,7 +3,6 @@ const { TranscribeClient, ListVocabulariesCommand } = require('@aws-sdk/client-t
const { Deepgram } = require('@deepgram/sdk'); const { Deepgram } = require('@deepgram/sdk');
const sdk = require('microsoft-cognitiveservices-speech-sdk'); const sdk = require('microsoft-cognitiveservices-speech-sdk');
const { SpeechClient } = require('@soniox/soniox-node'); const { SpeechClient } = require('@soniox/soniox-node');
const bent = require('bent');
const fs = require('fs'); const fs = require('fs');
const { AssemblyAI } = require('assemblyai'); const { AssemblyAI } = require('assemblyai');
const {decrypt, obscureKey} = require('./encrypt-decrypt'); const {decrypt, obscureKey} = require('./encrypt-decrypt');
@@ -288,44 +287,46 @@ const testMicrosoftTts = async(logger, synthAudio, credentials) => {
const testWellSaidTts = async(logger, credentials) => { const testWellSaidTts = async(logger, credentials) => {
const {api_key} = credentials; const {api_key} = credentials;
try { const response = await fetch('https://api.wellsaidlabs.com/v1/tts/stream', {
const post = bent('https://api.wellsaidlabs.com', 'POST', 'buffer', { method: 'POST',
headers: {
'X-Api-Key': api_key, 'X-Api-Key': api_key,
'Accept': 'audio/mpeg', 'Accept': 'audio/mpeg',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}); },
const mp3 = await post('/v1/tts/stream', { body: JSON.stringify({
text: 'Hello, world', text: 'Hello, world',
speaker_id: '3' speaker_id: '3'
}); })
return mp3; });
} catch (err) { if (!response.ok) {
logger.info({err}, 'testWellSaidTts returned error'); throw new Error('failed to synthesize speech');
throw err;
} }
return response.body;
}; };
const testElevenlabs = async(logger, credentials) => { const testElevenlabs = async(logger, credentials) => {
const {api_key, model_id} = credentials; const {api_key, model_id} = credentials;
try { const response = await fetch('https://api.elevenlabs.io/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM', {
const post = bent('https://api.elevenlabs.io', 'POST', 'buffer', { method: 'POST',
headers: {
'xi-api-key': api_key, 'xi-api-key': api_key,
'Accept': 'audio/mpeg', 'Accept': 'audio/mpeg',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}); },
const mp3 = await post('/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM', { body: JSON.stringify({
text: 'Hello', text: 'Hello',
model_id, model_id,
voice_settings: { voice_settings: {
stability: 0.5, stability: 0.5,
similarity_boost: 0.5 similarity_boost: 0.5
} }
}); })
return mp3; });
} catch (err) { if (!response.ok) {
logger.info({err}, 'synthEvenlabs returned error'); throw new Error('failed to synthesize speech');
throw err;
} }
return response.body;
}; };
const testPlayHT = async(logger, synthAudio, credentials) => { const testPlayHT = async(logger, synthAudio, credentials) => {
@@ -466,18 +467,18 @@ const testVerbioTts = async(logger, synthAudio, credentials) => {
}; };
const testVerbioStt = async(logger, getVerbioAccessToken, credentials) => { const testVerbioStt = async(logger, getVerbioAccessToken, credentials) => {
const token = await getVerbioAccessToken(credentials); const token = await getVerbioAccessToken(credentials);
try { const response = await fetch('https://us.rest.speechcenter.verbio.com/api/v1/recognize?language=en-US&version=V1', {
const post = bent('https://us.rest.speechcenter.verbio.com', 'POST', 'json', { method: 'POST',
headers: {
'Authorization': `Bearer ${token.access_token}`, 'Authorization': `Bearer ${token.access_token}`,
'User-Agent': 'jambonz', 'User-Agent': 'jambonz',
'Content-Type': 'audio/wav' 'Content-Type': 'audio/wav'
}); },
const json = await post('/api/v1/recognize?language=en-US&version=V1', body: fs.readFileSync(`${__dirname}/../../data/test_audio.wav`)
fs.readFileSync(`${__dirname}/../../data/test_audio.wav`)); });
logger.debug({json}, 'successfully speech to text from verbio'); if (!response.ok) {
} catch (err) { logger.error({Error: await response.text()}, 'Error transcribing speech');
logger.info({err}, 'testWellSaidTts returned error'); throw new Error('failed to transcribe speech');
throw err;
} }
}; };
@@ -546,16 +547,17 @@ const testAssemblyStt = async(logger, credentials) => {
const testVoxistStt = async(logger, credentials) => { const testVoxistStt = async(logger, credentials) => {
const {api_key} = credentials; const {api_key} = credentials;
try { const response = await fetch('https://api-asr.voxist.com/clients', {
const get = bent('https://api-asr.voxist.com', 'GET', 'json', { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'x-lvl-key': api_key 'x-lvl-key': api_key
}); }
await get('/clients'); });
} catch (err) { if (!response.ok) {
logger.info({err}, 'failed to get clients from Voxist'); logger.error({response}, 'Error retrieving clients');
throw err; throw new Error('failed to get clients');
} }
return response.json();
}; };
const getSpeechCredential = (credential, logger) => { const getSpeechCredential = (credential, logger) => {
@@ -812,17 +814,18 @@ async function getLanguagesVoicesForAws(credential, getTtsVoices, logger) {
async function getLanguagesVoicesForMicrosoft(credential, getTtsVoices, logger) { async function getLanguagesVoicesForMicrosoft(credential, getTtsVoices, logger) {
if (credential) { if (credential) {
try { const response = await fetch('https://westus.tts.speech.microsoft.com/cognitiveservices/voices/list', {
const get = bent('https://westus.tts.speech.microsoft.com', 'GET', 'json', { headers: {
'Ocp-Apim-Subscription-Key' : credential.api_key 'Ocp-Apim-Subscription-Key': credential.api_key
}); }
});
const voices = await get('/cognitiveservices/voices/list'); if (!response.ok) {
const tts = parseMicrosoftLanguagesVoices(voices); logger.error({response}, 'Error fetching Microsoft voices');
return tranform(tts, SttMicrosoftLanguagesVoices); throw new Error('failed to list voices');
} catch (err) {
logger.info('Error while fetching Microsoft languages, voices, return predefined values', err);
} }
const voices = await response.json();
const tts = parseMicrosoftLanguagesVoices(voices);
return tranform(tts, SttMicrosoftLanguagesVoices);
} }
return tranform(TtsMicrosoftLanguagesVoices, SttMicrosoftLanguagesVoices); return tranform(TtsMicrosoftLanguagesVoices, SttMicrosoftLanguagesVoices);
} }
@@ -885,14 +888,27 @@ async function getLanguagesVoicesForSpeechmatics(credential) {
async function getLanguagesVoicesForElevenlabs(credential) { async function getLanguagesVoicesForElevenlabs(credential) {
if (credential) { if (credential) {
const get = bent('https://api.elevenlabs.io', 'GET', 'json', { const headers = {
'xi-api-key' : credential.api_key 'xi-api-key': credential.api_key
};
const getModelPromise = fetch('https://api.elevenlabs.io/v1/models', {
headers
}); });
const getVoicePromise = fetch('https://api.elevenlabs.io/v1/voices', {
headers
});
const [langResp, voiceResp] = await Promise.all([getModelPromise, getVoicePromise]);
const [langResp, voiceResp] = await Promise.all([get('/v1/models'), get('/v1/voices')]); if (!langResp.ok || !voiceResp.ok) {
throw new Error('failed to list voices');
}
const model = langResp.find((m) => m.model_id === credential.model_id); const langs = await langResp.json();
const models = langResp.map((m) => { const voicesR = await voiceResp.json();
const model = langs.find((m) => m.model_id === credential.model_id);
const models = langs.map((m) => {
return { return {
value: m.model_id, value: m.model_id,
name: m.name name: m.name
@@ -908,7 +924,7 @@ async function getLanguagesVoicesForElevenlabs(credential) {
if (languages && languages.length > 0) { if (languages && languages.length > 0) {
// using if condition to avoid \n character in name // using if condition to avoid \n character in name
const voices = voiceResp ? voiceResp.voices.map((v) => { const voices = voicesR ? voicesR.voices.map((v) => {
let name = `${v.name}${v.category !== 'premade' ? ` (${v.category.trim()})` : ''} - (`; let name = `${v.name}${v.category !== 'premade' ? ` (${v.category.trim()})` : ''} - (`;
if (v.labels.accent) name += `${v.labels.accent}, `; if (v.labels.accent) name += `${v.labels.accent}, `;
if (v.labels.description) name += `${v.labels.description}, `; if (v.labels.description) name += `${v.labels.description}, `;
@@ -946,18 +962,28 @@ const concat = (a) => {
const fetchLayHTVoices = async(credential) => { const fetchLayHTVoices = async(credential) => {
if (credential) { if (credential) {
const get = bent('https://api.play.ht', 'GET', 'json', { const headers = {
'AUTHORIZATION' : credential.api_key, 'AUTHORIZATION': credential.api_key,
'X-USER-ID': credential.user_id, 'X-USER-ID': credential.user_id,
'Accept': 'application/json' 'Accept': 'application/json'
};
const response = await fetch('https://api.play.ht/api/v2/voices', {
headers
}); });
if (!response.ok) {
const voices = await get('/api/v2/voices'); throw new Error('failed to list voices');
}
const voices = await response.json();
let clone_voices = []; let clone_voices = [];
try { try {
// try if the account has permission to cloned voice // try if the account has permission to cloned voice
//otherwise ignore this. //otherwise ignore this.
clone_voices = await get('/api/v2/cloned-voices'); const clone_voices_Response = await fetch('https://api.play.ht/api/v2/cloned-voices', {
headers
});
if (clone_voices_Response.ok) {
clone_voices = await clone_voices_Response.json();
}
} catch {} } catch {}
return [clone_voices, voices]; return [clone_voices, voices];
} }
@@ -1032,10 +1058,15 @@ async function getLanguagesVoicesForPlayHT(credential) {
async function getLanguagesVoicesForRimelabs(credential) { async function getLanguagesVoicesForRimelabs(credential) {
const model_id = credential ? credential.model_id : null; const model_id = credential ? credential.model_id : null;
const get = bent('https://users.rime.ai', 'GET', 'json', { const response = await fetch('https://users.rime.ai//data/voices/all-v2.json', {
'Accept': 'application/json' headers: {
'Accept': 'application/json'
}
}); });
const voices = await get('/data/voices/all-v2.json'); if (!response.ok) {
throw new Error('failed to list models');
}
const voices = await response.json();
const modelVoices = model_id ? voices[model_id] : const modelVoices = model_id ? voices[model_id] :
Object.keys(voices).length > 0 ? voices[Object.keys(voices)[0]] : []; Object.keys(voices).length > 0 ? voices[Object.keys(voices)[0]] : [];
const ttsVoices = Object.entries(modelVoices).map(([key, voices]) => ({ const ttsVoices = Object.entries(modelVoices).map(([key, voices]) => ({
@@ -1238,14 +1269,18 @@ function parseVerbioLanguagesVoices(data) {
const fetchCartesiaVoices = async(credential) => { const fetchCartesiaVoices = async(credential) => {
if (credential) { if (credential) {
const get = bent('https://api.cartesia.ai', 'GET', 'json', { const response = await fetch('https://api.cartesia.ai/voices', {
'X-API-Key' : credential.api_key, headers: {
'Cartesia-Version': '2024-06-10', 'X-API-Key': credential.api_key,
'Accept': 'application/json' 'Cartesia-Version': '2024-06-10',
'Accept': 'application/json'
}
}); });
if (!response.ok) {
throw new Error('failed to list voices');
}
const voices = await get('/voices'); return await response.json();
return voices;
} }
}; };
+41 -5
View File
@@ -6,7 +6,6 @@ assert.ok(process.env.STRIPE_API_KEY || process.env.NODE_ENV === 'test',
assert.ok(process.env.STRIPE_BASE_URL || process.env.NODE_ENV === 'test', assert.ok(process.env.STRIPE_BASE_URL || process.env.NODE_ENV === 'test',
'missing env STRIPE_BASE_URL for billing operations'); 'missing env STRIPE_BASE_URL for billing operations');
const bent = require('bent');
const formurlencoded = require('form-urlencoded'); const formurlencoded = require('form-urlencoded');
const qs = require('qs'); const qs = require('qs');
const toBase64 = (str) => Buffer.from(str || '', 'utf8').toString('base64'); const toBase64 = (str) => Buffer.from(str || '', 'utf8').toString('base64');
@@ -14,10 +13,47 @@ const basicAuth = () => {
const header = `Basic ${toBase64(process.env.STRIPE_API_KEY)}`; const header = `Basic ${toBase64(process.env.STRIPE_API_KEY)}`;
return {Authorization: header}; return {Authorization: header};
}; };
const postForm = bent(process.env.STRIPE_BASE_URL || 'http://127.0.0.1', 'POST', 'string', const STRIPE_BASE_URL = process.env.STRIPE_BASE_URL || 'http://127.0.0.1';
Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, basicAuth()), 200); const getJSON = async(path) => {
const getJSON = bent(process.env.STRIPE_BASE_URL || 'http://127.0.0.1', 'GET', 'json', basicAuth(), 200); const response = await fetch(`${STRIPE_BASE_URL}${path}`, {
const deleteJSON = bent(process.env.STRIPE_BASE_URL || 'http://127.0.0.1', 'DELETE', 'json', basicAuth(), 200); headers: {
'Content-Type': 'application/json',
...basicAuth()
}
});
if (!response.ok) {
throw new Error(`Error retrieving ${path} from stripe: ${response.status}`);
}
return await response.json();
};
const postForm = async(path, body) => {
const response = await fetch(`${STRIPE_BASE_URL}${path}`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
...basicAuth()
},
body
});
if (!response.ok) {
throw new Error(`Error posting to ${path} from stripe: ${response.status}`);
}
return await response.text();
};
const deleteJSON = async(path) => {
const response = await fetch(`${STRIPE_BASE_URL}${path}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
...basicAuth()
}
});
if (!response.ok) {
throw new Error(`Error deleting ${path} from stripe: ${response.status}`);
}
return await response.json();
};
//const debug = require('debug')('jambonz:api-server'); //const debug = require('debug')('jambonz:api-server');
const listProducts = async(logger) => await getJSON('/products?active=true'); const listProducts = async(logger) => await getJSON('/products?active=true');
-338
View File
@@ -26,7 +26,6 @@
"@soniox/soniox-node": "^1.2.2", "@soniox/soniox-node": "^1.2.2",
"argon2": "^0.40.1", "argon2": "^0.40.1",
"assemblyai": "^4.3.4", "assemblyai": "^4.3.4",
"bent": "^7.3.12",
"cors": "^2.8.5", "cors": "^2.8.5",
"debug": "^4.3.4", "debug": "^4.3.4",
"express": "^4.19.2", "express": "^4.19.2",
@@ -58,8 +57,6 @@
"eslint-plugin-promise": "^6.1.1", "eslint-plugin-promise": "^6.1.1",
"husky": "9.0.11", "husky": "9.0.11",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"request": "^2.88.2",
"request-promise-native": "^1.0.9",
"tape": "^5.7.5" "tape": "^5.7.5"
} }
}, },
@@ -5771,15 +5768,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"dev": true,
"dependencies": {
"safer-buffer": "~2.1.0"
}
},
"node_modules/assemblyai": { "node_modules/assemblyai": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/assemblyai/-/assemblyai-4.3.4.tgz", "resolved": "https://registry.npmjs.org/assemblyai/-/assemblyai-4.3.4.tgz",
@@ -5840,15 +5828,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/aws-ssl-profiles": { "node_modules/aws-ssl-profiles": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.1.tgz", "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.1.tgz",
@@ -5858,12 +5837,6 @@
"node": ">= 6.0.0" "node": ">= 6.0.0"
} }
}, },
"node_modules/aws4": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
"dev": true
},
"node_modules/axios": { "node_modules/axios": {
"version": "1.7.7", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
@@ -5903,15 +5876,6 @@
} }
] ]
}, },
"node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
"dev": true,
"dependencies": {
"tweetnacl": "^0.14.3"
}
},
"node_modules/bent": { "node_modules/bent": {
"version": "7.3.12", "version": "7.3.12",
"resolved": "https://registry.npmjs.org/bent/-/bent-7.3.12.tgz", "resolved": "https://registry.npmjs.org/bent/-/bent-7.3.12.tgz",
@@ -6425,18 +6389,6 @@
"node": ">=0.12" "node": ">=0.12"
} }
}, },
"node_modules/dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
"dev": true,
"dependencies": {
"assert-plus": "^1.0.0"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/data-view-buffer": { "node_modules/data-view-buffer": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
@@ -6695,16 +6647,6 @@
"stream-shift": "^1.0.2" "stream-shift": "^1.0.2"
} }
}, },
"node_modules/ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
"dev": true,
"dependencies": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"node_modules/ecdsa-sig-formatter": { "node_modules/ecdsa-sig-formatter": {
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
@@ -7513,15 +7455,6 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/form-data": { "node_modules/form-data": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
@@ -7737,15 +7670,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
"dev": true,
"dependencies": {
"assert-plus": "^1.0.0"
}
},
"node_modules/glob": { "node_modules/glob": {
"version": "7.2.3", "version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -7884,29 +7808,6 @@
"node": ">=14.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/har-validator": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"deprecated": "this library is no longer supported",
"dev": true,
"dependencies": {
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/has-bigints": { "node_modules/has-bigints": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
@@ -8066,36 +7967,6 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
"dev": true,
"dependencies": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
},
"engines": {
"node": ">=0.8",
"npm": ">=1.3.7"
}
},
"node_modules/http-signature/node_modules/jsprim": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
"dev": true,
"dependencies": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.4.0",
"verror": "1.10.0"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/https-proxy-agent": { "node_modules/https-proxy-agent": {
"version": "7.0.4", "version": "7.0.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
@@ -8927,12 +8798,6 @@
"js-yaml": "bin/js-yaml.js" "js-yaml": "bin/js-yaml.js"
} }
}, },
"node_modules/jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
"dev": true
},
"node_modules/jsesc": { "node_modules/jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -8976,12 +8841,6 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true "dev": true
}, },
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"dev": true
},
"node_modules/json5": { "node_modules/json5": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -9104,12 +8963,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/lodash.camelcase": { "node_modules/lodash.camelcase": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
@@ -9761,15 +9614,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/object-assign": { "node_modules/object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -10083,12 +9927,6 @@
"url": "https://github.com/sponsors/Borewit" "url": "https://github.com/sponsors/Borewit"
} }
}, },
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
"dev": true
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@@ -10531,130 +10369,6 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
"deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
"dev": true,
"dependencies": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/request-promise-core": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
"integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
"dev": true,
"dependencies": {
"lodash": "^4.17.19"
},
"engines": {
"node": ">=0.10.0"
},
"peerDependencies": {
"request": "^2.34"
}
},
"node_modules/request-promise-native": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
"integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
"deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
"dev": true,
"dependencies": {
"request-promise-core": "1.1.4",
"stealthy-require": "^1.1.1",
"tough-cookie": "^2.3.3"
},
"engines": {
"node": ">=0.12.0"
},
"peerDependencies": {
"request": "^2.34"
}
},
"node_modules/request-promise-native/node_modules/tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"dev": true,
"dependencies": {
"psl": "^1.1.28",
"punycode": "^2.1.1"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/request/node_modules/form-data": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"dev": true,
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 0.12"
}
},
"node_modules/request/node_modules/qs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
"dev": true,
"engines": {
"node": ">=0.6"
}
},
"node_modules/request/node_modules/tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"dev": true,
"dependencies": {
"psl": "^1.1.28",
"punycode": "^2.1.1"
},
"engines": {
"node": ">=0.8"
}
},
"node_modules/request/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.",
"dev": true,
"bin": {
"uuid": "bin/uuid"
}
},
"node_modules/require-directory": { "node_modules/require-directory": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -11143,31 +10857,6 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/sshpk": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
"integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
"dev": true,
"dependencies": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
"dashdash": "^1.12.0",
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
},
"bin": {
"sshpk-conv": "bin/sshpk-conv",
"sshpk-sign": "bin/sshpk-sign",
"sshpk-verify": "bin/sshpk-verify"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/stack-utils": { "node_modules/stack-utils": {
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
@@ -11200,15 +10889,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/stop-iteration-iterator": { "node_modules/stop-iteration-iterator": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz",
@@ -11620,24 +11300,6 @@
"node": ">=0.6.11 <=0.7.0 || >=0.7.3" "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
} }
}, },
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true,
"dependencies": {
"safe-buffer": "^5.0.1"
},
"engines": {
"node": "*"
}
},
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
"dev": true
},
"node_modules/type": { "node_modules/type": {
"version": "2.7.2", "version": "2.7.2",
"resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
-3
View File
@@ -37,7 +37,6 @@
"@soniox/soniox-node": "^1.2.2", "@soniox/soniox-node": "^1.2.2",
"argon2": "^0.40.1", "argon2": "^0.40.1",
"assemblyai": "^4.3.4", "assemblyai": "^4.3.4",
"bent": "^7.3.12",
"cors": "^2.8.5", "cors": "^2.8.5",
"debug": "^4.3.4", "debug": "^4.3.4",
"express": "^4.19.2", "express": "^4.19.2",
@@ -69,8 +68,6 @@
"eslint-plugin-promise": "^6.1.1", "eslint-plugin-promise": "^6.1.1",
"husky": "9.0.11", "husky": "9.0.11",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"request": "^2.88.2",
"request-promise-native": "^1.0.9",
"tape": "^5.7.5" "tape": "^5.7.5"
} }
} }
+2 -5
View File
@@ -1,11 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const SP_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734ds'; const { createClient } = require('./http-client');
const authSP = {bearer: ADMIN_TOKEN}; const request = createClient({
const ACC_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734da';
const authAcc = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const { const {
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createVoipCarrier, createServiceProvider, const {createVoipCarrier, createServiceProvider,
+3 -1
View File
@@ -1,11 +1,13 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createVoipCarrier, createServiceProvider, createPhoneNumber, createAccount, deleteObjectBySid} = require('./utils'); const {createVoipCarrier, createServiceProvider, createPhoneNumber, createAccount, deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
}); });
+5 -6
View File
@@ -1,6 +1,7 @@
const test = require('tape'); const test = require('tape');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const consoleLogger = { debug: console.log, info: console.log, error: console.error } const consoleLogger = { debug: console.log, info: console.log, error: console.error }
@@ -47,8 +48,7 @@ test('Create Call Success With Synthesizer in Payload', async (t) => {
}); });
// THEN // THEN
t.ok(result.statusCode === 201, 'successfully created Call without Synthesizer && application_sid'); t.ok(result.statusCode === 201, 'successfully created Call without Synthesizer && application_sid');
const fs_request = await getLastRequestFromFeatureServer('15083778299_createCall'); const obj = await getLastRequestFromFeatureServer('15083778299_createCall');
const obj = JSON.parse(fs_request);
t.ok(obj.body.speech_synthesis_vendor == 'google', 'speech synthesizer successfully added') t.ok(obj.body.speech_synthesis_vendor == 'google', 'speech synthesizer successfully added')
t.ok(obj.body.speech_recognizer_vendor == 'google', 'speech recognizer successfully added') t.ok(obj.body.speech_recognizer_vendor == 'google', 'speech recognizer successfully added')
}); });
@@ -82,7 +82,7 @@ test('Create Call Success Without Synthesizer in Payload', async (t) => {
} }
} }
}).then(data => { t.ok(false, 'Create Call should not be success') }) }).then(data => { t.ok(false, 'Create Call should not be success') })
.catch(error => { t.ok(error.response.statusCode === 400, 'Call failed for no synthesizer') }); .catch(error => { t.ok(error.statusCode === 400, 'Call failed for no synthesizer') });
}); });
test("Create call with application sid and app_json", async(t) => { test("Create call with application sid and app_json", async(t) => {
@@ -150,7 +150,6 @@ result = await request.post(`/Accounts/${account_sid}/Calls`, {
}); });
// THEN // THEN
t.ok(result.statusCode === 201, 'successfully created Call without Synthesizer && application_sid'); t.ok(result.statusCode === 201, 'successfully created Call without Synthesizer && application_sid');
const fs_request = await getLastRequestFromFeatureServer('15083778299_createCall'); const obj = await getLastRequestFromFeatureServer('15083778299_createCall');
const obj = JSON.parse(fs_request);
t.ok(obj.body.app_json == app_json, 'app_json successfully added') t.ok(obj.body.app_json == app_json, 'app_json successfully added')
}); });
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const { createClient } = require('./http-client');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
+1 -3
View File
@@ -1,7 +1,5 @@
const test = require('tape'); const test = require('tape');
const {emailSimpleText} = require('../lib/utils/email-utils'); const {emailSimpleText} = require('../lib/utils/email-utils');
const bent = require('bent');
const getJSON = bent('json')
const logger = { const logger = {
debug: () =>{}, debug: () =>{},
info: () => {} info: () => {}
@@ -15,7 +13,7 @@ test('email-test', async(t) => {
await emailSimpleText(logger, 'test@gmail.com', 'subject', 'body text'); await emailSimpleText(logger, 'test@gmail.com', 'subject', 'body text');
const obj = await getJSON(`http://127.0.0.1:3101/lastRequest/custom_email_vendor`); const obj = await (await fetch(`http://127.0.0.1:3101/lastRequest/custom_email_vendor`)).json();
t.ok(obj.headers['Content-Type'] == 'application/json'); t.ok(obj.headers['Content-Type'] == 'application/json');
t.ok(obj.headers.Authorization == 'Basic VVNFUk5BTUU6UEFTU1dPUkQ='); t.ok(obj.headers.Authorization == 'Basic VVNFUk5BTUU6UEFTU1dPUkQ=');
t.ok(obj.body.from == 'jambonz Support <support@jambonz.org>'); t.ok(obj.body.from == 'jambonz Support <support@jambonz.org>');
+2 -1
View File
@@ -1,5 +1,6 @@
const test = require('tape'); const test = require('tape');
const request = require("request-promise-native").defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: "http://127.0.0.1:3000/v1", baseUrl: "http://127.0.0.1:3000/v1",
}); });
+172
View File
@@ -0,0 +1,172 @@
/**
* Fetch-based HTTP client that mimics the request-promise-native API
*/
class HttpClient {
constructor(defaults = {}) {
this.defaults = defaults;
this.baseUrl = defaults.baseUrl || '';
}
/**
* Make an HTTP GET request
*/
async get(url, options = {}) {
return this._makeRequest(url, 'GET', options);
}
/**
* Make an HTTP POST request
*/
async post(url, options = {}) {
return this._makeRequest(url, 'POST', options);
}
/**
* Make an HTTP PUT request
*/
async put(url, options = {}) {
return this._makeRequest(url, 'PUT', options);
}
/**
* Make an HTTP DELETE request
*/
async delete(url, options = {}) {
return this._makeRequest(url, 'DELETE', options);
}
/**
* Private method to handle all HTTP requests
*/
async _makeRequest(url, method, options = {}) {
const {
auth,
body,
json = true, // Changed default to true since most API calls expect JSON
qs = {},
simple = true,
resolveWithFullResponse = false
} = options;
// Build full URL with query parameters
const fullUrl = this._buildUrl(url, qs);
// Set up headers
const headers = {};
if (auth?.bearer) {
headers['Authorization'] = `Bearer ${auth.bearer}`;
}
// Set JSON headers for all requests when json is true
if (json) {
headers['Accept'] = 'application/json';
// Only set Content-Type when sending data
if (['POST', 'PUT', 'PATCH'].includes(method) && body) {
headers['Content-Type'] = 'application/json';
}
}
// Build request options
const fetchOptions = {
method,
headers
};
// Add request body if needed
if (body && ['POST', 'PUT', 'PATCH'].includes(method)) {
fetchOptions.body = json ? JSON.stringify(body) : body;
}
try {
// Make the request
const response = await fetch(fullUrl, fetchOptions);
// Clone the response before consuming it
// This allows us to use the body in error handling if needed
const clonedResponse = response.clone();
// Parse response body based on content type - only once
let responseBody = null;
if (response.status !== 204) { // No content
if (json) {
try {
responseBody = await response.json();
} catch (e) {
// If can't parse JSON, get text
responseBody = await clonedResponse.text();
}
} else {
responseBody = await response.text();
}
}
// Handle errors if simple mode is enabled
if (simple && !response.ok) {
const error = new Error(`Request failed with status code ${response.status}`);
error.statusCode = response.status;
error.body = responseBody; // Include the already parsed body
throw error;
}
// Return full response object or just body based on options
if (resolveWithFullResponse) {
return {
statusCode: response.status,
body: responseBody,
headers: Object.fromEntries(response.headers.entries())
};
}
return responseBody;
} catch (error) {
if (!simple) {
// If simple=false, return error response instead of throwing
return {
statusCode: error.statusCode || 500,
body: error.body || { message: error.message }
};
}
throw error;
}
}
/**
* Build URL with query parameters
*/
_buildUrl(url, qs) {
// Start with base URL
let fullUrl = this.baseUrl + url;
// Add query parameters
if (Object.keys(qs).length > 0) {
const params = new URLSearchParams();
Object.entries(qs).forEach(([key, value]) => {
params.append(key, value);
});
fullUrl += `?${params.toString()}`;
}
return fullUrl;
}
}
/**
* Create a client with default options
*/
function createClient(defaults = {}) {
const client = new HttpClient(defaults);
// Return the methods directly for API compatibility
return {
get: (url, options) => client.get(url, options),
post: (url, options) => client.post(url, options),
put: (url, options) => client.put(url, options),
delete: (url, options) => client.delete(url, options),
defaults: client.defaults
};
}
module.exports = {
createClient
};
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const { createClient } = require('./http-client');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
+9 -4
View File
@@ -1,12 +1,14 @@
const test = require('tape') ; const test = require('tape') ;
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const exec = require('child_process').exec ; const exec = require('child_process').exec ;
const {generateHashedPassword} = require('../lib/utils/password-utils'); const {generateHashedPassword} = require('../lib/utils/password-utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
}); });
@@ -52,7 +54,7 @@ test('login tests', async(t) => {
password: 'adm', password: 'adm',
} }
}).catch(error => { }).catch(error => {
t.ok(error.response.statusCode === 403, `Maximum login attempts reached. Please try again in ${attempTime} seconds.`) t.ok(error.statusCode === 403, `Maximum login attempts reached. Please try again in ${attempTime} seconds.`)
}); });
} else if (index < maxAttempts) { } else if (index < maxAttempts) {
attemptResult = await request.post('/login', { attemptResult = await request.post('/login', {
@@ -62,7 +64,10 @@ test('login tests', async(t) => {
username: 'admin', username: 'admin',
password: 'adm', password: 'adm',
} }
}).catch(error => t.ok(error.response.statusCode === 403)); }).catch(error => {
console.log(JSON.stringify(error));
t.ok(error.statusCode === 403);
});
} else { } else {
attemptResult = await request.post('/login', { attemptResult = await request.post('/login', {
resolveWithFullResponse: true, resolveWithFullResponse: true,
@@ -71,7 +76,7 @@ test('login tests', async(t) => {
username: 'admin', username: 'admin',
password: 'adm', password: 'adm',
} }
}).catch(error => t.ok(error.response.statusCode === 403, 'Maximum login attempts reached. Please try again later or reset your password.')); }).catch(error => t.ok(error.statusCode === 403, 'Maximum login attempts reached. Please try again later or reset your password.'));
} }
} }
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createServiceProvider, createAccount, deleteObjectBySid} = require('./utils'); const {createServiceProvider, createAccount, deleteObjectBySid} = require('./utils');
+2 -5
View File
@@ -1,9 +1,6 @@
const bent = require('bent');
const getJSON = bent('GET', 200);
const request = require('request');
const test = async() => { const test = async() => {
request.get('https://api.github.com/user', { fetch('https://api.github.com/user', {
method: 'GET',
headers: { headers: {
Authorization: `Bearer ${process.env.GH_CODE}`, Authorization: `Bearer ${process.env.GH_CODE}`,
Accept: 'application/json', Accept: 'application/json',
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const { createClient } = require('./http-client');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createVoipCarrier, deleteObjectBySid} = require('./utils'); const {createVoipCarrier, deleteObjectBySid} = require('./utils');
+2 -1
View File
@@ -3,7 +3,8 @@ const fs = require('fs');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const consoleLogger = {debug: console.log, info: console.log, error: console.error} const consoleLogger = {debug: console.log, info: console.log, error: console.error}
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createServiceProvider, deleteObjectBySid} = require('./utils'); const {createServiceProvider, deleteObjectBySid} = require('./utils');
+3 -1
View File
@@ -1,11 +1,13 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {deleteObjectBySid} = require('./utils'); const {deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
}); });
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createVoipCarrier, deleteObjectBySid} = require('./utils'); const {createVoipCarrier, deleteObjectBySid} = require('./utils');
+3 -1
View File
@@ -1,11 +1,13 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createVoipCarrier, deleteObjectBySid} = require('./utils'); const {createVoipCarrier, deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
}); });
+3 -1
View File
@@ -3,12 +3,14 @@ const fs = require('fs');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createServiceProvider, createAccount, deleteObjectBySid} = require('./utils'); const {createServiceProvider, createAccount, deleteObjectBySid} = require('./utils');
const { noopLogger } = require('@jambonz/realtimedb-helpers/lib/utils'); const { noopLogger } = require('@jambonz/realtimedb-helpers/lib/utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
}); });
+2 -1
View File
@@ -1,8 +1,9 @@
const test = require('tape') ; const test = require('tape') ;
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const { createClient } = require('./http-client');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
+2 -1
View File
@@ -2,7 +2,8 @@ const test = require('tape') ;
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const crypto = require('crypto'); const crypto = require('crypto');
+3 -1
View File
@@ -1,10 +1,12 @@
const test = require('tape') ; const test = require('tape') ;
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const exec = require('child_process').exec ; const exec = require('child_process').exec ;
const {generateHashedPassword} = require('../lib/utils/password-utils'); const {generateHashedPassword} = require('../lib/utils/password-utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
}); });
+3 -2
View File
@@ -1,10 +1,11 @@
const test = require('tape') ; const test = require('tape') ;
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const exec = require('child_process').exec ; const exec = require('child_process').exec ;
const {generateHashedPassword} = require('../lib/utils/password-utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
+2 -1
View File
@@ -1,6 +1,7 @@
const { v4: uuid } = require('uuid'); const { v4: uuid } = require('uuid');
const fs = require('fs'); const fs = require('fs');
const request_fs_mock = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request_fs_mock = createClient({
baseUrl: 'http://127.0.0.1:3100' baseUrl: 'http://127.0.0.1:3100'
}); });
+3 -1
View File
@@ -1,11 +1,13 @@
const test = require('tape') ; const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de'; const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN}; const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const {createServiceProvider, createAccount, createApplication, deleteObjectBySid} = require('./utils'); const {createServiceProvider, createAccount, createApplication, deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => { process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
}); });
+2 -1
View File
@@ -1,7 +1,8 @@
const test = require('tape') ; const test = require('tape') ;
const exec = require('child_process').exec ; const exec = require('child_process').exec ;
const Account = require('../lib/models/account'); const Account = require('../lib/models/account');
const request = require('request-promise-native').defaults({ const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1' baseUrl: 'http://127.0.0.1:3000/v1'
}); });
const theOneAndOnlyServiceProviderSid = '2708b1b3-2736-40ea-b502-c53d8396247f'; const theOneAndOnlyServiceProviderSid = '2708b1b3-2736-40ea-b502-c53d8396247f';