hooklatch 0.0.0-stage → 1.0.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.
Files changed (301) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +438 -2
  3. package/dist/adapters/cloudflare.d.ts +11 -0
  4. package/dist/adapters/cloudflare.d.ts.map +1 -0
  5. package/dist/adapters/cloudflare.js +27 -0
  6. package/dist/adapters/cloudflare.js.map +1 -0
  7. package/dist/adapters/express.d.ts +9 -0
  8. package/dist/adapters/express.d.ts.map +1 -0
  9. package/dist/adapters/express.js +63 -0
  10. package/dist/adapters/express.js.map +1 -0
  11. package/dist/adapters/hono.d.ts +12 -0
  12. package/dist/adapters/hono.d.ts.map +1 -0
  13. package/dist/adapters/hono.js +28 -0
  14. package/dist/adapters/hono.js.map +1 -0
  15. package/dist/adapters/nextjs.d.ts +6 -0
  16. package/dist/adapters/nextjs.d.ts.map +1 -0
  17. package/dist/adapters/nextjs.js +56 -0
  18. package/dist/adapters/nextjs.js.map +1 -0
  19. package/dist/adapters/shared.d.ts +8 -0
  20. package/dist/adapters/shared.d.ts.map +1 -0
  21. package/dist/adapters/shared.js +53 -0
  22. package/dist/adapters/shared.js.map +1 -0
  23. package/dist/cjs/adapters/cloudflare.cjs +29 -0
  24. package/dist/cjs/adapters/cloudflare.d.cts +10 -0
  25. package/dist/cjs/adapters/express.cjs +65 -0
  26. package/dist/cjs/adapters/express.d.cts +8 -0
  27. package/dist/cjs/adapters/hono.cjs +30 -0
  28. package/dist/cjs/adapters/hono.d.cts +11 -0
  29. package/dist/cjs/adapters/nextjs.cjs +58 -0
  30. package/dist/cjs/adapters/nextjs.d.cts +5 -0
  31. package/dist/cjs/adapters/shared.cjs +58 -0
  32. package/dist/cjs/adapters/shared.d.cts +7 -0
  33. package/dist/cjs/core.cjs +30 -0
  34. package/dist/cjs/core.d.cts +5 -0
  35. package/dist/cjs/diagnostics/catalog.cjs +341 -0
  36. package/dist/cjs/diagnostics/catalog.d.cts +19 -0
  37. package/dist/cjs/diagnostics/index.cjs +90 -0
  38. package/dist/cjs/diagnostics/index.d.cts +5 -0
  39. package/dist/cjs/diagnostics/types.cjs +2 -0
  40. package/dist/cjs/diagnostics/types.d.cts +20 -0
  41. package/dist/cjs/errors.cjs +13 -0
  42. package/dist/cjs/errors.d.cts +6 -0
  43. package/dist/cjs/index.cjs +9 -0
  44. package/dist/cjs/index.d.cts +3 -0
  45. package/dist/cjs/internal/body.cjs +50 -0
  46. package/dist/cjs/internal/body.d.cts +2 -0
  47. package/dist/cjs/internal/bytes.cjs +43 -0
  48. package/dist/cjs/internal/bytes.d.cts +4 -0
  49. package/dist/cjs/internal/crypto.cjs +52 -0
  50. package/dist/cjs/internal/crypto.d.cts +3 -0
  51. package/dist/cjs/internal/headers.cjs +72 -0
  52. package/dist/cjs/internal/headers.d.cts +2 -0
  53. package/dist/cjs/internal/options.cjs +130 -0
  54. package/dist/cjs/internal/options.d.cts +7 -0
  55. package/dist/cjs/internal/prepare.cjs +11 -0
  56. package/dist/cjs/internal/prepare.d.cts +4 -0
  57. package/dist/cjs/internal/provider-options.cjs +72 -0
  58. package/dist/cjs/internal/provider-options.d.cts +6 -0
  59. package/dist/cjs/internal/provider.cjs +2 -0
  60. package/dist/cjs/internal/provider.d.cts +39 -0
  61. package/dist/cjs/internal/verification.cjs +71 -0
  62. package/dist/cjs/internal/verification.d.cts +12 -0
  63. package/dist/cjs/providers/clerk.cjs +15 -0
  64. package/dist/cjs/providers/clerk.d.cts +9 -0
  65. package/dist/cjs/providers/dodo-payments.cjs +26 -0
  66. package/dist/cjs/providers/dodo-payments.d.cts +20 -0
  67. package/dist/cjs/providers/doppler.cjs +71 -0
  68. package/dist/cjs/providers/doppler.d.cts +37 -0
  69. package/dist/cjs/providers/fal.cjs +80 -0
  70. package/dist/cjs/providers/fal.d.cts +13 -0
  71. package/dist/cjs/providers/github.cjs +52 -0
  72. package/dist/cjs/providers/github.d.cts +7 -0
  73. package/dist/cjs/providers/gitlab.cjs +26 -0
  74. package/dist/cjs/providers/gitlab.d.cts +20 -0
  75. package/dist/cjs/providers/grafana.cjs +180 -0
  76. package/dist/cjs/providers/grafana.d.cts +35 -0
  77. package/dist/cjs/providers/index.cjs +110 -0
  78. package/dist/cjs/providers/index.d.cts +26 -0
  79. package/dist/cjs/providers/lemon-squeezy.cjs +36 -0
  80. package/dist/cjs/providers/lemon-squeezy.d.cts +15 -0
  81. package/dist/cjs/providers/linear.cjs +58 -0
  82. package/dist/cjs/providers/linear.d.cts +36 -0
  83. package/dist/cjs/providers/paddle.cjs +105 -0
  84. package/dist/cjs/providers/paddle.d.cts +14 -0
  85. package/dist/cjs/providers/polar.cjs +80 -0
  86. package/dist/cjs/providers/polar.d.cts +25 -0
  87. package/dist/cjs/providers/razorpay.cjs +43 -0
  88. package/dist/cjs/providers/razorpay.d.cts +19 -0
  89. package/dist/cjs/providers/replicate.cjs +25 -0
  90. package/dist/cjs/providers/replicate.d.cts +19 -0
  91. package/dist/cjs/providers/sanity.cjs +161 -0
  92. package/dist/cjs/providers/sanity.d.cts +38 -0
  93. package/dist/cjs/providers/sentry.cjs +47 -0
  94. package/dist/cjs/providers/sentry.d.cts +25 -0
  95. package/dist/cjs/providers/shared.cjs +49 -0
  96. package/dist/cjs/providers/shared.d.cts +14 -0
  97. package/dist/cjs/providers/shopify.cjs +40 -0
  98. package/dist/cjs/providers/shopify.d.cts +8 -0
  99. package/dist/cjs/providers/standard-webhooks-protocol.cjs +97 -0
  100. package/dist/cjs/providers/standard-webhooks-protocol.d.cts +14 -0
  101. package/dist/cjs/providers/standard-webhooks.cjs +15 -0
  102. package/dist/cjs/providers/standard-webhooks.d.cts +9 -0
  103. package/dist/cjs/providers/stripe.cjs +81 -0
  104. package/dist/cjs/providers/stripe.d.cts +7 -0
  105. package/dist/cjs/providers/svix.cjs +63 -0
  106. package/dist/cjs/providers/svix.d.cts +9 -0
  107. package/dist/cjs/providers/vercel.cjs +39 -0
  108. package/dist/cjs/providers/vercel.d.cts +15 -0
  109. package/dist/cjs/providers/workos.cjs +120 -0
  110. package/dist/cjs/providers/workos.d.cts +32 -0
  111. package/dist/cjs/types.cjs +2 -0
  112. package/dist/cjs/types.d.cts +68 -0
  113. package/dist/cli/args.d.ts +86 -0
  114. package/dist/cli/args.d.ts.map +1 -0
  115. package/dist/cli/args.js +358 -0
  116. package/dist/cli/args.js.map +1 -0
  117. package/dist/cli/filesystem.d.ts +15 -0
  118. package/dist/cli/filesystem.d.ts.map +1 -0
  119. package/dist/cli/filesystem.js +170 -0
  120. package/dist/cli/filesystem.js.map +1 -0
  121. package/dist/cli/index.d.ts +3 -0
  122. package/dist/cli/index.d.ts.map +1 -0
  123. package/dist/cli/index.js +64 -0
  124. package/dist/cli/index.js.map +1 -0
  125. package/dist/cli/templates.d.ts +13 -0
  126. package/dist/cli/templates.d.ts.map +1 -0
  127. package/dist/cli/templates.js +297 -0
  128. package/dist/cli/templates.js.map +1 -0
  129. package/dist/core.d.ts +6 -0
  130. package/dist/core.d.ts.map +1 -0
  131. package/dist/core.js +26 -0
  132. package/dist/core.js.map +1 -0
  133. package/dist/diagnostics/catalog.d.ts +20 -0
  134. package/dist/diagnostics/catalog.d.ts.map +1 -0
  135. package/dist/diagnostics/catalog.js +335 -0
  136. package/dist/diagnostics/catalog.js.map +1 -0
  137. package/dist/diagnostics/index.d.ts +6 -0
  138. package/dist/diagnostics/index.d.ts.map +1 -0
  139. package/dist/diagnostics/index.js +88 -0
  140. package/dist/diagnostics/index.js.map +1 -0
  141. package/dist/diagnostics/types.d.ts +21 -0
  142. package/dist/diagnostics/types.d.ts.map +1 -0
  143. package/dist/diagnostics/types.js +2 -0
  144. package/dist/diagnostics/types.js.map +1 -0
  145. package/dist/errors.d.ts +7 -0
  146. package/dist/errors.d.ts.map +1 -0
  147. package/dist/errors.js +10 -0
  148. package/dist/errors.js.map +1 -0
  149. package/dist/index.d.ts +4 -0
  150. package/dist/index.d.ts.map +1 -0
  151. package/dist/index.js +3 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/internal/body.d.ts +3 -0
  154. package/dist/internal/body.d.ts.map +1 -0
  155. package/dist/internal/body.js +48 -0
  156. package/dist/internal/body.js.map +1 -0
  157. package/dist/internal/bytes.d.ts +5 -0
  158. package/dist/internal/bytes.d.ts.map +1 -0
  159. package/dist/internal/bytes.js +38 -0
  160. package/dist/internal/bytes.js.map +1 -0
  161. package/dist/internal/crypto.d.ts +4 -0
  162. package/dist/internal/crypto.d.ts.map +1 -0
  163. package/dist/internal/crypto.js +49 -0
  164. package/dist/internal/crypto.js.map +1 -0
  165. package/dist/internal/headers.d.ts +3 -0
  166. package/dist/internal/headers.d.ts.map +1 -0
  167. package/dist/internal/headers.js +70 -0
  168. package/dist/internal/headers.js.map +1 -0
  169. package/dist/internal/options.d.ts +8 -0
  170. package/dist/internal/options.d.ts.map +1 -0
  171. package/dist/internal/options.js +128 -0
  172. package/dist/internal/options.js.map +1 -0
  173. package/dist/internal/prepare.d.ts +5 -0
  174. package/dist/internal/prepare.d.ts.map +1 -0
  175. package/dist/internal/prepare.js +9 -0
  176. package/dist/internal/prepare.js.map +1 -0
  177. package/dist/internal/provider-options.d.ts +7 -0
  178. package/dist/internal/provider-options.d.ts.map +1 -0
  179. package/dist/internal/provider-options.js +69 -0
  180. package/dist/internal/provider-options.js.map +1 -0
  181. package/dist/internal/provider.d.ts +40 -0
  182. package/dist/internal/provider.d.ts.map +1 -0
  183. package/dist/internal/provider.js +2 -0
  184. package/dist/internal/provider.js.map +1 -0
  185. package/dist/internal/verification.d.ts +13 -0
  186. package/dist/internal/verification.d.ts.map +1 -0
  187. package/dist/internal/verification.js +66 -0
  188. package/dist/internal/verification.js.map +1 -0
  189. package/dist/node/adapters/cloudflare.d.ts +1 -0
  190. package/dist/node/adapters/cloudflare.js +3 -0
  191. package/dist/node/adapters/express.d.ts +1 -0
  192. package/dist/node/adapters/express.js +3 -0
  193. package/dist/node/adapters/hono.d.ts +1 -0
  194. package/dist/node/adapters/hono.js +3 -0
  195. package/dist/node/adapters/nextjs.d.ts +1 -0
  196. package/dist/node/adapters/nextjs.js +3 -0
  197. package/dist/node/diagnostics/index.d.ts +1 -0
  198. package/dist/node/diagnostics/index.js +3 -0
  199. package/dist/node/index.d.ts +1 -0
  200. package/dist/node/index.js +6 -0
  201. package/dist/providers/clerk.d.ts +10 -0
  202. package/dist/providers/clerk.d.ts.map +1 -0
  203. package/dist/providers/clerk.js +13 -0
  204. package/dist/providers/clerk.js.map +1 -0
  205. package/dist/providers/dodo-payments.d.ts +21 -0
  206. package/dist/providers/dodo-payments.d.ts.map +1 -0
  207. package/dist/providers/dodo-payments.js +24 -0
  208. package/dist/providers/dodo-payments.js.map +1 -0
  209. package/dist/providers/doppler.d.ts +38 -0
  210. package/dist/providers/doppler.d.ts.map +1 -0
  211. package/dist/providers/doppler.js +69 -0
  212. package/dist/providers/doppler.js.map +1 -0
  213. package/dist/providers/fal.d.ts +14 -0
  214. package/dist/providers/fal.d.ts.map +1 -0
  215. package/dist/providers/fal.js +78 -0
  216. package/dist/providers/fal.js.map +1 -0
  217. package/dist/providers/github.d.ts +8 -0
  218. package/dist/providers/github.d.ts.map +1 -0
  219. package/dist/providers/github.js +50 -0
  220. package/dist/providers/github.js.map +1 -0
  221. package/dist/providers/gitlab.d.ts +21 -0
  222. package/dist/providers/gitlab.d.ts.map +1 -0
  223. package/dist/providers/gitlab.js +24 -0
  224. package/dist/providers/gitlab.js.map +1 -0
  225. package/dist/providers/grafana.d.ts +36 -0
  226. package/dist/providers/grafana.d.ts.map +1 -0
  227. package/dist/providers/grafana.js +178 -0
  228. package/dist/providers/grafana.js.map +1 -0
  229. package/dist/providers/index.d.ts +27 -0
  230. package/dist/providers/index.d.ts.map +1 -0
  231. package/dist/providers/index.js +89 -0
  232. package/dist/providers/index.js.map +1 -0
  233. package/dist/providers/lemon-squeezy.d.ts +16 -0
  234. package/dist/providers/lemon-squeezy.d.ts.map +1 -0
  235. package/dist/providers/lemon-squeezy.js +34 -0
  236. package/dist/providers/lemon-squeezy.js.map +1 -0
  237. package/dist/providers/linear.d.ts +37 -0
  238. package/dist/providers/linear.d.ts.map +1 -0
  239. package/dist/providers/linear.js +56 -0
  240. package/dist/providers/linear.js.map +1 -0
  241. package/dist/providers/paddle.d.ts +15 -0
  242. package/dist/providers/paddle.d.ts.map +1 -0
  243. package/dist/providers/paddle.js +103 -0
  244. package/dist/providers/paddle.js.map +1 -0
  245. package/dist/providers/polar.d.ts +26 -0
  246. package/dist/providers/polar.d.ts.map +1 -0
  247. package/dist/providers/polar.js +78 -0
  248. package/dist/providers/polar.js.map +1 -0
  249. package/dist/providers/razorpay.d.ts +20 -0
  250. package/dist/providers/razorpay.d.ts.map +1 -0
  251. package/dist/providers/razorpay.js +41 -0
  252. package/dist/providers/razorpay.js.map +1 -0
  253. package/dist/providers/replicate.d.ts +20 -0
  254. package/dist/providers/replicate.d.ts.map +1 -0
  255. package/dist/providers/replicate.js +23 -0
  256. package/dist/providers/replicate.js.map +1 -0
  257. package/dist/providers/sanity.d.ts +39 -0
  258. package/dist/providers/sanity.d.ts.map +1 -0
  259. package/dist/providers/sanity.js +159 -0
  260. package/dist/providers/sanity.js.map +1 -0
  261. package/dist/providers/sentry.d.ts +26 -0
  262. package/dist/providers/sentry.d.ts.map +1 -0
  263. package/dist/providers/sentry.js +45 -0
  264. package/dist/providers/sentry.js.map +1 -0
  265. package/dist/providers/shared.d.ts +15 -0
  266. package/dist/providers/shared.d.ts.map +1 -0
  267. package/dist/providers/shared.js +40 -0
  268. package/dist/providers/shared.js.map +1 -0
  269. package/dist/providers/shopify.d.ts +9 -0
  270. package/dist/providers/shopify.d.ts.map +1 -0
  271. package/dist/providers/shopify.js +38 -0
  272. package/dist/providers/shopify.js.map +1 -0
  273. package/dist/providers/standard-webhooks-protocol.d.ts +15 -0
  274. package/dist/providers/standard-webhooks-protocol.d.ts.map +1 -0
  275. package/dist/providers/standard-webhooks-protocol.js +95 -0
  276. package/dist/providers/standard-webhooks-protocol.js.map +1 -0
  277. package/dist/providers/standard-webhooks.d.ts +10 -0
  278. package/dist/providers/standard-webhooks.d.ts.map +1 -0
  279. package/dist/providers/standard-webhooks.js +13 -0
  280. package/dist/providers/standard-webhooks.js.map +1 -0
  281. package/dist/providers/stripe.d.ts +8 -0
  282. package/dist/providers/stripe.d.ts.map +1 -0
  283. package/dist/providers/stripe.js +79 -0
  284. package/dist/providers/stripe.js.map +1 -0
  285. package/dist/providers/svix.d.ts +10 -0
  286. package/dist/providers/svix.d.ts.map +1 -0
  287. package/dist/providers/svix.js +61 -0
  288. package/dist/providers/svix.js.map +1 -0
  289. package/dist/providers/vercel.d.ts +16 -0
  290. package/dist/providers/vercel.d.ts.map +1 -0
  291. package/dist/providers/vercel.js +37 -0
  292. package/dist/providers/vercel.js.map +1 -0
  293. package/dist/providers/workos.d.ts +33 -0
  294. package/dist/providers/workos.d.ts.map +1 -0
  295. package/dist/providers/workos.js +118 -0
  296. package/dist/providers/workos.js.map +1 -0
  297. package/dist/types.d.ts +69 -0
  298. package/dist/types.d.ts.map +1 -0
  299. package/dist/types.js +2 -0
  300. package/dist/types.js.map +1 -0
  301. package/package.json +200 -4
