@amigo-ai/platform-sdk 0.3.0 → 0.4.0
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/README.md +58 -0
- package/dist/core/errors.js +2 -3
- package/dist/core/errors.js.map +1 -1
- package/dist/core/webhooks.js +127 -13
- package/dist/core/webhooks.js.map +1 -1
- package/dist/index.cjs +123 -18
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +123 -18
- package/dist/index.mjs.map +2 -2
- package/dist/types/core/errors.d.ts.map +1 -1
- package/dist/types/core/webhooks.d.ts +19 -1
- package/dist/types/core/webhooks.d.ts.map +1 -1
- package/dist/types/generated/api.d.ts +12694 -11729
- package/dist/types/generated/api.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/resources/actions.d.ts +83 -83
- package/dist/types/resources/actions.d.ts.map +1 -1
- package/dist/types/resources/agents.d.ts +30 -30
- package/dist/types/resources/agents.d.ts.map +1 -1
- package/dist/types/resources/analytics.d.ts +12 -12
- package/dist/types/resources/analytics.d.ts.map +1 -1
- package/dist/types/resources/api-keys.d.ts +15 -15
- package/dist/types/resources/api-keys.d.ts.map +1 -1
- package/dist/types/resources/audit.d.ts +11 -11
- package/dist/types/resources/audit.d.ts.map +1 -1
- package/dist/types/resources/billing.d.ts +9 -9
- package/dist/types/resources/billing.d.ts.map +1 -1
- package/dist/types/resources/calls.d.ts +31 -45
- package/dist/types/resources/calls.d.ts.map +1 -1
- package/dist/types/resources/compliance.d.ts +17 -17
- package/dist/types/resources/context-graphs.d.ts +35 -35
- package/dist/types/resources/context-graphs.d.ts.map +1 -1
- package/dist/types/resources/data-sources.d.ts +47 -47
- package/dist/types/resources/data-sources.d.ts.map +1 -1
- package/dist/types/resources/functions.d.ts +12 -12
- package/dist/types/resources/functions.d.ts.map +1 -1
- package/dist/types/resources/integrations.d.ts +43 -43
- package/dist/types/resources/integrations.d.ts.map +1 -1
- package/dist/types/resources/memory.d.ts +10 -10
- package/dist/types/resources/memory.d.ts.map +1 -1
- package/dist/types/resources/operators.d.ts +53 -53
- package/dist/types/resources/operators.d.ts.map +1 -1
- package/dist/types/resources/personas.d.ts +23 -23
- package/dist/types/resources/personas.d.ts.map +1 -1
- package/dist/types/resources/phone-numbers.d.ts +38 -38
- package/dist/types/resources/phone-numbers.d.ts.map +1 -1
- package/dist/types/resources/recordings.d.ts +10 -10
- package/dist/types/resources/review-queue.d.ts +71 -71
- package/dist/types/resources/review-queue.d.ts.map +1 -1
- package/dist/types/resources/safety.d.ts +23 -23
- package/dist/types/resources/safety.d.ts.map +1 -1
- package/dist/types/resources/services.d.ts +50 -50
- package/dist/types/resources/services.d.ts.map +1 -1
- package/dist/types/resources/settings.d.ts +24 -24
- package/dist/types/resources/settings.d.ts.map +1 -1
- package/dist/types/resources/simulations.d.ts +12 -12
- package/dist/types/resources/simulations.d.ts.map +1 -1
- package/dist/types/resources/skills.d.ts +83 -83
- package/dist/types/resources/skills.d.ts.map +1 -1
- package/dist/types/resources/triggers.d.ts +55 -55
- package/dist/types/resources/triggers.d.ts.map +1 -1
- package/dist/types/resources/webhook-destinations.d.ts +35 -35
- package/dist/types/resources/webhook-destinations.d.ts.map +1 -1
- package/dist/types/resources/workspaces.d.ts +26 -26
- package/dist/types/resources/workspaces.d.ts.map +1 -1
- package/dist/types/resources/world.d.ts +41 -41
- package/dist/types/resources/world.d.ts.map +1 -1
- package/package.json +31 -14
package/README.md
CHANGED
|
@@ -63,6 +63,24 @@ const client = new AmigoClient({
|
|
|
63
63
|
|
|
64
64
|
GET requests are retried on 408, 429, 500, 502, 503, 504. POST requests are only retried on 429 with a `Retry-After` header. Backoff uses full jitter.
|
|
65
65
|
|
|
66
|
+
## Generated Types
|
|
67
|
+
|
|
68
|
+
The SDK ships with generated OpenAPI types and re-exports them for direct use:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import type { components, operations, paths } from '@amigo-ai/platform-sdk'
|
|
72
|
+
|
|
73
|
+
type Agent = components['schemas']['AgentResponse']
|
|
74
|
+
type ListAgentsQuery =
|
|
75
|
+
operations['list_agents_v1__workspace_id__agents_get']['parameters']['query']
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Public builds are generated from the committed [`openapi.json`](./openapi.json) snapshot in this repo so type output stays deterministic across machines and CI runs. When you need to refresh that snapshot, run:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm run openapi:sync
|
|
82
|
+
```
|
|
83
|
+
|
|
66
84
|
## Resources
|
|
67
85
|
|
|
68
86
|
### Agents
|
|
@@ -367,6 +385,44 @@ const dest = await client.webhookDestinations.create({
|
|
|
367
385
|
const deliveries = await client.webhookDestinations.listDeliveries(dest.id)
|
|
368
386
|
```
|
|
369
387
|
|
|
388
|
+
## Webhook Verification
|
|
389
|
+
|
|
390
|
+
Use the raw request body when verifying webhook deliveries. Timestamped signatures are replay-protected by default.
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
import {
|
|
394
|
+
parseWebhookEvent,
|
|
395
|
+
WebhookVerificationError,
|
|
396
|
+
} from '@amigo-ai/platform-sdk'
|
|
397
|
+
|
|
398
|
+
const body = await request.text()
|
|
399
|
+
|
|
400
|
+
try {
|
|
401
|
+
const event = await parseWebhookEvent({
|
|
402
|
+
payload: body,
|
|
403
|
+
signature: request.headers.get('x-amigo-signature') ?? '',
|
|
404
|
+
timestamp: request.headers.get('x-amigo-timestamp') ?? undefined,
|
|
405
|
+
secret: process.env.AMIGO_WEBHOOK_SECRET!,
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
console.log(event.type, event.data)
|
|
409
|
+
} catch (error) {
|
|
410
|
+
if (error instanceof WebhookVerificationError) {
|
|
411
|
+
console.error('Rejected webhook:', error.message)
|
|
412
|
+
} else {
|
|
413
|
+
throw error
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
If your delivery channel only provides a legacy HMAC without a timestamp, the original helper signature still works:
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
import { parseWebhookEvent } from '@amigo-ai/platform-sdk'
|
|
422
|
+
|
|
423
|
+
const event = await parseWebhookEvent(rawBody, signature, secret)
|
|
424
|
+
```
|
|
425
|
+
|
|
370
426
|
## BFF Proxy (Next.js)
|
|
371
427
|
|
|
372
428
|
For frontend apps that use a Backend-for-Frontend proxy:
|
|
@@ -422,6 +478,8 @@ try {
|
|
|
422
478
|
}
|
|
423
479
|
```
|
|
424
480
|
|
|
481
|
+
Webhook verification errors are separate from API transport errors and throw `WebhookVerificationError`.
|
|
482
|
+
|
|
425
483
|
### Error classes
|
|
426
484
|
|
|
427
485
|
| Class | HTTP Status | Description |
|
package/dist/core/errors.js
CHANGED
|
@@ -140,9 +140,8 @@ export class ConfigurationError extends AmigoError {
|
|
|
140
140
|
}
|
|
141
141
|
export async function createApiError(response) {
|
|
142
142
|
let body = {};
|
|
143
|
-
let rawBody;
|
|
144
143
|
try {
|
|
145
|
-
rawBody = await response.text();
|
|
144
|
+
const rawBody = await response.text();
|
|
146
145
|
body = JSON.parse(rawBody);
|
|
147
146
|
}
|
|
148
147
|
catch {
|
|
@@ -151,7 +150,7 @@ export async function createApiError(response) {
|
|
|
151
150
|
const ctx = {
|
|
152
151
|
statusCode: response.status,
|
|
153
152
|
errorCode: body.error_code,
|
|
154
|
-
requestId: body.request_id,
|
|
153
|
+
requestId: body.request_id ?? response.headers.get('x-request-id') ?? undefined,
|
|
155
154
|
detail: body.detail,
|
|
156
155
|
context: { url: response.url, response: body },
|
|
157
156
|
};
|
package/dist/core/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/core/webhooks.js
CHANGED
|
@@ -1,17 +1,131 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
.
|
|
7
|
-
.
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
export async function
|
|
11
|
-
const
|
|
1
|
+
const textEncoder = new TextEncoder();
|
|
2
|
+
const MAX_TIMESTAMP_SKEW_MS = 5 * 60 * 1000;
|
|
3
|
+
export class WebhookVerificationError extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'WebhookVerificationError';
|
|
7
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export async function verifyWebhookSignature(payloadOrOptions, signature, secret) {
|
|
11
|
+
const options = normalizeVerificationOptions(payloadOrOptions, signature, secret);
|
|
12
|
+
const payloadBytes = toUint8Array(options.payload);
|
|
13
|
+
const expectedSignature = await signWebhookPayload(payloadBytes, options.secret, options.timestamp);
|
|
14
|
+
const actualSignature = normalizeSignature(options.signature);
|
|
15
|
+
if (!actualSignature || !constantTimeEqual(expectedSignature, actualSignature)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (options.timestamp) {
|
|
19
|
+
const timestampMs = parseTimestamp(options.timestamp);
|
|
20
|
+
if (timestampMs === undefined)
|
|
21
|
+
return false;
|
|
22
|
+
const maxAgeMs = options.maxAgeMs ?? MAX_TIMESTAMP_SKEW_MS;
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
if (timestampMs > now + maxAgeMs || now - timestampMs > maxAgeMs) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
export async function parseWebhookEvent(payloadOrOptions, signature, secret) {
|
|
31
|
+
const options = normalizeParseOptions(payloadOrOptions, signature, secret);
|
|
32
|
+
const valid = await verifyWebhookSignature(options);
|
|
12
33
|
if (!valid) {
|
|
13
|
-
throw new
|
|
34
|
+
throw new WebhookVerificationError('Invalid or expired webhook signature');
|
|
35
|
+
}
|
|
36
|
+
const payloadText = decodePayload(options.payload);
|
|
37
|
+
let event;
|
|
38
|
+
try {
|
|
39
|
+
event = JSON.parse(payloadText, options.reviver);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new WebhookVerificationError('Invalid JSON webhook payload');
|
|
43
|
+
}
|
|
44
|
+
if (options.expectedType && event.type !== options.expectedType) {
|
|
45
|
+
throw new WebhookVerificationError(`Unexpected webhook event type: expected ${options.expectedType}, received ${event.type}`);
|
|
46
|
+
}
|
|
47
|
+
options.validate?.(event);
|
|
48
|
+
return event;
|
|
49
|
+
}
|
|
50
|
+
function normalizeVerificationOptions(payloadOrOptions, signature, secret) {
|
|
51
|
+
if (typeof payloadOrOptions === 'object' &&
|
|
52
|
+
payloadOrOptions !== null &&
|
|
53
|
+
'payload' in payloadOrOptions) {
|
|
54
|
+
return payloadOrOptions;
|
|
55
|
+
}
|
|
56
|
+
if (!signature || !secret) {
|
|
57
|
+
throw new TypeError('signature and secret are required');
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
payload: payloadOrOptions,
|
|
61
|
+
signature,
|
|
62
|
+
secret,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function normalizeParseOptions(payloadOrOptions, signature, secret) {
|
|
66
|
+
if (typeof payloadOrOptions === 'object' && payloadOrOptions !== null && 'payload' in payloadOrOptions) {
|
|
67
|
+
return payloadOrOptions;
|
|
14
68
|
}
|
|
15
|
-
|
|
69
|
+
if (!signature || !secret) {
|
|
70
|
+
throw new TypeError('signature and secret are required');
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
payload: payloadOrOptions,
|
|
74
|
+
signature,
|
|
75
|
+
secret,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function decodePayload(payload) {
|
|
79
|
+
if (typeof payload === 'string')
|
|
80
|
+
return payload;
|
|
81
|
+
return new TextDecoder().decode(toUint8Array(payload));
|
|
82
|
+
}
|
|
83
|
+
function toUint8Array(payload) {
|
|
84
|
+
if (typeof payload === 'string')
|
|
85
|
+
return textEncoder.encode(payload);
|
|
86
|
+
if (payload instanceof Uint8Array)
|
|
87
|
+
return payload;
|
|
88
|
+
return new Uint8Array(payload);
|
|
89
|
+
}
|
|
90
|
+
async function signWebhookPayload(payload, secret, timestamp) {
|
|
91
|
+
const key = await crypto.subtle.importKey('raw', textEncoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
92
|
+
const message = timestamp
|
|
93
|
+
? concatUint8Arrays(textEncoder.encode(`v1:${timestamp}:`), payload)
|
|
94
|
+
: payload;
|
|
95
|
+
const mac = await crypto.subtle.sign('HMAC', key, message);
|
|
96
|
+
return new Uint8Array(mac);
|
|
97
|
+
}
|
|
98
|
+
function normalizeSignature(signature) {
|
|
99
|
+
const normalized = signature.startsWith('sha256=') ? signature.slice(7) : signature;
|
|
100
|
+
if (!/^[a-fA-F0-9]+$/.test(normalized) || normalized.length % 2 !== 0) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
const bytes = new Uint8Array(normalized.length / 2);
|
|
104
|
+
for (let index = 0; index < normalized.length; index += 2) {
|
|
105
|
+
bytes[index / 2] = Number.parseInt(normalized.slice(index, index + 2), 16);
|
|
106
|
+
}
|
|
107
|
+
return bytes;
|
|
108
|
+
}
|
|
109
|
+
function constantTimeEqual(expected, actual) {
|
|
110
|
+
const maxLength = Math.max(expected.length, actual.length);
|
|
111
|
+
let diff = expected.length ^ actual.length;
|
|
112
|
+
for (let index = 0; index < maxLength; index += 1) {
|
|
113
|
+
diff |= (expected[index] ?? 0) ^ (actual[index] ?? 0);
|
|
114
|
+
}
|
|
115
|
+
return diff === 0;
|
|
116
|
+
}
|
|
117
|
+
function parseTimestamp(timestamp) {
|
|
118
|
+
const numeric = Number(timestamp);
|
|
119
|
+
if (Number.isFinite(numeric)) {
|
|
120
|
+
return numeric < 1_000_000_000_000 ? numeric * 1000 : numeric;
|
|
121
|
+
}
|
|
122
|
+
const parsed = Date.parse(timestamp);
|
|
123
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
124
|
+
}
|
|
125
|
+
function concatUint8Arrays(left, right) {
|
|
126
|
+
const combined = new Uint8Array(left.length + right.length);
|
|
127
|
+
combined.set(left, 0);
|
|
128
|
+
combined.set(right, left.length);
|
|
129
|
+
return combined;
|
|
16
130
|
}
|
|
17
131
|
//# sourceMappingURL=webhooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/core/webhooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/core/webhooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
ServerError: () => ServerError,
|
|
46
46
|
ServiceUnavailableError: () => ServiceUnavailableError,
|
|
47
47
|
ValidationError: () => ValidationError,
|
|
48
|
+
WebhookVerificationError: () => WebhookVerificationError,
|
|
48
49
|
actionId: () => actionId,
|
|
49
50
|
agentId: () => agentId,
|
|
50
51
|
apiKeyId: () => apiKeyId,
|
|
@@ -204,16 +205,15 @@ var ConfigurationError = class extends AmigoError {
|
|
|
204
205
|
};
|
|
205
206
|
async function createApiError(response) {
|
|
206
207
|
let body = {};
|
|
207
|
-
let rawBody;
|
|
208
208
|
try {
|
|
209
|
-
rawBody = await response.text();
|
|
209
|
+
const rawBody = await response.text();
|
|
210
210
|
body = JSON.parse(rawBody);
|
|
211
211
|
} catch {
|
|
212
212
|
}
|
|
213
213
|
const ctx = {
|
|
214
214
|
statusCode: response.status,
|
|
215
215
|
errorCode: body.error_code,
|
|
216
|
-
requestId: body.request_id,
|
|
216
|
+
requestId: body.request_id ?? response.headers.get("x-request-id") ?? void 0,
|
|
217
217
|
detail: body.detail,
|
|
218
218
|
context: { url: response.url, response: body }
|
|
219
219
|
};
|
|
@@ -2199,29 +2199,134 @@ function parseRateLimitHeaders(headers) {
|
|
|
2199
2199
|
}
|
|
2200
2200
|
|
|
2201
2201
|
// src/core/webhooks.ts
|
|
2202
|
-
|
|
2203
|
-
|
|
2202
|
+
var textEncoder = new TextEncoder();
|
|
2203
|
+
var MAX_TIMESTAMP_SKEW_MS = 5 * 60 * 1e3;
|
|
2204
|
+
var WebhookVerificationError = class extends Error {
|
|
2205
|
+
constructor(message) {
|
|
2206
|
+
super(message);
|
|
2207
|
+
this.name = "WebhookVerificationError";
|
|
2208
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
2209
|
+
}
|
|
2210
|
+
};
|
|
2211
|
+
async function verifyWebhookSignature(payloadOrOptions, signature, secret) {
|
|
2212
|
+
const options = normalizeVerificationOptions(payloadOrOptions, signature, secret);
|
|
2213
|
+
const payloadBytes = toUint8Array(options.payload);
|
|
2214
|
+
const expectedSignature = await signWebhookPayload(payloadBytes, options.secret, options.timestamp);
|
|
2215
|
+
const actualSignature = normalizeSignature(options.signature);
|
|
2216
|
+
if (!actualSignature || !constantTimeEqual(expectedSignature, actualSignature)) {
|
|
2217
|
+
return false;
|
|
2218
|
+
}
|
|
2219
|
+
if (options.timestamp) {
|
|
2220
|
+
const timestampMs = parseTimestamp(options.timestamp);
|
|
2221
|
+
if (timestampMs === void 0) return false;
|
|
2222
|
+
const maxAgeMs = options.maxAgeMs ?? MAX_TIMESTAMP_SKEW_MS;
|
|
2223
|
+
const now = Date.now();
|
|
2224
|
+
if (timestampMs > now + maxAgeMs || now - timestampMs > maxAgeMs) {
|
|
2225
|
+
return false;
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
return true;
|
|
2229
|
+
}
|
|
2230
|
+
async function parseWebhookEvent(payloadOrOptions, signature, secret) {
|
|
2231
|
+
const options = normalizeParseOptions(payloadOrOptions, signature, secret);
|
|
2232
|
+
const valid = await verifyWebhookSignature(options);
|
|
2233
|
+
if (!valid) {
|
|
2234
|
+
throw new WebhookVerificationError("Invalid or expired webhook signature");
|
|
2235
|
+
}
|
|
2236
|
+
const payloadText = decodePayload(options.payload);
|
|
2237
|
+
let event;
|
|
2238
|
+
try {
|
|
2239
|
+
event = JSON.parse(payloadText, options.reviver);
|
|
2240
|
+
} catch {
|
|
2241
|
+
throw new WebhookVerificationError("Invalid JSON webhook payload");
|
|
2242
|
+
}
|
|
2243
|
+
if (options.expectedType && event.type !== options.expectedType) {
|
|
2244
|
+
throw new WebhookVerificationError(
|
|
2245
|
+
`Unexpected webhook event type: expected ${options.expectedType}, received ${event.type}`
|
|
2246
|
+
);
|
|
2247
|
+
}
|
|
2248
|
+
options.validate?.(event);
|
|
2249
|
+
return event;
|
|
2250
|
+
}
|
|
2251
|
+
function normalizeVerificationOptions(payloadOrOptions, signature, secret) {
|
|
2252
|
+
if (typeof payloadOrOptions === "object" && payloadOrOptions !== null && "payload" in payloadOrOptions) {
|
|
2253
|
+
return payloadOrOptions;
|
|
2254
|
+
}
|
|
2255
|
+
if (!signature || !secret) {
|
|
2256
|
+
throw new TypeError("signature and secret are required");
|
|
2257
|
+
}
|
|
2258
|
+
return {
|
|
2259
|
+
payload: payloadOrOptions,
|
|
2260
|
+
signature,
|
|
2261
|
+
secret
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
function normalizeParseOptions(payloadOrOptions, signature, secret) {
|
|
2265
|
+
if (typeof payloadOrOptions === "object" && payloadOrOptions !== null && "payload" in payloadOrOptions) {
|
|
2266
|
+
return payloadOrOptions;
|
|
2267
|
+
}
|
|
2268
|
+
if (!signature || !secret) {
|
|
2269
|
+
throw new TypeError("signature and secret are required");
|
|
2270
|
+
}
|
|
2271
|
+
return {
|
|
2272
|
+
payload: payloadOrOptions,
|
|
2273
|
+
signature,
|
|
2274
|
+
secret
|
|
2275
|
+
};
|
|
2276
|
+
}
|
|
2277
|
+
function decodePayload(payload) {
|
|
2278
|
+
if (typeof payload === "string") return payload;
|
|
2279
|
+
return new TextDecoder().decode(toUint8Array(payload));
|
|
2280
|
+
}
|
|
2281
|
+
function toUint8Array(payload) {
|
|
2282
|
+
if (typeof payload === "string") return textEncoder.encode(payload);
|
|
2283
|
+
if (payload instanceof Uint8Array) return payload;
|
|
2284
|
+
return new Uint8Array(payload);
|
|
2285
|
+
}
|
|
2286
|
+
async function signWebhookPayload(payload, secret, timestamp) {
|
|
2204
2287
|
const key = await crypto.subtle.importKey(
|
|
2205
2288
|
"raw",
|
|
2206
|
-
|
|
2289
|
+
textEncoder.encode(secret),
|
|
2207
2290
|
{ name: "HMAC", hash: "SHA-256" },
|
|
2208
2291
|
false,
|
|
2209
2292
|
["sign"]
|
|
2210
2293
|
);
|
|
2211
|
-
const
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
typeof payload === "string" ? encoder.encode(payload) : payload
|
|
2215
|
-
);
|
|
2216
|
-
const expected = Array.from(new Uint8Array(mac)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
2217
|
-
return signature === `sha256=${expected}`;
|
|
2294
|
+
const message = timestamp ? concatUint8Arrays(textEncoder.encode(`v1:${timestamp}:`), payload) : payload;
|
|
2295
|
+
const mac = await crypto.subtle.sign("HMAC", key, message);
|
|
2296
|
+
return new Uint8Array(mac);
|
|
2218
2297
|
}
|
|
2219
|
-
|
|
2220
|
-
const
|
|
2221
|
-
if (
|
|
2222
|
-
|
|
2298
|
+
function normalizeSignature(signature) {
|
|
2299
|
+
const normalized = signature.startsWith("sha256=") ? signature.slice(7) : signature;
|
|
2300
|
+
if (!/^[a-fA-F0-9]+$/.test(normalized) || normalized.length % 2 !== 0) {
|
|
2301
|
+
return void 0;
|
|
2223
2302
|
}
|
|
2224
|
-
|
|
2303
|
+
const bytes = new Uint8Array(normalized.length / 2);
|
|
2304
|
+
for (let index = 0; index < normalized.length; index += 2) {
|
|
2305
|
+
bytes[index / 2] = Number.parseInt(normalized.slice(index, index + 2), 16);
|
|
2306
|
+
}
|
|
2307
|
+
return bytes;
|
|
2308
|
+
}
|
|
2309
|
+
function constantTimeEqual(expected, actual) {
|
|
2310
|
+
const maxLength = Math.max(expected.length, actual.length);
|
|
2311
|
+
let diff = expected.length ^ actual.length;
|
|
2312
|
+
for (let index = 0; index < maxLength; index += 1) {
|
|
2313
|
+
diff |= (expected[index] ?? 0) ^ (actual[index] ?? 0);
|
|
2314
|
+
}
|
|
2315
|
+
return diff === 0;
|
|
2316
|
+
}
|
|
2317
|
+
function parseTimestamp(timestamp) {
|
|
2318
|
+
const numeric = Number(timestamp);
|
|
2319
|
+
if (Number.isFinite(numeric)) {
|
|
2320
|
+
return numeric < 1e12 ? numeric * 1e3 : numeric;
|
|
2321
|
+
}
|
|
2322
|
+
const parsed = Date.parse(timestamp);
|
|
2323
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
2324
|
+
}
|
|
2325
|
+
function concatUint8Arrays(left, right) {
|
|
2326
|
+
const combined = new Uint8Array(left.length + right.length);
|
|
2327
|
+
combined.set(left, 0);
|
|
2328
|
+
combined.set(right, left.length);
|
|
2329
|
+
return combined;
|
|
2225
2330
|
}
|
|
2226
2331
|
|
|
2227
2332
|
// src/index.ts
|