@fedify/fedify 1.9.5 → 1.9.6

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 (101) hide show
  1. package/dist/{actor-BScoqM7M.js → actor-CEGEmRll.js} +187 -187
  2. package/dist/{actor-EEh71Njb.js → actor-DbpZ6pzg.js} +1 -1
  3. package/dist/{actor-Bpeh1XeR.cjs → actor-DlS-Q8hE.cjs} +187 -187
  4. package/dist/{authdocloader-zA6GeFTV.js → authdocloader-BLqMyboS.js} +3 -3
  5. package/dist/{authdocloader-Cln84bGw.cjs → authdocloader-CT_V4Z7G.cjs} +3 -3
  6. package/dist/{authdocloader-Dzg6OOeX.js → authdocloader-DUQcOTRS.js} +3 -3
  7. package/dist/{builder-vhQAUB_c.js → builder-BO61xeXE.js} +4 -4
  8. package/dist/{client-BjEfcq0Q.js → client-UG5wpNhG.js} +1 -1
  9. package/dist/compat/transformers.test.js +16 -16
  10. package/dist/{docloader-D_YsJgEb.cjs → docloader-BIFI3OS7.cjs} +31 -11
  11. package/dist/{docloader-ygR0HOEb.js → docloader-fJgJeqiX.js} +31 -11
  12. package/dist/{esm-CpGJtXU9.js → esm-C1EfGjSS.js} +1 -1
  13. package/dist/federation/builder.test.js +5 -5
  14. package/dist/federation/collection.test.js +3 -3
  15. package/dist/federation/handler.test.js +17 -17
  16. package/dist/federation/idempotency.test.js +17 -17
  17. package/dist/federation/inbox.test.js +4 -4
  18. package/dist/federation/keycache.test.js +8 -4
  19. package/dist/federation/kv.test.js +3 -3
  20. package/dist/federation/middleware.test.js +18 -18
  21. package/dist/federation/mod.cjs +10 -10
  22. package/dist/federation/mod.js +10 -10
  23. package/dist/federation/mq.test.js +3 -3
  24. package/dist/federation/retry.test.js +3 -3
  25. package/dist/federation/router.test.js +3 -3
  26. package/dist/federation/send.test.js +10 -10
  27. package/dist/{http-Ddo0ZppP.js → http-05HxN-lp.js} +17 -6
  28. package/dist/{http-BvRfZYTf.cjs → http-BgopPF-8.cjs} +18 -7
  29. package/dist/{http-Cstrlwgg.js → http-CR-Eg1Uq.js} +18 -7
  30. package/dist/{inbox-D2vwgPg3.js → inbox-DcJN1cxM.js} +1 -1
  31. package/dist/{key--6LDhz4H.js → key-BCUd8FWp.js} +4 -4
  32. package/dist/key-BUardnTH.cjs +10 -0
  33. package/dist/{key-s7VkHdD2.js → key-CPJcJjp-.js} +2 -2
  34. package/dist/{key-daNTxBaX.cjs → key-DjS1X9TG.cjs} +2 -2
  35. package/dist/{key-iV9rIe_w.js → key-Dr6H_e3K.js} +3 -3
  36. package/dist/{key-i1AKuYo2.js → key-ibMO03_0.js} +2 -2
  37. package/dist/{keycache-D-5tZgkF.js → keycache-CMUfqYqr.js} +11 -2
  38. package/dist/{keys-CfyZsHFW.js → keys-IZ5050fT.js} +1 -1
  39. package/dist/{ld-D08-gVSY.js → ld-DHNA2RSQ.js} +2 -2
  40. package/dist/{lookup-BY7ipa5A.js → lookup-BMAWLsP2.js} +1 -1
  41. package/dist/{lookup-B8OwEXPT.cjs → lookup-C4_dVYz7.cjs} +1 -1
  42. package/dist/{lookup-DKLV3BDT.js → lookup-CKZfuyxA.js} +1 -1
  43. package/dist/middleware-BJ83veqi.js +26 -0
  44. package/dist/{middleware-BPgbdjdi.cjs → middleware-CGbvIGvy.cjs} +20 -11
  45. package/dist/middleware-CJ4W2ir5.cjs +17 -0
  46. package/dist/{middleware-BU1AB564.js → middleware-DrhEvfTo.js} +13 -13
  47. package/dist/{middleware-DqaAsuyL.js → middleware-ODfDRN3q.js} +20 -11
  48. package/dist/middleware-Ve2mHJgo.js +17 -0
  49. package/dist/mod.cjs +10 -10
  50. package/dist/mod.js +10 -10
  51. package/dist/nodeinfo/client.test.js +5 -5
  52. package/dist/nodeinfo/handler.test.js +16 -16
  53. package/dist/nodeinfo/mod.cjs +2 -2
  54. package/dist/nodeinfo/mod.js +2 -2
  55. package/dist/nodeinfo/semver.test.js +3 -3
  56. package/dist/nodeinfo/types.test.js +3 -3
  57. package/dist/{owner-DwNbDv2o.js → owner-DDHsHYQO.js} +2 -2
  58. package/dist/{proof-Cf8y40Qt.cjs → proof-CX7ujFFX.cjs} +3 -3
  59. package/dist/{proof-D6yDDNPJ.js → proof-V1uQaB2y.js} +3 -3
  60. package/dist/{proof-CesqsPsI.js → proof-exgGRW88.js} +2 -2
  61. package/dist/runtime/authdocloader.test.js +9 -9
  62. package/dist/runtime/docloader.test.js +51 -4
  63. package/dist/runtime/key.test.js +5 -5
  64. package/dist/runtime/langstr.test.js +3 -3
  65. package/dist/runtime/link.test.js +3 -3
  66. package/dist/runtime/mod.cjs +6 -6
  67. package/dist/runtime/mod.js +6 -6
  68. package/dist/runtime/multibase/multibase.test.js +3 -3
  69. package/dist/runtime/url.test.js +3 -3
  70. package/dist/{send-CLRuMS0k.js → send-BfMYakUE.js} +2 -2
  71. package/dist/sig/http.test.js +51 -8
  72. package/dist/sig/key.test.js +6 -6
  73. package/dist/sig/ld.test.js +7 -7
  74. package/dist/sig/mod.cjs +6 -6
  75. package/dist/sig/mod.js +6 -6
  76. package/dist/sig/owner.test.js +7 -7
  77. package/dist/sig/proof.test.js +7 -7
  78. package/dist/testing/docloader.test.js +3 -3
  79. package/dist/testing/mod.js +3 -3
  80. package/dist/{testing-D3joI56Q.js → testing-RPOc_gVG.js} +2 -2
  81. package/dist/{type-CfOWb_f6.js → type-COPv6pMi.js} +216 -196
  82. package/dist/{types-CUQq-S-s.cjs → types-CGnM1vft.cjs} +1 -1
  83. package/dist/{types-C8K_AzLR.js → types-Cptev2nt.js} +1 -1
  84. package/dist/vocab/actor.test.js +5 -5
  85. package/dist/vocab/lookup.test.js +4 -4
  86. package/dist/vocab/mod.cjs +4 -4
  87. package/dist/vocab/mod.js +4 -4
  88. package/dist/vocab/type.test.js +3 -3
  89. package/dist/vocab/vocab.test.js +4 -4
  90. package/dist/{vocab-tt4hGhXv.cjs → vocab-BFy1CS5L.cjs} +3 -3
  91. package/dist/{vocab-YzUIufJF.js → vocab-BPFiQ650.js} +3 -3
  92. package/dist/webfinger/handler.test.js +16 -16
  93. package/dist/webfinger/lookup.test.js +4 -4
  94. package/dist/webfinger/mod.cjs +2 -2
  95. package/dist/webfinger/mod.js +2 -2
  96. package/dist/x/cfworkers.test.js +3 -3
  97. package/package.json +1 -1
  98. package/dist/key-sPbIt6SQ.cjs +0 -10
  99. package/dist/middleware-BNuGkCfG.js +0 -17
  100. package/dist/middleware-BVlxjlGK.js +0 -26
  101. package/dist/middleware-DGlXFNnB.cjs +0 -17
