@fedify/fedify 2.4.0-dev.2093 → 2.4.0-dev.2103

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 (84) hide show
  1. package/dist/{builder-Ld4Y9ymR.mjs → builder-CHht75pX.mjs} +2 -2
  2. package/dist/compat/mod.d.cts +1 -1
  3. package/dist/compat/mod.d.ts +1 -1
  4. package/dist/compat/transformers.test.mjs +1 -1
  5. package/dist/{compound-proof-CTx_lewQ.mjs → compound-proof-DKKH_Nr1.mjs} +2 -2
  6. package/dist/{context-BSywYspi.d.ts → context-CfJE_oQu.d.ts} +78 -13
  7. package/dist/{context-DlZhxdFT.mjs → context-CoNRxGYp.mjs} +2 -1
  8. package/dist/{context-CZjZYXFC.d.cts → context-mDTxTw-S.d.cts} +78 -13
  9. package/dist/{deno-8t8k_6Yv.mjs → deno-CkjiYK_Z.mjs} +1 -1
  10. package/dist/{docloader-DJKcsAiF.mjs → docloader-C1hAJnWc.mjs} +2 -2
  11. package/dist/federation/builder.test.mjs +1 -1
  12. package/dist/federation/compound-fanout.test.mjs +3 -3
  13. package/dist/federation/handler-compound-proof.test.mjs +4 -4
  14. package/dist/federation/handler.test.mjs +6 -6
  15. package/dist/federation/hashlink-media.test.mjs +2 -2
  16. package/dist/federation/idempotency.test.mjs +2 -2
  17. package/dist/federation/metrics.test.mjs +1 -1
  18. package/dist/federation/middleware.test.mjs +8 -8
  19. package/dist/federation/mod.cjs +1 -1
  20. package/dist/federation/mod.d.cts +2 -2
  21. package/dist/federation/mod.d.ts +2 -2
  22. package/dist/federation/mod.js +1 -1
  23. package/dist/federation/outgoing-proof.test.mjs +5 -5
  24. package/dist/federation/portable-actor.test.d.mts +2 -0
  25. package/dist/federation/portable-actor.test.mjs +446 -0
  26. package/dist/federation/portable-gateway-keys.test.mjs +4 -4
  27. package/dist/federation/portable-inbox.test.mjs +396 -10
  28. package/dist/federation/portable.test.mjs +3 -3
  29. package/dist/federation/send.test.mjs +3 -3
  30. package/dist/federation/tasks/enqueue.test.mjs +2 -2
  31. package/dist/federation/tasks/tasks.test.mjs +3 -3
  32. package/dist/federation/temporal.test.mjs +1 -1
  33. package/dist/federation/webfinger.test.mjs +2 -2
  34. package/dist/{federation-aSHO04ob.cjs → federation-C1dL6SiT.cjs} +1267 -1086
  35. package/dist/{http-B2ftY0Ha.mjs → http-BU-8fUrz.mjs} +82 -7
  36. package/dist/{http-DSaSAN7X.cjs → http-Cala2Grs.cjs} +89 -2
  37. package/dist/{http-DyT7DP1Y.js → http-tTlTeFa0.js} +78 -3
  38. package/dist/{key-Dwm4VswT.mjs → key-I8gLBkcf.mjs} +2 -2
  39. package/dist/{kv-cache-BSJAlP4C.cjs → kv-cache-Bl5EBFrU.cjs} +1 -1
  40. package/dist/{kv-cache-DmroAz3M.js → kv-cache-CxQu_cd4.js} +1 -1
  41. package/dist/{kv-cache-D0yYukqk.mjs → kv-cache-DJFoGRWQ.mjs} +1 -1
  42. package/dist/{ld-BYZOoDzZ.mjs → ld-wiJbqJHa.mjs} +3 -3
  43. package/dist/{metrics-B7YwKTFr.mjs → metrics-BCAa5-kE.mjs} +1 -1
  44. package/dist/{middleware-BNeqKSsL.mjs → middleware-6p2dYEVA.mjs} +1 -1
  45. package/dist/{middleware-Blq0882d.js → middleware-B6IVTVL0.js} +1362 -1181
  46. package/dist/{middleware-E_0IH72m.mjs → middleware-FnITXhtz.mjs} +549 -368
  47. package/dist/{mod-JzkaEXsi.d.cts → mod-B3OzOobN.d.cts} +1 -1
  48. package/dist/{mod-B2h2KY0q.d.ts → mod-BYvPz_T0.d.ts} +1 -1
  49. package/dist/mod.cjs +5 -5
  50. package/dist/mod.d.cts +2 -2
  51. package/dist/mod.d.ts +2 -2
  52. package/dist/mod.js +5 -5
  53. package/dist/nodeinfo/handler.test.mjs +2 -2
  54. package/dist/{owner-Cgx2Dc7I.mjs → owner-BJp47LxN.mjs} +3 -3
  55. package/dist/{owner-szIZl4qI.cjs → owner-DCt8W_Cv.cjs} +1 -1
  56. package/dist/{owner-DAGSC5gX.js → owner-j5yrbXS1.js} +1 -1
  57. package/dist/{portable-key-Cn1WJSN1.mjs → portable-key-B5oKE_wZ.mjs} +1 -1
  58. package/dist/{proof-DVXC6nYz.mjs → proof-BE4T5zF6.mjs} +4 -4
  59. package/dist/{send-D-hOvYKy.mjs → send-BFITuKHw.mjs} +3 -3
  60. package/dist/sig/compound-proof-discovery.test.mjs +1 -1
  61. package/dist/sig/compound-proof-producer.test.mjs +1 -1
  62. package/dist/sig/compound-proof-verification.test.mjs +2 -2
  63. package/dist/sig/compound-proof.test.mjs +2 -2
  64. package/dist/sig/http.test.mjs +72 -2
  65. package/dist/sig/key.test.mjs +1 -1
  66. package/dist/sig/ld.test.mjs +2 -2
  67. package/dist/sig/mod.cjs +3 -3
  68. package/dist/sig/mod.js +3 -3
  69. package/dist/sig/owner.test.mjs +1 -1
  70. package/dist/sig/portable-collection.test.mjs +2 -2
  71. package/dist/sig/portable-key.test.mjs +3 -3
  72. package/dist/sig/proof.test.mjs +3 -3
  73. package/dist/{sig-B5Ell7pO.js → sig-CJHdGk9w.js} +2 -2
  74. package/dist/{sig-CXOKN4Br.cjs → sig-CRTRoouH.cjs} +2 -2
  75. package/dist/{temporal-CqpKGEPk.mjs → temporal-CyDDbE4i.mjs} +1 -1
  76. package/dist/testing/kv.test.mjs +1 -1
  77. package/dist/testing/mod.d.mts +78 -13
  78. package/dist/testing/mod.mjs +2 -2
  79. package/dist/{testing-CO_cEvQc.mjs → testing-BWq1dCzx.mjs} +1 -1
  80. package/dist/utils/docloader.test.mjs +2 -2
  81. package/dist/utils/kv-cache.test.mjs +1 -1
  82. package/dist/utils/mod.cjs +1 -1
  83. package/dist/utils/mod.js +1 -1
  84. package/package.json +7 -7
