@hookflo/tern 3.0.3 → 3.0.5

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 { PlatformAlgorithmConfig, WebhookPlatform, SignatureConfig } from '../types';
1
+ import { PlatformAlgorithmConfig, WebhookPlatform, SignatureConfig } from "../types";
2
2
  export declare const platformAlgorithmConfigs: Record<WebhookPlatform, PlatformAlgorithmConfig>;
3
3
  export declare function getPlatformAlgorithmConfig(platform: WebhookPlatform): PlatformAlgorithmConfig;
4
4
  export declare function platformUsesAlgorithm(platform: WebhookPlatform, algorithm: string): boolean;
@@ -7,307 +7,309 @@ exports.getPlatformsUsingAlgorithm = getPlatformsUsingAlgorithm;
7
7
  exports.validateSignatureConfig = validateSignatureConfig;
8
8
  exports.platformAlgorithmConfigs = {
9
9
  github: {
10
- platform: 'github',
10
+ platform: "github",
11
11
  signatureConfig: {
12
- algorithm: 'hmac-sha256',
13
- headerName: 'x-hub-signature-256',
14
- headerFormat: 'prefixed',
15
- prefix: 'sha256=',
12
+ algorithm: "hmac-sha256",
13
+ headerName: "x-hub-signature-256",
14
+ headerFormat: "prefixed",
15
+ prefix: "sha256=",
16
16
  timestampHeader: undefined,
17
- payloadFormat: 'raw',
17
+ payloadFormat: "raw",
18
18
  },
19
- description: 'GitHub webhooks use HMAC-SHA256 with sha256= prefix',
19
+ description: "GitHub webhooks use HMAC-SHA256 with sha256= prefix",
20
20
  },
21
21
  stripe: {
22
- platform: 'stripe',
22
+ platform: "stripe",
23
23
  signatureConfig: {
24
- algorithm: 'hmac-sha256',
25
- headerName: 'stripe-signature',
26
- headerFormat: 'comma-separated',
24
+ algorithm: "hmac-sha256",
25
+ headerName: "stripe-signature",
26
+ headerFormat: "comma-separated",
27
27
  timestampHeader: undefined,
28
- payloadFormat: 'timestamped',
28
+ payloadFormat: "timestamped",
29
29
  customConfig: {
30
- signatureFormat: 't={timestamp},v1={signature}',
30
+ signatureFormat: "t={timestamp},v1={signature}",
31
31
  },
32
32
  },
33
- description: 'Stripe webhooks use HMAC-SHA256 with comma-separated format',
33
+ description: "Stripe webhooks use HMAC-SHA256 with comma-separated format",
34
34
  },
35
35
  clerk: {
36
- platform: 'clerk',
36
+ platform: "clerk",
37
37
  signatureConfig: {
38
- algorithm: 'hmac-sha256',
39
- headerName: 'svix-signature',
40
- headerFormat: 'raw',
41
- timestampHeader: 'svix-timestamp',
42
- timestampFormat: 'unix',
43
- payloadFormat: 'custom',
38
+ algorithm: "hmac-sha256",
39
+ headerName: "svix-signature",
40
+ headerFormat: "raw",
41
+ timestampHeader: "svix-timestamp",
42
+ timestampFormat: "unix",
43
+ payloadFormat: "custom",
44
44
  customConfig: {
45
- signatureFormat: 'v1={signature}',
46
- payloadFormat: '{id}.{timestamp}.{body}',
47
- encoding: 'base64',
48
- secretEncoding: 'base64',
49
- idHeader: 'svix-id',
45
+ signatureFormat: "v1={signature}",
46
+ payloadFormat: "{id}.{timestamp}.{body}",
47
+ encoding: "base64",
48
+ secretEncoding: "base64",
49
+ idHeader: "svix-id",
50
50
  },
51
51
  },
52
- description: 'Clerk webhooks use HMAC-SHA256 with base64 encoding',
52
+ description: "Clerk webhooks use HMAC-SHA256 with base64 encoding",
53
53
  },
54
54
  dodopayments: {
55
- platform: 'dodopayments',
55
+ platform: "dodopayments",
56
56
  signatureConfig: {
57
- algorithm: 'hmac-sha256',
58
- headerName: 'webhook-signature',
59
- headerFormat: 'raw',
60
- timestampHeader: 'webhook-timestamp',
61
- timestampFormat: 'unix',
62
- payloadFormat: 'custom',
57
+ algorithm: "hmac-sha256",
58
+ headerName: "webhook-signature",
59
+ headerFormat: "raw",
60
+ timestampHeader: "webhook-timestamp",
61
+ timestampFormat: "unix",
62
+ payloadFormat: "custom",
63
63
  customConfig: {
64
- signatureFormat: 'v1={signature}',
65
- payloadFormat: '{id}.{timestamp}.{body}',
66
- encoding: 'base64',
67
- secretEncoding: 'base64',
68
- idHeader: 'webhook-id',
64
+ signatureFormat: "v1={signature}",
65
+ payloadFormat: "{id}.{timestamp}.{body}",
66
+ encoding: "base64",
67
+ secretEncoding: "base64",
68
+ idHeader: "webhook-id",
69
69
  },
70
70
  },
71
- description: 'Dodo Payments webhooks use HMAC-SHA256 with svix-style format (Standard Webhooks)',
71
+ description: "Dodo Payments webhooks use HMAC-SHA256 with svix-style format (Standard Webhooks)",
72
72
  },
73
73
  shopify: {
74
- platform: 'shopify',
74
+ platform: "shopify",
75
75
  signatureConfig: {
76
- algorithm: 'hmac-sha256',
77
- headerName: 'x-shopify-hmac-sha256',
78
- headerFormat: 'raw',
79
- payloadFormat: 'raw',
76
+ algorithm: "hmac-sha256",
77
+ headerName: "x-shopify-hmac-sha256",
78
+ headerFormat: "raw",
79
+ payloadFormat: "raw",
80
80
  customConfig: {
81
- encoding: 'base64',
82
- secretEncoding: 'utf8',
81
+ encoding: "base64",
82
+ secretEncoding: "utf8",
83
83
  },
84
84
  },
85
- description: 'Shopify webhooks use HMAC-SHA256 with base64 encoded signature',
85
+ description: "Shopify webhooks use HMAC-SHA256 with base64 encoded signature",
86
86
  },
87
87
  vercel: {
88
- platform: 'vercel',
88
+ platform: "vercel",
89
89
  signatureConfig: {
90
- algorithm: 'hmac-sha256',
91
- headerName: 'x-vercel-signature',
92
- headerFormat: 'raw',
93
- timestampHeader: 'x-vercel-timestamp',
94
- timestampFormat: 'unix',
95
- payloadFormat: 'raw',
90
+ algorithm: "hmac-sha256",
91
+ headerName: "x-vercel-signature",
92
+ headerFormat: "raw",
93
+ timestampHeader: "x-vercel-timestamp",
94
+ timestampFormat: "unix",
95
+ payloadFormat: "raw",
96
96
  },
97
- description: 'Vercel webhooks use HMAC-SHA256',
97
+ description: "Vercel webhooks use HMAC-SHA256",
98
98
  },
99
99
  polar: {
100
- platform: 'polar',
100
+ platform: "polar",
101
101
  signatureConfig: {
102
- algorithm: 'hmac-sha256',
103
- headerName: 'webhook-signature',
104
- headerFormat: 'raw',
105
- timestampHeader: 'webhook-timestamp',
106
- timestampFormat: 'unix',
107
- payloadFormat: 'custom',
102
+ algorithm: "hmac-sha256",
103
+ headerName: "webhook-signature",
104
+ headerFormat: "raw",
105
+ timestampHeader: "webhook-timestamp",
106
+ timestampFormat: "unix",
107
+ payloadFormat: "custom",
108
108
  customConfig: {
109
- signatureFormat: 'v1={signature}',
110
- payloadFormat: '{id}.{timestamp}.{body}',
111
- encoding: 'base64',
112
- secretEncoding: 'utf8',
113
- idHeader: 'webhook-id',
109
+ signatureFormat: "v1={signature}",
110
+ payloadFormat: "{id}.{timestamp}.{body}",
111
+ encoding: "base64",
112
+ secretEncoding: "utf8",
113
+ idHeader: "webhook-id",
114
114
  },
115
115
  },
116
- description: 'Polar webhooks use HMAC-SHA256 with Standard Webhooks format',
116
+ description: "Polar webhooks use HMAC-SHA256 with Standard Webhooks format",
117
117
  },
118
118
  gitlab: {
119
- platform: 'gitlab',
119
+ platform: "gitlab",
120
120
  signatureConfig: {
121
- algorithm: 'custom',
122
- headerName: 'X-Gitlab-Token',
123
- headerFormat: 'raw',
124
- payloadFormat: 'raw',
121
+ algorithm: "custom",
122
+ headerName: "X-Gitlab-Token",
123
+ headerFormat: "raw",
124
+ payloadFormat: "raw",
125
125
  customConfig: {
126
- type: 'token-based',
127
- idHeader: 'X-Gitlab-Token',
126
+ type: "token-based",
127
+ idHeader: "X-Gitlab-Token",
128
128
  },
129
129
  },
130
- description: 'GitLab webhooks use token-based authentication via X-Gitlab-Token header',
130
+ description: "GitLab webhooks use token-based authentication via X-Gitlab-Token header",
131
131
  },
132
132
  paddle: {
133
- platform: 'paddle',
133
+ platform: "paddle",
134
134
  signatureConfig: {
135
- algorithm: 'hmac-sha256',
136
- headerName: 'paddle-signature',
137
- headerFormat: 'comma-separated',
138
- payloadFormat: 'custom',
135
+ algorithm: "hmac-sha256",
136
+ headerName: "paddle-signature",
137
+ headerFormat: "comma-separated",
138
+ payloadFormat: "custom",
139
139
  customConfig: {
140
- timestampKey: 'ts',
141
- signatureKey: 'h1',
142
- payloadFormat: '{timestamp}:{body}',
140
+ timestampKey: "ts",
141
+ signatureKey: "h1",
142
+ payloadFormat: "{timestamp}:{body}",
143
143
  },
144
144
  },
145
- description: 'Paddle webhooks use HMAC-SHA256 with Paddle-Signature (ts/h1) header format',
145
+ description: "Paddle webhooks use HMAC-SHA256 with Paddle-Signature (ts/h1) header format",
146
146
  },
147
147
  razorpay: {
148
- platform: 'razorpay',
148
+ platform: "razorpay",
149
149
  signatureConfig: {
150
- algorithm: 'hmac-sha256',
151
- headerName: 'x-razorpay-signature',
152
- headerFormat: 'raw',
153
- payloadFormat: 'raw',
150
+ algorithm: "hmac-sha256",
151
+ headerName: "x-razorpay-signature",
152
+ headerFormat: "raw",
153
+ payloadFormat: "raw",
154
154
  },
155
- description: 'Razorpay webhooks use HMAC-SHA256 with X-Razorpay-Signature header',
155
+ description: "Razorpay webhooks use HMAC-SHA256 with X-Razorpay-Signature header",
156
156
  },
157
157
  lemonsqueezy: {
158
- platform: 'lemonsqueezy',
158
+ platform: "lemonsqueezy",
159
159
  signatureConfig: {
160
- algorithm: 'hmac-sha256',
161
- headerName: 'x-signature',
162
- headerFormat: 'raw',
163
- payloadFormat: 'raw',
160
+ algorithm: "hmac-sha256",
161
+ headerName: "x-signature",
162
+ headerFormat: "raw",
163
+ payloadFormat: "raw",
164
164
  },
165
- description: 'Lemon Squeezy webhooks use HMAC-SHA256 with X-Signature header',
165
+ description: "Lemon Squeezy webhooks use HMAC-SHA256 with X-Signature header",
166
166
  },
167
167
  workos: {
168
- platform: 'workos',
168
+ platform: "workos",
169
169
  signatureConfig: {
170
- algorithm: 'hmac-sha256',
171
- headerName: 'workos-signature',
172
- headerFormat: 'comma-separated',
173
- payloadFormat: 'custom',
170
+ algorithm: "hmac-sha256",
171
+ headerName: "workos-signature",
172
+ headerFormat: "comma-separated",
173
+ payloadFormat: "custom",
174
174
  customConfig: {
175
- timestampKey: 't',
176
- signatureKey: 'v1',
177
- payloadFormat: '{timestamp}.{body}',
175
+ timestampKey: "t",
176
+ signatureKey: "v1",
177
+ payloadFormat: "{timestamp}.{body}",
178
178
  },
179
179
  },
180
- description: 'WorkOS webhooks use HMAC-SHA256 with WorkOS-Signature (t/v1) format',
180
+ description: "WorkOS webhooks use HMAC-SHA256 with WorkOS-Signature (t/v1) format",
181
181
  },
182
182
  woocommerce: {
183
- platform: 'woocommerce',
183
+ platform: "woocommerce",
184
184
  signatureConfig: {
185
- algorithm: 'hmac-sha256',
186
- headerName: 'x-wc-webhook-signature',
187
- headerFormat: 'raw',
188
- payloadFormat: 'raw',
185
+ algorithm: "hmac-sha256",
186
+ headerName: "x-wc-webhook-signature",
187
+ headerFormat: "raw",
188
+ payloadFormat: "raw",
189
189
  customConfig: {
190
- encoding: 'base64',
191
- secretEncoding: 'utf8',
190
+ encoding: "base64",
191
+ secretEncoding: "utf8",
192
192
  },
193
193
  },
194
- description: 'WooCommerce webhooks use HMAC-SHA256 with base64 encoded signature',
194
+ description: "WooCommerce webhooks use HMAC-SHA256 with base64 encoded signature",
195
195
  },
196
196
  replicateai: {
197
- platform: 'replicateai',
197
+ platform: "replicateai",
198
198
  signatureConfig: {
199
- algorithm: 'hmac-sha256',
200
- headerName: 'webhook-signature',
201
- headerFormat: 'raw',
202
- timestampHeader: 'webhook-timestamp',
203
- timestampFormat: 'unix',
204
- payloadFormat: 'custom',
199
+ algorithm: "hmac-sha256",
200
+ headerName: "webhook-signature",
201
+ headerFormat: "raw",
202
+ timestampHeader: "webhook-timestamp",
203
+ timestampFormat: "unix",
204
+ payloadFormat: "custom",
205
205
  customConfig: {
206
- signatureFormat: 'v1={signature}',
207
- payloadFormat: '{id}.{timestamp}.{body}',
208
- encoding: 'base64',
209
- secretEncoding: 'base64',
210
- idHeader: 'webhook-id',
206
+ signatureFormat: "v1={signature}",
207
+ payloadFormat: "{id}.{timestamp}.{body}",
208
+ encoding: "base64",
209
+ secretEncoding: "base64",
210
+ idHeader: "webhook-id",
211
211
  },
212
212
  },
213
- description: 'Replicate webhooks use HMAC-SHA256 with Standard Webhooks (svix-style) format',
213
+ description: "Replicate webhooks use HMAC-SHA256 with Standard Webhooks (svix-style) format",
214
214
  },
215
215
  falai: {
216
- platform: 'falai',
216
+ platform: "falai",
217
217
  signatureConfig: {
218
- algorithm: 'ed25519',
219
- headerName: 'x-fal-webhook-signature',
220
- headerFormat: 'raw',
221
- payloadFormat: 'custom',
218
+ algorithm: "ed25519",
219
+ headerName: "x-fal-webhook-signature",
220
+ headerFormat: "raw",
221
+ payloadFormat: "custom",
222
222
  customConfig: {
223
- requestIdHeader: 'x-fal-webhook-request-id',
224
- userIdHeader: 'x-fal-webhook-user-id',
225
- timestampHeader: 'x-fal-webhook-timestamp',
226
- jwksUrl: 'https://rest.alpha.fal.ai/.well-known/jwks.json',
223
+ requestIdHeader: "x-fal-webhook-request-id",
224
+ userIdHeader: "x-fal-webhook-user-id",
225
+ timestampHeader: "x-fal-webhook-timestamp",
226
+ jwksUrl: "https://rest.alpha.fal.ai/.well-known/jwks.json",
227
227
  },
228
228
  },
229
- description: 'fal.ai webhooks use ED25519 with JWKS key verification. No secret required — pass empty string.',
229
+ description: "fal.ai webhooks use ED25519 with JWKS key verification. No secret required — pass empty string.",
230
230
  },
231
231
  sentry: {
232
- platform: 'sentry',
232
+ platform: "sentry",
233
233
  signatureConfig: {
234
- algorithm: 'hmac-sha256',
235
- headerName: 'sentry-hook-signature',
236
- headerFormat: 'raw',
237
- timestampHeader: 'sentry-hook-timestamp',
238
- timestampFormat: 'unix',
239
- payloadFormat: 'json-stringified',
240
- idHeader: 'request-id',
234
+ algorithm: "hmac-sha256",
235
+ headerName: "sentry-hook-signature",
236
+ headerFormat: "raw",
237
+ timestampHeader: "sentry-hook-timestamp",
238
+ timestampFormat: "unix",
239
+ payloadFormat: "json-stringified",
240
+ idHeader: "request-id",
241
241
  customConfig: {
242
- issueAlertPayloadPath: 'data.issue_alert',
242
+ issueAlertPayloadPath: "data.issue_alert",
243
243
  },
244
244
  },
245
- description: 'Sentry webhooks use HMAC-SHA256 with JSON stringified body and Request-ID idempotency key',
245
+ description: "Sentry webhooks use HMAC-SHA256 with JSON stringified body and Request-ID idempotency key",
246
246
  },
247
247
  grafana: {
248
- platform: 'grafana',
248
+ platform: "grafana",
249
249
  signatureConfig: {
250
- algorithm: 'hmac-sha256',
251
- headerName: 'x-grafana-alerting-signature',
252
- headerFormat: 'raw',
253
- timestampHeader: 'x-grafana-alerting-timestamp',
254
- timestampFormat: 'unix',
255
- payloadFormat: 'timestamped',
250
+ algorithm: "hmac-sha256",
251
+ headerName: "x-grafana-alerting-signature",
252
+ headerFormat: "raw",
253
+ timestampHeader: "x-grafana-alerting-timestamp",
254
+ timestampFormat: "unix",
255
+ payloadFormat: "timestamped",
256
256
  },
257
- description: 'Grafana 12+ webhooks support HMAC-SHA256 with optional timestamped payload format',
257
+ description: "Grafana 12+ webhooks support HMAC-SHA256 with optional timestamped payload format",
258
258
  },
259
259
  doppler: {
260
- platform: 'doppler',
260
+ platform: "doppler",
261
261
  signatureConfig: {
262
- algorithm: 'hmac-sha256',
263
- headerName: 'x-doppler-signature',
264
- headerFormat: 'prefixed',
265
- prefix: 'sha256=',
266
- payloadFormat: 'raw',
262
+ algorithm: "hmac-sha256",
263
+ headerName: "x-doppler-signature",
264
+ headerFormat: "prefixed",
265
+ prefix: "sha256=",
266
+ payloadFormat: "raw",
267
267
  customConfig: {
268
- dedupHashAlgorithm: 'sha256',
268
+ dedupHashAlgorithm: "sha256",
269
269
  },
270
270
  },
271
- description: 'Doppler webhooks use HMAC-SHA256 with sha256= signature prefix and raw payload signing',
271
+ description: "Doppler webhooks use HMAC-SHA256 with sha256= signature prefix and raw payload signing",
272
272
  },
273
273
  sanity: {
274
- platform: 'sanity',
274
+ platform: "sanity",
275
275
  signatureConfig: {
276
- algorithm: 'hmac-sha256',
277
- headerName: 'sanity-webhook-signature',
278
- headerFormat: 'comma-separated',
279
- payloadFormat: 'timestamped',
276
+ algorithm: "hmac-sha256",
277
+ headerName: "sanity-webhook-signature",
278
+ headerFormat: "comma-separated",
279
+ payloadFormat: "timestamped",
280
280
  customConfig: {
281
- timestampKey: 't',
282
- signatureKey: 'v1',
281
+ timestampKey: "t",
282
+ signatureKey: "v1",
283
+ encoding: "base64",
284
+ secretEncoding: "utf8",
283
285
  },
284
- idHeader: 'idempotency-key',
286
+ idHeader: "idempotency-key",
285
287
  },
286
- description: 'Sanity webhooks use Stripe-compatible signatures with timestamp/body payload and idempotency key header',
288
+ description: "Sanity webhooks use Stripe-compatible HMAC-SHA256 with base64 encoded signature and plain UTF-8 secret",
287
289
  },
288
290
  custom: {
289
- platform: 'custom',
291
+ platform: "custom",
290
292
  signatureConfig: {
291
- algorithm: 'hmac-sha256',
292
- headerName: 'x-webhook-signature',
293
- headerFormat: 'raw',
294
- payloadFormat: 'raw',
293
+ algorithm: "hmac-sha256",
294
+ headerName: "x-webhook-signature",
295
+ headerFormat: "raw",
296
+ payloadFormat: "raw",
295
297
  customConfig: {
296
- type: 'token-based',
297
- idHeader: 'x-webhook-id',
298
+ type: "token-based",
299
+ idHeader: "x-webhook-id",
298
300
  },
299
301
  },
300
- description: 'Custom webhook configuration (supports token-based overrides via customConfig)',
302
+ description: "Custom webhook configuration (supports token-based overrides via customConfig)",
301
303
  },
302
304
  unknown: {
303
- platform: 'unknown',
305
+ platform: "unknown",
304
306
  signatureConfig: {
305
- algorithm: 'hmac-sha256',
306
- headerName: 'x-webhook-signature',
307
- headerFormat: 'raw',
308
- payloadFormat: 'raw',
307
+ algorithm: "hmac-sha256",
308
+ headerName: "x-webhook-signature",
309
+ headerFormat: "raw",
310
+ payloadFormat: "raw",
309
311
  },
310
- description: 'Unknown platform - using default HMAC-SHA256',
312
+ description: "Unknown platform - using default HMAC-SHA256",
311
313
  },
312
314
  };
313
315
  function getPlatformAlgorithmConfig(platform) {
@@ -327,15 +329,15 @@ function validateSignatureConfig(config) {
327
329
  return false;
328
330
  }
329
331
  switch (config.algorithm) {
330
- case 'hmac-sha256':
331
- case 'hmac-sha1':
332
- case 'hmac-sha512':
332
+ case "hmac-sha256":
333
+ case "hmac-sha1":
334
+ case "hmac-sha512":
333
335
  return true;
334
- case 'rsa-sha256':
336
+ case "rsa-sha256":
335
337
  return !!config.customConfig?.publicKey;
336
- case 'ed25519':
338
+ case "ed25519":
337
339
  return !!config.customConfig?.publicKey || !!config.customConfig?.jwksUrl;
338
- case 'custom':
340
+ case "custom":
339
341
  return !!config.customConfig;
340
342
  default:
341
343
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hookflo/tern",
3
- "version": "3.0.3",
3
+ "version": "3.0.5",
4
4
  "description": "A robust, scalable webhook verification framework supporting multiple platforms and signature algorithms",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",