@@ -3,12 +3,12 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import "../type-CfOWb_f6.js";
6
+ import "../type-COPv6pMi.js";
7
7
  import { assertEquals } from "../assert_equals-DSbWqCm3.js";
8
8
  import { assert } from "../assert-MZs1qjMx.js";
9
9
  import "../assert_instance_of-DHz7EHNU.js";
10
- import "../lookup-BY7ipa5A.js";
11
- import { test } from "../testing-D3joI56Q.js";
10
+ import "../lookup-BMAWLsP2.js";
11
+ import { test } from "../testing-RPOc_gVG.js";
12
12
  import { assertGreater, assertGreaterOrEqual } from "../std__assert-X-_kMxKM.js";
13
13
  import { assertFalse } from "../assert_rejects-DiIiJbZn.js";
14
14
  import "../assert_is_error-BPGph1Jx.js";
@@ -3,11 +3,11 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import "../type-CfOWb_f6.js";
6
+ import "../type-COPv6pMi.js";
7
7
  import { AssertionError, assertEquals } from "../assert_equals-DSbWqCm3.js";
8
- import "../lookup-BY7ipa5A.js";
8
+ import "../lookup-BMAWLsP2.js";
9
9
  import { createExponentialBackoffPolicy } from "../retry-D4GJ670a.js";
10
- import { test } from "../testing-D3joI56Q.js";
10
+ import { test } from "../testing-RPOc_gVG.js";
11
11
  import { assertNotEquals } from "../assert_not_equals-f3m3epl3.js";
12
12
 
13
13
  //#region src/federation/retry.test.ts
