@fedify/fedify 2.0.0-pr.435.1673 → 2.0.0-pr.445.1694

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 (138) hide show
  1. package/dist/{actor-CNUje03O.cjs → actor-CwZ2m5rG.cjs} +7263 -2440
  2. package/dist/{actor-DMgu-ZjT.d.cts → actor-D6K058Tb.d.cts} +1 -1
  3. package/dist/{actor-BxAu0qet.js → actor-D8gCwLzv.js} +1 -1
  4. package/dist/{actor-m_ko-86v.js → actor-DoMcqXsW.js} +7263 -2440
  5. package/dist/{actor-C22bXuuC.d.ts → actor-T6RyhRgk.d.ts} +1 -1
  6. package/dist/{authdocloader-nRFL9luh.js → authdocloader-Cv_qEn1G.js} +3 -3
  7. package/dist/{authdocloader-Chl2nuOI.js → authdocloader-DYTNpaMA.js} +3 -3
  8. package/dist/{authdocloader-D_3mtAjX.cjs → authdocloader-bsmVF6eO.cjs} +3 -3
  9. package/dist/{builder-C8Of4dPy.js → builder-1_skw-d2.js} +10 -4
  10. package/dist/{client-yGBH5stP.js → client-D5CBsPrc.js} +1 -1
  11. package/dist/compat/mod.d.cts +7 -7
  12. package/dist/compat/mod.d.ts +7 -7
  13. package/dist/compat/transformers.test.js +16 -16
  14. package/dist/{context-CQsAT7xk.d.ts → context-DBKpNBnc.d.ts} +67 -12
  15. package/dist/{context-tVOQ76fi.d.cts → context-DiqjMRef.d.cts} +67 -12
  16. package/dist/{docloader-SZjTrl6Z.cjs → docloader-CYnQRIXv.cjs} +1 -1
  17. package/dist/{docloader-_WdHTWQR.js → docloader-Czl3xV10.js} +1 -1
  18. package/dist/{esm-e_G_xo95.js → esm-Dl5T1RNE.js} +1 -1
  19. package/dist/federation/builder.test.js +5 -5
  20. package/dist/federation/collection.test.js +3 -3
  21. package/dist/federation/handler.test.js +17 -17
  22. package/dist/federation/idempotency.test.d.ts +3 -0
  23. package/dist/federation/idempotency.test.js +202 -0
  24. package/dist/federation/inbox.test.js +4 -4
  25. package/dist/federation/keycache.test.js +4 -4
  26. package/dist/federation/kv.test.js +3 -3
  27. package/dist/federation/middleware.test.js +24 -47
  28. package/dist/federation/mod.cjs +10 -10
  29. package/dist/federation/mod.d.cts +7 -7
  30. package/dist/federation/mod.d.ts +7 -7
  31. package/dist/federation/mod.js +10 -10
  32. package/dist/federation/mq.test.js +3 -3
  33. package/dist/federation/negotiation.test.js +3 -3
  34. package/dist/federation/retry.test.js +3 -3
  35. package/dist/federation/router.test.js +3 -3
  36. package/dist/federation/send.test.js +10 -10
  37. package/dist/fixtures/media.example.com/avatars/test-avatar.jpg.json +6 -0
  38. package/dist/{http-DREvFalF.cjs → http-CAusBl_3.cjs} +3 -3
  39. package/dist/{http-BpoEurUR.js → http-C_Qc2neP.js} +3 -3
  40. package/dist/{http-BEo67UOx.js → http-CuS-d4U0.js} +2 -2
  41. package/dist/{http-BS6766zs.d.cts → http-D-e6AFwR.d.cts} +1 -1
  42. package/dist/{http-DqSNLFNY.d.ts → http-D6Uj2x2y.d.ts} +1 -1
  43. package/dist/{inbox-D-B5xFtJ.js → inbox-IETv_Qez.js} +24 -7
  44. package/dist/{key-Cf8KTg-A.js → key-BNJQQm3h.js} +2 -2
  45. package/dist/{key-DJpcumqB.js → key-C_ruQbbl.js} +4 -4
  46. package/dist/key-DIMJMxf4.cjs +10 -0
  47. package/dist/{key-Cps8Sv3N.js → key-DnqhSgAv.js} +2 -2
  48. package/dist/{key-DqrTz8Xq.js → key-DpFjiItf.js} +3 -3
  49. package/dist/{key-JqiQvcq1.cjs → key-DuXv64tg.cjs} +2 -2
  50. package/dist/{keycache-D_Q1fPV0.js → keycache-CSBkusP8.js} +1 -1
  51. package/dist/{keys-F0jh2GNR.js → keys-D3_MDK7n.js} +1 -1
  52. package/dist/{ld-CXygHn_m.js → ld-Isot0tiW.js} +2 -2
  53. package/dist/{lookup-DuqY2_In.js → lookup-CbtuFbtg.js} +21 -12
  54. package/dist/{lookup-C-Y0Ep1a.cjs → lookup-D6dro5Au.cjs} +1 -1
  55. package/dist/{lookup-C6WSLjPE.js → lookup-Dhm78GlK.js} +1 -1
  56. package/dist/middleware-BpR6186a.js +26 -0
  57. package/dist/{middleware-2qNNXYEE.js → middleware-BuHr2fzh.js} +52 -29
  58. package/dist/middleware-DDMxdtWM.cjs +17 -0
  59. package/dist/{middleware-CMiUxZ6O.js → middleware-DQYscW90.js} +26 -26
  60. package/dist/{middleware-BsFAFlnZ.cjs → middleware-Dgmdgrvb.cjs} +52 -29
  61. package/dist/middleware-T-knSMwl.js +17 -0
  62. package/dist/{mod-Drmz72EK.d.ts → mod-BhUKmBJD.d.ts} +2 -2
  63. package/dist/{mod-DBQAI4v9.d.cts → mod-Bpb5QLaZ.d.cts} +2 -2
  64. package/dist/{mod-TFoH2Ql8.d.ts → mod-CerN_Sza.d.ts} +1 -1
  65. package/dist/{mod-Dc_-mf8s.d.cts → mod-Cj1tHXBR.d.cts} +1 -1
  66. package/dist/{mod-evzlRVZq.d.cts → mod-CxkWO3Mg.d.cts} +19 -1
  67. package/dist/{mod-B26zRlH1.d.ts → mod-D_y2y32N.d.ts} +2 -2
  68. package/dist/{mod-BClfg3ej.d.cts → mod-Djzcw2ry.d.cts} +2 -2
  69. package/dist/{mod-Cxt4Kpf6.d.ts → mod-DlU8ISoa.d.ts} +19 -1
  70. package/dist/mod.cjs +10 -10
  71. package/dist/mod.d.cts +10 -10
  72. package/dist/mod.d.ts +10 -10
  73. package/dist/mod.js +10 -10
  74. package/dist/nodeinfo/client.test.js +5 -5
  75. package/dist/nodeinfo/handler.test.js +16 -16
  76. package/dist/nodeinfo/mod.cjs +2 -2
  77. package/dist/nodeinfo/mod.js +2 -2
  78. package/dist/nodeinfo/types.test.js +3 -3
  79. package/dist/{owner-B-7Ptt_m.d.cts → owner-BN_tO3cY.d.cts} +2 -2
  80. package/dist/{owner-D2fTlp_x.js → owner-ChSL4aJ7.js} +2 -2
  81. package/dist/{owner-CQPnQVtf.d.ts → owner-hd9lvQcP.d.ts} +2 -2
  82. package/dist/{proof-CHM9su4L.js → proof-BiSCuwyA.js} +3 -3
  83. package/dist/{proof-C4Y4gJcm.cjs → proof-ONNmhInb.cjs} +3 -3
  84. package/dist/{proof-kEUjWRNJ.js → proof-x3IBewan.js} +2 -2
  85. package/dist/runtime/authdocloader.test.js +9 -9
  86. package/dist/runtime/docloader.test.js +4 -4
  87. package/dist/runtime/key.test.js +5 -5
  88. package/dist/runtime/langstr.test.js +3 -3
  89. package/dist/runtime/link.test.js +3 -3
  90. package/dist/runtime/mod.cjs +6 -6
  91. package/dist/runtime/mod.d.cts +3 -3
  92. package/dist/runtime/mod.d.ts +3 -3
  93. package/dist/runtime/mod.js +6 -6
  94. package/dist/runtime/multibase/multibase.test.js +3 -3
  95. package/dist/runtime/url.test.js +3 -3
  96. package/dist/{send-Utq2Jm0I.js → send-D5fjmUEj.js} +2 -2
  97. package/dist/sig/http.test.js +8 -8
  98. package/dist/sig/key.test.js +6 -6
  99. package/dist/sig/ld.test.js +7 -7
  100. package/dist/sig/mod.cjs +6 -6
  101. package/dist/sig/mod.d.cts +5 -5
  102. package/dist/sig/mod.d.ts +5 -5
  103. package/dist/sig/mod.js +6 -6
  104. package/dist/sig/owner.test.js +7 -7
  105. package/dist/sig/proof.test.js +7 -7
  106. package/dist/testing/docloader.test.js +3 -3
  107. package/dist/testing/mod.d.ts +272 -0
  108. package/dist/testing/mod.js +3 -3
  109. package/dist/{testing-DUpTIvNE.js → testing-tWr1VQxx.js} +2 -2
  110. package/dist/{type-BYN6Ax2M.js → type-DaUr3Il7.js} +6943 -2120
  111. package/dist/{types-BBpQe860.cjs → types-D2Nyz0tR.cjs} +1 -1
  112. package/dist/{types-BXkh8ctL.js → types-DQuSDtDg.js} +1 -1
  113. package/dist/vocab/actor.test.js +5 -5
  114. package/dist/vocab/lookup.test.js +255 -5
  115. package/dist/vocab/mod.cjs +4 -4
  116. package/dist/vocab/mod.d.cts +3 -3
  117. package/dist/vocab/mod.d.ts +3 -3
  118. package/dist/vocab/mod.js +4 -4
  119. package/dist/vocab/type.test.js +3 -3
  120. package/dist/vocab/vocab.test.js +397 -8
  121. package/dist/{vocab-SOE1ifCr.d.ts → vocab-BI0Ak5lL.d.ts} +290 -0
  122. package/dist/{vocab-DWZQ7gVQ.cjs → vocab-Dd4VMrr0.cjs} +23 -14
  123. package/dist/{vocab-DJTYMqyU.d.cts → vocab-Dw1-yVGg.d.cts} +290 -0
  124. package/dist/{vocab-PKJB4DyY.js → vocab-w--qk7HF.js} +23 -14
  125. package/dist/webfinger/handler.test.js +16 -16
  126. package/dist/webfinger/lookup.test.js +4 -4
  127. package/dist/webfinger/mod.cjs +2 -2
  128. package/dist/webfinger/mod.js +2 -2
  129. package/dist/x/cfworkers.test.js +3 -3
  130. package/dist/x/hono.d.cts +6 -6
  131. package/dist/x/hono.d.ts +6 -6
  132. package/dist/x/sveltekit.d.cts +6 -6
  133. package/dist/x/sveltekit.d.ts +6 -6
  134. package/package.json +1 -1
  135. package/dist/key-BvvbahfP.cjs +0 -10
  136. package/dist/middleware-BD1IE5O5.js +0 -26
  137. package/dist/middleware-BuZrvrDv.js +0 -17
  138. package/dist/middleware-h_3nRr8m.cjs +0 -17
