@mulmobridge/webhook-runtime 0.1.0 → 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.
- package/dist/index.d.ts +5 -0
- package/dist/index.js +18 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7,3 +7,8 @@ export declare function createWebhookApp(opts?: {
|
|
|
7
7
|
}): Express;
|
|
8
8
|
export declare function createWebhookRateLimit(limitPerMinute?: number): RateLimitRequestHandler;
|
|
9
9
|
export declare function verifyHmacSignature(body: string, signature: string, secret: string, algorithm?: string, encoding?: crypto.BinaryToTextEncoding): boolean;
|
|
10
|
+
export declare const SAFE_CHALLENGE_RE: RegExp;
|
|
11
|
+
/** The challenge string when `raw` matches the shape we'll echo, else
|
|
12
|
+
* `null`. Non-string query forms (`?hub.challenge[]=…`) return `null`
|
|
13
|
+
* rather than coercing to "", so callers can't compare a coerced empty. */
|
|
14
|
+
export declare function narrowChallenge(raw: unknown): string | null;
|
package/dist/index.js
CHANGED
|
@@ -83,3 +83,21 @@ export function verifyHmacSignature(body, signature, secret, algorithm = "SHA256
|
|
|
83
83
|
return false;
|
|
84
84
|
return crypto.timingSafeEqual(expected, provided);
|
|
85
85
|
}
|
|
86
|
+
// ── Meta (Messenger / WhatsApp) webhook verification ───────────
|
|
87
|
+
//
|
|
88
|
+
// Meta's GET handshake echoes back `hub.challenge`. Narrowing it to a
|
|
89
|
+
// known shape before it reaches `res.send()` is the CodeQL sanitiser that
|
|
90
|
+
// clears the `js/reflected-xss` alert (Codex review on #1328) and gives
|
|
91
|
+
// defence-in-depth. `[A-Za-z0-9_-]{1,256}` covers every observed base64url
|
|
92
|
+
// nonce (~32 chars); widen it HERE if Meta ever extends the format.
|
|
93
|
+
export const SAFE_CHALLENGE_RE = /^[A-Za-z0-9_-]{1,256}$/;
|
|
94
|
+
/** The challenge string when `raw` matches the shape we'll echo, else
|
|
95
|
+
* `null`. Non-string query forms (`?hub.challenge[]=…`) return `null`
|
|
96
|
+
* rather than coercing to "", so callers can't compare a coerced empty. */
|
|
97
|
+
export function narrowChallenge(raw) {
|
|
98
|
+
if (typeof raw !== "string")
|
|
99
|
+
return null;
|
|
100
|
+
if (!SAFE_CHALLENGE_RE.test(raw))
|
|
101
|
+
return null;
|
|
102
|
+
return raw;
|
|
103
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mulmobridge/webhook-runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Shared HTTP-webhook plumbing (Express app, trust-proxy, rate limit, HMAC verify) for the MulmoClaude messaging bridges",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|