@zi2/relay-sdk 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as DatabaseAdapter, P as PhoneRelayRecord, c as CreateRelayInput, d as PhoneRelayPairingRecord, e as CreatePairingInput, R as RelayMessageRecord, f as CreateMessageInput } from '../types-
|
|
1
|
+
import { D as DatabaseAdapter, P as PhoneRelayRecord, c as CreateRelayInput, d as PhoneRelayPairingRecord, e as CreatePairingInput, R as RelayMessageRecord, f as CreateMessageInput } from '../types-sIoVYfJj.js';
|
|
2
2
|
import 'ws';
|
|
3
3
|
|
|
4
4
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as EncryptionAdapter, B as BroadcastAdapter, L as LoggerAdapter, A as AuditAdapter, a as AuditEntry, D as DatabaseAdapter, S as SmsProviderAdapter, b as SmsSendResponse, F as FallbackConfig, C as ConnectionBroker, P as PhoneRelayRecord, c as CreateRelayInput, d as PhoneRelayPairingRecord, e as CreatePairingInput, R as RelayMessageRecord, f as CreateMessageInput, g as RelaySDKConfig, h as RelaySDK } from './types-
|
|
2
|
-
export { M as MessageList, i as PairingCompleteResult, j as PairingResult, k as RelayDetail, l as RelayListItem, m as SendResult } from './types-
|
|
1
|
+
import { E as EncryptionAdapter, B as BroadcastAdapter, L as LoggerAdapter, A as AuditAdapter, a as AuditEntry, D as DatabaseAdapter, S as SmsProviderAdapter, b as SmsSendResponse, F as FallbackConfig, C as ConnectionBroker, P as PhoneRelayRecord, c as CreateRelayInput, d as PhoneRelayPairingRecord, e as CreatePairingInput, R as RelayMessageRecord, f as CreateMessageInput, g as RelaySDKConfig, h as RelaySDK } from './types-sIoVYfJj.js';
|
|
2
|
+
export { M as MessageList, i as PairingCompleteResult, j as PairingResult, k as RelayDetail, l as RelayListItem, m as SendResult } from './types-sIoVYfJj.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { WebSocket } from 'ws';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -326,9 +326,17 @@ function createPairingService(deps) {
|
|
|
326
326
|
const sharedKey = deriveSharedKey(serverPrivateKey, devicePublicKey);
|
|
327
327
|
const authToken = generateSecureToken(64);
|
|
328
328
|
const authTokenHashed = hashToken(authToken);
|
|
329
|
+
const existingRelays = await db.findRelays(pairing.organizationId, "revoked");
|
|
330
|
+
let uniqueName = deviceName;
|
|
331
|
+
const existingNames = existingRelays.map((r) => r.deviceName);
|
|
332
|
+
if (existingNames.includes(uniqueName)) {
|
|
333
|
+
let counter = 2;
|
|
334
|
+
while (existingNames.includes(`${deviceName} (${counter})`)) counter++;
|
|
335
|
+
uniqueName = `${deviceName} (${counter})`;
|
|
336
|
+
}
|
|
329
337
|
const relay = await db.createRelay({
|
|
330
338
|
organizationId: pairing.organizationId,
|
|
331
|
-
deviceName,
|
|
339
|
+
deviceName: uniqueName,
|
|
332
340
|
platform,
|
|
333
341
|
phoneNumber: phoneNumber || null,
|
|
334
342
|
devicePublicKey,
|
|
@@ -348,7 +356,7 @@ function createPairingService(deps) {
|
|
|
348
356
|
});
|
|
349
357
|
await db.updatePairingStatus(pairingId, RELAY_PAIRING_STATUS.COMPLETED);
|
|
350
358
|
try {
|
|
351
|
-
await deps.onPairingComplete?.({ relayId: relay.id, orgId: pairing.organizationId, deviceName, phoneNumber });
|
|
359
|
+
await deps.onPairingComplete?.({ relayId: relay.id, orgId: pairing.organizationId, deviceName: uniqueName, phoneNumber });
|
|
352
360
|
} catch (err) {
|
|
353
361
|
deps.logger.error("onPairingComplete callback failed", { relayId: relay.id, error: String(err) });
|
|
354
362
|
}
|
|
@@ -2446,6 +2454,38 @@ function createRelay(config) {
|
|
|
2446
2454
|
async sendSMS(options) {
|
|
2447
2455
|
return queue.enqueueAndWait(options);
|
|
2448
2456
|
},
|
|
2457
|
+
async sendSMSToOrg(options) {
|
|
2458
|
+
const { orgId, to, body, timeoutMs } = options;
|
|
2459
|
+
const allRelays = await config.db.findRelays(orgId, "revoked");
|
|
2460
|
+
const activeRelays = allRelays.filter((r) => r.status === "active" || r.status === "degraded");
|
|
2461
|
+
if (activeRelays.length === 0) {
|
|
2462
|
+
throw new Error("No active relays available for this organization");
|
|
2463
|
+
}
|
|
2464
|
+
const todayUTC = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2465
|
+
const onlineRelays = activeRelays.filter((r) => isRelayOnline(r.id));
|
|
2466
|
+
const offlineRelays = activeRelays.filter((r) => !isRelayOnline(r.id));
|
|
2467
|
+
const sortedOnline = [...onlineRelays].sort((a, b) => {
|
|
2468
|
+
const aDaily = a.dailyResetAt && a.dailyResetAt.toISOString().slice(0, 10) === todayUTC ? a.dailySmsSent : 0;
|
|
2469
|
+
const bDaily = b.dailyResetAt && b.dailyResetAt.toISOString().slice(0, 10) === todayUTC ? b.dailySmsSent : 0;
|
|
2470
|
+
return aDaily - bDaily;
|
|
2471
|
+
});
|
|
2472
|
+
const sortedOffline = [...offlineRelays].sort((a, b) => {
|
|
2473
|
+
const aTime = a.lastSeenAt ? a.lastSeenAt.getTime() : 0;
|
|
2474
|
+
const bTime = b.lastSeenAt ? b.lastSeenAt.getTime() : 0;
|
|
2475
|
+
return bTime - aTime;
|
|
2476
|
+
});
|
|
2477
|
+
const candidates = [...sortedOnline, ...sortedOffline];
|
|
2478
|
+
let lastError;
|
|
2479
|
+
for (const candidate of candidates) {
|
|
2480
|
+
try {
|
|
2481
|
+
return await queue.enqueueAndWait({ relayId: candidate.id, orgId, to, body, timeoutMs });
|
|
2482
|
+
} catch (err) {
|
|
2483
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
2484
|
+
logger.warn("sendSMSToOrg: relay failed, trying next", { relayId: candidate.id, error: lastError.message });
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
throw lastError || new Error("All relays failed");
|
|
2488
|
+
},
|
|
2449
2489
|
async getMessages(relayId, orgId, limit = 50, offset = 0) {
|
|
2450
2490
|
const relay = await config.db.findRelay(relayId, orgId);
|
|
2451
2491
|
if (!relay) throw new Error("Relay not found");
|
|
@@ -263,6 +263,12 @@ interface RelaySDK {
|
|
|
263
263
|
body: string;
|
|
264
264
|
timeoutMs?: number;
|
|
265
265
|
}): Promise<SendResult>;
|
|
266
|
+
sendSMSToOrg(options: {
|
|
267
|
+
orgId: string;
|
|
268
|
+
to: string;
|
|
269
|
+
body: string;
|
|
270
|
+
timeoutMs?: number;
|
|
271
|
+
}): Promise<SendResult>;
|
|
266
272
|
getMessages(relayId: string, orgId: string, limit?: number, offset?: number): Promise<MessageList>;
|
|
267
273
|
isRelayOnline(relayId: string): boolean;
|
|
268
274
|
getRelaySocket(relayId: string): WebSocket | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zi2/relay-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Enterprise SMS relay SDK with E2E encryption, provider fallback, and PCI DSS v4 compliance",
|
|
5
5
|
"author": "Zenith Intelligence Technologies <dev@zisquare.app>",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|