@@ -1,11 +1,11 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-8t8k_6Yv.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-B7YwKTFr.mjs";
4
+ import { n as version, t as name } from "./deno-CkjiYK_Z.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BCAa5-kE.mjs";
6
6
  import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPVqki78.mjs";
7
- import { i as fetchKeyDetailed, s as validateCryptoKey } from "./key-Dwm4VswT.mjs";
8
- import { n as verifyPortableGatewayKeyDocument } from "./portable-key-Cn1WJSN1.mjs";
7
+ import { i as fetchKeyDetailed, s as validateCryptoKey } from "./key-I8gLBkcf.mjs";
8
+ import { n as verifyPortableGatewayKeyDocument } from "./portable-key-B5oKE_wZ.mjs";
9
9
  import { getLogger } from "@logtape/logtape";
10
10
  import { CryptographicKey } from "@fedify/vocab";
11
11
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -13,7 +13,7 @@ import { FetchError } from "@fedify/vocab-runtime";
13
13
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
14
14
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
15
15
  import { encodeHex } from "byte-encodings/hex";
16
- import { Item, decodeDict, encodeItem } from "structured-field-values";
16
+ import { Item, decodeDict, encodeDict, encodeItem } from "structured-field-values";
17
17
  //#region src/sig/http.ts
18
18
  const DEFAULT_MAX_REDIRECTION = 20;