@@ -3,12 +3,12 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import "../type-CfOWb_f6.js";
6
+ import "../type-COPv6pMi.js";
7
7
  import { assertEquals } from "../assert_equals-DSbWqCm3.js";
8
8
  import { assert } from "../assert-MZs1qjMx.js";
9
9
  import "../assert_instance_of-DHz7EHNU.js";
10
- import { Router, RouterError } from "../lookup-BY7ipa5A.js";
11
- import { test } from "../testing-D3joI56Q.js";
10
+ import { Router, RouterError } from "../lookup-BMAWLsP2.js";
11
+ import { test } from "../testing-RPOc_gVG.js";
12
12
  import "../std__assert-X-_kMxKM.js";
13
13
  import { assertFalse } from "../assert_rejects-DiIiJbZn.js";
14
14
  import "../assert_is_error-BPGph1Jx.js";
@@ -3,24 +3,24 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { Activity, Application, Endpoints, Group, Person, Service } from "../type-CfOWb_f6.js";
6
+ import { Activity, Application, Endpoints, Group, Person, Service } from "../type-COPv6pMi.js";
7
7
  import { assertEquals } from "../assert_equals-DSbWqCm3.js";
8
8
  import { assert } from "../assert-MZs1qjMx.js";
9
9
  import "../assert_instance_of-DHz7EHNU.js";
10
- import "../lookup-BY7ipa5A.js";
11
- import "../actor-EEh71Njb.js";
12
- import "../key-s7VkHdD2.js";
13
- import { verifyRequest } from "../http-Ddo0ZppP.js";
14
- import { doesActorOwnKey } from "../owner-DwNbDv2o.js";
15
- import { extractInboxes, sendActivity } from "../send-CLRuMS0k.js";
16
- import { mockDocumentLoader, test } from "../testing-D3joI56Q.js";
10
+ import "../lookup-BMAWLsP2.js";
11
+ import "../actor-DbpZ6pzg.js";
12
+ import "../key-CPJcJjp-.js";
13
+ import { verifyRequest } from "../http-05HxN-lp.js";
14
+ import { doesActorOwnKey } from "../owner-DDHsHYQO.js";
15
+ import { extractInboxes, sendActivity } from "../send-BfMYakUE.js";
16
+ import { mockDocumentLoader, test } from "../testing-RPOc_gVG.js";
17
17
  import "../std__assert-X-_kMxKM.js";
18
18
  import { assertFalse, assertRejects } from "../assert_rejects-DiIiJbZn.js";
19
19
  import "../assert_is_error-BPGph1Jx.js";
20
20
  import { assertNotEquals } from "../assert_not_equals-f3m3epl3.js";
21
21
  import "../assert_throws-BOO88avQ.js";
22
- import { ed25519Multikey, ed25519PrivateKey, rsaPrivateKey2, rsaPublicKey2 } from "../keys-CfyZsHFW.js";
23
- import { esm_default } from "../esm-CpGJtXU9.js";
22
+ import { ed25519Multikey, ed25519PrivateKey, rsaPrivateKey2, rsaPublicKey2 } from "../keys-IZ5050fT.js";
23
+ import { esm_default } from "../esm-C1EfGjSS.js";
24
24
 
25
25
  //#region src/federation/send.test.ts
26
26
  test("extractInboxes()", () => {
@@ -3,8 +3,8 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, deno_default } from "./type-CfOWb_f6.js";
7
- import { fetchKey, validateCryptoKey } from "./key-s7VkHdD2.js";
6
+ import { CryptographicKey, FetchError, deno_default } from "./type-COPv6pMi.js";
7
+ import { fetchKey, validateCryptoKey } from "./key-CPJcJjp-.js";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
10
10
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
@@ -13,6 +13,7 @@ import { encodeHex } from "byte-encodings/hex";
13
13
  import { Item, decodeDict, encodeItem } from "structured-field-values";
14
14
 
15
15
  //#region src/sig/http.ts
16
+ const DEFAULT_MAX_REDIRECTION = 20;
16
17
  /**
17
18
  * Signs a request using the given private key.
18
19
  * @param request The request to sign.
@@ -724,7 +725,11 @@ function createRedirectRequest(request, location, body) {
724
725
  * @since 1.6.0
725
726
  */
726
727
  async function doubleKnock(request, identity, options = {}) {
728
+ return await doubleKnockInternal(request, identity, options);
729
+ }
730
+ async function doubleKnockInternal(request, identity, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
727
731
  const { specDeterminer, log, tracerProvider, signal } = options;
732
+ visited.add(request.url);
728
733
  const origin = new URL(request.url).origin;
729
734
  const firstTrySpec = specDeterminer == null ? "rfc9421" : await specDeterminer.determineSpec(origin);
730
735
  const body = options.body !== void 0 ? options.body : request.method !== "GET" && request.method !== "HEAD" ? await request.clone().arrayBuffer() : null;
@@ -739,11 +744,14 @@ async function doubleKnock(request, identity, options = {}) {
739
744
  signal
740
745
  });
741
746
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
747
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
742
748
  const location = response.headers.get("Location");
743
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
749
+ const redirectRequest = createRedirectRequest(request, location, body);
750
+ if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
751
+ return doubleKnockInternal(redirectRequest, identity, {
744
752
  ...options,
745
753
  body
746
- });
754
+ }, redirected + 1, visited);
747
755
  } else if (response.status === 400 || response.status === 401 || response.status > 401) {
748
756
  const spec = firstTrySpec === "draft-cavage-http-signatures-12" ? "rfc9421" : "draft-cavage-http-signatures-12";
749
757
  getLogger([
@@ -767,11 +775,14 @@ async function doubleKnock(request, identity, options = {}) {
767
775
  signal
768
776
  });
769
777
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
778
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
770
779
  const location = response.headers.get("Location");
771
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
780
+ const redirectRequest = createRedirectRequest(request, location, body);
781
+ if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
782
+ return doubleKnockInternal(redirectRequest, identity, {
772
783
  ...options,
773
784
  body
774
- });
785
+ }, redirected + 1, visited);
775
786
  } else if (response.status !== 400 && response.status !== 401) await specDeterminer?.rememberSpec(origin, spec);
