@fedify/fedify 2.4.0-dev.1964 → 2.4.0-dev.1988

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 (83) hide show
  1. package/dist/{builder-B4zpKIFU.mjs → builder-Cts78G9N.mjs} +2 -2
  2. package/dist/{client-CtxvmazV.mjs → client-DpnpgjyX.mjs} +78 -4
  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/{context-COLwHogJ.d.cts → context-BeDnDuF3.d.cts} +4 -3
  7. package/dist/{context-DiiCt4S7.d.ts → context-uyRUWoZQ.d.ts} +4 -3
  8. package/dist/{deno-CtG93ohj.mjs → deno-BgMEefEr.mjs} +1 -1
  9. package/dist/{docloader-dk_k3S8d.mjs → docloader-DEYs99FZ.mjs} +2 -2
  10. package/dist/federation/builder.test.mjs +1 -1
  11. package/dist/federation/handler.test.mjs +122 -4
  12. package/dist/federation/idempotency.test.mjs +2 -2
  13. package/dist/federation/keycache.test.mjs +52 -9
  14. package/dist/federation/metrics.test.mjs +1 -1
  15. package/dist/federation/middleware.test.mjs +111 -15
  16. package/dist/federation/mod.cjs +1 -1
  17. package/dist/federation/mod.d.cts +2 -2
  18. package/dist/federation/mod.d.ts +2 -2
  19. package/dist/federation/mod.js +1 -1
  20. package/dist/federation/send.test.mjs +139 -4
  21. package/dist/federation/tasks/enqueue.test.mjs +1 -1
  22. package/dist/federation/tasks/tasks.test.mjs +2 -2
  23. package/dist/federation/temporal.test.mjs +1 -1
  24. package/dist/federation/webfinger.test.mjs +1 -1
  25. package/dist/{federation-Drjlrrax.cjs → federation-DzPUG_AP.cjs} +93 -17
  26. package/dist/{http-6TI0tI03.d.cts → http-65PYi9jY.d.ts} +34 -2
  27. package/dist/{http-CdrSn2ip.d.ts → http-CP-7OdSq.d.cts} +34 -2
  28. package/dist/{http-Dj4s1UQ0.js → http-CgwqtxAy.js} +169 -7
  29. package/dist/{http-D7LX-BL9.mjs → http-CtidZS_t.mjs} +3 -3
  30. package/dist/{http-B3skRvGo.cjs → http-Z3anvCd-.cjs} +180 -6
  31. package/dist/{key-BVjgbs_9.mjs → key-Cwbg5ggV.mjs} +169 -7
  32. package/dist/{keycache-ZLqIfrkL.mjs → keycache-BUDHB5rY.mjs} +12 -4
  33. package/dist/{kv-cache-DtsjH_bY.cjs → kv-cache-BM2-w-Wq.cjs} +2 -2
  34. package/dist/{kv-cache-tGNbvDCF.js → kv-cache-CykuL0ya.js} +2 -2
  35. package/dist/{kv-cache-xRcC_xxP.mjs → kv-cache-DHiR8yTf.mjs} +1 -1
  36. package/dist/{ld-OuCeQFny.mjs → ld-CzhdWyTt.mjs} +3 -3
  37. package/dist/{metrics-B9N27cCB.mjs → metrics-CrqsHP0l.mjs} +1 -1
  38. package/dist/{middleware-Cd_vPqDH.mjs → middleware-CZpYxSKD.mjs} +1 -1
  39. package/dist/{middleware-CPTDFMmJ.js → middleware-CeCj5caM.js} +101 -25
  40. package/dist/{middleware-TeLjzoxn.mjs → middleware-DCpiAsZi.mjs} +34 -23
  41. package/dist/{mod-DypxPS9H.d.ts → mod-C0BYc0OU.d.ts} +1 -1
  42. package/dist/{mod-CnGLNoVw.d.cts → mod-CbKDOnCt.d.cts} +1 -1
  43. package/dist/{mod-CLHkCwLm.d.cts → mod-CyiSjRkk.d.cts} +1 -1
  44. package/dist/{mod-CSH1Ee-I.d.ts → mod-D882_Xsg.d.ts} +1 -1
  45. package/dist/{mod-DzRXACM5.d.ts → mod-UDwMjuHM.d.ts} +1 -1
  46. package/dist/{mod-BZldCEU0.d.cts → mod-x9W0d0Pk.d.cts} +1 -1
  47. package/dist/mod.cjs +5 -5
  48. package/dist/mod.d.cts +6 -6
  49. package/dist/mod.d.ts +6 -6
  50. package/dist/mod.js +5 -5
  51. package/dist/nodeinfo/client.test.mjs +28 -1
  52. package/dist/nodeinfo/handler.test.mjs +1 -1
  53. package/dist/nodeinfo/mod.cjs +1 -1
  54. package/dist/nodeinfo/mod.js +1 -1
  55. package/dist/{owner-DGSfntI-.d.ts → owner-BF0L9cMt.d.cts} +12 -1
  56. package/dist/{owner-r_waTiQj.d.cts → owner-BSzr5-I8.d.ts} +12 -1
  57. package/dist/owner-BqVXJLW8.mjs +175 -0
  58. package/dist/{proof-BO_esQii.js → proof-CUghqhAf.js} +122 -65
  59. package/dist/{proof-Dua0d906.cjs → proof-DHu5zI0Z.cjs} +122 -65
  60. package/dist/{proof-D5Ajk4DJ.mjs → proof-DL8Iid3a.mjs} +14 -11
  61. package/dist/{send-DVXyUqhO.mjs → send-6jS4xFsX.mjs} +68 -11
  62. package/dist/sig/http.test.mjs +2 -2
  63. package/dist/sig/key.test.mjs +169 -2
  64. package/dist/sig/ld.test.mjs +55 -2
  65. package/dist/sig/mod.cjs +2 -2
  66. package/dist/sig/mod.d.cts +3 -3
  67. package/dist/sig/mod.d.ts +3 -3
  68. package/dist/sig/mod.js +2 -2
  69. package/dist/sig/owner.test.mjs +103 -4
  70. package/dist/sig/proof.test.mjs +120 -1
  71. package/dist/{temporal-BoDw51A-.mjs → temporal-DcyzeytP.mjs} +1 -1
  72. package/dist/testing/kv.test.mjs +1 -1
  73. package/dist/testing/mod.d.mts +2 -1
  74. package/dist/{types-RXm5YxpC.cjs → types-Be2zbyeG.cjs} +94 -2
  75. package/dist/{types-Dtyf8lVj.js → types-C_cNlNVK.js} +78 -4
  76. package/dist/utils/docloader.test.mjs +27 -3
  77. package/dist/utils/kv-cache.test.mjs +1 -1
  78. package/dist/utils/mod.cjs +1 -1
  79. package/dist/utils/mod.d.cts +1 -1
  80. package/dist/utils/mod.d.ts +1 -1
  81. package/dist/utils/mod.js +1 -1
  82. package/package.json +6 -6
  83. package/dist/owner-DTEqTzSr.mjs +0 -120
