Remove smpp (#559)

* remove smpp

* update db-helpers
This commit is contained in:
Sam Machin
2026-07-28 10:32:42 -04:00
committed by GitHub
parent e09933900b
commit 24621f79dd
31 changed files with 15 additions and 1150 deletions
-6
View File
@@ -66,7 +66,6 @@ const {
lookupAppByPhoneNumber, lookupAppByPhoneNumber,
lookupCarrierBySid, lookupCarrierBySid,
lookupSipGatewayBySid, lookupSipGatewayBySid,
lookupSmppGatewayBySid,
lookupClientByAccountAndUsername lookupClientByAccountAndUsername
} = require('@jambonz/db-helpers')({ } = require('@jambonz/db-helpers')({
host: process.env.JAMBONES_MYSQL_HOST, host: process.env.JAMBONES_MYSQL_HOST,
@@ -111,7 +110,6 @@ app.locals = {
lookupAppByPhoneNumber, lookupAppByPhoneNumber,
lookupCarrierBySid, lookupCarrierBySid,
lookupSipGatewayBySid, lookupSipGatewayBySid,
lookupSmppGatewayBySid,
lookupClientByAccountAndUsername, lookupClientByAccountAndUsername,
queryCdrs, queryCdrs,
queryCdrsSP, queryCdrsSP,
@@ -190,8 +188,6 @@ app.use('/v1', unless(
'/forgot-password', '/forgot-password',
'/signin', '/signin',
'/login', '/login',
'/messaging',
'/outboundSMS',
'/AccountTest', '/AccountTest',
'/InviteCodes', '/InviteCodes',
'/PredefinedCarriers' '/PredefinedCarriers'
@@ -202,8 +198,6 @@ app.use('/v1', unless(
'/forgot-password', '/forgot-password',
'/signin', '/signin',
'/login', '/login',
'/messaging',
'/outboundSMS',
'/AccountTest', '/AccountTest',
'/InviteCodes', '/InviteCodes',
'/PredefinedCarriers', '/PredefinedCarriers',
-64
View File
@@ -32,8 +32,6 @@ DROP TABLE IF EXISTS permissions;
DROP TABLE IF EXISTS predefined_sip_gateways; DROP TABLE IF EXISTS predefined_sip_gateways;
DROP TABLE IF EXISTS predefined_smpp_gateways;
DROP TABLE IF EXISTS predefined_carriers; DROP TABLE IF EXISTS predefined_carriers;
DROP TABLE IF EXISTS account_offers; DROP TABLE IF EXISTS account_offers;
@@ -52,8 +50,6 @@ DROP TABLE IF EXISTS service_provider_limits;
DROP TABLE IF EXISTS signup_history; DROP TABLE IF EXISTS signup_history;
DROP TABLE IF EXISTS smpp_addresses;
DROP TABLE IF EXISTS google_custom_voices; DROP TABLE IF EXISTS google_custom_voices;
DROP TABLE IF EXISTS speech_credentials; DROP TABLE IF EXISTS speech_credentials;
@@ -62,8 +58,6 @@ DROP TABLE IF EXISTS system_information;
DROP TABLE IF EXISTS users; DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS smpp_gateways;
DROP TABLE IF EXISTS phone_numbers; DROP TABLE IF EXISTS phone_numbers;
DROP TABLE IF EXISTS sip_gateways; DROP TABLE IF EXISTS sip_gateways;
@@ -220,20 +214,6 @@ predefined_carrier_sid CHAR(36) NOT NULL,
PRIMARY KEY (predefined_sip_gateway_sid) PRIMARY KEY (predefined_sip_gateway_sid)
); );
CREATE TABLE predefined_smpp_gateways
(
predefined_smpp_gateway_sid CHAR(36) NOT NULL UNIQUE ,
ipv4 VARCHAR(128) NOT NULL COMMENT 'ip address or DNS name of the gateway. ',
port INTEGER NOT NULL DEFAULT 2775 COMMENT 'smpp signaling port',
inbound BOOLEAN NOT NULL COMMENT 'if true, whitelist this IP to allow inbound SMS from the gateway',
outbound BOOLEAN NOT NULL COMMENT 'i',
netmask INTEGER NOT NULL DEFAULT 32,
is_primary BOOLEAN NOT NULL DEFAULT 1,
use_tls BOOLEAN DEFAULT 0,
predefined_carrier_sid CHAR(36) NOT NULL,
PRIMARY KEY (predefined_smpp_gateway_sid)
);
CREATE TABLE products CREATE TABLE products
( (
product_sid CHAR(36) NOT NULL UNIQUE , product_sid CHAR(36) NOT NULL UNIQUE ,
@@ -316,17 +296,6 @@ signed_up_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (email) PRIMARY KEY (email)
); );
CREATE TABLE smpp_addresses
(
smpp_address_sid CHAR(36) NOT NULL UNIQUE ,
ipv4 VARCHAR(255) NOT NULL,
port INTEGER NOT NULL DEFAULT 5060,
use_tls BOOLEAN NOT NULL DEFAULT 0,
is_primary BOOLEAN NOT NULL DEFAULT 1,
service_provider_sid CHAR(36),
PRIMARY KEY (smpp_address_sid)
);
CREATE TABLE speech_credentials CREATE TABLE speech_credentials
( (
speech_credential_sid CHAR(36) NOT NULL UNIQUE , speech_credential_sid CHAR(36) NOT NULL UNIQUE ,
@@ -408,11 +377,6 @@ inbound_auth_password VARCHAR(64),
diversion VARCHAR(32), diversion VARCHAR(32),
is_active BOOLEAN NOT NULL DEFAULT true, is_active BOOLEAN NOT NULL DEFAULT true,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
smpp_system_id VARCHAR(255),
smpp_password VARCHAR(64),
smpp_enquire_link_interval INTEGER DEFAULT 0,
smpp_inbound_system_id VARCHAR(255),
smpp_inbound_password VARCHAR(64),
register_from_user VARCHAR(128), register_from_user VARCHAR(128),
register_from_domain VARCHAR(255), register_from_domain VARCHAR(255),
register_public_ip_in_contact BOOLEAN NOT NULL DEFAULT false, register_public_ip_in_contact BOOLEAN NOT NULL DEFAULT false,
@@ -431,20 +395,6 @@ permission_sid CHAR(36) NOT NULL,
PRIMARY KEY (user_permissions_sid) PRIMARY KEY (user_permissions_sid)
); );
CREATE TABLE smpp_gateways
(
smpp_gateway_sid CHAR(36) NOT NULL UNIQUE ,
ipv4 VARCHAR(128) NOT NULL,
port INTEGER NOT NULL DEFAULT 2775,
netmask INTEGER NOT NULL DEFAULT 32,
is_primary BOOLEAN NOT NULL DEFAULT 1,
inbound BOOLEAN NOT NULL DEFAULT 0 COMMENT 'if true, whitelist this IP to allow inbound calls from the gateway',
outbound BOOLEAN NOT NULL DEFAULT 1 COMMENT 'if true, include in least-cost routing when placing calls to the PSTN',
use_tls BOOLEAN DEFAULT 0,
voip_carrier_sid CHAR(36) NOT NULL,
PRIMARY KEY (smpp_gateway_sid)
);
CREATE TABLE phone_numbers CREATE TABLE phone_numbers
( (
phone_number_sid CHAR(36) UNIQUE , phone_number_sid CHAR(36) UNIQUE ,
@@ -503,7 +453,6 @@ service_provider_sid CHAR(36) COMMENT 'if non-null, this application is a test a
account_sid CHAR(36) COMMENT 'account that this application belongs to (if null, this is a service provider test application)', account_sid CHAR(36) COMMENT 'account that this application belongs to (if null, this is a service provider test application)',
call_hook_sid CHAR(36) COMMENT 'webhook to call for inbound calls ', call_hook_sid CHAR(36) COMMENT 'webhook to call for inbound calls ',
call_status_hook_sid CHAR(36) COMMENT 'webhook to call for call status events', call_status_hook_sid CHAR(36) COMMENT 'webhook to call for call status events',
messaging_hook_sid CHAR(36) COMMENT 'webhook to call for inbound SMS/MMS ',
app_json TEXT, app_json TEXT,
speech_synthesis_vendor VARCHAR(64) NOT NULL DEFAULT 'google', speech_synthesis_vendor VARCHAR(64) NOT NULL DEFAULT 'google',
speech_synthesis_language VARCHAR(12) NOT NULL DEFAULT 'en-US', speech_synthesis_language VARCHAR(12) NOT NULL DEFAULT 'en-US',
@@ -604,10 +553,6 @@ CREATE INDEX predefined_sip_gateway_sid_idx ON predefined_sip_gateways (predefin
CREATE INDEX predefined_carrier_sid_idx ON predefined_sip_gateways (predefined_carrier_sid); CREATE INDEX predefined_carrier_sid_idx ON predefined_sip_gateways (predefined_carrier_sid);
ALTER TABLE predefined_sip_gateways ADD FOREIGN KEY predefined_carrier_sid_idxfk (predefined_carrier_sid) REFERENCES predefined_carriers (predefined_carrier_sid); ALTER TABLE predefined_sip_gateways ADD FOREIGN KEY predefined_carrier_sid_idxfk (predefined_carrier_sid) REFERENCES predefined_carriers (predefined_carrier_sid);
CREATE INDEX predefined_smpp_gateway_sid_idx ON predefined_smpp_gateways (predefined_smpp_gateway_sid);
CREATE INDEX predefined_carrier_sid_idx ON predefined_smpp_gateways (predefined_carrier_sid);
ALTER TABLE predefined_smpp_gateways ADD FOREIGN KEY predefined_carrier_sid_idxfk_1 (predefined_carrier_sid) REFERENCES predefined_carriers (predefined_carrier_sid);
CREATE INDEX product_sid_idx ON products (product_sid); CREATE INDEX product_sid_idx ON products (product_sid);
CREATE INDEX account_product_sid_idx ON account_products (account_product_sid); CREATE INDEX account_product_sid_idx ON account_products (account_product_sid);
CREATE INDEX account_subscription_sid_idx ON account_products (account_subscription_sid); CREATE INDEX account_subscription_sid_idx ON account_products (account_subscription_sid);
@@ -647,9 +592,6 @@ CREATE INDEX service_provider_sid_idx ON service_provider_limits (service_provid
ALTER TABLE service_provider_limits ADD FOREIGN KEY service_provider_sid_idxfk_3 (service_provider_sid) REFERENCES service_providers (service_provider_sid) ON DELETE CASCADE; ALTER TABLE service_provider_limits ADD FOREIGN KEY service_provider_sid_idxfk_3 (service_provider_sid) REFERENCES service_providers (service_provider_sid) ON DELETE CASCADE;
CREATE INDEX email_idx ON signup_history (email); CREATE INDEX email_idx ON signup_history (email);
CREATE INDEX smpp_address_sid_idx ON smpp_addresses (smpp_address_sid);
CREATE INDEX service_provider_sid_idx ON smpp_addresses (service_provider_sid);
ALTER TABLE smpp_addresses ADD FOREIGN KEY service_provider_sid_idxfk_4 (service_provider_sid) REFERENCES service_providers (service_provider_sid);
CREATE INDEX speech_credential_sid_idx ON speech_credentials (speech_credential_sid); CREATE INDEX speech_credential_sid_idx ON speech_credentials (speech_credential_sid);
CREATE INDEX service_provider_sid_idx ON speech_credentials (service_provider_sid); CREATE INDEX service_provider_sid_idx ON speech_credentials (service_provider_sid);
@@ -687,10 +629,6 @@ ALTER TABLE user_permissions ADD FOREIGN KEY user_sid_idxfk (user_sid) REFERENCE
ALTER TABLE user_permissions ADD FOREIGN KEY permission_sid_idxfk (permission_sid) REFERENCES permissions (permission_sid); ALTER TABLE user_permissions ADD FOREIGN KEY permission_sid_idxfk (permission_sid) REFERENCES permissions (permission_sid);
CREATE INDEX smpp_gateway_sid_idx ON smpp_gateways (smpp_gateway_sid);
CREATE INDEX voip_carrier_sid_idx ON smpp_gateways (voip_carrier_sid);
ALTER TABLE smpp_gateways ADD FOREIGN KEY voip_carrier_sid_idxfk (voip_carrier_sid) REFERENCES voip_carriers (voip_carrier_sid);
CREATE UNIQUE INDEX phone_numbers_unique_idx_voip_carrier_number ON phone_numbers (number,voip_carrier_sid); CREATE UNIQUE INDEX phone_numbers_unique_idx_voip_carrier_number ON phone_numbers (number,voip_carrier_sid);
CREATE INDEX phone_number_sid_idx ON phone_numbers (phone_number_sid); CREATE INDEX phone_number_sid_idx ON phone_numbers (phone_number_sid);
@@ -734,8 +672,6 @@ ALTER TABLE applications ADD FOREIGN KEY call_hook_sid_idxfk (call_hook_sid) REF
ALTER TABLE applications ADD FOREIGN KEY call_status_hook_sid_idxfk (call_status_hook_sid) REFERENCES webhooks (webhook_sid); ALTER TABLE applications ADD FOREIGN KEY call_status_hook_sid_idxfk (call_status_hook_sid) REFERENCES webhooks (webhook_sid);
ALTER TABLE applications ADD FOREIGN KEY messaging_hook_sid_idxfk (messaging_hook_sid) REFERENCES webhooks (webhook_sid);
CREATE INDEX service_provider_sid_idx ON service_providers (service_provider_sid); CREATE INDEX service_provider_sid_idx ON service_providers (service_provider_sid);
CREATE INDEX name_idx ON service_providers (name); CREATE INDEX name_idx ON service_providers (name);
CREATE INDEX root_domain_idx ON service_providers (root_domain); CREATE INDEX root_domain_idx ON service_providers (root_domain);
-10
View File
@@ -11,10 +11,6 @@ insert into sbc_addresses (sbc_address_sid, ipv4, port)
values('f6567ae1-bf97-49af-8931-ca014b689995', '52.55.111.178', 5060); values('f6567ae1-bf97-49af-8931-ca014b689995', '52.55.111.178', 5060);
insert into sbc_addresses (sbc_address_sid, ipv4, port) insert into sbc_addresses (sbc_address_sid, ipv4, port)
values('de5ed2f1-bccd-4600-a95e-cef46e9a3a4f', '3.34.102.122', 5060); values('de5ed2f1-bccd-4600-a95e-cef46e9a3a4f', '3.34.102.122', 5060);
insert into smpp_addresses (smpp_address_sid, ipv4, port, use_tls, is_primary)
values('de5ed2f1-bccd-4600-a95e-cef46e9a3a4f', '34.197.99.29', 2775, 0, 1);
insert into smpp_addresses (smpp_address_sid, ipv4, port, use_tls, is_primary)
values('049078a0', '3.209.58.102', 3550, 1, 1);
-- create one service provider and account -- create one service provider and account
insert into api_keys (api_key_sid, token) insert into api_keys (api_key_sid, token)
@@ -70,12 +66,6 @@ VALUES
('c9c3643e-9a83-4b78-b172-9c09d911bef5', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 5060, 1, 0), ('c9c3643e-9a83-4b78-b172-9c09d911bef5', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 5060, 1, 0),
('3b5b7fa5-4e61-4423-b921-05c3283b2101', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'sip01.TelecomsXChange.com', 32, 5060, 0, 1); ('3b5b7fa5-4e61-4423-b921-05c3283b2101', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'sip01.TelecomsXChange.com', 32, 5060, 0, 1);
insert into predefined_smpp_gateways (predefined_smpp_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound)
VALUES
('9b72467a-cfe3-491f-80bf-652c38e666b9', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'smpp01.telecomsxchange.com', 32, 2776, 0, 1),
('d22883b9-f124-4a89-bab2-4487cf783f64', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.11', 32, 2775, 1, 0),
('fdcf7f1e-1f5f-487b-afb3-c0f75ed0aa3d', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 2775, 1, 0);
-- twilio gateways -- twilio gateways
insert into predefined_sip_gateways (predefined_sip_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound) insert into predefined_sip_gateways (predefined_sip_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound)
VALUES VALUES
@@ -56,12 +56,6 @@ VALUES
('c9c3643e-9a83-4b78-b172-9c09d911bef5', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 5060, 1, 0), ('c9c3643e-9a83-4b78-b172-9c09d911bef5', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 5060, 1, 0),
('3b5b7fa5-4e61-4423-b921-05c3283b2101', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'sip01.TelecomsXChange.com', 32, 5060, 0, 1); ('3b5b7fa5-4e61-4423-b921-05c3283b2101', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'sip01.TelecomsXChange.com', 32, 5060, 0, 1);
insert into predefined_smpp_gateways (predefined_smpp_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound)
VALUES
('9b72467a-cfe3-491f-80bf-652c38e666b9', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'smpp01.telecomsxchange.com', 32, 2776, 0, 1),
('d22883b9-f124-4a89-bab2-4487cf783f64', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.11', 32, 2775, 1, 0),
('fdcf7f1e-1f5f-487b-afb3-c0f75ed0aa3d', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 2775, 1, 0);
-- twilio gateways -- twilio gateways
insert into predefined_sip_gateways (predefined_sip_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound) insert into predefined_sip_gateways (predefined_sip_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound)
VALUES VALUES
-6
View File
@@ -36,12 +36,6 @@ VALUES
('c9c3643e-9a83-4b78-b172-9c09d911bef5', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 5060, 1, 0), ('c9c3643e-9a83-4b78-b172-9c09d911bef5', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 5060, 1, 0),
('3b5b7fa5-4e61-4423-b921-05c3283b2101', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'sip01.TelecomsXChange.com', 32, 5060, 0, 1); ('3b5b7fa5-4e61-4423-b921-05c3283b2101', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'sip01.TelecomsXChange.com', 32, 5060, 0, 1);
insert into predefined_smpp_gateways (predefined_smpp_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound)
VALUES
('9b72467a-cfe3-491f-80bf-652c38e666b9', '17479288-bb9f-421a-89d1-f4ac57af1dca', 'smpp01.telecomsxchange.com', 32, 2776, 0, 1),
('d22883b9-f124-4a89-bab2-4487cf783f64', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.11', 32, 2775, 1, 0),
('fdcf7f1e-1f5f-487b-afb3-c0f75ed0aa3d', '17479288-bb9f-421a-89d1-f4ac57af1dca', '174.136.44.213', 32, 2775, 1, 0);
-- twilio gateways -- twilio gateways
insert into predefined_sip_gateways (predefined_sip_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound) insert into predefined_sip_gateways (predefined_sip_gateway_sid, predefined_carrier_sid, ipv4, netmask, port, inbound, outbound)
VALUES VALUES
-4
View File
@@ -9,10 +9,6 @@ values ('3f35518f-5a0d-4c2e-90a5-2407bb3b36f0', '38700987-c7a4-4685-a5bb-af378f9
-- one sbc -- one sbc
insert into sbc_addresses (sbc_address_sid, service_provider_sid, ipv4, port) values ('8d6d0fda-4550-41ab-8e2f-60761d81fe7d', null, '3.39.45.30', '5060'); insert into sbc_addresses (sbc_address_sid, service_provider_sid, ipv4, port) values ('8d6d0fda-4550-41ab-8e2f-60761d81fe7d', null, '3.39.45.30', '5060');
-- two smpp server
insert into smpp_addresses (smpp_address_sid, service_provider_sid, ipv4, port, use_tls, is_primary) values ('e5e8345b-d533-4c29-940b-57aaccc59f8b', null, '3.39.45.30', '2775', false, true);
insert into smpp_addresses (smpp_address_sid, service_provider_sid, ipv4, port, use_tls, is_primary) values ('ae060ef3-d5a4-4842-b331-426ec9329fbe', null, '3.39.45.30', '3550', true, true);
-- one voip carrier with one gateway -- one voip carrier with one gateway
insert into voip_carriers (voip_carrier_sid, name) values ('5145b436-2f38-4029-8d4c-fd8c67831c7a', 'my test carrier'); insert into voip_carriers (voip_carrier_sid, name) values ('5145b436-2f38-4029-8d4c-fd8c67831c7a', 'my test carrier');
insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound, is_active) insert into sip_gateways (sip_gateway_sid, voip_carrier_sid, ipv4, port, inbound, outbound, is_active)
+1 -12
View File
@@ -5,9 +5,7 @@ const retrieveSql = `SELECT * from applications app
LEFT JOIN webhooks AS ch LEFT JOIN webhooks AS ch
ON app.call_hook_sid = ch.webhook_sid ON app.call_hook_sid = ch.webhook_sid
LEFT JOIN webhooks AS sh LEFT JOIN webhooks AS sh
ON app.call_status_hook_sid = sh.webhook_sid ON app.call_status_hook_sid = sh.webhook_sid`;
LEFT JOIN webhooks AS mh
ON app.messaging_hook_sid = mh.webhook_sid`;
function transmogrifyResults(results) { function transmogrifyResults(results) {
return results.map((row) => { return results.map((row) => {
@@ -20,13 +18,8 @@ function transmogrifyResults(results) {
Object.assign(obj, {call_status_hook: row.sh}); Object.assign(obj, {call_status_hook: row.sh});
} }
else obj.call_status_hook = null; else obj.call_status_hook = null;
if (row.mh && Object.keys(row.mh).length && row.mh.url !== null) {
Object.assign(obj, {messaging_hook: row.mh});
}
else obj.messaging_hook = null;
delete obj.call_hook_sid; delete obj.call_hook_sid;
delete obj.call_status_hook_sid; delete obj.call_status_hook_sid;
delete obj.messaging_hook_sid;
return obj; return obj;
}); });
} }
@@ -215,10 +208,6 @@ Application.fields = [
name: 'call_status_hook_sid', name: 'call_status_hook_sid',
type: 'string', type: 'string',
}, },
{
name: 'messaging_hook_sid',
type: 'string',
},
{ {
name: 'record_all_calls', name: 'record_all_calls',
type: 'number', type: 'number',
-60
View File
@@ -1,60 +0,0 @@
const Model = require('./model');
const {promisePool} = require('../db');
const retrieveSql = 'SELECT * from smpp_gateways WHERE voip_carrier_sid = ?';
class SmppGateway extends Model {
constructor() {
super();
}
/**
* list all sip gateways for a voip_carrier
*/
static async retrieveForVoipCarrier(voip_carrier_sid) {
const [rows] = await promisePool.query(retrieveSql, voip_carrier_sid);
return rows;
}
}
SmppGateway.table = 'smpp_gateways';
SmppGateway.fields = [
{
name: 'smpp_gateway_sid',
type: 'string',
primaryKey: true
},
{
name: 'voip_carrier_sid',
type: 'string'
},
{
name: 'ipv4',
type: 'string',
required: true
},
{
name: 'port',
type: 'number'
},
{
name: 'netmask',
type: 'number'
},
{
name: 'inbound',
type: 'number'
},
{
name: 'outbound',
type: 'number'
},
{
name: 'is_primary',
type: 'number'
},
{
name: 'use_tls',
type: 'number'
}
];
module.exports = SmppGateway;
-55
View File
@@ -1,55 +0,0 @@
const Model = require('./model');
const {getMysqlConnection} = require('../db');
class Smpp extends Model {
constructor() {
super();
}
/**
* list all SBCs either for a given service provider, or those not associated with a
* service provider (i.e. community SBCs)
*/
static retrieveAll(service_provider_sid) {
const sql = service_provider_sid ?
'SELECT * from smpp_addresses WHERE service_provider_sid = ?' :
'SELECT * from smpp_addresses WHERE service_provider_sid IS NULL';
const args = service_provider_sid ? [service_provider_sid] : [];
return new Promise((resolve, reject) => {
getMysqlConnection((err, conn) => {
if (err) return reject(err);
conn.query(sql, args, (err, results) => {
conn.release();
if (err) return reject(err);
resolve(results);
});
});
});
}
}
Smpp.table = 'smpp_addresses';
Smpp.fields = [
{
name: 'smpp_address_sid',
type: 'string',
primaryKey: true
},
{
name: 'ipv4',
type: 'string',
required: true
},
{
name: 'port',
type: 'number'
},
{
name: 'service_provider_sid',
type: 'string'
}
];
module.exports = Smpp;
-24
View File
@@ -148,30 +148,6 @@ VoipCarrier.fields = [
name: 'is_active', name: 'is_active',
type: 'number' type: 'number'
}, },
{
name: 'smpp_system_id',
type: 'string'
},
{
name: 'smpp_password',
type: 'string'
},
{
name: 'smpp_inbound_system_id',
type: 'string'
},
{
name: 'smpp_inbound_password',
type: 'string'
},
{
name: 'smpp_enquire_link_interval',
type: 'number'
},
{
name: 'smpp_system_id',
type: 'string'
},
{ {
name: 'register_from_user', name: 'register_from_user',
type: 'string' type: 'string'
+1 -8
View File
@@ -5,9 +5,7 @@ const retrieveApplicationsSql = `SELECT * from applications app
LEFT JOIN webhooks AS ch LEFT JOIN webhooks AS ch
ON app.call_hook_sid = ch.webhook_sid ON app.call_hook_sid = ch.webhook_sid
LEFT JOIN webhooks AS sh LEFT JOIN webhooks AS sh
ON app.call_status_hook_sid = sh.webhook_sid ON app.call_status_hook_sid = sh.webhook_sid
LEFT JOIN webhooks AS mh
ON app.messaging_hook_sid = mh.webhook_sid
WHERE service_provider_sid = ?`; WHERE service_provider_sid = ?`;
const transmogrifyResults = (results) => { const transmogrifyResults = (results) => {
@@ -21,13 +19,8 @@ const transmogrifyResults = (results) => {
Object.assign(obj, {call_status_hook: row.sh}); Object.assign(obj, {call_status_hook: row.sh});
} }
else obj.call_status_hook = null; else obj.call_status_hook = null;
if (row.mh && Object.keys(row.mh).length && row.mh.url !== null) {
Object.assign(obj, {messaging_hook: row.mh});
}
else obj.messaging_hook = null;
delete obj.call_hook_sid; delete obj.call_hook_sid;
delete obj.call_status_hook_sid; delete obj.call_status_hook_sid;
delete obj.messaging_hook_sid;
return obj; return obj;
}); });
}; };
-65
View File
@@ -8,7 +8,6 @@ const ApiKey = require('../../models/api-key');
const ServiceProvider = require('../../models/service-provider'); const ServiceProvider = require('../../models/service-provider');
const {deleteDnsRecords} = require('../../utils/dns-utils'); const {deleteDnsRecords} = require('../../utils/dns-utils');
const {deleteCustomer} = require('../../utils/stripe-utils'); const {deleteCustomer} = require('../../utils/stripe-utils');
const { v4: uuidv4 } = require('uuid');
const snakeCase = require('../../utils/snake-case'); const snakeCase = require('../../utils/snake-case');
const sysError = require('../error'); const sysError = require('../error');
const {promisePool} = require('../../db'); const {promisePool} = require('../../db');
@@ -472,31 +471,6 @@ async function validateCreateCall(logger, sid, req) {
} }
} }
async function validateCreateMessage(logger, sid, req) {
const obj = req.body;
logger.debug({payload: req.body}, 'validateCreateMessage');
if (req.user.account_sid !== sid) {
throw new DbErrorBadRequest(`unauthorized createMessage request for account ${sid}`);
}
if (!obj.from) throw new DbErrorBadRequest('missing from property');
/*
else {
const regex = /^\+(\d+)$/;
const arr = regex.exec(obj.from);
const from = arr ? arr[1] : obj.from;
const account = await lookupAccountByPhoneNumber(from);
if (!account) throw new DbErrorBadRequest(`accountSid ${sid} does not own phone number ${from}`);
}
*/
if (!obj.to) throw new DbErrorBadRequest('missing to property');
if (!obj.text && !obj.media) {
throw new DbErrorBadRequest('either text or media required in outbound message');
}
}
async function validateAdd(req) { async function validateAdd(req) {
/* account-level token can not be used to add accounts */ /* account-level token can not be used to add accounts */
if (req.user.hasAccountAuth) { if (req.user.hasAccountAuth) {
@@ -1168,45 +1142,6 @@ router.put('/:sid/Calls/:callSid', async(req, res) => {
/** /**
* create a new Message * create a new Message
*/ */
router.post('/:sid/Messages', async(req, res) => {
const {retrieveSet, logger} = req.app.locals;
try {
const account_sid = parseAccountSid(req);
await validateRequest(req, account_sid);
const setName = `${(process.env.JAMBONES_CLUSTER_ID || 'default')}:fs-service-url`;
const serviceUrl = await getFsUrl(logger, retrieveSet, setName);
if (!serviceUrl) {
return res.status(480).json({msg: 'no available feature servers at this time'});
}
await validateCreateMessage(logger, account_sid, req);
const payload = {
message_sid: uuidv4(),
account_sid,
...req.body
};
logger.debug({payload}, `sending createMessage API request to to ${serviceUrl}`);
updateLastUsed(logger, account_sid, req).catch(() => {});
const response = await fetch(serviceUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
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) {
sysError(logger, res, err);
}
});
/** /**
* retrieve info for a group of queues under an account * retrieve info for a group of queues under an account
*/ */
+1 -16
View File
@@ -2,7 +2,6 @@ const router = require('express').Router();
const PredefinedCarrier = require('../../models/predefined-carrier'); const PredefinedCarrier = require('../../models/predefined-carrier');
const VoipCarrier = require('../../models/voip-carrier'); const VoipCarrier = require('../../models/voip-carrier');
const SipGateway = require('../../models/sip-gateway'); const SipGateway = require('../../models/sip-gateway');
const SmppGateway = require('../../models/smpp-gateway');
const {parseServiceProviderSid} = require('./utils'); const {parseServiceProviderSid} = require('./utils');
const short = require('short-uuid'); const short = require('short-uuid');
const {promisePool} = require('../../db'); const {promisePool} = require('../../db');
@@ -12,9 +11,7 @@ const sysError = require('../error');
const sqlSelectCarrierByNameForSP = `SELECT * FROM voip_carriers const sqlSelectCarrierByNameForSP = `SELECT * FROM voip_carriers
WHERE service_provider_sid = ? WHERE service_provider_sid = ?
AND name = ?`; AND name = ?`;
const sqlSelectTemplateSipGateways = `SELECT * FROM predefined_sip_gateways const sqlSelectTemplateSipGateways = `SELECT * FROM predefined_sip_gateways
WHERE predefined_carrier_sid = ?`;
const sqlSelectTemplateSmppGateways = `SELECT * FROM predefined_smpp_gateways
WHERE predefined_carrier_sid = ?`; WHERE predefined_carrier_sid = ?`;
@@ -46,10 +43,6 @@ router.post('/:sid', async(req, res) => {
const [r3] = await promisePool.query(sqlSelectTemplateSipGateways, template.predefined_carrier_sid); const [r3] = await promisePool.query(sqlSelectTemplateSipGateways, template.predefined_carrier_sid);
logger.debug({r3}, `retrieved template sip gateways for ${template.name}`); logger.debug({r3}, `retrieved template sip gateways for ${template.name}`);
/* retrieve all the smpp gateways */
const [r4] = await promisePool.query(sqlSelectTemplateSmppGateways, template.predefined_carrier_sid);
logger.debug({r4}, `retrieved template smpp gateways for ${template.name}`);
/* add a voip_carrier */ /* add a voip_carrier */
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const {requires_static_ip, predefined_carrier_sid, ...obj} = template; const {requires_static_ip, predefined_carrier_sid, ...obj} = template;
@@ -63,14 +56,6 @@ router.post('/:sid', async(req, res) => {
await SipGateway.make({...obj, voip_carrier_sid: uuid}); await SipGateway.make({...obj, voip_carrier_sid: uuid});
} }
/* add all the smpp gateways */
for (const gw of r4) {
// eslint-disable-next-line no-unused-vars
const {predefined_carrier_sid, predefined_smpp_gateway_sid, ...obj} = gw;
logger.debug({obj}, 'adding smpp gateway');
await SmppGateway.make({...obj, voip_carrier_sid: uuid});
}
logger.debug({sid: uuid}, 'Successfully added carrier from predefined list'); logger.debug({sid: uuid}, 'Successfully added carrier from predefined list');
res.status(201).json({sid: uuid}); res.status(201).json({sid: uuid});
} catch (err) { } catch (err) {
+4 -11
View File
@@ -150,7 +150,7 @@ router.post('/', async(req, res) => {
// create webhooks if provided // create webhooks if provided
const obj = Object.assign({}, req.body); const obj = Object.assign({}, req.body);
for (const prop of ['call_hook', 'call_status_hook', 'messaging_hook']) { for (const prop of ['call_hook', 'call_status_hook']) {
if (obj[prop]) { if (obj[prop]) {
obj[`${prop}_sid`] = await Webhook.make(obj[prop]); obj[`${prop}_sid`] = await Webhook.make(obj[prop]);
delete obj[prop]; delete obj[prop];
@@ -248,8 +248,8 @@ router.delete('/:sid', async(req, res) => {
await validateDelete(req, sid); await validateDelete(req, sid);
const [application] = await promisePool.query('SELECT * FROM applications WHERE application_sid = ?', sid); const [application] = await promisePool.query('SELECT * FROM applications WHERE application_sid = ?', sid);
const {call_hook_sid, call_status_hook_sid, messaging_hook_sid} = application[0]; const {call_hook_sid, call_status_hook_sid} = application[0];
logger.info({call_hook_sid, call_status_hook_sid, messaging_hook_sid, sid}, 'deleting application'); logger.info({call_hook_sid, call_status_hook_sid, sid}, 'deleting application');
await promisePool.execute('DELETE from applications where application_sid = ?', [sid]); await promisePool.execute('DELETE from applications where application_sid = ?', [sid]);
if (call_hook_sid) { if (call_hook_sid) {
@@ -267,13 +267,6 @@ router.delete('/:sid', async(req, res) => {
await promisePool.execute('DELETE from webhooks where webhook_sid = ?', [call_status_hook_sid]); await promisePool.execute('DELETE from webhooks where webhook_sid = ?', [call_status_hook_sid]);
} }
} }
if (messaging_hook_sid) {
const sql = 'SELECT COUNT(*) as count FROM applications WHERE messaging_hook_sid = ?';
const [r] = await promisePool.query(sql, messaging_hook_sid);
if (r[0]?.count === 0) {
await promisePool.execute('DELETE from webhooks where webhook_sid = ?', [messaging_hook_sid]);
}
}
res.status(204).end(); res.status(204).end();
} catch (err) { } catch (err) {
@@ -292,7 +285,7 @@ router.put('/:sid', async(req, res) => {
// create webhooks if provided // create webhooks if provided
const obj = Object.assign({}, req.body); const obj = Object.assign({}, req.body);
for (const prop of ['call_hook', 'call_status_hook', 'messaging_hook']) { for (const prop of ['call_hook', 'call_status_hook']) {
if (prop in obj && Object.keys(obj[prop]).length) { if (prop in obj && Object.keys(obj[prop]).length) {
if ('webhook_sid' in obj[prop]) { if ('webhook_sid' in obj[prop]) {
const sid = obj[prop]['webhook_sid']; const sid = obj[prop]['webhook_sid'];
-6
View File
@@ -22,7 +22,6 @@ api.use('/ServiceProviders', require('./service-providers'));
api.use('/VoipCarriers', require('./voip-carriers')); api.use('/VoipCarriers', require('./voip-carriers'));
api.use('/Webhooks', require('./webhooks')); api.use('/Webhooks', require('./webhooks'));
api.use('/SipGateways', require('./sip-gateways')); api.use('/SipGateways', require('./sip-gateways'));
api.use('/SmppGateways', require('./smpp-gateways'));
api.use('/PhoneNumbers', require('./phone-numbers')); api.use('/PhoneNumbers', require('./phone-numbers'));
api.use('/ApiKeys', require('./api-keys')); api.use('/ApiKeys', require('./api-keys'));
api.use('/Accounts', require('./accounts')); api.use('/Accounts', require('./accounts'));
@@ -56,9 +55,4 @@ api.use('/Clients', require('./clients'));
// Google Custom Voices // Google Custom Voices
api.use('/GoogleCustomVoices', require('./google-custom-voices')); api.use('/GoogleCustomVoices', require('./google-custom-voices'));
// messaging
api.use('/Smpps', require('./smpps')); // our smpp server info
api.use('/messaging', require('./sms-inbound')); // inbound SMS from carrier
api.use('/outboundSMS', require('./sms-outbound')); // outbound SMS from feature server
module.exports = api; module.exports = api;
-7
View File
@@ -24,12 +24,6 @@ WHERE voip_carrier_sid IN (
FROM voip_carriers FROM voip_carriers
WHERE service_provider_sid = ? WHERE service_provider_sid = ?
)`; )`;
const sqlDeleteSmppGateways = `DELETE from smpp_gateways
WHERE voip_carrier_sid IN (
SELECT voip_carrier_sid
FROM voip_carriers
WHERE service_provider_sid = ?
)`;
/* only admin users can add a service provider */ /* only admin users can add a service provider */
function validateAdd(req) { function validateAdd(req) {
@@ -95,7 +89,6 @@ async function noActiveAccountsOrUsers(req, sid) {
/* ok we can delete -- no active accounts. remove carriers and speech credentials */ /* ok we can delete -- no active accounts. remove carriers and speech credentials */
await promisePool.execute('DELETE from speech_credentials WHERE service_provider_sid = ?', [sid]); await promisePool.execute('DELETE from speech_credentials WHERE service_provider_sid = ?', [sid]);
await promisePool.query(sqlDeleteSipGateways, [sid]); await promisePool.query(sqlDeleteSipGateways, [sid]);
await promisePool.query(sqlDeleteSmppGateways, [sid]);
await promisePool.query('DELETE from voip_carriers WHERE service_provider_sid = ?', [sid]); await promisePool.query('DELETE from voip_carriers WHERE service_provider_sid = ?', [sid]);
await promisePool.query('DELETE from api_keys WHERE service_provider_sid = ?', [sid]); await promisePool.query('DELETE from api_keys WHERE service_provider_sid = ?', [sid]);
} }
-77
View File
@@ -1,77 +0,0 @@
const router = require('express').Router();
const SmppGateway = require('../../models/smpp-gateway');
const {DbErrorBadRequest, DbErrorForbidden} = require('../../utils/errors');
const decorate = require('./decorate');
const sysError = require('../error');
const checkUserScope = async(req, voip_carrier_sid) => {
const {lookupCarrierBySid} = req.app.locals;
if (!voip_carrier_sid) {
throw new DbErrorBadRequest('missing voip_carrier_sid');
}
if (req.user.hasAdminAuth) return;
if (req.user.hasAccountAuth) {
const carrier = await lookupCarrierBySid(voip_carrier_sid);
if (!carrier) throw new DbErrorBadRequest('invalid voip_carrier_sid');
if ((!carrier.service_provider_sid || carrier.service_provider_sid === req.user.service_provider_sid) &&
(!carrier.account_sid || carrier.account_sid === req.user.account_sid)) {
return;
}
}
if (req.user.hasServiceProviderAuth) {
const carrier = await lookupCarrierBySid(voip_carrier_sid);
if (!carrier) throw new DbErrorBadRequest('invalid voip_carrier_sid');
if (carrier.service_provider_sid === req.user.service_provider_sid) {
return;
}
}
throw new DbErrorForbidden('insufficient privileges');
};
const validate = async(req, sid) => {
const {lookupSmppGatewayBySid} = req.app.locals;
let voip_carrier_sid;
if (sid) {
const gateway = await lookupSmppGatewayBySid(sid);
if (!gateway) throw new DbErrorBadRequest('invalid smpp_gateway_sid');
voip_carrier_sid = gateway.voip_carrier_sid;
}
else {
voip_carrier_sid = req.body.voip_carrier_sid;
if (!voip_carrier_sid) throw new DbErrorBadRequest('missing voip_carrier_sid');
}
await checkUserScope(req, voip_carrier_sid);
};
const preconditions = {
'add': validate,
'retrieve': validate,
'update': validate,
'delete': validate
};
decorate(router, SmppGateway, ['add', 'retrieve', 'update', 'delete'], preconditions);
/* list */
router.get('/', async(req, res) => {
const logger = req.app.locals.logger;
const voip_carrier_sid = req.query.voip_carrier_sid;
try {
await checkUserScope(req, voip_carrier_sid);
if (!voip_carrier_sid) {
logger.info('GET /SmppGateways missing voip_carrier_sid param');
return res.status(400).json({message: 'missing voip_carrier_sid query param'});
}
const results = await SmppGateway.retrieveForVoipCarrier(voip_carrier_sid);
res.status(200).json(results);
} catch (err) {
sysError(logger, res, err);
}
});
module.exports = router;
-30
View File
@@ -1,30 +0,0 @@
const router = require('express').Router();
const Smpp = require('../../models/smpp');
const decorate = require('./decorate');
const sysError = require('../error');
//const {DbErrorBadRequest} = require('../../utils/errors');
//const {promisePool} = require('../../db');
decorate(router, Smpp, ['add', 'delete']);
/* list */
router.get('/', async(req, res) => {
const logger = req.app.locals.logger;
try {
const service_provider_sid = req.query.service_provider_sid;
/*
if (req.user.hasAccountAuth) {
const [r] = await promisePool.query('SELECT * from accounts WHERE account_sid = ?', req.user.account_sid);
if (0 === r.length) throw new Error('invalid account_sid');
service_provider_sid = r[0].service_provider_sid;
}
if (!service_provider_sid) throw new DbErrorBadRequest('missing service_provider_sid in query');
*/
const results = await Smpp.retrieveAll(service_provider_sid);
res.status(200).json(results);
} catch (err) {
sysError(logger, res, err);
}
});
module.exports = router;
-142
View File
@@ -1,142 +0,0 @@
const router = require('express').Router();
const getProvider = require('../../utils/sms-provider');
const { v4: uuidv4 } = require('uuid');
const sysError = require('../error');
let idx = 0;
const getFsUrl = async(logger, retrieveSet, setName, provider) => {
if (process.env.K8S) return `http://${process.env.K8S_FEATURE_SERVER_SERVICE_NAME}:3000/v1/messaging/${provider}`;
try {
const fs = await retrieveSet(setName);
if (0 === fs.length) {
logger.info('No available feature servers to handle createCall API request');
return ;
}
const f = fs[idx++ % fs.length];
logger.info({fs}, `feature servers available for createCall API request, selecting ${f}`);
return `${f}/v1/messaging/${provider}`;
} catch (err) {
logger.error({err}, 'getFsUrl: error retreving feature servers from redis');
}
};
const doSendResponse = async(res, respondFn, body) => {
if (typeof respondFn === 'number') res.sendStatus(respondFn);
else if (typeof respondFn !== 'function') res.sendStatus(200);
else {
const payload = await respondFn(body);
res.status(200).json(payload);
}
};
router.post('/:provider', async(req, res) => {
const provider = req.params.provider;
const {
retrieveSet,
lookupAppByPhoneNumber,
logger
} = req.app.locals;
const setName = `${process.env.JAMBONES_CLUSTER_ID || 'default'}:fs-service-url`;
logger.debug({path: req.path, body: req.body}, 'incomingSMS from carrier');
// search for provider module
const arr = getProvider(logger, provider);
if (!arr) {
logger.info({body: req.body, params: req.params},
`rejecting incomingSms request from unknown provider ${provider}`
);
return res.sendStatus(404);
}
const providerData = arr[1];
if (!providerData || !providerData.module) {
logger.info({body: req.body, params: req.params},
`rejecting incomingSms request from badly configured provider ${provider}`
);
return res.sendStatus(404);
}
// load provider module
let filterFn, respondFn;
try {
const {
fromProviderFormat,
formatProviderResponse
} = require(providerData.module);
// must at least provide a filter function
if (!fromProviderFormat) {
logger.info(
`missing fromProviderFormat function in module ${providerData.module} for provider ${provider}`
);
return res.sendStatus(404);
}
filterFn = fromProviderFormat;
respondFn = formatProviderResponse;
} catch (err) {
logger.info(
err,
`failure loading module ${providerData.module} for provider ${provider}`
);
return res.sendStatus(500);
}
try {
const serviceUrl = await getFsUrl(logger, retrieveSet, setName, provider);
if (!serviceUrl) res.json({msg: 'no available feature servers at this time'}).status(480);
const messageSid = uuidv4();
const payload = await Promise.resolve(filterFn({messageSid}, req.body));
/**
* lookup the application associated with the number in the To field
* since there could be multiple Tos, we have to search through (and cc also)
*/
let app;
const to = Array.isArray(payload.to) ? payload.to : [payload.to];
const cc = Array.isArray(payload.cc) ? payload.cc : (payload.cc ? [payload.cc] : []);
const dids = to.concat(cc).filter((n) => n.length);
for (let did of dids) {
const regex = /^\+(\d+)$/;
const arr = regex.exec(did);
did = arr ? arr[1] : did;
const obj = await lookupAppByPhoneNumber(did);
logger.info({obj}, `lookup app for phone number ${did}`);
if (obj) {
logger.info({did, obj}, 'Found app for DID');
app = obj;
break;
}
}
if (!app) {
logger.info({payload}, 'No application found for incoming SMS');
return res.sendStatus(404);
}
if (!app.messaging_hook) {
logger.info({payload}, `app "${app.name}" found for incoming SMS does not have an associated messaging hook`);
return res.sendStatus(404);
}
payload.app = app;
logger.debug({body: req.body, payload}, 'filtered incoming SMS');
logger.info({payload, url: serviceUrl}, `sending incomingSms API request to FS at ${serviceUrl}`);
const response = await fetch(serviceUrl, {
method: 'POST',
body: JSON.stringify(payload),
headers: {'Content-Type': 'application/json'},
});
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) {
sysError(logger, res, err);
}
});
module.exports = router;
-44
View File
@@ -1,44 +0,0 @@
const router = require('express').Router();
const getProvider = require('../../utils/sms-provider');
const sysError = require('../error');
router.post('/', async(req, res) => {
const { logger } = req.app.locals;
try {
// if provider specified use it, otherwise use first in list
const arr = getProvider(logger, req.body.provider);
if (!Array.isArray(arr)) {
throw new Error('outboundSMS - unable to locate sms provider to use to send message');
}
const providerData = arr[1];
if (!providerData || !providerData.module) {
throw new Error(`rejecting outgoingSms request for unknown or badly configured provider ${req.body.provider}`);
}
const provider = arr[0];
const opts = providerData.options;
if (!opts || !opts.url) {
throw new Error(`rejecting outgoingSms request -- no HTTP url for ${req.body.provider}`);
}
// load provider module
const { sendSms } = require(providerData.module);
if (!sendSms) {
throw new Error(`missing sendSms function in module ${providerData.module} for provider ${provider}`);
}
// send the SMS
const payload = req.body;
delete payload.provider;
logger.debug({opts, payload}, `outboundSMS - sending to ${opts.url}`);
const response = await sendSms(opts, payload);
logger.info({response, payload: req.body}, `outboundSMS - sent to ${opts.url}`);
res.status(200).json(response);
} catch (err) {
sysError(logger, res, err);
}
});
module.exports = router;
+1 -2
View File
@@ -191,9 +191,8 @@ const validateDelete = async(req, sid) => {
const activeAccounts = await VoipCarrier.getForeignKeyReferences('phone_numbers.voip_carrier_sid', sid); const activeAccounts = await VoipCarrier.getForeignKeyReferences('phone_numbers.voip_carrier_sid', sid);
if (activeAccounts > 0) throw new DbErrorUnprocessableRequest('cannot delete voip carrier with active phone numbers'); if (activeAccounts > 0) throw new DbErrorUnprocessableRequest('cannot delete voip carrier with active phone numbers');
/* remove all the sip and smpp gateways from the carrier first */ /* remove all the sip gateways from the carrier first */
await promisePool.execute('DELETE FROM sip_gateways WHERE voip_carrier_sid = ?', [sid]); await promisePool.execute('DELETE FROM sip_gateways WHERE voip_carrier_sid = ?', [sid]);
await promisePool.execute('DELETE FROM smpp_gateways WHERE voip_carrier_sid = ?', [sid]);
}; };
const preconditions = { const preconditions = {
-290
View File
@@ -32,8 +32,6 @@ tags:
description: Voip Carriers operations description: Voip Carriers operations
- name: Sip Gateways - name: Sip Gateways
description: Sip Gateways operations description: Sip Gateways operations
- name: Smpp Gateways
description: Smpp Gateways operations
- name: Webhooks - name: Webhooks
description: Webhooks operations description: Webhooks operations
- name: Microsoft Teams Tenants - name: Microsoft Teams Tenants
@@ -221,46 +219,6 @@ paths:
description: sbc address deleted description: sbc address deleted
404: 404:
description: sbc address not found description: sbc address not found
/Smpps:
get:
summary: retrieve public IP addresses of the jambonz smpp servers
operationId: listSmpps
parameters:
- in: query
name: service_provider_sid
required: false
schema:
type: string
description: return only the smpp servers operated for the sole use of this service provider
responses:
200:
description: list of smpp server addresses
content:
application/json:
schema:
type: array
items:
properties:
ipv4:
type: string
description: ip address of one of our Sbcs
port:
type: number
use_tls:
type: boolean
is_primary:
type: boolean
required:
- ipv4
- port
- use_tls
- is_primary
500:
description: system error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
/InviteCodes: /InviteCodes:
post: post:
summary: validate an invite code summary: validate an invite code
@@ -1437,156 +1395,6 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/GeneralError' $ref: '#/components/schemas/GeneralError'
/SmppGateways:
post:
tags:
- Smpp Gateways
summary: create smpp gateway
operationId: createSmppGateway
requestBody:
content:
application/json:
schema:
type: object
properties:
voip_carrier_sid:
type: string
description: voip carrier that provides this gateway
format: uuid
ipv4:
type: string
port:
type: number
netmask:
type: number
inbound:
type: boolean
outbound:
type: boolean
is_primary:
type: boolean
use_tls:
type: boolean
required:
- voip_carrier_sid
- ipv4
responses:
201:
description: smpp gateway successfully created
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessfulAdd'
400:
description: bad request
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
422:
description: unprocessable entity
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
500:
description: system error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
get:
tags:
- Smpp Gateways
summary: list smpp gateways
operationId: listSmppGateways
responses:
200:
description: list of smpp gateways
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SmppGateway'
500:
description: system error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
/SmppGateways/{SmppGatewaySid}:
parameters:
- name: SmppGatewaySid
in: path
required: true
style: simple
explode: false
schema:
type: string
delete:
tags:
- Smpp Gateways
summary: delete a smpp gateway
operationId: deleteSmppGateway
responses:
204:
description: smpp gateway successfully deleted
404:
description: smpp gateway not found
500:
description: system error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
get:
tags:
- Smpp Gateways
summary: retrieve smpp gateway
operationId: getSmppGateway
responses:
200:
description: smpp gateway found
content:
application/json:
schema:
$ref: '#/components/schemas/SmppGateway'
404:
description: smpp gateway not found
500:
description: system error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
put:
tags:
- Smpp Gateways
summary: update smpp gateway
operationId: updateSmppGateway
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SmppGateway'
responses:
204:
description: smpp gateway updated
400:
description: bad request
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
404:
description: smpp gateway not found
500:
description: system error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
/PhoneNumbers: /PhoneNumbers:
post: post:
tags: tags:
@@ -3738,9 +3546,6 @@ paths:
call_status_hook: call_status_hook:
$ref: '#/components/schemas/Webhook' $ref: '#/components/schemas/Webhook'
description: webhook to report call status events description: webhook to report call status events
messaging_hook:
$ref: '#/components/schemas/Webhook'
description: application webhook to handle inbound SMS/MMS messages
app_json: app_json:
type: string type: string
description: Voice Application Json, call_hook will not be invoked if app_json is provided description: Voice Application Json, call_hook will not be invoked if app_json is provided
@@ -4217,56 +4022,6 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/GeneralError' $ref: '#/components/schemas/GeneralError'
/Accounts/{AccountSid}/Messages:
post:
tags:
- Accounts
summary: create an outgoing SMS message
operationId: createMessage
parameters:
- name: AccountSid
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
responses:
201:
description: call successfully created
content:
application/json:
schema:
required:
- sid
properties:
sid:
type: string
format: uuid
example: 2531329f-fb09-4ef7-887e-84e648214436
providerResponse:
type: string
480:
description: temporary failure
content:
application/json:
schema:
required:
- sid
properties:
sid:
type: string
format: uuid
example: 2531329f-fb09-4ef7-887e-84e648214436
message:
type: string
smpp_err_code:
type: string
400:
description: bad request
/Accounts/{AccountSid}/Queues: /Accounts/{AccountSid}/Queues:
parameters: parameters:
- name: AccountSid - name: AccountSid
@@ -5238,17 +4993,6 @@ components:
type: string type: string
is_active: is_active:
type: boolean type: boolean
smpp_system_id:
type: string
smpp_password:
type: string
smpp_inbound_system_id:
type: string
smpp_inbound_password:
type: string
smpp_enquire_link_interval:
type: number
format: integer
required: required:
- voip_carrier_sid - voip_carrier_sid
- name - name
@@ -5277,35 +5021,6 @@ components:
- ipv4 - ipv4
- port - port
- netmask - netmask
SmppGateway:
type: object
properties:
smpp_gateway_sid:
type: string
format: uuid
ipv4:
type: string
port:
type: number
netmask:
type: number
voip_carrier_sid:
type: string
format: uuid
is_primary:
type: boolean
use_tls:
type: boolean
inbound:
type: boolean
outbound:
type: boolean
required:
- smpp_gateway_sid
- voip_carrier_sid
- ipv4
- port
- netmask
Account: Account:
type: object type: object
properties: properties:
@@ -5346,9 +5061,6 @@ components:
call_status_hook: call_status_hook:
$ref: '#/components/schemas/Webhook' $ref: '#/components/schemas/Webhook'
description: webhhok for reporting call status events description: webhhok for reporting call status events
messaging_hook:
$ref: '#/components/schemas/Webhook'
description: application webhook for inbound SMS/MMS
speech_synthesis_vendor: speech_synthesis_vendor:
type: string type: string
speech_synthesis_voice: speech_synthesis_voice:
@@ -5681,8 +5393,6 @@ components:
type: string type: string
call_status_hook_sid: call_status_hook_sid:
type: string type: string
messaging_hook_sid:
type: string
speech_synthesis_vendor: speech_synthesis_vendor:
type: string type: string
speech_synthesis_language: speech_synthesis_language:
-40
View File
@@ -1,40 +0,0 @@
const providers = new Map();
let init = false;
function initProviders(logger) {
if (init) return;
if (process.env.JAMBONES_MESSAGING) {
try {
const obj = JSON.parse(process.env.JAMBONES_MESSAGING);
for (const [key, value] of Object.entries(obj)) {
logger.debug({config: value}, `Adding SMS provider ${key}`);
providers.set(key, value);
}
logger.info(`Configured ${providers.size} SMS providers`);
} catch (err) {
logger.error(err, `expected JSON for JAMBONES_MESSAGING : ${process.env.JAMBONES_MESSAGING}`);
}
}
else {
logger.info('no JAMBONES_MESSAGING env var, messaging is disabled');
}
init = true;
}
function getProvider(logger, partner) {
initProviders(logger);
if (typeof partner === 'string') {
const config = providers.get(partner);
const arr = [partner, config];
logger.debug({arr}, 'getProvider by name');
return arr;
}
else if (providers.size) {
const arr = providers.entries().next().value;
logger.debug({arr}, 'getProvider by first available');
return arr;
}
}
module.exports = getProvider;
+4 -4
View File
@@ -17,7 +17,7 @@
"@gladiaio/sdk": "^0.5.2", "@gladiaio/sdk": "^0.5.2",
"@google-cloud/speech": "^6.5.0", "@google-cloud/speech": "^6.5.0",
"@google-cloud/storage": "^7.9.0", "@google-cloud/storage": "^7.9.0",
"@jambonz/db-helpers": "^0.9.18", "@jambonz/db-helpers": "^0.9.22",
"@jambonz/lamejs": "^1.2.2", "@jambonz/lamejs": "^1.2.2",
"@jambonz/mw-registrar": "^0.2.7", "@jambonz/mw-registrar": "^0.2.7",
"@jambonz/realtimedb-helpers": "^0.8.21", "@jambonz/realtimedb-helpers": "^0.8.21",
@@ -2815,9 +2815,9 @@
} }
}, },
"node_modules/@jambonz/db-helpers": { "node_modules/@jambonz/db-helpers": {
"version": "0.9.18", "version": "0.9.22",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.18.tgz", "resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.22.tgz",
"integrity": "sha512-rrrBzz6UnEW0LV4OXRUzjg2XzwUGNjuJptKPxozvCQYOSuXQsRYcc7AM+p32ssBd+LdTX866pQ0QwRc2cUEAPw==", "integrity": "sha512-mgrK1LaxuUbEgmRL7TVJDRzXCpXLHFbCdNSW02rkbLG6EYGiH9KcquTf8b1frJY1IRVGEgwpmTYB4LR27c6TBw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"cidr-matcher": "^2.1.1", "cidr-matcher": "^2.1.1",
+1 -1
View File
@@ -30,7 +30,7 @@
"@gladiaio/sdk": "^0.5.2", "@gladiaio/sdk": "^0.5.2",
"@google-cloud/speech": "^6.5.0", "@google-cloud/speech": "^6.5.0",
"@google-cloud/storage": "^7.9.0", "@google-cloud/storage": "^7.9.0",
"@jambonz/db-helpers": "^0.9.18", "@jambonz/db-helpers": "^0.9.22",
"@jambonz/lamejs": "^1.2.2", "@jambonz/lamejs": "^1.2.2",
"@jambonz/mw-registrar": "^0.2.7", "@jambonz/mw-registrar": "^0.2.7",
"@jambonz/realtimedb-helpers": "^0.8.21", "@jambonz/realtimedb-helpers": "^0.8.21",
+2 -19
View File
@@ -41,9 +41,6 @@ test('application tests', async(t) => {
url: 'http://example.com/status', url: 'http://example.com/status',
method: 'POST' method: 'POST'
}, },
messaging_hook: {
url: 'http://example.com/sms'
},
app_json : '[\ app_json : '[\
{\ {\
"verb": "play",\ "verb": "play",\
@@ -71,9 +68,6 @@ test('application tests', async(t) => {
url: 'http://example.com/status', url: 'http://example.com/status',
method: 'POST' method: 'POST'
}, },
messaging_hook: {
url: 'http://example.com/sms'
},
app_json : '[\ app_json : '[\
{\ {\
"verb": "play",\ "verb": "play",\
@@ -110,7 +104,6 @@ test('application tests', async(t) => {
json: true, json: true,
}); });
t.ok(result.name === 'daveh' , 'successfully retrieved application by sid'); t.ok(result.name === 'daveh' , 'successfully retrieved application by sid');
t.ok(result.messaging_hook.url === 'http://example.com/sms' , 'successfully retrieved messaging_hook from application');
t.ok(result.use_for_fallback_speech === 1, 'successfully create use_for_fallback_speech'); t.ok(result.use_for_fallback_speech === 1, 'successfully create use_for_fallback_speech');
t.ok(result.fallback_speech_synthesis_vendor === 'google', 'successfully create fallback_speech_synthesis_vendor'); t.ok(result.fallback_speech_synthesis_vendor === 'google', 'successfully create fallback_speech_synthesis_vendor');
t.ok(result.fallback_speech_synthesis_language === 'en-US', 'successfully create fallback_speech_synthesis_language'); t.ok(result.fallback_speech_synthesis_language === 'en-US', 'successfully create fallback_speech_synthesis_language');
@@ -151,9 +144,6 @@ test('application tests', async(t) => {
call_hook: { call_hook: {
url: 'http://example2.com' url: 'http://example2.com'
}, },
messaging_hook: {
url: 'http://example2.com/mms'
},
app_json : '[\ app_json : '[\
{\ {\
"verb": "hangup",\ "verb": "hangup",\
@@ -175,12 +165,11 @@ test('application tests', async(t) => {
}); });
t.ok(result.statusCode === 204, 'successfully updated application'); t.ok(result.statusCode === 204, 'successfully updated application');
/* validate messaging hook was updated */ /* validate application was updated */
result = await request.get(`/Applications/${sid}`, { result = await request.get(`/Applications/${sid}`, {
auth: authAdmin, auth: authAdmin,
json: true, json: true,
}); });
t.ok(result.messaging_hook.url === 'http://example2.com/mms' , 'successfully updated messaging_hook');
app_json = JSON.parse(result.app_json); app_json = JSON.parse(result.app_json);
t.ok(app_json[0].verb === 'hangup', 'successfully updated app_json from application') t.ok(app_json[0].verb === 'hangup', 'successfully updated app_json from application')
t.ok(result.record_all_calls === 1, 'successfully updated record_all_calls from application') t.ok(result.record_all_calls === 1, 'successfully updated record_all_calls from application')
@@ -202,15 +191,12 @@ test('application tests', async(t) => {
call_hook: { call_hook: {
url: 'http://example2.com' url: 'http://example2.com'
}, },
messaging_hook: {
url: 'http://example2.com/mms'
},
app_json : null app_json : null
} }
}); });
t.ok(result.statusCode === 204, 'successfully updated application'); t.ok(result.statusCode === 204, 'successfully updated application');
/* validate messaging hook was updated */ /* validate app_json was removed */
result = await request.get(`/Applications/${sid}`, { result = await request.get(`/Applications/${sid}`, {
auth: authAdmin, auth: authAdmin,
json: true, json: true,
@@ -227,9 +213,6 @@ test('application tests', async(t) => {
call_hook: { call_hook: {
url: 'http://example2.com' url: 'http://example2.com'
}, },
messaging_hook: {
url: 'http://example2.com/mms'
},
app_json : '[\ app_json : '[\
{\ {\
"verb": "play",\ "verb": "play",\
-3
View File
@@ -125,9 +125,6 @@ let result = await request.post('/Applications', {
url: 'http://example.com/status', url: 'http://example.com/status',
method: 'POST' method: 'POST'
}, },
messaging_hook: {
url: 'http://example.com/sms'
},
app_json app_json
} }
}); });
-1
View File
@@ -1,7 +1,6 @@
require('./docker_start'); require('./docker_start');
require('./create-test-db'); require('./create-test-db');
require('./sip-gateways'); require('./sip-gateways');
require('./smpp-gateways');
require('./service-providers'); require('./service-providers');
require('./voip-carriers'); require('./voip-carriers');
require('./accounts'); require('./accounts');
-90
View File
@@ -1,90 +0,0 @@
const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN};
const { createClient } = require('./http-client');
const request = createClient({
baseUrl: 'http://127.0.0.1:3000/v1'
});
const {createVoipCarrier, deleteObjectBySid} = require('./utils');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
test('smpp gateway tests', async(t) => {
const app = require('../app');
let sid;
try {
let result;
const voip_carrier_sid = await createVoipCarrier(request);
/* add a smpp gateway */
result = await request.post('/SmppGateways', {
resolveWithFullResponse: true,
auth: authAdmin,
json: true,
body: {
voip_carrier_sid,
ipv4: '192.168.1.1',
netmask: 32,
inbound: true,
outbound: true,
use_tls: true,
is_primary: true
}
});
t.ok(result.statusCode === 201, 'successfully created smpp gateway ');
const sid = result.body.sid;
/* query all smpp gateways */
console.log('querying with ')
result = await request.get('/SmppGateways', {
qs: {voip_carrier_sid},
auth: authAdmin,
json: true,
});
t.ok(result.length === 1 , 'successfully queried all smpp gateways');
/* query one smpp gateway */
result = await request.get(`/SmppGateways/${sid}`, {
auth: authAdmin,
json: true,
});
//console.log(`result: ${JSON.stringify(result)}`);
t.ok(result.ipv4 === '192.168.1.1' , 'successfully retrieved voip carrier by sid');
/* update smpp gateway */
result = await request.put(`/SmppGateways/${sid}`, {
auth: authAdmin,
json: true,
resolveWithFullResponse: true,
body: {
port: 5061,
netmask:24,
outbound: false
}
});
t.ok(result.statusCode === 204, 'successfully updated voip carrier');
/* delete smpp gatewas */
result = await request.delete(`/SmppGateways/${sid}`, {
resolveWithFullResponse: true,
simple: false,
json: true,
auth: authAdmin
});
//console.log(`result: ${JSON.stringify(result)}`);
t.ok(result.statusCode === 204, 'successfully deleted smpp gateway');
await deleteObjectBySid(request, '/VoipCarriers', voip_carrier_sid);
//t.end();
}
catch (err) {
console.error(err);
t.end(err);
}
});
-6
View File
@@ -180,9 +180,6 @@ test('view-only user tests', async(t) => {
url: 'http://example.com/status', url: 'http://example.com/status',
method: 'POST' method: 'POST'
}, },
messaging_hook: {
url: 'http://example.com/sms'
},
app_json : '[\ app_json : '[\
{\ {\
"verb": "play",\ "verb": "play",\
@@ -241,9 +238,6 @@ test('view-only user tests', async(t) => {
url: 'http://example.com/status', url: 'http://example.com/status',
method: 'POST' method: 'POST'
}, },
messaging_hook: {
url: 'http://example.com/sms'
},
app_json : '[\ app_json : '[\
{\ {\
"verb": "play",\ "verb": "play",\
-41
View File
@@ -439,39 +439,6 @@ test('webapp tests', async(t) => {
}); });
t.ok(result.statusCode === 204, 'successfully deleted sip gateway for BYOC carrier'); t.ok(result.statusCode === 204, 'successfully deleted sip gateway for BYOC carrier');
/* add a smpp gateway to the carrier */
result = await request.post('/SmppGateways', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
voip_carrier_sid: carrier_sid,
ipv4: '192.168.1.1',
inbound: true,
outbound: true
}
});
t.ok(result.statusCode === 201, 'successfully created smpp gateway for BYOC carrier');
gateway_sid = result.body.sid;
/* update smpp gateway */
result = await request.put(`/SmppGateways/${gateway_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
port: 5080
}
});
t.ok(result.statusCode === 204, 'successfully updated smpp gateway for BYOC carrier');
/* delete smpp gateway */
result = await request.delete(`/SmppGateways/${gateway_sid}`, {
resolveWithFullResponse: true,
auth: authUser,
});
t.ok(result.statusCode === 204, 'successfully deleted smpp gateway for BYOC carrier');
result = await request.get('/Sbcs', { result = await request.get('/Sbcs', {
resolveWithFullResponse: true, resolveWithFullResponse: true,
auth: authUser, auth: authUser,
@@ -479,14 +446,6 @@ test('webapp tests', async(t) => {
}); });
//console.log(result.body); //console.log(result.body);
t.ok(result.statusCode === 200 && result.body.length === 1, 'retrieve Sbcs'); t.ok(result.statusCode === 200 && result.body.length === 1, 'retrieve Sbcs');
result = await request.get('/Smpps', {
resolveWithFullResponse: true,
auth: authUser,
json: true,
});
//console.log(result.body);
t.ok(result.statusCode === 200 && result.body.length === 2, 'retrieve Smpps');
/* delete account */ /* delete account */
result = await request.delete(`/Accounts/${account_sid}`, { result = await request.delete(`/Accounts/${account_sid}`, {