776
787
  } else await specDeterminer?.rememberSpec(origin, firstTrySpec);
777
788
  return response;
@@ -3,9 +3,9 @@
3
3
  const { URLPattern } = require("urlpattern-polyfill");
4
4
 
5
5
  const require_chunk = require('./chunk-DqRYRqnO.cjs');
6
- const require_docloader = require('./docloader-D_YsJgEb.cjs');
7
- const require_actor = require('./actor-Bpeh1XeR.cjs');
8
- const require_key = require('./key-daNTxBaX.cjs');
6
+ const require_docloader = require('./docloader-BIFI3OS7.cjs');
7
+ const require_actor = require('./actor-DlS-Q8hE.cjs');
8
+ const require_key = require('./key-DjS1X9TG.cjs');
9
9
  const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
10
10
  const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
11
11
  const byte_encodings_base64 = require_chunk.__toESM(require("byte-encodings/base64"));
@@ -14,6 +14,7 @@ const __opentelemetry_semantic_conventions = require_chunk.__toESM(require("@ope
14
14
  const structured_field_values = require_chunk.__toESM(require("structured-field-values"));
15
15
 
16
16
  //#region src/sig/http.ts
17
+ const DEFAULT_MAX_REDIRECTION = 20;
17
18
  /**
18
19
  * Signs a request using the given private key.
19
20
  * @param request The request to sign.
@@ -725,7 +726,11 @@ function createRedirectRequest(request, location, body) {
725
726
  * @since 1.6.0
726
727
  */
727
728
  async function doubleKnock(request, identity, options = {}) {
729
+ return await doubleKnockInternal(request, identity, options);
730
+ }
731
+ async function doubleKnockInternal(request, identity, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
728
732
  const { specDeterminer, log, tracerProvider, signal } = options;
733
+ visited.add(request.url);
729
734
  const origin = new URL(request.url).origin;
730
735
  const firstTrySpec = specDeterminer == null ? "rfc9421" : await specDeterminer.determineSpec(origin);
731
736
  const body = options.body !== void 0 ? options.body : request.method !== "GET" && request.method !== "HEAD" ? await request.clone().arrayBuffer() : null;
@@ -740,11 +745,14 @@ async function doubleKnock(request, identity, options = {}) {
740
745
  signal
741
746
  });
742
747
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
748
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new require_docloader.FetchError(request.url, `Too many redirections (${redirected + 1})`);
743
749
  const location = response.headers.get("Location");
744
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
750
+ const redirectRequest = createRedirectRequest(request, location, body);
751
+ if (visited.has(redirectRequest.url)) throw new require_docloader.FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
752
+ return doubleKnockInternal(redirectRequest, identity, {
745
753
  ...options,
746
754
  body
747
- });
755
+ }, redirected + 1, visited);
748
756
  } else if (response.status === 400 || response.status === 401 || response.status > 401) {
749
757
  const spec = firstTrySpec === "draft-cavage-http-signatures-12" ? "rfc9421" : "draft-cavage-http-signatures-12";
750
758
  (0, __logtape_logtape.getLogger)([
@@ -768,11 +776,14 @@ async function doubleKnock(request, identity, options = {}) {
768
776
  signal
769
777
  });
770
778
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
779
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new require_docloader.FetchError(request.url, `Too many redirections (${redirected + 1})`);
771
780
  const location = response.headers.get("Location");
772
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
781
+ const redirectRequest = createRedirectRequest(request, location, body);
782
+ if (visited.has(redirectRequest.url)) throw new require_docloader.FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
783
+ return doubleKnockInternal(redirectRequest, identity, {
773
784
  ...options,
774
785
  body
775
- });
786
+ }, redirected + 1, visited);
776
787
  } else if (response.status !== 400 && response.status !== 401) await specDeterminer?.rememberSpec(origin, spec);
