@fedify/fedify 2.4.0-dev.2164 → 2.4.0-dev.2190

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 (103) hide show
  1. package/dist/{builder-BqRmnx7p.mjs → builder-CFF0YNTp.mjs} +3 -3
  2. package/dist/{circuit-breaker-C5NqoLBJ.mjs → circuit-breaker-XJ53md4S.mjs} +16 -11
  3. package/dist/compat/mod.d.cts +1 -1
  4. package/dist/compat/mod.d.ts +1 -1
  5. package/dist/compat/transformers.test.mjs +1 -1
  6. package/dist/{compound-proof-CxDBdtNz.mjs → compound-proof-F2jjkrt0.mjs} +3 -3
  7. package/dist/{context-BykNUf04.d.ts → context-9T--NSo4.d.ts} +55 -1
  8. package/dist/{context-L0Fnib9j.d.cts → context-CDcAgm4l.d.cts} +55 -1
  9. package/dist/{deno-CizGaYeG.mjs → deno-EopndaNb.mjs} +1 -1
  10. package/dist/{docloader-BBFAItNB.mjs → docloader-u6zzOExF.mjs} +25 -17
  11. package/dist/federation/builder.test.mjs +1 -1
  12. package/dist/federation/circuit-breaker.test.mjs +50 -1
  13. package/dist/federation/compound-fanout.test.mjs +3 -3
  14. package/dist/federation/handler-compound-proof.test.mjs +3 -3
  15. package/dist/federation/handler.test.mjs +5 -5
  16. package/dist/federation/hashlink-media.test.mjs +2 -2
  17. package/dist/federation/idempotency.test.mjs +2 -2
  18. package/dist/federation/keycache.test.mjs +1 -1
  19. package/dist/federation/metrics.test.mjs +1 -1
  20. package/dist/federation/middleware.test.mjs +137 -13
  21. package/dist/federation/mod.cjs +1 -1
  22. package/dist/federation/mod.d.cts +2 -2
  23. package/dist/federation/mod.d.ts +2 -2
  24. package/dist/federation/mod.js +1 -1
  25. package/dist/federation/outgoing-proof.test.mjs +5 -5
  26. package/dist/federation/portable-actor.test.mjs +3 -3
  27. package/dist/federation/portable-chain.test.mjs +3 -3
  28. package/dist/federation/portable-collection.test.mjs +4 -4
  29. package/dist/federation/portable-gateway-keys.test.mjs +6 -6
  30. package/dist/federation/portable-inbox.test.mjs +35 -5
  31. package/dist/federation/portable-parse-uri.test.mjs +1 -1
  32. package/dist/federation/portable-route-activity.test.d.mts +2 -0
  33. package/dist/federation/portable-route-activity.test.mjs +259 -0
  34. package/dist/federation/portable.test.mjs +3 -3
  35. package/dist/federation/send.test.mjs +3 -3
  36. package/dist/federation/tasks/enqueue.test.mjs +1 -1
  37. package/dist/federation/tasks/tasks.test.mjs +2 -2
  38. package/dist/federation/temporal.test.mjs +1 -1
  39. package/dist/federation/webfinger.test.mjs +1 -1
  40. package/dist/{federation-DFCnp94y.cjs → federation-BSS2dUO7.cjs} +38 -21
  41. package/dist/{http-Baovr6xq.js → http-BqN5kyUf.js} +426 -141
  42. package/dist/{http-DC1cqAQ2.d.cts → http-BrwKINQn.d.cts} +28 -0
  43. package/dist/{http-R4g1McwE.cjs → http-CCr2_ipG.cjs} +443 -140
  44. package/dist/{http-Cok5-vIC.d.ts → http-DGx0KOws.d.ts} +28 -0
  45. package/dist/{http-DRH0n8TD.mjs → http-Y1ObT1A8.mjs} +180 -92
  46. package/dist/{key-D5awqp7u.mjs → key-DyXf88bq.mjs} +4 -4
  47. package/dist/{key-owner-evidence-Bo3yaeL5.mjs → key-owner-evidence-APB6NpSk.mjs} +1 -1
  48. package/dist/{keycache-PiOM9pM0.mjs → keycache-Da8A8mZa.mjs} +1 -1
  49. package/dist/{kv-cache-CZiBDLPi.js → kv-cache-C02XitwK.js} +24 -16
  50. package/dist/{kv-cache-C7RWL7hz.mjs → kv-cache-C8YjNAi_.mjs} +1 -1
  51. package/dist/{kv-cache-Ct-KWRta.cjs → kv-cache-DUXluAc0.cjs} +23 -15
  52. package/dist/{ld-CyliEU48.mjs → ld-oQj6j_hP.mjs} +3 -3
  53. package/dist/{metrics-CFBEehTc.mjs → metrics-zMe834ID.mjs} +1 -1
  54. package/dist/{middleware-B99JjvFn.mjs → middleware-Bdu2-OPD.mjs} +37 -25
  55. package/dist/{middleware-CdpTFsa2.js → middleware-CaR2MRWY.js} +39 -22
  56. package/dist/{middleware-BmqEWsWP.mjs → middleware-Ck9yghxs.mjs} +1 -1
  57. package/dist/{mod-DK0y9fd-.d.ts → mod-B3OBLj5g.d.ts} +1 -1
  58. package/dist/{mod-B5z_q9TH.d.ts → mod-C5Mwx5ty.d.ts} +5 -1
  59. package/dist/{mod--jv6vyrP.d.ts → mod-Ck9_lSJB.d.ts} +1 -1
  60. package/dist/{mod-BLOXGs6m.d.cts → mod-D58KCqUg.d.cts} +1 -1
  61. package/dist/{mod-CPPqkyV_.d.cts → mod-DHTuu3l8.d.cts} +1 -1
  62. package/dist/{mod-BA_F2x53.d.cts → mod-Dp3Ij7sw.d.cts} +5 -1
  63. package/dist/mod.cjs +4 -4
  64. package/dist/mod.d.cts +5 -5
  65. package/dist/mod.d.ts +5 -5
  66. package/dist/mod.js +4 -4
  67. package/dist/nodeinfo/handler.test.mjs +1 -1
  68. package/dist/{owner-DKdtsrEq.mjs → owner-Dem4fbwc.mjs} +5 -5
  69. package/dist/{portable-collection-uv4CuQXm.js → portable-collection-BEqLrMW3.js} +1 -1
  70. package/dist/{portable-collection-Cb5cdPIU.mjs → portable-collection-BL6aZlQ0.mjs} +2 -2
  71. package/dist/{portable-collection-UajqDrSL.cjs → portable-collection-DJe_bk50.cjs} +1 -1
  72. package/dist/{portable-key-Bv1RdQ0n.mjs → portable-key-Duue9Y2Y.mjs} +209 -56
  73. package/dist/{portable-key-id-Bg259c4Z.mjs → portable-key-id-Ca30-hOa.mjs} +45 -1
  74. package/dist/{proof-CRTPWbVh.mjs → proof-C9115DX_.mjs} +5 -5
  75. package/dist/{send-2dULlZc8.mjs → send-D0hxFFRB.mjs} +3 -3
  76. package/dist/sig/compound-proof-discovery.test.mjs +1 -1
  77. package/dist/sig/compound-proof-producer.test.mjs +1 -1
  78. package/dist/sig/compound-proof-verification.test.mjs +2 -2
  79. package/dist/sig/compound-proof.test.mjs +2 -2
  80. package/dist/sig/http.test.mjs +495 -23
  81. package/dist/sig/key-owner-evidence.test.mjs +2 -2
  82. package/dist/sig/key.test.mjs +1 -1
  83. package/dist/sig/ld.test.mjs +2 -2
  84. package/dist/sig/mod.cjs +2 -2
  85. package/dist/sig/mod.d.cts +2 -2
  86. package/dist/sig/mod.d.ts +2 -2
  87. package/dist/sig/mod.js +2 -2
  88. package/dist/sig/owner.test.mjs +1 -1
  89. package/dist/sig/portable-collection.test.mjs +1 -1
  90. package/dist/sig/portable-key-id.test.d.mts +2 -0
  91. package/dist/sig/portable-key-id.test.mjs +67 -0
  92. package/dist/sig/portable-key.test.mjs +253 -7
  93. package/dist/sig/proof.test.mjs +3 -3
  94. package/dist/{temporal-Dhsk6aUT.mjs → temporal-DKchpKyp.mjs} +1 -1
  95. package/dist/testing/kv.test.mjs +1 -1
  96. package/dist/testing/mod.d.mts +52 -0
  97. package/dist/utils/docloader.test.mjs +93 -2
  98. package/dist/utils/kv-cache.test.mjs +1 -1
  99. package/dist/utils/mod.cjs +1 -1
  100. package/dist/utils/mod.d.cts +1 -1
  101. package/dist/utils/mod.d.ts +1 -1
  102. package/dist/utils/mod.js +1 -1
  103. package/package.json +6 -6