@@ -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-SZjTrl6Z.cjs');
7
- const require_actor = require('./actor-CNUje03O.cjs');
8
- const require_key = require('./key-JqiQvcq1.cjs');
6
+ const require_docloader = require('./docloader-CYnQRIXv.cjs');
7
+ const require_actor = require('./actor-CwZ2m5rG.cjs');
8
+ const require_key = require('./key-DuXv64tg.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"));
@@ -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-_WdHTWQR.js";
6
- import { CryptographicKey } from "./actor-m_ko-86v.js";
7
- import { fetchKey, validateCryptoKey } from "./key-Cf8KTg-A.js";
5
+ import { deno_default } from "./docloader-Czl3xV10.js";
6
+ import { CryptographicKey } from "./actor-DoMcqXsW.js";
7
+ import { fetchKey, validateCryptoKey } from "./key-BNJQQm3h.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,8 +3,8 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, deno_default } from "./type-BYN6Ax2M.js";
7
- import { fetchKey, validateCryptoKey } from "./key-Cps8Sv3N.js";
6
+ import { CryptographicKey, deno_default } from "./type-DaUr3Il7.js";
7
+ import { fetchKey, validateCryptoKey } from "./key-DnqhSgAv.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";
@@ -1,5 +1,5 @@
1
1
  import { DocumentLoader } from "./docloader-D-MrRyHl.cjs";
2
- import { CryptographicKey, Multikey } from "./vocab-DJTYMqyU.cjs";
2
+ import { CryptographicKey, Multikey } from "./vocab-Dw1-yVGg.cjs";
3
3
  import { TracerProvider } from "@opentelemetry/api";
4
4
 
5
5
  //#region src/sig/key.d.ts
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { DocumentLoader } from "./docloader-CxWcuWqQ.js";
4
- import { CryptographicKey, Multikey } from "./vocab-SOE1ifCr.js";
4
+ import { CryptographicKey, Multikey } from "./vocab-BI0Ak5lL.js";
5
5
  import { TracerProvider } from "@opentelemetry/api";
6
6
 
7
7
  //#region src/sig/key.d.ts
@@ -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-BYN6Ax2M.js";
6
+ import { Activity, deno_default, getTypeId } from "./type-DaUr3Il7.js";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
9
9
 
@@ -41,17 +41,34 @@ var InboxListenerSet = class InboxListenerSet {
41
41
  return this.dispatchWithClass(activity)?.listener ?? null;
42
42
  }
43
43
  };