777
788
  } else await specDeterminer?.rememberSpec(origin, firstTrySpec);
778
789
  return response;
@@ -2,9 +2,9 @@
2
2
  import { Temporal } from "@js-temporal/polyfill";
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
 
5
- import { deno_default } from "./docloader-ygR0HOEb.js";
6
- import { CryptographicKey } from "./actor-BScoqM7M.js";
7
- import { fetchKey, validateCryptoKey } from "./key-i1AKuYo2.js";
5
+ import { FetchError, deno_default } from "./docloader-fJgJeqiX.js";
6
+ import { CryptographicKey } from "./actor-CEGEmRll.js";
7
+ import { fetchKey, validateCryptoKey } from "./key-ibMO03_0.js";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
10
10
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
@@ -13,6 +13,7 @@ import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } fro
13
13
  import { Item, decodeDict, encodeItem } from "structured-field-values";
14
14
 
15
15
  //#region src/sig/http.ts
16
+ const DEFAULT_MAX_REDIRECTION = 20;
16
17
  /**
17
18
  * Signs a request using the given private key.
18
19
  * @param request The request to sign.
@@ -724,7 +725,11 @@ function createRedirectRequest(request, location, body) {
724
725
  * @since 1.6.0
725
726
  */
726
727
  async function doubleKnock(request, identity, options = {}) {
728
+ return await doubleKnockInternal(request, identity, options);
729
+ }
730
+ async function doubleKnockInternal(request, identity, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
727
731
  const { specDeterminer, log, tracerProvider, signal } = options;
732
+ visited.add(request.url);
728
733
  const origin = new URL(request.url).origin;
729
734
  const firstTrySpec = specDeterminer == null ? "rfc9421" : await specDeterminer.determineSpec(origin);
730
735
  const body = options.body !== void 0 ? options.body : request.method !== "GET" && request.method !== "HEAD" ? await request.clone().arrayBuffer() : null;
@@ -739,11 +744,14 @@ async function doubleKnock(request, identity, options = {}) {
739
744
  signal
740
745
  });
741
746
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
747
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
742
748
  const location = response.headers.get("Location");
743
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
749
+ const redirectRequest = createRedirectRequest(request, location, body);
750
+ if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
751
+ return doubleKnockInternal(redirectRequest, identity, {
744
752
  ...options,
745
753
  body
746
- });
754
+ }, redirected + 1, visited);
747
755
  } else if (response.status === 400 || response.status === 401 || response.status > 401) {
748
756
  const spec = firstTrySpec === "draft-cavage-http-signatures-12" ? "rfc9421" : "draft-cavage-http-signatures-12";
749
757
  getLogger([
@@ -767,11 +775,14 @@ async function doubleKnock(request, identity, options = {}) {
767
775
  signal
768
776
  });
769
777
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
778
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
770
779
  const location = response.headers.get("Location");
771
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
780
+ const redirectRequest = createRedirectRequest(request, location, body);
781
+ if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
782
+ return doubleKnockInternal(redirectRequest, identity, {
772
783
  ...options,
773
784
  body
774
- });
785
+ }, redirected + 1, visited);
775
786
  } else if (response.status !== 400 && response.status !== 401) await specDeterminer?.rememberSpec(origin, spec);
776
787
  } else await specDeterminer?.rememberSpec(origin, firstTrySpec);
777
788
  return response;
@@ -3,7 +3,7 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { Activity, deno_default, getTypeId } from "./type-CfOWb_f6.js";
6
+ import { Activity, deno_default, getTypeId } from "./type-COPv6pMi.js";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
9
9
 
@@ -2,9 +2,9 @@
2
2
  import { Temporal } from "@js-temporal/polyfill";
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
 
5
- import "./docloader-ygR0HOEb.js";
6
- import "./actor-BScoqM7M.js";
7
- import "./lookup-DKLV3BDT.js";
8
- import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-i1AKuYo2.js";
5
+ import "./docloader-fJgJeqiX.js";
6
+ import "./actor-CEGEmRll.js";
7
+ import "./lookup-CKZfuyxA.js";
8
+ import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-ibMO03_0.js";
9
9
 
10
10
  export { validateCryptoKey };
@@ -0,0 +1,10 @@
1
+
2
+ const { Temporal } = require("@js-temporal/polyfill");
3
+ const { URLPattern } = require("urlpattern-polyfill");
4
+
5
+ require('./docloader-BIFI3OS7.cjs');
6
+ require('./actor-DlS-Q8hE.cjs');
7
+ require('./lookup-C4_dVYz7.cjs');
8
+ const require_key = require('./key-DjS1X9TG.cjs');
9
+
10
+ exports.validateCryptoKey = require_key.validateCryptoKey;
@@ -3,8 +3,8 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, Object as Object$1, deno_default, getDocumentLoader } from "./type-CfOWb_f6.js";
7
- import { isActor } from "./actor-EEh71Njb.js";
6
+ import { CryptographicKey, Object as Object$1, deno_default, getDocumentLoader } from "./type-COPv6pMi.js";
7
+ import { isActor } from "./actor-DbpZ6pzg.js";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
10
10
 