@@ -0,0 +1,178 @@
1
+ import { HooklatchError } from '../errors.js';
2
+ import { concatBytes, utf8 } from '../internal/bytes.js';
3
+ import { decodeHexSignature, decodeLiteralSecret, failure, isCanonicalTimestamp } from './shared.js';
4
+ /** Grafana's own default signature header name. */
5
+ const DEFAULT_SIGNATURE_HEADER = 'x-grafana-alerting-signature';
6
+ /** RFC 9110 field-name token characters. */
7
+ const FIELD_NAME_TOKEN = /^[!#$%&'*+.^_`|~\dA-Za-z-]+$/;
8
+ /**
9
+ * Authentication and framing header names that a configured Grafana header
10
+ * must not replace. This is Hooklatch configuration policy, not a Grafana
11
+ * rule: Grafana itself does not restrict the configured header names.
12
+ */
13
+ const RESERVED_HEADER_NAMES = new Set([
14
+ 'host',
15
+ 'content-length',
16
+ 'transfer-encoding',
17
+ 'connection',
18
+ 'upgrade',
19
+ 'trailer',
20
+ 'te',
21
+ 'proxy-authorization',
22
+ 'proxy-authenticate',
23
+ 'authorization',
24
+ 'cookie',
25
+ 'set-cookie',
26
+ ]);
27
+ const ALLOWED_OPTION_KEYS = new Set([
28
+ 'mode',
29
+ 'signatureHeader',
30
+ 'timestampHeader',
31
+ ]);
32
+ const INVALID_OPTIONS_MESSAGE = 'Invalid Grafana provider options.';
33
+ function invalidOptions() {
34
+ throw new HooklatchError('invalid-options', INVALID_OPTIONS_MESSAGE);
35
+ }
36
+ function isOptionsObject(options) {
37
+ return typeof options === 'object' && options !== null && !Array.isArray(options);
38
+ }
39
+ function isHeaderNameText(value) {
40
+ return typeof value === 'string';
41
+ }
42
+ function isConfiguredHeaderName(value) {
43
+ return FIELD_NAME_TOKEN.test(value) && !RESERVED_HEADER_NAMES.has(value.toLowerCase());
44
+ }
45
+ /** Only the three documented option keys are accepted; nothing is inherited. */
46
+ function hasUnexpectedOptionKey(options) {
47
+ for (const key of Object.keys(options)) {
48
+ if (!ALLOWED_OPTION_KEYS.has(key))
49
+ return true;
50
+ }
51
+ for (const key of Object.getOwnPropertySymbols(options)) {
52
+ if (Object.prototype.propertyIsEnumerable.call(options, key))
53
+ return true;
54
+ }
55
+ return false;
56
+ }
57
+ function readSignatureHeader(options) {
58
+ if (!Object.hasOwn(options, 'signatureHeader'))
59
+ return DEFAULT_SIGNATURE_HEADER;
60
+ const value = options.signatureHeader;
61
+ if (!isHeaderNameText(value) || !isConfiguredHeaderName(value))
62
+ invalidOptions();
63
+ return value.toLowerCase();
64
+ }
65
+ function readTimestampHeader(options, mode, signatureHeader) {
66
+ const configured = Object.hasOwn(options, 'timestampHeader');
67
+ if (mode === 'body') {
68
+ // Body-only mode has no timestamp header, not even an explicit undefined.
69
+ if (configured)
70
+ invalidOptions();
71
+ return null;
72
+ }
73
+ if (!configured)
74
+ invalidOptions();
75
+ const value = options.timestampHeader;
76
+ if (!isHeaderNameText(value) || !isConfiguredHeaderName(value))
77
+ invalidOptions();
78
+ const normalized = value.toLowerCase();
79
+ // A collision would make the two headers unreadable, so it is rejected.
80
+ if (normalized === signatureHeader)
81
+ invalidOptions();
82
+ return normalized;
83
+ }
84
+ function buildConfiguration(options) {
85
+ if (!isOptionsObject(options))
86
+ invalidOptions();
87
+ if (hasUnexpectedOptionKey(options))
88
+ invalidOptions();
89
+ if (!Object.hasOwn(options, 'mode'))
90
+ invalidOptions();
91
+ const mode = options.mode;
92
+ if (mode !== 'body' && mode !== 'timestamped')
93
+ invalidOptions();
94
+ const signatureHeader = readSignatureHeader(options);
95
+ const timestampHeader = readTimestampHeader(options, mode, signatureHeader);
96
+ return { signatureHeader, timestampHeader };
97
+ }
98
+ /**
99
+ * Validate and snapshot the configuration. Any getter or proxy trap observed
100
+ * while reading the options is contained here and reported as one generic
101
+ * invalid-options error that never echoes the underlying exception.
102
+ */
103
+ function snapshotConfiguration(options) {
104
+ try {
105
+ return buildConfiguration(options);
106
+ }
107
+ catch {
108
+ throw new HooklatchError('invalid-options', INVALID_OPTIONS_MESSAGE);
109
+ }
110
+ }
111
+ /**
112
+ * Parse the configured Grafana headers into the bytes Grafana signs.
113
+ *
114
+ * The signature header is always read first: its structure decides the
115
+ * failure before any timestamp is inspected. Freshness and the HMAC check
116
+ * belong to core, so this only reports the signature and the signed bytes.
117
+ */
118
+ function parseGrafana(configuration, headers, rawBody) {
119
+ const signatureRaw = headers.get(configuration.signatureHeader);
120
+ if (signatureRaw === undefined || signatureRaw.trim() === '') {
121
+ return failure('missing-signature', 'No Grafana signature header was provided.');
122
+ }
123
+ const signature = decodeHexSignature(signatureRaw);
124
+ if (signature === null) {
125
+ return failure('malformed-signature', 'The Grafana signature header is malformed.');
126
+ }
127
+ const timestampHeader = configuration.timestampHeader;
128
+ if (timestampHeader === null) {
129
+ return {
130
+ ok: true,
131
+ signatures: [signature],
132
+ signedContent: rawBody,
133
+ identity: { deliveryId: null, eventId: null, timestamp: null, authenticatedFields: [] },
134
+ };
135
+ }
136
+ const timestampRaw = headers.get(timestampHeader);
137
+ if (timestampRaw === undefined || timestampRaw.trim() === '') {
138
+ return failure('missing-timestamp', 'No Grafana timestamp header was provided.');
139
+ }
140
+ if (!isCanonicalTimestamp(timestampRaw)) {
141
+ return failure('malformed-signature', 'The Grafana timestamp is malformed.');
142
+ }
143
+ return {
144
+ ok: true,
145
+ signatures: [signature],
146
+ signedContent: concatBytes(utf8(`${timestampRaw}:`), rawBody),
147
+ identity: {
148
+ deliveryId: null,
149
+ eventId: null,
150
+ timestamp: Number(timestampRaw),
151
+ authenticatedFields: ['timestamp'],
152
+ },
153
+ };
154
+ }
155
+ /**
156
+ * Create a Grafana descriptor for the given receiver configuration.
157
+ *
158
+ * The configuration is trusted application input, never derived from a
159
+ * request. Header names select which header is read; they are lookup
160
+ * configuration and are not part of the signed bytes, so the same secret,
161
+ * body and timestamp produce the same MAC under any configured header name.
162
+ *
163
+ * The returned descriptor is not registered with the public provider
164
+ * registry; the coordinator owns that integration.
165
+ */
166
+ export function createGrafanaDescriptor(options) {
167
+ const configuration = snapshotConfiguration(options);
168
+ return {
169
+ provider: 'grafana',
170
+ decodeSecret(secret) {
171
+ return decodeLiteralSecret(secret, 'Grafana');
172
+ },
173
+ parse(headers, rawBody) {
174
+ return parseGrafana(configuration, headers, rawBody);
175
+ },
176
+ };
177
+ }
178
+ //# sourceMappingURL=grafana.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grafana.js","sourceRoot":"","sources":["../../src/providers/grafana.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { AnyProviderDescriptor } from '../internal/provider.js';
2
+ import type { Provider, GrafanaOptions, PolarOptions } from '../types.js';
3
+ import { clerkDescriptor } from './clerk.js';
4
+ import { githubDescriptor } from './github.js';
5
+ import { shopifyDescriptor } from './shopify.js';
6
+ import { standardWebhooksDescriptor } from './standard-webhooks.js';
7
+ import { stripeDescriptor } from './stripe.js';
8
+ import { svixDescriptor } from './svix.js';
9
+ import { razorpayDescriptor } from './razorpay.js';
10
+ import { paddleDescriptor } from './paddle.js';
11
+ import { lemonSqueezyDescriptor } from './lemon-squeezy.js';
12
+ import { dodoPaymentsDescriptor } from './dodo-payments.js';
13
+ import { gitlabDescriptor } from './gitlab.js';
14
+ import { replicateDescriptor } from './replicate.js';
15
+ import { workosDescriptor } from './workos.js';
16
+ import { sentryDescriptor } from './sentry.js';
17
+ import { dopplerDescriptor } from './doppler.js';
18
+ import { sanityDescriptor } from './sanity.js';
19
+ import { linearDescriptor } from './linear.js';
20
+ import { vercelDescriptor } from './vercel.js';
21
+ import { falDescriptor } from './fal.js';
22
+ /** Registry order is part of the internal contract; append new providers only. */
23
+ export declare const SUPPORTED_PROVIDERS: readonly ["stripe", "github", "shopify", "standard-webhooks", "clerk", "svix", "razorpay", "paddle", "lemon-squeezy", "dodo-payments", "gitlab", "replicate", "workos", "sentry", "doppler", "sanity", "grafana", "polar", "linear", "vercel", "fal"];
24
+ /** Resolve the pure descriptor for a supported provider. */
25
+ export declare function getProviderDescriptor(provider: Provider, providerOptions?: GrafanaOptions | PolarOptions): AnyProviderDescriptor;
26
+ export { clerkDescriptor, githubDescriptor, shopifyDescriptor, standardWebhooksDescriptor, stripeDescriptor, svixDescriptor, razorpayDescriptor, paddleDescriptor, lemonSqueezyDescriptor, dodoPaymentsDescriptor, gitlabDescriptor, replicateDescriptor, workosDescriptor, sentryDescriptor, dopplerDescriptor, sanityDescriptor, linearDescriptor, vercelDescriptor, falDescriptor, };
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,uPAsBQ,CAAC;AAwBzC,4DAA4D;AAC5D,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,CAAC,EAAE,cAAc,GAAG,YAAY,GAAG,qBAAqB,CAwBhI;AAED,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,0BAA0B,EAC1B,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,GACd,CAAC"}
@@ -0,0 +1,89 @@
1
+ import { HooklatchError } from '../errors.js';
2
+ import { createGrafanaDescriptor } from './grafana.js';
3
+ import { createPolarDescriptor } from './polar.js';
4
+ import { clerkDescriptor } from './clerk.js';
5
+ import { githubDescriptor } from './github.js';
6
+ import { shopifyDescriptor } from './shopify.js';
7
+ import { standardWebhooksDescriptor } from './standard-webhooks.js';
8
+ import { stripeDescriptor } from './stripe.js';
9
+ import { svixDescriptor } from './svix.js';
10
+ import { razorpayDescriptor } from './razorpay.js';
11
+ import { paddleDescriptor } from './paddle.js';
12
+ import { lemonSqueezyDescriptor } from './lemon-squeezy.js';
13
+ import { dodoPaymentsDescriptor } from './dodo-payments.js';
14
+ import { gitlabDescriptor } from './gitlab.js';
15
+ import { replicateDescriptor } from './replicate.js';
16
+ import { workosDescriptor } from './workos.js';
17
+ import { sentryDescriptor } from './sentry.js';
18
+ import { dopplerDescriptor } from './doppler.js';
19
+ import { sanityDescriptor } from './sanity.js';
20
+ import { linearDescriptor } from './linear.js';
21
+ import { vercelDescriptor } from './vercel.js';
22
+ import { falDescriptor } from './fal.js';
23
+ /** Registry order is part of the internal contract; append new providers only. */
24
+ export const SUPPORTED_PROVIDERS = [
25
+ 'stripe',
26
+ 'github',
27
+ 'shopify',
28
+ 'standard-webhooks',
29
+ 'clerk',
30
+ 'svix',
31
+ 'razorpay',
32
+ 'paddle',
33
+ 'lemon-squeezy',
34
+ 'dodo-payments',
35
+ 'gitlab',
36
+ 'replicate',
37
+ 'workos',
38
+ 'sentry',
39
+ 'doppler',
40
+ 'sanity',
41
+ 'grafana',
42
+ 'polar',
43
+ 'linear',
44
+ 'vercel',
45
+ 'fal',
46
+ ];
47
+ const DESCRIPTORS = {
48
+ stripe: stripeDescriptor,
49
+ github: githubDescriptor,
50
+ shopify: shopifyDescriptor,
51
+ 'standard-webhooks': standardWebhooksDescriptor,
52
+ clerk: clerkDescriptor,
53
+ svix: svixDescriptor,
54
+ razorpay: razorpayDescriptor,
55
+ paddle: paddleDescriptor,
56
+ 'lemon-squeezy': lemonSqueezyDescriptor,
57
+ 'dodo-payments': dodoPaymentsDescriptor,
58
+ gitlab: gitlabDescriptor,
59
+ replicate: replicateDescriptor,
60
+ workos: workosDescriptor,
61
+ sentry: sentryDescriptor,
62
+ doppler: dopplerDescriptor,
63
+ sanity: sanityDescriptor,
64
+ linear: linearDescriptor,
65
+ vercel: vercelDescriptor,
66
+ fal: falDescriptor,
67
+ };
68
+ /** Resolve the pure descriptor for a supported provider. */
69
+ export function getProviderDescriptor(provider, providerOptions) {
70
+ if (provider === 'grafana') {
71
+ if (providerOptions === undefined || !('mode' in providerOptions)) {
72
+ throw new HooklatchError('invalid-options', 'Invalid provider options.');
73
+ }
74
+ return createGrafanaDescriptor(providerOptions);
75
+ }
76
+ if (provider === 'polar') {
77
+ if (providerOptions !== undefined && 'mode' in providerOptions) {
78
+ throw new HooklatchError('invalid-options', 'Invalid provider options.');
79
+ }
80
+ return createPolarDescriptor(providerOptions);
81
+ }
82
+ const descriptor = Object.hasOwn(DESCRIPTORS, provider) ? DESCRIPTORS[provider] : undefined;
83
+ if (descriptor === undefined) {
84
+ throw new HooklatchError('unknown-provider', 'Unsupported webhook provider.');
85
+ }
86
+ return descriptor;
87
+ }
88
+ export { clerkDescriptor, githubDescriptor, shopifyDescriptor, standardWebhooksDescriptor, stripeDescriptor, svixDescriptor, razorpayDescriptor, paddleDescriptor, lemonSqueezyDescriptor, dodoPaymentsDescriptor, gitlabDescriptor, replicateDescriptor, workosDescriptor, sentryDescriptor, dopplerDescriptor, sanityDescriptor, linearDescriptor, vercelDescriptor, falDescriptor, };
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { NormalizedHeaders, ParseResult } from '../internal/provider.js';
2
+ /**
3
+ * Lemon Squeezy `X-Signature`: a single 64-character hex HMAC-SHA256 digest of
4
+ * the exact raw body, keyed with the literal webhook signing secret. The docs
5
+ * suggest 6-40 character secrets, but that UI guidance is not enforced as a
6
+ * cryptographic limit. No timestamp or event identifier is documented for
7
+ * verification, so identity stays null and unsigned (`X-Event-Name` is
8
+ * metadata and is not interpreted).
9
+ * Source: https://docs.lemonsqueezy.com/help/webhooks/signing-requests
10
+ */
11
+ export declare const lemonSqueezyDescriptor: {
12
+ provider: "lemon-squeezy";
13
+ decodeSecret(secret: string): Uint8Array;
14
+ parse(headers: NormalizedHeaders, rawBody: Uint8Array): ParseResult;
15
+ };
16
+ //# sourceMappingURL=lemon-squeezy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lemon-squeezy.d.ts","sourceRoot":"","sources":["../../src/providers/lemon-squeezy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAsB,MAAM,yBAAyB,CAAC;AAKlG;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB;;yBAGZ,MAAM,GAAG,UAAU;mBAIzB,iBAAiB,WAAW,UAAU,GAAG,WAAW;CAoBkC,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { decodeHexSignature, decodeLiteralSecret, failure } from './shared.js';
2
+ const SIGNATURE_HEADER = 'x-signature';
3
+ /**
4
+ * Lemon Squeezy `X-Signature`: a single 64-character hex HMAC-SHA256 digest of
5
+ * the exact raw body, keyed with the literal webhook signing secret. The docs
6
+ * suggest 6-40 character secrets, but that UI guidance is not enforced as a
7
+ * cryptographic limit. No timestamp or event identifier is documented for
8
+ * verification, so identity stays null and unsigned (`X-Event-Name` is
9
+ * metadata and is not interpreted).
10
+ * Source: https://docs.lemonsqueezy.com/help/webhooks/signing-requests
11
+ */
12
+ export const lemonSqueezyDescriptor = {
13
+ provider: 'lemon-squeezy',
14
+ decodeSecret(secret) {
15
+ return decodeLiteralSecret(secret, 'Lemon Squeezy');
16
+ },
17
+ parse(headers, rawBody) {
18
+ const raw = headers.get(SIGNATURE_HEADER);
19
+ if (raw === undefined || raw.trim() === '') {
20
+ return failure('missing-signature', 'No Lemon Squeezy signature header was provided.');
21
+ }
22
+ const signature = decodeHexSignature(raw);
23
+ if (signature === null) {
24
+ return failure('malformed-signature', 'The Lemon Squeezy signature header is malformed.');
25
+ }
26
+ return {
27
+ ok: true,
28
+ signatures: [signature],
29
+ signedContent: rawBody,
30
+ identity: { deliveryId: null, eventId: null, timestamp: null, authenticatedFields: [] },
31
+ };
32
+ },
33
+ };
34
+ //# sourceMappingURL=lemon-squeezy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lemon-squeezy.js","sourceRoot":"","sources":["../../src/providers/lemon-squeezy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,QAAQ,EAAE,eAAe;IAEzB,YAAY,CAAC,MAAc;QACzB,OAAO,mBAAmB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,OAA0B,EAAE,OAAmB;QACnD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAE1C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC,mBAAmB,EAAE,iDAAiD,CAAC,CAAC;QACzF,CAAC;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC,qBAAqB,EAAE,kDAAkD,CAAC,CAAC;QAC5F,CAAC;QAED,OAAO;YACL,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,CAAC,SAAS,CAAC;YACvB,aAAa,EAAE,OAAO;YACtB,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE;SACxF,CAAC;IACJ,CAAC;CACoG,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { NormalizedHeaders, ParseResult } from '../internal/provider.js';
2
+ /**
3
+ * Linear webhook signature authentication: `Linear-Signature` is a single
4
+ * 64-character hex HMAC-SHA256 over the exact visible raw request body, keyed
5
+ * with the literal, untrimmed UTF-8 webhook secret. Missing or trim-blank values
6
+ * are `missing-signature`; prefixes, outer whitespace, commas, lists, non-hex,
7
+ * wrong length and all other nonconforming values fail closed as
8
+ * `malformed-signature`. Either hex case is accepted as Hooklatch receiver
9
+ * policy, not as a claim of exact Linear SDK parity.
10
+ *
11
+ * `Linear-Delivery`, `Linear-Event`, `linear-timestamp` and all alien
12
+ * authentication headers are outside the MAC. They cannot establish freshness or
13
+ * trusted identity. Every identity field is null and `authenticatedFields` is
14
+ * empty: this descriptor intentionally performs body-only authentication, does
15
+ * not parse JSON, and never derives identity or time from body content. Old or
16
+ * future unsigned timestamps therefore cannot change authenticity, and this
17
+ * descriptor does not provide replay protection or business idempotency.
18
+ *
19
+ * The secret is literal UTF-8 with no prefix stripping, Base64 decoding,
20
+ * trimming or inferred length bound. Empty secrets are invalid configuration;
21
+ * whitespace-only and non-ASCII secrets remain literal keys. The exact raw body
22
+ * bytes are returned as signed content, so callers must retain the received
23
+ * bytes rather than reserialize parsed JSON.
24
+ *
25
+ * Sources:
26
+ * - https://linear.app/developers/webhooks
27
+ * - https://linear.app/developers/sdk-webhooks
28
+ * - https://github.com/linear/linear/blob/4d9cdbf0beb1d1da1824deb5ff3cd458c71380c9/packages/sdk/src/webhooks/client.ts
29
+ *
30
+ * No Linear-published signature tuple is claimed; test anchors are synthetic.
31
+ */
32
+ export declare const linearDescriptor: {
33
+ provider: "linear";
34
+ decodeSecret(secret: string): Uint8Array;
35
+ parse(headers: NormalizedHeaders, rawBody: Uint8Array): ParseResult;
36
+ };
37
+ //# sourceMappingURL=linear.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../src/providers/linear.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAsB,MAAM,yBAAyB,CAAC;AAMlG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,gBAAgB;;yBAGN,MAAM,GAAG,UAAU;mBAIzB,iBAAiB,WAAW,UAAU,GAAG,WAAW;CAsB2B,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { decodeHexSignature, decodeLiteralSecret, failure } from './shared.js';
2
+ const SIGNATURE_HEADER = 'linear-signature';
3
+ /**
4
+ * Linear webhook signature authentication: `Linear-Signature` is a single
5
+ * 64-character hex HMAC-SHA256 over the exact visible raw request body, keyed
6
+ * with the literal, untrimmed UTF-8 webhook secret. Missing or trim-blank values
7
+ * are `missing-signature`; prefixes, outer whitespace, commas, lists, non-hex,
8
+ * wrong length and all other nonconforming values fail closed as
9
+ * `malformed-signature`. Either hex case is accepted as Hooklatch receiver
10
+ * policy, not as a claim of exact Linear SDK parity.
11
+ *
12
+ * `Linear-Delivery`, `Linear-Event`, `linear-timestamp` and all alien
13
+ * authentication headers are outside the MAC. They cannot establish freshness or
14
+ * trusted identity. Every identity field is null and `authenticatedFields` is
15
+ * empty: this descriptor intentionally performs body-only authentication, does
16
+ * not parse JSON, and never derives identity or time from body content. Old or
17
+ * future unsigned timestamps therefore cannot change authenticity, and this
18
+ * descriptor does not provide replay protection or business idempotency.
19
+ *
20
+ * The secret is literal UTF-8 with no prefix stripping, Base64 decoding,
21
+ * trimming or inferred length bound. Empty secrets are invalid configuration;
22
+ * whitespace-only and non-ASCII secrets remain literal keys. The exact raw body
23
+ * bytes are returned as signed content, so callers must retain the received
24
+ * bytes rather than reserialize parsed JSON.
25
+ *
26
+ * Sources:
27
+ * - https://linear.app/developers/webhooks
28
+ * - https://linear.app/developers/sdk-webhooks
29
+ * - https://github.com/linear/linear/blob/4d9cdbf0beb1d1da1824deb5ff3cd458c71380c9/packages/sdk/src/webhooks/client.ts
30
+ *
31
+ * No Linear-published signature tuple is claimed; test anchors are synthetic.
32
+ */
33
+ export const linearDescriptor = {
34
+ provider: 'linear',
35
+ decodeSecret(secret) {
36
+ return decodeLiteralSecret(secret, 'Linear');
37
+ },
38
+ parse(headers, rawBody) {
39
+ const raw = headers.get(SIGNATURE_HEADER);
40
+ if (raw === undefined || raw.trim() === '') {
41
+ return failure('missing-signature', 'No Linear signature header was provided.');
42
+ }
43
+ const signature = decodeHexSignature(raw);
44
+ if (signature === null) {
45
+ return failure('malformed-signature', 'The Linear signature header is malformed.');
46
+ }
47
+ const identity = {
48
+ deliveryId: null,
49
+ eventId: null,
50
+ timestamp: null,
51
+ authenticatedFields: [],
52
+ };
53
+ return { ok: true, signatures: [signature], signedContent: rawBody, identity };
54
+ },
55
+ };
56
+ //# sourceMappingURL=linear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.js","sourceRoot":"","sources":["../../src/providers/linear.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,EAAE,QAAQ;IAElB,YAAY,CAAC,MAAc;QACzB,OAAO,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,OAA0B,EAAE,OAAmB;QACnD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAE1C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC,mBAAmB,EAAE,0CAA0C,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,QAAQ,GAAkB;YAC9B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;YACf,mBAAmB,EAAE,EAAE;SACxB,CAAC;QAEF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACjF,CAAC;CAC6F,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { NormalizedHeaders, ParseResult } from '../internal/provider.js';
2
+ /**
3
+ * Paddle Billing: `Paddle-Signature: ts=<unix seconds>;h1=<64 hex>`.
4
+ * The signature covers the exact `ts` text, a colon, and the untouched raw
5
+ * body. Repeated `h1` values are a Hooklatch rotation accept-set; every `h1`
6
+ * must be valid. Unknown fields such as `h2` are validated then ignored.
7
+ * Freshness is enforced by core, never here.
8
+ * Source: https://developer.paddle.com/webhooks/about/signature-verification/
9
+ */
10
+ export declare const paddleDescriptor: {
11
+ provider: "paddle";
12
+ decodeSecret(secret: string): Uint8Array;
13
+ parse(headers: NormalizedHeaders, rawBody: Uint8Array): ParseResult;
14
+ };
15
+ //# sourceMappingURL=paddle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paddle.d.ts","sourceRoot":"","sources":["../../src/providers/paddle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAsB,MAAM,yBAAyB,CAAC;AAqBlG;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;yBAGN,MAAM,GAAG,UAAU;mBAIzB,iBAAiB,WAAW,UAAU,GAAG,WAAW;CAmG2B,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { concatBytes, utf8 } from '../internal/bytes.js';
2
+ import { decodeHexSignature, decodeLiteralSecret, failure, isCanonicalTimestamp, isSchemeToken, } from './shared.js';
3
+ const SIGNATURE_HEADER = 'paddle-signature';
4
+ const TIMESTAMP_KEY = 'ts';
5
+ const SIGNATURE_KEY = 'h1';
6
+ /**
7
+ * Opaque nonempty printable ASCII unknown-field value: no whitespace, commas,
8
+ * semicolons, or additional equals signs. This is a bounded Hooklatch grammar,
9
+ * not a promise to support an unspecified future signature version.
10
+ */
11
+ const OPAQUE_VALUE = /^[\x21-\x2b\x2d-\x3a\x3c\x3e-\x7e]+$/;
12
+ /**
13
+ * Paddle Billing: `Paddle-Signature: ts=<unix seconds>;h1=<64 hex>`.
14
+ * The signature covers the exact `ts` text, a colon, and the untouched raw
15
+ * body. Repeated `h1` values are a Hooklatch rotation accept-set; every `h1`
16
+ * must be valid. Unknown fields such as `h2` are validated then ignored.
17
+ * Freshness is enforced by core, never here.
18
+ * Source: https://developer.paddle.com/webhooks/about/signature-verification/
19
+ */
20
+ export const paddleDescriptor = {
21
+ provider: 'paddle',
22
+ decodeSecret(secret) {
23
+ return decodeLiteralSecret(secret, 'Paddle');
24
+ },
25
+ parse(headers, rawBody) {
26
+ const raw = headers.get(SIGNATURE_HEADER);
27
+ if (raw === undefined || raw.trim() === '') {
28
+ return failure('missing-signature', 'No Paddle signature header was provided.');
29
+ }
30
+ // HTTP comma-combined duplicate header values never form a valid field list.
31
+ if (raw.includes(',')) {
32
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
33
+ }
34
+ const signatures = [];
35
+ let timestampText;
36
+ let timestampCount = 0;
37
+ let unknownSchemes = 0;
38
+ for (const rawSegment of raw.split(';')) {
39
+ // Trim outer segment whitespace only; keys and values stay exact.
40
+ const segment = rawSegment.trim();
41
+ if (segment === '') {
42
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
43
+ }
44
+ // Reject missing keys, empty values, and extra equals signs.
45
+ const separator = segment.indexOf('=');
46
+ if (separator <= 0 || separator === segment.length - 1 || segment.indexOf('=', separator + 1) !== -1) {
47
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
48
+ }
49
+ const key = segment.slice(0, separator);
50
+ const value = segment.slice(separator + 1);
51
+ if (!isSchemeToken(key)) {
52
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
53
+ }
54
+ if (key === TIMESTAMP_KEY) {
55
+ timestampCount += 1;
56
+ if (timestampCount > 1) {
57
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
58
+ }
59
+ if (!isCanonicalTimestamp(value)) {
60
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
61
+ }
62
+ timestampText = value;
63
+ continue;
64
+ }
65
+ if (key === SIGNATURE_KEY) {
66
+ const decoded = decodeHexSignature(value);
67
+ // One malformed h1 poisons the whole header, even beside a valid h1.
68
+ if (decoded === null) {
69
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
70
+ }
71
+ signatures.push(decoded);
72
+ continue;
73
+ }
74
+ // Unknown fields are structurally validated, then ignored.
75
+ if (!OPAQUE_VALUE.test(value)) {
76
+ return failure('malformed-signature', 'The Paddle signature header is malformed.');
77
+ }
78
+ unknownSchemes += 1;
79
+ }
80
+ // Required-field checks run only after all structure/token validation.
81
+ if (signatures.length === 0) {
82
+ return unknownSchemes > 0
83
+ ? failure('unsupported-scheme', 'No supported Paddle signature scheme was provided.')
84
+ : failure('missing-signature', 'No Paddle signature value was provided.');
85
+ }
86
+ if (timestampText === undefined) {
87
+ return failure('missing-timestamp', 'No Paddle timestamp was provided.');
88
+ }
89
+ const identity = {
90
+ deliveryId: null,
91
+ eventId: null,
92
+ timestamp: Number(timestampText),
93
+ authenticatedFields: ['timestamp'],
94
+ };
95
+ return {
96
+ ok: true,
97
+ signatures,
98
+ signedContent: concatBytes(utf8(`${timestampText}:`), rawBody),
99
+ identity,
100
+ };
101
+ },
102
+ };
103
+ //# sourceMappingURL=paddle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paddle.js","sourceRoot":"","sources":["../../src/providers/paddle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,OAAO,EACP,oBAAoB,EACpB,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAC5C,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B;;;;GAIG;AACH,MAAM,YAAY,GAAG,sCAAsC,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,EAAE,QAAQ;IAElB,YAAY,CAAC,MAAc;QACzB,OAAO,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,OAA0B,EAAE,OAAmB;QACnD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAE1C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC,mBAAmB,EAAE,0CAA0C,CAAC,CAAC;QAClF,CAAC;QAED,6EAA6E;QAC7E,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,UAAU,GAAiB,EAAE,CAAC;QACpC,IAAI,aAAiC,CAAC;QACtC,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,KAAK,MAAM,UAAU,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,kEAAkE;YAClE,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;YAElC,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;YACrF,CAAC;YAED,6DAA6D;YAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAEvC,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACrG,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;YACrF,CAAC;YAED,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YAE3C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;YACrF,CAAC;YAED,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;gBAC1B,cAAc,IAAI,CAAC,CAAC;gBAEpB,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;oBACvB,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;gBACrF,CAAC;gBAED,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjC,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;gBACrF,CAAC;gBAED,aAAa,GAAG,KAAK,CAAC;gBACtB,SAAS;YACX,CAAC;YAED,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;gBAC1B,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAE1C,qEAAqE;gBACrE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACrB,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;gBACrF,CAAC;gBAED,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACzB,SAAS;YACX,CAAC;YAED,2DAA2D;YAC3D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,OAAO,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;YACrF,CAAC;YAED,cAAc,IAAI,CAAC,CAAC;QACtB,CAAC;QAED,uEAAuE;QACvE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,cAAc,GAAG,CAAC;gBACvB,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,oDAAoD,CAAC;gBACrF,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,yCAAyC,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC,mBAAmB,EAAE,mCAAmC,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,QAAQ,GAAkB;YAC9B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,MAAM,CAAC,aAAa,CAAC;YAChC,mBAAmB,EAAE,CAAC,WAAW,CAAC;SACnC,CAAC;QAEF,OAAO;YACL,EAAE,EAAE,IAAI;YACR,UAAU;YACV,aAAa,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,aAAa,GAAG,CAAC,EAAE,OAAO,CAAC;YAC9D,QAAQ;SACT,CAAC;IACJ,CAAC;CAC6F,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { ProviderDescriptor } from '../internal/provider.js';
2
+ export interface PolarDescriptorOptions {
3
+ readonly secretMode?: 'current' | 'legacy';
4
+ }
5
+ type PolarDescriptor = {
6
+ readonly provider: 'polar';
7
+ } & Pick<ProviderDescriptor, 'decodeSecret' | 'parse'>;
8
+ /**
9
+ * Polar webhooks use the canonical Standard Webhooks headers and signed
10
+ * content: `${webhook-id}.${webhook-timestamp}.${rawBody}`.
11
+ *
12
+ * `current` (the default) keeps the shared Standard Webhooks decoder: an
13
+ * optional `whsec_` prefix is removed and the remainder must decode as
14
+ * canonical Base64 to 24..64 bytes. `legacy` treats the complete secret string
15
+ * as literal UTF-8 bytes, including any `whsec_` prefix, with only the shared
16
+ * nonempty policy. Exactly one mode applies to every secret configured for the
17
+ * descriptor; there is no prefix inference or cross-mode fallback.
18
+ *
19
+ * Polar's SDK tries both key interpretations and floors fractional timestamps.
20
+ * Hooklatch deliberately does neither, and does not decode opaque bodies as
21
+ * text. Source:
22
+ * https://raw.githubusercontent.com/polarsource/polar/89917ad4fe752b06ff84bd31c313d2a53a6085f1/sdk/typescript/src/webhooks.ts
23
+ */
24
+ export declare function createPolarDescriptor(options?: PolarDescriptorOptions): PolarDescriptor;
25
+ export {};
26
+ //# sourceMappingURL=polar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polar.d.ts","sourceRoot":"","sources":["../../src/providers/polar.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAIlE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC5C;AAED,KAAK,eAAe,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAC1D,kBAAkB,EAClB,cAAc,GAAG,OAAO,CACzB,CAAC;AAqEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,eAAe,CAEvF"}