@crvouga/mockingbird-service-twilio 3.10.2 → 3.10.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog — @crvouga/mockingbird-service-twilio
2
2
 
3
+ ## 3.10.4 (2026-11-02)
4
+
5
+ ### Fixes and improvements
6
+
7
+ - compare the admin key in constant time ([2a43141](https://github.com/crvouga/mockingbird/commit/2a43141f50dab41e698c3bbce0c69bf65b40e24e))
8
+
9
+ ## 3.10.3 (2026-11-02)
10
+
11
+ ### Fixes and improvements
12
+
13
+ - stop walkSchema recursing forever on a self-referential $ref ([69464a9](https://github.com/crvouga/mockingbird/commit/69464a9d9e7f468c5e1095125108d4d3d5515431))
14
+ - densify sparse bracket arrays by their written indices ([84a28cb](https://github.com/crvouga/mockingbird/commit/84a28cb182e3d7df91102897f0fc11fca714ba5f))
15
+
3
16
  ## 3.10.2 (2026-11-02)
4
17
 
5
18
  ### Fixes and improvements
@@ -9,7 +9,7 @@ import {
9
9
  parseFaultHeader,
10
10
  resolveAdminPrefix,
11
11
  restoreClock
12
- } from "./chunk-FS6QBWFN.js";
12
+ } from "./chunk-ND57CPE5.js";
13
13
 
14
14
  // ../../adapters/node/dist/cli.js
15
15
  import { readFile as readFile5 } from "node:fs/promises";
@@ -3057,7 +3057,7 @@ async function preflightFleet(config, options) {
3057
3057
  break;
3058
3058
  }
3059
3059
  }
3060
- targets.set(name, { ...target, packageVersion: packageVersion ?? "3.10.2" });
3060
+ targets.set(name, { ...target, packageVersion: packageVersion ?? "3.10.4" });
3061
3061
  } catch (error) {
3062
3062
  throw new Error(`service ${name}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
3063
3063
  }
@@ -5122,4 +5122,4 @@ export {
5122
5122
  createServer2 as createServer,
5123
5123
  serveTarget
5124
5124
  };
5125
- //# sourceMappingURL=chunk-KN4BA6SE.js.map
5125
+ //# sourceMappingURL=chunk-EH6ZB3WH.js.map
@@ -622,6 +622,7 @@ var parsePath = (rawKey) => {
622
622
  return path;
623
623
  };
624
624
  var isIndex = (segment) => /^(0|[1-9][0-9]*)$/.test(segment);
625
+ var MAX_ARRAY_INDEX = 4294967294;
625
626
  var put = (target, key, value) => {
626
627
  if (key === "__proto__") {
627
628
  Object.defineProperty(target, key, {
@@ -684,8 +685,17 @@ var decodeFormPairs = (pairs) => {
684
685
  var densify = (value) => {
685
686
  if (typeof value === "string")
686
687
  return value;
687
- if (Array.isArray(value))
688
- return value.filter((item) => item !== void 0).map(densify);
688
+ if (Array.isArray(value)) {
689
+ const dense = [];
690
+ for (const key of Object.keys(value)) {
691
+ if (!isIndex(key) || Number(key) > MAX_ARRAY_INDEX)
692
+ continue;
693
+ const item = value[Number(key)];
694
+ if (item !== void 0)
695
+ dense.push(densify(item));
696
+ }
697
+ return dense;
698
+ }
689
699
  const out = {};
690
700
  for (const [key, item] of Object.entries(value))
691
701
  put(out, key, densify(item));
@@ -2399,6 +2409,46 @@ var createNamespaceControls = (options) => {
2399
2409
  };
2400
2410
  };
2401
2411
 
2412
+ // ../core/dist/signing.js
2413
+ var encoder = new TextEncoder();
2414
+ var toBase64 = (bytes) => {
2415
+ let binary = "";
2416
+ for (const byte of bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)) {
2417
+ binary += String.fromCharCode(byte);
2418
+ }
2419
+ return btoa(binary);
2420
+ };
2421
+ var fromBase64 = (value) => Uint8Array.from(atob(value), (char) => char.charCodeAt(0));
2422
+ var toHex = (bytes) => [...bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
2423
+ var keyBytes = (key) => typeof key === "string" ? encoder.encode(key) : key;
2424
+ var hmac = async (algorithm, key, message, encoding = "hex") => {
2425
+ const imported = await crypto.subtle.importKey("raw", keyBytes(key), { name: "HMAC", hash: algorithm }, false, ["sign"]);
2426
+ const signed = await crypto.subtle.sign("HMAC", imported, typeof message === "string" ? encoder.encode(message) : message);
2427
+ return encoding === "hex" ? toHex(signed) : toBase64(signed);
2428
+ };
2429
+ var svixSecretBytes = (secret) => {
2430
+ const raw = secret.replace(/^f?whsec_/, "");
2431
+ try {
2432
+ return fromBase64(raw);
2433
+ } catch {
2434
+ throw new TypeError("webhook secret must be whsec_<base64> (as Svix issues it)");
2435
+ }
2436
+ };
2437
+ var signSvix = async (secret, messageId, timestampSeconds, body) => `v1,${await hmac("SHA-256", svixSecretBytes(secret), `${messageId}.${timestampSeconds}.${body}`, "base64")}`;
2438
+ var signTimestamped = async (secret, timestampSeconds, body) => `t=${timestampSeconds},v1=${await hmac("SHA-256", secret, `${timestampSeconds}.${body}`, "hex")}`;
2439
+ var signTwilio = async (authToken, url, params) => {
2440
+ const payload = url + Object.keys(params).sort().map((key) => `${key}${params[key]}`).join("");
2441
+ return hmac("SHA-1", authToken, payload, "base64");
2442
+ };
2443
+ var timingSafeEqual2 = (a, b) => {
2444
+ if (a.length !== b.length)
2445
+ return false;
2446
+ let diff = 0;
2447
+ for (let i = 0; i < a.length; i++)
2448
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
2449
+ return diff === 0;
2450
+ };
2451
+
2402
2452
  // ../core/dist/surface.js
2403
2453
  var defineMock = (runtime) => runtime;
2404
2454
  var ADMIN_ROUTE_REFERENCE = {
@@ -2517,6 +2567,10 @@ var assertAdminPrefixAvailable = (prefix, paths) => {
2517
2567
  }
2518
2568
  };
2519
2569
  var ADMIN_KEY_HEADER = CONTROL_HEADERS.adminKey;
2570
+ var hasAdminKey = (headers, adminKey) => {
2571
+ const sent = headers.get(ADMIN_KEY_HEADER);
2572
+ return sent !== null && timingSafeEqual2(sent, adminKey);
2573
+ };
2520
2574
  var NAMESPACE_HEADER = CONTROL_HEADERS.namespace;
2521
2575
  var ADMIN_DOCS_URL = "https://mockingbird.chrisvouga.dev/docs/admin-controls";
2522
2576
  var ADMIN_CONTROL_PAGES = [
@@ -2990,7 +3044,7 @@ var createControlPlane = (context) => {
2990
3044
  }
2991
3045
  const path = url.pathname.slice(adminPrefix.length) || "/";
2992
3046
  const shell = request.method === "GET" && (path === "/ui" || path === "/ui/");
2993
- if (!shell && context.adminKey !== void 0 && request.headers.get(ADMIN_KEY_HEADER) !== context.adminKey) {
3047
+ if (!shell && context.adminKey !== void 0 && !hasAdminKey(request.headers, context.adminKey)) {
2994
3048
  return adminError(401, `missing or wrong ${ADMIN_KEY_HEADER}`);
2995
3049
  }
2996
3050
  for (const route of routes) {
@@ -3861,39 +3915,7 @@ var stateAdminRoutes = (routes) => {
3861
3915
  };
3862
3916
 
3863
3917
  // ../core/dist/version.js
3864
- var PACKAGE_VERSION = true ? "3.10.2" : UNRELEASED_VERSION;
3865
-
3866
- // ../core/dist/signing.js
3867
- var encoder = new TextEncoder();
3868
- var toBase64 = (bytes) => {
3869
- let binary = "";
3870
- for (const byte of bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)) {
3871
- binary += String.fromCharCode(byte);
3872
- }
3873
- return btoa(binary);
3874
- };
3875
- var fromBase64 = (value) => Uint8Array.from(atob(value), (char) => char.charCodeAt(0));
3876
- var toHex = (bytes) => [...bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
3877
- var keyBytes = (key) => typeof key === "string" ? encoder.encode(key) : key;
3878
- var hmac = async (algorithm, key, message, encoding = "hex") => {
3879
- const imported = await crypto.subtle.importKey("raw", keyBytes(key), { name: "HMAC", hash: algorithm }, false, ["sign"]);
3880
- const signed = await crypto.subtle.sign("HMAC", imported, typeof message === "string" ? encoder.encode(message) : message);
3881
- return encoding === "hex" ? toHex(signed) : toBase64(signed);
3882
- };
3883
- var svixSecretBytes = (secret) => {
3884
- const raw = secret.replace(/^f?whsec_/, "");
3885
- try {
3886
- return fromBase64(raw);
3887
- } catch {
3888
- throw new TypeError("webhook secret must be whsec_<base64> (as Svix issues it)");
3889
- }
3890
- };
3891
- var signSvix = async (secret, messageId, timestampSeconds, body) => `v1,${await hmac("SHA-256", svixSecretBytes(secret), `${messageId}.${timestampSeconds}.${body}`, "base64")}`;
3892
- var signTimestamped = async (secret, timestampSeconds, body) => `t=${timestampSeconds},v1=${await hmac("SHA-256", secret, `${timestampSeconds}.${body}`, "hex")}`;
3893
- var signTwilio = async (authToken, url, params) => {
3894
- const payload = url + Object.keys(params).sort().map((key) => `${key}${params[key]}`).join("");
3895
- return hmac("SHA-1", authToken, payload, "base64");
3896
- };
3918
+ var PACKAGE_VERSION = true ? "3.10.4" : UNRELEASED_VERSION;
3897
3919
 
3898
3920
  // ../core/dist/webhooks.js
3899
3921
  var signers = {
@@ -5290,7 +5312,7 @@ var createRuntime = (options) => {
5290
5312
  throw error;
5291
5313
  }
5292
5314
  const rewinds = at !== void 0 && selectedBranch === "main" && MUTATING_METHODS.has(request.method);
5293
- if ((requested || rewinds) && options.adminKey !== void 0 && request.headers.get(ADMIN_KEY_HEADER) !== options.adminKey)
5315
+ if ((requested || rewinds) && options.adminKey !== void 0 && !hasAdminKey(request.headers, options.adminKey))
5294
5316
  return refuse(401, `control headers need ${ADMIN_KEY_HEADER}`);
5295
5317
  controls.ensure(namespace);
5296
5318
  if (requested?.restore !== void 0 && !snapshotStore.get(namespace, requested.restore))
@@ -10503,4 +10525,4 @@ export {
10503
10525
  * Copyright (c) 2021 - present, Yusuke Wada and Hono contributors
10504
10526
  * MIT license: see THIRD_PARTY_NOTICES.md in the repository and npm packages.
10505
10527
  */
10506
- //# sourceMappingURL=chunk-FS6QBWFN.js.map
10528
+ //# sourceMappingURL=chunk-ND57CPE5.js.map