@@ -3,8 +3,8 @@
3
3
  const { URLPattern } = require("urlpattern-polyfill");
4
4
 
5
5
  const require_chunk = require('./chunk-DqRYRqnO.cjs');
6
- const require_docloader = require('./docloader-D_YsJgEb.cjs');
7
- const require_actor = require('./actor-Bpeh1XeR.cjs');
6
+ const require_docloader = require('./docloader-BIFI3OS7.cjs');
7
+ const require_actor = require('./actor-DlS-Q8hE.cjs');
8
8
  const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
9
9
  const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
10
10
 
@@ -3,8 +3,8 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import "./type-CfOWb_f6.js";
7
- import "./actor-EEh71Njb.js";
8
- import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-s7VkHdD2.js";
6
+ import "./type-COPv6pMi.js";
7
+ import "./actor-DbpZ6pzg.js";
8
+ import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-CPJcJjp-.js";
9
9
 
10
10
  export { validateCryptoKey };
@@ -2,8 +2,8 @@
2
2
  import { Temporal } from "@js-temporal/polyfill";
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
 
5
- import { deno_default, getDocumentLoader } from "./docloader-ygR0HOEb.js";
6
- import { CryptographicKey, Object as Object$1, isActor } from "./actor-BScoqM7M.js";
5
+ import { deno_default, getDocumentLoader } from "./docloader-fJgJeqiX.js";
6
+ import { CryptographicKey, Object as Object$1, isActor } from "./actor-CEGEmRll.js";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
9
9
 
@@ -3,9 +3,14 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, Multikey } from "./type-CfOWb_f6.js";
6
+ import { CryptographicKey, Multikey } from "./type-COPv6pMi.js";
7
7
 
8
8
  //#region src/federation/keycache.ts
