fix(sms): stop sending platform to the relay gateway
With platform "kave" (Kavenegar) the gateway answered "cURL library is not
loaded" and nothing was delivered. The body is now { phone, host, text } and
the gateway picks the line itself. SMS_RELAY_PLATFORM is removed from the
driver, docker-compose and the env examples.
Tests: sms.service.spec updated. 150 tests pass.
پیامک بدون انتخاب خط کاوهنگار فرستاده میشود و سرویس پیامک خودش خط را انتخاب میکند.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -130,8 +130,6 @@ SMS_RELAY_SECRET=
|
|||||||
# The "host" field. Blank sends this machine's first external IPv4 — inside
|
# The "host" field. Blank sends this machine's first external IPv4 — inside
|
||||||
# Docker that is the container's address.
|
# Docker that is the container's address.
|
||||||
SMS_RELAY_HOST=
|
SMS_RELAY_HOST=
|
||||||
# "kave" (default, Kavenegar) or "default" to let the gateway pick the line.
|
|
||||||
SMS_RELAY_PLATFORM=
|
|
||||||
# trez — only used with SMS_PROVIDER=trez. Never commit real values.
|
# trez — only used with SMS_PROVIDER=trez. Never commit real values.
|
||||||
# Override only for staging; defaults to the provider's live endpoint.
|
# Override only for staging; defaults to the provider's live endpoint.
|
||||||
SMS_TREZ_URL=
|
SMS_TREZ_URL=
|
||||||
|
|||||||
+2
-2
@@ -208,8 +208,8 @@ container.
|
|||||||
`SMS_PROVIDER`: `relay` (default), `trez`, or `none` (D26).
|
`SMS_PROVIDER`: `relay` (default), `trez`, or `none` (D26).
|
||||||
|
|
||||||
- **relay**: `SMS_RELAY_URL`, `SMS_RELAY_SECRET` (both have built-in
|
- **relay**: `SMS_RELAY_URL`, `SMS_RELAY_SECRET` (both have built-in
|
||||||
defaults), `SMS_RELAY_HOST` (blank = the machine's first external IPv4),
|
defaults), `SMS_RELAY_HOST` (blank = the machine's first external IPv4).
|
||||||
`SMS_RELAY_PLATFORM` (`kave` default, or `default` to let the gateway pick).
|
No `platform` is sent; the gateway picks the line.
|
||||||
- **trez**: `SMS_TREZ_URL`, `SMS_TREZ_USERNAME`, `SMS_TREZ_PASSWORD`,
|
- **trez**: `SMS_TREZ_URL`, `SMS_TREZ_USERNAME`, `SMS_TREZ_PASSWORD`,
|
||||||
`SMS_TREZ_SENDER_LINE`.
|
`SMS_TREZ_SENDER_LINE`.
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ SMS_RELAY_SECRET=
|
|||||||
# Docker it is the container's 172.x), the public IP is looked up once at boot.
|
# Docker it is the container's 172.x), the public IP is looked up once at boot.
|
||||||
# Setting it explicitly on the server is the surest; the boot log shows the value.
|
# Setting it explicitly on the server is the surest; the boot log shows the value.
|
||||||
SMS_RELAY_HOST=
|
SMS_RELAY_HOST=
|
||||||
# "kave" (default, Kavenegar) or "default" to let the gateway pick the line.
|
|
||||||
SMS_RELAY_PLATFORM=
|
|
||||||
# trez — only used with SMS_PROVIDER=trez.
|
# trez — only used with SMS_PROVIDER=trez.
|
||||||
# Defaults to the reference endpoint when unset; override for staging.
|
# Defaults to the reference endpoint when unset; override for staging.
|
||||||
SMS_TREZ_URL=
|
SMS_TREZ_URL=
|
||||||
|
|||||||
@@ -87570,7 +87570,6 @@ var require_relay_driver = __commonJS({
|
|||||||
var sms_driver_1 = require_sms_driver();
|
var sms_driver_1 = require_sms_driver();
|
||||||
var DEFAULT_RELAY_URL = "http://185.231.112.101/api/createsms";
|
var DEFAULT_RELAY_URL = "http://185.231.112.101/api/createsms";
|
||||||
var DEFAULT_RELAY_SECRET = "f21debfb-83ac-4624-a2f4-f08375043181";
|
var DEFAULT_RELAY_SECRET = "f21debfb-83ac-4624-a2f4-f08375043181";
|
||||||
var DEFAULT_RELAY_PLATFORM = "kave";
|
|
||||||
var REQUEST_TIMEOUT_MS = 15e3;
|
var REQUEST_TIMEOUT_MS = 15e3;
|
||||||
function serverIpv4() {
|
function serverIpv4() {
|
||||||
for (const addresses of Object.values((0, node_os_1.networkInterfaces)())) {
|
for (const addresses of Object.values((0, node_os_1.networkInterfaces)())) {
|
||||||
@@ -87609,13 +87608,10 @@ var require_relay_driver = __commonJS({
|
|||||||
publicIpv4 = null;
|
publicIpv4 = null;
|
||||||
}
|
}
|
||||||
function relayConfig() {
|
function relayConfig() {
|
||||||
const platform = (0, env_12.envOr)("SMS_RELAY_PLATFORM", DEFAULT_RELAY_PLATFORM);
|
|
||||||
return {
|
return {
|
||||||
url: (0, env_12.envOr)("SMS_RELAY_URL", DEFAULT_RELAY_URL),
|
url: (0, env_12.envOr)("SMS_RELAY_URL", DEFAULT_RELAY_URL),
|
||||||
secret: (0, env_12.envOr)("SMS_RELAY_SECRET", DEFAULT_RELAY_SECRET),
|
secret: (0, env_12.envOr)("SMS_RELAY_SECRET", DEFAULT_RELAY_SECRET),
|
||||||
host: (0, env_12.envOrNull)("SMS_RELAY_HOST") ?? publicIpv4 ?? serverIpv4(),
|
host: (0, env_12.envOrNull)("SMS_RELAY_HOST") ?? publicIpv4 ?? serverIpv4()
|
||||||
// "default" sends null, so the gateway chooses the line itself.
|
|
||||||
platform: platform.toLowerCase() === "default" ? null : platform
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function relayRejection(body) {
|
function relayRejection(body) {
|
||||||
@@ -87649,7 +87645,7 @@ var require_relay_driver = __commonJS({
|
|||||||
async deliver(mobile, text) {
|
async deliver(mobile, text) {
|
||||||
await resolveRelayHost();
|
await resolveRelayHost();
|
||||||
const c = relayConfig();
|
const c = relayConfig();
|
||||||
const reply = await (0, sms_driver_1.postWithTimeout)(c.url, { "Content-Type": "application/json", secret_key: c.secret }, JSON.stringify({ phone: mobile, host: c.host, text, platform: c.platform }), REQUEST_TIMEOUT_MS);
|
const reply = await (0, sms_driver_1.postWithTimeout)(c.url, { "Content-Type": "application/json", secret_key: c.secret }, JSON.stringify({ phone: mobile, host: c.host, text }), REQUEST_TIMEOUT_MS);
|
||||||
if (!reply.ok)
|
if (!reply.ok)
|
||||||
return { ok: false, response: reply.body, error: `http-${reply.status}` };
|
return { ok: false, response: reply.body, error: `http-${reply.status}` };
|
||||||
const rejection = relayRejection(reply.body);
|
const rejection = relayRejection(reply.body);
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import { SmsDriver, postWithTimeout } from './sms-driver';
|
|||||||
*
|
*
|
||||||
* Shape, from the owner's PHP client:
|
* Shape, from the owner's PHP client:
|
||||||
* * POST JSON, 15s timeout, auth header `secret_key`
|
* * POST JSON, 15s timeout, auth header `secret_key`
|
||||||
* * body: { phone, host, text, platform }
|
* * body: { phone, host, text }
|
||||||
* * `host` identifies the sending server: a configured value, else the
|
* * `host` identifies the sending server: a configured value, else the
|
||||||
* server's own IP (`gethostbyname(gethostname())`)
|
* server's own IP (`gethostbyname(gethostname())`)
|
||||||
* * `platform: "kave"` routes through Kavenegar; null lets the gateway pick.
|
* * no `platform`: the gateway picks the line itself. Sending
|
||||||
* The owner wants every message through Kavenegar.
|
* `platform: "kave"` (Kavenegar) failed on the gateway with
|
||||||
|
* "cURL library is not loaded".
|
||||||
*
|
*
|
||||||
* The secret is in source on the owner's decision (D26): the gateway has a
|
* The secret is in source on the owner's decision (D26): the gateway has a
|
||||||
* second verification factor held elsewhere. `SMS_RELAY_SECRET` overrides it.
|
* second verification factor held elsewhere. `SMS_RELAY_SECRET` overrides it.
|
||||||
@@ -24,8 +25,6 @@ import { SmsDriver, postWithTimeout } from './sms-driver';
|
|||||||
|
|
||||||
const DEFAULT_RELAY_URL = 'http://185.231.112.101/api/createsms';
|
const DEFAULT_RELAY_URL = 'http://185.231.112.101/api/createsms';
|
||||||
const DEFAULT_RELAY_SECRET = 'f21debfb-83ac-4624-a2f4-f08375043181';
|
const DEFAULT_RELAY_SECRET = 'f21debfb-83ac-4624-a2f4-f08375043181';
|
||||||
const DEFAULT_RELAY_PLATFORM = 'kave';
|
|
||||||
|
|
||||||
/** `Http::timeout(15)` in the owner's client. */
|
/** `Http::timeout(15)` in the owner's client. */
|
||||||
const REQUEST_TIMEOUT_MS = 15_000;
|
const REQUEST_TIMEOUT_MS = 15_000;
|
||||||
|
|
||||||
@@ -79,13 +78,10 @@ export function resetRelayHostCache() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function relayConfig() {
|
export function relayConfig() {
|
||||||
const platform = envOr('SMS_RELAY_PLATFORM', DEFAULT_RELAY_PLATFORM);
|
|
||||||
return {
|
return {
|
||||||
url: envOr('SMS_RELAY_URL', DEFAULT_RELAY_URL),
|
url: envOr('SMS_RELAY_URL', DEFAULT_RELAY_URL),
|
||||||
secret: envOr('SMS_RELAY_SECRET', DEFAULT_RELAY_SECRET),
|
secret: envOr('SMS_RELAY_SECRET', DEFAULT_RELAY_SECRET),
|
||||||
host: envOrNull('SMS_RELAY_HOST') ?? publicIpv4 ?? serverIpv4(),
|
host: envOrNull('SMS_RELAY_HOST') ?? publicIpv4 ?? serverIpv4(),
|
||||||
// "default" sends null, so the gateway chooses the line itself.
|
|
||||||
platform: platform.toLowerCase() === 'default' ? null : platform,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +133,7 @@ export const relayDriver: SmsDriver = {
|
|||||||
const reply = await postWithTimeout(
|
const reply = await postWithTimeout(
|
||||||
c.url,
|
c.url,
|
||||||
{ 'Content-Type': 'application/json', secret_key: c.secret },
|
{ 'Content-Type': 'application/json', secret_key: c.secret },
|
||||||
JSON.stringify({ phone: mobile, host: c.host, text, platform: c.platform }),
|
JSON.stringify({ phone: mobile, host: c.host, text }),
|
||||||
REQUEST_TIMEOUT_MS,
|
REQUEST_TIMEOUT_MS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -75,12 +75,11 @@ describe('SMS configuration', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('relay', () => {
|
describe('relay', () => {
|
||||||
it('works out of the box, sending through Kavenegar', () => {
|
it('works out of the box', () => {
|
||||||
process.env.SMS_RELAY_HOST = '10.0.0.5';
|
process.env.SMS_RELAY_HOST = '10.0.0.5';
|
||||||
const c = relayConfig();
|
const c = relayConfig();
|
||||||
expect(c.url).toBe('http://185.231.112.101/api/createsms');
|
expect(c.url).toBe('http://185.231.112.101/api/createsms');
|
||||||
expect(c.secret).toBeTruthy();
|
expect(c.secret).toBeTruthy();
|
||||||
expect(c.platform).toBe('kave');
|
|
||||||
expect(smsConfigured()).toBe(true);
|
expect(smsConfigured()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -97,11 +96,6 @@ describe('SMS configuration', () => {
|
|||||||
expect(relayConfig().host).toBe('gold.example');
|
expect(relayConfig().host).toBe('gold.example');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sends platform null when SMS_RELAY_PLATFORM=default', () => {
|
|
||||||
process.env.SMS_RELAY_PLATFORM = 'default';
|
|
||||||
expect(relayConfig().platform).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is not configured, and warns by name, when no host can be found', () => {
|
it('is not configured, and warns by name, when no host can be found', () => {
|
||||||
noExternalIp();
|
noExternalIp();
|
||||||
expect(smsConfigured()).toBe(false);
|
expect(smsConfigured()).toBe(false);
|
||||||
@@ -232,7 +226,6 @@ describe('SmsService.send', () => {
|
|||||||
phone: '09120000000',
|
phone: '09120000000',
|
||||||
host: '10.0.0.5',
|
host: '10.0.0.5',
|
||||||
text: 'سلام',
|
text: 'سلام',
|
||||||
platform: 'kave',
|
|
||||||
});
|
});
|
||||||
expect(create).toHaveBeenCalledWith({
|
expect(create).toHaveBeenCalledWith({
|
||||||
data: expect.objectContaining({ recipients: '09120000000', body: 'سلام' }),
|
data: expect.objectContaining({ recipients: '09120000000', body: 'سلام' }),
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ services:
|
|||||||
- SMS_RELAY_URL=${SMS_RELAY_URL:-}
|
- SMS_RELAY_URL=${SMS_RELAY_URL:-}
|
||||||
- SMS_RELAY_SECRET=${SMS_RELAY_SECRET:-}
|
- SMS_RELAY_SECRET=${SMS_RELAY_SECRET:-}
|
||||||
- SMS_RELAY_HOST=${SMS_RELAY_HOST:-}
|
- SMS_RELAY_HOST=${SMS_RELAY_HOST:-}
|
||||||
- SMS_RELAY_PLATFORM=${SMS_RELAY_PLATFORM:-}
|
|
||||||
- SMS_TREZ_URL=${SMS_TREZ_URL:-}
|
- SMS_TREZ_URL=${SMS_TREZ_URL:-}
|
||||||
- SMS_TREZ_USERNAME=${SMS_TREZ_USERNAME:-}
|
- SMS_TREZ_USERNAME=${SMS_TREZ_USERNAME:-}
|
||||||
- SMS_TREZ_PASSWORD=${SMS_TREZ_PASSWORD:-}
|
- SMS_TREZ_PASSWORD=${SMS_TREZ_PASSWORD:-}
|
||||||
|
|||||||
Reference in New Issue
Block a user