@fedify/fedify 1.10.5 → 1.10.7
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.
- package/dist/{actor-CjkHF7Cj.cjs → actor-BGIAXtRd.cjs} +3112 -4674
- package/dist/{actor-Ch9BTg3N.js → actor-C-_2S5Mn.mjs} +8 -15
- package/dist/{actor-CQdxP8N-.js → actor-Cujbx4Zv.js} +1205 -2768
- package/dist/{actor-eeONG_sv.d.ts → actor-DXwwgFeR.d.ts} +3 -3
- package/dist/{actor-D190nbTD.d.cts → actor-DxvGbmjm.d.cts} +3 -3
- package/dist/{assert-MZs1qjMx.js → assert-DikXweDx.mjs} +5 -9
- package/dist/{assert_equals-DSbWqCm3.js → assert_equals-Ew3jOFa3.mjs} +55 -69
- package/dist/{assert_instance_of-DHz7EHNU.js → assert_instance_of-C4Ri6VuN.mjs} +5 -9
- package/dist/{assert_is_error-BPGph1Jx.js → assert_is_error-C50x8tnw.mjs} +5 -9
- package/dist/{assert_not_equals-f3m3epl3.js → assert_not_equals--wG9hV7u.mjs} +6 -13
- package/dist/{assert_rejects-DiIiJbZn.js → assert_rejects-CJC9ThS-.mjs} +6 -11
- package/dist/{assert_throws-BOO88avQ.js → assert_throws-BIL7gChy.mjs} +6 -10
- package/dist/{authdocloader-fR-Fqcpa.js → authdocloader-1Sk2bqFx.mjs} +9 -14
- package/dist/{authdocloader-COFZT9Wh.js → authdocloader-D4Y6iyTF.js} +8 -15
- package/dist/{authdocloader-zc5ibOmU.cjs → authdocloader-DQfruCir.cjs} +14 -22
- package/dist/{builder-YD0q32nG.js → builder-CZbrDRl7.mjs} +31 -40
- package/dist/{client-B3mQJNO7.d.ts → client-D7t26_op.d.ts} +2 -2
- package/dist/{client-BgCucCG7.js → client-Dyb8MI3u.mjs} +11 -15
- package/dist/{client-n6L4GtQL.d.cts → client-yc0Z0P6Y.d.cts} +2 -2
- package/dist/{collection-CSzG2j1P.js → collection-BD6-SZ6O.mjs} +7 -12
- package/dist/compat/mod.cjs +5 -8
- package/dist/compat/mod.d.cts +78 -12
- package/dist/compat/mod.d.ts +78 -12
- package/dist/compat/mod.js +4 -8
- package/dist/compat/transformers.test.mjs +62 -0
- package/dist/{context-Cr5DIxq_.d.ts → context-C6n2yrj0.d.ts} +33 -26
- package/dist/{context-WJoO0SQs.d.cts → context-PfghnHYj.d.cts} +33 -26
- package/dist/{denokv-D0nfNQ1x.js → denokv-NJPMXyK0.mjs} +22 -11
- package/dist/{docloader-BucCRHZI.d.ts → docloader-D7k5A9JP.d.ts} +2 -7
- package/dist/{docloader-ChxNLZAA.d.cts → docloader-DbM94pGY.d.cts} +2 -7
- package/dist/{docloader-BETPdM09.js → docloader-Dtaju6oI.js} +18 -156
- package/dist/{docloader-irBWMSOZ.cjs → docloader-Q3DfzuUi.cjs} +116 -220
- package/dist/{esm-iGH0sRsE.js → esm-DOJg552-.mjs} +49 -85
- package/dist/federation/{builder.test.js → builder.test.mjs} +22 -41
- package/dist/federation/collection.test.d.mts +2 -0
- package/dist/federation/collection.test.mjs +21 -0
- package/dist/federation/handler.test.d.mts +2 -0
- package/dist/federation/{handler.test.js → handler.test.mjs} +29 -58
- package/dist/federation/idempotency.test.d.mts +2 -0
- package/dist/federation/{idempotency.test.js → idempotency.test.mjs} +29 -59
- package/dist/federation/inbox.test.d.mts +2 -0
- package/dist/federation/{inbox.test.js → inbox.test.mjs} +10 -15
- package/dist/federation/keycache.test.d.mts +2 -0
- package/dist/federation/{keycache.test.js → keycache.test.mjs} +13 -18
- package/dist/federation/kv.test.d.mts +2 -0
- package/dist/federation/{kv.test.js → kv.test.mjs} +12 -26
- package/dist/federation/middleware.test.d.mts +2 -0
- package/dist/federation/{middleware.test.js → middleware.test.mjs} +182 -197
- package/dist/federation/mod.cjs +245 -21
- package/dist/federation/mod.d.cts +4 -13
- package/dist/federation/mod.d.ts +4 -13
- package/dist/federation/mod.js +240 -18
- package/dist/federation/mq.test.d.mts +2 -0
- package/dist/federation/{mq.test.js → mq.test.mjs} +23 -38
- package/dist/federation/retry.test.d.mts +2 -0
- package/dist/federation/{retry.test.js → retry.test.mjs} +9 -14
- package/dist/federation/router.test.d.mts +2 -0
- package/dist/federation/{router.test.js → router.test.mjs} +12 -19
- package/dist/federation/send.test.d.mts +2 -0
- package/dist/federation/{send.test.js → send.test.mjs} +24 -34
- package/dist/{http-PgdBoDIj.js → http-BRwSVBn1.mjs} +16 -32
- package/dist/{http-DS9z_HzB.d.ts → http-BYXQvoZQ.d.ts} +5 -9
- package/dist/{http-C_1RU1U_.d.cts → http-CMzg-A9P.d.cts} +5 -9
- package/dist/{http-CQAqR_vx.cjs → http-DCrun8ql.cjs} +51 -68
- package/dist/{http-CxiIW4rD.js → http-DRnRwr3i.js} +17 -33
- package/dist/{inbox-DcDIqTbR.js → inbox-pD1nbb_5.mjs} +17 -25
- package/dist/key-Cmbps6xt.cjs +4 -0
- package/dist/{key-dNFkodH5.cjs → key-DEYIxAFs.cjs} +42 -50
- package/dist/key-DMO0TgTa.mjs +5 -0
- package/dist/{key-I-ibyaZH.js → key-DdL5Oc59.mjs} +12 -18
- package/dist/{key-Cg0kO4dA.js → key-vIzWPiil.js} +19 -19
- package/dist/{keycache-hSs_XFSb.js → keycache-BVR9f06Y.mjs} +6 -10
- package/dist/{keys-CElJez9H.js → keys-Co-0pK8a.mjs} +6 -10
- package/dist/{kv-DipCBaw2.d.ts → kv-C6UC8M9S.d.ts} +1 -1
- package/dist/{kv-BqEOXcZv.d.cts → kv-ClC9WJh5.d.cts} +1 -1
- package/dist/{kv-QzKcOQgP.js → kv-OuT2IU64.mjs} +6 -10
- package/dist/{ld-b16r91YS.js → ld-BFaDk5gX.mjs} +17 -31
- package/dist/{lookup-CySNcNcC.js → lookup-CMYXdjVH.mjs} +8 -17
- package/dist/{lookup-Bfq9Jpm0.cjs → lookup-CZGJqSjm.cjs} +16 -23
- package/dist/{lookup-CiSAeWJl.js → lookup-jlmCTRsO.js} +5 -11
- package/dist/middleware-BWlZ-wms.cjs +4 -0
- package/dist/{middleware-C5emnCh-.js → middleware-BXD5WJbj.mjs} +276 -321
- package/dist/{middleware-Dxo56yae.cjs → middleware-BhMQrJXH.cjs} +494 -547
- package/dist/{middleware-Bs4xDuXR.js → middleware-CmA2E9Bu.js} +349 -393
- package/dist/middleware-H3Ce7yn3.mjs +5 -0
- package/dist/{mod-D5rfgGFE.d.cts → mod-BQ3lrlXU.d.cts} +3 -3
- package/dist/{mod-Dz5Y15Uy.d.cts → mod-C72agZIN.d.cts} +4 -4
- package/dist/{mod-CxMBb_dd.d.cts → mod-CDbqB60V.d.cts} +2 -2
- package/dist/{mod-DS4kJskR.d.ts → mod-Lj0W1nnG.d.ts} +3 -3
- package/dist/{mod-BZfdiPBo.d.ts → mod-_HNKaczF.d.ts} +4 -4
- package/dist/{mod-ChbckRnC.d.ts → mod-lHd-Zdd_.d.ts} +2 -2
- package/dist/mod.cjs +31 -33
- package/dist/mod.d.cts +15 -17
- package/dist/mod.d.ts +15 -17
- package/dist/mod.js +20 -23
- package/dist/{mq-B7R1Q-M5.d.cts → mq-CrItclRD.d.cts} +1 -1
- package/dist/{mq-CRGm1e_F.d.ts → mq-D_ZZRdby.d.ts} +1 -1
- package/dist/nodeinfo/client.test.d.mts +2 -0
- package/dist/nodeinfo/{client.test.js → client.test.mjs} +23 -45
- package/dist/nodeinfo/handler.test.d.mts +2 -0
- package/dist/nodeinfo/{handler.test.js → handler.test.mjs} +14 -43
- package/dist/nodeinfo/mod.cjs +5 -9
- package/dist/nodeinfo/mod.d.cts +2 -5
- package/dist/nodeinfo/mod.d.ts +2 -5
- package/dist/nodeinfo/mod.js +4 -9
- package/dist/nodeinfo/semver.test.d.mts +2 -0
- package/dist/nodeinfo/{semver.test.js → semver.test.mjs} +28 -51
- package/dist/nodeinfo/types.test.d.mts +2 -0
- package/dist/nodeinfo/{types.test.js → types.test.mjs} +10 -21
- package/dist/otel/exporter.test.d.mts +2 -0
- package/dist/otel/{exporter.test.js → exporter.test.mjs} +122 -180
- package/dist/otel/mod.cjs +16 -22
- package/dist/otel/mod.d.cts +2 -2
- package/dist/otel/mod.d.ts +2 -2
- package/dist/otel/mod.js +9 -16
- package/dist/{otel-Chy5T2Xh.js → otel-0v4Zy01l.mjs} +5 -10
- package/dist/{owner-AcrG3Xz1.d.cts → owner-0yNTyGMb.d.cts} +4 -4
- package/dist/{owner-Bs-sPbHX.js → owner-CNdS8zxf.mjs} +11 -16
- package/dist/{owner-8NMhXwJd.d.ts → owner-CPEbNpnZ.d.ts} +4 -4
- package/dist/{proof-SgRikE_Y.js → proof-Co7YmDpv.mjs} +20 -32
- package/dist/{proof-flD2DeA-.js → proof-DHPbi_Mx.js} +34 -60
- package/dist/{proof-BvQS195q.cjs → proof-DcPdtve2.cjs} +115 -140
- package/dist/{retry-D4GJ670a.js → retry-Ddbq3AcK.mjs} +4 -7
- package/dist/rolldown-runtime-C7fyD9f2.js +15 -0
- package/dist/runtime/authdocloader.test.d.mts +2 -0
- package/dist/runtime/{authdocloader.test.js → authdocloader.test.mjs} +16 -28
- package/dist/runtime/docloader.test.d.mts +2 -0
- package/dist/runtime/{docloader.test.js → docloader.test.mjs} +55 -77
- package/dist/runtime/key.test.d.mts +2 -0
- package/dist/runtime/{key.test.js → key.test.mjs} +27 -57
- package/dist/runtime/langstr.test.d.mts +2 -0
- package/dist/runtime/{langstr.test.js → langstr.test.mjs} +9 -19
- package/dist/runtime/link.test.d.mts +2 -0
- package/dist/runtime/{link.test.js → link.test.mjs} +7 -11
- package/dist/runtime/mod.cjs +7 -13
- package/dist/runtime/mod.d.cts +103 -6
- package/dist/runtime/mod.d.ts +103 -6
- package/dist/runtime/mod.js +6 -13
- package/dist/runtime/multibase/multibase.test.d.mts +2 -0
- package/dist/runtime/multibase/{multibase.test.js → multibase.test.mjs} +16 -33
- package/dist/runtime/url.test.d.mts +2 -0
- package/dist/runtime/{url.test.js → url.test.mjs} +10 -15
- package/dist/{semver-dArNLkR9.js → semver-CgD82xxg.mjs} +13 -28
- package/dist/{send-C0gFHa2i.js → send-BRCWNcMa.mjs} +7 -12
- package/dist/sig/http.test.d.mts +2 -0
- package/dist/sig/{http.test.js → http.test.mjs} +119 -203
- package/dist/sig/key.test.d.mts +2 -0
- package/dist/sig/{key.test.js → key.test.mjs} +13 -22
- package/dist/sig/ld.test.d.mts +2 -0
- package/dist/sig/{ld.test.js → ld.test.mjs} +24 -39
- package/dist/sig/mod.cjs +7 -13
- package/dist/sig/mod.d.cts +3 -7
- package/dist/sig/mod.d.ts +3 -7
- package/dist/sig/mod.js +6 -13
- package/dist/sig/owner.test.d.mts +2 -0
- package/dist/sig/{owner.test.js → owner.test.mjs} +23 -39
- package/dist/sig/proof.test.d.mts +2 -0
- package/dist/sig/{proof.test.js → proof.test.mjs} +18 -31
- package/dist/{std__assert-X-_kMxKM.js → std__assert-2v7gYiZp.mjs} +13 -24
- package/dist/testing/docloader.test.d.mts +2 -0
- package/dist/testing/docloader.test.mjs +12 -0
- package/dist/testing/{mod.d.ts → mod.d.mts} +371 -541
- package/dist/testing/mod.mjs +5 -0
- package/dist/{testing-C1GIraJh.js → testing-BLIh1cXz.mjs} +27 -35
- package/dist/{transformers-BFT6d7J5.js → transformers-BV4OeK9o.js} +3 -7
- package/dist/{transformers-CoBS-oFG.cjs → transformers-CLtJ5H8o.cjs} +20 -25
- package/dist/{types-BgUCCngg.cjs → types-B34v-m2N.cjs} +45 -64
- package/dist/{types-BIgY6c-l.js → types-CAnkAQGM.mjs} +5 -9
- package/dist/{types-Bu-epI-z.js → types-CXZk86AG.js} +18 -36
- package/dist/vocab/actor.test.d.mts +2 -0
- package/dist/vocab/{actor.test.js → actor.test.mjs} +308 -550
- package/dist/vocab/cjs.test.d.mts +2 -0
- package/dist/vocab/cjs.test.mjs +14 -0
- package/dist/vocab/lookup.test.d.mts +2 -0
- package/dist/vocab/{lookup.test.js → lookup.test.mjs} +34 -51
- package/dist/vocab/mod.cjs +256 -16
- package/dist/vocab/mod.d.cts +3 -5
- package/dist/vocab/mod.d.ts +3 -5
- package/dist/vocab/mod.js +249 -10
- package/dist/vocab/type.test.d.mts +2 -0
- package/dist/vocab/type.test.mjs +16 -0
- package/dist/vocab/vocab.test.d.mts +2 -0
- package/dist/vocab/{vocab.test.js → vocab.test.mjs} +178 -311
- package/dist/{vocab-BASuuzcJ.d.ts → vocab-DaT4UsJF.d.ts} +2 -2
- package/dist/{vocab-DPMmFPJ1.d.cts → vocab-DnlmNyXi.d.cts} +2 -2
- package/dist/{type-DUhon7qK.js → vocab-rT_94Pke.mjs} +1178 -2876
- package/dist/webfinger/handler.test.d.mts +2 -0
- package/dist/webfinger/{handler.test.js → handler.test.mjs} +23 -56
- package/dist/webfinger/lookup.test.d.mts +2 -0
- package/dist/webfinger/{lookup.test.js → lookup.test.mjs} +13 -27
- package/dist/webfinger/mod.cjs +5 -9
- package/dist/webfinger/mod.d.cts +1 -3
- package/dist/webfinger/mod.d.ts +1 -3
- package/dist/webfinger/mod.js +4 -9
- package/dist/x/cfworkers.cjs +25 -14
- package/dist/x/cfworkers.d.cts +33 -6
- package/dist/x/cfworkers.d.ts +33 -6
- package/dist/x/cfworkers.js +22 -12
- package/dist/x/cfworkers.test.d.mts +2 -0
- package/dist/x/{cfworkers.test.js → cfworkers.test.mjs} +28 -26
- package/dist/x/hono.cjs +25 -14
- package/dist/x/hono.d.cts +1 -11
- package/dist/x/hono.d.ts +1 -11
- package/dist/x/hono.js +22 -12
- package/dist/x/sveltekit.cjs +23 -12
- package/dist/x/sveltekit.d.cts +1 -11
- package/dist/x/sveltekit.d.ts +1 -11
- package/dist/x/sveltekit.js +20 -10
- package/package.json +2 -2
- package/dist/chunk-DqRYRqnO.cjs +0 -34
- package/dist/compat/transformers.test.d.ts +0 -3
- package/dist/compat/transformers.test.js +0 -86
- package/dist/compat-DmDDELst.cjs +0 -4
- package/dist/compat-nxUqe4Z-.js +0 -4
- package/dist/federation/builder.test.d.ts +0 -3
- package/dist/federation/collection.test.d.ts +0 -3
- package/dist/federation/collection.test.js +0 -35
- package/dist/federation/handler.test.d.ts +0 -3
- package/dist/federation/idempotency.test.d.ts +0 -3
- package/dist/federation/inbox.test.d.ts +0 -3
- package/dist/federation/keycache.test.d.ts +0 -3
- package/dist/federation/kv.test.d.ts +0 -3
- package/dist/federation/middleware.test.d.ts +0 -3
- package/dist/federation/mq.test.d.ts +0 -3
- package/dist/federation/retry.test.d.ts +0 -3
- package/dist/federation/router.test.d.ts +0 -3
- package/dist/federation/send.test.d.ts +0 -3
- package/dist/federation-C15gGOh1.cjs +0 -266
- package/dist/federation-K-xsO03l.js +0 -248
- package/dist/key-Bnod5wJl.js +0 -10
- package/dist/key-C6swTX71.js +0 -10
- package/dist/key-_Uq8gkmM.cjs +0 -10
- package/dist/middleware-BWsOtDIF.cjs +0 -17
- package/dist/middleware-Bm4bJzjg.js +0 -26
- package/dist/middleware-BvODpE_U.js +0 -17
- package/dist/mod-C2tOeRkN.d.cts +0 -1
- package/dist/mod-CD7gfdq3.d.ts +0 -104
- package/dist/mod-CnULG6Aa.d.ts +0 -82
- package/dist/mod-FZd39qVq.d.cts +0 -1
- package/dist/mod-JUhOKMHj.d.cts +0 -102
- package/dist/mod-OQfb33eH.d.cts +0 -80
- package/dist/nodeinfo/client.test.d.ts +0 -3
- package/dist/nodeinfo/handler.test.d.ts +0 -3
- package/dist/nodeinfo/semver.test.d.ts +0 -3
- package/dist/nodeinfo/types.test.d.ts +0 -3
- package/dist/nodeinfo-Co9lJrWl.cjs +0 -4
- package/dist/nodeinfo-DfycQ8Wf.js +0 -4
- package/dist/otel/exporter.test.d.ts +0 -3
- package/dist/runtime/authdocloader.test.d.ts +0 -3
- package/dist/runtime/docloader.test.d.ts +0 -3
- package/dist/runtime/key.test.d.ts +0 -3
- package/dist/runtime/langstr.test.d.ts +0 -3
- package/dist/runtime/link.test.d.ts +0 -3
- package/dist/runtime/multibase/multibase.test.d.ts +0 -3
- package/dist/runtime/url.test.d.ts +0 -3
- package/dist/runtime-C58AJWSv.cjs +0 -4
- package/dist/runtime-DPYEDf-o.js +0 -4
- package/dist/sig/http.test.d.ts +0 -3
- package/dist/sig/key.test.d.ts +0 -3
- package/dist/sig/ld.test.d.ts +0 -3
- package/dist/sig/owner.test.d.ts +0 -3
- package/dist/sig/proof.test.d.ts +0 -3
- package/dist/sig-ByHXzqUi.cjs +0 -4
- package/dist/sig-Cj3tk-ig.js +0 -4
- package/dist/testing/docloader.test.d.ts +0 -3
- package/dist/testing/docloader.test.js +0 -24
- package/dist/testing/mod.js +0 -10
- package/dist/vocab/actor.test.d.ts +0 -3
- package/dist/vocab/lookup.test.d.ts +0 -3
- package/dist/vocab/type.test.d.ts +0 -3
- package/dist/vocab/type.test.js +0 -25
- package/dist/vocab/vocab.test.d.ts +0 -3
- package/dist/vocab-5i6DEIi6.cjs +0 -294
- package/dist/vocab-CBavAdew.js +0 -258
- package/dist/webfinger/handler.test.d.ts +0 -3
- package/dist/webfinger/lookup.test.d.ts +0 -3
- package/dist/webfinger-BjOEdFPs.cjs +0 -4
- package/dist/webfinger-De_bU0iE.js +0 -4
- package/dist/x/cfworkers.test.d.ts +0 -3
- /package/dist/{mod-1pDWKvUL.d.ts → compat/transformers.test.d.mts} +0 -0
- /package/dist/{mod-g0xFzAP9.d.ts → federation/builder.test.d.mts} +0 -0
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { lookupObject, traverseCollection } from "./vocab-CBavAdew.js";
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
import { t as __exportAll } from "./rolldown-runtime-C7fyD9f2.js";
|
|
4
|
+
import { r as getDefaultActivityTransformers } from "./transformers-BV4OeK9o.js";
|
|
5
|
+
import { d as name, f as version, i as getDocumentLoader, s as kvCache } from "./docloader-Dtaju6oI.js";
|
|
6
|
+
import { G as Multikey, Tt as getTypeId, V as Link, X as OrderedCollectionPage, Y as OrderedCollection, _ as CollectionPage, g as Collection, q as Object$1, s as Activity, y as CryptographicKey } from "./actor-Cujbx4Zv.js";
|
|
7
|
+
import { t as lookupWebFinger } from "./lookup-jlmCTRsO.js";
|
|
8
|
+
import { i as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-vIzWPiil.js";
|
|
9
|
+
import { r as verifyRequest, t as doubleKnock } from "./http-DRnRwr3i.js";
|
|
10
|
+
import { a as doesActorOwnKey, d as signJsonLd, f as verifyJsonLd, l as detachSignature, n as signObject, o as getKeyOwner, r as verifyObject, u as hasSignature } from "./proof-DHPbi_Mx.js";
|
|
11
|
+
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-CXZk86AG.js";
|
|
12
|
+
import { t as getAuthenticatedDocumentLoader } from "./authdocloader-D4Y6iyTF.js";
|
|
13
|
+
import { lookupObject, traverseCollection } from "./vocab/mod.js";
|
|
15
14
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
16
15
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
17
16
|
import { encodeHex } from "byte-encodings/hex";
|
|
@@ -20,7 +19,6 @@ import { Router } from "uri-template-router";
|
|
|
20
19
|
import { parseTemplate } from "url-template";
|
|
21
20
|
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";
|
|
22
21
|
import { domainToASCII } from "node:url";
|
|
23
|
-
|
|
24
22
|
//#region src/federation/inbox.ts
|
|
25
23
|
var InboxListenerSet = class InboxListenerSet {
|
|
26
24
|
#listeners;
|
|
@@ -57,7 +55,7 @@ var InboxListenerSet = class InboxListenerSet {
|
|
|
57
55
|
};
|
|
58
56
|
let warnedAboutDefaultIdempotency = false;
|
|
59
57
|
async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
|
|
60
|
-
const logger
|
|
58
|
+
const logger = getLogger([
|
|
61
59
|
"fedify",
|
|
62
60
|
"federation",
|
|
63
61
|
"inbox"
|
|
@@ -67,14 +65,12 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
67
65
|
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
|
|
68
66
|
const strategy = idempotencyStrategy ?? "per-origin";
|
|
69
67
|
if (idempotencyStrategy === void 0 && !warnedAboutDefaultIdempotency) {
|
|
70
|
-
logger
|
|
68
|
+
logger.warn("Using default idempotency strategy 'per-origin'. This default will change to 'per-inbox' in Fedify 2.0. Please explicitly set the idempotency strategy using .withIdempotency().");
|
|
71
69
|
warnedAboutDefaultIdempotency = true;
|
|
72
70
|
}
|
|
73
71
|
let keyString;
|
|
74
|
-
if (typeof strategy === "function")
|
|
75
|
-
|
|
76
|
-
keyString = result;
|
|
77
|
-
} else switch (strategy) {
|
|
72
|
+
if (typeof strategy === "function") keyString = await strategy(inboxContext, activity);
|
|
73
|
+
else switch (strategy) {
|
|
78
74
|
case "global":
|
|
79
75
|
keyString = activity.id.href;
|
|
80
76
|
break;
|
|
@@ -89,9 +85,8 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
89
85
|
if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
|
|
90
86
|
}
|
|
91
87
|
if (cacheKey != null) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
logger$1.debug("Activity {activityId} has already been processed.", {
|
|
88
|
+
if (await kv.get(cacheKey) === true) {
|
|
89
|
+
logger.debug("Activity {activityId} has already been processed.", {
|
|
95
90
|
activityId: activity.id?.href,
|
|
96
91
|
activity: json,
|
|
97
92
|
recipient
|
|
@@ -104,7 +99,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
104
99
|
}
|
|
105
100
|
}
|
|
106
101
|
if (activity.actorId == null) {
|
|
107
|
-
logger
|
|
102
|
+
logger.error("Missing actor.", { activity: json });
|
|
108
103
|
span.setStatus({
|
|
109
104
|
code: SpanStatusCode.ERROR,
|
|
110
105
|
message: "Missing actor."
|
|
@@ -127,7 +122,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
127
122
|
traceContext: carrier
|
|
128
123
|
});
|
|
129
124
|
} catch (error) {
|
|
130
|
-
logger
|
|
125
|
+
logger.error("Failed to enqueue the incoming activity {activityId}:\n{error}", {
|
|
131
126
|
error,
|
|
132
127
|
activityId: activity.id?.href,
|
|
133
128
|
activity: json,
|
|
@@ -139,7 +134,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
139
134
|
});
|
|
140
135
|
throw error;
|
|
141
136
|
}
|
|
142
|
-
logger
|
|
137
|
+
logger.info("Activity {activityId} is enqueued.", {
|
|
143
138
|
activityId: activity.id?.href,
|
|
144
139
|
activity: json,
|
|
145
140
|
recipient
|
|
@@ -147,60 +142,58 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
147
142
|
return "enqueued";
|
|
148
143
|
}
|
|
149
144
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
150
|
-
|
|
151
|
-
return await tracer.startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span$1) => {
|
|
145
|
+
return await tracerProvider.getTracer(name, version).startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
|
|
152
146
|
const dispatched = inboxListeners?.dispatchWithClass(activity);
|
|
153
147
|
if (dispatched == null) {
|
|
154
|
-
logger
|
|
148
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
155
149
|
activity: json,
|
|
156
150
|
recipient
|
|
157
151
|
});
|
|
158
|
-
span
|
|
152
|
+
span.setStatus({
|
|
159
153
|
code: SpanStatusCode.UNSET,
|
|
160
154
|
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
161
155
|
});
|
|
162
|
-
span
|
|
156
|
+
span.end();
|
|
163
157
|
return "unsupportedActivity";
|
|
164
158
|
}
|
|
165
159
|
const { class: cls, listener } = dispatched;
|
|
166
|
-
span
|
|
160
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
167
161
|
try {
|
|
168
162
|
await listener(inboxContextFactory(recipient, json, activity?.id?.href, getTypeId(activity).href), activity);
|
|
169
163
|
} catch (error) {
|
|
170
164
|
try {
|
|
171
165
|
await inboxErrorHandler?.(ctx, error);
|
|
172
|
-
} catch (error
|
|
173
|
-
logger
|
|
174
|
-
error
|
|
166
|
+
} catch (error) {
|
|
167
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
168
|
+
error,
|
|
175
169
|
activityId: activity.id?.href,
|
|
176
170
|
activity: json,
|
|
177
171
|
recipient
|
|
178
172
|
});
|
|
179
173
|
}
|
|
180
|
-
logger
|
|
174
|
+
logger.error("Failed to process the incoming activity {activityId}:\n{error}", {
|
|
181
175
|
error,
|
|
182
176
|
activityId: activity.id?.href,
|
|
183
177
|
activity: json,
|
|
184
178
|
recipient
|
|
185
179
|
});
|
|
186
|
-
span
|
|
180
|
+
span.setStatus({
|
|
187
181
|
code: SpanStatusCode.ERROR,
|
|
188
182
|
message: String(error)
|
|
189
183
|
});
|
|
190
|
-
span
|
|
184
|
+
span.end();
|
|
191
185
|
return "error";
|
|
192
186
|
}
|
|
193
187
|
if (cacheKey != null) await kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
194
|
-
logger
|
|
188
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
195
189
|
activityId: activity.id?.href,
|
|
196
190
|
activity: json,
|
|
197
191
|
recipient
|
|
198
192
|
});
|
|
199
|
-
span
|
|
193
|
+
span.end();
|
|
200
194
|
return "success";
|
|
201
195
|
});
|
|
202
196
|
}
|
|
203
|
-
|
|
204
197
|
//#endregion
|
|
205
198
|
//#region src/federation/router.ts
|
|
206
199
|
function cloneInnerRouter(router) {
|
|
@@ -308,7 +301,6 @@ var RouterError = class extends Error {
|
|
|
308
301
|
this.name = "RouterError";
|
|
309
302
|
}
|
|
310
303
|
};
|
|
311
|
-
|
|
312
304
|
//#endregion
|
|
313
305
|
//#region src/federation/builder.ts
|
|
314
306
|
var FederationBuilderImpl = class {
|
|
@@ -344,8 +336,8 @@ var FederationBuilderImpl = class {
|
|
|
344
336
|
this.collectionTypeIds = {};
|
|
345
337
|
}
|
|
346
338
|
async build(options) {
|
|
347
|
-
const { FederationImpl
|
|
348
|
-
const f = new FederationImpl
|
|
339
|
+
const { FederationImpl } = await Promise.resolve().then(() => middleware_exports);
|
|
340
|
+
const f = new FederationImpl(options);
|
|
349
341
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
350
342
|
f.router = this.router.clone();
|
|
351
343
|
f.router.trailingSlashInsensitive = trailingSlashInsensitiveValue;
|
|
@@ -370,7 +362,7 @@ var FederationBuilderImpl = class {
|
|
|
370
362
|
return f;
|
|
371
363
|
}
|
|
372
364
|
_getTracer() {
|
|
373
|
-
return trace.getTracer(
|
|
365
|
+
return trace.getTracer(name, version);
|
|
374
366
|
}
|
|
375
367
|
setActorDispatcher(path, dispatcher) {
|
|
376
368
|
if (this.router.has("actor")) throw new RouterError("Actor dispatcher already set.");
|
|
@@ -381,17 +373,17 @@ var FederationBuilderImpl = class {
|
|
|
381
373
|
"federation",
|
|
382
374
|
"actor"
|
|
383
375
|
]).warn("The {{handle}} variable in the actor dispatcher path is deprecated. Use {{identifier}} instead.");
|
|
384
|
-
const callbacks = { dispatcher: async (context
|
|
376
|
+
const callbacks = { dispatcher: async (context, identifier) => {
|
|
385
377
|
const actor = await this._getTracer().startActiveSpan("activitypub.dispatch_actor", {
|
|
386
378
|
kind: SpanKind.SERVER,
|
|
387
379
|
attributes: { "fedify.actor.identifier": identifier }
|
|
388
380
|
}, async (span) => {
|
|
389
381
|
try {
|
|
390
|
-
const actor
|
|
391
|
-
span.setAttribute("activitypub.actor.id", (actor
|
|
392
|
-
if (actor
|
|
393
|
-
else span.setAttribute("activitypub.actor.type", getTypeId(actor
|
|
394
|
-
return actor
|
|
382
|
+
const actor = await dispatcher(context, identifier);
|
|
383
|
+
span.setAttribute("activitypub.actor.id", (actor?.id ?? context.getActorUri(identifier)).href);
|
|
384
|
+
if (actor == null) span.setStatus({ code: SpanStatusCode.ERROR });
|
|
385
|
+
else span.setAttribute("activitypub.actor.type", getTypeId(actor).href);
|
|
386
|
+
return actor;
|
|
395
387
|
} catch (error) {
|
|
396
388
|
span.setStatus({
|
|
397
389
|
code: SpanStatusCode.ERROR,
|
|
@@ -403,52 +395,52 @@ var FederationBuilderImpl = class {
|
|
|
403
395
|
}
|
|
404
396
|
});
|
|
405
397
|
if (actor == null) return null;
|
|
406
|
-
const logger
|
|
398
|
+
const logger = getLogger([
|
|
407
399
|
"fedify",
|
|
408
400
|
"federation",
|
|
409
401
|
"actor"
|
|
410
402
|
]);
|
|
411
|
-
if (actor.id == null) logger
|
|
412
|
-
else if (actor.id.href != context
|
|
403
|
+
if (actor.id == null) logger.warn("Actor dispatcher returned an actor without an id property. Set the property with Context.getActorUri(identifier).");
|
|
404
|
+
else if (actor.id.href != context.getActorUri(identifier).href) logger.warn("Actor dispatcher returned an actor with an id property that does not match the actor URI. Set the property with Context.getActorUri(identifier).");
|
|
413
405
|
if (this.followingCallbacks != null && this.followingCallbacks.dispatcher != null) {
|
|
414
|
-
if (actor.followingId == null) logger
|
|
415
|
-
else if (actor.followingId.href != context
|
|
406
|
+
if (actor.followingId == null) logger.warn("You configured a following collection dispatcher, but the actor does not have a following property. Set the property with Context.getFollowingUri(identifier).");
|
|
407
|
+
else if (actor.followingId.href != context.getFollowingUri(identifier).href) logger.warn("You configured a following collection dispatcher, but the actor's following property does not match the following collection URI. Set the property with Context.getFollowingUri(identifier).");
|
|
416
408
|
}
|
|
417
409
|
if (this.followersCallbacks != null && this.followersCallbacks.dispatcher != null) {
|
|
418
|
-
if (actor.followersId == null) logger
|
|
419
|
-
else if (actor.followersId.href != context
|
|
410
|
+
if (actor.followersId == null) logger.warn("You configured a followers collection dispatcher, but the actor does not have a followers property. Set the property with Context.getFollowersUri(identifier).");
|
|
411
|
+
else if (actor.followersId.href != context.getFollowersUri(identifier).href) logger.warn("You configured a followers collection dispatcher, but the actor's followers property does not match the followers collection URI. Set the property with Context.getFollowersUri(identifier).");
|
|
420
412
|
}
|
|
421
413
|
if (this.outboxCallbacks != null && this.outboxCallbacks.dispatcher != null) {
|
|
422
|
-
if (actor?.outboxId == null) logger
|
|
423
|
-
else if (actor.outboxId.href != context
|
|
414
|
+
if (actor?.outboxId == null) logger.warn("You configured an outbox collection dispatcher, but the actor does not have an outbox property. Set the property with Context.getOutboxUri(identifier).");
|
|
415
|
+
else if (actor.outboxId.href != context.getOutboxUri(identifier).href) logger.warn("You configured an outbox collection dispatcher, but the actor's outbox property does not match the outbox collection URI. Set the property with Context.getOutboxUri(identifier).");
|
|
424
416
|
}
|
|
425
417
|
if (this.likedCallbacks != null && this.likedCallbacks.dispatcher != null) {
|
|
426
|
-
if (actor?.likedId == null) logger
|
|
427
|
-
else if (actor.likedId.href != context
|
|
418
|
+
if (actor?.likedId == null) logger.warn("You configured a liked collection dispatcher, but the actor does not have a liked property. Set the property with Context.getLikedUri(identifier).");
|
|
419
|
+
else if (actor.likedId.href != context.getLikedUri(identifier).href) logger.warn("You configured a liked collection dispatcher, but the actor's liked property does not match the liked collection URI. Set the property with Context.getLikedUri(identifier).");
|
|
428
420
|
}
|
|
429
421
|
if (this.featuredCallbacks != null && this.featuredCallbacks.dispatcher != null) {
|
|
430
|
-
if (actor?.featuredId == null) logger
|
|
431
|
-
else if (actor.featuredId.href != context
|
|
422
|
+
if (actor?.featuredId == null) logger.warn("You configured a featured collection dispatcher, but the actor does not have a featured property. Set the property with Context.getFeaturedUri(identifier).");
|
|
423
|
+
else if (actor.featuredId.href != context.getFeaturedUri(identifier).href) logger.warn("You configured a featured collection dispatcher, but the actor's featured property does not match the featured collection URI. Set the property with Context.getFeaturedUri(identifier).");
|
|
432
424
|
}
|
|
433
425
|
if (this.featuredTagsCallbacks != null && this.featuredTagsCallbacks.dispatcher != null) {
|
|
434
|
-
if (actor?.featuredTagsId == null) logger
|
|
435
|
-
else if (actor.featuredTagsId.href != context
|
|
426
|
+
if (actor?.featuredTagsId == null) logger.warn("You configured a featured tags collection dispatcher, but the actor does not have a featuredTags property. Set the property with Context.getFeaturedTagsUri(identifier).");
|
|
427
|
+
else if (actor.featuredTagsId.href != context.getFeaturedTagsUri(identifier).href) logger.warn("You configured a featured tags collection dispatcher, but the actor's featuredTags property does not match the featured tags collection URI. Set the property with Context.getFeaturedTagsUri(identifier).");
|
|
436
428
|
}
|
|
437
429
|
if (this.router.has("inbox")) {
|
|
438
|
-
if (actor.inboxId == null) logger
|
|
439
|
-
else if (actor.inboxId.href != context
|
|
440
|
-
if (actor.endpoints == null || actor.endpoints.sharedInbox == null) logger
|
|
441
|
-
else if (actor.endpoints.sharedInbox.href != context
|
|
430
|
+
if (actor.inboxId == null) logger.warn("You configured inbox listeners, but the actor does not have an inbox property. Set the property with Context.getInboxUri(identifier).");
|
|
431
|
+
else if (actor.inboxId.href != context.getInboxUri(identifier).href) logger.warn("You configured inbox listeners, but the actor's inbox property does not match the inbox URI. Set the property with Context.getInboxUri(identifier).");
|
|
432
|
+
if (actor.endpoints == null || actor.endpoints.sharedInbox == null) logger.warn("You configured inbox listeners, but the actor does not have a endpoints.sharedInbox property. Set the property with Context.getInboxUri().");
|
|
433
|
+
else if (actor.endpoints.sharedInbox.href != context.getInboxUri().href) logger.warn("You configured inbox listeners, but the actor's endpoints.sharedInbox property does not match the shared inbox URI. Set the property with Context.getInboxUri().");
|
|
442
434
|
}
|
|
443
435
|
if (callbacks.keyPairsDispatcher != null) {
|
|
444
|
-
if (actor.publicKeyId == null) logger
|
|
445
|
-
if (actor.assertionMethodId == null) logger
|
|
436
|
+
if (actor.publicKeyId == null) logger.warn("You configured a key pairs dispatcher, but the actor does not have a publicKey property. Set the property with Context.getActorKeyPairs(identifier).");
|
|
437
|
+
if (actor.assertionMethodId == null) logger.warn("You configured a key pairs dispatcher, but the actor does not have an assertionMethod property. Set the property with Context.getActorKeyPairs(identifier).");
|
|
446
438
|
}
|
|
447
439
|
return actor;
|
|
448
440
|
} };
|
|
449
441
|
this.actorCallbacks = callbacks;
|
|
450
442
|
const setters = {
|
|
451
|
-
setKeyPairsDispatcher: (dispatcher
|
|
443
|
+
setKeyPairsDispatcher: (dispatcher) => {
|
|
452
444
|
callbacks.keyPairsDispatcher = (ctx, identifier) => this._getTracer().startActiveSpan("activitypub.dispatch_actor_key_pairs", {
|
|
453
445
|
kind: SpanKind.SERVER,
|
|
454
446
|
attributes: {
|
|
@@ -457,7 +449,7 @@ var FederationBuilderImpl = class {
|
|
|
457
449
|
}
|
|
458
450
|
}, async (span) => {
|
|
459
451
|
try {
|
|
460
|
-
return await dispatcher
|
|
452
|
+
return await dispatcher(ctx, identifier);
|
|
461
453
|
} catch (e) {
|
|
462
454
|
span.setStatus({
|
|
463
455
|
code: SpanStatusCode.ERROR,
|
|
@@ -487,8 +479,7 @@ var FederationBuilderImpl = class {
|
|
|
487
479
|
}
|
|
488
480
|
setNodeInfoDispatcher(path, dispatcher) {
|
|
489
481
|
if (this.router.has("nodeInfo")) throw new RouterError("NodeInfo dispatcher already set.");
|
|
490
|
-
|
|
491
|
-
if (variables.size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
|
|
482
|
+
if (this.router.add(path, "nodeInfo").size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
|
|
492
483
|
this.nodeInfoDispatcher = dispatcher;
|
|
493
484
|
}
|
|
494
485
|
setWebFingerLinksDispatcher(dispatcher) {
|
|
@@ -501,8 +492,7 @@ var FederationBuilderImpl = class {
|
|
|
501
492
|
if (variables.size < 1) throw new RouterError("Path for object dispatcher must have at least one variable.");
|
|
502
493
|
const callbacks = {
|
|
503
494
|
dispatcher: (ctx, values) => {
|
|
504
|
-
|
|
505
|
-
return tracer.startActiveSpan("activitypub.dispatch_object", {
|
|
495
|
+
return this._getTracer().startActiveSpan("activitypub.dispatch_object", {
|
|
506
496
|
kind: SpanKind.SERVER,
|
|
507
497
|
attributes: {
|
|
508
498
|
"fedify.object.type": cls.typeId.href,
|
|
@@ -773,8 +763,7 @@ var FederationBuilderImpl = class {
|
|
|
773
763
|
]).warn("The {{handle}} variable in the inbox path is deprecated. Use {{identifier}} instead.");
|
|
774
764
|
}
|
|
775
765
|
if (sharedInboxPath != null) {
|
|
776
|
-
|
|
777
|
-
if (siVars.size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
|
|
766
|
+
if (this.router.add(sharedInboxPath, "sharedInbox").size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
|
|
778
767
|
}
|
|
779
768
|
const listeners = this.inboxListeners = new InboxListenerSet();
|
|
780
769
|
const setters = {
|
|
@@ -808,8 +797,7 @@ var FederationBuilderImpl = class {
|
|
|
808
797
|
const routeName = `${collectionType}:${this.#uniqueCollectionId(name)}`;
|
|
809
798
|
if (this.router.has(routeName)) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
|
|
810
799
|
if (this.collectionCallbacks[name] != null) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
|
|
811
|
-
|
|
812
|
-
if (variables.size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
|
|
800
|
+
if (this.router.add(path, routeName).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
|
|
813
801
|
const callbacks = { dispatcher };
|
|
814
802
|
this.collectionCallbacks[name] = callbacks;
|
|
815
803
|
this.collectionTypeIds[name] = itemType;
|
|
@@ -844,8 +832,7 @@ var FederationBuilderImpl = class {
|
|
|
844
832
|
getCollectionPath(name, values) {
|
|
845
833
|
if (!(name in this.collectionCallbacks)) return null;
|
|
846
834
|
const routeName = this.#uniqueCollectionId(name);
|
|
847
|
-
|
|
848
|
-
return path;
|
|
835
|
+
return this.router.build(`collection:${routeName}`, values) ?? this.router.build(`orderedCollection:${routeName}`, values);
|
|
849
836
|
}
|
|
850
837
|
/**
|
|
851
838
|
* Converts a name (string or symbol) to a unique string identifier.
|
|
@@ -868,7 +855,6 @@ var FederationBuilderImpl = class {
|
|
|
868
855
|
function createFederationBuilder() {
|
|
869
856
|
return new FederationBuilderImpl();
|
|
870
857
|
}
|
|
871
|
-
|
|
872
858
|
//#endregion
|
|
873
859
|
//#region src/federation/collection.ts
|
|
874
860
|
/**
|
|
@@ -887,8 +873,8 @@ async function digest(uris) {
|
|
|
887
873
|
if (processed.has(u)) continue;
|
|
888
874
|
processed.add(u);
|
|
889
875
|
const encoded = encoder.encode(u);
|
|
890
|
-
const digest
|
|
891
|
-
for (let i = 0; i < 32; i++) result[i] ^= digest
|
|
876
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", encoded));
|
|
877
|
+
for (let i = 0; i < 32; i++) result[i] ^= digest[i];
|
|
892
878
|
}
|
|
893
879
|
return result;
|
|
894
880
|
}
|
|
@@ -906,10 +892,8 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
|
|
|
906
892
|
const baseUrl = new URL(anyActorId);
|
|
907
893
|
const url = new URL(collectionId);
|
|
908
894
|
url.searchParams.set("base-url", `${baseUrl.origin}/`);
|
|
909
|
-
|
|
910
|
-
return `collectionId="${collectionId}", url="${url}", digest="${hash}"`;
|
|
895
|
+
return `collectionId="${collectionId}", url="${url}", digest="${encodeHex(await digest(actorIds))}"`;
|
|
911
896
|
}
|
|
912
|
-
|
|
913
897
|
//#endregion
|
|
914
898
|
//#region src/federation/keycache.ts
|
|
915
899
|
const NULL_KEY_CACHE_VALUE = { _fedify: "key-unavailable" };
|
|
@@ -943,7 +927,7 @@ var KvKeyCache = class {
|
|
|
943
927
|
return await Multikey.fromJsonLd(serialized, this.options);
|
|
944
928
|
} catch {
|
|
945
929
|
await this.kv.delete([...this.prefix, keyId.href]);
|
|
946
|
-
return
|
|
930
|
+
return;
|
|
947
931
|
}
|
|
948
932
|
}
|
|
949
933
|
}
|
|
@@ -958,7 +942,6 @@ var KvKeyCache = class {
|
|
|
958
942
|
await this.kv.set([...this.prefix, keyId.href], serialized);
|
|
959
943
|
}
|
|
960
944
|
};
|
|
961
|
-
|
|
962
945
|
//#endregion
|
|
963
946
|
//#region src/federation/negotiation.ts
|
|
964
947
|
function compareSpecs(a, b) {
|
|
@@ -1003,8 +986,8 @@ function parseMediaType(str, i) {
|
|
|
1003
986
|
function parseAccept(accept) {
|
|
1004
987
|
const accepts = accept.split(",").map((p) => p.trim());
|
|
1005
988
|
const mediaTypes = [];
|
|
1006
|
-
for (const [index, accept
|
|
1007
|
-
const mediaType = parseMediaType(accept
|
|
989
|
+
for (const [index, accept] of accepts.entries()) {
|
|
990
|
+
const mediaType = parseMediaType(accept.trim(), index);
|
|
1008
991
|
if (mediaType) mediaTypes.push(mediaType);
|
|
1009
992
|
}
|
|
1010
993
|
return mediaTypes;
|
|
@@ -1013,10 +996,8 @@ function getFullType(spec) {
|
|
|
1013
996
|
return `${spec.type}/${spec.subtype}`;
|
|
1014
997
|
}
|
|
1015
998
|
function preferredMediaTypes(accept) {
|
|
1016
|
-
|
|
1017
|
-
return accepts.filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
999
|
+
return parseAccept(accept === void 0 ? "*/*" : accept ?? "").filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
1018
1000
|
}
|
|
1019
|
-
|
|
1020
1001
|
//#endregion
|
|
1021
1002
|
//#region src/federation/handler.ts
|
|
1022
1003
|
function acceptsJsonLd(request) {
|
|
@@ -1033,24 +1014,24 @@ function acceptsJsonLd(request) {
|
|
|
1033
1014
|
* @param parameters The parameters for handling the actor.
|
|
1034
1015
|
* @returns A promise that resolves to an HTTP response.
|
|
1035
1016
|
*/
|
|
1036
|
-
async function handleActor(request, { identifier, context
|
|
1037
|
-
const logger
|
|
1017
|
+
async function handleActor(request, { identifier, context, actorDispatcher, authorizePredicate, onNotFound, onNotAcceptable, onUnauthorized }) {
|
|
1018
|
+
const logger = getLogger([
|
|
1038
1019
|
"fedify",
|
|
1039
1020
|
"federation",
|
|
1040
1021
|
"actor"
|
|
1041
1022
|
]);
|
|
1042
1023
|
if (actorDispatcher == null) {
|
|
1043
|
-
logger
|
|
1024
|
+
logger.debug("Actor dispatcher is not set.", { identifier });
|
|
1044
1025
|
return await onNotFound(request);
|
|
1045
1026
|
}
|
|
1046
|
-
const actor = await actorDispatcher(context
|
|
1027
|
+
const actor = await actorDispatcher(context, identifier);
|
|
1047
1028
|
if (actor == null) {
|
|
1048
|
-
logger
|
|
1029
|
+
logger.debug("Actor {identifier} not found.", { identifier });
|
|
1049
1030
|
return await onNotFound(request);
|
|
1050
1031
|
}
|
|
1051
1032
|
if (!acceptsJsonLd(request)) return await onNotAcceptable(request);
|
|
1052
1033
|
if (authorizePredicate != null) {
|
|
1053
|
-
let key = await context
|
|
1034
|
+
let key = await context.getSignedKey();
|
|
1054
1035
|
key = key?.clone({}, { $warning: {
|
|
1055
1036
|
category: [
|
|
1056
1037
|
"fedify",
|
|
@@ -1059,7 +1040,7 @@ async function handleActor(request, { identifier, context: context$1, actorDispa
|
|
|
1059
1040
|
],
|
|
1060
1041
|
message: "The third parameter of AuthorizePredicate is deprecated in favor of RequestContext.getSignedKey() method. The third parameter will be removed in a future release."
|
|
1061
1042
|
} }) ?? null;
|
|
1062
|
-
let keyOwner = await context
|
|
1043
|
+
let keyOwner = await context.getSignedKeyOwner();
|
|
1063
1044
|
keyOwner = keyOwner?.clone({}, { $warning: {
|
|
1064
1045
|
category: [
|
|
1065
1046
|
"fedify",
|
|
@@ -1068,9 +1049,9 @@ async function handleActor(request, { identifier, context: context$1, actorDispa
|
|
|
1068
1049
|
],
|
|
1069
1050
|
message: "The fourth parameter of AuthorizePredicate is deprecated in favor of RequestContext.getSignedKeyOwner() method. The fourth parameter will be removed in a future release."
|
|
1070
1051
|
} }) ?? null;
|
|
1071
|
-
if (!await authorizePredicate(context
|
|
1052
|
+
if (!await authorizePredicate(context, identifier, key, keyOwner)) return await onUnauthorized(request);
|
|
1072
1053
|
}
|
|
1073
|
-
const jsonLd = await actor.toJsonLd(context
|
|
1054
|
+
const jsonLd = await actor.toJsonLd(context);
|
|
1074
1055
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1075
1056
|
"Content-Type": "application/activity+json",
|
|
1076
1057
|
Vary: "Accept"
|
|
@@ -1083,13 +1064,13 @@ async function handleActor(request, { identifier, context: context$1, actorDispa
|
|
|
1083
1064
|
* @param parameters The parameters for handling the object.
|
|
1084
1065
|
* @returns A promise that resolves to an HTTP response.
|
|
1085
1066
|
*/
|
|
1086
|
-
async function handleObject(request, { values, context
|
|
1067
|
+
async function handleObject(request, { values, context, objectDispatcher, authorizePredicate, onNotFound, onNotAcceptable, onUnauthorized }) {
|
|
1087
1068
|
if (objectDispatcher == null) return await onNotFound(request);
|
|
1088
|
-
const object = await objectDispatcher(context
|
|
1069
|
+
const object = await objectDispatcher(context, values);
|
|
1089
1070
|
if (object == null) return await onNotFound(request);
|
|
1090
1071
|
if (!acceptsJsonLd(request)) return await onNotAcceptable(request);
|
|
1091
1072
|
if (authorizePredicate != null) {
|
|
1092
|
-
let key = await context
|
|
1073
|
+
let key = await context.getSignedKey();
|
|
1093
1074
|
key = key?.clone({}, { $warning: {
|
|
1094
1075
|
category: [
|
|
1095
1076
|
"fedify",
|
|
@@ -1098,7 +1079,7 @@ async function handleObject(request, { values, context: context$1, objectDispatc
|
|
|
1098
1079
|
],
|
|
1099
1080
|
message: "The third parameter of ObjectAuthorizePredicate is deprecated in favor of RequestContext.getSignedKey() method. The third parameter will be removed in a future release."
|
|
1100
1081
|
} }) ?? null;
|
|
1101
|
-
let keyOwner = await context
|
|
1082
|
+
let keyOwner = await context.getSignedKeyOwner();
|
|
1102
1083
|
keyOwner = keyOwner?.clone({}, { $warning: {
|
|
1103
1084
|
category: [
|
|
1104
1085
|
"fedify",
|
|
@@ -1107,9 +1088,9 @@ async function handleObject(request, { values, context: context$1, objectDispatc
|
|
|
1107
1088
|
],
|
|
1108
1089
|
message: "The fourth parameter of ObjectAuthorizePredicate is deprecated in favor of RequestContext.getSignedKeyOwner() method. The fourth parameter will be removed in a future release."
|
|
1109
1090
|
} }) ?? null;
|
|
1110
|
-
if (!await authorizePredicate(context
|
|
1091
|
+
if (!await authorizePredicate(context, values, key, keyOwner)) return await onUnauthorized(request);
|
|
1111
1092
|
}
|
|
1112
|
-
const jsonLd = await object.toJsonLd(context
|
|
1093
|
+
const jsonLd = await object.toJsonLd(context);
|
|
1113
1094
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1114
1095
|
"Content-Type": "application/activity+json",
|
|
1115
1096
|
Vary: "Accept"
|
|
@@ -1125,18 +1106,17 @@ async function handleObject(request, { values, context: context$1, objectDispatc
|
|
|
1125
1106
|
* @param parameters The parameters for handling the collection.
|
|
1126
1107
|
* @returns A promise that resolves to an HTTP response.
|
|
1127
1108
|
*/
|
|
1128
|
-
async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context
|
|
1129
|
-
const spanName = name.trim().replace(/\s+/g, "_");
|
|
1109
|
+
async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound, onNotAcceptable }) {
|
|
1110
|
+
const spanName = name$2.trim().replace(/\s+/g, "_");
|
|
1130
1111
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
1131
|
-
const tracer = tracerProvider.getTracer(
|
|
1132
|
-
const
|
|
1133
|
-
const cursor = url.searchParams.get("cursor");
|
|
1112
|
+
const tracer = tracerProvider.getTracer(name, version);
|
|
1113
|
+
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1134
1114
|
if (collectionCallbacks == null) return await onNotFound(request);
|
|
1135
1115
|
let collection;
|
|
1136
1116
|
const baseUri = uriGetter(identifier);
|
|
1137
1117
|
if (cursor == null) {
|
|
1138
|
-
const firstCursor = await collectionCallbacks.firstCursor?.(context
|
|
1139
|
-
const totalItems = filter == null ? await collectionCallbacks.counter?.(context
|
|
1118
|
+
const firstCursor = await collectionCallbacks.firstCursor?.(context, identifier);
|
|
1119
|
+
const totalItems = filter == null ? await collectionCallbacks.counter?.(context, identifier) : void 0;
|
|
1140
1120
|
if (firstCursor == null) {
|
|
1141
1121
|
const itemsOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection ${spanName}`, {
|
|
1142
1122
|
kind: SpanKind.SERVER,
|
|
@@ -1147,7 +1127,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1147
1127
|
}, async (span) => {
|
|
1148
1128
|
if (totalItems != null) span.setAttribute("activitypub.collection.total_items", Number(totalItems));
|
|
1149
1129
|
try {
|
|
1150
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1130
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
|
|
1151
1131
|
if (page == null) {
|
|
1152
1132
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1153
1133
|
return await onNotFound(request);
|
|
@@ -1169,15 +1149,15 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1169
1149
|
collection = new OrderedCollection({
|
|
1170
1150
|
id: baseUri,
|
|
1171
1151
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1172
|
-
items: filterCollectionItems(itemsOrResponse, name, filterPredicate)
|
|
1152
|
+
items: filterCollectionItems(itemsOrResponse, name$2, filterPredicate)
|
|
1173
1153
|
});
|
|
1174
1154
|
} else {
|
|
1175
|
-
const lastCursor = await collectionCallbacks.lastCursor?.(context
|
|
1176
|
-
const first = new URL(context
|
|
1155
|
+
const lastCursor = await collectionCallbacks.lastCursor?.(context, identifier);
|
|
1156
|
+
const first = new URL(context.url);
|
|
1177
1157
|
first.searchParams.set("cursor", firstCursor);
|
|
1178
1158
|
let last = null;
|
|
1179
1159
|
if (lastCursor != null) {
|
|
1180
|
-
last = new URL(context
|
|
1160
|
+
last = new URL(context.url);
|
|
1181
1161
|
last.searchParams.set("cursor", lastCursor);
|
|
1182
1162
|
}
|
|
1183
1163
|
collection = new OrderedCollection({
|
|
@@ -1190,7 +1170,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1190
1170
|
} else {
|
|
1191
1171
|
const uri = new URL(baseUri);
|
|
1192
1172
|
uri.searchParams.set("cursor", cursor);
|
|
1193
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name}`, {
|
|
1173
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
|
|
1194
1174
|
kind: SpanKind.SERVER,
|
|
1195
1175
|
attributes: {
|
|
1196
1176
|
"activitypub.collection.id": uri.href,
|
|
@@ -1199,7 +1179,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1199
1179
|
}
|
|
1200
1180
|
}, async (span) => {
|
|
1201
1181
|
try {
|
|
1202
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1182
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
|
|
1203
1183
|
if (page == null) {
|
|
1204
1184
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1205
1185
|
return await onNotFound(request);
|
|
@@ -1220,27 +1200,27 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1220
1200
|
const { items, prevCursor, nextCursor } = pageOrResponse;
|
|
1221
1201
|
let prev = null;
|
|
1222
1202
|
if (prevCursor != null) {
|
|
1223
|
-
prev = new URL(context
|
|
1203
|
+
prev = new URL(context.url);
|
|
1224
1204
|
prev.searchParams.set("cursor", prevCursor);
|
|
1225
1205
|
}
|
|
1226
1206
|
let next = null;
|
|
1227
1207
|
if (nextCursor != null) {
|
|
1228
|
-
next = new URL(context
|
|
1208
|
+
next = new URL(context.url);
|
|
1229
1209
|
next.searchParams.set("cursor", nextCursor);
|
|
1230
1210
|
}
|
|
1231
|
-
const partOf = new URL(context
|
|
1211
|
+
const partOf = new URL(context.url);
|
|
1232
1212
|
partOf.searchParams.delete("cursor");
|
|
1233
1213
|
collection = new OrderedCollectionPage({
|
|
1234
1214
|
id: uri,
|
|
1235
1215
|
prev,
|
|
1236
1216
|
next,
|
|
1237
|
-
items: filterCollectionItems(items, name, filterPredicate),
|
|
1217
|
+
items: filterCollectionItems(items, name$2, filterPredicate),
|
|
1238
1218
|
partOf
|
|
1239
1219
|
});
|
|
1240
1220
|
}
|
|
1241
1221
|
if (!acceptsJsonLd(request)) return await onNotAcceptable(request);
|
|
1242
1222
|
if (collectionCallbacks.authorizePredicate != null) {
|
|
1243
|
-
let key = await context
|
|
1223
|
+
let key = await context.getSignedKey();
|
|
1244
1224
|
key = key?.clone({}, { $warning: {
|
|
1245
1225
|
category: [
|
|
1246
1226
|
"fedify",
|
|
@@ -1249,7 +1229,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1249
1229
|
],
|
|
1250
1230
|
message: "The third parameter of AuthorizePredicate is deprecated in favor of RequestContext.getSignedKey() method. The third parameter will be removed in a future release."
|
|
1251
1231
|
} }) ?? null;
|
|
1252
|
-
let keyOwner = await context
|
|
1232
|
+
let keyOwner = await context.getSignedKeyOwner();
|
|
1253
1233
|
keyOwner = keyOwner?.clone({}, { $warning: {
|
|
1254
1234
|
category: [
|
|
1255
1235
|
"fedify",
|
|
@@ -1258,9 +1238,9 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1258
1238
|
],
|
|
1259
1239
|
message: "The fourth parameter of AuthorizePredicate is deprecated in favor of RequestContext.getSignedKeyOwner() method. The fourth parameter will be removed in a future release."
|
|
1260
1240
|
} }) ?? null;
|
|
1261
|
-
if (!await collectionCallbacks.authorizePredicate(context
|
|
1241
|
+
if (!await collectionCallbacks.authorizePredicate(context, identifier, key, keyOwner)) return await onUnauthorized(request);
|
|
1262
1242
|
}
|
|
1263
|
-
const jsonLd = await collection.toJsonLd(context
|
|
1243
|
+
const jsonLd = await collection.toJsonLd(context);
|
|
1264
1244
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1265
1245
|
"Content-Type": "application/activity+json",
|
|
1266
1246
|
Vary: "Accept"
|
|
@@ -1305,9 +1285,7 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1305
1285
|
* @returns A promise that resolves to an HTTP response.
|
|
1306
1286
|
*/
|
|
1307
1287
|
async function handleInbox(request, options) {
|
|
1308
|
-
|
|
1309
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
1310
|
-
return await tracer.startActiveSpan("activitypub.inbox", {
|
|
1288
|
+
return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("activitypub.inbox", {
|
|
1311
1289
|
kind: options.queue == null ? SpanKind.SERVER : SpanKind.PRODUCER,
|
|
1312
1290
|
attributes: { "activitypub.shared_inbox": options.recipient == null }
|
|
1313
1291
|
}, async (span) => {
|
|
@@ -1335,22 +1313,21 @@ async function handleInbox(request, options) {
|
|
|
1335
1313
|
*/
|
|
1336
1314
|
async function handleInboxInternal(request, parameters, span) {
|
|
1337
1315
|
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider } = parameters;
|
|
1338
|
-
const logger
|
|
1316
|
+
const logger = getLogger([
|
|
1339
1317
|
"fedify",
|
|
1340
1318
|
"federation",
|
|
1341
1319
|
"inbox"
|
|
1342
1320
|
]);
|
|
1343
1321
|
if (actorDispatcher == null) {
|
|
1344
|
-
logger
|
|
1322
|
+
logger.error("Actor dispatcher is not set.", { recipient });
|
|
1345
1323
|
span.setStatus({
|
|
1346
1324
|
code: SpanStatusCode.ERROR,
|
|
1347
1325
|
message: "Actor dispatcher is not set."
|
|
1348
1326
|
});
|
|
1349
1327
|
return await onNotFound(request);
|
|
1350
1328
|
} else if (recipient != null) {
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
logger$1.error("Actor {recipient} not found.", { recipient });
|
|
1329
|
+
if (await actorDispatcher(ctx, recipient) == null) {
|
|
1330
|
+
logger.error("Actor {recipient} not found.", { recipient });
|
|
1354
1331
|
span.setStatus({
|
|
1355
1332
|
code: SpanStatusCode.ERROR,
|
|
1356
1333
|
message: `Actor ${recipient} not found.`
|
|
@@ -1359,7 +1336,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1359
1336
|
}
|
|
1360
1337
|
}
|
|
1361
1338
|
if (request.bodyUsed) {
|
|
1362
|
-
logger
|
|
1339
|
+
logger.error("Request body has already been read.", { recipient });
|
|
1363
1340
|
span.setStatus({
|
|
1364
1341
|
code: SpanStatusCode.ERROR,
|
|
1365
1342
|
message: "Request body has already been read."
|
|
@@ -1369,7 +1346,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1369
1346
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1370
1347
|
});
|
|
1371
1348
|
} else if (request.body?.locked) {
|
|
1372
|
-
logger
|
|
1349
|
+
logger.error("Request body is locked.", { recipient });
|
|
1373
1350
|
span.setStatus({
|
|
1374
1351
|
code: SpanStatusCode.ERROR,
|
|
1375
1352
|
message: "Request body is locked."
|
|
@@ -1383,15 +1360,15 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1383
1360
|
try {
|
|
1384
1361
|
json = await request.clone().json();
|
|
1385
1362
|
} catch (error) {
|
|
1386
|
-
logger
|
|
1363
|
+
logger.error("Failed to parse JSON:\n{error}", {
|
|
1387
1364
|
recipient,
|
|
1388
1365
|
error
|
|
1389
1366
|
});
|
|
1390
1367
|
try {
|
|
1391
1368
|
await inboxErrorHandler?.(ctx, error);
|
|
1392
|
-
} catch (error
|
|
1393
|
-
logger
|
|
1394
|
-
error
|
|
1369
|
+
} catch (error) {
|
|
1370
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1371
|
+
error,
|
|
1395
1372
|
activity: json,
|
|
1396
1373
|
recipient
|
|
1397
1374
|
});
|
|
@@ -1416,7 +1393,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1416
1393
|
});
|
|
1417
1394
|
} catch (error) {
|
|
1418
1395
|
if (error instanceof Error && error.name === "jsonld.SyntaxError") {
|
|
1419
|
-
logger
|
|
1396
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
1420
1397
|
recipient,
|
|
1421
1398
|
error
|
|
1422
1399
|
});
|
|
@@ -1430,13 +1407,13 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1430
1407
|
const jsonWithoutSig = detachSignature(json);
|
|
1431
1408
|
let activity = null;
|
|
1432
1409
|
if (ldSigVerified) {
|
|
1433
|
-
logger
|
|
1410
|
+
logger.debug("Linked Data Signatures are verified.", {
|
|
1434
1411
|
recipient,
|
|
1435
1412
|
json
|
|
1436
1413
|
});
|
|
1437
1414
|
activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1438
1415
|
} else {
|
|
1439
|
-
logger
|
|
1416
|
+
logger.debug("Linked Data Signatures are not verified.", {
|
|
1440
1417
|
recipient,
|
|
1441
1418
|
json
|
|
1442
1419
|
});
|
|
@@ -1448,16 +1425,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1448
1425
|
tracerProvider
|
|
1449
1426
|
});
|
|
1450
1427
|
} catch (error) {
|
|
1451
|
-
logger
|
|
1428
|
+
logger.error("Failed to parse activity:\n{error}", {
|
|
1452
1429
|
recipient,
|
|
1453
1430
|
activity: json,
|
|
1454
1431
|
error
|
|
1455
1432
|
});
|
|
1456
1433
|
try {
|
|
1457
1434
|
await inboxErrorHandler?.(ctx, error);
|
|
1458
|
-
} catch (error
|
|
1459
|
-
logger
|
|
1460
|
-
error
|
|
1435
|
+
} catch (error) {
|
|
1436
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1437
|
+
error,
|
|
1461
1438
|
activity: json,
|
|
1462
1439
|
recipient
|
|
1463
1440
|
});
|
|
@@ -1471,11 +1448,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1471
1448
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1472
1449
|
});
|
|
1473
1450
|
}
|
|
1474
|
-
if (activity == null) logger
|
|
1451
|
+
if (activity == null) logger.debug("Object Integrity Proofs are not verified.", {
|
|
1475
1452
|
recipient,
|
|
1476
1453
|
activity: json
|
|
1477
1454
|
});
|
|
1478
|
-
else logger
|
|
1455
|
+
else logger.debug("Object Integrity Proofs are verified.", {
|
|
1479
1456
|
recipient,
|
|
1480
1457
|
activity: json
|
|
1481
1458
|
});
|
|
@@ -1491,17 +1468,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1491
1468
|
tracerProvider
|
|
1492
1469
|
});
|
|
1493
1470
|
if (key == null) {
|
|
1494
|
-
logger
|
|
1471
|
+
logger.error("Failed to verify the request's HTTP Signatures.", { recipient });
|
|
1495
1472
|
span.setStatus({
|
|
1496
1473
|
code: SpanStatusCode.ERROR,
|
|
1497
1474
|
message: `Failed to verify the request's HTTP Signatures.`
|
|
1498
1475
|
});
|
|
1499
|
-
|
|
1476
|
+
return new Response("Failed to verify the request signature.", {
|
|
1500
1477
|
status: 401,
|
|
1501
1478
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1502
1479
|
});
|
|
1503
|
-
|
|
1504
|
-
} else logger$1.debug("HTTP Signatures are verified.", { recipient });
|
|
1480
|
+
} else logger.debug("HTTP Signatures are verified.", { recipient });
|
|
1505
1481
|
httpSigKey = key;
|
|
1506
1482
|
}
|
|
1507
1483
|
activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
@@ -1516,7 +1492,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1516
1492
|
"http_signatures.key_id": httpSigKey?.id?.href ?? ""
|
|
1517
1493
|
});
|
|
1518
1494
|
if (httpSigKey != null && !await doesActorOwnKey(activity, httpSigKey, ctx)) {
|
|
1519
|
-
logger
|
|
1495
|
+
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
|
1520
1496
|
activity: json,
|
|
1521
1497
|
recipient,
|
|
1522
1498
|
keyId: httpSigKey.id?.href,
|
|
@@ -1583,12 +1559,12 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1583
1559
|
* @since 1.8.0
|
|
1584
1560
|
*/
|
|
1585
1561
|
const handleCustomCollection = exceptWrapper(_handleCustomCollection);
|
|
1586
|
-
async function _handleCustomCollection(request, { name, values, context
|
|
1562
|
+
async function _handleCustomCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1587
1563
|
verifyDefined(callbacks);
|
|
1588
1564
|
verifyJsonLdRequest(request);
|
|
1589
|
-
await authIfNeeded(context
|
|
1565
|
+
await authIfNeeded(context, values, callbacks);
|
|
1590
1566
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1591
|
-
return await new CustomCollectionHandler(name, values, context
|
|
1567
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, Collection, CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1592
1568
|
}
|
|
1593
1569
|
/**
|
|
1594
1570
|
* Handles an ordered collection request.
|
|
@@ -1602,12 +1578,12 @@ async function _handleCustomCollection(request, { name, values, context: context
|
|
|
1602
1578
|
* @since 1.8.0
|
|
1603
1579
|
*/
|
|
1604
1580
|
const handleOrderedCollection = exceptWrapper(_handleOrderedCollection);
|
|
1605
|
-
async function _handleOrderedCollection(request, { name, values, context
|
|
1581
|
+
async function _handleOrderedCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1606
1582
|
verifyDefined(callbacks);
|
|
1607
1583
|
verifyJsonLdRequest(request);
|
|
1608
|
-
await authIfNeeded(context
|
|
1584
|
+
await authIfNeeded(context, values, callbacks);
|
|
1609
1585
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1610
|
-
return await new CustomCollectionHandler(name, values, context
|
|
1586
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, OrderedCollection, OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1611
1587
|
}
|
|
1612
1588
|
/**
|
|
1613
1589
|
* Handling custom collections with support for pagination and filtering.
|
|
@@ -1657,17 +1633,17 @@ var CustomCollectionHandler = class {
|
|
|
1657
1633
|
* @param CollectionPage The CollectionPage constructor.
|
|
1658
1634
|
* @param filterPredicate Optional filter predicate for items.
|
|
1659
1635
|
*/
|
|
1660
|
-
constructor(name, values, context
|
|
1661
|
-
this.name = name;
|
|
1636
|
+
constructor(name$1, values, context, callbacks, tracerProvider = trace.getTracerProvider(), Collection, CollectionPage, filterPredicate) {
|
|
1637
|
+
this.name = name$1;
|
|
1662
1638
|
this.values = values;
|
|
1663
|
-
this.context = context
|
|
1639
|
+
this.context = context;
|
|
1664
1640
|
this.callbacks = callbacks;
|
|
1665
1641
|
this.tracerProvider = tracerProvider;
|
|
1666
|
-
this.Collection = Collection
|
|
1667
|
-
this.CollectionPage = CollectionPage
|
|
1642
|
+
this.Collection = Collection;
|
|
1643
|
+
this.CollectionPage = CollectionPage;
|
|
1668
1644
|
this.filterPredicate = filterPredicate;
|
|
1669
1645
|
this.name = this.name.trim().replace(/\s+/g, "_");
|
|
1670
|
-
this.#tracer = this.tracerProvider.getTracer(
|
|
1646
|
+
this.#tracer = this.tracerProvider.getTracer(name, version);
|
|
1671
1647
|
this.#id = new URL(this.context.url);
|
|
1672
1648
|
this.#dispatcher = callbacks.dispatcher.bind(callbacks);
|
|
1673
1649
|
}
|
|
@@ -1696,8 +1672,8 @@ var CustomCollectionHandler = class {
|
|
|
1696
1672
|
*/
|
|
1697
1673
|
async getCollection(cursor = null) {
|
|
1698
1674
|
if (cursor !== null) {
|
|
1699
|
-
const props
|
|
1700
|
-
return new this.CollectionPage(props
|
|
1675
|
+
const props = await this.getPageProps(cursor);
|
|
1676
|
+
return new this.CollectionPage(props);
|
|
1701
1677
|
}
|
|
1702
1678
|
const firstCursor = await this.firstCursor;
|
|
1703
1679
|
const props = typeof firstCursor === "string" ? await this.getProps(firstCursor) : await this.getPropsWithoutCursor();
|
|
@@ -1845,7 +1821,7 @@ var CustomCollectionHandler = class {
|
|
|
1845
1821
|
* @param value The total items count or a promise that resolves to it.
|
|
1846
1822
|
*/
|
|
1847
1823
|
set totalItems(value) {
|
|
1848
|
-
const toNumber = (value
|
|
1824
|
+
const toNumber = (value) => value == null ? null : Number(value);
|
|
1849
1825
|
this.#totalItems = value instanceof Promise ? value.then(toNumber) : Promise.resolve(toNumber(value));
|
|
1850
1826
|
}
|
|
1851
1827
|
/**
|
|
@@ -1919,11 +1895,9 @@ const verifyJsonLdRequest = (request) => {
|
|
|
1919
1895
|
* @throws {UnauthorizedError} If authorization fails.
|
|
1920
1896
|
* @since 1.8.0
|
|
1921
1897
|
*/
|
|
1922
|
-
const authIfNeeded = async (context
|
|
1898
|
+
const authIfNeeded = async (context, values, { authorizePredicate: authorize = void 0 }) => {
|
|
1923
1899
|
if (authorize === void 0) return;
|
|
1924
|
-
|
|
1925
|
-
const keyOwner = (await context$1.getSignedKeyOwner())?.clone({}, warning.keyOwner) ?? null;
|
|
1926
|
-
if (!await authorize(context$1, values, key, keyOwner)) throw new UnauthorizedError();
|
|
1900
|
+
if (!await authorize(context, values, (await context.getSignedKey())?.clone({}, warning.key) ?? null, (await context.getSignedKeyOwner())?.clone({}, warning.keyOwner) ?? null)) throw new UnauthorizedError();
|
|
1927
1901
|
};
|
|
1928
1902
|
/** Warning messages for `authIfNeeded`. */
|
|
1929
1903
|
const warning = {
|
|
@@ -2037,7 +2011,6 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
2037
2011
|
response.headers.set("Vary", "Accept");
|
|
2038
2012
|
return response;
|
|
2039
2013
|
}
|
|
2040
|
-
|
|
2041
2014
|
//#endregion
|
|
2042
2015
|
//#region src/nodeinfo/handler.ts
|
|
2043
2016
|
/**
|
|
@@ -2047,10 +2020,9 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
2047
2020
|
* @param parameters The parameters for handling the request.
|
|
2048
2021
|
* @returns The response to the request.
|
|
2049
2022
|
*/
|
|
2050
|
-
async function handleNodeInfo(_request, { context
|
|
2051
|
-
const promise = nodeInfoDispatcher(context
|
|
2052
|
-
const
|
|
2053
|
-
const json = nodeInfoToJson(nodeInfo);
|
|
2023
|
+
async function handleNodeInfo(_request, { context, nodeInfoDispatcher }) {
|
|
2024
|
+
const promise = nodeInfoDispatcher(context);
|
|
2025
|
+
const json = nodeInfoToJson(promise instanceof Promise ? await promise : promise);
|
|
2054
2026
|
return new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\"" } });
|
|
2055
2027
|
}
|
|
2056
2028
|
/**
|
|
@@ -2060,22 +2032,20 @@ async function handleNodeInfo(_request, { context: context$1, nodeInfoDispatcher
|
|
|
2060
2032
|
* @param context The request context.
|
|
2061
2033
|
* @returns The response to the request.
|
|
2062
2034
|
*/
|
|
2063
|
-
function handleNodeInfoJrd(_request, context
|
|
2035
|
+
function handleNodeInfoJrd(_request, context) {
|
|
2064
2036
|
const links = [];
|
|
2065
2037
|
try {
|
|
2066
2038
|
links.push({
|
|
2067
2039
|
rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
|
|
2068
|
-
href: context
|
|
2040
|
+
href: context.getNodeInfoUri().href,
|
|
2069
2041
|
type: "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\""
|
|
2070
2042
|
});
|
|
2071
2043
|
} catch (e) {
|
|
2072
2044
|
if (!(e instanceof RouterError)) throw e;
|
|
2073
2045
|
}
|
|
2074
|
-
const
|
|
2075
|
-
const response = new Response(JSON.stringify(jrd), { headers: { "Content-Type": "application/jrd+json" } });
|
|
2046
|
+
const response = new Response(JSON.stringify({ links }), { headers: { "Content-Type": "application/jrd+json" } });
|
|
2076
2047
|
return Promise.resolve(response);
|
|
2077
2048
|
}
|
|
2078
|
-
|
|
2079
2049
|
//#endregion
|
|
2080
2050
|
//#region src/webfinger/handler.ts
|
|
2081
2051
|
const logger = getLogger([
|
|
@@ -2108,12 +2078,12 @@ async function handleWebFinger(request, options) {
|
|
|
2108
2078
|
}
|
|
2109
2079
|
});
|
|
2110
2080
|
}
|
|
2111
|
-
async function handleWebFingerInternal(request, { context
|
|
2081
|
+
async function handleWebFingerInternal(request, { context, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
|
|
2112
2082
|
if (actorDispatcher == null) {
|
|
2113
2083
|
logger.error("Actor dispatcher is not set.");
|
|
2114
2084
|
return await onNotFound(request);
|
|
2115
2085
|
}
|
|
2116
|
-
const resource = context
|
|
2086
|
+
const resource = context.url.searchParams.get("resource");
|
|
2117
2087
|
if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
|
|
2118
2088
|
span?.setAttribute("webfinger.resource", resource);
|
|
2119
2089
|
let resourceUrl;
|
|
@@ -2129,26 +2099,26 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2129
2099
|
logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
|
|
2130
2100
|
return username;
|
|
2131
2101
|
}
|
|
2132
|
-
const identifier
|
|
2133
|
-
if (identifier
|
|
2102
|
+
const identifier = await actorHandleMapper(context, username);
|
|
2103
|
+
if (identifier == null) {
|
|
2134
2104
|
logger.error("Actor {username} not found.", { username });
|
|
2135
2105
|
return null;
|
|
2136
2106
|
}
|
|
2137
|
-
return identifier
|
|
2107
|
+
return identifier;
|
|
2138
2108
|
}
|
|
2139
2109
|
let identifier = null;
|
|
2140
|
-
const uriParsed = context
|
|
2110
|
+
const uriParsed = context.parseUri(resourceUrl);
|
|
2141
2111
|
if (uriParsed?.type != "actor") {
|
|
2142
2112
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
2143
2113
|
if (match == null) {
|
|
2144
|
-
const result = await actorAliasMapper?.(context
|
|
2114
|
+
const result = await actorAliasMapper?.(context, resourceUrl);
|
|
2145
2115
|
if (result == null) return await onNotFound(request);
|
|
2146
2116
|
if ("identifier" in result) identifier = result.identifier;
|
|
2147
2117
|
else identifier = await mapUsernameToIdentifier(result.username);
|
|
2148
2118
|
} else {
|
|
2149
2119
|
const portMatch = /:\d+$/.exec(match[2]);
|
|
2150
2120
|
const normalizedHost = portMatch == null ? domainToASCII(match[2].toLowerCase()) : domainToASCII(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
2151
|
-
if (normalizedHost != context
|
|
2121
|
+
if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
|
|
2152
2122
|
else {
|
|
2153
2123
|
identifier = await mapUsernameToIdentifier(match[1]);
|
|
2154
2124
|
resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
|
|
@@ -2156,14 +2126,14 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2156
2126
|
}
|
|
2157
2127
|
} else identifier = uriParsed.identifier;
|
|
2158
2128
|
if (identifier == null) return await onNotFound(request);
|
|
2159
|
-
const actor = await actorDispatcher(context
|
|
2129
|
+
const actor = await actorDispatcher(context, identifier);
|
|
2160
2130
|
if (actor == null) {
|
|
2161
2131
|
logger.error("Actor {identifier} not found.", { identifier });
|
|
2162
2132
|
return await onNotFound(request);
|
|
2163
2133
|
}
|
|
2164
2134
|
const links = [{
|
|
2165
2135
|
rel: "self",
|
|
2166
|
-
href: context
|
|
2136
|
+
href: context.getActorUri(identifier).href,
|
|
2167
2137
|
type: "application/activity+json"
|
|
2168
2138
|
}];
|
|
2169
2139
|
for (const url of actor.urls) if (url instanceof Link && url.href != null) links.push({
|
|
@@ -2185,16 +2155,16 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2185
2155
|
links.push(link);
|
|
2186
2156
|
}
|
|
2187
2157
|
if (webFingerLinksDispatcher != null) {
|
|
2188
|
-
const customLinks = await webFingerLinksDispatcher(context
|
|
2158
|
+
const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
|
|
2189
2159
|
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
2190
2160
|
}
|
|
2191
2161
|
const aliases = [];
|
|
2192
2162
|
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
|
|
2193
|
-
aliases.push(`acct:${actor.preferredUsername}@${host ?? context
|
|
2194
|
-
if (host != null && host !== context
|
|
2163
|
+
aliases.push(`acct:${actor.preferredUsername}@${host ?? context.url.host}`);
|
|
2164
|
+
if (host != null && host !== context.url.host) aliases.push(`acct:${actor.preferredUsername}@${context.url.host}`);
|
|
2195
2165
|
}
|
|
2196
|
-
if (resourceUrl.href !== context
|
|
2197
|
-
if (resourceUrl.protocol === "acct:" && host != null && host !== context
|
|
2166
|
+
if (resourceUrl.href !== context.getActorUri(identifier).href) aliases.push(context.getActorUri(identifier).href);
|
|
2167
|
+
if (resourceUrl.protocol === "acct:" && host != null && host !== context.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
2198
2168
|
const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
|
|
2199
2169
|
aliases.push(`acct:${username}@${host}`);
|
|
2200
2170
|
}
|
|
@@ -2208,7 +2178,6 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2208
2178
|
"Access-Control-Allow-Origin": "*"
|
|
2209
2179
|
} });
|
|
2210
2180
|
}
|
|
2211
|
-
|
|
2212
2181
|
//#endregion
|
|
2213
2182
|
//#region src/federation/retry.ts
|
|
2214
2183
|
/**
|
|
@@ -2235,11 +2204,10 @@ function createExponentialBackoffPolicy(options = {}) {
|
|
|
2235
2204
|
milliseconds *= 1 + Math.random();
|
|
2236
2205
|
milliseconds = Math.round(milliseconds);
|
|
2237
2206
|
}
|
|
2238
|
-
const delay
|
|
2239
|
-
return Temporal.Duration.compare(delay
|
|
2207
|
+
const delay = Temporal.Duration.from({ milliseconds });
|
|
2208
|
+
return Temporal.Duration.compare(delay, maxDelay) > 0 ? maxDelay : delay;
|
|
2240
2209
|
};
|
|
2241
2210
|
}
|
|
2242
|
-
|
|
2243
2211
|
//#endregion
|
|
2244
2212
|
//#region src/federation/send.ts
|
|
2245
2213
|
/**
|
|
@@ -2277,8 +2245,7 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
|
|
|
2277
2245
|
*/
|
|
2278
2246
|
function sendActivity(options) {
|
|
2279
2247
|
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
2280
|
-
|
|
2281
|
-
return tracer.startActiveSpan("activitypub.send_activity", {
|
|
2248
|
+
return tracerProvider.getTracer(name, version).startActiveSpan("activitypub.send_activity", {
|
|
2282
2249
|
kind: SpanKind.CLIENT,
|
|
2283
2250
|
attributes: { "activitypub.shared_inbox": options.sharedInbox ?? false }
|
|
2284
2251
|
}, async (span) => {
|
|
@@ -2301,7 +2268,7 @@ function sendActivity(options) {
|
|
|
2301
2268
|
});
|
|
2302
2269
|
}
|
|
2303
2270
|
async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }, span) {
|
|
2304
|
-
const logger
|
|
2271
|
+
const logger = getLogger([
|
|
2305
2272
|
"fedify",
|
|
2306
2273
|
"federation",
|
|
2307
2274
|
"outbox"
|
|
@@ -2318,7 +2285,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2318
2285
|
rsaKey = key;
|
|
2319
2286
|
break;
|
|
2320
2287
|
}
|
|
2321
|
-
if (rsaKey == null) logger
|
|
2288
|
+
if (rsaKey == null) logger.warn("No supported key found to sign the request to {inbox}. The request will be sent without a signature. In order to sign the request, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
|
|
2322
2289
|
inbox: inbox.href,
|
|
2323
2290
|
keys: keys.map((pair) => ({
|
|
2324
2291
|
keyId: pair.keyId.href,
|
|
@@ -2332,7 +2299,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2332
2299
|
specDeterminer
|
|
2333
2300
|
});
|
|
2334
2301
|
} catch (error) {
|
|
2335
|
-
logger
|
|
2302
|
+
logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
|
|
2336
2303
|
activityId,
|
|
2337
2304
|
inbox: inbox.href,
|
|
2338
2305
|
error
|
|
@@ -2346,7 +2313,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2346
2313
|
} catch (_) {
|
|
2347
2314
|
error = "";
|
|
2348
2315
|
}
|
|
2349
|
-
logger
|
|
2316
|
+
logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
|
|
2350
2317
|
activityId,
|
|
2351
2318
|
inbox: inbox.href,
|
|
2352
2319
|
status: response.status,
|
|
@@ -2361,9 +2328,15 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2361
2328
|
"activitypub.activity.id": activityId ?? ""
|
|
2362
2329
|
});
|
|
2363
2330
|
}
|
|
2364
|
-
|
|
2365
2331
|
//#endregion
|
|
2366
2332
|
//#region src/federation/middleware.ts
|
|
2333
|
+
var middleware_exports = /* @__PURE__ */ __exportAll({
|
|
2334
|
+
ContextImpl: () => ContextImpl,
|
|
2335
|
+
FederationImpl: () => FederationImpl,
|
|
2336
|
+
InboxContextImpl: () => InboxContextImpl,
|
|
2337
|
+
KvSpecDeterminer: () => KvSpecDeterminer,
|
|
2338
|
+
createFederation: () => createFederation
|
|
2339
|
+
});
|
|
2367
2340
|
/**
|
|
2368
2341
|
* Create a new {@link Federation} instance.
|
|
2369
2342
|
* @param parameters Parameters for initializing the instance.
|
|
@@ -2399,7 +2372,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2399
2372
|
firstKnock;
|
|
2400
2373
|
constructor(options) {
|
|
2401
2374
|
super();
|
|
2402
|
-
const logger
|
|
2375
|
+
const logger = getLogger(["fedify", "federation"]);
|
|
2403
2376
|
this.kv = options.kv;
|
|
2404
2377
|
this.kvPrefixes = {
|
|
2405
2378
|
activityIdempotence: ["_fedify", "activityIdempotence"],
|
|
@@ -2456,7 +2429,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2456
2429
|
if (options.documentLoader != null) {
|
|
2457
2430
|
if (options.documentLoaderFactory != null) throw new TypeError("Cannot set both documentLoader and documentLoaderFactory options at a time; use documentLoaderFactory only.");
|
|
2458
2431
|
this.documentLoaderFactory = () => options.documentLoader;
|
|
2459
|
-
logger
|
|
2432
|
+
logger.warn("The documentLoader option is deprecated; use documentLoaderFactory option instead.");
|
|
2460
2433
|
} else this.documentLoaderFactory = options.documentLoaderFactory ?? ((opts) => {
|
|
2461
2434
|
return kvCache({
|
|
2462
2435
|
loader: getDocumentLoader({
|
|
@@ -2470,7 +2443,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2470
2443
|
if (options.contextLoader != null) {
|
|
2471
2444
|
if (options.contextLoaderFactory != null) throw new TypeError("Cannot set both contextLoader and contextLoaderFactory options at a time; use contextLoaderFactory only.");
|
|
2472
2445
|
this.contextLoaderFactory = () => options.contextLoader;
|
|
2473
|
-
logger
|
|
2446
|
+
logger.warn("The contextLoader option is deprecated; use contextLoaderFactory option instead.");
|
|
2474
2447
|
} else this.contextLoaderFactory = options.contextLoaderFactory ?? this.documentLoaderFactory;
|
|
2475
2448
|
this.authenticatedDocumentLoaderFactory = options.authenticatedDocumentLoaderFactory ?? ((identity) => getAuthenticatedDocumentLoader(identity, {
|
|
2476
2449
|
allowPrivateAddress,
|
|
@@ -2493,28 +2466,28 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2493
2466
|
this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
|
|
2494
2467
|
}
|
|
2495
2468
|
_getTracer() {
|
|
2496
|
-
return this.tracerProvider.getTracer(
|
|
2469
|
+
return this.tracerProvider.getTracer(name, version);
|
|
2497
2470
|
}
|
|
2498
2471
|
async _startQueueInternal(ctxData, signal, queue) {
|
|
2499
2472
|
if (this.inboxQueue == null && this.outboxQueue == null) return;
|
|
2500
|
-
const logger
|
|
2473
|
+
const logger = getLogger([
|
|
2501
2474
|
"fedify",
|
|
2502
2475
|
"federation",
|
|
2503
2476
|
"queue"
|
|
2504
2477
|
]);
|
|
2505
2478
|
const promises = [];
|
|
2506
2479
|
if (this.inboxQueue != null && (queue == null || queue === "inbox") && !this.inboxQueueStarted) {
|
|
2507
|
-
logger
|
|
2480
|
+
logger.debug("Starting an inbox task worker.");
|
|
2508
2481
|
this.inboxQueueStarted = true;
|
|
2509
2482
|
promises.push(this.inboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2510
2483
|
}
|
|
2511
2484
|
if (this.outboxQueue != null && this.outboxQueue !== this.inboxQueue && (queue == null || queue === "outbox") && !this.outboxQueueStarted) {
|
|
2512
|
-
logger
|
|
2485
|
+
logger.debug("Starting an outbox task worker.");
|
|
2513
2486
|
this.outboxQueueStarted = true;
|
|
2514
2487
|
promises.push(this.outboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2515
2488
|
}
|
|
2516
2489
|
if (this.fanoutQueue != null && this.fanoutQueue !== this.inboxQueue && this.fanoutQueue !== this.outboxQueue && (queue == null || queue === "fanout") && !this.fanoutQueueStarted) {
|
|
2517
|
-
logger
|
|
2490
|
+
logger.debug("Starting a fanout task worker.");
|
|
2518
2491
|
this.fanoutQueueStarted = true;
|
|
2519
2492
|
promises.push(this.fanoutQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2520
2493
|
}
|
|
@@ -2580,12 +2553,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2580
2553
|
});
|
|
2581
2554
|
}
|
|
2582
2555
|
async #listenFanoutMessage(data, message) {
|
|
2583
|
-
|
|
2556
|
+
getLogger([
|
|
2584
2557
|
"fedify",
|
|
2585
2558
|
"federation",
|
|
2586
2559
|
"fanout"
|
|
2587
|
-
])
|
|
2588
|
-
logger$1.debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2560
|
+
]).debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2589
2561
|
activityId: message.activityId,
|
|
2590
2562
|
inboxes: globalThis.Object.keys(message.inboxes).length
|
|
2591
2563
|
});
|
|
@@ -2604,17 +2576,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2604
2576
|
}),
|
|
2605
2577
|
tracerProvider: this.tracerProvider
|
|
2606
2578
|
});
|
|
2607
|
-
const context
|
|
2579
|
+
const context = this.#createContext(new URL(message.baseUrl), data, { documentLoader: this.documentLoaderFactory({
|
|
2608
2580
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
2609
2581
|
userAgent: this.userAgent
|
|
2610
2582
|
}) });
|
|
2611
2583
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
2612
2584
|
collectionSync: message.collectionSync,
|
|
2613
|
-
context
|
|
2585
|
+
context
|
|
2614
2586
|
});
|
|
2615
2587
|
}
|
|
2616
2588
|
async #listenOutboxMessage(_, message, span) {
|
|
2617
|
-
const logger
|
|
2589
|
+
const logger = getLogger([
|
|
2618
2590
|
"fedify",
|
|
2619
2591
|
"federation",
|
|
2620
2592
|
"outbox"
|
|
@@ -2662,65 +2634,64 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2662
2634
|
});
|
|
2663
2635
|
try {
|
|
2664
2636
|
this.onOutboxError?.(error, activity);
|
|
2665
|
-
} catch (error
|
|
2666
|
-
logger
|
|
2637
|
+
} catch (error) {
|
|
2638
|
+
logger.error("An unexpected error occurred in onError handler:\n{error}", {
|
|
2667
2639
|
...logData,
|
|
2668
|
-
error
|
|
2640
|
+
error
|
|
2669
2641
|
});
|
|
2670
2642
|
}
|
|
2671
2643
|
if (this.outboxQueue?.nativeRetrial) {
|
|
2672
|
-
logger
|
|
2644
|
+
logger.error("Failed to send activity {activityId} to {inbox}; backend will handle retry:\n{error}", {
|
|
2673
2645
|
...logData,
|
|
2674
2646
|
error
|
|
2675
2647
|
});
|
|
2676
2648
|
throw error;
|
|
2677
2649
|
}
|
|
2678
|
-
const delay
|
|
2650
|
+
const delay = this.outboxRetryPolicy({
|
|
2679
2651
|
elapsedTime: Temporal.Instant.from(message.started).until(Temporal.Now.instant()),
|
|
2680
2652
|
attempts: message.attempt
|
|
2681
2653
|
});
|
|
2682
|
-
if (delay
|
|
2683
|
-
logger
|
|
2654
|
+
if (delay != null) {
|
|
2655
|
+
logger.error("Failed to send activity {activityId} to {inbox} (attempt #{attempt}); retry...:\n{error}", {
|
|
2684
2656
|
...logData,
|
|
2685
2657
|
error
|
|
2686
2658
|
});
|
|
2687
2659
|
await this.outboxQueue?.enqueue({
|
|
2688
2660
|
...message,
|
|
2689
2661
|
attempt: message.attempt + 1
|
|
2690
|
-
}, { delay: Temporal.Duration.compare(delay
|
|
2691
|
-
} else logger
|
|
2662
|
+
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2663
|
+
} else logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
2692
2664
|
...logData,
|
|
2693
2665
|
error
|
|
2694
2666
|
});
|
|
2695
2667
|
return;
|
|
2696
2668
|
}
|
|
2697
|
-
logger
|
|
2669
|
+
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
2698
2670
|
}
|
|
2699
2671
|
async #listenInboxMessage(ctxData, message, span) {
|
|
2700
|
-
const logger
|
|
2672
|
+
const logger = getLogger([
|
|
2701
2673
|
"fedify",
|
|
2702
2674
|
"federation",
|
|
2703
2675
|
"inbox"
|
|
2704
2676
|
]);
|
|
2705
2677
|
const baseUrl = new URL(message.baseUrl);
|
|
2706
|
-
let context
|
|
2707
|
-
if (message.identifier != null) context
|
|
2678
|
+
let context = this.#createContext(baseUrl, ctxData);
|
|
2679
|
+
if (message.identifier != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: await context.getDocumentLoader({ identifier: message.identifier }) });
|
|
2708
2680
|
else if (this.sharedInboxKeyDispatcher != null) {
|
|
2709
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
2710
|
-
if (identity != null) context
|
|
2681
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
2682
|
+
if (identity != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity || "handle" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
2711
2683
|
}
|
|
2712
|
-
const activity = await Activity.fromJsonLd(message.activity, context
|
|
2684
|
+
const activity = await Activity.fromJsonLd(message.activity, context);
|
|
2713
2685
|
span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
|
|
2714
2686
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2715
2687
|
const cacheKey = activity.id == null ? null : [
|
|
2716
2688
|
...this.kvPrefixes.activityIdempotence,
|
|
2717
|
-
context
|
|
2689
|
+
context.origin,
|
|
2718
2690
|
activity.id.href
|
|
2719
2691
|
];
|
|
2720
2692
|
if (cacheKey != null) {
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
logger$1.debug("Activity {activityId} has already been processed.", {
|
|
2693
|
+
if (await this.kv.get(cacheKey) === true) {
|
|
2694
|
+
logger.debug("Activity {activityId} has already been processed.", {
|
|
2724
2695
|
activityId: activity.id?.href,
|
|
2725
2696
|
activity: message.activity,
|
|
2726
2697
|
recipient: message.identifier
|
|
@@ -2728,32 +2699,32 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2728
2699
|
return;
|
|
2729
2700
|
}
|
|
2730
2701
|
}
|
|
2731
|
-
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span
|
|
2702
|
+
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
|
|
2732
2703
|
const dispatched = this.inboxListeners?.dispatchWithClass(activity);
|
|
2733
2704
|
if (dispatched == null) {
|
|
2734
|
-
logger
|
|
2705
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
2735
2706
|
activityId: activity.id?.href,
|
|
2736
2707
|
activity: message.activity,
|
|
2737
2708
|
recipient: message.identifier,
|
|
2738
2709
|
trial: message.attempt
|
|
2739
2710
|
});
|
|
2740
|
-
span
|
|
2711
|
+
span.setStatus({
|
|
2741
2712
|
code: SpanStatusCode.ERROR,
|
|
2742
2713
|
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
2743
2714
|
});
|
|
2744
|
-
span
|
|
2715
|
+
span.end();
|
|
2745
2716
|
return;
|
|
2746
2717
|
}
|
|
2747
2718
|
const { class: cls, listener } = dispatched;
|
|
2748
|
-
span
|
|
2719
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
2749
2720
|
try {
|
|
2750
|
-
await listener(context
|
|
2721
|
+
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, getTypeId(activity).href), activity);
|
|
2751
2722
|
} catch (error) {
|
|
2752
2723
|
try {
|
|
2753
|
-
await this.inboxErrorHandler?.(context
|
|
2754
|
-
} catch (error
|
|
2755
|
-
logger
|
|
2756
|
-
error
|
|
2724
|
+
await this.inboxErrorHandler?.(context, error);
|
|
2725
|
+
} catch (error) {
|
|
2726
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
2727
|
+
error,
|
|
2757
2728
|
trial: message.attempt,
|
|
2758
2729
|
activityId: activity.id?.href,
|
|
2759
2730
|
activity: message.activity,
|
|
@@ -2761,25 +2732,25 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2761
2732
|
});
|
|
2762
2733
|
}
|
|
2763
2734
|
if (this.inboxQueue?.nativeRetrial) {
|
|
2764
|
-
logger
|
|
2735
|
+
logger.error("Failed to process the incoming activity {activityId}; backend will handle retry:\n{error}", {
|
|
2765
2736
|
error,
|
|
2766
2737
|
activityId: activity.id?.href,
|
|
2767
2738
|
activity: message.activity,
|
|
2768
2739
|
recipient: message.identifier
|
|
2769
2740
|
});
|
|
2770
|
-
span
|
|
2741
|
+
span.setStatus({
|
|
2771
2742
|
code: SpanStatusCode.ERROR,
|
|
2772
2743
|
message: String(error)
|
|
2773
2744
|
});
|
|
2774
|
-
span
|
|
2745
|
+
span.end();
|
|
2775
2746
|
throw error;
|
|
2776
2747
|
}
|
|
2777
|
-
const delay
|
|
2748
|
+
const delay = this.inboxRetryPolicy({
|
|
2778
2749
|
elapsedTime: Temporal.Instant.from(message.started).until(Temporal.Now.instant()),
|
|
2779
2750
|
attempts: message.attempt
|
|
2780
2751
|
});
|
|
2781
|
-
if (delay
|
|
2782
|
-
logger
|
|
2752
|
+
if (delay != null) {
|
|
2753
|
+
logger.error("Failed to process the incoming activity {activityId} (attempt #{attempt}); retry...:\n{error}", {
|
|
2783
2754
|
error,
|
|
2784
2755
|
attempt: message.attempt,
|
|
2785
2756
|
activityId: activity.id?.href,
|
|
@@ -2789,27 +2760,27 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2789
2760
|
await this.inboxQueue?.enqueue({
|
|
2790
2761
|
...message,
|
|
2791
2762
|
attempt: message.attempt + 1
|
|
2792
|
-
}, { delay: Temporal.Duration.compare(delay
|
|
2793
|
-
} else logger
|
|
2763
|
+
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2764
|
+
} else logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
2794
2765
|
error,
|
|
2795
2766
|
activityId: activity.id?.href,
|
|
2796
2767
|
activity: message.activity,
|
|
2797
2768
|
recipient: message.identifier
|
|
2798
2769
|
});
|
|
2799
|
-
span
|
|
2770
|
+
span.setStatus({
|
|
2800
2771
|
code: SpanStatusCode.ERROR,
|
|
2801
2772
|
message: String(error)
|
|
2802
2773
|
});
|
|
2803
|
-
span
|
|
2774
|
+
span.end();
|
|
2804
2775
|
return;
|
|
2805
2776
|
}
|
|
2806
2777
|
if (cacheKey != null) await this.kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
2807
|
-
logger
|
|
2778
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
2808
2779
|
activityId: activity.id?.href,
|
|
2809
2780
|
activity: message.activity,
|
|
2810
2781
|
recipient: message.identifier
|
|
2811
2782
|
});
|
|
2812
|
-
span
|
|
2783
|
+
span.end();
|
|
2813
2784
|
});
|
|
2814
2785
|
}
|
|
2815
2786
|
startQueue(contextData, options = {}) {
|
|
@@ -2853,7 +2824,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2853
2824
|
};
|
|
2854
2825
|
}
|
|
2855
2826
|
async sendActivity(keys, inboxes, activity, options) {
|
|
2856
|
-
const logger
|
|
2827
|
+
const logger = getLogger([
|
|
2857
2828
|
"fedify",
|
|
2858
2829
|
"federation",
|
|
2859
2830
|
"outbox"
|
|
@@ -2887,7 +2858,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2887
2858
|
format: "compact",
|
|
2888
2859
|
contextLoader
|
|
2889
2860
|
});
|
|
2890
|
-
if (rsaKey == null) logger
|
|
2861
|
+
if (rsaKey == null) logger.warn("No supported key found to create a Linked Data signature for the activity {activityId}. The activity will be sent without a Linked Data signature. In order to create a Linked Data signature, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
|
|
2891
2862
|
activityId,
|
|
2892
2863
|
keys: keys.map((pair) => ({
|
|
2893
2864
|
keyId: pair.keyId.href,
|
|
@@ -2898,7 +2869,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2898
2869
|
contextLoader,
|
|
2899
2870
|
tracerProvider: this.tracerProvider
|
|
2900
2871
|
});
|
|
2901
|
-
if (!proofCreated) logger
|
|
2872
|
+
if (!proofCreated) logger.warn("No supported key found to create a proof for the activity {activityId}. The activity will be sent without a proof. In order to create a proof, at least one Ed25519 key must be provided.", {
|
|
2902
2873
|
activityId,
|
|
2903
2874
|
keys: keys.map((pair) => ({
|
|
2904
2875
|
keyId: pair.keyId.href,
|
|
@@ -2906,11 +2877,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2906
2877
|
}))
|
|
2907
2878
|
});
|
|
2908
2879
|
if (immediate || this.outboxQueue == null) {
|
|
2909
|
-
if (immediate) logger
|
|
2880
|
+
if (immediate) logger.debug("Sending activity immediately without queue since immediate option is set.", {
|
|
2910
2881
|
activityId: activity.id.href,
|
|
2911
2882
|
activity: jsonLd
|
|
2912
2883
|
});
|
|
2913
|
-
else logger
|
|
2884
|
+
else logger.debug("Sending activity immediately without queue since queue is not set.", {
|
|
2914
2885
|
activityId: activity.id.href,
|
|
2915
2886
|
activity: jsonLd
|
|
2916
2887
|
});
|
|
@@ -2929,7 +2900,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2929
2900
|
await Promise.all(promises);
|
|
2930
2901
|
return;
|
|
2931
2902
|
}
|
|
2932
|
-
logger
|
|
2903
|
+
logger.debug("Enqueuing activity {activityId} to send later.", {
|
|
2933
2904
|
activityId: activity.id.href,
|
|
2934
2905
|
activity: jsonLd
|
|
2935
2906
|
});
|
|
@@ -2966,10 +2937,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2966
2937
|
const { outboxQueue } = this;
|
|
2967
2938
|
if (outboxQueue.enqueueMany == null) {
|
|
2968
2939
|
const promises = messages.map((m) => outboxQueue.enqueue(m));
|
|
2969
|
-
const
|
|
2970
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2940
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2971
2941
|
if (errors.length > 0) {
|
|
2972
|
-
logger
|
|
2942
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
2973
2943
|
activityId: activity.id.href,
|
|
2974
2944
|
errors
|
|
2975
2945
|
});
|
|
@@ -2979,7 +2949,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2979
2949
|
} else try {
|
|
2980
2950
|
await outboxQueue.enqueueMany(messages);
|
|
2981
2951
|
} catch (error) {
|
|
2982
|
-
logger
|
|
2952
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
2983
2953
|
activityId: activity.id.href,
|
|
2984
2954
|
error
|
|
2985
2955
|
});
|
|
@@ -2987,8 +2957,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2987
2957
|
}
|
|
2988
2958
|
}
|
|
2989
2959
|
fetch(request, options) {
|
|
2990
|
-
|
|
2991
|
-
return withContext({ requestId }, async () => {
|
|
2960
|
+
return withContext({ requestId: getRequestId(request) }, async () => {
|
|
2992
2961
|
const tracer = this._getTracer();
|
|
2993
2962
|
return await tracer.startActiveSpan(request.method, {
|
|
2994
2963
|
kind: SpanKind.SERVER,
|
|
@@ -2997,7 +2966,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2997
2966
|
[ATTR_URL_FULL]: request.url
|
|
2998
2967
|
}
|
|
2999
2968
|
}, async (span) => {
|
|
3000
|
-
const logger
|
|
2969
|
+
const logger = getLogger([
|
|
3001
2970
|
"fedify",
|
|
3002
2971
|
"federation",
|
|
3003
2972
|
"http"
|
|
@@ -3016,7 +2985,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3016
2985
|
message: `${error}`
|
|
3017
2986
|
});
|
|
3018
2987
|
span.end();
|
|
3019
|
-
logger
|
|
2988
|
+
logger.error("An error occurred while serving request {method} {url}: {error}", {
|
|
3020
2989
|
method: request.method,
|
|
3021
2990
|
url: request.url,
|
|
3022
2991
|
error
|
|
@@ -3040,9 +3009,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3040
3009
|
url: request.url,
|
|
3041
3010
|
status: response.status
|
|
3042
3011
|
};
|
|
3043
|
-
if (response.status >= 500) logger
|
|
3044
|
-
else if (response.status >= 400) logger
|
|
3045
|
-
else logger
|
|
3012
|
+
if (response.status >= 500) logger.error(logTpl, values);
|
|
3013
|
+
else if (response.status >= 400) logger.warn(logTpl, values);
|
|
3014
|
+
else logger.info(logTpl, values);
|
|
3046
3015
|
return response;
|
|
3047
3016
|
});
|
|
3048
3017
|
});
|
|
@@ -3055,11 +3024,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3055
3024
|
const route = this.router.route(url.pathname);
|
|
3056
3025
|
if (route == null) return await onNotFound(request);
|
|
3057
3026
|
span.updateName(`${request.method} ${route.template}`);
|
|
3058
|
-
let context
|
|
3027
|
+
let context = this.#createContext(request, contextData);
|
|
3059
3028
|
const routeName = route.name.replace(/:.*$/, "");
|
|
3060
3029
|
switch (routeName) {
|
|
3061
3030
|
case "webfinger": return await handleWebFinger(request, {
|
|
3062
|
-
context
|
|
3031
|
+
context,
|
|
3063
3032
|
host: this.origin?.handleHost,
|
|
3064
3033
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3065
3034
|
actorHandleMapper: this.actorCallbacks?.handleMapper,
|
|
@@ -3068,16 +3037,16 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3068
3037
|
onNotFound,
|
|
3069
3038
|
tracer
|
|
3070
3039
|
});
|
|
3071
|
-
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context
|
|
3040
|
+
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context);
|
|
3072
3041
|
case "nodeInfo": return await handleNodeInfo(request, {
|
|
3073
|
-
context
|
|
3042
|
+
context,
|
|
3074
3043
|
nodeInfoDispatcher: this.nodeInfoDispatcher
|
|
3075
3044
|
});
|
|
3076
3045
|
case "actor":
|
|
3077
|
-
context
|
|
3046
|
+
context = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier: route.values.identifier ?? route.values.handle } });
|
|
3078
3047
|
return await handleActor(request, {
|
|
3079
3048
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3080
|
-
context
|
|
3049
|
+
context,
|
|
3081
3050
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3082
3051
|
authorizePredicate: this.actorCallbacks?.authorizePredicate,
|
|
3083
3052
|
onUnauthorized,
|
|
@@ -3088,13 +3057,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3088
3057
|
const typeId = route.name.replace(/^object:/, "");
|
|
3089
3058
|
const callbacks = this.objectCallbacks[typeId];
|
|
3090
3059
|
const cls = this.objectTypeIds[typeId];
|
|
3091
|
-
context
|
|
3060
|
+
context = this.#createContext(request, contextData, { invokedFromObjectDispatcher: {
|
|
3092
3061
|
cls,
|
|
3093
3062
|
values: route.values
|
|
3094
3063
|
} });
|
|
3095
3064
|
return await handleObject(request, {
|
|
3096
3065
|
values: route.values,
|
|
3097
|
-
context
|
|
3066
|
+
context,
|
|
3098
3067
|
objectDispatcher: callbacks?.dispatcher,
|
|
3099
3068
|
authorizePredicate: callbacks?.authorizePredicate,
|
|
3100
3069
|
onUnauthorized,
|
|
@@ -3105,8 +3074,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3105
3074
|
case "outbox": return await handleCollection(request, {
|
|
3106
3075
|
name: "outbox",
|
|
3107
3076
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3108
|
-
uriGetter: context
|
|
3109
|
-
context
|
|
3077
|
+
uriGetter: context.getOutboxUri.bind(context),
|
|
3078
|
+
context,
|
|
3110
3079
|
collectionCallbacks: this.outboxCallbacks,
|
|
3111
3080
|
tracerProvider: this.tracerProvider,
|
|
3112
3081
|
onUnauthorized,
|
|
@@ -3117,25 +3086,25 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3117
3086
|
if (request.method !== "POST") return await handleCollection(request, {
|
|
3118
3087
|
name: "inbox",
|
|
3119
3088
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3120
|
-
uriGetter: context
|
|
3121
|
-
context
|
|
3089
|
+
uriGetter: context.getInboxUri.bind(context),
|
|
3090
|
+
context,
|
|
3122
3091
|
collectionCallbacks: this.inboxCallbacks,
|
|
3123
3092
|
tracerProvider: this.tracerProvider,
|
|
3124
3093
|
onUnauthorized,
|
|
3125
3094
|
onNotFound,
|
|
3126
3095
|
onNotAcceptable
|
|
3127
3096
|
});
|
|
3128
|
-
context
|
|
3097
|
+
context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier: route.values.identifier ?? route.values.handle }) });
|
|
3129
3098
|
case "sharedInbox":
|
|
3130
3099
|
if (routeName !== "inbox" && this.sharedInboxKeyDispatcher != null) {
|
|
3131
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
3132
|
-
if (identity != null) context
|
|
3100
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
3101
|
+
if (identity != null) context = this.#createContext(request, contextData, { documentLoader: "identifier" in identity || "username" in identity || "handle" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
3133
3102
|
}
|
|
3134
3103
|
if (!this.manuallyStartQueue) this._startQueueInternal(contextData);
|
|
3135
3104
|
return await handleInbox(request, {
|
|
3136
3105
|
recipient: route.values.identifier ?? route.values.handle ?? null,
|
|
3137
|
-
context
|
|
3138
|
-
inboxContextFactory: context
|
|
3106
|
+
context,
|
|
3107
|
+
inboxContextFactory: context.toInboxContext.bind(context),
|
|
3139
3108
|
kv: this.kv,
|
|
3140
3109
|
kvPrefixes: this.kvPrefixes,
|
|
3141
3110
|
queue: this.inboxQueue,
|
|
@@ -3151,8 +3120,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3151
3120
|
case "following": return await handleCollection(request, {
|
|
3152
3121
|
name: "following",
|
|
3153
3122
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3154
|
-
uriGetter: context
|
|
3155
|
-
context
|
|
3123
|
+
uriGetter: context.getFollowingUri.bind(context),
|
|
3124
|
+
context,
|
|
3156
3125
|
collectionCallbacks: this.followingCallbacks,
|
|
3157
3126
|
tracerProvider: this.tracerProvider,
|
|
3158
3127
|
onUnauthorized,
|
|
@@ -3169,14 +3138,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3169
3138
|
return await handleCollection(request, {
|
|
3170
3139
|
name: "followers",
|
|
3171
3140
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3172
|
-
uriGetter: baseUrl == null ? context
|
|
3173
|
-
const uri = context
|
|
3141
|
+
uriGetter: baseUrl == null ? context.getFollowersUri.bind(context) : (identifier) => {
|
|
3142
|
+
const uri = context.getFollowersUri(identifier);
|
|
3174
3143
|
uri.searchParams.set("base-url", baseUrl);
|
|
3175
3144
|
return uri;
|
|
3176
3145
|
},
|
|
3177
|
-
context
|
|
3146
|
+
context,
|
|
3178
3147
|
filter: baseUrl != null ? new URL(baseUrl) : void 0,
|
|
3179
|
-
filterPredicate: baseUrl != null ? (i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl) : void 0,
|
|
3148
|
+
filterPredicate: baseUrl != null ? ((i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl)) : void 0,
|
|
3180
3149
|
collectionCallbacks: this.followersCallbacks,
|
|
3181
3150
|
tracerProvider: this.tracerProvider,
|
|
3182
3151
|
onUnauthorized,
|
|
@@ -3187,8 +3156,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3187
3156
|
case "liked": return await handleCollection(request, {
|
|
3188
3157
|
name: "liked",
|
|
3189
3158
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3190
|
-
uriGetter: context
|
|
3191
|
-
context
|
|
3159
|
+
uriGetter: context.getLikedUri.bind(context),
|
|
3160
|
+
context,
|
|
3192
3161
|
collectionCallbacks: this.likedCallbacks,
|
|
3193
3162
|
tracerProvider: this.tracerProvider,
|
|
3194
3163
|
onUnauthorized,
|
|
@@ -3198,8 +3167,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3198
3167
|
case "featured": return await handleCollection(request, {
|
|
3199
3168
|
name: "featured",
|
|
3200
3169
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3201
|
-
uriGetter: context
|
|
3202
|
-
context
|
|
3170
|
+
uriGetter: context.getFeaturedUri.bind(context),
|
|
3171
|
+
context,
|
|
3203
3172
|
collectionCallbacks: this.featuredCallbacks,
|
|
3204
3173
|
tracerProvider: this.tracerProvider,
|
|
3205
3174
|
onUnauthorized,
|
|
@@ -3209,8 +3178,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3209
3178
|
case "featuredTags": return await handleCollection(request, {
|
|
3210
3179
|
name: "featured tags",
|
|
3211
3180
|
identifier: route.values.identifier ?? route.values.handle,
|
|
3212
|
-
uriGetter: context
|
|
3213
|
-
context
|
|
3181
|
+
uriGetter: context.getFeaturedTagsUri.bind(context),
|
|
3182
|
+
context,
|
|
3214
3183
|
collectionCallbacks: this.featuredTagsCallbacks,
|
|
3215
3184
|
tracerProvider: this.tracerProvider,
|
|
3216
3185
|
onUnauthorized,
|
|
@@ -3222,7 +3191,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3222
3191
|
const callbacks = this.collectionCallbacks[name];
|
|
3223
3192
|
return await handleCustomCollection(request, {
|
|
3224
3193
|
name,
|
|
3225
|
-
context
|
|
3194
|
+
context,
|
|
3226
3195
|
values: route.values,
|
|
3227
3196
|
collectionCallbacks: callbacks,
|
|
3228
3197
|
tracerProvider: this.tracerProvider,
|
|
@@ -3236,7 +3205,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3236
3205
|
const callbacks = this.collectionCallbacks[name];
|
|
3237
3206
|
return await handleOrderedCollection(request, {
|
|
3238
3207
|
name,
|
|
3239
|
-
context
|
|
3208
|
+
context,
|
|
3240
3209
|
values: route.values,
|
|
3241
3210
|
collectionCallbacks: callbacks,
|
|
3242
3211
|
tracerProvider: this.tracerProvider,
|
|
@@ -3334,9 +3303,9 @@ var ContextImpl = class ContextImpl {
|
|
|
3334
3303
|
}
|
|
3335
3304
|
getInboxUri(identifier) {
|
|
3336
3305
|
if (identifier == null) {
|
|
3337
|
-
const path
|
|
3338
|
-
if (path
|
|
3339
|
-
return new URL(path
|
|
3306
|
+
const path = this.federation.router.build("sharedInbox", {});
|
|
3307
|
+
if (path == null) throw new RouterError("No shared inbox path registered.");
|
|
3308
|
+
return new URL(path, this.canonicalOrigin);
|
|
3340
3309
|
}
|
|
3341
3310
|
const path = this.federation.router.build("inbox", {
|
|
3342
3311
|
identifier,
|
|
@@ -3394,14 +3363,13 @@ var ContextImpl = class ContextImpl {
|
|
|
3394
3363
|
if (uri == null) return null;
|
|
3395
3364
|
if (uri.origin !== this.origin && uri.origin !== this.canonicalOrigin) return null;
|
|
3396
3365
|
const route = this.federation.router.route(uri.pathname);
|
|
3397
|
-
const logger
|
|
3366
|
+
const logger = getLogger(["fedify", "federation"]);
|
|
3398
3367
|
if (route == null) return null;
|
|
3399
3368
|
else if (route.name === "sharedInbox") return {
|
|
3400
3369
|
type: "inbox",
|
|
3401
3370
|
identifier: void 0,
|
|
3402
3371
|
get handle() {
|
|
3403
|
-
logger
|
|
3404
|
-
return void 0;
|
|
3372
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3405
3373
|
}
|
|
3406
3374
|
};
|
|
3407
3375
|
const identifier = "identifier" in route.values ? route.values.identifier : route.values.handle;
|
|
@@ -3409,7 +3377,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3409
3377
|
type: "actor",
|
|
3410
3378
|
identifier,
|
|
3411
3379
|
get handle() {
|
|
3412
|
-
logger
|
|
3380
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3413
3381
|
return identifier;
|
|
3414
3382
|
}
|
|
3415
3383
|
};
|
|
@@ -3425,7 +3393,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3425
3393
|
type: "inbox",
|
|
3426
3394
|
identifier,
|
|
3427
3395
|
get handle() {
|
|
3428
|
-
logger
|
|
3396
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3429
3397
|
return identifier;
|
|
3430
3398
|
}
|
|
3431
3399
|
};
|
|
@@ -3433,7 +3401,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3433
3401
|
type: "outbox",
|
|
3434
3402
|
identifier,
|
|
3435
3403
|
get handle() {
|
|
3436
|
-
logger
|
|
3404
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3437
3405
|
return identifier;
|
|
3438
3406
|
}
|
|
3439
3407
|
};
|
|
@@ -3441,7 +3409,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3441
3409
|
type: "following",
|
|
3442
3410
|
identifier,
|
|
3443
3411
|
get handle() {
|
|
3444
|
-
logger
|
|
3412
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3445
3413
|
return identifier;
|
|
3446
3414
|
}
|
|
3447
3415
|
};
|
|
@@ -3449,7 +3417,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3449
3417
|
type: "followers",
|
|
3450
3418
|
identifier,
|
|
3451
3419
|
get handle() {
|
|
3452
|
-
logger
|
|
3420
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3453
3421
|
return identifier;
|
|
3454
3422
|
}
|
|
3455
3423
|
};
|
|
@@ -3457,7 +3425,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3457
3425
|
type: "liked",
|
|
3458
3426
|
identifier,
|
|
3459
3427
|
get handle() {
|
|
3460
|
-
logger
|
|
3428
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3461
3429
|
return identifier;
|
|
3462
3430
|
}
|
|
3463
3431
|
};
|
|
@@ -3465,7 +3433,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3465
3433
|
type: "featured",
|
|
3466
3434
|
identifier,
|
|
3467
3435
|
get handle() {
|
|
3468
|
-
logger
|
|
3436
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3469
3437
|
return identifier;
|
|
3470
3438
|
}
|
|
3471
3439
|
};
|
|
@@ -3473,12 +3441,11 @@ var ContextImpl = class ContextImpl {
|
|
|
3473
3441
|
type: "featuredTags",
|
|
3474
3442
|
identifier,
|
|
3475
3443
|
get handle() {
|
|
3476
|
-
logger
|
|
3444
|
+
logger.warn("The ParseUriResult.handle property is deprecated; use ParseUriResult.identifier instead.");
|
|
3477
3445
|
return identifier;
|
|
3478
3446
|
}
|
|
3479
3447
|
};
|
|
3480
|
-
const
|
|
3481
|
-
const collectionRegex = /* @__PURE__ */ new RegExp(`^(${collectionTypes.join("|")}):(.*)$`);
|
|
3448
|
+
const collectionRegex = new RegExp(`^(${["collection", "orderedCollection"].join("|")}):(.*)$`);
|
|
3482
3449
|
const match = route.name.match(collectionRegex);
|
|
3483
3450
|
if (match !== null) {
|
|
3484
3451
|
const [, type, name] = match;
|
|
@@ -3494,12 +3461,12 @@ var ContextImpl = class ContextImpl {
|
|
|
3494
3461
|
return null;
|
|
3495
3462
|
}
|
|
3496
3463
|
async getActorKeyPairs(identifier) {
|
|
3497
|
-
const logger
|
|
3464
|
+
const logger = getLogger([
|
|
3498
3465
|
"fedify",
|
|
3499
3466
|
"federation",
|
|
3500
3467
|
"actor"
|
|
3501
3468
|
]);
|
|
3502
|
-
if (this.invokedFromActorKeyPairsDispatcher != null) logger
|
|
3469
|
+
if (this.invokedFromActorKeyPairsDispatcher != null) logger.warn("Context.getActorKeyPairs({getActorKeyPairsIdentifier}) method is invoked from the actor key pairs dispatcher ({actorKeyPairsDispatcherIdentifier}); this may cause an infinite loop.", {
|
|
3503
3470
|
getActorKeyPairsIdentifier: identifier,
|
|
3504
3471
|
actorKeyPairsDispatcherIdentifier: this.invokedFromActorKeyPairsDispatcher.identifier
|
|
3505
3472
|
});
|
|
@@ -3507,7 +3474,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3507
3474
|
try {
|
|
3508
3475
|
keyPairs = await this.getKeyPairsFromIdentifier(identifier);
|
|
3509
3476
|
} catch (_) {
|
|
3510
|
-
logger
|
|
3477
|
+
logger.warn("No actor key pairs dispatcher registered.");
|
|
3511
3478
|
return [];
|
|
3512
3479
|
}
|
|
3513
3480
|
const owner = this.getActorUri(identifier);
|
|
@@ -3531,7 +3498,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3531
3498
|
return result;
|
|
3532
3499
|
}
|
|
3533
3500
|
async getKeyPairsFromIdentifier(identifier) {
|
|
3534
|
-
const logger
|
|
3501
|
+
const logger = getLogger([
|
|
3535
3502
|
"fedify",
|
|
3536
3503
|
"federation",
|
|
3537
3504
|
"actor"
|
|
@@ -3542,7 +3509,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3542
3509
|
actorUri = this.getActorUri(identifier);
|
|
3543
3510
|
} catch (error) {
|
|
3544
3511
|
if (error instanceof RouterError) {
|
|
3545
|
-
logger
|
|
3512
|
+
logger.warn(error.message);
|
|
3546
3513
|
return [];
|
|
3547
3514
|
}
|
|
3548
3515
|
throw error;
|
|
@@ -3551,7 +3518,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3551
3518
|
...this,
|
|
3552
3519
|
invokedFromActorKeyPairsDispatcher: { identifier }
|
|
3553
3520
|
}), identifier);
|
|
3554
|
-
if (keyPairs.length < 1) logger
|
|
3521
|
+
if (keyPairs.length < 1) logger.warn("No key pairs found for actor {identifier}.", { identifier });
|
|
3555
3522
|
let i = 0;
|
|
3556
3523
|
const result = [];
|
|
3557
3524
|
for (const keyPair of keyPairs) {
|
|
@@ -3599,8 +3566,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3599
3566
|
} else identifierPromise = Promise.resolve(identity.identifier);
|
|
3600
3567
|
return identifierPromise.then((identifier) => {
|
|
3601
3568
|
if (identifier == null) return this.documentLoader;
|
|
3602
|
-
|
|
3603
|
-
return keyPair.then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
3569
|
+
return this.getRsaKeyPairFromIdentifier(identifier).then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
3604
3570
|
});
|
|
3605
3571
|
}
|
|
3606
3572
|
return this.federation.authenticatedDocumentLoaderFactory(identity);
|
|
@@ -3642,8 +3608,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3642
3608
|
});
|
|
3643
3609
|
}
|
|
3644
3610
|
sendActivity(sender, recipients, activity, options = {}) {
|
|
3645
|
-
|
|
3646
|
-
return tracer.startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
3611
|
+
return this.tracerProvider.getTracer(name, version).startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
3647
3612
|
kind: this.federation.outboxQueue == null || options.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
3648
3613
|
attributes: {
|
|
3649
3614
|
"activitypub.activity.type": getTypeId(activity).href,
|
|
@@ -3668,7 +3633,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3668
3633
|
});
|
|
3669
3634
|
}
|
|
3670
3635
|
async sendActivityInternal(sender, recipients, activity, options, span) {
|
|
3671
|
-
const logger
|
|
3636
|
+
const logger = getLogger([
|
|
3672
3637
|
"fedify",
|
|
3673
3638
|
"federation",
|
|
3674
3639
|
"outbox"
|
|
@@ -3682,7 +3647,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3682
3647
|
if ("username" in sender) username = sender.username;
|
|
3683
3648
|
else {
|
|
3684
3649
|
username = sender.handle;
|
|
3685
|
-
logger
|
|
3650
|
+
logger.warn("The \"handle\" property for the sender parameter is deprecated; use \"identifier\" or \"username\" instead.", { sender });
|
|
3686
3651
|
}
|
|
3687
3652
|
if (this.federation.actorCallbacks?.handleMapper == null) identifier = username;
|
|
3688
3653
|
else {
|
|
@@ -3718,7 +3683,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3718
3683
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
3719
3684
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
3720
3685
|
if (activity.actorId == null) {
|
|
3721
|
-
logger
|
|
3686
|
+
logger.error("Activity {activityId} to send does not have an actor.", {
|
|
3722
3687
|
activity,
|
|
3723
3688
|
activityId: activity?.id?.href
|
|
3724
3689
|
});
|
|
@@ -3729,7 +3694,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3729
3694
|
preferSharedInbox: options.preferSharedInbox,
|
|
3730
3695
|
excludeBaseUris: options.excludeBaseUris
|
|
3731
3696
|
});
|
|
3732
|
-
logger
|
|
3697
|
+
logger.debug("Sending activity {activityId} to inboxes:\n{inboxes}", {
|
|
3733
3698
|
inboxes: globalThis.Object.keys(inboxes),
|
|
3734
3699
|
activityId: activity.id?.href,
|
|
3735
3700
|
activity
|
|
@@ -3763,7 +3728,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3763
3728
|
traceContext: carrier
|
|
3764
3729
|
};
|
|
3765
3730
|
if (!this.federation.manuallyStartQueue) this.federation._startQueueInternal(this.data);
|
|
3766
|
-
this.federation.fanoutQueue.enqueue(message);
|
|
3731
|
+
await this.federation.fanoutQueue.enqueue(message);
|
|
3767
3732
|
}
|
|
3768
3733
|
async *getFollowers(identifier) {
|
|
3769
3734
|
if (this.federation.followersCallbacks == null) throw new Error("No followers collection dispatcher registered.");
|
|
@@ -3780,16 +3745,14 @@ var ContextImpl = class ContextImpl {
|
|
|
3780
3745
|
"outbox"
|
|
3781
3746
|
]).warn("Since the followers collection dispatcher returned null for no cursor (i.e., one-shot dispatcher), the pagination is used to fetch \"followers\". However, it is recommended to implement the one-shot dispatcher for better performance.", { identifier });
|
|
3782
3747
|
while (cursor != null) {
|
|
3783
|
-
const result
|
|
3784
|
-
if (result
|
|
3785
|
-
for (const recipient of result
|
|
3786
|
-
cursor = result
|
|
3748
|
+
const result = await this.federation.followersCallbacks.dispatcher(this, identifier, cursor);
|
|
3749
|
+
if (result == null) break;
|
|
3750
|
+
for (const recipient of result.items) yield recipient;
|
|
3751
|
+
cursor = result.nextCursor ?? null;
|
|
3787
3752
|
}
|
|
3788
3753
|
}
|
|
3789
3754
|
routeActivity(recipient, activity, options = {}) {
|
|
3790
|
-
|
|
3791
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
3792
|
-
return tracer.startActiveSpan("activitypub.inbox", {
|
|
3755
|
+
return (this.tracerProvider ?? this.tracerProvider).getTracer(name, version).startActiveSpan("activitypub.inbox", {
|
|
3793
3756
|
kind: this.federation.inboxQueue == null || options.immediate ? SpanKind.INTERNAL : SpanKind.PRODUCER,
|
|
3794
3757
|
attributes: { "activitypub.activity.type": getTypeId(activity).href }
|
|
3795
3758
|
}, async (span) => {
|
|
@@ -3817,7 +3780,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3817
3780
|
});
|
|
3818
3781
|
}
|
|
3819
3782
|
async routeActivityInternal(recipient, activity, options = {}, span) {
|
|
3820
|
-
const logger
|
|
3783
|
+
const logger = getLogger([
|
|
3821
3784
|
"fedify",
|
|
3822
3785
|
"federation",
|
|
3823
3786
|
"inbox"
|
|
@@ -3825,19 +3788,18 @@ var ContextImpl = class ContextImpl {
|
|
|
3825
3788
|
const contextLoader = options.contextLoader ?? this.contextLoader;
|
|
3826
3789
|
const json = await activity.toJsonLd({ contextLoader });
|
|
3827
3790
|
const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, this);
|
|
3828
|
-
|
|
3791
|
+
if (await verifyObject(Activity, json, {
|
|
3829
3792
|
contextLoader,
|
|
3830
3793
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3831
3794
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
3832
3795
|
keyCache
|
|
3833
|
-
})
|
|
3834
|
-
|
|
3835
|
-
logger$1.debug("Object Integrity Proofs are not verified.", {
|
|
3796
|
+
}) == null) {
|
|
3797
|
+
logger.debug("Object Integrity Proofs are not verified.", {
|
|
3836
3798
|
recipient,
|
|
3837
3799
|
activity: json
|
|
3838
3800
|
});
|
|
3839
3801
|
if (activity.id == null) {
|
|
3840
|
-
logger
|
|
3802
|
+
logger.debug("Activity is missing an ID; unable to fetch.", {
|
|
3841
3803
|
recipient,
|
|
3842
3804
|
activity: json
|
|
3843
3805
|
});
|
|
@@ -3845,26 +3807,26 @@ var ContextImpl = class ContextImpl {
|
|
|
3845
3807
|
}
|
|
3846
3808
|
const fetched = await this.lookupObject(activity.id, options);
|
|
3847
3809
|
if (fetched == null) {
|
|
3848
|
-
logger
|
|
3810
|
+
logger.debug("Failed to fetch the remote activity object {activityId}.", {
|
|
3849
3811
|
recipient,
|
|
3850
3812
|
activity: json,
|
|
3851
3813
|
activityId: activity.id.href
|
|
3852
3814
|
});
|
|
3853
3815
|
return false;
|
|
3854
3816
|
} else if (!(fetched instanceof Activity)) {
|
|
3855
|
-
logger
|
|
3817
|
+
logger.debug("Fetched object is not an Activity.", {
|
|
3856
3818
|
recipient,
|
|
3857
3819
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3858
3820
|
});
|
|
3859
3821
|
return false;
|
|
3860
3822
|
} else if (fetched.id?.href !== activity.id.href) {
|
|
3861
|
-
logger
|
|
3823
|
+
logger.debug("Fetched activity object has a different ID; failed to verify.", {
|
|
3862
3824
|
recipient,
|
|
3863
3825
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3864
3826
|
});
|
|
3865
3827
|
return false;
|
|
3866
3828
|
} else if (fetched.actorIds.length < 1) {
|
|
3867
|
-
logger
|
|
3829
|
+
logger.debug("Fetched activity object is missing an actor; unable to verify.", {
|
|
3868
3830
|
recipient,
|
|
3869
3831
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3870
3832
|
});
|
|
@@ -3872,15 +3834,15 @@ var ContextImpl = class ContextImpl {
|
|
|
3872
3834
|
}
|
|
3873
3835
|
const activityId = fetched.id;
|
|
3874
3836
|
if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
|
|
3875
|
-
logger
|
|
3837
|
+
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
3876
3838
|
recipient,
|
|
3877
3839
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3878
3840
|
});
|
|
3879
3841
|
return false;
|
|
3880
3842
|
}
|
|
3881
|
-
logger
|
|
3843
|
+
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
3882
3844
|
activity = fetched;
|
|
3883
|
-
} else logger
|
|
3845
|
+
} else logger.debug("Object Integrity Proofs are verified.", {
|
|
3884
3846
|
recipient,
|
|
3885
3847
|
activity: json
|
|
3886
3848
|
});
|
|
@@ -4006,8 +3968,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4006
3968
|
});
|
|
4007
3969
|
}
|
|
4008
3970
|
forwardActivity(forwarder, recipients, options) {
|
|
4009
|
-
|
|
4010
|
-
return tracer.startActiveSpan("activitypub.outbox", {
|
|
3971
|
+
return this.tracerProvider.getTracer(name, version).startActiveSpan("activitypub.outbox", {
|
|
4011
3972
|
kind: this.federation.outboxQueue == null || options?.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
4012
3973
|
attributes: { "activitypub.activity.type": this.activityType }
|
|
4013
3974
|
}, async (span) => {
|
|
@@ -4026,7 +3987,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4026
3987
|
});
|
|
4027
3988
|
}
|
|
4028
3989
|
async forwardActivityInternal(forwarder, recipients, options) {
|
|
4029
|
-
const logger
|
|
3990
|
+
const logger = getLogger([
|
|
4030
3991
|
"fedify",
|
|
4031
3992
|
"federation",
|
|
4032
3993
|
"inbox"
|
|
@@ -4040,7 +4001,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4040
4001
|
if ("username" in forwarder) username = forwarder.username;
|
|
4041
4002
|
else {
|
|
4042
4003
|
username = forwarder.handle;
|
|
4043
|
-
logger
|
|
4004
|
+
logger.warn("The \"handle\" property for the forwarder parameter is deprecated; use \"identifier\" or \"username\" instead.", { forwarder });
|
|
4044
4005
|
}
|
|
4045
4006
|
if (this.federation.actorCallbacks?.handleMapper == null) identifier = username;
|
|
4046
4007
|
else {
|
|
@@ -4058,14 +4019,13 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4058
4019
|
if (!hasSignature(this.activity)) {
|
|
4059
4020
|
let hasProof;
|
|
4060
4021
|
try {
|
|
4061
|
-
|
|
4062
|
-
hasProof = await activity.getProof() != null;
|
|
4022
|
+
hasProof = await (await Activity.fromJsonLd(this.activity, this)).getProof() != null;
|
|
4063
4023
|
} catch {
|
|
4064
4024
|
hasProof = false;
|
|
4065
4025
|
}
|
|
4066
4026
|
if (!hasProof) {
|
|
4067
4027
|
if (options?.skipIfUnsigned) return;
|
|
4068
|
-
logger
|
|
4028
|
+
logger.warn("The received activity {activityId} is not signed; even if it is forwarded to other servers as is, it may not be accepted by them due to the lack of a signature/proof.");
|
|
4069
4029
|
}
|
|
4070
4030
|
}
|
|
4071
4031
|
if (recipients === "followers") {
|
|
@@ -4079,14 +4039,14 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4079
4039
|
preferSharedInbox: options?.preferSharedInbox,
|
|
4080
4040
|
excludeBaseUris: options?.excludeBaseUris
|
|
4081
4041
|
});
|
|
4082
|
-
logger
|
|
4042
|
+
logger.debug("Forwarding activity {activityId} to inboxes:\n{inboxes}", {
|
|
4083
4043
|
inboxes: globalThis.Object.keys(inboxes),
|
|
4084
4044
|
activityId: this.activityId,
|
|
4085
4045
|
activity: this.activity
|
|
4086
4046
|
});
|
|
4087
4047
|
if (options?.immediate || this.federation.outboxQueue == null) {
|
|
4088
|
-
if (options?.immediate) logger
|
|
4089
|
-
else logger
|
|
4048
|
+
if (options?.immediate) logger.debug("Forwarding activity immediately without queue since immediate option is set.");
|
|
4049
|
+
else logger.debug("Forwarding activity immediately without queue since queue is not set.");
|
|
4090
4050
|
const promises = [];
|
|
4091
4051
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
4092
4052
|
keys,
|
|
@@ -4101,7 +4061,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4101
4061
|
await Promise.all(promises);
|
|
4102
4062
|
return;
|
|
4103
4063
|
}
|
|
4104
|
-
logger
|
|
4064
|
+
logger.debug("Enqueuing activity {activityId} to forward later.", {
|
|
4105
4065
|
activityId: this.activityId,
|
|
4106
4066
|
activity: this.activity
|
|
4107
4067
|
});
|
|
@@ -4137,10 +4097,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4137
4097
|
const { outboxQueue } = this.federation;
|
|
4138
4098
|
if (outboxQueue.enqueueMany == null) {
|
|
4139
4099
|
const promises = messages.map((m) => outboxQueue.enqueue(m));
|
|
4140
|
-
const
|
|
4141
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4100
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4142
4101
|
if (errors.length > 0) {
|
|
4143
|
-
logger
|
|
4102
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4144
4103
|
activityId: this.activityId,
|
|
4145
4104
|
errors
|
|
4146
4105
|
});
|
|
@@ -4150,7 +4109,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4150
4109
|
} else try {
|
|
4151
4110
|
await outboxQueue.enqueueMany(messages);
|
|
4152
4111
|
} catch (error) {
|
|
4153
|
-
logger
|
|
4112
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
|
|
4154
4113
|
activityId: this.activityId,
|
|
4155
4114
|
error
|
|
4156
4115
|
});
|
|
@@ -4205,10 +4164,7 @@ function unauthorized(_request) {
|
|
|
4205
4164
|
function getRequestId(request) {
|
|
4206
4165
|
const traceId = request.headers.get("X-Request-Id") || request.headers.get("X-Correlation-Id") || request.headers.get("Traceparent")?.split("-")[1];
|
|
4207
4166
|
if (traceId != null) return traceId;
|
|
4208
|
-
|
|
4209
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
4210
|
-
return `req_${timestamp}${random}`;
|
|
4167
|
+
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
4211
4168
|
}
|
|
4212
|
-
|
|
4213
4169
|
//#endregion
|
|
4214
|
-
export {
|
|
4170
|
+
export { respondWithObjectIfAcceptable as a, createFederationBuilder as c, respondWithObject as i, Router$1 as l, middleware_exports as n, buildCollectionSynchronizationHeader as o, createExponentialBackoffPolicy as r, digest as s, createFederation as t, RouterError as u };
|