9
+ const NULL_KEY_CACHE_VALUE = { _fedify: "key-unavailable" };
10
+ const NULL_KEY_CACHE_TTL = Temporal.Duration.from({ minutes: 5 });
11
+ function isNullKeyCacheValue(value) {
12
+ return typeof value === "object" && value != null && "_fedify" in value && value._fedify === NULL_KEY_CACHE_VALUE._fedify;
13
+ }
9
14
  var KvKeyCache = class {
10
15
  kv;
11
16
  prefix;
@@ -21,6 +26,10 @@ var KvKeyCache = class {
21
26
  if (this.nullKeys.has(keyId.href)) return null;
22
27
  const serialized = await this.kv.get([...this.prefix, keyId.href]);
23
28
  if (serialized == null) return void 0;
29
+ if (isNullKeyCacheValue(serialized)) {
30
+ this.nullKeys.add(keyId.href);
31
+ return null;
32
+ }
24
33
  try {
25
34
  return await CryptographicKey.fromJsonLd(serialized, this.options);
26
35
  } catch {
@@ -35,7 +44,7 @@ var KvKeyCache = class {
35
44
  async set(keyId, key) {
36
45
  if (key == null) {
37
46
  this.nullKeys.add(keyId.href);
38
- await this.kv.delete([...this.prefix, keyId.href]);
47
+ await this.kv.set([...this.prefix, keyId.href], NULL_KEY_CACHE_VALUE, { ttl: NULL_KEY_CACHE_TTL });
39
48
  return;
40
49
  }
41
50
  this.nullKeys.delete(keyId.href);
@@ -3,7 +3,7 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, Multikey, importSpki } from "./type-CfOWb_f6.js";
6
+ import { CryptographicKey, Multikey, importSpki } from "./type-COPv6pMi.js";
7
7
 
8
8
  //#region src/testing/keys.ts
9
9
  const rsaPublicKey1 = new CryptographicKey({
@@ -3,8 +3,8 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { Activity, CryptographicKey, Object as Object$1, deno_default, getDocumentLoader, getTypeId } from "./type-CfOWb_f6.js";
7
- import { fetchKey, validateCryptoKey } from "./key-s7VkHdD2.js";
6
+ import { Activity, CryptographicKey, Object as Object$1, deno_default, getDocumentLoader, getTypeId } from "./type-COPv6pMi.js";
7
+ import { fetchKey, validateCryptoKey } from "./key-CPJcJjp-.js";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
10
10
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
@@ -3,7 +3,7 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { Object as Object$1, deno_default, getDocumentLoader, getTypeId, lookupWebFinger } from "./type-CfOWb_f6.js";
6
+ import { Object as Object$1, deno_default, getDocumentLoader, getTypeId, lookupWebFinger } from "./type-COPv6pMi.js";
7
7
  import { cloneDeep, delay } from "es-toolkit";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -3,7 +3,7 @@
3
3
  const { URLPattern } = require("urlpattern-polyfill");
4
4
 
5
5
  const require_chunk = require('./chunk-DqRYRqnO.cjs');
6
- const require_docloader = require('./docloader-D_YsJgEb.cjs');
6
+ const require_docloader = require('./docloader-BIFI3OS7.cjs');
7
7
  const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
8
8
  const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
9
9
 
@@ -2,7 +2,7 @@
2
2
  import { Temporal } from "@js-temporal/polyfill";
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
 
5
- import { UrlError, deno_default, getUserAgent, validatePublicUrl } from "./docloader-ygR0HOEb.js";
5
+ import { UrlError, deno_default, getUserAgent, validatePublicUrl } from "./docloader-fJgJeqiX.js";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
8
8
 
@@ -0,0 +1,26 @@
1
+
2
+ import { Temporal } from "@js-temporal/polyfill";
3
+ import { URLPattern } from "urlpattern-polyfill";
4
+ globalThis.addEventListener = () => {};
5
+
6
+ import "./type-COPv6pMi.js";
7
+ import { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, createFederation } from "./middleware-DrhEvfTo.js";
8
+ import "./semver-dArNLkR9.js";
9
+ import "./client-UG5wpNhG.js";
10
+ import "./lookup-BMAWLsP2.js";
11
+ import "./types-BIgY6c-l.js";
12
+ import "./actor-DbpZ6pzg.js";
13
+ import "./key-CPJcJjp-.js";
14
+ import "./http-05HxN-lp.js";
15
+ import "./authdocloader-BLqMyboS.js";
16
+ import "./ld-DHNA2RSQ.js";
17
+ import "./owner-DDHsHYQO.js";
18
+ import "./proof-exgGRW88.js";
19
+ import "./inbox-DcJN1cxM.js";
20
+ import "./builder-BO61xeXE.js";
21
+ import "./collection-CSzG2j1P.js";
22
+ import "./keycache-CMUfqYqr.js";
23
+ import "./retry-D4GJ670a.js";
24
+ import "./send-BfMYakUE.js";
25
+
26
+ export { FederationImpl };
@@ -4,15 +4,15 @@
4
4
 
5
5
  const require_chunk = require('./chunk-DqRYRqnO.cjs');
6
6
  const require_transformers = require('./transformers-CoBS-oFG.cjs');
7
- const require_docloader = require('./docloader-D_YsJgEb.cjs');
8
- const require_actor = require('./actor-Bpeh1XeR.cjs');
9
- const require_lookup = require('./lookup-B8OwEXPT.cjs');
10
- const require_key = require('./key-daNTxBaX.cjs');
11
- const require_http = require('./http-BvRfZYTf.cjs');
12
- const require_proof = require('./proof-Cf8y40Qt.cjs');
13
- const require_types = require('./types-CUQq-S-s.cjs');
14
- const require_authdocloader = require('./authdocloader-Cln84bGw.cjs');
15
- const require_vocab = require('./vocab-tt4hGhXv.cjs');
7
+ const require_docloader = require('./docloader-BIFI3OS7.cjs');
8
+ const require_actor = require('./actor-DlS-Q8hE.cjs');
9
+ const require_lookup = require('./lookup-C4_dVYz7.cjs');
10
+ const require_key = require('./key-DjS1X9TG.cjs');
11
+ const require_http = require('./http-BgopPF-8.cjs');
12
+ const require_proof = require('./proof-CX7ujFFX.cjs');
13
+ const require_types = require('./types-CGnM1vft.cjs');
14
+ const require_authdocloader = require('./authdocloader-CT_V4Z7G.cjs');
15
+ const require_vocab = require('./vocab-BFy1CS5L.cjs');
16
16
  const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
17
17
  const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
18
18
  const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
@@ -345,7 +345,7 @@ var FederationBuilderImpl = class {
345
345
  this.collectionTypeIds = {};
346
346
  }
347
347
  async build(options) {
348
- const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-DGlXFNnB.cjs"));
348
+ const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-CJ4W2ir5.cjs"));
349
349
  const f = new FederationImpl$1(options);
350
350
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
351
351
  f.router = this.router.clone();
@@ -913,6 +913,11 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
913
913
 
914
914
  //#endregion
915
915
  //#region src/federation/keycache.ts
916
+ const NULL_KEY_CACHE_VALUE = { _fedify: "key-unavailable" };
917
+ const NULL_KEY_CACHE_TTL = Temporal.Duration.from({ minutes: 5 });
918
+ function isNullKeyCacheValue(value) {
919
+ return typeof value === "object" && value != null && "_fedify" in value && value._fedify === NULL_KEY_CACHE_VALUE._fedify;
920
+ }
916
921
  var KvKeyCache = class {
917
922
  kv;
918
923
  prefix;
@@ -928,6 +933,10 @@ var KvKeyCache = class {
928
933
  if (this.nullKeys.has(keyId.href)) return null;
929
934
  const serialized = await this.kv.get([...this.prefix, keyId.href]);
930
935
  if (serialized == null) return void 0;
936
+ if (isNullKeyCacheValue(serialized)) {
937
+ this.nullKeys.add(keyId.href);
938
+ return null;
939
+ }
931
940
  try {
932
941
  return await require_actor.CryptographicKey.fromJsonLd(serialized, this.options);
933
942
  } catch {
@@ -942,7 +951,7 @@ var KvKeyCache = class {
942
951
  async set(keyId, key) {
943
952
  if (key == null) {
944
953
  this.nullKeys.add(keyId.href);
945
- await this.kv.delete([...this.prefix, keyId.href]);
954
+ await this.kv.set([...this.prefix, keyId.href], NULL_KEY_CACHE_VALUE, { ttl: NULL_KEY_CACHE_TTL });
946
955
  return;
947
956
  }
948
957
  this.nullKeys.delete(keyId.href);
@@ -0,0 +1,17 @@
1
+
2
+ const { Temporal } = require("@js-temporal/polyfill");
3
+ const { URLPattern } = require("urlpattern-polyfill");
4
+
5
+ require('./transformers-CoBS-oFG.cjs');
6
+ require('./docloader-BIFI3OS7.cjs');
7
+ require('./actor-DlS-Q8hE.cjs');
8
+ const require_middleware = require('./middleware-CGbvIGvy.cjs');
9
+ require('./lookup-C4_dVYz7.cjs');
10
+ require('./key-DjS1X9TG.cjs');
11
+ require('./http-BgopPF-8.cjs');
12
+ require('./proof-CX7ujFFX.cjs');
13
+ require('./types-CGnM1vft.cjs');
14
+ require('./authdocloader-CT_V4Z7G.cjs');
15
+ require('./vocab-BFy1CS5L.cjs');
16
+
17
+ exports.FederationImpl = require_middleware.FederationImpl;
@@ -3,22 +3,22 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, deno_default, getDocumentLoader, getTypeId, kvCache, lookupWebFinger } from "./type-CfOWb_f6.js";
7
- import { getNodeInfo } from "./client-BjEfcq0Q.js";
8
- import { RouterError, lookupObject, traverseCollection } from "./lookup-BY7ipa5A.js";
6
+ import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, deno_default, getDocumentLoader, getTypeId, kvCache, lookupWebFinger } from "./type-COPv6pMi.js";
7
+ import { getNodeInfo } from "./client-UG5wpNhG.js";
8
+ import { RouterError, lookupObject, traverseCollection } from "./lookup-BMAWLsP2.js";
9
9
  import { nodeInfoToJson } from "./types-BIgY6c-l.js";
10
- import { exportJwk, importJwk, validateCryptoKey } from "./key-s7VkHdD2.js";
11
- import { verifyRequest } from "./http-Ddo0ZppP.js";
12
- import { getAuthenticatedDocumentLoader } from "./authdocloader-zA6GeFTV.js";
13
- import { detachSignature, hasSignature, signJsonLd, verifyJsonLd } from "./ld-D08-gVSY.js";
14
- import { doesActorOwnKey, getKeyOwner } from "./owner-DwNbDv2o.js";
15
- import { signObject, verifyObject } from "./proof-CesqsPsI.js";
16
- import { routeActivity } from "./inbox-D2vwgPg3.js";
17
- import { FederationBuilderImpl } from "./builder-vhQAUB_c.js";
10
+ import { exportJwk, importJwk, validateCryptoKey } from "./key-CPJcJjp-.js";
11
+ import { verifyRequest } from "./http-05HxN-lp.js";
12
+ import { getAuthenticatedDocumentLoader } from "./authdocloader-BLqMyboS.js";
13
+ import { detachSignature, hasSignature, signJsonLd, verifyJsonLd } from "./ld-DHNA2RSQ.js";
14
+ import { doesActorOwnKey, getKeyOwner } from "./owner-DDHsHYQO.js";
15
+ import { signObject, verifyObject } from "./proof-exgGRW88.js";
16
+ import { routeActivity } from "./inbox-DcJN1cxM.js";
17
+ import { FederationBuilderImpl } from "./builder-BO61xeXE.js";
18
18
  import { buildCollectionSynchronizationHeader } from "./collection-CSzG2j1P.js";
19
- import { KvKeyCache } from "./keycache-D-5tZgkF.js";
19
+ import { KvKeyCache } from "./keycache-CMUfqYqr.js";
20
20
  import { createExponentialBackoffPolicy } from "./retry-D4GJ670a.js";
21
- import { extractInboxes, sendActivity } from "./send-CLRuMS0k.js";
21
+ import { extractInboxes, sendActivity } from "./send-BfMYakUE.js";
22
22
  import { getLogger, withContext } from "@logtape/logtape";
23
23
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
24
24
  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";