@sayna-ai/node-sdk 0.0.5 → 0.0.7

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.
@@ -0,0 +1,203 @@
1
+ import type { WebhookSIPOutput } from "./types";
2
+ /**
3
+ * Receives and verifies cryptographically signed webhooks from Sayna SIP service.
4
+ *
5
+ * This class handles the secure verification of webhook signatures using HMAC-SHA256,
6
+ * validates timestamp freshness to prevent replay attacks, and parses the webhook
7
+ * payload into a strongly-typed WebhookSIPOutput object.
8
+ *
9
+ * ## Security Features
10
+ *
11
+ * - **HMAC-SHA256 Signature Verification**: Ensures webhook authenticity
12
+ * - **Constant-Time Comparison**: Prevents timing attack vulnerabilities
13
+ * - **Replay Protection**: 5-minute timestamp window prevents replay attacks
14
+ * - **Strict Validation**: Comprehensive checks on all required fields
15
+ *
16
+ * ## Usage
17
+ *
18
+ * ### Basic Example
19
+ *
20
+ * ```typescript
21
+ * import { WebhookReceiver } from "@sayna-ai/node-sdk";
22
+ *
23
+ * // Initialize with secret (or uses SAYNA_WEBHOOK_SECRET env variable)
24
+ * const receiver = new WebhookReceiver("your-secret-key-min-16-chars");
25
+ *
26
+ * // In your Express route handler
27
+ * app.post('/webhook', express.json({ verify: (req, res, buf) => {
28
+ * req.rawBody = buf.toString('utf8');
29
+ * }}), (req, res) => {
30
+ * try {
31
+ * const webhook = receiver.receive(req.headers, req.rawBody);
32
+ *
33
+ * console.log('Valid webhook received:');
34
+ * console.log(' From:', webhook.from_phone_number);
35
+ * console.log(' To:', webhook.to_phone_number);
36
+ * console.log(' Room:', webhook.room.name);
37
+ * console.log(' SIP Host:', webhook.sip_host);
38
+ * console.log(' Participant:', webhook.participant.identity);
39
+ *
40
+ * res.status(200).json({ received: true });
41
+ * } catch (error) {
42
+ * console.error('Webhook verification failed:', error.message);
43
+ * res.status(401).json({ error: 'Invalid signature' });
44
+ * }
45
+ * });
46
+ * ```
47
+ *
48
+ * ### With Environment Variable
49
+ *
50
+ * ```typescript
51
+ * // Set environment variable
52
+ * process.env.SAYNA_WEBHOOK_SECRET = "your-secret-key";
53
+ *
54
+ * // Receiver automatically uses env variable
55
+ * const receiver = new WebhookReceiver();
56
+ * ```
57
+ *
58
+ * ### Fastify Example
59
+ *
60
+ * ```typescript
61
+ * import Fastify from 'fastify';
62
+ * import { WebhookReceiver } from "@sayna-ai/node-sdk";
63
+ *
64
+ * const fastify = Fastify();
65
+ * const receiver = new WebhookReceiver();
66
+ *
67
+ * fastify.post('/webhook', {
68
+ * config: {
69
+ * rawBody: true
70
+ * }
71
+ * }, async (request, reply) => {
72
+ * try {
73
+ * const webhook = receiver.receive(
74
+ * request.headers,
75
+ * request.rawBody
76
+ * );
77
+ *
78
+ * // Process webhook...
79
+ *
80
+ * return { received: true };
81
+ * } catch (error) {
82
+ * reply.code(401);
83
+ * return { error: error.message };
84
+ * }
85
+ * });
86
+ * ```
87
+ *
88
+ * ## Important Notes
89
+ *
90
+ * - **Raw Body Required**: You MUST pass the raw request body string, not the parsed JSON object.
91
+ * The signature is computed over the exact bytes received, so any formatting changes will
92
+ * cause verification to fail.
93
+ *
94
+ * - **Case-Insensitive Headers**: Header names are case-insensitive in HTTP. This class handles
95
+ * both `X-Sayna-Signature` and `x-sayna-signature` correctly.
96
+ *
97
+ * - **Secret Security**: Never commit secrets to version control. Use environment variables
98
+ * or a secret management system.
99
+ *
100
+ * @see WebhookSIPOutput
101
+ */
102
+ export declare class WebhookReceiver {
103
+ private readonly secret;
104
+ /**
105
+ * Creates a new webhook receiver with the specified signing secret.
106
+ *
107
+ * @param secret - HMAC signing secret (min 16 chars, 32+ recommended).
108
+ * If not provided, uses SAYNA_WEBHOOK_SECRET environment variable.
109
+ *
110
+ * @throws {SaynaValidationError} If secret is missing or too short
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * // Explicit secret
115
+ * const receiver = new WebhookReceiver("my-secret-key-at-least-16-chars");
116
+ *
117
+ * // From environment variable
118
+ * const receiver = new WebhookReceiver();
119
+ * ```
120
+ */
121
+ constructor(secret?: string);
122
+ /**
123
+ * Verifies and parses an incoming SIP webhook from Sayna.
124
+ *
125
+ * This method performs the following security checks:
126
+ * 1. Validates presence of required headers
127
+ * 2. Verifies timestamp is within acceptable window (prevents replay attacks)
128
+ * 3. Computes HMAC-SHA256 signature over canonical string
129
+ * 4. Performs constant-time comparison to prevent timing attacks
130
+ * 5. Parses and validates the webhook payload structure
131
+ *
132
+ * @param headers - HTTP request headers (case-insensitive)
133
+ * @param body - Raw request body as string (not parsed JSON)
134
+ *
135
+ * @returns Parsed and validated webhook payload
136
+ *
137
+ * @throws {SaynaValidationError} If signature verification fails or payload is invalid
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const receiver = new WebhookReceiver("your-secret");
142
+ *
143
+ * // Express example
144
+ * app.post('/webhook', express.json({ verify: (req, res, buf) => {
145
+ * req.rawBody = buf.toString();
146
+ * }}), (req, res) => {
147
+ * const webhook = receiver.receive(req.headers, req.rawBody);
148
+ * // webhook is now a validated WebhookSIPOutput object
149
+ * });
150
+ * ```
151
+ */
152
+ receive(headers: Record<string, string | string[] | undefined>, body: string): WebhookSIPOutput;
153
+ /**
154
+ * Normalizes HTTP headers to lowercase for case-insensitive access.
155
+ * Handles both single string values and arrays of strings.
156
+ *
157
+ * @internal
158
+ */
159
+ private normalizeHeaders;
160
+ /**
161
+ * Retrieves a required header value or throws a validation error.
162
+ *
163
+ * @internal
164
+ */
165
+ private getRequiredHeader;
166
+ /**
167
+ * Validates the timestamp is within the acceptable window.
168
+ *
169
+ * @internal
170
+ */
171
+ private validateTimestamp;
172
+ /**
173
+ * Performs constant-time string comparison to prevent timing attacks.
174
+ *
175
+ * @internal
176
+ */
177
+ private constantTimeEqual;
178
+ /**
179
+ * Parses and validates the webhook payload structure.
180
+ *
181
+ * @internal
182
+ */
183
+ private parseAndValidatePayload;
184
+ /**
185
+ * Validates the participant object structure.
186
+ *
187
+ * @internal
188
+ */
189
+ private validateParticipant;
190
+ /**
191
+ * Validates the room object structure.
192
+ *
193
+ * @internal
194
+ */
195
+ private validateRoom;
196
+ /**
197
+ * Validates a required string field.
198
+ *
199
+ * @internal
200
+ */
201
+ private validateStringField;
202
+ }
203
+ //# sourceMappingURL=webhook-receiver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-receiver.d.ts","sourceRoot":"","sources":["../../src/webhook-receiver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAehD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC;;;;;;;;;;;;;;;;OAgBG;gBACS,MAAM,CAAC,EAAE,MAAM;IAsB3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,OAAO,CACL,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACtD,IAAI,EAAE,MAAM,GACX,gBAAgB;IAyDnB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAgC/B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAapB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;CAa5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../tests/errors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sayna-client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sayna-client.test.d.ts","sourceRoot":"","sources":["../../tests/sayna-client.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../tests/types.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=webhook-receiver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-receiver.test.d.ts","sourceRoot":"","sources":["../../tests/webhook-receiver.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sayna-ai/node-sdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Node.js SDK for Sayna.ai server-side WebSocket connections",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,6 +19,8 @@
19
19
  ],
