@crvouga/mockingbird-service-sqs 3.10.3 → 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,11 @@
1
1
  # Changelog — @crvouga/mockingbird-service-sqs
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
+
3
9
  ## 3.10.3 (2026-11-02)
4
10
 
5
11
  ### Fixes and improvements
@@ -2557,6 +2557,17 @@ var createNamespaceControls = (options) => {
2557
2557
  };
2558
2558
  };
2559
2559
 
2560
+ // ../core/dist/signing.js
2561
+ var encoder = new TextEncoder();
2562
+ var timingSafeEqual = (a, b) => {
2563
+ if (a.length !== b.length)
2564
+ return false;
2565
+ let diff = 0;
2566
+ for (let i = 0; i < a.length; i++)
2567
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
2568
+ return diff === 0;
2569
+ };
2570
+
2560
2571
  // ../core/dist/surface.js
2561
2572
  var defineMock = (runtime) => runtime;
2562
2573
  var ADMIN_ROUTE_REFERENCE = {
@@ -2675,6 +2686,10 @@ var assertAdminPrefixAvailable = (prefix, paths) => {
2675
2686
  }
2676
2687
  };
2677
2688
  var ADMIN_KEY_HEADER = CONTROL_HEADERS.adminKey;
2689
+ var hasAdminKey = (headers, adminKey) => {
2690
+ const sent = headers.get(ADMIN_KEY_HEADER);
2691
+ return sent !== null && timingSafeEqual(sent, adminKey);
2692
+ };
2678
2693
  var NAMESPACE_HEADER = CONTROL_HEADERS.namespace;
2679
2694
  var ADMIN_DOCS_URL = "https://mockingbird.chrisvouga.dev/docs/admin-controls";
2680
2695
  var ADMIN_CONTROL_PAGES = [
@@ -3148,7 +3163,7 @@ var createControlPlane = (context) => {
3148
3163
  }
3149
3164
  const path = url.pathname.slice(adminPrefix.length) || "/";
3150
3165
  const shell = request.method === "GET" && (path === "/ui" || path === "/ui/");
3151
- if (!shell && context.adminKey !== void 0 && request.headers.get(ADMIN_KEY_HEADER) !== context.adminKey) {
3166
+ if (!shell && context.adminKey !== void 0 && !hasAdminKey(request.headers, context.adminKey)) {
3152
3167
  return adminError(401, `missing or wrong ${ADMIN_KEY_HEADER}`);
3153
3168
  }
3154
3169
  for (const route of routes) {
@@ -3911,7 +3926,7 @@ var stateAdminRoutes = (routes) => {
3911
3926
  };
3912
3927
 
3913
3928
  // ../core/dist/version.js
3914
- var PACKAGE_VERSION = true ? "3.10.3" : UNRELEASED_VERSION;
3929
+ var PACKAGE_VERSION = true ? "3.10.4" : UNRELEASED_VERSION;
3915
3930
 
3916
3931
  // ../core/dist/webhooks.js
3917
3932
  var json4 = (status, body) => new Response(JSON.stringify(body), {
@@ -4890,7 +4905,7 @@ var createRuntime = (options) => {
4890
4905
  throw error;
4891
4906
  }
4892
4907
  const rewinds = at !== void 0 && selectedBranch === "main" && MUTATING_METHODS.has(request.method);
4893
- if ((requested || rewinds) && options.adminKey !== void 0 && request.headers.get(ADMIN_KEY_HEADER) !== options.adminKey)
4908
+ if ((requested || rewinds) && options.adminKey !== void 0 && !hasAdminKey(request.headers, options.adminKey))
4894
4909
  return refuse(401, `control headers need ${ADMIN_KEY_HEADER}`);
4895
4910
  controls.ensure(namespace);
4896
4911
  if (requested?.restore !== void 0 && !snapshotStore.get(namespace, requested.restore))
@@ -5946,7 +5961,7 @@ var SqsAPI = class {
5946
5961
  const size = value.length;
5947
5962
  bytes.push(size >>> 24 & 255, size >>> 16 & 255, size >>> 8 & 255, size & 255, ...value);
5948
5963
  };
5949
- const encoder = new TextEncoder();
5964
+ const encoder2 = new TextEncoder();
5950
5965
  for (const [name2, value] of entries) {
5951
5966
  if (!/^[a-zA-Z0-9_.-]{1,256}$/.test(name2) || /^(aws|amazon)\./i.test(name2) || name2.startsWith(".") || name2.endsWith(".") || name2.includes(".."))
5952
5967
  throw new TypeError("Invalid message attribute name");
@@ -5956,11 +5971,11 @@ var SqsAPI = class {
5956
5971
  const binary = kind === "Binary";
5957
5972
  if (binary ? !value.BinaryValue : typeof value.StringValue !== "string" || !value.StringValue)
5958
5973
  throw new TypeError("Message attribute value is required");
5959
- append(encoder.encode(name2));
5960
- append(encoder.encode(value.DataType));
5974
+ append(encoder2.encode(name2));
5975
+ append(encoder2.encode(value.DataType));
5961
5976
  bytes.push(binary ? 2 : 1);
5962
5977
  append(
5963
- binary ? Uint8Array.from(atob(value.BinaryValue ?? ""), (char) => char.charCodeAt(0)) : encoder.encode(value.StringValue ?? "")
5978
+ binary ? Uint8Array.from(atob(value.BinaryValue ?? ""), (char) => char.charCodeAt(0)) : encoder2.encode(value.StringValue ?? "")
5964
5979
  );
5965
5980
  }
5966
5981
  return awsMd5(new Uint8Array(bytes));
@@ -5997,4 +6012,4 @@ export {
5997
6012
  accessKeyCredential,
5998
6013
  SqsAPI
5999
6014
  };
6000
- //# sourceMappingURL=chunk-FECMX637.js.map
6015
+ //# sourceMappingURL=chunk-GH66O7P3.js.map