@daloyjs/core 0.14.1 → 0.15.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/security.js CHANGED
@@ -173,4 +173,189 @@ export function randomId() {
173
173
  // Last-resort fallback (should never trigger on Node 20+/Bun/Deno/Workers).
174
174
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
175
175
  }
176
+ /**
177
+ * Header names that MUST appear at most once on a request per RFC 7230.
178
+ * Duplicate values for these headers are a classic HTTP-request-smuggling
179
+ * vector — front-end and back-end proxies can disagree on which value
180
+ * "wins", letting an attacker desync the connection.
181
+ *
182
+ * Exported for adapter authors that need the same set.
183
+ *
184
+ * @since 0.15.0
185
+ */
186
+ export const SMUGGLING_SINGLETON_HEADERS = Object.freeze([
187
+ "host",
188
+ "content-length",
189
+ ]);
190
+ /**
191
+ * Reject requests that carry more than one value for any header in
192
+ * {@link SMUGGLING_SINGLETON_HEADERS}. Because the standard `Headers`
193
+ * collection normalizes duplicates to a comma-joined string for these
194
+ * fields, the check is "value contains a comma at the top level".
195
+ *
196
+ * Throws {@link BadRequestError} so the framework returns a structured
197
+ * `400 problem+json` instead of forwarding a smuggling-class request.
198
+ *
199
+ * @since 0.15.0
200
+ */
201
+ export function assertNoDuplicateSingletonHeaders(headers) {
202
+ for (const name of SMUGGLING_SINGLETON_HEADERS) {
203
+ const v = headers.get(name);
204
+ if (v !== null && v.indexOf(",") !== -1) {
205
+ throw new BadRequestError(`Duplicate ${name} header rejected`);
206
+ }
207
+ }
208
+ }
209
+ const HEX_RE = /^[0-9a-fA-F]+$/;
210
+ const WEBHOOK_HMAC_ALGORITHMS = {
211
+ sha256: { hashName: "SHA-256", signatureBytes: 32 },
212
+ sha384: { hashName: "SHA-384", signatureBytes: 48 },
213
+ sha512: { hashName: "SHA-512", signatureBytes: 64 },
214
+ };
215
+ function resolveWebhookAlgorithm(algorithm) {
216
+ if (algorithm !== "sha256" && algorithm !== "sha384" && algorithm !== "sha512") {
217
+ return null;
218
+ }
219
+ return { name: algorithm, ...WEBHOOK_HMAC_ALGORITHMS[algorithm] };
220
+ }
221
+ function hexToBytes(hex) {
222
+ if (hex.length === 0 || hex.length % 2 !== 0 || !HEX_RE.test(hex))
223
+ return null;
224
+ const out = new Uint8Array(hex.length / 2);
225
+ for (let i = 0; i < out.length; i++) {
226
+ out[i] = parseInt(hex.substr(i * 2, 2), 16);
227
+ }
228
+ return out;
229
+ }
230
+ function base64ToBytes(b64) {
231
+ // Accept both standard and URL-safe base64, with or without padding.
232
+ if (b64.length === 0 || b64.length % 4 === 1)
233
+ return null;
234
+ if (!/^[A-Za-z0-9+/_-]+={0,2}$/.test(b64))
235
+ return null;
236
+ try {
237
+ const normalized = b64.replace(/-/g, "+").replace(/_/g, "/");
238
+ const pad = normalized.length % 4 === 0 ? "" : "=".repeat(4 - (normalized.length % 4));
239
+ const bin = atob(normalized + pad);
240
+ const out = new Uint8Array(bin.length);
241
+ for (let i = 0; i < bin.length; i++)
242
+ out[i] = bin.charCodeAt(i);
243
+ return out;
244
+ }
245
+ catch {
246
+ return null;
247
+ }
248
+ }
249
+ function bytesToHex(buf) {
250
+ let s = "";
251
+ for (let i = 0; i < buf.length; i++)
252
+ s += (buf[i] ?? 0).toString(16).padStart(2, "0");
253
+ return s;
254
+ }
255
+ function timingSafeEqualBytes(a, b) {
256
+ const len = Math.max(a.length, b.length);
257
+ let mismatch = a.length ^ b.length;
258
+ for (let i = 0; i < len; i++) {
259
+ mismatch |= (a[i] ?? 0) ^ (b[i] ?? 0);
260
+ }
261
+ return mismatch === 0;
262
+ }
263
+ function decodeWebhookSignature(signature, expected, expectedBytes) {
264
+ if (signature instanceof Uint8Array) {
265
+ return signature.length === expectedBytes ? signature : null;
266
+ }
267
+ let value = signature.trim();
268
+ const prefixed = /^(sha1|sha256|sha384|sha512)=/i.exec(value);
269
+ if (prefixed) {
270
+ const prefix = prefixed[1]?.toLowerCase();
271
+ if (prefix !== expected)
272
+ return null;
273
+ value = value.slice(prefixed[0].length);
274
+ }
275
+ const hex = hexToBytes(value);
276
+ if (hex && hex.length === expectedBytes)
277
+ return hex;
278
+ const b64 = base64ToBytes(value);
279
+ return b64 && b64.length === expectedBytes ? b64 : null;
280
+ }
281
+ /**
282
+ * Verify an HMAC signature for a webhook payload in constant time.
283
+ *
284
+ * Accepts the four common signature shapes seen in the wild:
285
+ *
286
+ * - Raw hex (`"a1b2..."`)
287
+ * - Raw base64 / base64url (`"oRY..."`, with or without padding)
288
+ * - Matching GitHub-style prefixed (`"sha256=..."`, `"sha384=..."`, `"sha512=..."`)
289
+ * - A `Uint8Array` of raw signature bytes
290
+ *
291
+ * Returns `false` for every malformed input — never throws on bad
292
+ * signatures so the caller cannot distinguish "wrong format" from "wrong
293
+ * key" through exception side channels.
294
+ *
295
+ * @example
296
+ * ```ts
297
+ * import { verifyWebhookSignature } from "@daloyjs/core";
298
+ *
299
+ * app.route({
300
+ * method: "POST",
301
+ * path: "/webhook",
302
+ * handler: async ({ request }) => {
303
+ * const raw = new Uint8Array(await request.arrayBuffer());
304
+ * const sig = request.headers.get("x-hub-signature-256") ?? "";
305
+ * if (!await verifyWebhookSignature({
306
+ * payload: raw, signature: sig, secret: process.env.WEBHOOK_SECRET!,
307
+ * })) {
308
+ * return { status: 401 as const, body: { ok: false } };
309
+ * }
310
+ * // safe to parse
311
+ * },
312
+ * });
313
+ * ```
314
+ *
315
+ * @since 0.15.0
316
+ */
317
+ export async function verifyWebhookSignature(opts) {
318
+ const algo = resolveWebhookAlgorithm(opts.algorithm ?? "sha256");
319
+ if (!algo)
320
+ return false;
321
+ const payloadBytes = typeof opts.payload === "string"
322
+ ? new TextEncoder().encode(opts.payload)
323
+ : opts.payload;
324
+ const secretBytes = typeof opts.secret === "string"
325
+ ? new TextEncoder().encode(opts.secret)
326
+ : opts.secret;
327
+ const providedBytes = decodeWebhookSignature(opts.signature, algo.name, algo.signatureBytes);
328
+ if (!providedBytes)
329
+ return false;
330
+ const c = globalThis.crypto;
331
+ if (!c?.subtle)
332
+ return false;
333
+ const key = await c.subtle.importKey("raw", secretBytes, { name: "HMAC", hash: algo.hashName }, false, ["sign"]);
334
+ const computed = new Uint8Array(await c.subtle.sign("HMAC", key, payloadBytes));
335
+ return timingSafeEqualBytes(computed, providedBytes);
336
+ }
337
+ /**
338
+ * Compute an HMAC signature over `payload` and return it hex-encoded. The
339
+ * companion of {@link verifyWebhookSignature}; useful for tests, for
340
+ * outbound webhook senders, and for diffing implementations.
341
+ *
342
+ * @since 0.15.0
343
+ */
344
+ export async function signWebhookPayload(opts) {
345
+ const algo = resolveWebhookAlgorithm(opts.algorithm ?? "sha256");
346
+ if (!algo)
347
+ throw new TypeError("unsupported webhook HMAC algorithm");
348
+ const payloadBytes = typeof opts.payload === "string"
349
+ ? new TextEncoder().encode(opts.payload)
350
+ : opts.payload;
351
+ const secretBytes = typeof opts.secret === "string"
352
+ ? new TextEncoder().encode(opts.secret)
353
+ : opts.secret;
354
+ const c = globalThis.crypto;
355
+ if (!c?.subtle)
356
+ throw new Error("WebCrypto unavailable: cannot sign webhook payload");
357
+ const key = await c.subtle.importKey("raw", secretBytes, { name: "HMAC", hash: algo.hashName }, false, ["sign"]);
358
+ const computed = new Uint8Array(await c.subtle.sign("HMAC", key, payloadBytes));
359
+ return bytesToHex(computed);
360
+ }
176
361
  //# sourceMappingURL=security.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daloyjs/core",