19
19
  const DOUBLE_KNOCK_TRANSPORT_RETRY_DELAY_MS = 100;
@@ -202,6 +202,81 @@ function parseRfc9421Signature(signature) {
202
202
  for (const [key, value] of Object.entries(dict)) if (value.value instanceof Uint8Array) result[key] = value.value;
203
203
  return result;
204
204
  }
205
+ /**
206
+ * Parses the `Signature` header of draft-cavage HTTP Signatures into its
207
+ * fields, e.g., `keyId` and `headers`.
208
+ */
209
+ function parseDraftSignature(signature) {
210
+ return Object.fromEntries(signature.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
211
+ }
212
+ /**
213
+ * Lists the HTTP Signatures that a request claims to carry, without verifying
214
+ * any of them. Signatures whose key IDs are not URLs are left out.
215
+ * @param request The request.
216
+ * @returns The signatures; RFC 9421 ones if the request has
217
+ * a `Signature-Input` header, or a draft-cavage one otherwise.
218
+ * @internal
219
+ */
220
+ function listRequestSignatures(request) {
221
+ const signatureInput = request.headers.get("Signature-Input");
222
+ if (signatureInput != null) {
223
+ const signatures = [];
224
+ const inputs = parseRfc9421SignatureInput(signatureInput);
225
+ for (const [label, input] of Object.entries(inputs)) {
226
+ const keyId = parseKeyId(input.keyId);
227
+ if (keyId == null) continue;
228
+ signatures.push({
229
+ keyId,
230
+ label,
231
+ components: input.components
232
+ });
233
+ }
234
+ return signatures;
235
+ }
236
+ const signature = request.headers.get("Signature");
237
+ if (signature == null) return [];
238
+ const values = parseDraftSignature(signature);
239
+ const keyId = parseKeyId(values.keyId);
240
+ if (keyId == null) return [];
241
+ return [{
242
+ keyId,
243
+ label: null,
244
+ components: (values.headers ?? "").split(/\s+/g).filter((name) => name !== "").map((name) => ({
245
+ value: name,
246
+ params: {}
247
+ }))
248
+ }];
249
+ }
250
+ /**
251
+ * Makes a copy of a request that carries only one of its RFC 9421 signatures,
252
+ * so that verifying the copy verifies that signature and no other.
253
+ * A draft-cavage signature is the only one in its request, so the request is
254
+ * just copied.
255
+ * @param request The request, whose body must not be consumed.
256
+ * @param signature One of the signatures that {@link listRequestSignatures}
257
+ * lists for the request.
258
+ * @returns The copy of the request.
259
+ * @internal
260
+ */
261
+ function selectRequestSignature(request, signature) {
262
+ const copy = request.clone();
263
+ if (signature.label == null) return copy;
264
+ const { label } = signature;
265
+ const pick = (header) => {
266
+ if (header == null) return "";
267
+ let dict;
268
+ try {
269
+ dict = decodeDict(header);
270
+ } catch {
271
+ return "";
272
+ }
273
+ return Object.hasOwn(dict, label) ? encodeDict({ [label]: dict[label] }) : "";
274
+ };
275
+ const headers = new Headers(copy.headers);
276
+ headers.set("Signature-Input", pick(headers.get("Signature-Input")));
277
+ headers.set("Signature", pick(headers.get("Signature")));
278
+ return new Request(copy, { headers });
279
+ }
205
280
  async function signRequestRfc9421(request, privateKey, keyId, span, currentTime, bodyBuffer, rfc9421Options) {
206
281
  if (privateKey.algorithm.name !== "RSASSA-PKCS1-v1_5") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
207
282
  const url = new URL(request.url);
@@ -433,7 +508,7 @@ async function verifyRequestDraft(request, span, metricsContext, { documentLoade
433
508
  logger.debug("Failed to verify; no Signature header found.", { headers: Object.fromEntries(request.headers.entries()) });
434
509
  return noSignatureResult();
435
510
  }
436
- const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
511
+ const sigValues = parseDraftSignature(sigHeader);
437
512
  const parsedKeyId = parseKeyId(sigValues.keyId);
438
513
  const dateHeader = request.headers.get("Date");
439
514
  if (dateHeader == null) {
@@ -1106,4 +1181,4 @@ function timingSafeEqual(a, b) {
1106
1181
  return result === 0;
1107
1182
  }
1108
1183
  //#endregion
1109
- export { parseRfc9421Signature as a, timingSafeEqual as c, formatRfc9421SignatureParameters as i, verifyRequest as l, doubleKnock as n, parseRfc9421SignatureInput as o, formatRfc9421Signature as r, signRequest as s, createRfc9421SignatureBase as t, verifyRequestDetailed as u };
1184
+ export { listRequestSignatures as a, selectRequestSignature as c, verifyRequest as d, verifyRequestDetailed as f, formatRfc9421SignatureParameters as i, signRequest as l, doubleKnock as n, parseRfc9421Signature as o, formatRfc9421Signature as r, parseRfc9421SignatureInput as s, createRfc9421SignatureBase as t, timingSafeEqual as u };
@@ -16,7 +16,7 @@ json_canon = require_rolldown_runtime.__toESM(json_canon, 1);
16
16
  let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
17
17
  //#region deno.json
18
18
  var name = "@fedify/fedify";
19
- var version = "2.4.0-dev.2093+e9706a54";
19
+ var version = "2.4.0-dev.2103+3be829c0";
20
20
  //#endregion
21
21
  //#region src/sig/portable-key-id.ts
22
22
  const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
@@ -7876,6 +7876,81 @@ function parseRfc9421Signature(signature) {
7876
7876
  for (const [key, value] of Object.entries(dict)) if (value.value instanceof Uint8Array) result[key] = value.value;
7877
7877
  return result;
7878
7878
  }
7879
+ /**
7880
+ * Parses the `Signature` header of draft-cavage HTTP Signatures into its
7881
+ * fields, e.g., `keyId` and `headers`.
7882
+ */
7883
+ function parseDraftSignature(signature) {
7884
+ return Object.fromEntries(signature.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
7885
+ }
7886
+ /**
7887
+ * Lists the HTTP Signatures that a request claims to carry, without verifying
7888
+ * any of them. Signatures whose key IDs are not URLs are left out.
7889
+ * @param request The request.
7890
+ * @returns The signatures; RFC 9421 ones if the request has
7891
+ * a `Signature-Input` header, or a draft-cavage one otherwise.
7892
+ * @internal
7893
+ */
7894
+ function listRequestSignatures(request) {
7895
+ const signatureInput = request.headers.get("Signature-Input");
7896
+ if (signatureInput != null) {
7897
+ const signatures = [];
7898
+ const inputs = parseRfc9421SignatureInput(signatureInput);
7899
+ for (const [label, input] of Object.entries(inputs)) {
7900
+ const keyId = parseKeyId(input.keyId);
7901
+ if (keyId == null) continue;
7902
+ signatures.push({
7903
+ keyId,
7904
+ label,
7905
+ components: input.components
7906
+ });
7907
+ }
7908
+ return signatures;
7909
+ }
7910
+ const signature = request.headers.get("Signature");
7911
+ if (signature == null) return [];
7912
+ const values = parseDraftSignature(signature);
7913
+ const keyId = parseKeyId(values.keyId);
7914
+ if (keyId == null) return [];
7915
+ return [{
7916
+ keyId,
7917
+ label: null,
7918
+ components: (values.headers ?? "").split(/\s+/g).filter((name) => name !== "").map((name) => ({
7919
+ value: name,
7920
+ params: {}
7921
+ }))
7922
+ }];
7923
+ }
7924
+ /**
7925
+ * Makes a copy of a request that carries only one of its RFC 9421 signatures,
7926
+ * so that verifying the copy verifies that signature and no other.
7927
+ * A draft-cavage signature is the only one in its request, so the request is
7928
+ * just copied.
7929
+ * @param request The request, whose body must not be consumed.
7930
+ * @param signature One of the signatures that {@link listRequestSignatures}
7931
+ * lists for the request.
7932
+ * @returns The copy of the request.
7933
+ * @internal
7934
+ */
7935
+ function selectRequestSignature(request, signature) {
7936
+ const copy = request.clone();
7937
+ if (signature.label == null) return copy;
7938
+ const { label } = signature;
7939
+ const pick = (header) => {
7940
+ if (header == null) return "";
7941
+ let dict;
7942
+ try {
7943
+ dict = (0, structured_field_values.decodeDict)(header);
7944
+ } catch {
7945
+ return "";
7946
+ }
7947
+ return Object.hasOwn(dict, label) ? (0, structured_field_values.encodeDict)({ [label]: dict[label] }) : "";
7948
+ };
7949
+ const headers = new Headers(copy.headers);
7950
+ headers.set("Signature-Input", pick(headers.get("Signature-Input")));
7951
+ headers.set("Signature", pick(headers.get("Signature")));
7952
+ return new Request(copy, { headers });
7953
+ }
7879
7954
  async function signRequestRfc9421(request, privateKey, keyId, span, currentTime, bodyBuffer, rfc9421Options) {
7880
7955
  if (privateKey.algorithm.name !== "RSASSA-PKCS1-v1_5") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
7881
7956
  const url = new URL(request.url);
@@ -8107,7 +8182,7 @@ async function verifyRequestDraft(request, span, metricsContext, { documentLoade
8107
8182
  logger.debug("Failed to verify; no Signature header found.", { headers: Object.fromEntries(request.headers.entries()) });
8108
8183
  return noSignatureResult();
8109
8184
  }
8110
- const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
8185
+ const sigValues = parseDraftSignature(sigHeader);
8111
8186
  const parsedKeyId = parseKeyId(sigValues.keyId);
8112
8187
  const dateHeader = request.headers.get("Date");
8113
8188
  if (dateHeader == null) {
@@ -9008,6 +9083,12 @@ Object.defineProperty(exports, "isSamePublicKey", {
9008
9083
  return isSamePublicKey;
9009
9084
  }
9010
9085
  });
9086
+ Object.defineProperty(exports, "listRequestSignatures", {
9087
+ enumerable: true,
9088
+ get: function() {
9089
+ return listRequestSignatures;
9090
+ }
9091
+ });
9011
9092
  Object.defineProperty(exports, "name", {
9012
9093
  enumerable: true,
9013
9094
  get: function() {
@@ -9110,6 +9191,12 @@ Object.defineProperty(exports, "registerQueueDepthGauge", {
9110
9191
  return registerQueueDepthGauge;
9111
9192
  }
9112
9193
  });
9194
+ Object.defineProperty(exports, "selectRequestSignature", {
9195
+ enumerable: true,
9196
+ get: function() {
9197
+ return selectRequestSignature;
9198
+ }
9199
+ });
9113
9200
  Object.defineProperty(exports, "signJsonLd", {
9114
9201
  enumerable: true,
9115
9202
  get: function() {
@@ -14,7 +14,7 @@ import serialize from "json-canon";
14
14
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
15
15
  //#region deno.json
16
16
  var name = "@fedify/fedify";
17
- var version = "2.4.0-dev.2093+e9706a54";
17
+ var version = "2.4.0-dev.2103+3be829c0";
18
18
  //#endregion
19
19
  //#region src/sig/portable-key-id.ts
20
20
  const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
@@ -4308,6 +4308,81 @@ function parseRfc9421Signature(signature) {
4308
4308
  for (const [key, value] of Object.entries(dict)) if (value.value instanceof Uint8Array) result[key] = value.value;
4309
4309
  return result;
4310
4310
  }
4311
+ /**
4312
+ * Parses the `Signature` header of draft-cavage HTTP Signatures into its
4313
+ * fields, e.g., `keyId` and `headers`.
4314
+ */
4315
+ function parseDraftSignature(signature) {
4316
+ return Object.fromEntries(signature.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
4317
+ }
4318
+ /**
4319
+ * Lists the HTTP Signatures that a request claims to carry, without verifying
4320
+ * any of them. Signatures whose key IDs are not URLs are left out.
4321
+ * @param request The request.
4322
+ * @returns The signatures; RFC 9421 ones if the request has
4323
+ * a `Signature-Input` header, or a draft-cavage one otherwise.
4324
+ * @internal
4325
+ */
4326
+ function listRequestSignatures(request) {
4327
+ const signatureInput = request.headers.get("Signature-Input");
4328
+ if (signatureInput != null) {
4329
+ const signatures = [];
4330
+ const inputs = parseRfc9421SignatureInput(signatureInput);
4331
+ for (const [label, input] of Object.entries(inputs)) {
4332
+ const keyId = parseKeyId(input.keyId);
4333
+ if (keyId == null) continue;
4334
+ signatures.push({
4335
+ keyId,
4336
+ label,
4337
+ components: input.components
4338
+ });
4339
+ }
4340
+ return signatures;
4341
+ }
4342
+ const signature = request.headers.get("Signature");
4343
+ if (signature == null) return [];
4344
+ const values = parseDraftSignature(signature);
4345
+ const keyId = parseKeyId(values.keyId);
4346
+ if (keyId == null) return [];
4347
+ return [{
4348
+ keyId,
4349
+ label: null,
4350
+ components: (values.headers ?? "").split(/\s+/g).filter((name) => name !== "").map((name) => ({
4351
+ value: name,
4352
+ params: {}
4353
+ }))
4354
+ }];
4355
+ }
4356
+ /**
4357
+ * Makes a copy of a request that carries only one of its RFC 9421 signatures,
4358
+ * so that verifying the copy verifies that signature and no other.
4359
+ * A draft-cavage signature is the only one in its request, so the request is
4360
+ * just copied.
4361
+ * @param request The request, whose body must not be consumed.
4362
+ * @param signature One of the signatures that {@link listRequestSignatures}
4363
+ * lists for the request.
4364
+ * @returns The copy of the request.
4365
+ * @internal
4366
+ */
4367
+ function selectRequestSignature(request, signature) {
4368
+ const copy = request.clone();
4369
+ if (signature.label == null) return copy;
4370
+ const { label } = signature;
4371
+ const pick = (header) => {
4372
+ if (header == null) return "";
4373
+ let dict;
4374
+ try {
4375
+ dict = decodeDict(header);
4376
+ } catch {
4377
+ return "";
4378
+ }
4379
+ return Object.hasOwn(dict, label) ? encodeDict({ [label]: dict[label] }) : "";
4380
+ };
4381
+ const headers = new Headers(copy.headers);
4382
+ headers.set("Signature-Input", pick(headers.get("Signature-Input")));
4383
+ headers.set("Signature", pick(headers.get("Signature")));
4384
+ return new Request(copy, { headers });
4385
+ }
4311
4386
  async function signRequestRfc9421(request, privateKey, keyId, span, currentTime, bodyBuffer, rfc9421Options) {
4312
4387
  if (privateKey.algorithm.name !== "RSASSA-PKCS1-v1_5") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
4313
4388
  const url = new URL(request.url);
@@ -4539,7 +4614,7 @@ async function verifyRequestDraft(request, span, metricsContext, { documentLoade
4539
4614
  logger.debug("Failed to verify; no Signature header found.", { headers: Object.fromEntries(request.headers.entries()) });
4540
4615
  return noSignatureResult();
4541
4616
  }
4542
- const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
4617
+ const sigValues = parseDraftSignature(sigHeader);
4543
4618
  const parsedKeyId = parseKeyId(sigValues.keyId);
4544
4619
  const dateHeader = request.headers.get("Date");
4545
4620
  if (dateHeader == null) {
@@ -5212,4 +5287,4 @@ function timingSafeEqual(a, b) {
5212
5287
  return result === 0;
5213
5288
  }
5214
5289
  //#endregion
5215
- export { recordFanoutRecipients as $, verifyCompactJsonLd as A, validateCryptoKey as B, detachSignature as C, isClearlyMalformedContextReference as D, hasSignatureLike as E, fetchActorDocument as F, instrumentDocumentLoader as G, getDurationMs as H, fetchKey as I, recordCollectionDispatchDuration as J, isAbortError$1 as K, fetchKeyDetailed as L, verifySignature as M, wrapContextLoaderForJsonLd as N, isInvalidUrlTypeError as O, exportJwk as P, recordDocumentCache as Q, generateCryptoKeyPair as R, createSignature as S, hasSignature as T, getFederationMetrics as U, verifyKeyOwnership as V, getRemoteHost as W, recordCollectionRequest as X, recordCollectionPageItems as Y, recordCollectionTotalItems as Z, normalizeOutgoingActivityJsonLd as _, isSamePublicKey as _t, verifyRequestDetailed as a, preloadedOnlyDocumentLoader as at, attachSignature as b, createProof as c, parseAcceptSignature as ct, verifyMapLocalProof as d, getGatewayKeyBase as dt, recordInboxActivity as et, verifyObject as f, getPortableDid as ft, verifyProof as g, isPortableUri as gt, verifyPortableObjectProofWithRoot as h, isPortableId as ht, verifyRequest as i, registerQueueDepthGauge as it, verifyJsonLd as j, signJsonLd as k, hasProofLike as l, validateAcceptSignature as lt, verifyPortableObjectProofPolicy as m, isCompatibleKeyId as mt, parseRfc9421SignatureInput as n, recordOutboxEnqueue as nt, fetchPortableGatewayKey as o, formatAcceptSignature as ot, verifyPortableObjectProof as p, hasPortableActor as pt, recordCircuitBreakerStateChange as q, signRequest as r, recordWebFingerHandle as rt, InvalidPortableObjectIdError as s, fulfillAcceptSignature as st, doubleKnock as t, recordOutboxActivity as tt, signObject as u, getCanonicalPortableId as ut, InvalidContextReferenceError as v, name as vt, getNormalizationContextLoader as w, compactJsonLd as x, assertSafeJsonLd as y, version as yt, importJwk as z };
5290
+ export { recordCollectionTotalItems as $, isInvalidUrlTypeError as A, generateCryptoKeyPair as B, compactJsonLd as C, hasSignature as D, getNormalizationContextLoader as E, wrapContextLoaderForJsonLd as F, getFederationMetrics as G, validateCryptoKey as H, exportJwk as I, isAbortError$1 as J, getRemoteHost as K, fetchActorDocument as L, verifyCompactJsonLd as M, verifyJsonLd as N, hasSignatureLike as O, verifySignature as P, recordCollectionRequest as Q, fetchKey as R, attachSignature as S, detachSignature as T, verifyKeyOwnership as U, importJwk as V, getDurationMs as W, recordCollectionDispatchDuration as X, recordCircuitBreakerStateChange as Y, recordCollectionPageItems as Z, verifyPortableObjectProofWithRoot as _, isPortableId as _t, signRequest as a, recordWebFingerHandle as at, InvalidContextReferenceError as b, name as bt, fetchPortableGatewayKey as c, formatAcceptSignature as ct, hasProofLike as d, validateAcceptSignature as dt, recordDocumentCache as et, signObject as f, getCanonicalPortableId as ft, verifyPortableObjectProofPolicy as g, isCompatibleKeyId as gt, verifyPortableObjectProof as h, hasPortableActor as ht, selectRequestSignature as i, recordOutboxEnqueue as it, signJsonLd as j, isClearlyMalformedContextReference as k, InvalidPortableObjectIdError as l, fulfillAcceptSignature as lt, verifyObject as m, getPortableDid as mt, listRequestSignatures as n, recordInboxActivity as nt, verifyRequest as o, registerQueueDepthGauge as ot, verifyMapLocalProof as p, getGatewayKeyBase as pt, instrumentDocumentLoader as q, parseRfc9421SignatureInput as r, recordOutboxActivity as rt, verifyRequestDetailed as s, preloadedOnlyDocumentLoader as st, doubleKnock as t, recordFanoutRecipients as tt, createProof as u, parseAcceptSignature as ut, verifyProof as v, isPortableUri as vt, createSignature as w, assertSafeJsonLd as x, version as xt, normalizeOutgoingActivityJsonLd as y, isSamePublicKey as yt, fetchKeyDetailed as z };
@@ -1,8 +1,8 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-8t8k_6Yv.mjs";
5
- import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-B7YwKTFr.mjs";
4
+ import { n as version, t as name } from "./deno-CkjiYK_Z.mjs";
5
+ import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-BCAa5-kE.mjs";
6
6
  import { a as isCompatibleKeyId, o as isPortableActorDocument, s as isPortableId } from "./portable-key-id-Bva5iT3W.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
@@ -1,5 +1,5 @@
1
1
  const { URLPattern } = require("urlpattern-polyfill");
2
- const require_http = require("./http-DSaSAN7X.cjs");
2
+ const require_http = require("./http-Cala2Grs.cjs");
3
3
  let _logtape_logtape = require("@logtape/logtape");
4
4
  let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
5
5
  let es_toolkit = require("es-toolkit");
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { B as validateCryptoKey, Q as recordDocumentCache, t as doubleKnock } from "./http-DyT7DP1Y.js";
3
+ import { H as validateCryptoKey, et as recordDocumentCache, t as doubleKnock } from "./http-tTlTeFa0.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
6
6
  import { curry } from "es-toolkit";
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { p as recordDocumentCache } from "./metrics-B7YwKTFr.mjs";
4
+ import { p as recordDocumentCache } from "./metrics-BCAa5-kE.mjs";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { preloadedContexts } from "@fedify/vocab-runtime";
7
7
  //#region src/utils/kv-cache.ts
@@ -1,9 +1,9 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-8t8k_6Yv.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-B7YwKTFr.mjs";
6
- import { r as fetchKey, s as validateCryptoKey } from "./key-Dwm4VswT.mjs";
4
+ import { n as version, t as name } from "./deno-CkjiYK_Z.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BCAa5-kE.mjs";
6
+ import { r as fetchKey, s as validateCryptoKey } from "./key-I8gLBkcf.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,7 +1,7 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-8t8k_6Yv.mjs";
4
+ import { n as version, t as name } from "./deno-CkjiYK_Z.mjs";
5
5
  import { metrics } from "@opentelemetry/api";
6
6
  import { FetchError } from "@fedify/vocab-runtime";
7
7
  //#region src/federation/metrics.ts
@@ -1,5 +1,5 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as FederationImpl } from "./middleware-E_0IH72m.mjs";
4
+ import { n as FederationImpl } from "./middleware-FnITXhtz.mjs";
5
5
  export { FederationImpl };