@@ -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-CizGaYeG.mjs";
4
+ import { n as version, t as name } from "./deno-EopndaNb.mjs";
5
5
  import { metrics } from "@opentelemetry/api";
6
6
  import { FetchError } from "@fedify/vocab-runtime";
7
7
  //#region src/federation/metrics.ts
@@ -1,29 +1,29 @@
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-CizGaYeG.mjs";
5
- import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-CFBEehTc.mjs";
4
+ import { n as version, t as name } from "./deno-EopndaNb.mjs";
5
+ import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-zMe834ID.mjs";
6
6
  import { t as formatAcceptSignature } from "./accept-CPVqki78.mjs";
7
- import { a as hasPortableActor, c as isPortableId, l as isPortableKeyId, n as getGatewayKeyBase, o as isCompatibleKeyId, r as getPortableDid, t as getCanonicalPortableId, u as isPortableUri } from "./portable-key-id-Bg259c4Z.mjs";
8
- import { c as validateCryptoKey, n as exportJwk, s as importJwk } from "./key-D5awqp7u.mjs";
7
+ import { d as isPortableUri, f as isSameObjectId, i as getPortableDid, l as isPortableId, n as getCanonicalPortableId, o as hasPortableActor, r as getGatewayKeyBase, s as isCompatibleKeyId, t as getAuthenticationOrigin, u as isPortableKeyId } from "./portable-key-id-Ca30-hOa.mjs";
8
+ import { c as validateCryptoKey, n as exportJwk, s as importJwk } from "./key-DyXf88bq.mjs";
9
9
  import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-4IJqPYos.mjs";
10
- import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-CyliEU48.mjs";
11
- import { a as signObject, c as verifyPortableObjectProof, i as hasProofLike, s as verifyObject, t as InvalidPortableObjectIdError, u as verifyPortableObjectProofWithRoot } from "./proof-CRTPWbVh.mjs";
12
- import { a as listRequestSignatures, c as selectRequestSignature, d as verifyRequest, f as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-DRH0n8TD.mjs";
13
- import { t as getAuthenticatedDocumentLoader } from "./docloader-BBFAItNB.mjs";
14
- import { n as kvCache } from "./kv-cache-C7RWL7hz.mjs";
10
+ import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-oQj6j_hP.mjs";
11
+ import { a as signObject, c as verifyPortableObjectProof, i as hasProofLike, s as verifyObject, t as InvalidPortableObjectIdError, u as verifyPortableObjectProofWithRoot } from "./proof-C9115DX_.mjs";
12
+ import { a as listRequestSignatures, c as selectRequestSignature, d as validateMaxSignatures, f as verifyRequest, p as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-Y1ObT1A8.mjs";
13
+ import { t as getAuthenticatedDocumentLoader } from "./docloader-u6zzOExF.mjs";
14
+ import { n as kvCache } from "./kv-cache-C8YjNAi_.mjs";
15
15
  import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-CEnNz8O7.mjs";
16
16
  import { t as nodeInfoToJson } from "./types-DE_LV1JB.mjs";
17
- import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-DKdtsrEq.mjs";
18
- import { t as verifyPortableObject } from "./portable-collection-Cb5cdPIU.mjs";
19
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-2dULlZc8.mjs";
20
- import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-BqRmnx7p.mjs";
21
- import { t as CircuitBreaker } from "./circuit-breaker-C5NqoLBJ.mjs";
17
+ import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-Dem4fbwc.mjs";
18
+ import { t as verifyPortableObject } from "./portable-collection-BL6aZlQ0.mjs";
19
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-D0hxFFRB.mjs";
20
+ import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-CFF0YNTp.mjs";
21
+ import { t as CircuitBreaker } from "./circuit-breaker-XJ53md4S.mjs";
22
22
  import { t as buildCollectionSynchronizationHeader } from "./collection-CnnP1UAv.mjs";
23
- import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, s as verifyServedPortableObjects, t as containsCompoundPortableObject } from "./compound-proof-CxDBdtNz.mjs";
24
- import { t as KvKeyCache } from "./keycache-PiOM9pM0.mjs";
23
+ import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, s as verifyServedPortableObjects, t as containsCompoundPortableObject } from "./compound-proof-F2jjkrt0.mjs";
24
+ import { t as KvKeyCache } from "./keycache-Da8A8mZa.mjs";
25
25
  import { t as acceptsJsonLd } from "./negotiation-CCocWT_N.mjs";
26
- import { t as hasMalformedKnownTemporalLiteral } from "./temporal-Dhsk6aUT.mjs";
26
+ import { t as hasMalformedKnownTemporalLiteral } from "./temporal-DKchpKyp.mjs";
27
27
  import { t as createExponentialBackoffPolicy } from "./retry-zX5xw5e0.mjs";
28
28
  import { t as TaskCodec } from "./codec-C6rTrpIp.mjs";
29
29
  import { getLogger, withContext } from "@logtape/logtape";
@@ -32,7 +32,7 @@ import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey,
32
32
  import { lookupWebFinger } from "@fedify/webfinger";
33
33
  import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
34
34
  import { uniq } from "es-toolkit";
35
- import { FetchError, canonicalizePortableUri, decodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDigestMultibase, parseHashlink, parseIri, toCompatibleEf61Id } from "@fedify/vocab-runtime";
35
+ import { FetchError, canonicalizePortableUri, decodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDigestMultibase, parseHashlink, parseIri, resolveDocumentLoaderTimeout, toCompatibleEf61Id } from "@fedify/vocab-runtime";
36
36
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
37
37
  import { isCompatibleEf61Iri } from "@fedify/vocab-runtime/internal/portable-dereference";
38
38
  import jsonld from "@fedify/vocab-runtime/jsonld";