@@ -2,17 +2,17 @@ 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 { A as formatAcceptSignature, D as recordOutboxEnqueue, E as recordOutboxActivity, F as version, O as recordWebFingerHandle, P as name, S as recordCollectionTotalItems, T as recordInboxActivity, a as verifyRequestDetailed, b as recordCollectionPageItems, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, k as registerQueueDepthGauge, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, v as recordCircuitBreakerStateChange, w as recordFanoutRecipients, x as recordCollectionRequest, y as recordCollectionDispatchDuration } from "./http-Dj4s1UQ0.js";
6
- import { S as verifyCompactJsonLd, T as wrapContextLoaderForJsonLd, _ as hasSignature, b as isInvalidUrlTypeError, c as doesActorOwnKey, d as assertSafeJsonLd, g as getNormalizationContextLoader, h as detachSignature, i as verifyObject, l as getKeyOwner, n as hasProofLike, p as compactJsonLd, r as signObject, s as normalizeOutgoingActivityJsonLd, u as InvalidContextReferenceError, v as hasSignatureLike, x as signJsonLd, y as isClearlyMalformedContextReference } from "./proof-BO_esQii.js";
7
- import { n as getNodeInfo, t as nodeInfoToJson } from "./types-Dtyf8lVj.js";
8
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-tGNbvDCF.js";
5
+ import { A as recordWebFingerHandle, C as recordCollectionRequest, D as recordInboxActivity, E as recordFanoutRecipients, I as name, L as version, M as formatAcceptSignature, O as recordOutboxActivity, S as recordCollectionPageItems, _ as instrumentDocumentLoader, a as verifyRequestDetailed, b as recordCircuitBreakerStateChange, d as importJwk, f as validateCryptoKey, g as getRemoteHost, h as getFederationMetrics, i as verifyRequest, j as registerQueueDepthGauge, k as recordOutboxEnqueue, m as getDurationMs, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, v as isAbortError, w as recordCollectionTotalItems, x as recordCollectionDispatchDuration } from "./http-CgwqtxAy.js";
6
+ import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-C_cNlNVK.js";
7
+ import { S as verifyCompactJsonLd, T as wrapContextLoaderForJsonLd, _ as hasSignature, b as isInvalidUrlTypeError, c as doesActorOwnKey, d as assertSafeJsonLd, g as getNormalizationContextLoader, h as detachSignature, i as verifyObject, l as getKeyOwner, n as hasProofLike, p as compactJsonLd, r as signObject, s as normalizeOutgoingActivityJsonLd, u as InvalidContextReferenceError, v as hasSignatureLike, x as signJsonLd, y as isClearlyMalformedContextReference } from "./proof-CUghqhAf.js";
8
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-CykuL0ya.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, lookupObject, traverseCollection } from "@fedify/vocab";
12
12
  import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
13
13
  import { encodeHex } from "byte-encodings/hex";
14
+ import { FetchError, UrlError, getDocumentLoader, validatePublicUrl } from "@fedify/vocab-runtime";
14
15
  import { uniq } from "es-toolkit";
15
- import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
16
16
  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";
17
17
  import jsonld from "@fedify/vocab-runtime/jsonld";
18
18
  import { lookupWebFinger } from "@fedify/webfinger";
@@ -1455,6 +1455,7 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
1455
1455
  }
1456
1456
  //#endregion
1457
1457
  //#region src/federation/keycache.ts
1458
+ const KEY_CACHE_GENERATION = "2";
1458
1459
  var KvKeyCache = class {
1459
1460
  kv;
1460
1461
  prefix;
@@ -1477,13 +1478,20 @@ var KvKeyCache = class {
1477
1478
  keyId.href
1478
1479
  ];
1479
1480
  }