3
- "version": "0.14.1",
3
+ "version": "0.15.0",
4
4
  "description": "DaloyJS is a runtime-portable, contract-first TypeScript web framework with built-in OpenAPI (Hey API), typed client generation, large-scale maintainability, and security-first defaults. Hono-grade portability, Elysia-grade DX, FastAPI-grade docs, Fastify-grade ops — distributed via pnpm.",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -37,7 +37,7 @@
37
37
  "daloy": "bin/daloy.mjs"
38
38
  },
39
39
  "engines": {
40
- "node": ">=24.15.0",
40
+ "node": ">=24.0.0",
41
41
  "pnpm": ">=11.0.0"
42
42
  },
43
43
  "exports": {
@@ -120,6 +120,10 @@
120
120
  "./banner": {
121
121
  "types": "./dist/banner.d.ts",
122
122
  "import": "./dist/banner.js"
123
+ },
124
+ "./hashing": {
125
+ "types": "./dist/hashing.d.ts",
126
+ "import": "./dist/hashing.js"
123
127
  }
124
128
  },
125
129
  "devDependencies": {
@@ -143,7 +147,7 @@
143
147
  "bench": "node --import tsx bench/router.bench.ts",
144
148
  "test": "node --import tsx --test tests/**/*.test.ts",
145
149
  "coverage": "node --import tsx --test --experimental-test-coverage --test-coverage-include='src/**' --test-coverage-lines=99.9 --test-coverage-functions=100 tests/**/*.test.ts",
146
- "coverage:branches": "tsc -p tsconfig.coverage.json && node --test --experimental-test-coverage --test-coverage-include='dist-coverage/src/**' --test-coverage-branches=94 dist-coverage/tests/**/*.test.js",
150
+ "coverage:branches": "tsc -p tsconfig.coverage.json && node --test --experimental-test-coverage --test-coverage-include='dist-coverage/src/**' --test-coverage-branches=93 dist-coverage/tests/**/*.test.js",
147
151
  "typecheck": "tsc --noEmit",
148
152
  "gen:openapi": "node --import tsx scripts/dump-openapi.ts",
149
153
  "gen:client": "openapi-ts",