20
20
  "scripts": {
21
21
  "build": "bun run build.ts",
22
+ "test": "bun test",
23
+ "test:watch": "bun test --watch",
22
24
  "typecheck": "tsc --noEmit",
23
25
  "lint": "eslint .",
24
26
  "lint:fix": "eslint . --fix",
@@ -37,10 +39,10 @@
37
39
  "license": "MIT",
38
40
  "repository": {
39
41
  "type": "git",
40
- "url": "https://github.com/sayna/saysdk"
42
+ "url": "https://github.com/SaynaAi/saysdk"
41
43
  },
42
44
  "bugs": {
43
- "url": "https://github.com/sayna/saysdk/issues"
45
+ "url": "https://github.com/SaynaAi/saysdk/issues"
44
46
  },
45
47
  "homepage": "https://sayna.ai",
46
48
  "engines": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,UAAU;gBACxC,OAAO,GAAE,MAA2C;CAKjE;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,UAAU;gBAE9C,OAAO,GAAE,MAA0F;CAMtG;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,SAAyB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAE7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAM7C;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;gBACtC,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;gBAClC,OAAO,EAAE,MAAM;CAK5B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE9D,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,aAAa,CAAC,EAAE,aAAa,EAC7B,YAAY,GAAE,OAAe,GAC5B,OAAO,CAAC,WAAW,CAAC,CAUtB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sayna-client.d.ts","sourceRoot":"","sources":["../src/sayna-client.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
File without changes