44
- async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider }) {
44
+ async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
45
45
  const logger = getLogger([
46
46
  "fedify",
47
47
  "federation",
48
48
  "inbox"
49
49
  ]);
50
- const cacheKey = activity.id == null ? null : [
51
- ...kvPrefixes.activityIdempotence,
52
- ctx.origin,
53
- activity.id.href
54
- ];
50
+ let cacheKey = null;
51
+ if (activity.id != null) {
52
+ const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
53
+ const strategy = idempotencyStrategy ?? "per-inbox";
54
+ let keyString;
55
+ if (typeof strategy === "function") {
56
+ const result = await strategy(inboxContext, activity);
57
+ keyString = result;
58
+ } else switch (strategy) {
59
+ case "global":
60
+ keyString = activity.id.href;
61
+ break;
62
+ case "per-origin":
63
+ keyString = `${ctx.origin}\n${activity.id.href}`;
64
+ break;
65
+ case "per-inbox":
66
+ keyString = `${ctx.origin}\n${activity.id.href}\n${recipient == null ? "sharedInbox" : `inbox\n${recipient}`}`;
67
+ break;
68
+ default: keyString = `${ctx.origin}\n${activity.id.href}`;
69
+ }
70
+ if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
71
+ }
55
72
  if (cacheKey != null) {
56
73
  const cached = await kv.get(cacheKey);
57
74
  if (cached === true) {
@@ -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-_WdHTWQR.js";
6
- import { CryptographicKey, Object as Object$1, isActor } from "./actor-m_ko-86v.js";
5
+ import { deno_default, getDocumentLoader } from "./docloader-Czl3xV10.js";
6
+ import { CryptographicKey, Object as Object$1, isActor } from "./actor-DoMcqXsW.js";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { SpanKind, SpanStatusCode, 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-_WdHTWQR.js";
6
- import "./actor-m_ko-86v.js";
7
- import "./lookup-C6WSLjPE.js";
8
- import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-Cf8KTg-A.js";
5
+ import "./docloader-Czl3xV10.js";
6
+ import "./actor-DoMcqXsW.js";
7
+ import "./lookup-Dhm78GlK.js";
8
+ import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-BNJQQm3h.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-CYnQRIXv.cjs');
6
+ require('./actor-CwZ2m5rG.cjs');
7
+ require('./lookup-D6dro5Au.cjs');
8
+ const require_key = require('./key-DuXv64tg.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-BYN6Ax2M.js";
7
- import { isActor } from "./actor-BxAu0qet.js";
6
+ import { CryptographicKey, Object as Object$1, deno_default, getDocumentLoader } from "./type-DaUr3Il7.js";
7
+ import { isActor } from "./actor-D8gCwLzv.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
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import "./type-BYN6Ax2M.js";
7
- import "./actor-BxAu0qet.js";
8
- import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-Cps8Sv3N.js";
6
+ import "./type-DaUr3Il7.js";
7
+ import "./actor-D8gCwLzv.js";
8
+ import { exportJwk, fetchKey, generateCryptoKeyPair, importJwk, validateCryptoKey } from "./key-DnqhSgAv.js";
9
9
 
10
10
  export { validateCryptoKey };
@@ -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-SZjTrl6Z.cjs');
7
- const require_actor = require('./actor-CNUje03O.cjs');
6
+ const require_docloader = require('./docloader-CYnQRIXv.cjs');
7
+ const require_actor = require('./actor-CwZ2m5rG.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,7 +3,7 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, Multikey } from "./type-BYN6Ax2M.js";
6
+ import { CryptographicKey, Multikey } from "./type-DaUr3Il7.js";
7
7
 
8
8
  //#region src/federation/keycache.ts
9
9
  var KvKeyCache = class {
@@ -3,7 +3,7 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, Multikey, importSpki } from "./type-BYN6Ax2M.js";
6
+ import { CryptographicKey, Multikey, importSpki } from "./type-DaUr3Il7.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-BYN6Ax2M.js";
7
- import { fetchKey, validateCryptoKey } from "./key-Cps8Sv3N.js";
6
+ import { Activity, CryptographicKey, Object as Object$1, deno_default, getDocumentLoader, getTypeId } from "./type-DaUr3Il7.js";
7
+ import { fetchKey, validateCryptoKey } from "./key-DnqhSgAv.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-BYN6Ax2M.js";
6
+ import { Object as Object$1, deno_default, getDocumentLoader, getTypeId, lookupWebFinger } from "./type-DaUr3Il7.js";
7
7
  import { cloneDeep, delay } from "es-toolkit";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -240,14 +240,13 @@ async function lookupObject(identifier, options = {}) {
240
240
  async function lookupObjectInternal(identifier, options = {}) {
241
241
  const documentLoader = options.documentLoader ?? getDocumentLoader({ userAgent: options.userAgent });
242
242
  if (typeof identifier === "string") identifier = toAcctUrl(identifier) ?? new URL(identifier);
243
- let document = null;
243
+ let remoteDoc = null;
244
244
  if (identifier.protocol === "http:" || identifier.protocol === "https:") try {
245
- const remoteDoc = await documentLoader(identifier.href, { signal: options.signal });
246
- document = remoteDoc.document;
245
+ remoteDoc = await documentLoader(identifier.href, { signal: options.signal });
247
246
  } catch (error) {
248
247
  logger.debug("Failed to fetch remote document:\n{error}", { error });
249
248
  }
250
- if (document == null) {
249
+ if (remoteDoc == null) {
251
250
  const jrd = await lookupWebFinger(identifier, {
252
251
  userAgent: options.userAgent,
253
252
  tracerProvider: options.tracerProvider,
@@ -258,8 +257,7 @@ async function lookupObjectInternal(identifier, options = {}) {
258
257
  for (const l of jrd.links) {
259
258
  if (l.type !== "application/activity+json" && !l.type?.match(/application\/ld\+json;\s*profile="https:\/\/www.w3.org\/ns\/activitystreams"/) || l.rel !== "self" || l.href == null) continue;
260
259
  try {
261
- const remoteDoc = await documentLoader(l.href, { signal: options.signal });
262
- document = remoteDoc.document;
260
+ remoteDoc = await documentLoader(l.href, { signal: options.signal });
263
261
  break;
264
262
  } catch (error) {
265
263
  logger.debug("Failed to fetch remote document:\n{error}", { error });
@@ -267,23 +265,34 @@ async function lookupObjectInternal(identifier, options = {}) {
267
265
  }
268
266
  }
269
267
  }
270
- if (document == null) return null;
268
+ if (remoteDoc == null) return null;
269
+ let object;
271
270
  try {
272
- return await Object$1.fromJsonLd(document, {
271
+ object = await Object$1.fromJsonLd(remoteDoc.document, {
273
272
  documentLoader,
274
273
  contextLoader: options.contextLoader,
275
- tracerProvider: options.tracerProvider
274
+ tracerProvider: options.tracerProvider,
275
+ baseUrl: new URL(remoteDoc.documentUrl)
276
276
  });
277
277
  } catch (error) {
278
278
  if (error instanceof TypeError) {
279
279
  logger.debug("Failed to parse JSON-LD document: {error}\n{document}", {
280
- error,
281
- document
280
+ ...remoteDoc,
281
+ error
282
282
  });
283
283
  return null;
284
284
  }
285
285
  throw error;
286
286
  }
287
+ if (options.crossOrigin !== "trust" && object.id != null && object.id.origin !== new URL(remoteDoc.documentUrl).origin) {
288
+ if (options.crossOrigin === "throw") throw new Error(`The object's @id (${object.id.href}) has a different origin than the document URL (${remoteDoc.documentUrl}); refusing to return the object. If you want to bypass this check and are aware of the security implications, set the crossOrigin option to "trust".`);
289
+ logger.warn("The object's @id ({objectId}) has a different origin than the document URL ({documentUrl}); refusing to return the object. If you want to bypass this check and are aware of the security implications, set the crossOrigin option to \"trust\".", {
290
+ ...remoteDoc,
291
+ objectId: object.id.href
292
+ });
293
+ return null;
294
+ }
295
+ return object;
287
296
  }
288
297
  /**
289
298
  * Traverses a collection, yielding each item in the collection.
@@ -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-SZjTrl6Z.cjs');
6
+ const require_docloader = require('./docloader-CYnQRIXv.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-_WdHTWQR.js";
5
+ import { UrlError, deno_default, getUserAgent, validatePublicUrl } from "./docloader-Czl3xV10.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-DaUr3Il7.js";
7
+ import { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, createFederation } from "./middleware-DQYscW90.js";
8
+ import "./client-D5CBsPrc.js";
9
+ import "./lookup-CbtuFbtg.js";
10
+ import "./types-BSuWJsOm.js";
11
+ import "./actor-D8gCwLzv.js";
12
+ import "./key-DnqhSgAv.js";
13
+ import "./http-CuS-d4U0.js";
14
+ import "./authdocloader-DYTNpaMA.js";
15
+ import "./ld-Isot0tiW.js";
16
+ import "./owner-ChSL4aJ7.js";
17
+ import "./proof-x3IBewan.js";
18
+ import "./inbox-IETv_Qez.js";
19
+ import "./builder-1_skw-d2.js";
20
+ import "./collection-CcnIw1qY.js";
21
+ import "./keycache-CSBkusP8.js";
22
+ import "./negotiation-5NPJL6zp.js";
23
+ import "./retry-D4GJ670a.js";
24
+ import "./send-D5fjmUEj.js";
25
+
26
+ export { FederationImpl };
@@ -3,15 +3,15 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
 
5
5
  import { getDefaultActivityTransformers } from "./transformers-BFT6d7J5.js";
6
- import { deno_default, getDocumentLoader, kvCache } from "./docloader-_WdHTWQR.js";
7
- import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId } from "./actor-m_ko-86v.js";
8
- import { lookupWebFinger } from "./lookup-C6WSLjPE.js";
9
- import { exportJwk, importJwk, validateCryptoKey } from "./key-Cf8KTg-A.js";
10
- import { doubleKnock, verifyRequest } from "./http-BpoEurUR.js";
11
- import { detachSignature, doesActorOwnKey, getKeyOwner, hasSignature, signJsonLd, signObject, verifyJsonLd, verifyObject } from "./proof-CHM9su4L.js";
12
- import { getNodeInfo, nodeInfoToJson } from "./types-BXkh8ctL.js";
13
- import { getAuthenticatedDocumentLoader } from "./authdocloader-nRFL9luh.js";
14
- import { lookupObject, traverseCollection } from "./vocab-PKJB4DyY.js";
6
+ import { deno_default, getDocumentLoader, kvCache } from "./docloader-Czl3xV10.js";
7
+ import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId } from "./actor-DoMcqXsW.js";
8
+ import { lookupWebFinger } from "./lookup-Dhm78GlK.js";
9
+ import { exportJwk, importJwk, validateCryptoKey } from "./key-BNJQQm3h.js";
10
+ import { doubleKnock, verifyRequest } from "./http-C_Qc2neP.js";
11
+ import { detachSignature, doesActorOwnKey, getKeyOwner, hasSignature, signJsonLd, signObject, verifyJsonLd, verifyObject } from "./proof-BiSCuwyA.js";
12
+ import { getNodeInfo, nodeInfoToJson } from "./types-DQuSDtDg.js";
13
+ import { getAuthenticatedDocumentLoader } from "./authdocloader-Cv_qEn1G.js";
14
+ import { lookupObject, traverseCollection } from "./vocab-w--qk7HF.js";
15
15
  import { getLogger, withContext } from "@logtape/logtape";
16
16
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
17
17
  import { encodeHex } from "byte-encodings/hex";
@@ -55,17 +55,34 @@ var InboxListenerSet = class InboxListenerSet {
55
55
  return this.dispatchWithClass(activity)?.listener ?? null;
56
56
  }
57
57
  };
58
- async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider }) {
58
+ async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
59
59
  const logger$1 = getLogger([
60
60
  "fedify",
61
61
  "federation",
62
62
  "inbox"
63
63
  ]);
64
- const cacheKey = activity.id == null ? null : [
65
- ...kvPrefixes.activityIdempotence,
66
- ctx.origin,
67
- activity.id.href
68
- ];
64
+ let cacheKey = null;
65
+ if (activity.id != null) {
66
+ const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
67
+ const strategy = idempotencyStrategy ?? "per-inbox";
68
+ let keyString;
69
+ if (typeof strategy === "function") {
70
+ const result = await strategy(inboxContext, activity);
71
+ keyString = result;
72
+ } else switch (strategy) {
73
+ case "global":
74
+ keyString = activity.id.href;
75
+ break;
76
+ case "per-origin":
77
+ keyString = `${ctx.origin}\n${activity.id.href}`;
78
+ break;
79
+ case "per-inbox":
80
+ keyString = `${ctx.origin}\n${activity.id.href}\n${recipient == null ? "sharedInbox" : `inbox\n${recipient}`}`;
81
+ break;
82
+ default: keyString = `${ctx.origin}\n${activity.id.href}`;
83
+ }
84
+ if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
85
+ }
69
86
  if (cacheKey != null) {
70
87
  const cached = await kv.get(cacheKey);
71
88
  if (cached === true) {
@@ -307,6 +324,7 @@ var FederationBuilderImpl = class {
307
324
  inboxListeners;
308
325
  inboxErrorHandler;
309
326
  sharedInboxKeyDispatcher;
327
+ idempotencyStrategy;
310
328
  collectionTypeIds;
311
329
  collectionCallbacks;
312
330
  /**
@@ -321,7 +339,7 @@ var FederationBuilderImpl = class {
321
339
  this.collectionTypeIds = {};
322
340
  }
323
341
  async build(options) {
324
- const { FederationImpl: FederationImpl$1 } = await import("./middleware-BuZrvrDv.js");
342
+ const { FederationImpl: FederationImpl$1 } = await import("./middleware-T-knSMwl.js");
325
343
  const f = new FederationImpl$1(options);
326
344
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
327
345
  f.router = this.router.clone();
@@ -343,6 +361,7 @@ var FederationBuilderImpl = class {
343
361
  f.inboxListeners = this.inboxListeners?.clone();
344
362
  f.inboxErrorHandler = this.inboxErrorHandler;
345
363
  f.sharedInboxKeyDispatcher = this.sharedInboxKeyDispatcher;
364
+ f.idempotencyStrategy = this.idempotencyStrategy;
346
365
  return f;
347
366
  }
348
367
  _getTracer() {
@@ -765,6 +784,10 @@ var FederationBuilderImpl = class {
765
784
  setSharedKeyDispatcher: (dispatcher) => {
766
785
  this.sharedInboxKeyDispatcher = dispatcher;
767
786
  return setters;
787
+ },
788
+ withIdempotency: (strategy) => {
789
+ this.idempotencyStrategy = strategy;
790
+ return setters;
768
791
  }
769
792
  };
770
793
  return setters;
@@ -1293,7 +1316,8 @@ async function handleInbox(request, options) {
1293
1316
  * @param span The OpenTelemetry span for tracing.
1294
1317
  * @returns A promise that resolves to an HTTP response.
1295
1318
  */
1296
- async function handleInboxInternal(request, { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider }, span) {
1319
+ async function handleInboxInternal(request, parameters, span) {
1320
+ const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider } = parameters;
1297
1321
  const logger$1 = getLogger([
1298
1322
  "fedify",
1299
1323
  "federation",
@@ -1495,7 +1519,8 @@ async function handleInboxInternal(request, { recipient, context: ctx, inboxCont
1495
1519
  kvPrefixes,
1496
1520
  queue,
1497
1521
  span,
1498
- tracerProvider
1522
+ tracerProvider,
1523
+ idempotencyStrategy: parameters.idempotencyStrategy
1499
1524
  });
1500
1525
  if (routeResult === "alreadyProcessed") return new Response(`Activity <${activity.id}> has already been processed.`, {
1501
1526
  status: 202,
@@ -2325,7 +2350,6 @@ var FederationImpl = class extends FederationBuilderImpl {
2325
2350
  firstKnock;
2326
2351
  constructor(options) {
2327
2352
  super();
2328
- const logger$1 = getLogger(["fedify", "federation"]);
2329
2353
  this.kv = options.kv;
2330
2354
  this.kvPrefixes = {
2331
2355
  activityIdempotence: ["_fedify", "activityIdempotence"],
@@ -2373,8 +2397,9 @@ var FederationImpl = class extends FederationBuilderImpl {
2373
2397
  this.router.trailingSlashInsensitive = options.trailingSlashInsensitive ?? false;
2374
2398
  this._initializeRouter();
2375
2399
  if (options.allowPrivateAddress || options.userAgent != null) {
2376
- if (options.contextLoader != null) throw new TypeError("Cannot set contextLoader with allowPrivateAddress or userAgent options.");
2377
- else if (options.authenticatedDocumentLoaderFactory != null) throw new TypeError("Cannot set authenticatedDocumentLoaderFactory with allowPrivateAddress or userAgent options.");
2400
+ if (options.documentLoaderFactory != null) throw new TypeError("Cannot set documentLoaderFactory with allowPrivateAddress or userAgent options.");
2401
+ if (options.contextLoaderFactory != null) throw new TypeError("Cannot set contextLoaderFactory with allowPrivateAddress or userAgent options.");
2402
+ if (options.authenticatedDocumentLoaderFactory != null) throw new TypeError("Cannot set authenticatedDocumentLoaderFactory with allowPrivateAddress or userAgent options.");
2378
2403
  }
2379
2404
  const { allowPrivateAddress, userAgent } = options;
2380
2405
  this.allowPrivateAddress = allowPrivateAddress ?? false;
@@ -2388,11 +2413,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2388
2413
  prefix: this.kvPrefixes.remoteDocument
2389
2414
  });
2390
2415
  });
2391
- if (options.contextLoader != null) {
2392
- if (options.contextLoaderFactory != null) throw new TypeError("Cannot set both contextLoader and contextLoaderFactory options at a time; use contextLoaderFactory only.");
2393
- this.contextLoaderFactory = () => options.contextLoader;
2394
- logger$1.warn("The contextLoader option is deprecated; use contextLoaderFactory option instead.");
2395
- } else this.contextLoaderFactory = options.contextLoaderFactory ?? this.documentLoaderFactory;
2416
+ this.contextLoaderFactory = options.contextLoaderFactory ?? this.documentLoaderFactory;
2396
2417
  this.authenticatedDocumentLoaderFactory = options.authenticatedDocumentLoaderFactory ?? ((identity) => getAuthenticatedDocumentLoader(identity, {
2397
2418
  allowPrivateAddress,
2398
2419
  userAgent,
@@ -2996,7 +3017,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2996
3017
  nodeInfoDispatcher: this.nodeInfoDispatcher
2997
3018
  });
2998
3019
  }
2999
- if (!acceptsJsonLd(request)) return await onNotAcceptable(request);
3020
+ if (request.method !== "POST" && !acceptsJsonLd(request)) return await onNotAcceptable(request);
3000
3021
  switch (routeName) {
3001
3022
  case "actor":
3002
3023
  context$1 = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier: route.values.identifier ?? route.values.handle } });
@@ -3066,7 +3087,8 @@ var FederationImpl = class extends FederationBuilderImpl {
3066
3087
  onNotFound,
3067
3088
  signatureTimeWindow: this.signatureTimeWindow,
3068
3089
  skipSignatureVerification: this.skipSignatureVerification,
3069
- tracerProvider: this.tracerProvider
3090
+ tracerProvider: this.tracerProvider,
3091
+ idempotencyStrategy: this.idempotencyStrategy
3070
3092
  });
3071
3093
  case "following": return await handleCollection(request, {
3072
3094
  name: "following",
@@ -3809,7 +3831,8 @@ var ContextImpl = class ContextImpl {
3809
3831
  kvPrefixes: this.federation.kvPrefixes,
3810
3832
  queue: this.federation.inboxQueue,
3811
3833
  span,
3812
- tracerProvider: options.tracerProvider ?? this.tracerProvider
3834
+ tracerProvider: options.tracerProvider ?? this.tracerProvider,
3835
+ idempotencyStrategy: this.federation.idempotencyStrategy
3813
3836
  });
3814
3837
  return routeResult === "alreadyProcessed" || routeResult === "enqueued" || routeResult === "unsupportedActivity" || routeResult === "success";
3815
3838
  }
@@ -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-CYnQRIXv.cjs');
7
+ require('./actor-CwZ2m5rG.cjs');
8
+ const require_middleware = require('./middleware-Dgmdgrvb.cjs');
9
+ require('./lookup-D6dro5Au.cjs');
10
+ require('./key-DuXv64tg.cjs');
11
+ require('./http-CAusBl_3.cjs');
12
+ require('./proof-ONNmhInb.cjs');
13
+ require('./types-D2Nyz0tR.cjs');
14
+ require('./authdocloader-bsmVF6eO.cjs');
15
+ require('./vocab-Dd4VMrr0.cjs');
16
+
17
+ exports.FederationImpl = require_middleware.FederationImpl;