@@ -2007,7 +2007,7 @@ async function handleInbox(request, options) {
2007
2007
  * @returns A promise that resolves to an HTTP response.
2008
2008
  */
2009
2009
  async function handleInboxInternal(request, parameters, span) {
2010
- const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, publicKeyTtl, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, inboxChallengePolicy, meterProvider, tracerProvider, portableInbox } = parameters;
2010
+ const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, publicKeyTtl, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, maxHttpSignatures, skipSignatureVerification, inboxChallengePolicy, meterProvider, tracerProvider, portableInbox } = parameters;
2011
2011
  const logger = getLogger([
2012
2012
  "fedify",
2013
2013
  "federation",
@@ -2293,6 +2293,7 @@ async function handleInboxInternal(request, parameters, span) {
2293
2293
  contextLoader: ctx.contextLoader,
2294
2294
  documentLoader: ctx.documentLoader,
2295
2295
  timeWindow: signatureTimeWindow,
2296
+ maxSignatures: maxHttpSignatures,
2296
2297
  keyCache,
2297
2298
  meterProvider,
2298
2299
  tracerProvider
@@ -2515,7 +2516,7 @@ async function handleInboxInternal(request, parameters, span) {
2515
2516
  inbox: portableInbox.recipient.canonicalInboxId
2516
2517
  });
2517
2518
  else try {
2518
- await portableInbox.forward(json, activity.id, getTypeId(activity).href, listRequestSignatures(request).map((signature) => ({
2519
+ await portableInbox.forward(json, activity.id, getTypeId(activity).href, listRequestSignatures(request, maxHttpSignatures).map((signature) => ({
2519
2520
  keyId: signature.keyId,
2520
2521
  coversDelivery: coversDelivery(signature),
2521
2522
  verify: async () => {
@@ -4086,6 +4087,8 @@ function isLinkedDataSignatureJsonLdProcessingError(error) {
4086
4087
  * @returns A new {@link Federation} instance.
4087
4088
  * @throws {TypeError} If benchmark mode and `meterProvider` are both
4088
4089
  * specified.
4090
+ * @throws {RangeError} If {@link FederationOptions.maxHttpSignatures} is not
4091
+ * a positive integer or `Infinity`.
4089
4092
  * @since 0.10.0
4090
4093
  */
4091
4094
  function createFederation(options) {
@@ -4112,6 +4115,7 @@ var FederationImpl = class extends FederationBuilderImpl {
4112
4115
  onOutboxError;
4113
4116
  permanentFailureStatusCodes;
4114
4117
  signatureTimeWindow;
4118
+ maxHttpSignatures;
4115
4119
  skipSignatureVerification;
4116
4120
  outboxRetryPolicy;
4117
4121
  inboxRetryPolicy;
@@ -4140,6 +4144,7 @@ var FederationImpl = class extends FederationBuilderImpl {
4140
4144
  const hasCustomLoaderFactory = options.documentLoaderFactory != null || options.contextLoaderFactory != null;
4141
4145
  const allowPrivateAddress = options.allowPrivateAddress ?? (benchmarkMode && !hasCustomLoaderFactory ? true : false);
4142
4146
  const signatureTimeWindow = options.signatureTimeWindow ?? (benchmarkMode ? false : { hours: 1 });
4147
+ if (options.maxHttpSignatures !== void 0) validateMaxSignatures(options.maxHttpSignatures, "maxHttpSignatures");
4143
4148
  if (benchmarkMode && options.meterProvider != null) throw new TypeError("benchmarkMode requires Fedify to own the meterProvider; OpenTelemetry metric readers cannot be added after a MeterProvider is constructed.");
4144
4149
  if (benchmarkMode) {
4145
4150
  const relaxations = getBenchmarkRelaxations(allowPrivateAddress, signatureTimeWindow);
@@ -4232,13 +4237,15 @@ var FederationImpl = class extends FederationBuilderImpl {
4232
4237
  }
4233
4238
  const { userAgent } = options;
4234
4239
  this.allowPrivateAddress = allowPrivateAddress;
4240
+ const documentLoaderTimeout = resolveDocumentLoaderTimeout(options.documentLoaderTimeout == null ? options.documentLoaderTimeout : Temporal.Duration.from(options.documentLoaderTimeout).total("millisecond"));
4235
4241
  const userDocumentLoaderFactory = options.documentLoaderFactory;
4236
4242
  const userContextLoaderFactory = options.contextLoaderFactory;
4237
4243
  const userAuthFactory = options.authenticatedDocumentLoaderFactory;
4238
4244
  const builtinDocumentLoaderFactory = (opts) => kvCache({
4239
4245
  loader: getDocumentLoader({
4240
4246
  allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
4241
- userAgent: opts?.userAgent ?? userAgent
4247
+ userAgent: opts?.userAgent ?? userAgent,
4248
+ timeout: opts?.timeout !== void 0 ? opts.timeout : documentLoaderTimeout
4242
4249
  }),
4243
4250
  kv: options.kv,
4244
4251
  prefix: this.kvPrefixes.remoteDocument,
@@ -4248,7 +4255,8 @@ var FederationImpl = class extends FederationBuilderImpl {
4248
4255
  const builtinContextLoaderFactory = (opts) => kvCache({
4249
4256
  loader: getDocumentLoader({
4250
4257
  allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
4251
- userAgent: opts?.userAgent ?? userAgent
4258
+ userAgent: opts?.userAgent ?? userAgent,
4259
+ timeout: opts?.timeout !== void 0 ? opts.timeout : documentLoaderTimeout
4252
4260
  }),
4253
4261
  kv: options.kv,
4254
4262
  prefix: this.kvPrefixes.remoteDocument,
@@ -4269,6 +4277,7 @@ var FederationImpl = class extends FederationBuilderImpl {
4269
4277
  this.authenticatedDocumentLoaderFactory = (identity, factoryOpts) => instrumentDocumentLoader(userAuthFactory != null ? userAuthFactory(identity, factoryOpts) : getAuthenticatedDocumentLoader(identity, {
4270
4278
  allowPrivateAddress: factoryOpts?.allowPrivateAddress ?? allowPrivateAddress,
4271
4279
  userAgent: factoryOpts?.userAgent ?? userAgent,
4280
+ timeout: factoryOpts?.timeout !== void 0 ? factoryOpts.timeout : documentLoaderTimeout,
4272
4281
  specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, options.firstKnock, { specTtl: this.httpMessageSignaturesSpecTtl }),
4273
4282
  tracerProvider: this.tracerProvider
4274
4283
  }), {
@@ -4280,6 +4289,7 @@ var FederationImpl = class extends FederationBuilderImpl {
4280
4289
  this.onOutboxError = options.onOutboxError;
4281
4290
  this.permanentFailureStatusCodes = options.permanentFailureStatusCodes ?? [404, 410];
4282
4291
  this.signatureTimeWindow = signatureTimeWindow;
4292
+ this.maxHttpSignatures = options.maxHttpSignatures ?? 3;
4283
4293
  this.skipSignatureVerification = options.skipSignatureVerification ?? false;
4284
4294
  this.inboxChallengePolicy = options.inboxChallengePolicy;
4285
4295
  this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy();
@@ -5905,6 +5915,7 @@ var FederationImpl = class extends FederationBuilderImpl {
5905
5915
  unverifiedActivityHandler: this.unverifiedActivityHandler,
5906
5916
  onNotFound,
5907
5917
  signatureTimeWindow: this.signatureTimeWindow,
5918
+ maxHttpSignatures: this.maxHttpSignatures,
5908
5919
  skipSignatureVerification: this.skipSignatureVerification,
5909
5920
  inboxChallengePolicy: this.inboxChallengePolicy,
5910
5921
  meterProvider: this.meterProvider,
@@ -6893,7 +6904,7 @@ var ContextImpl = class ContextImpl {
6893
6904
  activity: await fetched.toJsonLd({ contextLoader })
6894
6905
  });
6895
6906
  return false;
6896
- } else if (fetched.id?.href !== activity.id.href) {
6907
+ } else if (fetched.id == null || !isSameObjectId(fetched.id, activity.id)) {
6897
6908
  logger.debug("Fetched activity object has a different ID; failed to verify.", {
6898
6909
  recipient,
6899
6910
  activity: await fetched.toJsonLd({ contextLoader })
@@ -6906,8 +6917,8 @@ var ContextImpl = class ContextImpl {
6906
6917
  });
6907
6918
  return false;
6908
6919
  }
6909
- const activityId = fetched.id;
6910
- if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
6920
+ const activityOrigin = getAuthenticationOrigin(fetched.id);
6921
+ if (activityOrigin == null || !fetched.actorIds.every((actor) => getAuthenticationOrigin(actor) === activityOrigin)) {
6911
6922
  logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
6912
6923
  recipient,
6913
6924
  activity: await fetched.toJsonLd({ contextLoader })
@@ -7043,6 +7054,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
7043
7054
  contextLoader: options.contextLoader ?? this.contextLoader,
7044
7055
  documentLoader: options.documentLoader ?? this.documentLoader,
7045
7056
  timeWindow: this.federation.signatureTimeWindow,
7057
+ maxSignatures: this.federation.maxHttpSignatures,
7046
7058
  meterProvider: this.meterProvider,
7047
7059
  tracerProvider: options.tracerProvider ?? this.tracerProvider
7048
7060
  });
@@ -2,15 +2,15 @@ import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { t as __exportAll } from "./rolldown-runtime-BC-Eo5Mj.js";
4
4
  import { r as getDefaultActivityTransformers } from "./transformers-DAtXl_Kc.js";
5
- import { $ as isAbortError, A as hasSignatureLike, C as assertSafeJsonLd, Ct as isPortableId, D as detachSignature, Dt as name, K as MAX_PORTABLE_KEY_TTL, L as wrapContextLoaderForJsonLd, M as isInvalidUrlTypeError, N as signJsonLd, O as getNormalizationContextLoader, Ot as version, P as verifyCompactJsonLd, Q as instrumentDocumentLoader, R as exportJwk, S as InvalidContextReferenceError, St as isCompatibleKeyId, T as compactJsonLd, Tt as isPortableUri, U as importJwk, W as validateCryptoKey, X as getFederationMetrics, Y as getDurationMs, Z as getRemoteHost, _ as verifyPortableObjectProof, _t as getCanonicalPortableId, bt as getRawCanonicalPortableId, ct as recordOutboxActivity, d as classifyFep2277CoreType, dt as registerQueueDepthGauge, et as recordCircuitBreakerStateChange, ft as preloadedOnlyDocumentLoader, g as verifyObject, h as verifyMapLocalProof, i as selectRequestSignature, it as recordCollectionTotalItems, j as isClearlyMalformedContextReference, k as hasSignature, lt as recordOutboxEnqueue, m as signObject, n as listRequestSignatures, nt as recordCollectionPageItems, o as verifyRequest, ot as recordFanoutRecipients, p as hasProofLike, pt as formatAcceptSignature, r as parseRfc9421SignatureInput, rt as recordCollectionRequest, s as verifyRequestDetailed, st as recordInboxActivity, t as doubleKnock, tt as recordCollectionDispatchDuration, u as InvalidPortableObjectIdError, ut as recordWebFingerHandle, v as verifyPortableObjectProofPolicy, vt as getGatewayKeyBase, wt as isPortableKeyId, x as normalizeOutgoingActivityJsonLd, xt as hasPortableActor, y as verifyPortableObjectProofWithRoot, yt as getPortableDid } from "./http-Baovr6xq.js";
5
+ import { $ as instrumentDocumentLoader, A as hasSignature, At as name, C as InvalidContextReferenceError, Ct as hasPortableActor, Dt as isPortableUri, E as compactJsonLd, Et as isPortableKeyId, F as verifyCompactJsonLd, G as validateCryptoKey, M as isClearlyMalformedContextReference, N as isInvalidUrlTypeError, O as detachSignature, Ot as isSameObjectId, P as signJsonLd, Q as getRemoteHost, R as wrapContextLoaderForJsonLd, S as normalizeOutgoingActivityJsonLd, St as getRawCanonicalPortableId, Tt as isPortableId, W as importJwk, X as getDurationMs, Z as getFederationMetrics, _ as verifyObject, at as recordCollectionTotalItems, b as verifyPortableObjectProofWithRoot, bt as getGatewayKeyBase, c as verifyRequestDetailed, ct as recordInboxActivity, d as InvalidPortableObjectIdError, dt as recordWebFingerHandle, et as isAbortError, f as classifyFep2277CoreType, ft as registerQueueDepthGauge, g as verifyMapLocalProof, h as signObject, i as selectRequestSignature, it as recordCollectionRequest, j as hasSignatureLike, jt as version, k as getNormalizationContextLoader, lt as recordOutboxActivity, m as hasProofLike, mt as formatAcceptSignature, n as listRequestSignatures, nt as recordCollectionDispatchDuration, o as validateMaxSignatures, pt as preloadedOnlyDocumentLoader, q as MAX_PORTABLE_KEY_TTL, r as parseRfc9421SignatureInput, rt as recordCollectionPageItems, s as verifyRequest, st as recordFanoutRecipients, t as doubleKnock, tt as recordCircuitBreakerStateChange, ut as recordOutboxEnqueue, v as verifyPortableObjectProof, vt as getAuthenticationOrigin, w as assertSafeJsonLd, wt as isCompatibleKeyId, xt as getPortableDid, y as verifyPortableObjectProofPolicy, yt as getCanonicalPortableId, z as exportJwk } from "./http-BqN5kyUf.js";
6
6
  import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-_S2_MeLF.js";
7
- import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "./portable-collection-uv4CuQXm.js";
8
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-CZiBDLPi.js";
7
+ import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "./portable-collection-BEqLrMW3.js";
8
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-C02XitwK.js";
9
9
  import { getLogger, withContext } from "@logtape/logtape";
10
10
  import { Router, RouterError, assertPath } from "@fedify/uri-template";
11
11
  import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, isActor, lookupObject, traverseCollection } from "@fedify/vocab";
12
12
  import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
13
- import { FetchError, UrlError, canonicalizePortableUri, decodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDigestMultibase, parseHashlink, parseIri, preloadedContexts, toCompatibleEf61Id, validatePublicUrl } from "@fedify/vocab-runtime";
13
+ import { FetchError, UrlError, canonicalizePortableUri, decodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDigestMultibase, parseHashlink, parseIri, preloadedContexts, resolveDocumentLoaderTimeout, toCompatibleEf61Id, validatePublicUrl } from "@fedify/vocab-runtime";
14
14
  import { isCompatibleEf61Iri } from "@fedify/vocab-runtime/internal/portable-dereference";
15
15
  import { encodeHex } from "byte-encodings/hex";
16
16
  import jsonld from "@fedify/vocab-runtime/jsonld";
@@ -885,7 +885,7 @@ var CircuitBreaker = class {
885
885
  };
886
886
  let lastConflictingState;
887
887
  for (let attempt = 0; attempt < 10; attempt++) {
888
- const oldState = await this.#get(remoteHost);
888
+ const { state: oldState, raw: oldValue } = await this.#get(remoteHost);
889
889
  if (oldState == null || oldState.state === "closed") return {
890
890
  type: "send",
891
891
  probe: false
@@ -911,7 +911,7 @@ var CircuitBreaker = class {
911
911
  state: "half-open",
912
912
  halfOpened: now.toString()
913
913
  };
914
- if (await this.#replace(remoteHost, oldState, newState)) return {
914
+ if (await this.#replace(remoteHost, oldValue, newState)) return {
915
915
  type: "send",
916
916
  probe: true
917
917
  };
@@ -933,7 +933,7 @@ var CircuitBreaker = class {
933
933
  state: "half-open",
934
934
  halfOpened: now.toString()
935
935
  };
936
- if (await this.#replace(remoteHost, oldState, newState)) {
936
+ if (await this.#replace(remoteHost, oldValue, newState)) {
937
937
  await this.#notifyStateChange(remoteHost, "open", "half-open");
938
938
  return {
939
939
  type: "send",
@@ -960,9 +960,9 @@ var CircuitBreaker = class {
960
960
  async recordSuccess(remoteHost) {
961
961
  this.#sweepLegacyStates();
962
962
  for (let attempt = 0; attempt < 10; attempt++) {
963
- const oldState = await this.#get(remoteHost);
963
+ const { state: oldState, raw: oldValue } = await this.#get(remoteHost);
964
964
  if (oldState == null) return void 0;
965
- if (await this.#replace(remoteHost, oldState, void 0)) {
965
+ if (await this.#replace(remoteHost, oldValue, void 0)) {
966
966
  if (oldState.state !== "closed") {
967
967
  await this.#notifyStateChange(remoteHost, oldState.state, "closed");
968
968
  return {
@@ -982,7 +982,7 @@ var CircuitBreaker = class {
982
982
  this.#sweepLegacyStates();
983
983
  const now = this.#now();
984
984
  for (let attempt = 0; attempt < 10; attempt++) {
985
- const oldState = await this.#get(remoteHost);
985
+ const { state: oldState, raw: oldValue } = await this.#get(remoteHost);
986
986
  if (oldState?.state === "open") return void 0;
987
987
  const oldFailures = oldState?.failures.map(Temporal.Instant.from) ?? [];
988
988
  const failures = this.#options.pruneFailures([...oldFailures, now], now);
@@ -999,7 +999,7 @@ var CircuitBreaker = class {
999
999
  state: "closed",
1000
1000
  failures: failures.map((t) => t.toString())
1001
1001
  };
1002
- if (await this.#replace(remoteHost, oldState, newState)) {
1002
+ if (await this.#replace(remoteHost, oldValue, newState)) {
1003
1003
  if (transition != null) {
1004
1004
  await this.#notifyStateChange(remoteHost, transition[0], transition[1]);
1005
1005
  return {
@@ -1028,7 +1028,7 @@ var CircuitBreaker = class {
1028
1028
  }
1029
1029
  async getState(remoteHost) {
1030
1030
  this.#sweepLegacyStates();
1031
- return stripStoredCircuitBreakerState(await this.#get(remoteHost));
1031
+ return stripStoredCircuitBreakerState((await this.#get(remoteHost)).state);
1032
1032
  }
1033
1033
  /**
1034
1034
  * The currently running background legacy sweep, if any.
@@ -1148,9 +1148,14 @@ var CircuitBreaker = class {
1148
1148
  return Temporal.Instant.compare(expiresAt, retryAt) < 0 ? expiresAt : retryAt;
1149
1149
  }
1150
1150
  async #get(remoteHost) {
1151
- return parseStoredCircuitBreakerKvState(await this.#kv.get(this.#key(remoteHost)));
1151
+ const value = await this.#kv.get(this.#key(remoteHost));
1152
+ const state = parseStoredCircuitBreakerKvState(value);
1153
+ return {
1154
+ state,
1155
+ raw: state == null ? void 0 : value
1156
+ };
1152
1157
  }
1153
- async #replace(remoteHost, oldState, newState) {
1158
+ async #replace(remoteHost, oldValue, newState) {
1154
1159
  const key = this.#key(remoteHost);
1155
1160
  const storedState = newState == null ? void 0 : markCircuitBreakerState(newState);
1156
1161
  if (this.#kv.cas == null) {
@@ -1158,7 +1163,7 @@ var CircuitBreaker = class {
1158
1163
  else await this.#kv.set(key, storedState, this.#setOptions());
1159
1164
  return true;
1160
1165
  }
1161
- return await this.#kv.cas(key, oldState, storedState, storedState == null ? void 0 : this.#setOptions());
1166
+ return await this.#kv.cas(key, oldValue, storedState, storedState == null ? void 0 : this.#setOptions());
1162
1167
  }
1163
1168
  #setOptions() {
1164
1169
  return this.#options.stateTtl == null ? void 0 : { ttl: this.#options.stateTtl };
@@ -4661,7 +4666,7 @@ async function handleInbox(request, options) {
4661
4666
  * @returns A promise that resolves to an HTTP response.
4662
4667
  */
4663
4668
  async function handleInboxInternal(request, parameters, span) {
4664
- const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, publicKeyTtl, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, inboxChallengePolicy, meterProvider, tracerProvider, portableInbox } = parameters;
4669
+ const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, publicKeyTtl, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, maxHttpSignatures, skipSignatureVerification, inboxChallengePolicy, meterProvider, tracerProvider, portableInbox } = parameters;
4665
4670
  const logger = getLogger([
4666
4671
  "fedify",
4667
4672
  "federation",
@@ -4947,6 +4952,7 @@ async function handleInboxInternal(request, parameters, span) {
4947
4952
  contextLoader: ctx.contextLoader,
4948
4953
  documentLoader: ctx.documentLoader,
4949
4954
  timeWindow: signatureTimeWindow,
4955
+ maxSignatures: maxHttpSignatures,
4950
4956
  keyCache,
4951
4957
  meterProvider,
4952
4958
  tracerProvider
@@ -5169,7 +5175,7 @@ async function handleInboxInternal(request, parameters, span) {
5169
5175
  inbox: portableInbox.recipient.canonicalInboxId
5170
5176
  });
5171
5177
  else try {
5172
- await portableInbox.forward(json, activity.id, getTypeId(activity).href, listRequestSignatures(request).map((signature) => ({
5178
+ await portableInbox.forward(json, activity.id, getTypeId(activity).href, listRequestSignatures(request, maxHttpSignatures).map((signature) => ({
5173
5179
  keyId: signature.keyId,
5174
5180
  coversDelivery: coversDelivery(signature),
5175
5181
  verify: async () => {
@@ -7149,6 +7155,8 @@ function isLinkedDataSignatureJsonLdProcessingError(error) {
7149
7155
  * @returns A new {@link Federation} instance.
7150
7156
  * @throws {TypeError} If benchmark mode and `meterProvider` are both
7151
7157
  * specified.
7158
+ * @throws {RangeError} If {@link FederationOptions.maxHttpSignatures} is not
7159
+ * a positive integer or `Infinity`.
7152
7160
  * @since 0.10.0
7153
7161
  */
7154
7162
  function createFederation(options) {
@@ -7175,6 +7183,7 @@ var FederationImpl = class extends FederationBuilderImpl {
7175
7183
  onOutboxError;
7176
7184
  permanentFailureStatusCodes;
7177
7185
  signatureTimeWindow;
7186
+ maxHttpSignatures;
7178
7187
  skipSignatureVerification;
7179
7188
  outboxRetryPolicy;
7180
7189
  inboxRetryPolicy;
@@ -7203,6 +7212,7 @@ var FederationImpl = class extends FederationBuilderImpl {
7203
7212
  const hasCustomLoaderFactory = options.documentLoaderFactory != null || options.contextLoaderFactory != null;
7204
7213
  const allowPrivateAddress = options.allowPrivateAddress ?? (benchmarkMode && !hasCustomLoaderFactory ? true : false);
7205
7214
  const signatureTimeWindow = options.signatureTimeWindow ?? (benchmarkMode ? false : { hours: 1 });
7215
+ if (options.maxHttpSignatures !== void 0) validateMaxSignatures(options.maxHttpSignatures, "maxHttpSignatures");
7206
7216
  if (benchmarkMode && options.meterProvider != null) throw new TypeError("benchmarkMode requires Fedify to own the meterProvider; OpenTelemetry metric readers cannot be added after a MeterProvider is constructed.");
7207
7217
  if (benchmarkMode) {
7208
7218
  const relaxations = getBenchmarkRelaxations(allowPrivateAddress, signatureTimeWindow);
@@ -7295,13 +7305,15 @@ var FederationImpl = class extends FederationBuilderImpl {
7295
7305
  }
7296
7306
  const { userAgent } = options;
7297
7307
  this.allowPrivateAddress = allowPrivateAddress;
7308
+ const documentLoaderTimeout = resolveDocumentLoaderTimeout(options.documentLoaderTimeout == null ? options.documentLoaderTimeout : Temporal.Duration.from(options.documentLoaderTimeout).total("millisecond"));
7298
7309
  const userDocumentLoaderFactory = options.documentLoaderFactory;
7299
7310
  const userContextLoaderFactory = options.contextLoaderFactory;
7300
7311
  const userAuthFactory = options.authenticatedDocumentLoaderFactory;
7301
7312
  const builtinDocumentLoaderFactory = (opts) => kvCache({
7302
7313
  loader: getDocumentLoader({
7303
7314
  allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
7304
- userAgent: opts?.userAgent ?? userAgent
7315
+ userAgent: opts?.userAgent ?? userAgent,
7316
+ timeout: opts?.timeout !== void 0 ? opts.timeout : documentLoaderTimeout
7305
7317
  }),
7306
7318
  kv: options.kv,
7307
7319
  prefix: this.kvPrefixes.remoteDocument,
@@ -7311,7 +7323,8 @@ var FederationImpl = class extends FederationBuilderImpl {
7311
7323
  const builtinContextLoaderFactory = (opts) => kvCache({
7312
7324
  loader: getDocumentLoader({
7313
7325
  allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
7314
- userAgent: opts?.userAgent ?? userAgent
7326
+ userAgent: opts?.userAgent ?? userAgent,
7327
+ timeout: opts?.timeout !== void 0 ? opts.timeout : documentLoaderTimeout
7315
7328
  }),
7316
7329
  kv: options.kv,
7317
7330
  prefix: this.kvPrefixes.remoteDocument,
@@ -7332,6 +7345,7 @@ var FederationImpl = class extends FederationBuilderImpl {
7332
7345
  this.authenticatedDocumentLoaderFactory = (identity, factoryOpts) => instrumentDocumentLoader(userAuthFactory != null ? userAuthFactory(identity, factoryOpts) : getAuthenticatedDocumentLoader(identity, {
7333
7346
  allowPrivateAddress: factoryOpts?.allowPrivateAddress ?? allowPrivateAddress,
7334
7347
  userAgent: factoryOpts?.userAgent ?? userAgent,
7348
+ timeout: factoryOpts?.timeout !== void 0 ? factoryOpts.timeout : documentLoaderTimeout,
7335
7349
  specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, options.firstKnock, { specTtl: this.httpMessageSignaturesSpecTtl }),
7336
7350
  tracerProvider: this.tracerProvider
7337
7351
  }), {
@@ -7343,6 +7357,7 @@ var FederationImpl = class extends FederationBuilderImpl {
7343
7357
  this.onOutboxError = options.onOutboxError;
7344
7358
  this.permanentFailureStatusCodes = options.permanentFailureStatusCodes ?? [404, 410];
7345
7359
  this.signatureTimeWindow = signatureTimeWindow;
7360
+ this.maxHttpSignatures = options.maxHttpSignatures ?? 3;
7346
7361
  this.skipSignatureVerification = options.skipSignatureVerification ?? false;
7347
7362
  this.inboxChallengePolicy = options.inboxChallengePolicy;
7348
7363
  this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy();
@@ -8968,6 +8983,7 @@ var FederationImpl = class extends FederationBuilderImpl {
8968
8983
  unverifiedActivityHandler: this.unverifiedActivityHandler,
8969
8984
  onNotFound,
8970
8985
  signatureTimeWindow: this.signatureTimeWindow,
8986
+ maxHttpSignatures: this.maxHttpSignatures,
8971
8987
  skipSignatureVerification: this.skipSignatureVerification,
8972
8988
  inboxChallengePolicy: this.inboxChallengePolicy,
8973
8989
  meterProvider: this.meterProvider,
@@ -9956,7 +9972,7 @@ var ContextImpl = class ContextImpl {
9956
9972
  activity: await fetched.toJsonLd({ contextLoader })
9957
9973
  });
9958
9974
  return false;
9959
- } else if (fetched.id?.href !== activity.id.href) {
9975
+ } else if (fetched.id == null || !isSameObjectId(fetched.id, activity.id)) {
9960
9976
  logger.debug("Fetched activity object has a different ID; failed to verify.", {
9961
9977
  recipient,
9962
9978
  activity: await fetched.toJsonLd({ contextLoader })
@@ -9969,8 +9985,8 @@ var ContextImpl = class ContextImpl {
9969
9985
  });
9970
9986
  return false;
9971
9987
  }
9972
- const activityId = fetched.id;
9973
- if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
9988
+ const activityOrigin = getAuthenticationOrigin(fetched.id);
9989
+ if (activityOrigin == null || !fetched.actorIds.every((actor) => getAuthenticationOrigin(actor) === activityOrigin)) {
9974
9990
  logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
9975
9991
  recipient,
9976
9992
  activity: await fetched.toJsonLd({ contextLoader })
@@ -10106,6 +10122,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
10106
10122
  contextLoader: options.contextLoader ?? this.contextLoader,
10107
10123
  documentLoader: options.documentLoader ?? this.documentLoader,
10108
10124
  timeWindow: this.federation.signatureTimeWindow,
10125
+ maxSignatures: this.federation.maxHttpSignatures,
10109
10126
  meterProvider: this.meterProvider,
10110
10127
  tracerProvider: options.tracerProvider ?? this.tracerProvider
10111
10128
  });
@@ -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-B99JjvFn.mjs";
4
+ import { n as FederationImpl } from "./middleware-Bdu2-OPD.mjs";
5
5
  export { FederationImpl };
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { bt as ActorDispatcher, f as RequestContext, qt as WebFingerLinksDispatcher, xt as ActorHandleMapper, yt as ActorAliasMapper } from "./context-BykNUf04.js";
2
+ import { bt as ActorDispatcher, f as RequestContext, qt as WebFingerLinksDispatcher, xt as ActorHandleMapper, yt as ActorAliasMapper } from "./context-9T--NSo4.js";
3
3
  import { RouterError, RouterOptions, RouterRouteResult } from "@fedify/uri-template";
4
4
  import { MeterProvider, Span, Tracer } from "@opentelemetry/api";
5
5
 
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { n as HttpMessageSignaturesSpecDeterminer } from "./http-Cok5-vIC.js";
2
+ import { n as HttpMessageSignaturesSpecDeterminer } from "./http-DGx0KOws.js";
3
3
  import { n as KvStore, t as KvKey } from "./kv-BhNbN8Ed.js";
4
4
  import { t as DocumentFetchKind } from "./metrics-DoRtI0qU.js";
5
5
  import { MeterProvider, TracerProvider } from "@opentelemetry/api";
@@ -33,11 +33,14 @@ interface GetAuthenticatedDocumentLoaderOptions extends DocumentLoaderFactoryOpt
33
33
  * the fetched documents.
34
34
  * At most 20 HTTP redirects and alternate document links are followed in total
35
35
  * per call. Revisiting a URL within that chain throws a {@link FetchError}.
36
+ * Each call, including its double-knocking retries, times out after
37
+ * 10 seconds by default; see {@link DocumentLoaderFactoryOptions.timeout}.
36
38
  * @param identity The identity to get the document loader for.
37
39
  * The actor's key pair.
38
40
  * @param options The options for the document loader.
39
41
  * @returns The authenticated document loader.
40
42
  * @throws {TypeError} If the key is invalid or unsupported.
43
+ * @throws {RangeError} If the `timeout` option is invalid.
41
44
  * @since 0.4.0
42
45
  */
43
46
  declare function getAuthenticatedDocumentLoader(identity: {
@@ -48,6 +51,7 @@ declare function getAuthenticatedDocumentLoader(identity: {
48
51
  maxRedirection,
49
52
  userAgent,
50
53
  specDeterminer,
54
+ timeout,
51
55
  tracerProvider
52
56
  }?: GetAuthenticatedDocumentLoaderOptions): DocumentLoader;
53
57
  //#endregion
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { S as KeyCache } from "./http-Cok5-vIC.js";
2
+ import { S as KeyCache } from "./http-DGx0KOws.js";
3
3
  import { CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1 } from "@fedify/vocab";
4
4
  import { MeterProvider, TracerProvider } from "@opentelemetry/api";
5
5
  import { DocumentLoader, PortableObjectVerifier, PortableObjectVerifierOptions } from "@fedify/vocab-runtime";
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { bt as ActorDispatcher, f as RequestContext, qt as WebFingerLinksDispatcher, xt as ActorHandleMapper, yt as ActorAliasMapper } from "./context-L0Fnib9j.cjs";
2
+ import { bt as ActorDispatcher, f as RequestContext, qt as WebFingerLinksDispatcher, xt as ActorHandleMapper, yt as ActorAliasMapper } from "./context-CDcAgm4l.cjs";
3
3
  import { MeterProvider, Span, Tracer } from "@opentelemetry/api";
4
4
  import { RouterError, RouterOptions, RouterRouteResult } from "@fedify/uri-template";
5
5
 
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { S as KeyCache } from "./http-DC1cqAQ2.cjs";
2
+ import { S as KeyCache } from "./http-BrwKINQn.cjs";
3
3
  import { CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1 } from "@fedify/vocab";
4
4
  import { DocumentLoader, PortableObjectVerifier, PortableObjectVerifierOptions } from "@fedify/vocab-runtime";
5
5
  import { MeterProvider, TracerProvider } from "@opentelemetry/api";
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { n as HttpMessageSignaturesSpecDeterminer } from "./http-DC1cqAQ2.cjs";
2
+ import { n as HttpMessageSignaturesSpecDeterminer } from "./http-BrwKINQn.cjs";
3
3
  import { n as KvStore, t as KvKey } from "./kv-BhNbN8Ed.cjs";
4
4
  import { t as DocumentFetchKind } from "./metrics-DVKYY6K1.cjs";
5
5
  import { DocumentLoader, DocumentLoaderFactoryOptions } from "@fedify/vocab-runtime";
@@ -33,11 +33,14 @@ interface GetAuthenticatedDocumentLoaderOptions extends DocumentLoaderFactoryOpt
33
33
  * the fetched documents.
34
34
  * At most 20 HTTP redirects and alternate document links are followed in total
35
35
  * per call. Revisiting a URL within that chain throws a {@link FetchError}.
36
+ * Each call, including its double-knocking retries, times out after
37
+ * 10 seconds by default; see {@link DocumentLoaderFactoryOptions.timeout}.
36
38
  * @param identity The identity to get the document loader for.
37
39
  * The actor's key pair.
38
40
  * @param options The options for the document loader.
39
41
  * @returns The authenticated document loader.
40
42
  * @throws {TypeError} If the key is invalid or unsupported.
43
+ * @throws {RangeError} If the `timeout` option is invalid.
41
44
  * @since 0.4.0
42
45
  */
43
46
  declare function getAuthenticatedDocumentLoader(identity: {
@@ -48,6 +51,7 @@ declare function getAuthenticatedDocumentLoader(identity: {
48
51
  maxRedirection,
49
52
  userAgent,
50
53
  specDeterminer,
54
+ timeout,
51
55
  tracerProvider
52
56
  }?: GetAuthenticatedDocumentLoaderOptions): DocumentLoader;
53
57
  //#endregion
package/dist/mod.cjs CHANGED
@@ -3,11 +3,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  require("./rolldown-runtime-Dmm3t92W.cjs");
4
4
  const require_transformers = require("./transformers-BalCrSsr.cjs");
5
5
  require("./compat/mod.cjs");
6
- const require_http = require("./http-R4g1McwE.cjs");
7
- const require_federation = require("./federation-DFCnp94y.cjs");
6
+ const require_http = require("./http-CCr2_ipG.cjs");
7
+ const require_federation = require("./federation-BSS2dUO7.cjs");
8
8
  const require_types = require("./types-poIao40f.cjs");
9
- const require_portable_collection = require("./portable-collection-UajqDrSL.cjs");
10
- const require_kv_cache = require("./kv-cache-Ct-KWRta.cjs");
9
+ const require_portable_collection = require("./portable-collection-DJe_bk50.cjs");
10
+ const require_kv_cache = require("./kv-cache-DUXluAc0.cjs");
11
11
  require("./nodeinfo/mod.cjs");
12
12
  require("./runtime/mod.cjs");
13
13
  require("./sig/mod.cjs");
package/dist/mod.d.cts CHANGED
@@ -1,13 +1,13 @@
1
1
  /// <reference lib="esnext.temporal" />
2
2
  import { a as InboundService, c as OutboundService, d as Software, f as Usage, i as parseNodeInfo, l as Protocol, n as ParseNodeInfoOptions, o as JsonValue, p as nodeInfoToJson, r as getNodeInfo, s as NodeInfo, t as GetNodeInfoOptions, u as Services } from "./client-D-XP_Ccb.cjs";
3
- import { C as exportJwk, D as importJwk, E as generateCryptoKeyPair, S as KeyCache, T as fetchKeyDetailed, _ as validateAcceptSignature, a as VerifyRequestDetailedResult, b as FetchKeyOptions, c as signRequest, d as AcceptSignatureMember, f as AcceptSignatureParameters, g as parseAcceptSignature, h as fulfillAcceptSignature, i as SignRequestOptions, l as verifyRequest, m as formatAcceptSignature, n as HttpMessageSignaturesSpecDeterminer, o as VerifyRequestFailureReason, p as FulfillAcceptSignatureResult, r as Rfc9421SignRequestOptions, s as VerifyRequestOptions, t as HttpMessageSignaturesSpec, u as verifyRequestDetailed, v as FetchKeyDetailedResult, w as fetchKey, x as FetchKeyResult, y as FetchKeyErrorResult } from "./http-DC1cqAQ2.cjs";
3
+ import { C as exportJwk, D as importJwk, E as generateCryptoKeyPair, S as KeyCache, T as fetchKeyDetailed, _ as validateAcceptSignature, a as VerifyRequestDetailedResult, b as FetchKeyOptions, c as signRequest, d as AcceptSignatureMember, f as AcceptSignatureParameters, g as parseAcceptSignature, h as fulfillAcceptSignature, i as SignRequestOptions, l as verifyRequest, m as formatAcceptSignature, n as HttpMessageSignaturesSpecDeterminer, o as VerifyRequestFailureReason, p as FulfillAcceptSignatureResult, r as Rfc9421SignRequestOptions, s as VerifyRequestOptions, t as HttpMessageSignaturesSpec, u as verifyRequestDetailed, v as FetchKeyDetailedResult, w as fetchKey, x as FetchKeyResult, y as FetchKeyErrorResult } from "./http-BrwKINQn.cjs";
4
4
  import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-BF0L9cMt.cjs";
5
- import { $ as respondWithObjectIfAcceptable, $t as ActivityTransformer, A as InboxListenerSetters, At as HashlinkMediaDispatcher, B as Message, Bt as OutboxListenerErrorHandler, C as FederationBuilder, Ct as AuthorizePredicate, D as IdempotencyKeyCallback, Dt as CustomCollectionCounter, E as FederationStartQueueOptions, Et as CollectionDispatcher, F as Rfc6570Expression, Ft as NodeInfoDispatcher, G as TaskHandler, Gt as UnverifiedActivityHandler, H as TaskDefinition, Ht as PortableActorIdMapper, I as FederationKvPrefixes, It as ObjectAuthorizePredicate, J as RetryContext, Jt as SendActivityError, K as TaskRegistry, Kt as UnverifiedActivityReason, L as FederationOrigin, Lt as ObjectDispatcher, M as ObjectCallbackSetters, Mt as InboxErrorHandler, N as OutboxListenerSetters, Nt as InboxListener, O as IdempotencyStrategy, Ot as CustomCollectionCursor, P as PortableInboxForwardingOptions, Pt as MediaUploaderCallback, Q as respondWithObject, Qt as digest, R as FederationQueueOptions, Rt as OutboxErrorHandler, S as FederationBenchmarkOptions, St as ActorKeyPairsDispatcher, T as FederationOptions, Tt as CollectionCursor, U as TaskDefinitionOptions, Ut as PortableCollectionOwnerMapper, V as createFederationBuilder, Vt as OutboxPermanentFailureHandler, W as TaskEnqueueOptions, Wt as SharedInboxKeyDispatcher, X as createExponentialBackoffPolicy, Xt as PageItems, Y as RetryPolicy, Yt as SenderKeyPair, Z as RespondWithObjectOptions, Zt as buildCollectionSynchronizationHeader, _ as CollectionCallbackSetters, _t as normalizeCircuitBreakerOptions, a as GetObjectOptions, at as MessageQueueListenOptions, b as Federatable, bt as ActorDispatcher, c as OutboxContext, ct as CircuitBreakerActivityDrop, d as PortableRequest, dt as CircuitBreakerFailurePolicy, et as InProcessMessageQueue, f as RequestContext, ft as CircuitBreakerKvState, g as ActorCallbackSetters, gt as NormalizedCircuitBreakerOptions, h as SendActivityOptionsForCollection, ht as CircuitBreakerStateChange, i as GetActorOptions, it as MessageQueueEnqueueOptions, j as MediaUploaderSetters, jt as HashlinkMediaRequest, k as InboxChallengePolicy, kt as CustomCollectionDispatcher, l as ParseUriOptions, lt as CircuitBreakerBeforeSendDecision, m as SendActivityOptions, mt as CircuitBreakerState, n as Context, nt as MessageQueue, o as GetSignedKeyOptions, ot as ParallelMessageQueue, p as RouteActivityOptions, pt as CircuitBreakerOptions, q as CreateExponentialBackoffPolicyOptions, qt as WebFingerLinksDispatcher, r as ForwardActivityOptions, rt as MessageQueueDepth, s as InboxContext, st as CircuitBreaker, t as ActorKeyPair, tt as InProcessMessageQueueOptions, u as ParseUriResult, ut as CircuitBreakerCreateOptions, v as ConstructorWithTypeId, vt as parseCircuitBreakerKvState, w as FederationFetchOptions, wt as CollectionCounter, x as Federation, xt as ActorHandleMapper, y as CustomCollectionCallbackSetters, yt as ActorAliasMapper, z as createFederation, zt as OutboxListener } from "./context-L0Fnib9j.cjs";
5
+ import { $ as respondWithObjectIfAcceptable, $t as ActivityTransformer, A as InboxListenerSetters, At as HashlinkMediaDispatcher, B as Message, Bt as OutboxListenerErrorHandler, C as FederationBuilder, Ct as AuthorizePredicate, D as IdempotencyKeyCallback, Dt as CustomCollectionCounter, E as FederationStartQueueOptions, Et as CollectionDispatcher, F as Rfc6570Expression, Ft as NodeInfoDispatcher, G as TaskHandler, Gt as UnverifiedActivityHandler, H as TaskDefinition, Ht as PortableActorIdMapper, I as FederationKvPrefixes, It as ObjectAuthorizePredicate, J as RetryContext, Jt as SendActivityError, K as TaskRegistry, Kt as UnverifiedActivityReason, L as FederationOrigin, Lt as ObjectDispatcher, M as ObjectCallbackSetters, Mt as InboxErrorHandler, N as OutboxListenerSetters, Nt as InboxListener, O as IdempotencyStrategy, Ot as CustomCollectionCursor, P as PortableInboxForwardingOptions, Pt as MediaUploaderCallback, Q as respondWithObject, Qt as digest, R as FederationQueueOptions, Rt as OutboxErrorHandler, S as FederationBenchmarkOptions, St as ActorKeyPairsDispatcher, T as FederationOptions, Tt as CollectionCursor, U as TaskDefinitionOptions, Ut as PortableCollectionOwnerMapper, V as createFederationBuilder, Vt as OutboxPermanentFailureHandler, W as TaskEnqueueOptions, Wt as SharedInboxKeyDispatcher, X as createExponentialBackoffPolicy, Xt as PageItems, Y as RetryPolicy, Yt as SenderKeyPair, Z as RespondWithObjectOptions, Zt as buildCollectionSynchronizationHeader, _ as CollectionCallbackSetters, _t as normalizeCircuitBreakerOptions, a as GetObjectOptions, at as MessageQueueListenOptions, b as Federatable, bt as ActorDispatcher, c as OutboxContext, ct as CircuitBreakerActivityDrop, d as PortableRequest, dt as CircuitBreakerFailurePolicy, et as InProcessMessageQueue, f as RequestContext, ft as CircuitBreakerKvState, g as ActorCallbackSetters, gt as NormalizedCircuitBreakerOptions, h as SendActivityOptionsForCollection, ht as CircuitBreakerStateChange, i as GetActorOptions, it as MessageQueueEnqueueOptions, j as MediaUploaderSetters, jt as HashlinkMediaRequest, k as InboxChallengePolicy, kt as CustomCollectionDispatcher, l as ParseUriOptions, lt as CircuitBreakerBeforeSendDecision, m as SendActivityOptions, mt as CircuitBreakerState, n as Context, nt as MessageQueue, o as GetSignedKeyOptions, ot as ParallelMessageQueue, p as RouteActivityOptions, pt as CircuitBreakerOptions, q as CreateExponentialBackoffPolicyOptions, qt as WebFingerLinksDispatcher, r as ForwardActivityOptions, rt as MessageQueueDepth, s as InboxContext, st as CircuitBreaker, t as ActorKeyPair, tt as InProcessMessageQueueOptions, u as ParseUriResult, ut as CircuitBreakerCreateOptions, v as ConstructorWithTypeId, vt as parseCircuitBreakerKvState, w as FederationFetchOptions, wt as CollectionCounter, x as Federation, xt as ActorHandleMapper, y as CustomCollectionCallbackSetters, yt as ActorAliasMapper, z as createFederation, zt as OutboxListener } from "./context-CDcAgm4l.cjs";
6
6
  import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "./kv-BhNbN8Ed.cjs";
7
7
  import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "./compat/mod.cjs";
8
- import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "./mod-BLOXGs6m.cjs";
9
- import { C as createSignature, D as verifyJsonLd, E as signJsonLd, O as verifySignature, S as attachSignature, T as hasSignatureLike, _ as verifyProof, a as CreateProofOptions, b as VerifyJsonLdOptions, c as VerifyPortableObjectProofFailureReason, d as VerifyProofOptions, f as createProof, g as verifyPortableObjectProof, h as verifyObject, i as verifyPortableObject, l as VerifyPortableObjectProofOptions, m as signObject, n as VerifyPortableObjectOptions, o as SignObjectOptions, p as hasProofLike, r as VerifyPortableObjectResult, s as VerifyObjectOptions, t as VerifyPortableObjectFailureReason, u as VerifyPortableObjectProofResult, v as CreateSignatureOptions, w as detachSignature, x as VerifySignatureOptions, y as SignJsonLdOptions } from "./mod-CPPqkyV_.cjs";
10
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-BA_F2x53.cjs";
8
+ import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "./mod-D58KCqUg.cjs";
9
+ import { C as createSignature, D as verifyJsonLd, E as signJsonLd, O as verifySignature, S as attachSignature, T as hasSignatureLike, _ as verifyProof, a as CreateProofOptions, b as VerifyJsonLdOptions, c as VerifyPortableObjectProofFailureReason, d as VerifyProofOptions, f as createProof, g as verifyPortableObjectProof, h as verifyObject, i as verifyPortableObject, l as VerifyPortableObjectProofOptions, m as signObject, n as VerifyPortableObjectOptions, o as SignObjectOptions, p as hasProofLike, r as VerifyPortableObjectResult, s as VerifyObjectOptions, t as VerifyPortableObjectFailureReason, u as VerifyPortableObjectProofResult, v as CreateSignatureOptions, w as detachSignature, x as VerifySignatureOptions, y as SignJsonLdOptions } from "./mod-DHTuu3l8.cjs";
10
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-Dp3Ij7sw.cjs";
11
11
  export * from "@fedify/vocab-runtime";
12
12
 
13
13
  //#region src/mod.d.ts