@fedify/fedify 2.4.0-pr.936.41 → 2.5.0-dev.2271

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 (244) hide show
  1. package/README.md +50 -39
  2. package/dist/{assert-CJ1KXcvv.mjs → assert-D1Eafmd_.mjs} +1 -1
  3. package/dist/{assert_equals-BV7oLMxm.mjs → assert_equals-Z6IcEbWU.mjs} +2 -28
  4. package/dist/assert_exists-cffSpJ7X.mjs +28 -0
  5. package/dist/assert_false-CPdRnc3E.mjs +23 -0
  6. package/dist/assert_greater_or_equal-BlafOF4-.mjs +31 -0
  7. package/dist/{assert_instance_of-Q9KTBnrf.mjs → assert_instance_of-mrXWWNY-.mjs} +1 -1
  8. package/dist/{assert_not_equals-EPJPoxuf.mjs → assert_not_equals-CpPK2t89.mjs} +2 -1
  9. package/dist/assert_rejects-CTptdYck.mjs +39 -0
  10. package/dist/{assert_strict_equals-Ec20AUwa.mjs → assert_strict_equals-CYvBmkpC.mjs} +2 -1
  11. package/dist/{assert_throws-NiFfqbnH.mjs → assert_throws-BYITOvPO.mjs} +2 -1
  12. package/dist/assertion_error-B-cx0fFA.mjs +31 -0
  13. package/dist/audience-CHQ-FlLD.mjs +95 -0
  14. package/dist/{builder-DonuxRl_.mjs → builder-Bda6LK7A.mjs} +169 -14
  15. package/dist/{circuit-breaker-CBGyz5F7.mjs → circuit-breaker-XJ53md4S.mjs} +224 -17
  16. package/dist/circuit-breaker-test-utils-DW6YC_Pe.mjs +14 -0
  17. package/dist/{client-CjF5IYQS.mjs → client-CEnNz8O7.mjs} +144 -8
  18. package/dist/{codec-BBga-FWI.mjs → codec-C6rTrpIp.mjs} +26 -3
  19. package/dist/{collection-BIhlldqK.mjs → collection-CnnP1UAv.mjs} +1 -1
  20. package/dist/compat/mod.cjs +1 -1
  21. package/dist/compat/mod.d.cts +1 -1
  22. package/dist/compat/mod.d.ts +1 -1
  23. package/dist/compat/mod.js +1 -1
  24. package/dist/compat/outgoing-jsonld.test.mjs +71 -3
  25. package/dist/compat/public-audience.test.mjs +14 -5
  26. package/dist/compat/secured-document.test.d.mts +2 -0
  27. package/dist/compat/secured-document.test.mjs +58 -0
  28. package/dist/compat/transformers.test.mjs +5 -5
  29. package/dist/compound-proof-B-9mXxFW.mjs +989 -0
  30. package/dist/{context-Zii1f5xS.d.ts → context-7NyiqIcg.d.ts} +1600 -25
  31. package/dist/{context-BJXxPElm.mjs → context-8Tu9kea0.mjs} +21 -63
  32. package/dist/{context-lxX6I7as.d.cts → context-tsYPJ2Ew.d.cts} +1600 -25
  33. package/dist/{deno-BHzKn9Ig.mjs → deno-oR5aJKpU.mjs} +1 -1
  34. package/dist/dist-DJQM4u7i.mjs +189 -0
  35. package/dist/docloader-DBoYbvYW.mjs +87 -0
  36. package/dist/{esm-yYQfPhIY.mjs → esm-BHXXx4Wx.mjs} +13 -6
  37. package/dist/federation/audience.test.d.mts +2 -0
  38. package/dist/federation/audience.test.mjs +130 -0
  39. package/dist/federation/builder.test.mjs +54 -5
  40. package/dist/federation/circuit-breaker.test.mjs +838 -7
  41. package/dist/federation/collection.test.mjs +3 -3
  42. package/dist/federation/compound-fanout.test.d.mts +2 -0
  43. package/dist/federation/compound-fanout.test.mjs +228 -0
  44. package/dist/federation/handler-compound-proof.test.d.mts +2 -0
  45. package/dist/federation/handler-compound-proof.test.mjs +384 -0
  46. package/dist/federation/handler.test.mjs +385 -15
  47. package/dist/federation/hashlink-media.test.d.mts +2 -0
  48. package/dist/federation/hashlink-media.test.mjs +422 -0
  49. package/dist/federation/idempotency.test.mjs +6 -6
  50. package/dist/federation/inbox-report.test.d.mts +2 -0
  51. package/dist/federation/inbox-report.test.mjs +475 -0
  52. package/dist/federation/inbox.test.mjs +3 -3
  53. package/dist/federation/keycache.test.mjs +215 -14
  54. package/dist/federation/kv.test.mjs +3 -3
  55. package/dist/federation/metrics.test.mjs +5 -5
  56. package/dist/federation/middleware.test.mjs +967 -35
  57. package/dist/federation/mod.cjs +18 -261
  58. package/dist/federation/mod.d.cts +5 -5
  59. package/dist/federation/mod.d.ts +5 -5
  60. package/dist/federation/mod.js +279 -1
  61. package/dist/federation/mq.test.mjs +123 -47
  62. package/dist/federation/negotiation.test.mjs +4 -4
  63. package/dist/federation/outgoing-proof.test.d.mts +2 -0
  64. package/dist/federation/outgoing-proof.test.mjs +931 -0
  65. package/dist/federation/portable-actor.test.d.mts +2 -0
  66. package/dist/federation/portable-actor.test.mjs +496 -0
  67. package/dist/federation/portable-chain.test.d.mts +2 -0
  68. package/dist/federation/portable-chain.test.mjs +370 -0
  69. package/dist/federation/portable-collection.test.d.mts +2 -0
  70. package/dist/federation/portable-collection.test.mjs +832 -0
  71. package/dist/federation/portable-delivery.test.d.mts +2 -0
  72. package/dist/federation/portable-delivery.test.mjs +746 -0
  73. package/dist/federation/portable-gateway-keys.test.d.mts +2 -0
  74. package/dist/federation/portable-gateway-keys.test.mjs +686 -0
  75. package/dist/federation/portable-inbox.test.d.mts +2 -0
  76. package/dist/federation/portable-inbox.test.mjs +1535 -0
  77. package/dist/federation/portable-parse-uri.test.d.mts +2 -0
  78. package/dist/federation/portable-parse-uri.test.mjs +348 -0
  79. package/dist/federation/portable-route-activity.test.d.mts +2 -0
  80. package/dist/federation/portable-route-activity.test.mjs +259 -0
  81. package/dist/federation/portable.test.d.mts +2 -0
  82. package/dist/federation/portable.test.mjs +1072 -0
  83. package/dist/federation/retry.test.mjs +4 -3
  84. package/dist/federation/router.test.mjs +9 -159
  85. package/dist/federation/send.test.mjs +245 -27
  86. package/dist/federation/tasks/codec.test.mjs +4 -4
  87. package/dist/federation/tasks/enqueue.test.mjs +42 -4
  88. package/dist/federation/tasks/tasks.test.mjs +7 -6
  89. package/dist/federation/temporal.test.mjs +4 -4
  90. package/dist/federation/webfinger.test.mjs +275 -12
  91. package/dist/{middleware-FrSMAYEx.cjs → federation-CkZiAcWY.cjs} +8640 -3722
  92. package/dist/http-B5JT115n.cjs +10630 -0
  93. package/dist/http-DydWCB7R.js +6527 -0
  94. package/dist/{http-CPVMUgsW.mjs → http-siciWkmx.mjs} +397 -168
  95. package/dist/key-BspPiXqn.mjs +951 -0
  96. package/dist/key-C1nv7_jD.d.ts +1125 -0
  97. package/dist/key-DYxuyd-s.d.cts +1125 -0
  98. package/dist/key-owner-evidence-APB6NpSk.mjs +108 -0
  99. package/dist/keycache-Da8A8mZa.mjs +200 -0
  100. package/dist/{kv-D6hNiMTK.d.ts → kv-B2mzK5tl.d.cts} +3 -2
  101. package/dist/{kv-gJ8LYbxX.d.cts → kv-B2mzK5tl.d.ts} +3 -2
  102. package/dist/kv-DBRWVx3Q.mjs +104 -0
  103. package/dist/{kv-cache-KyGqJqSp.mjs → kv-cache-BF1hnW65.mjs} +1 -1
  104. package/dist/{kv-cache-5bnX3-Jq.js → kv-cache-CTQr1tbn.js} +54 -16
  105. package/dist/{kv-cache-DQ29C4XL.cjs → kv-cache-DCac1nEU.cjs} +55 -19
  106. package/dist/{ld-Cj9F_5AP.mjs → ld-CzaP-hJl.mjs} +44 -12
  107. package/dist/map-local-context-conflict-DOYEEJ3u.mjs +204 -0
  108. package/dist/map-local-create-note-B0SeXJms.mjs +214 -0
  109. package/dist/{metrics-DMk-nTxI.mjs → metrics-CYg9yxBL.mjs} +3 -2
  110. package/dist/metrics-DVKYY6K1.d.cts +36 -0
  111. package/dist/metrics-DoRtI0qU.d.ts +36 -0
  112. package/dist/{middleware-Y-kpsp6S.js → middleware-CsDDXKuL.js} +5493 -1103
  113. package/dist/{middleware-CvwTUgnP.mjs → middleware-D7_LO-Vs.mjs} +3157 -272
  114. package/dist/{middleware-CEctxBN6.mjs → middleware-DWjrfpcz.mjs} +1 -1
  115. package/dist/{mod-gOlPDuT8.d.cts → mod-BojP2Bw3.d.cts} +1 -1
  116. package/dist/mod-CavhAgLw.d.cts +320 -0
  117. package/dist/mod-CtpF2BU5.d.ts +320 -0
  118. package/dist/{mod-BtEaIEcD.d.cts → mod-DEZXwV6J.d.ts} +10 -4
  119. package/dist/{mod-UMmveiO0.d.ts → mod-Dw-nPxQh.d.cts} +10 -4
  120. package/dist/{mod-DLc2Ot6f.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
  121. package/dist/mod.cjs +40 -39
  122. package/dist/mod.d.cts +10 -11
  123. package/dist/mod.d.ts +10 -11
  124. package/dist/mod.js +9 -9
  125. package/dist/{mq-llHKivST.mjs → mq-Dm1Wmtm-.mjs} +6 -0
  126. package/dist/nodeinfo/client.test.mjs +139 -4
  127. package/dist/nodeinfo/handler.test.mjs +5 -5
  128. package/dist/nodeinfo/mod.cjs +1 -1
  129. package/dist/nodeinfo/mod.d.cts +1 -1
  130. package/dist/nodeinfo/mod.d.ts +1 -1
  131. package/dist/nodeinfo/mod.js +1 -1
  132. package/dist/nodeinfo/types.test.mjs +4 -4
  133. package/dist/otel/exporter.test.mjs +3 -3
  134. package/dist/otel/mod.cjs +0 -1
  135. package/dist/otel/mod.d.cts +1 -1
  136. package/dist/otel/mod.d.ts +1 -1
  137. package/dist/{outgoing-jsonld-URuqsICz.mjs → outgoing-jsonld-4IJqPYos.mjs} +12 -10
  138. package/dist/{owner-DEvZuyOE.d.cts → owner-BF0L9cMt.d.cts} +11 -0
  139. package/dist/{owner-CnngXDNJ.d.ts → owner-BSzr5-I8.d.ts} +11 -0
  140. package/dist/owner-DYgfTFHy.mjs +267 -0
  141. package/dist/portable-collection-BpsVsRov.js +670 -0
  142. package/dist/portable-collection-C74P1vtC.mjs +418 -0
  143. package/dist/portable-collection-DZd2bm7M.cjs +686 -0
  144. package/dist/portable-key-BIMLrAP4.mjs +549 -0
  145. package/dist/portable-key-id-Ca30-hOa.mjs +248 -0
  146. package/dist/proof-Dxy6ByqI.mjs +1299 -0
  147. package/dist/{public-audience-Cr5MsnMq.mjs → public-audience--klBIOk1.mjs} +15 -10
  148. package/dist/router-u5O5KCQr.mjs +156 -0
  149. package/dist/runtime/mod.cjs +1 -1
  150. package/dist/runtime/mod.js +1 -1
  151. package/dist/secured-document-CxzZZ9nL.mjs +35 -0
  152. package/dist/send-C4dDpAxm.mjs +495 -0
  153. package/dist/sig/accept.test.mjs +1 -1
  154. package/dist/sig/compound-proof-discovery.test.d.mts +2 -0
  155. package/dist/sig/compound-proof-discovery.test.mjs +331 -0
  156. package/dist/sig/compound-proof-producer.test.d.mts +2 -0
  157. package/dist/sig/compound-proof-producer.test.mjs +107 -0
  158. package/dist/sig/compound-proof-verification.test.d.mts +2 -0
  159. package/dist/sig/compound-proof-verification.test.mjs +833 -0
  160. package/dist/sig/compound-proof.test.d.mts +2 -0
  161. package/dist/sig/compound-proof.test.mjs +411 -0
  162. package/dist/sig/http.test.mjs +702 -31
  163. package/dist/sig/key-owner-evidence.test.d.mts +2 -0
  164. package/dist/sig/key-owner-evidence.test.mjs +100 -0
  165. package/dist/sig/key.test.mjs +220 -8
  166. package/dist/sig/ld.test.mjs +65 -7
  167. package/dist/sig/mitra-receive-interop.test.d.mts +2 -0
  168. package/dist/sig/mitra-receive-interop.test.mjs +260 -0
  169. package/dist/sig/mitra-send-interop.test.d.mts +2 -0
  170. package/dist/sig/mitra-send-interop.test.mjs +461 -0
  171. package/dist/sig/mod.cjs +18 -16
  172. package/dist/sig/mod.d.cts +4 -4
  173. package/dist/sig/mod.d.ts +4 -4
  174. package/dist/sig/mod.js +3 -3
  175. package/dist/sig/owner.test.mjs +108 -9
  176. package/dist/sig/portable-collection.test.d.mts +2 -0
  177. package/dist/sig/portable-collection.test.mjs +697 -0
  178. package/dist/sig/portable-interop.test.d.mts +2 -0
  179. package/dist/sig/portable-interop.test.mjs +156 -0
  180. package/dist/sig/portable-key-id.test.d.mts +2 -0
  181. package/dist/sig/portable-key-id.test.mjs +67 -0
  182. package/dist/sig/portable-key.test.d.mts +2 -0
  183. package/dist/sig/portable-key.test.mjs +1439 -0
  184. package/dist/sig/proof.test.mjs +1753 -16
  185. package/dist/sig/tootik-request-interop.test.d.mts +2 -0
  186. package/dist/sig/tootik-request-interop.test.mjs +190 -0
  187. package/dist/sig/tootik-send-interop.test.d.mts +2 -0
  188. package/dist/sig/tootik-send-interop.test.mjs +331 -0
  189. package/dist/sig/verification.test.d.mts +2 -0
  190. package/dist/sig/verification.test.mjs +310 -0
  191. package/dist/std__assert-DvMDRPes.mjs +8 -0
  192. package/dist/{testing-CO7ftO8A.mjs → tasks-IG3pHfvZ.mjs} +2 -2
  193. package/dist/{temporal-fsXO5IvD.mjs → temporal-D0KJI4NF.mjs} +3 -3
  194. package/dist/testing/context.test.d.mts +2 -0
  195. package/dist/testing/context.test.mjs +19 -0
  196. package/dist/testing/kv.test.d.mts +2 -0
  197. package/dist/testing/kv.test.mjs +101 -0
  198. package/dist/testing/mod.d.mts +1617 -48
  199. package/dist/testing/mod.mjs +6 -3
  200. package/dist/testing-t8xDeJZ5.mjs +8 -0
  201. package/dist/{transformers-DGwl-hD1.cjs → transformers-BalCrSsr.cjs} +0 -1
  202. package/dist/{types-DC1pNgJA.js → types-_S2_MeLF.js} +144 -8
  203. package/dist/{types-CPym83zc.cjs → types-poIao40f.cjs} +160 -7
  204. package/dist/utils/docloader.test.mjs +530 -8
  205. package/dist/utils/kv-cache.test.mjs +2 -2
  206. package/dist/utils/mod.cjs +1 -1
  207. package/dist/utils/mod.d.cts +1 -1
  208. package/dist/utils/mod.d.ts +1 -1
  209. package/dist/utils/mod.js +1 -1
  210. package/dist/verification-C3954hQh.mjs +5 -0
  211. package/dist/verification-Dpfcw8ml.mjs +105 -0
  212. package/dist/vocab/cjs.test.mjs +1 -1
  213. package/package.json +8 -8
  214. package/dist/assert_rejects-EgstcQy5.mjs +0 -82
  215. package/dist/docloader-e1khNUKy.mjs +0 -49
  216. package/dist/http-CsmQ-BQ4.js +0 -2483
  217. package/dist/http-VyDTd4G3.d.cts +0 -553
  218. package/dist/http-hlIjmewS.cjs +0 -2694
  219. package/dist/http-lf8Hsd91.d.ts +0 -553
  220. package/dist/key-DfPsX8hv.mjs +0 -453
  221. package/dist/keycache-_DHqz5z_.mjs +0 -97
  222. package/dist/metrics-CoUJLQhZ.d.cts +0 -276
  223. package/dist/metrics-Dc4jR-IC.d.ts +0 -276
  224. package/dist/mod-B0hW12_O.d.cts +0 -307
  225. package/dist/mod-COIAjwRS.d.ts +0 -307
  226. package/dist/owner-Br9YYzn_.mjs +0 -120
  227. package/dist/proof-B4ngoaNQ.mjs +0 -316
  228. package/dist/proof-B6E0XUXJ.js +0 -1415
  229. package/dist/proof-NN4xCQGL.cjs +0 -1562
  230. package/dist/send-CxHKUNzv.mjs +0 -239
  231. package/dist/std__assert-B2NnY9bq.mjs +0 -79
  232. package/dist/temporal-polyfill-BCdTHexd.cjs +0 -3565
  233. /package/dist/{accept-8PiolDP7.mjs → accept-CPVqki78.mjs} +0 -0
  234. /package/dist/{activity-listener-BtTSxZWA.mjs → activity-listener-C-BSbKI7.mjs} +0 -0
  235. /package/dist/{client-CAM_bQXx.d.cts → client-D-XP_Ccb.d.cts} +0 -0
  236. /package/dist/{client-CSddvgWN.d.ts → client-D-XP_Ccb.d.ts} +0 -0
  237. /package/dist/{keys-Dbyd7bhl.mjs → keys-DIJNHW-Y.mjs} +0 -0
  238. /package/dist/{kv-CXBAok3k.mjs → kv-DCHkaJ9-.mjs} +0 -0
  239. /package/dist/{negotiation-RuwrPFqi.mjs → negotiation-CCocWT_N.mjs} +0 -0
  240. /package/dist/{retry-DgFqeS5k.mjs → retry-zX5xw5e0.mjs} +0 -0
  241. /package/dist/{chunk-D5IdezsZ.js → rolldown-runtime-BC-Eo5Mj.js} +0 -0
  242. /package/dist/{chunk-Czpeue4M.cjs → rolldown-runtime-Dmm3t92W.cjs} +0 -0
  243. /package/dist/{transformers-DXze6FUB.js → transformers-DAtXl_Kc.js} +0 -0
  244. /package/dist/{types-CrtdVuDP.mjs → types-DE_LV1JB.mjs} +0 -0
@@ -1,10 +1,10 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import "../std__assert-B2NnY9bq.mjs";
5
- import { r as assertFalse } from "../assert_rejects-EgstcQy5.mjs";
6
- import { t as assert } from "../assert-CJ1KXcvv.mjs";
7
- import { t as hasMalformedKnownTemporalLiteral } from "../temporal-fsXO5IvD.mjs";
4
+ import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
5
+ import "../std__assert-DvMDRPes.mjs";
6
+ import { t as assert } from "../assert-D1Eafmd_.mjs";
7
+ import { t as hasMalformedKnownTemporalLiteral } from "../temporal-D0KJI4NF.mjs";
8
8
  import { test } from "@fedify/fixture";
9
9
  //#region src/federation/temporal.test.ts
10
10
  test("hasMalformedKnownTemporalLiteral() detects expanded proof timestamps", async () => {
@@ -1,13 +1,14 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { r as createRequestContext } from "../context-BJXxPElm.mjs";
5
- import { t as MemoryKvStore } from "../kv-CXBAok3k.mjs";
6
- import { t as assertEquals } from "../assert_equals-BV7oLMxm.mjs";
7
- import "../std__assert-B2NnY9bq.mjs";
8
- import { t as assertNotEquals } from "../assert_not_equals-EPJPoxuf.mjs";
9
- import { o as createFederation, s as handleWebFinger } from "../middleware-CvwTUgnP.mjs";
4
+ import { r as createRequestContext } from "../context-8Tu9kea0.mjs";
5
+ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
6
+ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
7
+ import { t as assertNotEquals } from "../assert_not_equals-CpPK2t89.mjs";
8
+ import "../std__assert-DvMDRPes.mjs";
9
+ import { o as createFederation, s as handleWebFinger } from "../middleware-D7_LO-Vs.mjs";
10
10
  import { Image, Link, Person, Tombstone } from "@fedify/vocab";
11
+ import { parseIri } from "@fedify/vocab-runtime";
11
12
  import { createTestMeterProvider, test } from "@fedify/fixture";
12
13
  //#region src/federation/webfinger.test.ts
13
14
  test("handleWebFinger()", async (t) => {
@@ -258,7 +259,7 @@ test("handleWebFinger()", async (t) => {
258
259
  });
259
260
  onNotFoundCalled = null;
260
261
  const actorHandleMapper = (_ctx, username) => {
261
- return username === "foo" ? "someone" : username === "bar" ? "someone2" : null;
262
+ return username === "foo" ? "someone" : username === "bar" ? "someone2" : username === "qux" ? "someone2" : null;
262
263
  };
263
264
  await t.step("handle mapper", async () => {
264
265
  const u = new URL(url);
@@ -381,21 +382,83 @@ test("handleWebFinger()", async (t) => {
381
382
  assertEquals(response.status, 404);
382
383
  });
383
384
  await t.step("handleHost", async () => {
384
- const u = new URL(url);
385
- u.searchParams.set("resource", "acct:someone@example.com");
385
+ let u = new URL("https://ap.example.com/.well-known/webfinger");
386
+ u.searchParams.set("resource", "acct:someone@ap.example.com");
386
387
  let context = createContext(u);
387
388
  let request = context.request;
388
389
  let response = await handleWebFinger(request, {
389
390
  context,
390
- host: "handle.example.com",
391
+ host: "example.com",
391
392
  actorDispatcher,
392
393
  onNotFound
393
394
  });
394
395
  assertEquals(response.status, 200);
395
396
  assertEquals(await response.json(), {
396
- ...expected,
397
- aliases: [...expected.aliases, "acct:someone@handle.example.com"]
397
+ subject: "acct:someone@example.com",
398
+ aliases: ["https://ap.example.com/users/someone", "acct:someone@ap.example.com"],
399
+ links: [
400
+ {
401
+ href: "https://ap.example.com/users/someone",
402
+ rel: "self",
403
+ type: "application/activity+json"
404
+ },
405
+ {
406
+ href: "https://ap.example.com/@someone",
407
+ rel: "http://webfinger.net/rel/profile-page"
408
+ },
409
+ {
410
+ href: "https://ap.example.com/@someone",
411
+ rel: "alternate",
412
+ type: "text/html"
413
+ },
414
+ {
415
+ href: "https://ap.example.com/icon.jpg",
416
+ rel: "http://webfinger.net/rel/avatar",
417
+ type: "image/jpeg"
418
+ }
419
+ ]
420
+ });
421
+ u.searchParams.set("resource", "acct:qux@ap.example.com");
422
+ context = createContext(u);
423
+ request = context.request;
424
+ response = await handleWebFinger(request, {
425
+ context,
426
+ host: "example.com",
427
+ actorDispatcher,
428
+ actorHandleMapper,
429
+ onNotFound
398
430
  });
431
+ assertEquals(response.status, 200);
432
+ assertEquals(await response.json(), {
433
+ subject: "acct:bar@example.com",
434
+ aliases: [
435
+ "https://ap.example.com/users/someone2",
436
+ "acct:qux@ap.example.com",
437
+ "acct:bar@ap.example.com"
438
+ ],
439
+ links: [
440
+ {
441
+ href: "https://ap.example.com/users/someone2",
442
+ rel: "self",
443
+ type: "application/activity+json"
444
+ },
445
+ {
446
+ href: "https://ap.example.com/@someone2",
447
+ rel: "http://webfinger.net/rel/profile-page"
448
+ },
449
+ {
450
+ href: "https://ap.example.com/@someone2",
451
+ rel: "alternate",
452
+ type: "text/html"
453
+ },
454
+ {
455
+ href: "https://ap.example.com/icon.jpg",
456
+ rel: "http://webfinger.net/rel/avatar",
457
+ type: "image/jpeg"
458
+ }
459
+ ]
460
+ });
461
+ u = new URL(url);
399
462
  u.searchParams.set("resource", "acct:someone@handle.example.com");
400
463
  context = createContext(u);
401
464
  request = context.request;
@@ -677,5 +740,205 @@ test("handleWebFinger() records webfinger.handle counter and duration", async (t
677
740
  assertEquals(recorder.getMeasurements("webfinger.handle.duration").length, 0);
678
741
  });
679
742
  });
743
+ test("handleWebFinger() for FEP-ef61 portable actors", async (t) => {
744
+ const did = "did:key:z6Mkabc";
745
+ const compatibleId = `https://example.com/.well-known/apgateway/${did}/actor`;
746
+ const gateways = {
747
+ alice: [new URL("https://example.com")],
748
+ secondary: [new URL("https://primary.example"), new URL("https://example.com")],
749
+ anonymous: [new URL("https://example.com")],
750
+ nogateway: []
751
+ };
752
+ const actorDispatcher = (_ctx, identifier) => {
753
+ if (!(identifier in gateways)) return null;
754
+ return new Person({
755
+ id: parseIri(`ap://${did}/actor`),
756
+ preferredUsername: identifier === "anonymous" ? null : "alice",
757
+ gateways: gateways[identifier]
758
+ });
759
+ };
760
+ const actorAliasMapper = (_ctx, resource) => {
761
+ if (resource.href === compatibleId) return { identifier: "alice" };
762
+ if (resource.protocol === "ap+ef61:") return { identifier: "anonymous" };
763
+ if (resource.href === "acct:anonymous") return { identifier: "anonymous" };
764
+ return null;
765
+ };
766
+ async function query(resource, host = "example.com") {
767
+ const url = new URL(`https://${host}/.well-known/webfinger`);
768
+ url.searchParams.set("resource", resource);
769
+ const context = createRequestContext({
770
+ federation: createFederation({ kv: new MemoryKvStore() }),
771
+ url,
772
+ data: void 0,
773
+ getActorUri(identifier) {
774
+ return new URL(`${url.origin}/users/${identifier}`);
775
+ },
776
+ parseUri: () => null
777
+ });
778
+ return await handleWebFinger(context.request, {
779
+ context,
780
+ actorDispatcher,
781
+ actorAliasMapper,
782
+ onNotFound: () => new Response("Not found", { status: 404 })
783
+ });
784
+ }
785
+ const selfLink = {
786
+ rel: "self",
787
+ href: compatibleId,
788
+ type: "application/activity+json"
789
+ };
790
+ await t.step("acct: on the first gateway", async () => {
791
+ const response = await query("acct:alice@example.com");
792
+ assertEquals(response.status, 200);
793
+ assertEquals(await response.json(), {
794
+ subject: "acct:alice@example.com",
795
+ aliases: [compatibleId],
796
+ links: [selfLink]
797
+ });
798
+ });
799
+ await t.step("acct: on a secondary gateway", async () => {
800
+ const response = await query("acct:secondary@example.com");
801
+ assertEquals(response.status, 200);
802
+ const primaryCompatibleId = `https://primary.example/.well-known/apgateway/${did}/actor`;
803
+ assertEquals(await response.json(), {
804
+ subject: "acct:alice@primary.example",
805
+ aliases: [primaryCompatibleId, "acct:secondary@example.com"],
806
+ links: [{
807
+ ...selfLink,
808
+ href: primaryCompatibleId
809
+ }]
810
+ });
811
+ });
812
+ await t.step("compatible identifier", async () => {
813
+ const response = await query(compatibleId);
814
+ assertEquals(response.status, 200);
815
+ assertEquals(await response.json(), {
816
+ subject: "acct:alice@example.com",
817
+ aliases: [compatibleId],
818
+ links: [selfLink]
819
+ });
820
+ });
821
+ await t.step("portable ID without preferredUsername", async () => {
822
+ const response = await query(`ap://${did}/actor`);
823
+ assertEquals(response.status, 200);
824
+ assertEquals(await response.json(), {
825
+ subject: compatibleId,
826
+ aliases: [],
827
+ links: [selfLink]
828
+ });
829
+ });
830
+ await t.step("acct: without preferredUsername", async () => {
831
+ const response = await query("acct:anonymous@example.com");
832
+ assertEquals(response.status, 200);
833
+ assertEquals(await response.json(), {
834
+ subject: "acct:anonymous@example.com",
835
+ aliases: [compatibleId],
836
+ links: [selfLink]
837
+ });
838
+ });
839
+ await t.step("acct: without a host or preferredUsername", async () => {
840
+ const response = await query("acct:anonymous");
841
+ assertEquals(response.status, 200);
842
+ assertEquals(await response.json(), {
843
+ subject: "acct:anonymous",
844
+ aliases: [compatibleId],
845
+ links: [selfLink]
846
+ });
847
+ });
848
+ await t.step("no gateways", async () => {
849
+ assertEquals((await query("acct:nogateway@example.com")).status, 404);
850
+ });
851
+ await t.step("another host", async () => {
852
+ assertEquals((await query("acct:alice@primary.example")).status, 404);
853
+ });
854
+ });
855
+ test("handleWebFinger() for FEP-ef61 compatible-ID actors", async (t) => {
856
+ const compatibleId = `https://example.com/.well-known/apgateway/did:key:z6Mkabc/actor`;
857
+ const actors = {
858
+ alice: {
859
+ id: compatibleId,
860
+ gateways: [new URL("https://example.com")]
861
+ },
862
+ secondary: {
863
+ id: compatibleId,
864
+ gateways: [new URL("https://primary.example"), new URL("https://example.com")]
865
+ },
866
+ malformed: {
867
+ id: `${compatibleId}?@gateway=https%3A%2F%2Fexample.com`,
868
+ gateways: [new URL("https://example.com")]
869
+ },
870
+ nogateway: {
871
+ id: compatibleId,
872
+ gateways: []
873
+ }
874
+ };
875
+ const actorDispatcher = (_ctx, identifier) => {
876
+ const actor = actors[identifier];
877
+ if (actor == null) return null;
878
+ return new Person({
879
+ id: new URL(actor.id),
880
+ preferredUsername: "alice",
881
+ gateways: actor.gateways
882
+ });
883
+ };
884
+ const actorAliasMapper = (_ctx, resource) => resource.href === compatibleId ? { identifier: "alice" } : null;
885
+ async function query(resource) {
886
+ const url = new URL("https://example.com/.well-known/webfinger");
887
+ url.searchParams.set("resource", resource);
888
+ const context = createRequestContext({
889
+ federation: createFederation({ kv: new MemoryKvStore() }),
890
+ url,
891
+ data: void 0,
892
+ getActorUri(identifier) {
893
+ return new URL(`${url.origin}/users/${identifier}`);
894
+ },
895
+ parseUri: () => null
896
+ });
897
+ return await handleWebFinger(context.request, {
898
+ context,
899
+ actorDispatcher,
900
+ actorAliasMapper,
901
+ onNotFound: () => new Response("Not found", { status: 404 })
902
+ });
903
+ }
904
+ const selfLink = {
905
+ rel: "self",
906
+ href: compatibleId,
907
+ type: "application/activity+json"
908
+ };
909
+ await t.step("acct: on the first gateway", async () => {
910
+ const response = await query("acct:alice@example.com");
911
+ assertEquals(response.status, 200);
912
+ assertEquals(await response.json(), {
913
+ subject: "acct:alice@example.com",
914
+ aliases: [compatibleId],
915
+ links: [selfLink]
916
+ });
917
+ });
918
+ await t.step("compatible identifier", async () => {
919
+ const response = await query(compatibleId);
920
+ assertEquals(response.status, 200);
921
+ assertEquals(await response.json(), {
922
+ subject: "acct:alice@example.com",
923
+ aliases: [compatibleId],
924
+ links: [selfLink]
925
+ });
926
+ });
927
+ await t.step("compatible identifier not on the first gateway", async () => {
928
+ const response = await query("acct:secondary@example.com");
929
+ assertEquals(response.status, 200);
930
+ assertEquals(await response.json(), {
931
+ subject: "acct:alice@primary.example",
932
+ aliases: [compatibleId, "acct:secondary@example.com"],
933
+ links: [selfLink]
934
+ });
935
+ });
936
+ await t.step("malformed compatible identifier", async () => {
937
+ assertEquals((await query("acct:malformed@example.com")).status, 404);
938
+ });
939
+ await t.step("no gateways", async () => {
940
+ assertEquals((await query("acct:nogateway@example.com")).status, 404);
941
+ });
942
+ });
680
943
  //#endregion
681
944
  export {};