@absolutejs/voice 0.0.22-beta.272 → 0.0.22-beta.274

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.
package/dist/index.d.ts CHANGED
@@ -159,11 +159,13 @@ export type { VoiceS3ReviewStoreClient, VoiceS3ReviewStoreFile, VoiceS3ReviewSto
159
159
  export type { VoiceSQLiteRuntimeStorage, VoiceSQLiteStoreOptions } from './sqliteStore';
160
160
  export type { StoredVoiceIntegrationEvent, StoredVoiceExternalObjectMap, StoredVoiceOpsTask, VoiceExternalObjectMap, VoiceExternalObjectMapStore, VoiceOpsTaskAgeBucket, VoiceOpsTaskAnalyticsOptions, VoiceOpsTaskAnalyticsSummary, VoiceOpsTaskAssignmentRule, VoiceOpsTaskAssignmentRuleCondition, VoiceOpsTaskAssignmentRules, VoiceOpsTaskAssigneeAnalytics, VoiceOpsDispositionTaskPolicies, VoiceOpsSLABreachPolicy, VoiceIntegrationDeliveryStatus, VoiceIntegrationEvent, VoiceIntegrationEventStore, VoiceIntegrationSinkDelivery, VoiceIntegrationEventType, VoiceIntegrationWebhookConfig, VoiceOpsTask, VoiceOpsTaskHistoryEntry, VoiceOpsTaskKind, VoiceOpsTaskPolicy, VoiceOpsTaskPriority, VoiceOpsTaskStatus, VoiceOpsTaskStore, VoiceOpsTaskSummary, VoiceOpsTaskWorkerAnalytics } from './ops';
161
161
  export { createTwilioMediaStreamBridge, createTwilioVoiceRoutes, createTwilioVoiceResponse, decodeTwilioMulawBase64, encodeTwilioMulawBase64, transcodePCMToTwilioOutboundPayload, transcodeTwilioInboundPayloadToPCM16 } from './telephony/twilio';
162
+ export { createVoiceTelephonyWebhookSecurityPreset } from './telephony/security';
162
163
  export { evaluateVoiceTelephonyContract } from './telephony/contract';
163
164
  export { createMemoryVoiceTelnyxWebhookEventStore, createTelnyxMediaStreamBridge, createTelnyxVoiceResponse, createTelnyxVoiceRoutes, createVoicePostgresTelnyxWebhookEventStore, createVoiceRedisTelnyxWebhookEventStore, createVoiceSQLiteTelnyxWebhookEventStore, createVoiceTelnyxWebhookVerifier, verifyVoiceTelnyxWebhookSignature } from './telephony/telnyx';
164
165
  export { createMemoryVoicePlivoWebhookNonceStore, createPlivoMediaStreamBridge, createPlivoVoiceResponse, createPlivoVoiceRoutes, createVoicePostgresPlivoWebhookNonceStore, createVoicePlivoWebhookVerifier, createVoiceRedisPlivoWebhookNonceStore, createVoiceSQLitePlivoWebhookNonceStore, signVoicePlivoWebhook, verifyVoicePlivoWebhookSignature } from './telephony/plivo';
165
166
  export { createVoiceTelephonyCarrierMatrix, createVoiceTelephonyCarrierMatrixRoutes, renderVoiceTelephonyCarrierMatrixHTML } from './telephony/matrix';
166
167
  export type { TwilioInboundMessage, TwilioMediaStreamBridge, TwilioMediaStreamBridgeOptions, TwilioMediaStreamSocket, TwilioOutboundClearMessage, TwilioOutboundMarkMessage, TwilioOutboundMediaMessage, TwilioOutboundMessage, TwilioVoiceRouteParameters, TwilioVoiceResponseOptions, TwilioVoiceSmokeCheck, TwilioVoiceSmokeOptions, TwilioVoiceSmokeReport, TwilioVoiceSetupOptions, TwilioVoiceSetupStatus, TwilioVoiceRoutesOptions } from './telephony/twilio';
168
+ export type { VoiceTelephonyWebhookSecurityOptions, VoiceTelephonyWebhookSecurityPreset, VoiceTelephonyWebhookSecurityStorePreset } from './telephony/security';
167
169
  export type { VoiceTelephonyContractIssue, VoiceTelephonyContractOptions, VoiceTelephonyContractReport, VoiceTelephonyContractRequirement, VoiceTelephonyProvider, VoiceTelephonySetupStatus, VoiceTelephonySmokeCheck, VoiceTelephonySmokeReport } from './telephony/contract';
168
170
  export type { TelnyxInboundMessage, TelnyxMediaPayload, TelnyxMediaStreamBridge, TelnyxMediaStreamBridgeOptions, TelnyxMediaStreamSocket, TelnyxOutboundClearMessage, TelnyxOutboundMarkMessage, TelnyxOutboundMediaMessage, TelnyxOutboundMessage, TelnyxVoiceResponseOptions, TelnyxVoiceRoutesOptions, TelnyxVoiceSetupOptions, TelnyxVoiceSetupStatus, TelnyxVoiceSmokeCheck, TelnyxVoiceSmokeOptions, TelnyxVoiceSmokeReport, VoicePostgresTelnyxWebhookEventStoreOptions, VoiceRedisTelnyxWebhookEventClient, VoiceRedisTelnyxWebhookEventStoreOptions, VoiceSQLiteTelnyxWebhookEventStoreOptions, VoiceTelnyxWebhookEventStore, VoiceTelnyxWebhookEventStoreOptions, VoiceTelnyxWebhookVerifierOptions } from './telephony/telnyx';
169
171
  export type { PlivoInboundMessage, PlivoMediaStreamBridge, PlivoMediaStreamBridgeOptions, PlivoMediaStreamSocket, PlivoOutboundCheckpointMessage, PlivoOutboundClearAudioMessage, PlivoOutboundMessage, PlivoOutboundPlayAudioMessage, PlivoVoiceResponseOptions, PlivoVoiceRoutesOptions, PlivoVoiceSetupOptions, PlivoVoiceSetupStatus, PlivoVoiceSmokeCheck, PlivoVoiceSmokeOptions, PlivoVoiceSmokeReport, VoicePostgresPlivoWebhookNonceStoreOptions, VoicePlivoWebhookNonceStore, VoicePlivoWebhookNonceStoreOptions, VoicePlivoWebhookVerifierOptions, VoiceRedisPlivoWebhookNonceClient, VoiceRedisPlivoWebhookNonceStoreOptions, VoiceSQLitePlivoWebhookNonceStoreOptions } from './telephony/plivo';
package/dist/index.js CHANGED
@@ -13757,6 +13757,17 @@ var buildRetentionPolicyFromQuery = (query, options) => ({
13757
13757
  scopes: parseRetentionScopes(query.scopes),
13758
13758
  traceFilter: typeof query.sessionId === "string" && query.sessionId.trim() ? { sessionId: query.sessionId } : undefined
13759
13759
  });
13760
+ var buildAuditFilterFromQuery = (query) => {
13761
+ const filter = {
13762
+ after: getNumberQuery(query.auditAfter),
13763
+ afterOrAt: getNumberQuery(query.auditAfterOrAt),
13764
+ before: getNumberQuery(query.auditBefore),
13765
+ beforeOrAt: getNumberQuery(query.auditBeforeOrAt),
13766
+ limit: getNumberQuery(query.auditLimit),
13767
+ sessionId: typeof query.sessionId === "string" && query.sessionId.trim() ? query.sessionId : undefined
13768
+ };
13769
+ return Object.values(filter).some((value) => value !== undefined) ? filter : undefined;
13770
+ };
13760
13771
  var parseRetentionPolicyBody = (body, options, dryRun) => {
13761
13772
  const input = body && typeof body === "object" ? body : {};
13762
13773
  return {
@@ -13777,6 +13788,7 @@ var createVoiceDataControlRoutes = (options) => {
13777
13788
  });
13778
13789
  routes.get(path, async ({ query }) => {
13779
13790
  const report = await buildVoiceDataControlReport({
13791
+ auditFilter: buildAuditFilterFromQuery(query),
13780
13792
  ...options,
13781
13793
  retention: buildRetentionPolicyFromQuery(query, options)
13782
13794
  });
@@ -13788,11 +13800,13 @@ var createVoiceDataControlRoutes = (options) => {
13788
13800
  });
13789
13801
  });
13790
13802
  routes.get(`${path}.json`, async ({ query }) => buildVoiceDataControlReport({
13803
+ auditFilter: buildAuditFilterFromQuery(query),
13791
13804
  ...options,
13792
13805
  retention: buildRetentionPolicyFromQuery(query, options)
13793
13806
  }));
13794
13807
  routes.get(`${path}.md`, async ({ query }) => {
13795
13808
  const report = await buildVoiceDataControlReport({
13809
+ auditFilter: buildAuditFilterFromQuery(query),
13796
13810
  ...options,
13797
13811
  retention: buildRetentionPolicyFromQuery(query, options)
13798
13812
  });
@@ -31664,6 +31678,139 @@ var createVoiceSTTRoutingCorrectionHandler = (mode = "generic") => {
31664
31678
  }
31665
31679
  return createPhraseHintCorrectionHandler();
31666
31680
  };
31681
+ // src/telephony/security.ts
31682
+ var resolveVerificationUrl2 = (option, input) => typeof option === "function" ? option(input) : option ?? input.request.url;
31683
+ var createStores = (options) => {
31684
+ const ttlSeconds = options.ttlSeconds;
31685
+ const store = options.store ?? { kind: "memory" };
31686
+ if (store.kind === "sqlite") {
31687
+ return {
31688
+ idempotency: options.twilio?.idempotencyStore ?? createVoiceSQLiteTelephonyWebhookIdempotencyStore({
31689
+ path: store.path,
31690
+ tableName: "voice_twilio_webhook_idempotency",
31691
+ tablePrefix: store.tablePrefix
31692
+ }),
31693
+ plivo: options.plivo?.nonceStore ?? createVoiceSQLitePlivoWebhookNonceStore({
31694
+ path: store.path,
31695
+ tableName: "voice_plivo_webhook_nonces",
31696
+ tablePrefix: store.tablePrefix,
31697
+ ttlSeconds
31698
+ }),
31699
+ telnyx: options.telnyx?.eventStore ?? createVoiceSQLiteTelnyxWebhookEventStore({
31700
+ path: store.path,
31701
+ tableName: "voice_telnyx_webhook_events",
31702
+ tablePrefix: store.tablePrefix,
31703
+ ttlSeconds
31704
+ })
31705
+ };
31706
+ }
31707
+ if (store.kind === "postgres") {
31708
+ return {
31709
+ idempotency: options.twilio?.idempotencyStore ?? createVoicePostgresTelephonyWebhookIdempotencyStore({
31710
+ connectionString: store.connectionString,
31711
+ schemaName: store.schemaName,
31712
+ sql: store.sql,
31713
+ tableName: "voice_twilio_webhook_idempotency",
31714
+ tablePrefix: store.tablePrefix
31715
+ }),
31716
+ plivo: options.plivo?.nonceStore ?? createVoicePostgresPlivoWebhookNonceStore({
31717
+ connectionString: store.connectionString,
31718
+ schemaName: store.schemaName,
31719
+ sql: store.sql,
31720
+ tableName: "voice_plivo_webhook_nonces",
31721
+ tablePrefix: store.tablePrefix,
31722
+ ttlSeconds
31723
+ }),
31724
+ telnyx: options.telnyx?.eventStore ?? createVoicePostgresTelnyxWebhookEventStore({
31725
+ connectionString: store.connectionString,
31726
+ schemaName: store.schemaName,
31727
+ sql: store.sql,
31728
+ tableName: "voice_telnyx_webhook_events",
31729
+ tablePrefix: store.tablePrefix,
31730
+ ttlSeconds
31731
+ })
31732
+ };
31733
+ }
31734
+ if (store.kind === "redis") {
31735
+ const keyPrefix = store.keyPrefix?.trim() || "voice:webhook-security";
31736
+ return {
31737
+ idempotency: options.twilio?.idempotencyStore ?? createVoiceRedisTelephonyWebhookIdempotencyStore({
31738
+ client: store.idempotencyClient,
31739
+ keyPrefix: `${keyPrefix}:twilio:idempotency`,
31740
+ ttlSeconds,
31741
+ url: store.url
31742
+ }),
31743
+ plivo: options.plivo?.nonceStore ?? createVoiceRedisPlivoWebhookNonceStore({
31744
+ client: store.plivoClient,
31745
+ keyPrefix: `${keyPrefix}:plivo:nonce`,
31746
+ ttlSeconds,
31747
+ url: store.url
31748
+ }),
31749
+ telnyx: options.telnyx?.eventStore ?? createVoiceRedisTelnyxWebhookEventStore({
31750
+ client: store.telnyxClient,
31751
+ keyPrefix: `${keyPrefix}:telnyx:event`,
31752
+ ttlSeconds,
31753
+ url: store.url
31754
+ })
31755
+ };
31756
+ }
31757
+ return {
31758
+ idempotency: options.twilio?.idempotencyStore ?? createMemoryVoiceTelephonyWebhookIdempotencyStore(),
31759
+ plivo: options.plivo?.nonceStore ?? createMemoryVoicePlivoWebhookNonceStore(),
31760
+ telnyx: options.telnyx?.eventStore ?? createMemoryVoiceTelnyxWebhookEventStore()
31761
+ };
31762
+ };
31763
+ var createVoiceTelephonyWebhookSecurityPreset = (options = {}) => {
31764
+ const stores = createStores(options);
31765
+ const twilioVerificationUrl = options.twilio?.verificationUrl;
31766
+ const plivoVerify = createVoicePlivoWebhookVerifier({
31767
+ authToken: options.plivo?.authToken,
31768
+ nonceStore: stores.plivo,
31769
+ verificationUrl: options.plivo?.verificationUrl
31770
+ });
31771
+ const telnyxVerify = createVoiceTelnyxWebhookVerifier({
31772
+ eventStore: stores.telnyx,
31773
+ publicKey: options.telnyx?.publicKey,
31774
+ toleranceSeconds: options.telnyx?.toleranceSeconds
31775
+ });
31776
+ const twilioVerify = async (input) => verifyVoiceTwilioWebhookSignature({
31777
+ authToken: options.twilio?.authToken,
31778
+ body: input.body,
31779
+ headers: input.headers,
31780
+ url: resolveVerificationUrl2(twilioVerificationUrl, {
31781
+ query: input.query,
31782
+ request: input.request
31783
+ })
31784
+ });
31785
+ return {
31786
+ plivo: {
31787
+ authToken: options.plivo?.authToken,
31788
+ nonceStore: stores.plivo,
31789
+ verify: plivoVerify
31790
+ },
31791
+ telnyx: {
31792
+ eventStore: stores.telnyx,
31793
+ publicKey: options.telnyx?.publicKey,
31794
+ toleranceSeconds: options.telnyx?.toleranceSeconds,
31795
+ verify: telnyxVerify
31796
+ },
31797
+ twilio: {
31798
+ idempotency: {
31799
+ enabled: true,
31800
+ store: stores.idempotency
31801
+ },
31802
+ requireVerification: true,
31803
+ signingSecret: options.twilio?.authToken,
31804
+ verificationUrl: twilioVerificationUrl,
31805
+ verify: twilioVerify
31806
+ },
31807
+ verify: {
31808
+ plivo: plivoVerify,
31809
+ telnyx: telnyxVerify,
31810
+ twilio: twilioVerify
31811
+ }
31812
+ };
31813
+ };
31667
31814
  // src/telephony/response.ts
31668
31815
  var normalizeWhitespace = (value) => value.replace(/\s+/g, " ").trim();
31669
31816
  var DEFAULT_MAX_WORDS = 12;
@@ -31974,6 +32121,7 @@ export {
31974
32121
  createVoiceToolContract,
31975
32122
  createVoiceTelnyxWebhookVerifier,
31976
32123
  createVoiceTelnyxCampaignDialer,
32124
+ createVoiceTelephonyWebhookSecurityPreset,
31977
32125
  createVoiceTelephonyWebhookRoutes,
31978
32126
  createVoiceTelephonyWebhookHandler,
31979
32127
  createVoiceTelephonyOutcomePolicy,
@@ -0,0 +1,95 @@
1
+ import { type VoiceTelephonyWebhookIdempotencyStore, type VoiceTelephonyWebhookVerificationResult } from '../telephonyOutcome';
2
+ import { type VoicePostgresClient } from '../postgresStore';
3
+ import { type VoiceRedisTelephonyWebhookIdempotencyClient } from '../queue';
4
+ import { type VoicePlivoWebhookNonceStore, type VoiceRedisPlivoWebhookNonceClient } from './plivo';
5
+ import { type VoiceRedisTelnyxWebhookEventClient, type VoiceTelnyxWebhookEventStore } from './telnyx';
6
+ export type VoiceTelephonyWebhookSecurityStorePreset = {
7
+ kind?: 'memory';
8
+ } | {
9
+ kind: 'sqlite';
10
+ path: string;
11
+ tablePrefix?: string;
12
+ } | {
13
+ connectionString?: string;
14
+ kind: 'postgres';
15
+ schemaName?: string;
16
+ sql?: VoicePostgresClient;
17
+ tablePrefix?: string;
18
+ } | {
19
+ idempotencyClient?: VoiceRedisTelephonyWebhookIdempotencyClient;
20
+ keyPrefix?: string;
21
+ kind: 'redis';
22
+ plivoClient?: VoiceRedisPlivoWebhookNonceClient;
23
+ telnyxClient?: VoiceRedisTelnyxWebhookEventClient;
24
+ url?: string;
25
+ };
26
+ export type VoiceTelephonyWebhookSecurityOptions<TResult = unknown> = {
27
+ plivo?: {
28
+ authToken?: string;
29
+ nonceStore?: VoicePlivoWebhookNonceStore;
30
+ verificationUrl?: string | ((input: {
31
+ query: Record<string, unknown>;
32
+ request: Request;
33
+ }) => string);
34
+ };
35
+ store?: VoiceTelephonyWebhookSecurityStorePreset;
36
+ telnyx?: {
37
+ eventStore?: VoiceTelnyxWebhookEventStore;
38
+ publicKey?: string;
39
+ toleranceSeconds?: number;
40
+ };
41
+ ttlSeconds?: number;
42
+ twilio?: {
43
+ authToken?: string;
44
+ idempotencyStore?: VoiceTelephonyWebhookIdempotencyStore<TResult>;
45
+ verificationUrl?: string | ((input: {
46
+ query: Record<string, unknown>;
47
+ request: Request;
48
+ }) => string);
49
+ };
50
+ };
51
+ export type VoiceTelephonyWebhookSecurityPreset<TResult = unknown> = {
52
+ plivo: {
53
+ authToken?: string;
54
+ nonceStore: VoicePlivoWebhookNonceStore;
55
+ verify: (input: {
56
+ body: unknown;
57
+ headers: Headers;
58
+ query: Record<string, unknown>;
59
+ request: Request;
60
+ }) => Promise<VoiceTelephonyWebhookVerificationResult>;
61
+ };
62
+ telnyx: {
63
+ eventStore: VoiceTelnyxWebhookEventStore;
64
+ publicKey?: string;
65
+ toleranceSeconds?: number;
66
+ verify: (input: {
67
+ headers: Headers;
68
+ rawBody: string;
69
+ }) => Promise<VoiceTelephonyWebhookVerificationResult>;
70
+ };
71
+ twilio: {
72
+ idempotency: {
73
+ enabled: true;
74
+ store: VoiceTelephonyWebhookIdempotencyStore<TResult>;
75
+ };
76
+ requireVerification: true;
77
+ signingSecret?: string;
78
+ verificationUrl?: string | ((input: {
79
+ query: Record<string, unknown>;
80
+ request: Request;
81
+ }) => string);
82
+ verify: (input: {
83
+ body: unknown;
84
+ headers: Headers;
85
+ query: Record<string, unknown>;
86
+ request: Request;
87
+ }) => Promise<VoiceTelephonyWebhookVerificationResult>;
88
+ };
89
+ verify: {
90
+ plivo: VoiceTelephonyWebhookSecurityPreset<TResult>['plivo']['verify'];
91
+ telnyx: VoiceTelephonyWebhookSecurityPreset<TResult>['telnyx']['verify'];
92
+ twilio: VoiceTelephonyWebhookSecurityPreset<TResult>['twilio']['verify'];
93
+ };
94
+ };
95
+ export declare const createVoiceTelephonyWebhookSecurityPreset: <TResult = unknown>(options?: VoiceTelephonyWebhookSecurityOptions<TResult>) => VoiceTelephonyWebhookSecurityPreset<TResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.272",
3
+ "version": "0.0.22-beta.274",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",