1481
+ #entryKey(keyId) {
1482
+ return [
1483
+ ...this.prefix,
1484
+ KEY_CACHE_GENERATION,
1485
+ keyId.href
1486
+ ];
1487
+ }
1480
1488
  async get(keyId) {
1481
1489
  const negativeExpiration = this.nullKeys.get(keyId.href);
1482
1490
  if (negativeExpiration != null) {
1483
1491
  if (Temporal.Now.instant().until(negativeExpiration).sign >= 0) return null;
1484
1492
  this.nullKeys.delete(keyId.href);
1485
1493
  }
1486
- const serialized = await this.kv.get([...this.prefix, keyId.href]);
1494
+ const serialized = await this.kv.get(this.#entryKey(keyId));
1487
1495
  if (serialized === void 0) return void 0;
1488
1496
  if (serialized === null) {
1489
1497
  this.nullKeys.set(keyId.href, Temporal.Now.instant().add(this.unavailableKeyTtl));
@@ -1495,7 +1503,7 @@ var KvKeyCache = class {
1495
1503
  try {
1496
1504
  return await Multikey.fromJsonLd(serialized, this.options);
1497
1505
  } catch {
1498
- await this.kv.delete([...this.prefix, keyId.href]);
1506
+ await this.kv.delete(this.#entryKey(keyId));
1499
1507
  return;
1500
1508
  }
1501
1509
  }
@@ -1503,12 +1511,12 @@ var KvKeyCache = class {
1503
1511
  async set(keyId, key) {
1504
1512
  if (key == null) {
1505
1513
  this.nullKeys.set(keyId.href, Temporal.Now.instant().add(this.unavailableKeyTtl));
1506
- await this.kv.set([...this.prefix, keyId.href], null, { ttl: this.unavailableKeyTtl });
1514
+ await this.kv.set(this.#entryKey(keyId), null, { ttl: this.unavailableKeyTtl });
1507
1515
  return;
1508
1516
  }
1509
1517
  this.nullKeys.delete(keyId.href);
1510
1518
  const serialized = await key.toJsonLd(this.options);
1511
- await this.kv.set([...this.prefix, keyId.href], serialized, { ttl: this.keyTtl });
1519
+ await this.kv.set(this.#entryKey(keyId), serialized, { ttl: this.keyTtl });
1512
1520
  }
1513
1521
  async getFetchError(keyId) {
1514
1522
  const cached = await this.kv.get(this.#getFetchErrorKey(keyId));
@@ -1855,13 +1863,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
1855
1863
  * @param parameters The parameters for handling the collection.
1856
1864
  * @returns A promise that resolves to an HTTP response.
1857
1865
  */
1858
- async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
1859
- const spanName = name$1.trim().replace(/\s+/g, "_");
1866
+ async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
1867
+ const spanName = name$2.trim().replace(/\s+/g, "_");
1860
1868
  tracerProvider = tracerProvider ?? trace.getTracerProvider();
1861
1869
  const tracer = tracerProvider.getTracer(name, version);
1862
1870
  const cursor = new URL(request.url).searchParams.get("cursor");
1863
1871
  const metricBase = {
1864
- kind: getCollectionMetricKind(name$1),
1872
+ kind: getCollectionMetricKind(name$2),
1865
1873
  page: cursor != null,
1866
1874
  dispatcher: "built_in"
1867
1875
  };
@@ -1902,7 +1910,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
1902
1910
  span.setStatus({ code: SpanStatusCode.ERROR });
1903
1911
  return await onNotFound(request);
1904
1912
  }
1905
- const items = filterCollectionItems(page.items, name$1, filterPredicate);
1913
+ const items = filterCollectionItems(page.items, name$2, filterPredicate);
1906
1914
  itemCount = items.length;
1907
1915
  span.setAttribute("fedify.collection.items", itemCount);
1908
1916
  return items;
@@ -1942,7 +1950,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
1942
1950
  } else {
1943
1951
  const uri = new URL(baseUri);
1944
1952
  uri.searchParams.set("cursor", cursor);
1945
- const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
1953
+ const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
1946
1954
  kind: SpanKind.SERVER,
1947
1955
  attributes: {
1948
1956
  "activitypub.collection.id": uri.href,
@@ -1958,7 +1966,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
1958
1966
  span.setStatus({ code: SpanStatusCode.ERROR });
1959
1967
  return await onNotFound(request);
1960
1968
  }
1961
- const items = filterCollectionItems(page.items, name$1, filterPredicate);
1969
+ const items = filterCollectionItems(page.items, name$2, filterPredicate);
1962
1970
  itemCount = items.length;
1963
1971
  span.setAttribute("fedify.collection.items", itemCount);
1964
1972
  return {
@@ -2511,8 +2519,16 @@ async function handleInboxInternal(request, parameters, span) {
2511
2519
  }
2512
2520
  let json;
2513
2521
  try {
2514
- json = await request.clone().json();
2522
+ json = JSON.parse(await readBoundedText(request.clone(), MAX_BODY_SIZE, request.url));
2515
2523
  } catch (error) {
2524
+ if (error instanceof BodyTooLargeError) {
2525
+ request.body?.cancel(error).catch(() => {});
2526
+ span.setStatus({
2527
+ code: SpanStatusCode.ERROR,
2528
+ message: String(error)
2529
+ });
2530
+ return new Response("Inbox body too large.", { status: 413 });
2531
+ }
2516
2532
  logger.error("Failed to parse JSON:\n{error}", {
2517
2533
  recipient,
2518
2534
  error
@@ -3018,8 +3034,8 @@ var CustomCollectionHandler = class {
3018
3034
  * @param CollectionPage The CollectionPage constructor.
3019
3035
  * @param filterPredicate Optional filter predicate for items.
3020
3036
  */
3021
- constructor(name$2, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
3022
- this.name = name$2;
3037
+ constructor(name$1, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
3038
+ this.name = name$1;
3023
3039
  this.values = values;
3024
3040
  this.context = context;
3025
3041
  this.callbacks = callbacks;
@@ -3644,7 +3660,7 @@ async function readLimitedResponseBody(response, maxBytes) {
3644
3660
  if (truncated) result += "… (truncated)";
3645
3661
  return result;
3646
3662
  }
3647
- async function sendActivityInternal({ activity, activityId, activityType, keys, inbox, headers, specDeterminer, meterProvider, tracerProvider }, span) {
3663
+ async function sendActivityInternal({ activity, activityId, activityType, keys, inbox, allowPrivateAddress, headers, specDeterminer, meterProvider, tracerProvider }, span) {
3648
3664
  const logger = getLogger([
3649
3665
  "fedify",
3650
3666
  "federation",
@@ -3653,12 +3669,25 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
3653
3669
  const federationMetrics = getFederationMetrics(meterProvider);
3654
3670
  const started = performance.now();
3655
3671
  let deliverySuccess = false;
3672
+ async function validateUrl(url) {
3673
+ if (!allowPrivateAddress) try {
3674
+ await validatePublicUrl(url);
3675
+ } catch (error) {
3676
+ if (error instanceof UrlError) logger.error("Disallowed private URL: {url}", {
3677
+ url,
3678
+ error
3679
+ });
3680
+ throw error;
3681
+ }
3682
+ }
3683
+ await validateUrl(inbox.href);
3656
3684
  headers = new Headers(headers);
3657
3685
  headers.set("Content-Type", "application/activity+json");
3658
3686
  const request = new Request(inbox, {
3659
3687
  method: "POST",
3660
3688
  headers,
3661
- body: JSON.stringify(activity)
3689
+ body: JSON.stringify(activity),
3690
+ redirect: "manual"
3662
3691
  });
3663
3692
  let rsaKey = null;
3664
3693
  for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
@@ -3674,19 +3703,20 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
3674
3703
  });
3675
3704
  let response;
3676
3705
  try {
3677
- response = rsaKey == null ? await fetch(request) : await doubleKnock(request, rsaKey, {
3706
+ response = rsaKey == null ? await fetchWithValidatedRedirects(request, validateUrl) : await doubleKnock(request, rsaKey, {
3678
3707
  tracerProvider,
3679
- specDeterminer
3708
+ specDeterminer,
3709
+ validateRedirect: validateUrl
3680
3710
  });
3681
3711
  } catch (error) {
3682
- const transportError = error instanceof FetchError ? error : createFetchError(inbox.href, error);
3712
+ const failure = error instanceof FetchError || error instanceof UrlError ? error : createFetchError(inbox.href, error);
3683
3713
  logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
3684
3714
  activityId,
3685
3715
  inbox: inbox.href,
3686
- error: transportError
3716
+ error: failure
3687
3717
  });
3688
3718
  federationMetrics.recordDelivery(inbox, getDurationMs(started), false, activityType);
3689
- throw transportError;
3719
+ throw failure;
3690
3720
  }
3691
3721
  try {
3692
3722
  if (!response.ok) {
@@ -3723,6 +3753,49 @@ function createFetchError(url, cause) {
3723
3753
  error.cause = cause;
3724
3754
  return error;
3725
3755
  }
3756
+ async function fetchWithValidatedRedirects(request, validateUrl) {
3757
+ let body = await request.clone().text();
3758
+ for (let redirects = 0;; redirects++) {
3759
+ const response = await fetch(request, { redirect: "manual" });
3760
+ const location = response.headers.get("Location");
3761
+ if (![
3762
+ 301,
3763
+ 302,
3764
+ 303,
3765
+ 307,
3766
+ 308
3767
+ ].includes(response.status) || location == null) return response;
3768
+ await response.body?.cancel();
3769
+ if (redirects >= 20) throw new TypeError("Too many redirects");
3770
+ const url = new URL(location, request.url);
3771
+ await validateUrl(url.href);
3772
+ const headers = new Headers(request.headers);
3773
+ if (url.origin !== new URL(request.url).origin) {
3774
+ headers.delete("Authorization");
3775
+ headers.delete("Proxy-Authorization");
3776
+ headers.delete("Cookie");
3777
+ headers.delete("Host");
3778
+ }
3779
+ let method = request.method;
3780
+ if ((response.status === 301 || response.status === 302) && method === "POST" || response.status === 303 && method !== "GET" && method !== "HEAD") {
3781
+ method = "GET";
3782
+ body = void 0;
3783
+ for (const name of [
3784
+ "Content-Encoding",
3785
+ "Content-Language",
3786
+ "Content-Length",
3787
+ "Content-Location",
3788
+ "Content-Type"
3789
+ ]) headers.delete(name);
3790
+ }
3791
+ request = new Request(url, {
3792
+ method,
3793
+ headers,
3794
+ body,
3795
+ redirect: "manual"
3796
+ });
3797
+ }
3798
+ }
3726
3799
  /**
3727
3800
  * An error that is thrown when an activity fails to send to a remote inbox.
3728
3801
  * It contains structured information about the failure, including the HTTP
@@ -5213,6 +5286,7 @@ var FederationImpl = class extends FederationBuilderImpl {
5213
5286
  if (decision.stateChange != null) recordCircuitBreakerSpanEvent(span, remoteHost, decision.stateChange);
5214
5287
  }
5215
5288
  await sendActivity({
5289
+ allowPrivateAddress: this.allowPrivateAddress,
5216
5290
  keys,
5217
5291
  activity: message.activity,
5218
5292
  activityId: message.activityId,
@@ -5834,6 +5908,7 @@ var FederationImpl = class extends FederationBuilderImpl {
5834
5908
  });
5835
5909
  const promises = [];
5836
5910
  for (const inbox in inboxes) promises.push(sendActivity({
5911
+ allowPrivateAddress: this.allowPrivateAddress,
5837
5912
  keys,
5838
5913
  activity: jsonLd,
5839
5914
  activityId: activity.id?.href,
@@ -7168,6 +7243,7 @@ async function forwardActivityInternal(ctx, loggerCategory, forwarder, recipient
7168
7243
  else logger.debug("Forwarding activity immediately without queue since queue is not set.");
7169
7244
  const promises = [];
7170
7245
  for (const inbox in inboxes) promises.push(sendActivity({
7246
+ allowPrivateAddress: ctx.federation.allowPrivateAddress,
7171
7247
  keys,
7172
7248
  activity: ctx.activity,
7173
7249
  activityId: ctx.activityId,
@@ -1,26 +1,26 @@
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-CtG93ohj.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-B9N27cCB.mjs";
4
+ import { n as version, t as name } from "./deno-BgMEefEr.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-CrqsHP0l.mjs";
6
6
  import { t as formatAcceptSignature } from "./accept-CPVqki78.mjs";
7
- import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-BVjgbs_9.mjs";
8
- import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-D7LX-BL9.mjs";
9
- import { t as getAuthenticatedDocumentLoader } from "./docloader-dk_k3S8d.mjs";
10
- import { n as kvCache } from "./kv-cache-xRcC_xxP.mjs";
7
+ import { o as importJwk, s as validateCryptoKey, t as exportJwk } from "./key-Cwbg5ggV.mjs";
8
+ import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-CtidZS_t.mjs";
9
+ import { t as getAuthenticatedDocumentLoader } from "./docloader-DEYs99FZ.mjs";
10
+ import { n as kvCache } from "./kv-cache-DHiR8yTf.mjs";
11
11
  import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-B5Ne7JoL.mjs";
12
- import { t as getNodeInfo } from "./client-CtxvmazV.mjs";
12
+ import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-DpnpgjyX.mjs";
13
13
  import { t as nodeInfoToJson } from "./types-DE_LV1JB.mjs";
14
- 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-OuCeQFny.mjs";
15
- import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-DTEqTzSr.mjs";
16
- import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-D5Ajk4DJ.mjs";
17
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-DVXyUqhO.mjs";
18
- import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-B4zpKIFU.mjs";
14
+ 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-CzhdWyTt.mjs";
15
+ import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-BqVXJLW8.mjs";
16
+ import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-DL8Iid3a.mjs";
17
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-6jS4xFsX.mjs";
18
+ import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-Cts78G9N.mjs";
19
19
  import { t as CircuitBreaker } from "./circuit-breaker-C5NqoLBJ.mjs";
20
20
  import { t as buildCollectionSynchronizationHeader } from "./collection-CnnP1UAv.mjs";
21
- import { t as KvKeyCache } from "./keycache-ZLqIfrkL.mjs";
21
+ import { t as KvKeyCache } from "./keycache-BUDHB5rY.mjs";
22
22
  import { t as acceptsJsonLd } from "./negotiation-CCocWT_N.mjs";
23
- import { t as hasMalformedKnownTemporalLiteral } from "./temporal-BoDw51A-.mjs";
23
+ import { t as hasMalformedKnownTemporalLiteral } from "./temporal-DcyzeytP.mjs";
24
24
  import { t as createExponentialBackoffPolicy } from "./retry-zX5xw5e0.mjs";
25
25
  import { t as TaskCodec } from "./codec-C6rTrpIp.mjs";
26
26
  import { getLogger, withContext } from "@logtape/logtape";
@@ -637,13 +637,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
637
637
  * @param parameters The parameters for handling the collection.
638
638
  * @returns A promise that resolves to an HTTP response.
639
639
  */
640
- async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
641
- const spanName = name$1.trim().replace(/\s+/g, "_");
640
+ async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
641
+ const spanName = name$2.trim().replace(/\s+/g, "_");
642
642
  tracerProvider = tracerProvider ?? trace.getTracerProvider();
643
643
  const tracer = tracerProvider.getTracer(name, version);
644
644
  const cursor = new URL(request.url).searchParams.get("cursor");
645
645
  const metricBase = {
646
- kind: getCollectionMetricKind(name$1),
646
+ kind: getCollectionMetricKind(name$2),
647
647
  page: cursor != null,
648
648
  dispatcher: "built_in"
649
649
  };
@@ -684,7 +684,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
684
684
  span.setStatus({ code: SpanStatusCode.ERROR });
685
685
  return await onNotFound(request);
686
686
  }
687
- const items = filterCollectionItems(page.items, name$1, filterPredicate);
687
+ const items = filterCollectionItems(page.items, name$2, filterPredicate);
688
688
  itemCount = items.length;
689
689
  span.setAttribute("fedify.collection.items", itemCount);
690
690
  return items;
@@ -724,7 +724,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
724
724
  } else {
725
725
  const uri = new URL(baseUri);
726
726
  uri.searchParams.set("cursor", cursor);
727
- const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
727
+ const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
728
728
  kind: SpanKind.SERVER,
729
729
  attributes: {
730
730
  "activitypub.collection.id": uri.href,
@@ -740,7 +740,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
740
740
  span.setStatus({ code: SpanStatusCode.ERROR });
741
741
  return await onNotFound(request);
742
742
  }
743
- const items = filterCollectionItems(page.items, name$1, filterPredicate);
743
+ const items = filterCollectionItems(page.items, name$2, filterPredicate);
744
744
  itemCount = items.length;
745
745
  span.setAttribute("fedify.collection.items", itemCount);
746
746
  return {
@@ -1293,8 +1293,16 @@ async function handleInboxInternal(request, parameters, span) {
1293
1293
  }
1294
1294
  let json;
1295
1295
  try {
1296
- json = await request.clone().json();
1296
+ json = JSON.parse(await readBoundedText(request.clone(), MAX_BODY_SIZE, request.url));
1297
1297
  } catch (error) {
1298
+ if (error instanceof BodyTooLargeError) {
1299
+ request.body?.cancel(error).catch(() => {});
1300
+ span.setStatus({
1301
+ code: SpanStatusCode.ERROR,
1302
+ message: String(error)
1303
+ });
1304
+ return new Response("Inbox body too large.", { status: 413 });
1305
+ }
1298
1306
  logger.error("Failed to parse JSON:\n{error}", {
1299
1307
  recipient,
1300
1308
  error
@@ -1800,8 +1808,8 @@ var CustomCollectionHandler = class {
1800
1808
  * @param CollectionPage The CollectionPage constructor.
1801
1809
  * @param filterPredicate Optional filter predicate for items.
1802
1810
  */
1803
- constructor(name$2, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
1804
- this.name = name$2;
1811
+ constructor(name$1, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
1812
+ this.name = name$1;
1805
1813
  this.values = values;
1806
1814
  this.context = context;
1807
1815
  this.callbacks = callbacks;
@@ -3357,6 +3365,7 @@ var FederationImpl = class extends FederationBuilderImpl {
3357
3365
  if (decision.stateChange != null) recordCircuitBreakerSpanEvent(span, remoteHost, decision.stateChange);
3358
3366
  }
3359
3367
  await sendActivity({
3368
+ allowPrivateAddress: this.allowPrivateAddress,
3360
3369
  keys,
3361
3370
  activity: message.activity,
3362
3371
  activityId: message.activityId,
@@ -3978,6 +3987,7 @@ var FederationImpl = class extends FederationBuilderImpl {
3978
3987
  });
3979
3988
  const promises = [];
3980
3989
  for (const inbox in inboxes) promises.push(sendActivity({
3990
+ allowPrivateAddress: this.allowPrivateAddress,
3981
3991
  keys,
3982
3992
  activity: jsonLd,
3983
3993
  activityId: activity.id?.href,
@@ -5312,6 +5322,7 @@ async function forwardActivityInternal(ctx, loggerCategory, forwarder, recipient
5312
5322
  else logger.debug("Forwarding activity immediately without queue since queue is not set.");
5313
5323
  const promises = [];
5314
5324
  for (const inbox in inboxes) promises.push(sendActivity({
5325
+ allowPrivateAddress: ctx.federation.allowPrivateAddress,
5315
5326
  keys,
5316
5327
  activity: ctx.activity,
5317
5328
  activityId: ctx.activityId,
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { n as HttpMessageSignaturesSpecDeterminer } from "./http-CdrSn2ip.js";
2
+ import { n as HttpMessageSignaturesSpecDeterminer } from "./http-65PYi9jY.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";
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { S as KeyCache } from "./http-6TI0tI03.cjs";
2
+ import { S as KeyCache } from "./http-CP-7OdSq.cjs";
3
3
  import { CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1 } from "@fedify/vocab";
4
4
  import { DocumentLoader } 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-6TI0tI03.cjs";
2
+ import { n as HttpMessageSignaturesSpecDeterminer } from "./http-CP-7OdSq.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";
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { _t as ActorHandleMapper, gt as ActorDispatcher, ht as ActorAliasMapper, l as RequestContext, zt as WebFingerLinksDispatcher } from "./context-DiiCt4S7.js";
2
+ import { _t as ActorHandleMapper, gt as ActorDispatcher, ht as ActorAliasMapper, l as RequestContext, zt as WebFingerLinksDispatcher } from "./context-uyRUWoZQ.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 { S as KeyCache } from "./http-CdrSn2ip.js";
2
+ import { S as KeyCache } from "./http-65PYi9jY.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 } from "@fedify/vocab-runtime";
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { _t as ActorHandleMapper, gt as ActorDispatcher, ht as ActorAliasMapper, l as RequestContext, zt as WebFingerLinksDispatcher } from "./context-COLwHogJ.cjs";
2
+ import { _t as ActorHandleMapper, gt as ActorDispatcher, ht as ActorAliasMapper, l as RequestContext, zt as WebFingerLinksDispatcher } from "./context-BeDnDuF3.cjs";
3
3
  import { MeterProvider, Span, Tracer } from "@opentelemetry/api";
4
4
  import { RouterError, RouterOptions, RouterRouteResult } from "@fedify/uri-template";
5
5
 
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-B3skRvGo.cjs");
7
- const require_federation = require("./federation-Drjlrrax.cjs");
8
- const require_proof = require("./proof-Dua0d906.cjs");
9
- const require_types = require("./types-RXm5YxpC.cjs");
10
- const require_kv_cache = require("./kv-cache-DtsjH_bY.cjs");
6
+ const require_http = require("./http-Z3anvCd-.cjs");
7
+ const require_federation = require("./federation-DzPUG_AP.cjs");
8
+ const require_types = require("./types-Be2zbyeG.cjs");
9
+ const require_proof = require("./proof-DHu5zI0Z.cjs");
10
+ const require_kv_cache = require("./kv-cache-BM2-w-Wq.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-6TI0tI03.cjs";
4
- import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-r_waTiQj.cjs";
5
- import { $ as MessageQueueDepth, A as OutboxListenerSetters, At as ObjectAuthorizePredicate, B as TaskEnqueueOptions, Bt as SendActivityError, C as FederationStartQueueOptions, Ct as CustomCollectionCounter, D as InboxListenerSetters, Dt as InboxListener, E as InboxChallengePolicy, Et as InboxErrorHandler, F as createFederation, Ft as OutboxPermanentFailureHandler, G as RetryPolicy, Gt as ActivityTransformer, H as TaskRegistry, Ht as PageItems, I as Message, It as SharedInboxKeyDispatcher, J as respondWithObject, K as createExponentialBackoffPolicy, L as createFederationBuilder, Lt as UnverifiedActivityHandler, M as FederationKvPrefixes, Mt as OutboxErrorHandler, N as FederationOrigin, Nt as OutboxListener, O as MediaUploaderSetters, Ot as MediaUploaderCallback, P as FederationQueueOptions, Pt as OutboxListenerErrorHandler, Q as MessageQueue, R as TaskDefinition, Rt as UnverifiedActivityReason, S as FederationOptions, St as CollectionDispatcher, T as IdempotencyStrategy, Tt as CustomCollectionDispatcher, U as CreateExponentialBackoffPolicyOptions, Ut as buildCollectionSynchronizationHeader, V as TaskHandler, Vt as SenderKeyPair, W as RetryContext, Wt as digest, X as InProcessMessageQueue, Y as respondWithObjectIfAcceptable, Z as InProcessMessageQueueOptions, _ as Federatable, _t as ActorHandleMapper, a as GetSignedKeyOptions, at as CircuitBreakerBeforeSendDecision, b as FederationBuilder, bt as CollectionCounter, c as ParseUriResult, ct as CircuitBreakerKvState, d as SendActivityOptions, dt as CircuitBreakerStateChange, et as MessageQueueEnqueueOptions, f as SendActivityOptionsForCollection, ft as NormalizedCircuitBreakerOptions, g as CustomCollectionCallbackSetters, gt as ActorDispatcher, h as ConstructorWithTypeId, ht as ActorAliasMapper, i as GetActorOptions, it as CircuitBreakerActivityDrop, j as Rfc6570Expression, jt as ObjectDispatcher, k as ObjectCallbackSetters, kt as NodeInfoDispatcher, l as RequestContext, lt as CircuitBreakerOptions, m as CollectionCallbackSetters, mt as parseCircuitBreakerKvState, n as Context, nt as ParallelMessageQueue, o as InboxContext, ot as CircuitBreakerCreateOptions, p as ActorCallbackSetters, pt as normalizeCircuitBreakerOptions, q as RespondWithObjectOptions, r as ForwardActivityOptions, rt as CircuitBreaker, s as OutboxContext, st as CircuitBreakerFailurePolicy, t as ActorKeyPair, tt as MessageQueueListenOptions, u as RouteActivityOptions, ut as CircuitBreakerState, v as Federation, vt as ActorKeyPairsDispatcher, w as IdempotencyKeyCallback, wt as CustomCollectionCursor, x as FederationFetchOptions, xt as CollectionCursor, y as FederationBenchmarkOptions, yt as AuthorizePredicate, z as TaskDefinitionOptions, zt as WebFingerLinksDispatcher } from "./context-COLwHogJ.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-CP-7OdSq.cjs";
4
+ import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-BF0L9cMt.cjs";
5
+ import { $ as MessageQueueDepth, A as OutboxListenerSetters, At as ObjectAuthorizePredicate, B as TaskEnqueueOptions, Bt as SendActivityError, C as FederationStartQueueOptions, Ct as CustomCollectionCounter, D as InboxListenerSetters, Dt as InboxListener, E as InboxChallengePolicy, Et as InboxErrorHandler, F as createFederation, Ft as OutboxPermanentFailureHandler, G as RetryPolicy, Gt as ActivityTransformer, H as TaskRegistry, Ht as PageItems, I as Message, It as SharedInboxKeyDispatcher, J as respondWithObject, K as createExponentialBackoffPolicy, L as createFederationBuilder, Lt as UnverifiedActivityHandler, M as FederationKvPrefixes, Mt as OutboxErrorHandler, N as FederationOrigin, Nt as OutboxListener, O as MediaUploaderSetters, Ot as MediaUploaderCallback, P as FederationQueueOptions, Pt as OutboxListenerErrorHandler, Q as MessageQueue, R as TaskDefinition, Rt as UnverifiedActivityReason, S as FederationOptions, St as CollectionDispatcher, T as IdempotencyStrategy, Tt as CustomCollectionDispatcher, U as CreateExponentialBackoffPolicyOptions, Ut as buildCollectionSynchronizationHeader, V as TaskHandler, Vt as SenderKeyPair, W as RetryContext, Wt as digest, X as InProcessMessageQueue, Y as respondWithObjectIfAcceptable, Z as InProcessMessageQueueOptions, _ as Federatable, _t as ActorHandleMapper, a as GetSignedKeyOptions, at as CircuitBreakerBeforeSendDecision, b as FederationBuilder, bt as CollectionCounter, c as ParseUriResult, ct as CircuitBreakerKvState, d as SendActivityOptions, dt as CircuitBreakerStateChange, et as MessageQueueEnqueueOptions, f as SendActivityOptionsForCollection, ft as NormalizedCircuitBreakerOptions, g as CustomCollectionCallbackSetters, gt as ActorDispatcher, h as ConstructorWithTypeId, ht as ActorAliasMapper, i as GetActorOptions, it as CircuitBreakerActivityDrop, j as Rfc6570Expression, jt as ObjectDispatcher, k as ObjectCallbackSetters, kt as NodeInfoDispatcher, l as RequestContext, lt as CircuitBreakerOptions, m as CollectionCallbackSetters, mt as parseCircuitBreakerKvState, n as Context, nt as ParallelMessageQueue, o as InboxContext, ot as CircuitBreakerCreateOptions, p as ActorCallbackSetters, pt as normalizeCircuitBreakerOptions, q as RespondWithObjectOptions, r as ForwardActivityOptions, rt as CircuitBreaker, s as OutboxContext, st as CircuitBreakerFailurePolicy, t as ActorKeyPair, tt as MessageQueueListenOptions, u as RouteActivityOptions, ut as CircuitBreakerState, v as Federation, vt as ActorKeyPairsDispatcher, w as IdempotencyKeyCallback, wt as CustomCollectionCursor, x as FederationFetchOptions, xt as CollectionCursor, y as FederationBenchmarkOptions, yt as AuthorizePredicate, z as TaskDefinitionOptions, zt as WebFingerLinksDispatcher } from "./context-BeDnDuF3.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-BZldCEU0.cjs";
9
- import { C as verifyJsonLd, S as signJsonLd, _ as VerifySignatureOptions, a as VerifyPortableObjectProofOptions, b as detachSignature, c as createProof, d as verifyObject, f as verifyPortableObjectProof, g as VerifyJsonLdOptions, h as SignJsonLdOptions, i as VerifyPortableObjectProofFailureReason, l as hasProofLike, m as CreateSignatureOptions, n as SignObjectOptions, o as VerifyPortableObjectProofResult, p as verifyProof, r as VerifyObjectOptions, s as VerifyProofOptions, t as CreateProofOptions, u as signObject, v as attachSignature, w as verifySignature, x as hasSignatureLike, y as createSignature } from "./mod-CnGLNoVw.cjs";
10
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-CLHkCwLm.cjs";
8
+ import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "./mod-x9W0d0Pk.cjs";
9
+ import { C as verifyJsonLd, S as signJsonLd, _ as VerifySignatureOptions, a as VerifyPortableObjectProofOptions, b as detachSignature, c as createProof, d as verifyObject, f as verifyPortableObjectProof, g as VerifyJsonLdOptions, h as SignJsonLdOptions, i as VerifyPortableObjectProofFailureReason, l as hasProofLike, m as CreateSignatureOptions, n as SignObjectOptions, o as VerifyPortableObjectProofResult, p as verifyProof, r as VerifyObjectOptions, s as VerifyProofOptions, t as CreateProofOptions, u as signObject, v as attachSignature, w as verifySignature, x as hasSignatureLike, y as createSignature } from "./mod-CbKDOnCt.cjs";
10
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-CyiSjRkk.cjs";
11
11
  export * from "@fedify/vocab-runtime";
12
12
 
13
13
  //#region src/mod.d.ts
package/dist/mod.d.ts 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.js";
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-CdrSn2ip.js";
4
- import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-DGSfntI-.js";
5
- import { $ as MessageQueueDepth, A as OutboxListenerSetters, At as ObjectAuthorizePredicate, B as TaskEnqueueOptions, Bt as SendActivityError, C as FederationStartQueueOptions, Ct as CustomCollectionCounter, D as InboxListenerSetters, Dt as InboxListener, E as InboxChallengePolicy, Et as InboxErrorHandler, F as createFederation, Ft as OutboxPermanentFailureHandler, G as RetryPolicy, Gt as ActivityTransformer, H as TaskRegistry, Ht as PageItems, I as Message, It as SharedInboxKeyDispatcher, J as respondWithObject, K as createExponentialBackoffPolicy, L as createFederationBuilder, Lt as UnverifiedActivityHandler, M as FederationKvPrefixes, Mt as OutboxErrorHandler, N as FederationOrigin, Nt as OutboxListener, O as MediaUploaderSetters, Ot as MediaUploaderCallback, P as FederationQueueOptions, Pt as OutboxListenerErrorHandler, Q as MessageQueue, R as TaskDefinition, Rt as UnverifiedActivityReason, S as FederationOptions, St as CollectionDispatcher, T as IdempotencyStrategy, Tt as CustomCollectionDispatcher, U as CreateExponentialBackoffPolicyOptions, Ut as buildCollectionSynchronizationHeader, V as TaskHandler, Vt as SenderKeyPair, W as RetryContext, Wt as digest, X as InProcessMessageQueue, Y as respondWithObjectIfAcceptable, Z as InProcessMessageQueueOptions, _ as Federatable, _t as ActorHandleMapper, a as GetSignedKeyOptions, at as CircuitBreakerBeforeSendDecision, b as FederationBuilder, bt as CollectionCounter, c as ParseUriResult, ct as CircuitBreakerKvState, d as SendActivityOptions, dt as CircuitBreakerStateChange, et as MessageQueueEnqueueOptions, f as SendActivityOptionsForCollection, ft as NormalizedCircuitBreakerOptions, g as CustomCollectionCallbackSetters, gt as ActorDispatcher, h as ConstructorWithTypeId, ht as ActorAliasMapper, i as GetActorOptions, it as CircuitBreakerActivityDrop, j as Rfc6570Expression, jt as ObjectDispatcher, k as ObjectCallbackSetters, kt as NodeInfoDispatcher, l as RequestContext, lt as CircuitBreakerOptions, m as CollectionCallbackSetters, mt as parseCircuitBreakerKvState, n as Context, nt as ParallelMessageQueue, o as InboxContext, ot as CircuitBreakerCreateOptions, p as ActorCallbackSetters, pt as normalizeCircuitBreakerOptions, q as RespondWithObjectOptions, r as ForwardActivityOptions, rt as CircuitBreaker, s as OutboxContext, st as CircuitBreakerFailurePolicy, t as ActorKeyPair, tt as MessageQueueListenOptions, u as RouteActivityOptions, ut as CircuitBreakerState, v as Federation, vt as ActorKeyPairsDispatcher, w as IdempotencyKeyCallback, wt as CustomCollectionCursor, x as FederationFetchOptions, xt as CollectionCursor, y as FederationBenchmarkOptions, yt as AuthorizePredicate, z as TaskDefinitionOptions, zt as WebFingerLinksDispatcher } from "./context-DiiCt4S7.js";
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-65PYi9jY.js";
4
+ import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-BSzr5-I8.js";
5
+ import { $ as MessageQueueDepth, A as OutboxListenerSetters, At as ObjectAuthorizePredicate, B as TaskEnqueueOptions, Bt as SendActivityError, C as FederationStartQueueOptions, Ct as CustomCollectionCounter, D as InboxListenerSetters, Dt as InboxListener, E as InboxChallengePolicy, Et as InboxErrorHandler, F as createFederation, Ft as OutboxPermanentFailureHandler, G as RetryPolicy, Gt as ActivityTransformer, H as TaskRegistry, Ht as PageItems, I as Message, It as SharedInboxKeyDispatcher, J as respondWithObject, K as createExponentialBackoffPolicy, L as createFederationBuilder, Lt as UnverifiedActivityHandler, M as FederationKvPrefixes, Mt as OutboxErrorHandler, N as FederationOrigin, Nt as OutboxListener, O as MediaUploaderSetters, Ot as MediaUploaderCallback, P as FederationQueueOptions, Pt as OutboxListenerErrorHandler, Q as MessageQueue, R as TaskDefinition, Rt as UnverifiedActivityReason, S as FederationOptions, St as CollectionDispatcher, T as IdempotencyStrategy, Tt as CustomCollectionDispatcher, U as CreateExponentialBackoffPolicyOptions, Ut as buildCollectionSynchronizationHeader, V as TaskHandler, Vt as SenderKeyPair, W as RetryContext, Wt as digest, X as InProcessMessageQueue, Y as respondWithObjectIfAcceptable, Z as InProcessMessageQueueOptions, _ as Federatable, _t as ActorHandleMapper, a as GetSignedKeyOptions, at as CircuitBreakerBeforeSendDecision, b as FederationBuilder, bt as CollectionCounter, c as ParseUriResult, ct as CircuitBreakerKvState, d as SendActivityOptions, dt as CircuitBreakerStateChange, et as MessageQueueEnqueueOptions, f as SendActivityOptionsForCollection, ft as NormalizedCircuitBreakerOptions, g as CustomCollectionCallbackSetters, gt as ActorDispatcher, h as ConstructorWithTypeId, ht as ActorAliasMapper, i as GetActorOptions, it as CircuitBreakerActivityDrop, j as Rfc6570Expression, jt as ObjectDispatcher, k as ObjectCallbackSetters, kt as NodeInfoDispatcher, l as RequestContext, lt as CircuitBreakerOptions, m as CollectionCallbackSetters, mt as parseCircuitBreakerKvState, n as Context, nt as ParallelMessageQueue, o as InboxContext, ot as CircuitBreakerCreateOptions, p as ActorCallbackSetters, pt as normalizeCircuitBreakerOptions, q as RespondWithObjectOptions, r as ForwardActivityOptions, rt as CircuitBreaker, s as OutboxContext, st as CircuitBreakerFailurePolicy, t as ActorKeyPair, tt as MessageQueueListenOptions, u as RouteActivityOptions, ut as CircuitBreakerState, v as Federation, vt as ActorKeyPairsDispatcher, w as IdempotencyKeyCallback, wt as CustomCollectionCursor, x as FederationFetchOptions, xt as CollectionCursor, y as FederationBenchmarkOptions, yt as AuthorizePredicate, z as TaskDefinitionOptions, zt as WebFingerLinksDispatcher } from "./context-uyRUWoZQ.js";
6
6
  import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "./kv-BhNbN8Ed.js";
7
7
  import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "./compat/mod.js";
8
- import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "./mod-CSH1Ee-I.js";
9
- import { C as verifyJsonLd, S as signJsonLd, _ as VerifySignatureOptions, a as VerifyPortableObjectProofOptions, b as detachSignature, c as createProof, d as verifyObject, f as verifyPortableObjectProof, g as VerifyJsonLdOptions, h as SignJsonLdOptions, i as VerifyPortableObjectProofFailureReason, l as hasProofLike, m as CreateSignatureOptions, n as SignObjectOptions, o as VerifyPortableObjectProofResult, p as verifyProof, r as VerifyObjectOptions, s as VerifyProofOptions, t as CreateProofOptions, u as signObject, v as attachSignature, w as verifySignature, x as hasSignatureLike, y as createSignature } from "./mod-DzRXACM5.js";
10
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-DypxPS9H.js";
8
+ import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "./mod-D882_Xsg.js";
9
+ import { C as verifyJsonLd, S as signJsonLd, _ as VerifySignatureOptions, a as VerifyPortableObjectProofOptions, b as detachSignature, c as createProof, d as verifyObject, f as verifyPortableObjectProof, g as VerifyJsonLdOptions, h as SignJsonLdOptions, i as VerifyPortableObjectProofFailureReason, l as hasProofLike, m as CreateSignatureOptions, n as SignObjectOptions, o as VerifyPortableObjectProofResult, p as verifyProof, r as VerifyObjectOptions, s as VerifyProofOptions, t as CreateProofOptions, u as signObject, v as attachSignature, w as verifySignature, x as hasSignatureLike, y as createSignature } from "./mod-UDwMjuHM.js";
10
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-C0BYc0OU.js";
11
11
  export * from "@fedify/vocab-runtime";
12
12
 
13
13
  //#region src/mod.d.ts
package/dist/mod.js CHANGED
@@ -3,11 +3,11 @@ import { URLPattern } from "urlpattern-polyfill";
3
3
  import "./rolldown-runtime-BC-Eo5Mj.js";
4
4
  import { n as autoIdAssigner, r as getDefaultActivityTransformers, t as actorDehydrator } from "./transformers-DAtXl_Kc.js";
5
5
  import "./compat/mod.js";
6
- import { A as formatAcceptSignature, M as parseAcceptSignature, N as validateAcceptSignature, a as verifyRequestDetailed, c as fetchKeyDetailed, i as verifyRequest, j as fulfillAcceptSignature, l as generateCryptoKeyPair, o as exportJwk, r as signRequest, s as fetchKey, u as importJwk } from "./http-Dj4s1UQ0.js";
7
- import { a as respondWithObject, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as SendActivityError, l as CircuitBreaker, n as handleWebFinger, o as respondWithObjectIfAcceptable, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "./middleware-CPTDFMmJ.js";
8
- import { C as verifyJsonLd, a as verifyPortableObjectProof, c as doesActorOwnKey, f as attachSignature, h as detachSignature, i as verifyObject, l as getKeyOwner, m as createSignature, n as hasProofLike, o as verifyProof, r as signObject, t as createProof, v as hasSignatureLike, w as verifySignature, x as signJsonLd } from "./proof-BO_esQii.js";
9
- import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "./types-Dtyf8lVj.js";
10
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-tGNbvDCF.js";
6
+ import { F as validateAcceptSignature, M as formatAcceptSignature, N as fulfillAcceptSignature, P as parseAcceptSignature, a as verifyRequestDetailed, c as fetchKey, d as importJwk, i as verifyRequest, l as fetchKeyDetailed, o as exportJwk, r as signRequest, u as generateCryptoKeyPair } from "./http-CgwqtxAy.js";
7
+ import { a as respondWithObject, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as SendActivityError, l as CircuitBreaker, n as handleWebFinger, o as respondWithObjectIfAcceptable, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "./middleware-CeCj5caM.js";
8
+ import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "./types-C_cNlNVK.js";
9
+ import { C as verifyJsonLd, a as verifyPortableObjectProof, c as doesActorOwnKey, f as attachSignature, h as detachSignature, i as verifyObject, l as getKeyOwner, m as createSignature, n as hasProofLike, o as verifyProof, r as signObject, t as createProof, v as hasSignatureLike, w as verifySignature, x as signJsonLd } from "./proof-CUghqhAf.js";
10
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-CykuL0ya.js";
11
11
  import { InProcessMessageQueue, MemoryKvStore, ParallelMessageQueue, Router, RouterError } from "./federation/mod.js";
12
12
  import "./nodeinfo/mod.js";
13
13
  import "./runtime/mod.js";
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
4
4
  import { t as esm_default } from "../esm-BHXXx4Wx.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-CBlRfA-_.mjs";
6
6
  import "../std__assert-CxFT0MNt.mjs";
7
- import { a as parseProtocol, c as parseUsage, i as parseOutboundService, n as parseInboundService, o as parseServices, r as parseNodeInfo, s as parseSoftware, t as getNodeInfo } from "../client-CtxvmazV.mjs";
7
+ import { a as parseProtocol, c as parseUsage, i as parseOutboundService, n as parseInboundService, o as parseServices, r as parseNodeInfo, s as parseSoftware, t as getNodeInfo } from "../client-DpnpgjyX.mjs";
8
8
  import { test } from "@fedify/fixture";
9
9
  //#region src/nodeinfo/client.test.ts
10
10
  test("getNodeInfo()", async (t) => {
@@ -967,5 +967,32 @@ test("parseUsage()", () => {
967
967
  localComments: 456
968
968
  });
969
969
  });
970
+ test("getNodeInfo() bounds both discovery and document responses", async () => {
971
+ esm_default.mockGlobal();
972
+ const base = "https://8.8.8.8";
973
+ const descriptor = { links: [{
974
+ rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
975
+ href: `${base}/nodeinfo`
976
+ }] };
977
+ let oversizedDescriptor = true;
978
+ let oversizedDocument = true;
979
+ const data = { padding: "a".repeat(256) };
980
+ try {
981
+ esm_default.get(`${base}/.well-known/nodeinfo`, () => new Response(JSON.stringify(descriptor), { headers: oversizedDescriptor ? { "Content-Length": String(16777217) } : {} }));
982
+ esm_default.get(`${base}/nodeinfo`, () => new Response(JSON.stringify(data), { headers: oversizedDocument ? { "Content-Length": String(16777217) } : {} }));
983
+ assertEquals(await getNodeInfo(base), void 0);
984
+ assertEquals(esm_default.callHistory.calls(`${base}/nodeinfo`).length, 0);
985
+ oversizedDescriptor = false;
986
+ assertEquals(await getNodeInfo(base), void 0);
987
+ assertEquals(await getNodeInfo(`${base}/nodeinfo`, {
988
+ direct: true,
989
+ parse: "none"
990
+ }), void 0);
991
+ oversizedDocument = false;
992
+ assertEquals(await getNodeInfo(base, { parse: "none" }), data);
993
+ } finally {
994
+ esm_default.hardReset();
995
+ }
996
+ });
970
997
  //#endregion
971
998
  export {};