@fedify/fedify 2.4.0-pr.934.40 → 2.4.0

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 +48 -40
  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-BBPwtB2v.mjs → builder-lJDh222H.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-zAjqsHiN.mjs +989 -0
  30. package/dist/{context-Cjnr0ig1.d.ts → context-7NyiqIcg.d.ts} +1600 -25
  31. package/dist/{context-BJXxPElm.mjs → context-8Tu9kea0.mjs} +21 -63
  32. package/dist/{context-C05Rgxmu.d.cts → context-tsYPJ2Ew.d.cts} +1600 -25
  33. package/dist/{deno-D3c0o_N0.mjs → deno-D8wr4ikF.mjs} +1 -1
  34. package/dist/dist-DJQM4u7i.mjs +189 -0
  35. package/dist/docloader-TCvsU9vF.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 +387 -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 -540
  58. package/dist/federation/mod.d.cts +5 -5
  59. package/dist/federation/mod.d.ts +5 -5
  60. package/dist/federation/mod.js +1 -1
  61. package/dist/federation/mq.test.mjs +104 -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 +5 -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-BW7WQltk.cjs → federation-Dfl-i7Jt.cjs} +6098 -895
  92. package/dist/{http-Dm0JAUa_.mjs → http-BAgKAAGY.mjs} +397 -168
  93. package/dist/http-CYO4wjB5.cjs +10630 -0
  94. package/dist/http-RW_i_Nkq.js +6527 -0
  95. package/dist/key-C1nv7_jD.d.ts +1125 -0
  96. package/dist/key-D979vduq.mjs +951 -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-BxUZRBC2.js → kv-cache-Cqfdytdd.js} +54 -16
  104. package/dist/{kv-cache-B7H7lZ84.mjs → kv-cache-Gh05Xv-P.mjs} +1 -1
  105. package/dist/{kv-cache-D-hbjJAD.cjs → kv-cache-zd0dNGxi.cjs} +55 -19
  106. package/dist/{ld-DAPAVL_7.mjs → ld-wmqC-95l.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-BMaatuZi.mjs → metrics-DPdi_XK7.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-O2LHXFEk.mjs → middleware-CqQ5Qahj.mjs} +3155 -269
  113. package/dist/{middleware-CfZR_riY.js → middleware-DbCI_eni.js} +5527 -865
  114. package/dist/{middleware-DfPBAh9L.mjs → middleware-DjEMIAP5.mjs} +1 -1
  115. package/dist/{mod-DdONo-ep.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-CNef4in0.d.ts → mod-DEZXwV6J.d.ts} +9 -3
  119. package/dist/{mod-BrpVsSfY.d.cts → mod-Dw-nPxQh.d.cts} +9 -3
  120. package/dist/{mod-BsCE5Ihq.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 +8 -8
  125. package/dist/nodeinfo/client.test.mjs +139 -4
  126. package/dist/nodeinfo/handler.test.mjs +5 -5
  127. package/dist/nodeinfo/mod.cjs +1 -1
  128. package/dist/nodeinfo/mod.d.cts +1 -1
  129. package/dist/nodeinfo/mod.d.ts +1 -1
  130. package/dist/nodeinfo/mod.js +1 -1
  131. package/dist/nodeinfo/types.test.mjs +4 -4
  132. package/dist/otel/exporter.test.mjs +3 -3
  133. package/dist/otel/mod.cjs +0 -1
  134. package/dist/otel/mod.d.cts +1 -1
  135. package/dist/otel/mod.d.ts +1 -1
  136. package/dist/{outgoing-jsonld-URuqsICz.mjs → outgoing-jsonld-4IJqPYos.mjs} +12 -10
  137. package/dist/{owner-DEvZuyOE.d.cts → owner-BF0L9cMt.d.cts} +11 -0
  138. package/dist/{owner-CnngXDNJ.d.ts → owner-BSzr5-I8.d.ts} +11 -0
  139. package/dist/owner-BfygwLNy.mjs +267 -0
  140. package/dist/portable-collection-DSrR0BSV.js +670 -0
  141. package/dist/portable-collection-L8jCHlci.cjs +686 -0
  142. package/dist/portable-collection-idA006Sj.mjs +418 -0
  143. package/dist/portable-key-CA6u-dST.mjs +549 -0
  144. package/dist/portable-key-id-Ca30-hOa.mjs +248 -0
  145. package/dist/proof-DeC9pb6t.mjs +1299 -0
  146. package/dist/{public-audience-Cr5MsnMq.mjs → public-audience--klBIOk1.mjs} +15 -10
  147. package/dist/router-u5O5KCQr.mjs +156 -0
  148. package/dist/runtime/mod.cjs +1 -1
  149. package/dist/runtime/mod.js +1 -1
  150. package/dist/secured-document-CxzZZ9nL.mjs +35 -0
  151. package/dist/send-1tcGhW1h.mjs +495 -0
  152. package/dist/sig/accept.test.mjs +1 -1
  153. package/dist/sig/compound-proof-discovery.test.d.mts +2 -0
  154. package/dist/sig/compound-proof-discovery.test.mjs +331 -0
  155. package/dist/sig/compound-proof-producer.test.d.mts +2 -0
  156. package/dist/sig/compound-proof-producer.test.mjs +107 -0
  157. package/dist/sig/compound-proof-verification.test.d.mts +2 -0
  158. package/dist/sig/compound-proof-verification.test.mjs +833 -0
  159. package/dist/sig/compound-proof.test.d.mts +2 -0
  160. package/dist/sig/compound-proof.test.mjs +411 -0
  161. package/dist/sig/http.test.mjs +702 -31
  162. package/dist/sig/key-owner-evidence.test.d.mts +2 -0
  163. package/dist/sig/key-owner-evidence.test.mjs +100 -0
  164. package/dist/sig/key.test.mjs +220 -8
  165. package/dist/sig/ld.test.mjs +65 -7
  166. package/dist/sig/mitra-receive-interop.test.d.mts +2 -0
  167. package/dist/sig/mitra-receive-interop.test.mjs +260 -0
  168. package/dist/sig/mitra-send-interop.test.d.mts +2 -0
  169. package/dist/sig/mitra-send-interop.test.mjs +461 -0
  170. package/dist/sig/mod.cjs +18 -16
  171. package/dist/sig/mod.d.cts +4 -4
  172. package/dist/sig/mod.d.ts +4 -4
  173. package/dist/sig/mod.js +3 -3
  174. package/dist/sig/owner.test.mjs +108 -9
  175. package/dist/sig/portable-collection.test.d.mts +2 -0
  176. package/dist/sig/portable-collection.test.mjs +697 -0
  177. package/dist/sig/portable-interop.test.d.mts +2 -0
  178. package/dist/sig/portable-interop.test.mjs +156 -0
  179. package/dist/sig/portable-key-id.test.d.mts +2 -0
  180. package/dist/sig/portable-key-id.test.mjs +67 -0
  181. package/dist/sig/portable-key.test.d.mts +2 -0
  182. package/dist/sig/portable-key.test.mjs +1439 -0
  183. package/dist/sig/proof.test.mjs +1753 -16
  184. package/dist/sig/tootik-request-interop.test.d.mts +2 -0
  185. package/dist/sig/tootik-request-interop.test.mjs +190 -0
  186. package/dist/sig/tootik-send-interop.test.d.mts +2 -0
  187. package/dist/sig/tootik-send-interop.test.mjs +331 -0
  188. package/dist/sig/verification.test.d.mts +2 -0
  189. package/dist/sig/verification.test.mjs +310 -0
  190. package/dist/std__assert-DvMDRPes.mjs +8 -0
  191. package/dist/{testing-CO7ftO8A.mjs → tasks-IG3pHfvZ.mjs} +2 -2
  192. package/dist/{temporal-yE5EcfNX.mjs → temporal-DA7r1fm3.mjs} +3 -3
  193. package/dist/testing/context.test.d.mts +2 -0
  194. package/dist/testing/context.test.mjs +19 -0
  195. package/dist/testing/kv.test.d.mts +2 -0
  196. package/dist/testing/kv.test.mjs +101 -0
  197. package/dist/testing/mod.d.mts +1604 -48
  198. package/dist/testing/mod.mjs +6 -3
  199. package/dist/testing-t8xDeJZ5.mjs +8 -0
  200. package/dist/{transformers-DGwl-hD1.cjs → transformers-BalCrSsr.cjs} +0 -1
  201. package/dist/{types-DC1pNgJA.js → types-_S2_MeLF.js} +144 -8
  202. package/dist/{types-CPym83zc.cjs → types-poIao40f.cjs} +160 -7
  203. package/dist/utils/docloader.test.mjs +530 -8
  204. package/dist/utils/kv-cache.test.mjs +2 -2
  205. package/dist/utils/mod.cjs +1 -1
  206. package/dist/utils/mod.d.cts +1 -1
  207. package/dist/utils/mod.d.ts +1 -1
  208. package/dist/utils/mod.js +1 -1
  209. package/dist/verification-C3954hQh.mjs +5 -0
  210. package/dist/verification-Dpfcw8ml.mjs +105 -0
  211. package/dist/vocab/cjs.test.mjs +1 -1
  212. package/package.json +9 -9
  213. package/dist/assert_rejects-EgstcQy5.mjs +0 -82
  214. package/dist/docloader-BCecHIxU.mjs +0 -49
  215. package/dist/http-Ctb_KhZ8.js +0 -2483
  216. package/dist/http-VyDTd4G3.d.cts +0 -553
  217. package/dist/http-jr0TkgZe.cjs +0 -2694
  218. package/dist/http-lf8Hsd91.d.ts +0 -553
  219. package/dist/key-C_gNKtxm.mjs +0 -453
  220. package/dist/keycache-_DHqz5z_.mjs +0 -97
  221. package/dist/metrics-DN13mCAw.d.cts +0 -294
  222. package/dist/metrics-v_e0n5GQ.d.ts +0 -294
  223. package/dist/mod-B0hW12_O.d.cts +0 -307
  224. package/dist/mod-COIAjwRS.d.ts +0 -307
  225. package/dist/owner-Dcx-czqn.mjs +0 -120
  226. package/dist/proof-BkAxvrjt.mjs +0 -316
  227. package/dist/proof-D-H_PnJW.js +0 -1415
  228. package/dist/proof-NY0D8Oux.cjs +0 -1562
  229. package/dist/send-D_j7E-oC.mjs +0 -239
  230. package/dist/std__assert-B2NnY9bq.mjs +0 -79
  231. package/dist/temporal-polyfill-BCdTHexd.cjs +0 -3565
  232. /package/dist/{accept-8PiolDP7.mjs → accept-CPVqki78.mjs} +0 -0
  233. /package/dist/{activity-listener-BtTSxZWA.mjs → activity-listener-C-BSbKI7.mjs} +0 -0
  234. /package/dist/{client-CAM_bQXx.d.cts → client-D-XP_Ccb.d.cts} +0 -0
  235. /package/dist/{client-CSddvgWN.d.ts → client-D-XP_Ccb.d.ts} +0 -0
  236. /package/dist/{keys-Dbyd7bhl.mjs → keys-DIJNHW-Y.mjs} +0 -0
  237. /package/dist/{kv-CXBAok3k.mjs → kv-DCHkaJ9-.mjs} +0 -0
  238. /package/dist/{mq-Bo7Etgh6.mjs → mq-Dm1Wmtm-.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,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-O2LHXFEk.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-CqQ5Qahj.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 {};