@fedify/fedify 2.0.0-pr.490.2 → 2.0.0-pr.559.4
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/LICENSE +1 -1
- package/README.md +64 -37
- package/dist/{builder-4syLV1-z.js → builder-DTlQwmVF.js} +10 -3
- package/dist/{client-BsGzbnV-.d.ts → client-CUTUGgvJ.d.ts} +18 -18
- package/dist/{client-pY7-3icS.js → client-Dg7OfUDA.js} +28 -23
- package/dist/{client-94iWEfQa.d.cts → client-by-PEGAJ.d.cts} +18 -18
- package/dist/compat/mod.cjs +1 -1
- package/dist/compat/mod.d.cts +6 -10
- package/dist/compat/mod.d.ts +6 -10
- package/dist/compat/mod.js +1 -1
- package/dist/compat/transformers.test.js +22 -21
- package/dist/{context-PxGADCsD.d.cts → context-B6X-7loD.d.cts} +206 -74
- package/dist/{context-V-XS2_6O.d.ts → context-CJaICYPw.d.ts} +206 -74
- package/dist/context-CZ5llAss.js +109 -0
- package/dist/deno-DGx1JZHr.js +124 -0
- package/dist/{testing-BslrM_9E.js → dist-B5f6a8Tt.js} +90 -110
- package/dist/{docloader-DndkGj0O.js → docloader-D8UHsyqD.js} +3 -3
- package/dist/{esm-VlKMJQqV.js → esm-DGl7uK1r.js} +1 -1
- package/dist/federation/builder.test.js +7 -5
- package/dist/federation/collection.test.js +2 -3
- package/dist/federation/handler.test.js +24 -23
- package/dist/federation/idempotency.test.js +59 -22
- package/dist/federation/inbox.test.js +4 -3
- package/dist/federation/keycache.test.js +4 -4
- package/dist/federation/kv.test.js +56 -3
- package/dist/federation/middleware.test.js +307 -93
- package/dist/federation/mod.cjs +9 -10
- package/dist/federation/mod.d.cts +7 -11
- package/dist/federation/mod.d.ts +7 -11
- package/dist/federation/mod.js +8 -11
- package/dist/federation/mq.test.js +167 -16
- package/dist/federation/negotiation.test.js +2 -3
- package/dist/federation/retry.test.js +2 -3
- package/dist/federation/router.test.js +2 -2
- package/dist/federation/send.test.js +93 -11
- package/dist/{webfinger/handler.test.js → federation/webfinger.test.js} +24 -22
- package/dist/{federation-CRpdnOMS.cjs → federation-CE0CJ_0G.cjs} +116 -10
- package/dist/{federation-jcR8-ZxP.js → federation-D6FVaeAR.js} +122 -16
- package/dist/{http-YhR_TMMQ.js → http-CL3G0rnf.js} +126 -9
- package/dist/{http-M8k5mKc0.d.cts → http-ClB3pLcL.d.cts} +1 -1
- package/dist/{http-Dxpqz4hE.cjs → http-DKBUv5zZ.cjs} +139 -16
- package/dist/{http-BbO0ejuk.d.ts → http-DLBDPal9.d.ts} +1 -1
- package/dist/{http-DH47B-h3.js → http-LGtYlSfN.js} +3 -2
- package/dist/{inbox-CEyHvxOo.js → inbox-DbtWQY2D.js} +2 -1
- package/dist/{key-x7E5PYI0.js → key-BCtt1Ugy.js} +3 -3
- package/dist/{keycache-BRXuBDuy.js → keycache-DRxpZ5r9.js} +1 -1
- package/dist/{keys-DLk_8H-l.js → keys-ZbcByPg9.js} +1 -1
- package/dist/{kv-Bxr0Q87_.d.cts → kv-B4vFhIYL.d.cts} +30 -1
- package/dist/{kv-BKNZ-Tb-.d.ts → kv-CYySNrsn.d.ts} +30 -1
- package/dist/{kv-CRZrzyXm.js → kv-QzKcOQgP.js} +22 -0
- package/dist/{kv-cache-HFnFIjSD.js → kv-cache-0786BfqY.js} +3 -3
- package/dist/{kv-cache-DN9pfMBe.js → kv-cache-B__dHl7g.js} +15 -2
- package/dist/{kv-cache-BMpfJFTx.cjs → kv-cache-DCJojeTn.cjs} +3 -3
- package/dist/{ld-CRPaU6c8.js → ld-QlZPwGEH.js} +4 -3
- package/dist/middleware-B3jUPnDa.js +12 -0
- package/dist/middleware-BFiwWMA2.cjs +12 -0
- package/dist/middleware-DMx6DyIw.js +26 -0
- package/dist/{middleware-DfLpMu7C.js → middleware-Dm58nObp.js} +280 -166
- package/dist/{middleware-BIqFwRwI.js → middleware-WokE4qxc.js} +245 -178
- package/dist/{middleware-Ck7O6mb0.cjs → middleware-hWyKOO_6.cjs} +332 -206
- package/dist/{mod-DMpuiKXi.d.cts → mod-BHXq4Q3x.d.cts} +7 -7
- package/dist/{mod-DgxG-byT.d.cts → mod-BrS8tiad.d.cts} +2 -2
- package/dist/mod-CoMP50Rf.d.ts +64 -0
- package/dist/{mod-BoRKfJPE.d.cts → mod-DScazwCW.d.cts} +4 -4
- package/dist/mod-DTzN6Pv3.d.cts +62 -0
- package/dist/{mod-aAE2wOWV.d.ts → mod-DZmuPaKv.d.ts} +7 -7
- package/dist/{mod-D5Z2tISD.d.ts → mod-jOa7W503.d.ts} +2 -2
- package/dist/{mod-Cdo6SYlJ.d.ts → mod-xKJ57rwu.d.ts} +4 -4
- package/dist/mod.cjs +12 -93
- package/dist/mod.d.cts +11 -15
- package/dist/mod.d.ts +11 -15
- package/dist/mod.js +11 -15
- package/dist/nodeinfo/client.test.js +3 -4
- package/dist/nodeinfo/handler.test.js +22 -21
- package/dist/nodeinfo/mod.cjs +2 -2
- package/dist/nodeinfo/mod.d.cts +2 -2
- package/dist/nodeinfo/mod.d.ts +2 -2
- package/dist/nodeinfo/mod.js +2 -2
- package/dist/nodeinfo/types.test.js +2 -3
- package/dist/otel/exporter.test.js +893 -0
- package/dist/otel/mod.cjs +256 -0
- package/dist/otel/mod.d.cts +230 -0
- package/dist/otel/mod.d.ts +232 -0
- package/dist/otel/mod.js +255 -0
- package/dist/{owner-kQRGVXG1.d.ts → owner-BgI8C-VY.d.ts} +1 -2
- package/dist/{owner-B4HbyP8s.d.cts → owner-C-zfmVAD.d.cts} +1 -2
- package/dist/{owner-CIWnopkT.js → owner-Cejm-F7S.js} +2 -2
- package/dist/{proof-D-5ri6rf.js → proof-BOQBHd-i.js} +3 -2
- package/dist/{proof-fEwcA7LA.cjs → proof-Bmi8ZIcW.cjs} +24 -25
- package/dist/{proof-C8-2l0zH.js → proof-CnaEQ_Ev.js} +4 -5
- package/dist/router-D9eI0s4b.js +118 -0
- package/dist/{send-CPGk9QKZ.js → send-jFxXfsN8.js} +38 -4
- package/dist/sig/http.test.js +6 -7
- package/dist/sig/key.test.js +5 -5
- package/dist/sig/ld.test.js +6 -6
- package/dist/sig/mod.cjs +3 -5
- package/dist/sig/mod.d.cts +3 -5
- package/dist/sig/mod.d.ts +3 -5
- package/dist/sig/mod.js +3 -5
- package/dist/sig/owner.test.js +6 -7
- package/dist/sig/proof.test.js +6 -6
- package/dist/testing/mod.d.ts +173 -7006
- package/dist/testing/mod.js +4 -3
- package/dist/{transformers-CoBS-oFG.cjs → transformers-BjBg6Lag.cjs} +2 -2
- package/dist/{transformers-BFT6d7J5.js → transformers-N_ip_y4P.js} +2 -2
- package/dist/{types-BtUjyi5y.js → types-8l28uC8o.js} +30 -25
- package/dist/{types-CWgzGaqk.cjs → types-B6z6CqIz.cjs} +30 -25
- package/dist/{types-C2XVl6gj.js → types-CPz01LGH.js} +3 -3
- package/dist/utils/docloader.test.js +7 -8
- package/dist/utils/kv-cache.test.js +5 -3
- package/dist/utils/mod.cjs +3 -5
- package/dist/utils/mod.d.cts +3 -4
- package/dist/utils/mod.d.ts +3 -4
- package/dist/utils/mod.js +3 -5
- package/dist/vocab/mod.cjs +8 -81
- package/dist/vocab/mod.d.cts +1 -4
- package/dist/vocab/mod.d.ts +1 -4
- package/dist/vocab/mod.js +1 -5
- package/package.json +27 -27
- package/dist/actor-BT-e5fn9.js +0 -146
- package/dist/actor-B_gRMloq.js +0 -41647
- package/dist/actor-CBfPjuWj.cjs +0 -42079
- package/dist/actor-DqFajh9s.d.ts +0 -130
- package/dist/actor-f2NtjyCg.d.cts +0 -128
- package/dist/fixtures/activitypub.academy/users/brauca_darradiul.json +0 -83
- package/dist/fixtures/example.com/announce.json +0 -6
- package/dist/fixtures/example.com/collection.json +0 -19
- package/dist/fixtures/example.com/create.json +0 -6
- package/dist/fixtures/example.com/cross-origin-actor.json +0 -6
- package/dist/fixtures/example.com/hong-gildong.json +0 -11
- package/dist/fixtures/example.com/invite.json +0 -7
- package/dist/fixtures/example.com/key.json +0 -7
- package/dist/fixtures/example.com/key2.json +0 -6
- package/dist/fixtures/example.com/object.json +0 -6
- package/dist/fixtures/example.com/orderedcollectionpage.json +0 -24
- package/dist/fixtures/example.com/paged/a.json +0 -13
- package/dist/fixtures/example.com/paged/b.json +0 -16
- package/dist/fixtures/example.com/paged-collection.json +0 -6
- package/dist/fixtures/example.com/person.json +0 -22
- package/dist/fixtures/example.com/person2.json +0 -40
- package/dist/fixtures/example.com/test.json +0 -5
- package/dist/fixtures/example.com/users/handle.json +0 -16
- package/dist/fixtures/example.com/wrong-type.json +0 -3
- package/dist/fixtures/media.example.com/avatars/test-avatar.jpg.json +0 -6
- package/dist/fixtures/oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd.json +0 -24
- package/dist/fixtures/remote.domain/users/bob.json +0 -20
- package/dist/fixtures/server.example/users/alice.json +0 -20
- package/dist/fixtures/w3id.org/identity/v1.json +0 -152
- package/dist/fixtures/w3id.org/security/data-integrity/v1.json +0 -74
- package/dist/fixtures/w3id.org/security/multikey/v1.json +0 -35
- package/dist/fixtures/w3id.org/security/v1.json +0 -50
- package/dist/fixtures/wizard.casa/users/hongminhee.json +0 -69
- package/dist/fixtures/www.w3.org/ns/activitystreams.json +0 -379
- package/dist/fixtures/www.w3.org/ns/did/v1.json +0 -58
- package/dist/lookup-BTqtVATt.cjs +0 -266
- package/dist/lookup-DOSnR912.js +0 -254
- package/dist/lookup-Dj9-mgOn.js +0 -42184
- package/dist/middleware-CxswDtQn.js +0 -15
- package/dist/middleware-CyITsnX0.js +0 -26
- package/dist/middleware-Z8lc_drL.cjs +0 -15
- package/dist/mod-BlVovdcy.d.ts +0 -309
- package/dist/mod-BxRCHTz-.d.cts +0 -307
- package/dist/mod-C58MZ7Wx.d.cts +0 -113
- package/dist/mod-CcDPcLJW.d.cts +0 -1
- package/dist/mod-Ds0mpFZU.d.ts +0 -115
- package/dist/mod-bjzj5QIb.d.ts +0 -2
- package/dist/otel-1BmGPuZc.js +0 -64
- package/dist/src/vocab/accept.yaml +0 -15
- package/dist/src/vocab/activity.yaml +0 -98
- package/dist/src/vocab/add.yaml +0 -16
- package/dist/src/vocab/announce.yaml +0 -30
- package/dist/src/vocab/application.yaml +0 -324
- package/dist/src/vocab/arrive.yaml +0 -15
- package/dist/src/vocab/article.yaml +0 -46
- package/dist/src/vocab/audio.yaml +0 -11
- package/dist/src/vocab/block.yaml +0 -16
- package/dist/src/vocab/chatmessage.yaml +0 -50
- package/dist/src/vocab/collection.yaml +0 -154
- package/dist/src/vocab/collectionpage.yaml +0 -55
- package/dist/src/vocab/create.yaml +0 -28
- package/dist/src/vocab/dataintegrityproof.yaml +0 -56
- package/dist/src/vocab/delete.yaml +0 -27
- package/dist/src/vocab/didservice.yaml +0 -22
- package/dist/src/vocab/dislike.yaml +0 -14
- package/dist/src/vocab/document.yaml +0 -31
- package/dist/src/vocab/emoji.yaml +0 -12
- package/dist/src/vocab/emojireact.yaml +0 -17
- package/dist/src/vocab/endpoints.yaml +0 -85
- package/dist/src/vocab/event.yaml +0 -11
- package/dist/src/vocab/export.yaml +0 -9
- package/dist/src/vocab/flag.yaml +0 -15
- package/dist/src/vocab/follow.yaml +0 -19
- package/dist/src/vocab/group.yaml +0 -324
- package/dist/src/vocab/hashtag.yaml +0 -14
- package/dist/src/vocab/ignore.yaml +0 -14
- package/dist/src/vocab/image.yaml +0 -9
- package/dist/src/vocab/intransitiveactivity.yaml +0 -15
- package/dist/src/vocab/invite.yaml +0 -14
- package/dist/src/vocab/join.yaml +0 -14
- package/dist/src/vocab/key.yaml +0 -28
- package/dist/src/vocab/leave.yaml +0 -14
- package/dist/src/vocab/like.yaml +0 -16
- package/dist/src/vocab/link.yaml +0 -101
- package/dist/src/vocab/listen.yaml +0 -12
- package/dist/src/vocab/mention.yaml +0 -9
- package/dist/src/vocab/move.yaml +0 -15
- package/dist/src/vocab/multikey.yaml +0 -36
- package/dist/src/vocab/note.yaml +0 -48
- package/dist/src/vocab/object.yaml +0 -404
- package/dist/src/vocab/offer.yaml +0 -15
- package/dist/src/vocab/orderedcollection.yaml +0 -39
- package/dist/src/vocab/orderedcollectionpage.yaml +0 -50
- package/dist/src/vocab/organization.yaml +0 -324
- package/dist/src/vocab/page.yaml +0 -11
- package/dist/src/vocab/person.yaml +0 -324
- package/dist/src/vocab/place.yaml +0 -75
- package/dist/src/vocab/profile.yaml +0 -26
- package/dist/src/vocab/propertyvalue.yaml +0 -32
- package/dist/src/vocab/question.yaml +0 -103
- package/dist/src/vocab/read.yaml +0 -13
- package/dist/src/vocab/reject.yaml +0 -14
- package/dist/src/vocab/relationship.yaml +0 -52
- package/dist/src/vocab/remove.yaml +0 -14
- package/dist/src/vocab/service.yaml +0 -324
- package/dist/src/vocab/source.yaml +0 -26
- package/dist/src/vocab/tentativeaccept.yaml +0 -14
- package/dist/src/vocab/tentativereject.yaml +0 -14
- package/dist/src/vocab/tombstone.yaml +0 -24
- package/dist/src/vocab/travel.yaml +0 -16
- package/dist/src/vocab/undo.yaml +0 -26
- package/dist/src/vocab/update.yaml +0 -58
- package/dist/src/vocab/video.yaml +0 -11
- package/dist/src/vocab/view.yaml +0 -13
- package/dist/testing/docloader.test.js +0 -22
- package/dist/vocab/actor.test.js +0 -5963
- package/dist/vocab/lookup.test.d.ts +0 -3
- package/dist/vocab/lookup.test.js +0 -476
- package/dist/vocab/type.test.d.ts +0 -3
- package/dist/vocab/type.test.js +0 -24
- package/dist/vocab/vocab.test.d.ts +0 -3
- package/dist/vocab/vocab.test.js +0 -9397
- package/dist/vocab-BCWe1Ih5.d.ts +0 -14905
- package/dist/vocab-ByUp-A2_.js +0 -260
- package/dist/vocab-CeDBzu-f.d.cts +0 -14903
- package/dist/vocab-X_X5T8D3.cjs +0 -296
- package/dist/webfinger/handler.test.d.ts +0 -3
- package/dist/webfinger/lookup.test.d.ts +0 -3
- package/dist/webfinger/lookup.test.js +0 -193
- package/dist/webfinger/mod.cjs +0 -8
- package/dist/webfinger/mod.d.cts +0 -2
- package/dist/webfinger/mod.d.ts +0 -4
- package/dist/webfinger/mod.js +0 -8
- package/dist/webfinger-C72Y8lrh.js +0 -4
- package/dist/webfinger-vAtLmxOF.cjs +0 -4
- /package/dist/{collection-BzWsN9pB.js → collection-CcnIw1qY.js} +0 -0
- /package/dist/{testing/docloader.test.d.ts → federation/webfinger.test.d.ts} +0 -0
- /package/dist/{mod-CVgZgliM.d.ts → mod-1E3W847c.d.ts} +0 -0
- /package/dist/{mod-B-hUPT2N.d.cts → mod-C81L6_lQ.d.cts} +0 -0
- /package/dist/{negotiation-C4nFufNk.js → negotiation-5NPJL6zp.js} +0 -0
- /package/dist/{nodeinfo-BnthBobC.js → nodeinfo-BlLsRSiT.js} +0 -0
- /package/dist/{nodeinfo-CdN0rEnZ.cjs → nodeinfo-DuMYTpbZ.cjs} +0 -0
- /package/dist/{vocab/actor.test.d.ts → otel/exporter.test.d.ts} +0 -0
- /package/dist/{retry-CfF8Gn4d.js → retry-D4GJ670a.js} +0 -0
- /package/dist/{sig-C34-oHBl.js → sig-CwuONEzF.js} +0 -0
- /package/dist/{sig-YYj5tCnr.cjs → sig-DeXX2xnj.cjs} +0 -0
- /package/dist/{utils-DyRU1gdZ.cjs → utils-Db0ZmjcD.cjs} +0 -0
- /package/dist/{utils-D-Va7aXC.js → utils-Wranxuoe.js} +0 -0
|
@@ -3,22 +3,21 @@
|
|
|
3
3
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
4
4
|
|
|
5
5
|
const require_chunk = require('./chunk-DqRYRqnO.cjs');
|
|
6
|
-
const require_transformers = require('./transformers-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const require_types = require('./types-CWgzGaqk.cjs');
|
|
12
|
-
const require_kv_cache = require('./kv-cache-BMpfJFTx.cjs');
|
|
13
|
-
const require_vocab = require('./vocab-X_X5T8D3.cjs');
|
|
6
|
+
const require_transformers = require('./transformers-BjBg6Lag.cjs');
|
|
7
|
+
const require_http = require('./http-DKBUv5zZ.cjs');
|
|
8
|
+
const require_proof = require('./proof-Bmi8ZIcW.cjs');
|
|
9
|
+
const require_types = require('./types-B6z6CqIz.cjs');
|
|
10
|
+
const require_kv_cache = require('./kv-cache-DCJojeTn.cjs');
|
|
14
11
|
const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
|
|
12
|
+
const __fedify_vocab = require_chunk.__toESM(require("@fedify/vocab"));
|
|
15
13
|
const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
|
|
16
|
-
const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
|
|
17
14
|
const es_toolkit = require_chunk.__toESM(require("es-toolkit"));
|
|
18
15
|
const uri_template_router = require_chunk.__toESM(require("uri-template-router"));
|
|
19
16
|
const url_template = require_chunk.__toESM(require("url-template"));
|
|
20
17
|
const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
|
|
21
18
|
const __opentelemetry_semantic_conventions = require_chunk.__toESM(require("@opentelemetry/semantic-conventions"));
|
|
19
|
+
const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
|
|
20
|
+
const __fedify_webfinger = require_chunk.__toESM(require("@fedify/webfinger"));
|
|
22
21
|
const node_url = require_chunk.__toESM(require("node:url"));
|
|
23
22
|
|
|
24
23
|
//#region src/federation/inbox.ts
|
|
@@ -42,7 +41,7 @@ var InboxListenerSet = class InboxListenerSet {
|
|
|
42
41
|
if (inboxListeners == null) return null;
|
|
43
42
|
while (true) {
|
|
44
43
|
if (inboxListeners.has(cls)) break;
|
|
45
|
-
if (cls ===
|
|
44
|
+
if (cls === __fedify_vocab.Activity) return null;
|
|
46
45
|
cls = globalThis.Object.getPrototypeOf(cls);
|
|
47
46
|
}
|
|
48
47
|
const listener = inboxListeners.get(cls);
|
|
@@ -63,7 +62,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
63
62
|
]);
|
|
64
63
|
let cacheKey = null;
|
|
65
64
|
if (activity.id != null) {
|
|
66
|
-
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href,
|
|
65
|
+
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, (0, __fedify_vocab.getTypeId)(activity).href);
|
|
67
66
|
const strategy = idempotencyStrategy ?? "per-inbox";
|
|
68
67
|
let keyString;
|
|
69
68
|
if (typeof strategy === "function") {
|
|
@@ -142,7 +141,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
142
141
|
return "enqueued";
|
|
143
142
|
}
|
|
144
143
|
tracerProvider = tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
145
|
-
const tracer = tracerProvider.getTracer(
|
|
144
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
146
145
|
return await tracer.startActiveSpan("activitypub.dispatch_inbox_listener", { kind: __opentelemetry_api.SpanKind.INTERNAL }, async (span$1) => {
|
|
147
146
|
const dispatched = inboxListeners?.dispatchWithClass(activity);
|
|
148
147
|
if (dispatched == null) {
|
|
@@ -152,7 +151,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
152
151
|
});
|
|
153
152
|
span$1.setStatus({
|
|
154
153
|
code: __opentelemetry_api.SpanStatusCode.UNSET,
|
|
155
|
-
message: `Unsupported activity type: ${
|
|
154
|
+
message: `Unsupported activity type: ${(0, __fedify_vocab.getTypeId)(activity).href}`
|
|
156
155
|
});
|
|
157
156
|
span$1.end();
|
|
158
157
|
return "unsupportedActivity";
|
|
@@ -160,7 +159,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
160
159
|
const { class: cls, listener } = dispatched;
|
|
161
160
|
span$1.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
162
161
|
try {
|
|
163
|
-
await listener(inboxContextFactory(recipient, json, activity?.id?.href,
|
|
162
|
+
await listener(inboxContextFactory(recipient, json, activity?.id?.href, (0, __fedify_vocab.getTypeId)(activity).href), activity);
|
|
164
163
|
} catch (error) {
|
|
165
164
|
try {
|
|
166
165
|
await inboxErrorHandler?.(ctx, error);
|
|
@@ -324,6 +323,7 @@ var FederationBuilderImpl = class {
|
|
|
324
323
|
inboxListeners;
|
|
325
324
|
inboxErrorHandler;
|
|
326
325
|
sharedInboxKeyDispatcher;
|
|
326
|
+
outboxPermanentFailureHandler;
|
|
327
327
|
idempotencyStrategy;
|
|
328
328
|
collectionTypeIds;
|
|
329
329
|
collectionCallbacks;
|
|
@@ -339,7 +339,7 @@ var FederationBuilderImpl = class {
|
|
|
339
339
|
this.collectionTypeIds = {};
|
|
340
340
|
}
|
|
341
341
|
async build(options) {
|
|
342
|
-
const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-
|
|
342
|
+
const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-BFiwWMA2.cjs"));
|
|
343
343
|
const f = new FederationImpl$1(options);
|
|
344
344
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
345
345
|
f.router = this.router.clone();
|
|
@@ -361,11 +361,12 @@ var FederationBuilderImpl = class {
|
|
|
361
361
|
f.inboxListeners = this.inboxListeners?.clone();
|
|
362
362
|
f.inboxErrorHandler = this.inboxErrorHandler;
|
|
363
363
|
f.sharedInboxKeyDispatcher = this.sharedInboxKeyDispatcher;
|
|
364
|
+
f.outboxPermanentFailureHandler = this.outboxPermanentFailureHandler;
|
|
364
365
|
f.idempotencyStrategy = this.idempotencyStrategy;
|
|
365
366
|
return f;
|
|
366
367
|
}
|
|
367
368
|
_getTracer() {
|
|
368
|
-
return __opentelemetry_api.trace.getTracer(
|
|
369
|
+
return __opentelemetry_api.trace.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
369
370
|
}
|
|
370
371
|
setActorDispatcher(path, dispatcher) {
|
|
371
372
|
if (this.router.has("actor")) throw new RouterError("Actor dispatcher already set.");
|
|
@@ -385,7 +386,7 @@ var FederationBuilderImpl = class {
|
|
|
385
386
|
const actor$1 = await dispatcher(context$2, identifier);
|
|
386
387
|
span.setAttribute("activitypub.actor.id", (actor$1?.id ?? context$2.getActorUri(identifier)).href);
|
|
387
388
|
if (actor$1 == null) span.setStatus({ code: __opentelemetry_api.SpanStatusCode.ERROR });
|
|
388
|
-
else span.setAttribute("activitypub.actor.type",
|
|
389
|
+
else span.setAttribute("activitypub.actor.type", (0, __fedify_vocab.getTypeId)(actor$1).href);
|
|
389
390
|
return actor$1;
|
|
390
391
|
} catch (error) {
|
|
391
392
|
span.setStatus({
|
|
@@ -508,7 +509,7 @@ var FederationBuilderImpl = class {
|
|
|
508
509
|
const object = await dispatcher(ctx, values);
|
|
509
510
|
span.setAttribute("activitypub.object.id", (object?.id ?? ctx.getObjectUri(cls, values)).href);
|
|
510
511
|
if (object == null) span.setStatus({ code: __opentelemetry_api.SpanStatusCode.ERROR });
|
|
511
|
-
else span.setAttribute("activitypub.object.type",
|
|
512
|
+
else span.setAttribute("activitypub.object.type", (0, __fedify_vocab.getTypeId)(object).href);
|
|
512
513
|
return object;
|
|
513
514
|
} catch (e) {
|
|
514
515
|
span.setStatus({
|
|
@@ -842,6 +843,9 @@ var FederationBuilderImpl = class {
|
|
|
842
843
|
const path = this.router.build(`collection:${routeName}`, values) ?? this.router.build(`orderedCollection:${routeName}`, values);
|
|
843
844
|
return path;
|
|
844
845
|
}
|
|
846
|
+
setOutboxPermanentFailureHandler(handler) {
|
|
847
|
+
this.outboxPermanentFailureHandler = handler;
|
|
848
|
+
}
|
|
845
849
|
/**
|
|
846
850
|
* Converts a name (string or symbol) to a unique string identifier.
|
|
847
851
|
* For symbols, generates and caches a UUID if not already present.
|
|
@@ -923,10 +927,10 @@ var KvKeyCache = class {
|
|
|
923
927
|
const serialized = await this.kv.get([...this.prefix, keyId.href]);
|
|
924
928
|
if (serialized == null) return void 0;
|
|
925
929
|
try {
|
|
926
|
-
return await
|
|
930
|
+
return await __fedify_vocab.CryptographicKey.fromJsonLd(serialized, this.options);
|
|
927
931
|
} catch {
|
|
928
932
|
try {
|
|
929
|
-
return await
|
|
933
|
+
return await __fedify_vocab.Multikey.fromJsonLd(serialized, this.options);
|
|
930
934
|
} catch {
|
|
931
935
|
await this.kv.delete([...this.prefix, keyId.href]);
|
|
932
936
|
return void 0;
|
|
@@ -1112,7 +1116,7 @@ async function handleObject(request, { values, context: context$2, objectDispatc
|
|
|
1112
1116
|
async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context: context$2, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound }) {
|
|
1113
1117
|
const spanName = name.trim().replace(/\s+/g, "_");
|
|
1114
1118
|
tracerProvider = tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
1115
|
-
const tracer = tracerProvider.getTracer(
|
|
1119
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
1116
1120
|
const url = new URL(request.url);
|
|
1117
1121
|
const cursor = url.searchParams.get("cursor");
|
|
1118
1122
|
if (collectionCallbacks == null) return await onNotFound(request);
|
|
@@ -1126,7 +1130,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1126
1130
|
kind: __opentelemetry_api.SpanKind.SERVER,
|
|
1127
1131
|
attributes: {
|
|
1128
1132
|
"activitypub.collection.id": baseUri.href,
|
|
1129
|
-
"activitypub.collection.type":
|
|
1133
|
+
"activitypub.collection.type": __fedify_vocab.OrderedCollection.typeId.href
|
|
1130
1134
|
}
|
|
1131
1135
|
}, async (span) => {
|
|
1132
1136
|
if (totalItems != null) span.setAttribute("activitypub.collection.total_items", Number(totalItems));
|
|
@@ -1150,7 +1154,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1150
1154
|
}
|
|
1151
1155
|
});
|
|
1152
1156
|
if (itemsOrResponse instanceof Response) return itemsOrResponse;
|
|
1153
|
-
collection = new
|
|
1157
|
+
collection = new __fedify_vocab.OrderedCollection({
|
|
1154
1158
|
id: baseUri,
|
|
1155
1159
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1156
1160
|
items: filterCollectionItems(itemsOrResponse, name, filterPredicate)
|
|
@@ -1164,7 +1168,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1164
1168
|
last = new URL(context$2.url);
|
|
1165
1169
|
last.searchParams.set("cursor", lastCursor);
|
|
1166
1170
|
}
|
|
1167
|
-
collection = new
|
|
1171
|
+
collection = new __fedify_vocab.OrderedCollection({
|
|
1168
1172
|
id: baseUri,
|
|
1169
1173
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1170
1174
|
first,
|
|
@@ -1178,7 +1182,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1178
1182
|
kind: __opentelemetry_api.SpanKind.SERVER,
|
|
1179
1183
|
attributes: {
|
|
1180
1184
|
"activitypub.collection.id": uri.href,
|
|
1181
|
-
"activitypub.collection.type":
|
|
1185
|
+
"activitypub.collection.type": __fedify_vocab.OrderedCollectionPage.typeId.href,
|
|
1182
1186
|
"fedify.collection.cursor": cursor
|
|
1183
1187
|
}
|
|
1184
1188
|
}, async (span) => {
|
|
@@ -1214,7 +1218,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1214
1218
|
}
|
|
1215
1219
|
const partOf = new URL(context$2.url);
|
|
1216
1220
|
partOf.searchParams.delete("cursor");
|
|
1217
|
-
collection = new
|
|
1221
|
+
collection = new __fedify_vocab.OrderedCollectionPage({
|
|
1218
1222
|
id: uri,
|
|
1219
1223
|
prev,
|
|
1220
1224
|
next,
|
|
@@ -1262,7 +1266,7 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1262
1266
|
let logged = false;
|
|
1263
1267
|
for (const item of items) {
|
|
1264
1268
|
let mappedItem;
|
|
1265
|
-
if (item instanceof
|
|
1269
|
+
if (item instanceof __fedify_vocab.Object || item instanceof __fedify_vocab.Link || item instanceof URL) mappedItem = item;
|
|
1266
1270
|
else if (item.id == null) continue;
|
|
1267
1271
|
else mappedItem = item.id;
|
|
1268
1272
|
if (filterPredicate != null && !filterPredicate(item)) {
|
|
@@ -1289,7 +1293,7 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1289
1293
|
*/
|
|
1290
1294
|
async function handleInbox(request, options) {
|
|
1291
1295
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
1292
|
-
const tracer = tracerProvider.getTracer(
|
|
1296
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
1293
1297
|
return await tracer.startActiveSpan("activitypub.inbox", {
|
|
1294
1298
|
kind: options.queue == null ? __opentelemetry_api.SpanKind.SERVER : __opentelemetry_api.SpanKind.PRODUCER,
|
|
1295
1299
|
attributes: { "activitypub.shared_inbox": options.recipient == null }
|
|
@@ -1417,14 +1421,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1417
1421
|
recipient,
|
|
1418
1422
|
json
|
|
1419
1423
|
});
|
|
1420
|
-
activity = await
|
|
1424
|
+
activity = await __fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1421
1425
|
} else {
|
|
1422
1426
|
logger$1.debug("Linked Data Signatures are not verified.", {
|
|
1423
1427
|
recipient,
|
|
1424
1428
|
json
|
|
1425
1429
|
});
|
|
1426
1430
|
try {
|
|
1427
|
-
activity = await require_proof.verifyObject(
|
|
1431
|
+
activity = await require_proof.verifyObject(__fedify_vocab.Activity, jsonWithoutSig, {
|
|
1428
1432
|
contextLoader: ctx.contextLoader,
|
|
1429
1433
|
documentLoader: ctx.documentLoader,
|
|
1430
1434
|
keyCache,
|
|
@@ -1487,10 +1491,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1487
1491
|
} else logger$1.debug("HTTP Signatures are verified.", { recipient });
|
|
1488
1492
|
httpSigKey = key;
|
|
1489
1493
|
}
|
|
1490
|
-
activity = await
|
|
1494
|
+
activity = await __fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1491
1495
|
}
|
|
1492
1496
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
1493
|
-
span.setAttribute("activitypub.activity.type",
|
|
1497
|
+
span.setAttribute("activitypub.activity.type", (0, __fedify_vocab.getTypeId)(activity).href);
|
|
1494
1498
|
span.addEvent("activitypub.activity.received", {
|
|
1495
1499
|
"activitypub.activity.json": JSON.stringify(json),
|
|
1496
1500
|
"activitypub.activity.verified": activity != null,
|
|
@@ -1570,7 +1574,7 @@ async function _handleCustomCollection(request, { name, values, context: context
|
|
|
1570
1574
|
verifyDefined(callbacks);
|
|
1571
1575
|
await authIfNeeded(context$2, values, callbacks);
|
|
1572
1576
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1573
|
-
return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider,
|
|
1577
|
+
return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider, __fedify_vocab.Collection, __fedify_vocab.CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1574
1578
|
}
|
|
1575
1579
|
/**
|
|
1576
1580
|
* Handles an ordered collection request.
|
|
@@ -1588,7 +1592,7 @@ async function _handleOrderedCollection(request, { name, values, context: contex
|
|
|
1588
1592
|
verifyDefined(callbacks);
|
|
1589
1593
|
await authIfNeeded(context$2, values, callbacks);
|
|
1590
1594
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1591
|
-
return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider,
|
|
1595
|
+
return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider, __fedify_vocab.OrderedCollection, __fedify_vocab.OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1592
1596
|
}
|
|
1593
1597
|
/**
|
|
1594
1598
|
* Handling custom collections with support for pagination and filtering.
|
|
@@ -1648,7 +1652,7 @@ var CustomCollectionHandler = class {
|
|
|
1648
1652
|
this.CollectionPage = CollectionPage$1;
|
|
1649
1653
|
this.filterPredicate = filterPredicate;
|
|
1650
1654
|
this.name = this.name.trim().replace(/\s+/g, "_");
|
|
1651
|
-
this.#tracer = this.tracerProvider.getTracer(
|
|
1655
|
+
this.#tracer = this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
1652
1656
|
this.#id = new URL(this.context.url);
|
|
1653
1657
|
this.#dispatcher = callbacks.dispatcher.bind(callbacks);
|
|
1654
1658
|
}
|
|
@@ -2038,139 +2042,6 @@ function handleNodeInfoJrd(_request, context$2) {
|
|
|
2038
2042
|
return Promise.resolve(response);
|
|
2039
2043
|
}
|
|
2040
2044
|
|
|
2041
|
-
//#endregion
|
|
2042
|
-
//#region src/webfinger/handler.ts
|
|
2043
|
-
const logger = (0, __logtape_logtape.getLogger)([
|
|
2044
|
-
"fedify",
|
|
2045
|
-
"webfinger",
|
|
2046
|
-
"server"
|
|
2047
|
-
]);
|
|
2048
|
-
/**
|
|
2049
|
-
* Handles a WebFinger request. You would not typically call this function
|
|
2050
|
-
* directly, but instead use {@link Federation.fetch} method.
|
|
2051
|
-
* @param request The WebFinger request to handle.
|
|
2052
|
-
* @param parameters The parameters for handling the request.
|
|
2053
|
-
* @returns The response to the request.
|
|
2054
|
-
*/
|
|
2055
|
-
async function handleWebFinger(request, options) {
|
|
2056
|
-
if (options.tracer == null) return await handleWebFingerInternal(request, options);
|
|
2057
|
-
return await options.tracer.startActiveSpan("webfinger.handle", { kind: __opentelemetry_api.SpanKind.SERVER }, async (span) => {
|
|
2058
|
-
try {
|
|
2059
|
-
const response = await handleWebFingerInternal(request, options);
|
|
2060
|
-
span.setStatus({ code: response.ok ? __opentelemetry_api.SpanStatusCode.UNSET : __opentelemetry_api.SpanStatusCode.ERROR });
|
|
2061
|
-
return response;
|
|
2062
|
-
} catch (error) {
|
|
2063
|
-
span.setStatus({
|
|
2064
|
-
code: __opentelemetry_api.SpanStatusCode.ERROR,
|
|
2065
|
-
message: String(error)
|
|
2066
|
-
});
|
|
2067
|
-
throw error;
|
|
2068
|
-
} finally {
|
|
2069
|
-
span.end();
|
|
2070
|
-
}
|
|
2071
|
-
});
|
|
2072
|
-
}
|
|
2073
|
-
async function handleWebFingerInternal(request, { context: context$2, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
|
|
2074
|
-
if (actorDispatcher == null) {
|
|
2075
|
-
logger.error("Actor dispatcher is not set.");
|
|
2076
|
-
return await onNotFound(request);
|
|
2077
|
-
}
|
|
2078
|
-
const resource = context$2.url.searchParams.get("resource");
|
|
2079
|
-
if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
|
|
2080
|
-
span?.setAttribute("webfinger.resource", resource);
|
|
2081
|
-
let resourceUrl;
|
|
2082
|
-
try {
|
|
2083
|
-
resourceUrl = new URL(resource);
|
|
2084
|
-
} catch (e) {
|
|
2085
|
-
if (e instanceof TypeError) return new Response("Invalid resource URL.", { status: 400 });
|
|
2086
|
-
throw e;
|
|
2087
|
-
}
|
|
2088
|
-
span?.setAttribute("webfinger.resource.scheme", resourceUrl.protocol.replace(/:$/, ""));
|
|
2089
|
-
async function mapUsernameToIdentifier(username) {
|
|
2090
|
-
if (actorHandleMapper == null) {
|
|
2091
|
-
logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
|
|
2092
|
-
return username;
|
|
2093
|
-
}
|
|
2094
|
-
const identifier$1 = await actorHandleMapper(context$2, username);
|
|
2095
|
-
if (identifier$1 == null) {
|
|
2096
|
-
logger.error("Actor {username} not found.", { username });
|
|
2097
|
-
return null;
|
|
2098
|
-
}
|
|
2099
|
-
return identifier$1;
|
|
2100
|
-
}
|
|
2101
|
-
let identifier = null;
|
|
2102
|
-
const uriParsed = context$2.parseUri(resourceUrl);
|
|
2103
|
-
if (uriParsed?.type != "actor") {
|
|
2104
|
-
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
2105
|
-
if (match == null) {
|
|
2106
|
-
const result = await actorAliasMapper?.(context$2, resourceUrl);
|
|
2107
|
-
if (result == null) return await onNotFound(request);
|
|
2108
|
-
if ("identifier" in result) identifier = result.identifier;
|
|
2109
|
-
else identifier = await mapUsernameToIdentifier(result.username);
|
|
2110
|
-
} else {
|
|
2111
|
-
const portMatch = /:\d+$/.exec(match[2]);
|
|
2112
|
-
const normalizedHost = portMatch == null ? (0, node_url.domainToASCII)(match[2].toLowerCase()) : (0, node_url.domainToASCII)(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
2113
|
-
if (normalizedHost != context$2.url.host && normalizedHost != host) return await onNotFound(request);
|
|
2114
|
-
else {
|
|
2115
|
-
identifier = await mapUsernameToIdentifier(match[1]);
|
|
2116
|
-
resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
|
|
2117
|
-
}
|
|
2118
|
-
}
|
|
2119
|
-
} else identifier = uriParsed.identifier;
|
|
2120
|
-
if (identifier == null) return await onNotFound(request);
|
|
2121
|
-
const actor = await actorDispatcher(context$2, identifier);
|
|
2122
|
-
if (actor == null) {
|
|
2123
|
-
logger.error("Actor {identifier} not found.", { identifier });
|
|
2124
|
-
return await onNotFound(request);
|
|
2125
|
-
}
|
|
2126
|
-
const links = [{
|
|
2127
|
-
rel: "self",
|
|
2128
|
-
href: context$2.getActorUri(identifier).href,
|
|
2129
|
-
type: "application/activity+json"
|
|
2130
|
-
}];
|
|
2131
|
-
for (const url of actor.urls) if (url instanceof require_actor.Link && url.href != null) links.push({
|
|
2132
|
-
rel: url.rel ?? "http://webfinger.net/rel/profile-page",
|
|
2133
|
-
href: url.href.href,
|
|
2134
|
-
type: url.mediaType == null ? void 0 : url.mediaType
|
|
2135
|
-
});
|
|
2136
|
-
else if (url instanceof URL) links.push({
|
|
2137
|
-
rel: "http://webfinger.net/rel/profile-page",
|
|
2138
|
-
href: url.href
|
|
2139
|
-
});
|
|
2140
|
-
for await (const image of actor.getIcons()) {
|
|
2141
|
-
if (image.url?.href == null) continue;
|
|
2142
|
-
const link = {
|
|
2143
|
-
rel: "http://webfinger.net/rel/avatar",
|
|
2144
|
-
href: image.url.href.toString()
|
|
2145
|
-
};
|
|
2146
|
-
if (image.mediaType != null) link.type = image.mediaType;
|
|
2147
|
-
links.push(link);
|
|
2148
|
-
}
|
|
2149
|
-
if (webFingerLinksDispatcher != null) {
|
|
2150
|
-
const customLinks = await webFingerLinksDispatcher(context$2, resourceUrl);
|
|
2151
|
-
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
2152
|
-
}
|
|
2153
|
-
const aliases = [];
|
|
2154
|
-
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
|
|
2155
|
-
aliases.push(`acct:${actor.preferredUsername}@${host ?? context$2.url.host}`);
|
|
2156
|
-
if (host != null && host !== context$2.url.host) aliases.push(`acct:${actor.preferredUsername}@${context$2.url.host}`);
|
|
2157
|
-
}
|
|
2158
|
-
if (resourceUrl.href !== context$2.getActorUri(identifier).href) aliases.push(context$2.getActorUri(identifier).href);
|
|
2159
|
-
if (resourceUrl.protocol === "acct:" && host != null && host !== context$2.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
2160
|
-
const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
|
|
2161
|
-
aliases.push(`acct:${username}@${host}`);
|
|
2162
|
-
}
|
|
2163
|
-
const jrd = {
|
|
2164
|
-
subject: resourceUrl.href,
|
|
2165
|
-
aliases,
|
|
2166
|
-
links
|
|
2167
|
-
};
|
|
2168
|
-
return new Response(JSON.stringify(jrd), { headers: {
|
|
2169
|
-
"Content-Type": "application/jrd+json",
|
|
2170
|
-
"Access-Control-Allow-Origin": "*"
|
|
2171
|
-
} });
|
|
2172
|
-
}
|
|
2173
|
-
|
|
2174
2045
|
//#endregion
|
|
2175
2046
|
//#region src/federation/retry.ts
|
|
2176
2047
|
/**
|
|
@@ -2239,7 +2110,7 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
|
|
|
2239
2110
|
*/
|
|
2240
2111
|
function sendActivity(options) {
|
|
2241
2112
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
2242
|
-
const tracer = tracerProvider.getTracer(
|
|
2113
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
2243
2114
|
return tracer.startActiveSpan("activitypub.send_activity", {
|
|
2244
2115
|
kind: __opentelemetry_api.SpanKind.CLIENT,
|
|
2245
2116
|
attributes: { "activitypub.shared_inbox": options.sharedInbox ?? false }
|
|
@@ -2315,7 +2186,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2315
2186
|
statusText: response.statusText,
|
|
2316
2187
|
error
|
|
2317
2188
|
});
|
|
2318
|
-
throw new
|
|
2189
|
+
throw new SendActivityError(inbox, response.status, `Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`, error);
|
|
2319
2190
|
}
|
|
2320
2191
|
span.addEvent("activitypub.activity.sent", {
|
|
2321
2192
|
"activitypub.activity.json": JSON.stringify(activity),
|
|
@@ -2323,6 +2194,172 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2323
2194
|
"activitypub.activity.id": activityId ?? ""
|
|
2324
2195
|
});
|
|
2325
2196
|
}
|
|
2197
|
+
/**
|
|
2198
|
+
* An error that is thrown when an activity fails to send to a remote inbox.
|
|
2199
|
+
* It contains structured information about the failure, including the HTTP
|
|
2200
|
+
* status code, the inbox URL, and the response body.
|
|
2201
|
+
* @since 2.0.0
|
|
2202
|
+
*/
|
|
2203
|
+
var SendActivityError = class extends Error {
|
|
2204
|
+
/**
|
|
2205
|
+
* The inbox URL that the activity was being sent to.
|
|
2206
|
+
*/
|
|
2207
|
+
inbox;
|
|
2208
|
+
/**
|
|
2209
|
+
* The HTTP status code returned by the inbox.
|
|
2210
|
+
*/
|
|
2211
|
+
statusCode;
|
|
2212
|
+
/**
|
|
2213
|
+
* The response body from the inbox, if any.
|
|
2214
|
+
*/
|
|
2215
|
+
responseBody;
|
|
2216
|
+
/**
|
|
2217
|
+
* Creates a new {@link SendActivityError}.
|
|
2218
|
+
* @param inbox The inbox URL.
|
|
2219
|
+
* @param statusCode The HTTP status code.
|
|
2220
|
+
* @param message The error message.
|
|
2221
|
+
* @param responseBody The response body.
|
|
2222
|
+
*/
|
|
2223
|
+
constructor(inbox, statusCode, message, responseBody) {
|
|
2224
|
+
super(message);
|
|
2225
|
+
this.name = "SendActivityError";
|
|
2226
|
+
this.inbox = inbox;
|
|
2227
|
+
this.statusCode = statusCode;
|
|
2228
|
+
this.responseBody = responseBody;
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
|
|
2232
|
+
//#endregion
|
|
2233
|
+
//#region src/federation/webfinger.ts
|
|
2234
|
+
const logger = (0, __logtape_logtape.getLogger)([
|
|
2235
|
+
"fedify",
|
|
2236
|
+
"webfinger",
|
|
2237
|
+
"server"
|
|
2238
|
+
]);
|
|
2239
|
+
/**
|
|
2240
|
+
* Handles a WebFinger request. You would not typically call this function
|
|
2241
|
+
* directly, but instead use {@link Federation.fetch} method.
|
|
2242
|
+
* @param request The WebFinger request to handle.
|
|
2243
|
+
* @param parameters The parameters for handling the request.
|
|
2244
|
+
* @returns The response to the request.
|
|
2245
|
+
*/
|
|
2246
|
+
async function handleWebFinger(request, options) {
|
|
2247
|
+
if (options.tracer == null) return await handleWebFingerInternal(request, options);
|
|
2248
|
+
return await options.tracer.startActiveSpan("webfinger.handle", { kind: __opentelemetry_api.SpanKind.SERVER }, async (span) => {
|
|
2249
|
+
try {
|
|
2250
|
+
const response = await handleWebFingerInternal(request, options);
|
|
2251
|
+
span.setStatus({ code: response.ok ? __opentelemetry_api.SpanStatusCode.UNSET : __opentelemetry_api.SpanStatusCode.ERROR });
|
|
2252
|
+
return response;
|
|
2253
|
+
} catch (error) {
|
|
2254
|
+
span.setStatus({
|
|
2255
|
+
code: __opentelemetry_api.SpanStatusCode.ERROR,
|
|
2256
|
+
message: String(error)
|
|
2257
|
+
});
|
|
2258
|
+
throw error;
|
|
2259
|
+
} finally {
|
|
2260
|
+
span.end();
|
|
2261
|
+
}
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
2264
|
+
async function handleWebFingerInternal(request, { context: context$2, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
|
|
2265
|
+
if (actorDispatcher == null) {
|
|
2266
|
+
logger.error("Actor dispatcher is not set.");
|
|
2267
|
+
return await onNotFound(request);
|
|
2268
|
+
}
|
|
2269
|
+
const resource = context$2.url.searchParams.get("resource");
|
|
2270
|
+
if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
|
|
2271
|
+
span?.setAttribute("webfinger.resource", resource);
|
|
2272
|
+
let resourceUrl;
|
|
2273
|
+
try {
|
|
2274
|
+
resourceUrl = new URL(resource);
|
|
2275
|
+
} catch (e) {
|
|
2276
|
+
if (e instanceof TypeError) return new Response("Invalid resource URL.", { status: 400 });
|
|
2277
|
+
throw e;
|
|
2278
|
+
}
|
|
2279
|
+
span?.setAttribute("webfinger.resource.scheme", resourceUrl.protocol.replace(/:$/, ""));
|
|
2280
|
+
async function mapUsernameToIdentifier(username) {
|
|
2281
|
+
if (actorHandleMapper == null) {
|
|
2282
|
+
logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
|
|
2283
|
+
return username;
|
|
2284
|
+
}
|
|
2285
|
+
const identifier$1 = await actorHandleMapper(context$2, username);
|
|
2286
|
+
if (identifier$1 == null) {
|
|
2287
|
+
logger.error("Actor {username} not found.", { username });
|
|
2288
|
+
return null;
|
|
2289
|
+
}
|
|
2290
|
+
return identifier$1;
|
|
2291
|
+
}
|
|
2292
|
+
let identifier = null;
|
|
2293
|
+
const uriParsed = context$2.parseUri(resourceUrl);
|
|
2294
|
+
if (uriParsed?.type != "actor") {
|
|
2295
|
+
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
2296
|
+
if (match == null) {
|
|
2297
|
+
const result = await actorAliasMapper?.(context$2, resourceUrl);
|
|
2298
|
+
if (result == null) return await onNotFound(request);
|
|
2299
|
+
if ("identifier" in result) identifier = result.identifier;
|
|
2300
|
+
else identifier = await mapUsernameToIdentifier(result.username);
|
|
2301
|
+
} else {
|
|
2302
|
+
const portMatch = /:\d+$/.exec(match[2]);
|
|
2303
|
+
const normalizedHost = portMatch == null ? (0, node_url.domainToASCII)(match[2].toLowerCase()) : (0, node_url.domainToASCII)(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
2304
|
+
if (normalizedHost != context$2.url.host && normalizedHost != host) return await onNotFound(request);
|
|
2305
|
+
else {
|
|
2306
|
+
identifier = await mapUsernameToIdentifier(match[1]);
|
|
2307
|
+
resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
} else identifier = uriParsed.identifier;
|
|
2311
|
+
if (identifier == null) return await onNotFound(request);
|
|
2312
|
+
const actor = await actorDispatcher(context$2, identifier);
|
|
2313
|
+
if (actor == null) {
|
|
2314
|
+
logger.error("Actor {identifier} not found.", { identifier });
|
|
2315
|
+
return await onNotFound(request);
|
|
2316
|
+
}
|
|
2317
|
+
const links = [{
|
|
2318
|
+
rel: "self",
|
|
2319
|
+
href: context$2.getActorUri(identifier).href,
|
|
2320
|
+
type: "application/activity+json"
|
|
2321
|
+
}];
|
|
2322
|
+
for (const url of actor.urls) if (url instanceof __fedify_vocab.Link && url.href != null) links.push({
|
|
2323
|
+
rel: url.rel ?? "http://webfinger.net/rel/profile-page",
|
|
2324
|
+
href: url.href.href,
|
|
2325
|
+
type: url.mediaType == null ? void 0 : url.mediaType
|
|
2326
|
+
});
|
|
2327
|
+
else if (url instanceof URL) links.push({
|
|
2328
|
+
rel: "http://webfinger.net/rel/profile-page",
|
|
2329
|
+
href: url.href
|
|
2330
|
+
});
|
|
2331
|
+
for await (const image of actor.getIcons()) {
|
|
2332
|
+
if (image.url?.href == null) continue;
|
|
2333
|
+
links.push({
|
|
2334
|
+
rel: "http://webfinger.net/rel/avatar",
|
|
2335
|
+
href: image.url.href.toString(),
|
|
2336
|
+
...image.mediaType != null && { type: image.mediaType }
|
|
2337
|
+
});
|
|
2338
|
+
}
|
|
2339
|
+
if (webFingerLinksDispatcher != null) {
|
|
2340
|
+
const customLinks = await webFingerLinksDispatcher(context$2, resourceUrl);
|
|
2341
|
+
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
2342
|
+
}
|
|
2343
|
+
const aliases = [];
|
|
2344
|
+
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
|
|
2345
|
+
aliases.push(`acct:${actor.preferredUsername}@${host ?? context$2.url.host}`);
|
|
2346
|
+
if (host != null && host !== context$2.url.host) aliases.push(`acct:${actor.preferredUsername}@${context$2.url.host}`);
|
|
2347
|
+
}
|
|
2348
|
+
if (resourceUrl.href !== context$2.getActorUri(identifier).href) aliases.push(context$2.getActorUri(identifier).href);
|
|
2349
|
+
if (resourceUrl.protocol === "acct:" && host != null && host !== context$2.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
2350
|
+
const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
|
|
2351
|
+
aliases.push(`acct:${username}@${host}`);
|
|
2352
|
+
}
|
|
2353
|
+
const jrd = {
|
|
2354
|
+
subject: resourceUrl.href,
|
|
2355
|
+
aliases,
|
|
2356
|
+
links
|
|
2357
|
+
};
|
|
2358
|
+
return new Response(JSON.stringify(jrd), { headers: {
|
|
2359
|
+
"Content-Type": "application/jrd+json",
|
|
2360
|
+
"Access-Control-Allow-Origin": "*"
|
|
2361
|
+
} });
|
|
2362
|
+
}
|
|
2326
2363
|
|
|
2327
2364
|
//#endregion
|
|
2328
2365
|
//#region src/federation/middleware.ts
|
|
@@ -2352,6 +2389,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2352
2389
|
allowPrivateAddress;
|
|
2353
2390
|
userAgent;
|
|
2354
2391
|
onOutboxError;
|
|
2392
|
+
permanentFailureStatusCodes;
|
|
2355
2393
|
signatureTimeWindow;
|
|
2356
2394
|
skipSignatureVerification;
|
|
2357
2395
|
outboxRetryPolicy;
|
|
@@ -2433,6 +2471,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2433
2471
|
}));
|
|
2434
2472
|
this.userAgent = userAgent;
|
|
2435
2473
|
this.onOutboxError = options.onOutboxError;
|
|
2474
|
+
this.permanentFailureStatusCodes = options.permanentFailureStatusCodes ?? [404, 410];
|
|
2436
2475
|
this.signatureTimeWindow = options.signatureTimeWindow ?? { hours: 1 };
|
|
2437
2476
|
this.skipSignatureVerification = options.skipSignatureVerification ?? false;
|
|
2438
2477
|
this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy();
|
|
@@ -2446,7 +2485,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2446
2485
|
this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
|
|
2447
2486
|
}
|
|
2448
2487
|
_getTracer() {
|
|
2449
|
-
return this.tracerProvider.getTracer(
|
|
2488
|
+
return this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
2450
2489
|
}
|
|
2451
2490
|
async _startQueueInternal(ctxData, signal, queue) {
|
|
2452
2491
|
if (this.inboxQueue == null && this.outboxQueue == null) return;
|
|
@@ -2546,7 +2585,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2546
2585
|
keyId: new URL(keyId),
|
|
2547
2586
|
privateKey: await require_http.importJwk(privateKey, "private")
|
|
2548
2587
|
})));
|
|
2549
|
-
const activity = await
|
|
2588
|
+
const activity = await __fedify_vocab.Activity.fromJsonLd(message.activity, {
|
|
2550
2589
|
contextLoader: this.contextLoaderFactory({
|
|
2551
2590
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
2552
2591
|
userAgent: this.userAgent
|
|
@@ -2563,6 +2602,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2563
2602
|
}) });
|
|
2564
2603
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
2565
2604
|
collectionSync: message.collectionSync,
|
|
2605
|
+
orderingKey: message.orderingKey,
|
|
2566
2606
|
context: context$2
|
|
2567
2607
|
});
|
|
2568
2608
|
}
|
|
@@ -2608,19 +2648,50 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2608
2648
|
message: String(error)
|
|
2609
2649
|
});
|
|
2610
2650
|
const loaderOptions = this.#getLoaderOptions(message.baseUrl);
|
|
2611
|
-
const activity = await
|
|
2651
|
+
const activity = await __fedify_vocab.Activity.fromJsonLd(message.activity, {
|
|
2612
2652
|
contextLoader: this.contextLoaderFactory(loaderOptions),
|
|
2613
2653
|
documentLoader: rsaKeyPair == null ? this.documentLoaderFactory(loaderOptions) : this.authenticatedDocumentLoaderFactory(rsaKeyPair, loaderOptions),
|
|
2614
2654
|
tracerProvider: this.tracerProvider
|
|
2615
2655
|
});
|
|
2616
2656
|
try {
|
|
2617
|
-
this.onOutboxError?.(error, activity);
|
|
2657
|
+
await this.onOutboxError?.(error, activity);
|
|
2618
2658
|
} catch (error$1) {
|
|
2619
2659
|
logger$1.error("An unexpected error occurred in onError handler:\n{error}", {
|
|
2620
2660
|
...logData,
|
|
2621
2661
|
error: error$1
|
|
2622
2662
|
});
|
|
2623
2663
|
}
|
|
2664
|
+
if (error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode)) {
|
|
2665
|
+
logger$1.warn("Permanent delivery failure for activity {activityId} to {inbox} ({status}); not retrying.", {
|
|
2666
|
+
...logData,
|
|
2667
|
+
status: error.statusCode
|
|
2668
|
+
});
|
|
2669
|
+
if (this.outboxPermanentFailureHandler != null) {
|
|
2670
|
+
const ctx = this.#createContext(new URL(message.baseUrl), _, { documentLoader: this.documentLoaderFactory(loaderOptions) });
|
|
2671
|
+
try {
|
|
2672
|
+
await this.outboxPermanentFailureHandler(ctx, {
|
|
2673
|
+
inbox: new URL(message.inbox),
|
|
2674
|
+
activity,
|
|
2675
|
+
error,
|
|
2676
|
+
statusCode: error.statusCode,
|
|
2677
|
+
actorIds: (message.actorIds ?? []).flatMap((id) => {
|
|
2678
|
+
try {
|
|
2679
|
+
return [new URL(id)];
|
|
2680
|
+
} catch {
|
|
2681
|
+
logger$1.warn("Invalid actorId URL in OutboxMessage: {id}", { id });
|
|
2682
|
+
return [];
|
|
2683
|
+
}
|
|
2684
|
+
})
|
|
2685
|
+
});
|
|
2686
|
+
} catch (handlerError) {
|
|
2687
|
+
logger$1.error("An unexpected error occurred in outboxPermanentFailureHandler:\n{error}", {
|
|
2688
|
+
...logData,
|
|
2689
|
+
error: handlerError
|
|
2690
|
+
});
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
return;
|
|
2694
|
+
}
|
|
2624
2695
|
if (this.outboxQueue?.nativeRetrial) {
|
|
2625
2696
|
logger$1.error("Failed to send activity {activityId} to {inbox}; backend will handle retry:\n{error}", {
|
|
2626
2697
|
...logData,
|
|
@@ -2662,8 +2733,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2662
2733
|
const identity = await this.sharedInboxKeyDispatcher(context$2);
|
|
2663
2734
|
if (identity != null) context$2 = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity || "handle" in identity ? await context$2.getDocumentLoader(identity) : context$2.getDocumentLoader(identity) });
|
|
2664
2735
|
}
|
|
2665
|
-
const activity = await
|
|
2666
|
-
span.setAttribute("activitypub.activity.type",
|
|
2736
|
+
const activity = await __fedify_vocab.Activity.fromJsonLd(message.activity, context$2);
|
|
2737
|
+
span.setAttribute("activitypub.activity.type", (0, __fedify_vocab.getTypeId)(activity).href);
|
|
2667
2738
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2668
2739
|
const cacheKey = activity.id == null ? null : [
|
|
2669
2740
|
...this.kvPrefixes.activityIdempotence,
|
|
@@ -2692,7 +2763,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2692
2763
|
});
|
|
2693
2764
|
span$1.setStatus({
|
|
2694
2765
|
code: __opentelemetry_api.SpanStatusCode.ERROR,
|
|
2695
|
-
message: `Unsupported activity type: ${
|
|
2766
|
+
message: `Unsupported activity type: ${(0, __fedify_vocab.getTypeId)(activity).href}`
|
|
2696
2767
|
});
|
|
2697
2768
|
span$1.end();
|
|
2698
2769
|
return;
|
|
@@ -2700,7 +2771,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2700
2771
|
const { class: cls, listener } = dispatched;
|
|
2701
2772
|
span$1.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
2702
2773
|
try {
|
|
2703
|
-
await listener(context$2.toInboxContext(message.identifier, message.activity, activity.id?.href,
|
|
2774
|
+
await listener(context$2.toInboxContext(message.identifier, message.activity, activity.id?.href, (0, __fedify_vocab.getTypeId)(activity).href), activity);
|
|
2704
2775
|
} catch (error) {
|
|
2705
2776
|
try {
|
|
2706
2777
|
await this.inboxErrorHandler?.(context$2, error);
|
|
@@ -2811,7 +2882,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2811
2882
|
"federation",
|
|
2812
2883
|
"outbox"
|
|
2813
2884
|
]);
|
|
2814
|
-
const { immediate, collectionSync, context: ctx } = options;
|
|
2885
|
+
const { immediate, collectionSync, orderingKey, context: ctx } = options;
|
|
2815
2886
|
if (activity.id == null) throw new TypeError("The activity to send must have an id.");
|
|
2816
2887
|
if (activity.actorId == null) throw new TypeError("The activity to send must have at least one actor property.");
|
|
2817
2888
|
else if (keys.length < 1) throw new TypeError("The keys must not be empty.");
|
|
@@ -2872,7 +2943,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2872
2943
|
keys,
|
|
2873
2944
|
activity: jsonLd,
|
|
2874
2945
|
activityId: activity.id?.href,
|
|
2875
|
-
activityType:
|
|
2946
|
+
activityType: (0, __fedify_vocab.getTypeId)(activity).href,
|
|
2876
2947
|
inbox: new URL(inbox),
|
|
2877
2948
|
sharedInbox: inboxes[inbox].sharedInbox,
|
|
2878
2949
|
headers: collectionSync == null ? void 0 : new Headers({ "Collection-Synchronization": await buildCollectionSynchronizationHeader(collectionSync, inboxes[inbox].actorIds) }),
|
|
@@ -2899,6 +2970,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2899
2970
|
__opentelemetry_api.propagation.inject(__opentelemetry_api.context.active(), carrier);
|
|
2900
2971
|
const messages = [];
|
|
2901
2972
|
for (const inbox in inboxes) {
|
|
2973
|
+
const inboxOrigin = new URL(inbox).origin;
|
|
2974
|
+
const messageOrderingKey = orderingKey == null ? void 0 : `${orderingKey}\n${inboxOrigin}`;
|
|
2902
2975
|
const message = {
|
|
2903
2976
|
type: "outbox",
|
|
2904
2977
|
id: crypto.randomUUID(),
|
|
@@ -2906,19 +2979,36 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2906
2979
|
keys: keyJwkPairs,
|
|
2907
2980
|
activity: jsonLd,
|
|
2908
2981
|
activityId: activity.id?.href,
|
|
2909
|
-
activityType:
|
|
2982
|
+
activityType: (0, __fedify_vocab.getTypeId)(activity).href,
|
|
2910
2983
|
inbox,
|
|
2911
2984
|
sharedInbox: inboxes[inbox].sharedInbox,
|
|
2985
|
+
actorIds: [...inboxes[inbox].actorIds],
|
|
2912
2986
|
started: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2913
2987
|
attempt: 0,
|
|
2914
2988
|
headers: collectionSync == null ? {} : { "Collection-Synchronization": await buildCollectionSynchronizationHeader(collectionSync, inboxes[inbox].actorIds) },
|
|
2989
|
+
orderingKey: messageOrderingKey,
|
|
2915
2990
|
traceContext: carrier
|
|
2916
2991
|
};
|
|
2917
|
-
messages.push(
|
|
2992
|
+
messages.push({
|
|
2993
|
+
message,
|
|
2994
|
+
orderingKey: messageOrderingKey
|
|
2995
|
+
});
|
|
2918
2996
|
}
|
|
2919
2997
|
const { outboxQueue } = this;
|
|
2920
2998
|
if (outboxQueue.enqueueMany == null) {
|
|
2921
|
-
const promises = messages.map((m) => outboxQueue.enqueue(m));
|
|
2999
|
+
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
3000
|
+
const results = await Promise.allSettled(promises);
|
|
3001
|
+
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
3002
|
+
if (errors.length > 0) {
|
|
3003
|
+
logger$1.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
3004
|
+
activityId: activity.id.href,
|
|
3005
|
+
errors
|
|
3006
|
+
});
|
|
3007
|
+
if (errors.length > 1) throw new AggregateError(errors, `Failed to enqueue activity ${activityId} to send later.`);
|
|
3008
|
+
throw errors[0];
|
|
3009
|
+
}
|
|
3010
|
+
} else if (orderingKey != null) {
|
|
3011
|
+
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
2922
3012
|
const results = await Promise.allSettled(promises);
|
|
2923
3013
|
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2924
3014
|
if (errors.length > 0) {
|
|
@@ -2930,7 +3020,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2930
3020
|
throw errors[0];
|
|
2931
3021
|
}
|
|
2932
3022
|
} else try {
|
|
2933
|
-
await outboxQueue.enqueueMany(messages);
|
|
3023
|
+
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
2934
3024
|
} catch (error) {
|
|
2935
3025
|
logger$1.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
2936
3026
|
activityId: activity.id.href,
|
|
@@ -3461,12 +3551,12 @@ var ContextImpl = class ContextImpl {
|
|
|
3461
3551
|
for (const keyPair of keyPairs) {
|
|
3462
3552
|
const newPair = {
|
|
3463
3553
|
...keyPair,
|
|
3464
|
-
cryptographicKey: new
|
|
3554
|
+
cryptographicKey: new __fedify_vocab.CryptographicKey({
|
|
3465
3555
|
id: keyPair.keyId,
|
|
3466
3556
|
owner,
|
|
3467
3557
|
publicKey: keyPair.publicKey
|
|
3468
3558
|
}),
|
|
3469
|
-
multikey: new
|
|
3559
|
+
multikey: new __fedify_vocab.Multikey({
|
|
3470
3560
|
id: keyPair.keyId,
|
|
3471
3561
|
controller: owner,
|
|
3472
3562
|
publicKey: keyPair.publicKey
|
|
@@ -3552,7 +3642,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3552
3642
|
return this.federation.authenticatedDocumentLoaderFactory(identity);
|
|
3553
3643
|
}
|
|
3554
3644
|
lookupObject(identifier, options = {}) {
|
|
3555
|
-
return
|
|
3645
|
+
return (0, __fedify_vocab.lookupObject)(identifier, {
|
|
3556
3646
|
...options,
|
|
3557
3647
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3558
3648
|
contextLoader: options.contextLoader ?? this.contextLoader,
|
|
@@ -3562,7 +3652,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3562
3652
|
});
|
|
3563
3653
|
}
|
|
3564
3654
|
traverseCollection(collection, options = {}) {
|
|
3565
|
-
return
|
|
3655
|
+
return (0, __fedify_vocab.traverseCollection)(collection, {
|
|
3566
3656
|
...options,
|
|
3567
3657
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3568
3658
|
contextLoader: options.contextLoader ?? this.contextLoader
|
|
@@ -3580,7 +3670,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3580
3670
|
});
|
|
3581
3671
|
}
|
|
3582
3672
|
lookupWebFinger(resource, options = {}) {
|
|
3583
|
-
return
|
|
3673
|
+
return (0, __fedify_webfinger.lookupWebFinger)(resource, {
|
|
3584
3674
|
...options,
|
|
3585
3675
|
userAgent: options.userAgent ?? this.federation.userAgent,
|
|
3586
3676
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
@@ -3588,11 +3678,11 @@ var ContextImpl = class ContextImpl {
|
|
|
3588
3678
|
});
|
|
3589
3679
|
}
|
|
3590
3680
|
sendActivity(sender, recipients, activity, options = {}) {
|
|
3591
|
-
const tracer = this.tracerProvider.getTracer(
|
|
3681
|
+
const tracer = this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
3592
3682
|
return tracer.startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
3593
3683
|
kind: this.federation.outboxQueue == null || options.immediate ? __opentelemetry_api.SpanKind.CLIENT : __opentelemetry_api.SpanKind.PRODUCER,
|
|
3594
3684
|
attributes: {
|
|
3595
|
-
"activitypub.activity.type":
|
|
3685
|
+
"activitypub.activity.type": (0, __fedify_vocab.getTypeId)(activity).href,
|
|
3596
3686
|
"activitypub.activity.to": activity.toIds.map((to) => to.href),
|
|
3597
3687
|
"activitypub.activity.cc": activity.toIds.map((cc) => cc.href),
|
|
3598
3688
|
"activitypub.activity.bto": activity.btoIds.map((bto) => bto.href),
|
|
@@ -3646,20 +3736,25 @@ var ContextImpl = class ContextImpl {
|
|
|
3646
3736
|
} else keys = [sender];
|
|
3647
3737
|
if (keys.length < 1) throw new TypeError("The sender's keys must not be empty.");
|
|
3648
3738
|
for (const { privateKey } of keys) require_http.validateCryptoKey(privateKey, "private");
|
|
3649
|
-
const opts = { context: this };
|
|
3650
3739
|
let expandedRecipients;
|
|
3740
|
+
let collectionSync;
|
|
3651
3741
|
if (Array.isArray(recipients)) expandedRecipients = recipients;
|
|
3652
3742
|
else if (recipients === "followers") {
|
|
3653
3743
|
if (identifier == null) throw new Error("If recipients is \"followers\", sender must be an actor identifier or username.");
|
|
3654
3744
|
expandedRecipients = [];
|
|
3655
3745
|
for await (const recipient of this.getFollowers(identifier)) expandedRecipients.push(recipient);
|
|
3656
3746
|
if (options.syncCollection) try {
|
|
3657
|
-
|
|
3747
|
+
collectionSync = this.getFollowersUri(identifier).href;
|
|
3658
3748
|
} catch (error) {
|
|
3659
|
-
if (error instanceof RouterError)
|
|
3660
|
-
else throw error;
|
|
3749
|
+
if (!(error instanceof RouterError)) throw error;
|
|
3661
3750
|
}
|
|
3662
3751
|
} else expandedRecipients = [recipients];
|
|
3752
|
+
const opts = {
|
|
3753
|
+
context: this,
|
|
3754
|
+
orderingKey: options.orderingKey,
|
|
3755
|
+
collectionSync,
|
|
3756
|
+
immediate: options.immediate
|
|
3757
|
+
};
|
|
3663
3758
|
span.setAttribute("activitypub.inboxes", expandedRecipients.length);
|
|
3664
3759
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
3665
3760
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
@@ -3704,12 +3799,13 @@ var ContextImpl = class ContextImpl {
|
|
|
3704
3799
|
contextLoader: this.contextLoader
|
|
3705
3800
|
}),
|
|
3706
3801
|
activityId: activity.id?.href,
|
|
3707
|
-
activityType:
|
|
3802
|
+
activityType: (0, __fedify_vocab.getTypeId)(activity).href,
|
|
3708
3803
|
collectionSync: opts.collectionSync,
|
|
3804
|
+
orderingKey: options.orderingKey,
|
|
3709
3805
|
traceContext: carrier
|
|
3710
3806
|
};
|
|
3711
3807
|
if (!this.federation.manuallyStartQueue) this.federation._startQueueInternal(this.data);
|
|
3712
|
-
this.federation.fanoutQueue.enqueue(message);
|
|
3808
|
+
this.federation.fanoutQueue.enqueue(message, { orderingKey: options.orderingKey });
|
|
3713
3809
|
}
|
|
3714
3810
|
async *getFollowers(identifier) {
|
|
3715
3811
|
if (this.federation.followersCallbacks == null) throw new Error("No followers collection dispatcher registered.");
|
|
@@ -3734,10 +3830,10 @@ var ContextImpl = class ContextImpl {
|
|
|
3734
3830
|
}
|
|
3735
3831
|
routeActivity(recipient, activity, options = {}) {
|
|
3736
3832
|
const tracerProvider = this.tracerProvider ?? this.tracerProvider;
|
|
3737
|
-
const tracer = tracerProvider.getTracer(
|
|
3833
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
3738
3834
|
return tracer.startActiveSpan("activitypub.inbox", {
|
|
3739
3835
|
kind: this.federation.inboxQueue == null || options.immediate ? __opentelemetry_api.SpanKind.INTERNAL : __opentelemetry_api.SpanKind.PRODUCER,
|
|
3740
|
-
attributes: { "activitypub.activity.type":
|
|
3836
|
+
attributes: { "activitypub.activity.type": (0, __fedify_vocab.getTypeId)(activity).href }
|
|
3741
3837
|
}, async (span) => {
|
|
3742
3838
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
3743
3839
|
if (activity.toIds.length > 0) span.setAttribute("activitypub.activity.to", activity.toIds.map((to) => to.href));
|
|
@@ -3771,7 +3867,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3771
3867
|
const contextLoader = options.contextLoader ?? this.contextLoader;
|
|
3772
3868
|
const json = await activity.toJsonLd({ contextLoader });
|
|
3773
3869
|
const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, this);
|
|
3774
|
-
const verified = await require_proof.verifyObject(
|
|
3870
|
+
const verified = await require_proof.verifyObject(__fedify_vocab.Activity, json, {
|
|
3775
3871
|
contextLoader,
|
|
3776
3872
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3777
3873
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
@@ -3797,7 +3893,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3797
3893
|
activityId: activity.id.href
|
|
3798
3894
|
});
|
|
3799
3895
|
return false;
|
|
3800
|
-
} else if (!(fetched instanceof
|
|
3896
|
+
} else if (!(fetched instanceof __fedify_vocab.Activity)) {
|
|
3801
3897
|
logger$1.debug("Fetched object is not an Activity.", {
|
|
3802
3898
|
recipient,
|
|
3803
3899
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
@@ -3952,7 +4048,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3952
4048
|
});
|
|
3953
4049
|
}
|
|
3954
4050
|
forwardActivity(forwarder, recipients, options) {
|
|
3955
|
-
const tracer = this.tracerProvider.getTracer(
|
|
4051
|
+
const tracer = this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
3956
4052
|
return tracer.startActiveSpan("activitypub.outbox", {
|
|
3957
4053
|
kind: this.federation.outboxQueue == null || options?.immediate ? __opentelemetry_api.SpanKind.CLIENT : __opentelemetry_api.SpanKind.PRODUCER,
|
|
3958
4054
|
attributes: { "activitypub.activity.type": this.activityType }
|
|
@@ -4004,7 +4100,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4004
4100
|
if (!require_proof.hasSignature(this.activity)) {
|
|
4005
4101
|
let hasProof;
|
|
4006
4102
|
try {
|
|
4007
|
-
const activity = await
|
|
4103
|
+
const activity = await __fedify_vocab.Activity.fromJsonLd(this.activity, this);
|
|
4008
4104
|
hasProof = await activity.getProof() != null;
|
|
4009
4105
|
} catch {
|
|
4010
4106
|
hasProof = false;
|
|
@@ -4061,8 +4157,10 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4061
4157
|
}
|
|
4062
4158
|
const carrier = {};
|
|
4063
4159
|
__opentelemetry_api.propagation.inject(__opentelemetry_api.context.active(), carrier);
|
|
4160
|
+
const orderingKey = options?.orderingKey;
|
|
4064
4161
|
const messages = [];
|
|
4065
4162
|
for (const inbox in inboxes) {
|
|
4163
|
+
const inboxUrl = new URL(inbox);
|
|
4066
4164
|
const message = {
|
|
4067
4165
|
type: "outbox",
|
|
4068
4166
|
id: crypto.randomUUID(),
|
|
@@ -4076,13 +4174,29 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4076
4174
|
started: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4077
4175
|
attempt: 0,
|
|
4078
4176
|
headers: {},
|
|
4177
|
+
orderingKey: orderingKey == null ? void 0 : `${orderingKey}\n${inboxUrl.origin}`,
|
|
4079
4178
|
traceContext: carrier
|
|
4080
4179
|
};
|
|
4081
|
-
messages.push(
|
|
4180
|
+
messages.push({
|
|
4181
|
+
message,
|
|
4182
|
+
orderingKey: message.orderingKey
|
|
4183
|
+
});
|
|
4082
4184
|
}
|
|
4083
4185
|
const { outboxQueue } = this.federation;
|
|
4084
4186
|
if (outboxQueue.enqueueMany == null) {
|
|
4085
|
-
const promises = messages.map((m) => outboxQueue.enqueue(m));
|
|
4187
|
+
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4188
|
+
const results = await Promise.allSettled(promises);
|
|
4189
|
+
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4190
|
+
if (errors.length > 0) {
|
|
4191
|
+
logger$1.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4192
|
+
activityId: this.activityId,
|
|
4193
|
+
errors
|
|
4194
|
+
});
|
|
4195
|
+
if (errors.length > 1) throw new AggregateError(errors, `Failed to enqueue activity ${this.activityId} to forward later.`);
|
|
4196
|
+
throw errors[0];
|
|
4197
|
+
}
|
|
4198
|
+
} else if (orderingKey != null) {
|
|
4199
|
+
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4086
4200
|
const results = await Promise.allSettled(promises);
|
|
4087
4201
|
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4088
4202
|
if (errors.length > 0) {
|
|
@@ -4094,7 +4208,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4094
4208
|
throw errors[0];
|
|
4095
4209
|
}
|
|
4096
4210
|
} else try {
|
|
4097
|
-
await outboxQueue.enqueueMany(messages);
|
|
4211
|
+
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
4098
4212
|
} catch (error) {
|
|
4099
4213
|
logger$1.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
|
|
4100
4214
|
activityId: this.activityId,
|
|
@@ -4193,6 +4307,12 @@ Object.defineProperty(exports, 'RouterError', {
|
|
|
4193
4307
|
return RouterError;
|
|
4194
4308
|
}
|
|
4195
4309
|
});
|
|
4310
|
+
Object.defineProperty(exports, 'SendActivityError', {
|
|
4311
|
+
enumerable: true,
|
|
4312
|
+
get: function () {
|
|
4313
|
+
return SendActivityError;
|
|
4314
|
+
}
|
|
4315
|
+
});
|
|
4196
4316
|
Object.defineProperty(exports, 'buildCollectionSynchronizationHeader', {
|
|
4197
4317
|
enumerable: true,
|
|
4198
4318
|
get: function () {
|
|
@@ -4223,6 +4343,12 @@ Object.defineProperty(exports, 'digest', {
|
|
|
4223
4343
|
return digest;
|
|
4224
4344
|
}
|
|
4225
4345
|
});
|
|
4346
|
+
Object.defineProperty(exports, 'handleWebFinger', {
|
|
4347
|
+
enumerable: true,
|
|
4348
|
+
get: function () {
|
|
4349
|
+
return handleWebFinger;
|
|
4350
|
+
}
|
|
4351
|
+
});
|
|
4226
4352
|
Object.defineProperty(exports, 'respondWithObject', {
|
|
4227
4353
|
enumerable: true,
|
|
4228
4354
|
get: function () {
|