@fedify/fedify 2.0.7 → 2.0.9
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/{assert-MZs1qjMx.js → assert-ddO5KLpe.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_not_equals-C80BG-_5.js → assert_not_equals--wG9hV7u.mjs} +6 -13
- package/dist/{assert_rejects-Ce45JcFg.js → assert_rejects-B-qJtC9Z.mjs} +6 -11
- package/dist/{assert_throws-BNXdRGWP.js → assert_throws-4NwKEy2q.mjs} +5 -10
- package/dist/{builder-DA7Qgx_F.js → builder-DDoQaGOu.mjs} +32 -41
- package/dist/{chunk-CGaQZ11T.cjs → chunk-DDcVe30Y.cjs} +23 -24
- package/dist/{chunk-DJNbSFdH.js → chunk-nlSIicah.js} +8 -8
- package/dist/{client-CoCIaTNO.js → client-A1UrnX6I.mjs} +9 -13
- package/dist/{client-BxMZiQaD.d.ts → client-AtlibPOU.d.ts} +1 -1
- package/dist/{client-C97KOq3x.d.cts → client-z-8dc-e1.d.cts} +1 -1
- package/dist/{collection-CcnIw1qY.js → collection-ChgDTHLz.mjs} +7 -12
- package/dist/compat/mod.cjs +5 -8
- package/dist/compat/mod.d.cts +78 -6
- package/dist/compat/mod.d.ts +78 -6
- package/dist/compat/mod.js +4 -8
- package/dist/compat/transformers.test.mjs +62 -0
- package/dist/{context-D3QkEtZd.d.cts → context-CNIt-Qn7.d.cts} +9 -18
- package/dist/{context-DZJhUmzF.d.ts → context-Dyg7P1qW.d.ts} +9 -18
- package/dist/{context-pa9aIrwp.js → context-Juj6bdHC.mjs} +7 -11
- package/dist/deno-CuVDEdyj.mjs +8 -0
- package/dist/{docloader-CJeSPcS_.js → docloader-BPq9yzC_.mjs} +8 -14
- package/dist/{esm-nLm00z9V.js → esm-DVILvP5e.mjs} +50 -89
- package/dist/federation/builder.test.d.mts +2 -0
- package/dist/federation/{builder.test.js → builder.test.mjs} +19 -38
- 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} +26 -56
- package/dist/federation/idempotency.test.d.mts +2 -0
- package/dist/federation/{idempotency.test.js → idempotency.test.mjs} +31 -62
- package/dist/federation/inbox.test.d.mts +2 -0
- package/dist/federation/{inbox.test.js → inbox.test.mjs} +8 -12
- package/dist/federation/keycache.test.d.mts +2 -0
- package/dist/federation/{keycache.test.js → keycache.test.mjs} +13 -13
- package/dist/federation/kv.test.d.mts +2 -0
- package/dist/federation/{kv.test.js → kv.test.mjs} +11 -22
- package/dist/federation/middleware.test.d.mts +2 -0
- package/dist/federation/{middleware.test.js → middleware.test.mjs} +146 -225
- package/dist/federation/mod.cjs +327 -16
- package/dist/federation/mod.d.cts +3 -6
- package/dist/federation/mod.d.ts +3 -6
- package/dist/federation/mod.js +322 -13
- package/dist/federation/mq.test.d.mts +2 -0
- package/dist/federation/{mq.test.js → mq.test.mjs} +21 -35
- package/dist/federation/negotiation.test.d.mts +2 -0
- package/dist/federation/{negotiation.test.js → negotiation.test.mjs} +9 -16
- package/dist/federation/retry.test.d.mts +2 -0
- package/dist/federation/{retry.test.js → retry.test.mjs} +8 -11
- package/dist/federation/router.test.d.mts +2 -0
- package/dist/federation/{router.test.js → router.test.mjs} +11 -16
- package/dist/federation/send.test.d.mts +2 -0
- package/dist/federation/{send.test.js → send.test.mjs} +22 -29
- package/dist/federation/webfinger.test.d.mts +2 -0
- package/dist/federation/{webfinger.test.js → webfinger.test.mjs} +22 -55
- package/dist/{http-DkHdFfrc.d.ts → http-B2wiNmSo.d.ts} +1 -6
- package/dist/{http-B3vAjAtl.js → http-Bz7avX57.js} +39 -159
- package/dist/{http-Cz3MlXAZ.d.cts → http-C_tEAiZj.d.cts} +1 -6
- package/dist/{http-CjaLjnRN.js → http-DI213UHg.mjs} +31 -35
- package/dist/{http-CQ7TiYUI.cjs → http-DKBDoudA.cjs} +119 -233
- package/dist/{inbox-B33isX44.js → inbox-Bdn-CSRd.mjs} +18 -26
- package/dist/{key-Cga1p73u.js → key-DzJf84o7.mjs} +12 -19
- package/dist/{keycache-DRxpZ5r9.js → keycache-DaQ3ndaJ.mjs} +15 -10
- package/dist/{keys-ZbcByPg9.js → keys-CtZLJq76.mjs} +5 -9
- package/dist/{kv-QzKcOQgP.js → kv-BrZHNugx.mjs} +6 -10
- package/dist/{kv-BL4nlICN.d.cts → kv-CbLNp3zQ.d.cts} +1 -1
- package/dist/{kv-DXEUEP6z.d.ts → kv-GFYnFoOl.d.ts} +1 -1
- package/dist/{kv-cache-CFdy0BpZ.js → kv-cache-DBd7BezJ.js} +6 -13
- package/dist/{kv-cache--qyREO7e.cjs → kv-cache-Dj1Q7TiW.cjs} +27 -34
- package/dist/{kv-cache-El7We5sy.js → kv-cache-OWmRLHir.mjs} +4 -8
- package/dist/{ld-BWSOukKj.js → ld-DczS1fLK.mjs} +17 -31
- package/dist/middleware-B5CiOImA.mjs +5 -0
- package/dist/{middleware-CP7JdsGq.js → middleware-BKNu57ZI.js} +331 -365
- package/dist/middleware-C36TOX-2.cjs +4 -0
- package/dist/{middleware-Scz2k9eL.cjs → middleware-CyjmpK70.cjs} +523 -565
- package/dist/{middleware-BI1VCuPT.js → middleware-DoHz9oIo.mjs} +260 -292
- package/dist/{mod-DPkRU3EK.d.cts → mod-1xhgsHef.d.cts} +2 -2
- package/dist/{mod-DUWcVv49.d.ts → mod-BGtYJZKu.d.ts} +2 -2
- package/dist/{mod-DXsQakeS.d.cts → mod-Bld7oeqf.d.cts} +3 -3
- package/dist/{mod-DnSsduJF.d.ts → mod-BnAKGh2w.d.ts} +2 -2
- package/dist/{mod-CwZXZJ9d.d.ts → mod-DTOUyCce.d.ts} +3 -3
- package/dist/{mod-Di3W5OdP.d.cts → mod-DWoQffTD.d.cts} +2 -2
- package/dist/mod.cjs +29 -68
- package/dist/mod.d.cts +11 -14
- package/dist/mod.d.ts +11 -15
- package/dist/mod.js +17 -65
- package/dist/{negotiation-5NPJL6zp.js → negotiation-BehA2uul.mjs} +7 -11
- package/dist/nodeinfo/client.test.d.mts +2 -0
- package/dist/nodeinfo/{client.test.js → client.test.mjs} +22 -40
- package/dist/nodeinfo/handler.test.d.mts +2 -0
- package/dist/nodeinfo/{handler.test.js → handler.test.mjs} +13 -42
- package/dist/nodeinfo/mod.cjs +5 -8
- package/dist/nodeinfo/mod.d.cts +2 -3
- package/dist/nodeinfo/mod.d.ts +2 -3
- package/dist/nodeinfo/mod.js +4 -8
- package/dist/nodeinfo/types.test.d.mts +2 -0
- package/dist/nodeinfo/{types.test.js → types.test.mjs} +9 -16
- package/dist/otel/exporter.test.d.mts +2 -0
- package/dist/otel/{exporter.test.js → exporter.test.mjs} +117 -169
- package/dist/otel/mod.cjs +15 -20
- package/dist/otel/mod.d.cts +2 -2
- package/dist/otel/mod.d.ts +2 -2
- package/dist/otel/mod.js +8 -14
- package/dist/{owner-gd0Q9FuU.d.ts → owner-74ARJ5TL.d.ts} +1 -1
- package/dist/{owner-1AbPBOOZ.d.cts → owner-CptqhsOy.d.cts} +1 -1
- package/dist/{owner-HASxJJP1.js → owner-DXMGUEOr.mjs} +11 -16
- package/dist/{proof-BwfRl5J4.js → proof-C-7NljBU.js} +33 -59
- package/dist/{proof-BXt2Oi8t.js → proof-CEOujj0L.mjs} +21 -33
- package/dist/{proof-BYZ4hcgN.cjs → proof-DMu-6A_w.cjs} +133 -157
- package/dist/{retry-D4GJ670a.js → retry-Ddbq3AcK.mjs} +4 -7
- package/dist/{router-D9eI0s4b.js → router-CrMLXoOr.mjs} +4 -8
- package/dist/runtime/mod.cjs +11 -13
- package/dist/runtime/mod.d.cts +6 -2
- package/dist/runtime/mod.d.ts +0 -1
- package/dist/runtime/mod.js +4 -7
- package/dist/{send-BF3omx5-.js → send-DIfrLTB_.mjs} +8 -13
- package/dist/sig/http.test.d.mts +2 -0
- package/dist/sig/{http.test.js → http.test.mjs} +160 -199
- package/dist/sig/key.test.d.mts +2 -0
- package/dist/sig/{key.test.js → key.test.mjs} +11 -18
- package/dist/sig/ld.test.d.mts +2 -0
- package/dist/sig/{ld.test.js → ld.test.mjs} +22 -35
- package/dist/sig/mod.cjs +6 -9
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +5 -9
- package/dist/sig/owner.test.d.mts +2 -0
- package/dist/sig/{owner.test.js → owner.test.mjs} +19 -34
- package/dist/sig/proof.test.d.mts +2 -0
- package/dist/sig/{proof.test.js → proof.test.mjs} +16 -27
- package/dist/{std__assert-DWivtrGR.js → std__assert-Duiq_YC9.mjs} +12 -24
- package/dist/testing/{mod.d.ts → mod.d.mts} +26 -78
- package/dist/testing/mod.mjs +6 -0
- package/dist/{transformers-3g8GZwkZ.cjs → transformers-NeAONrAq.cjs} +20 -25
- package/dist/{transformers-C3FLHUd6.js → transformers-ve6e2xcg.js} +3 -7
- package/dist/{types-CPz01LGH.js → types-C37hquWI.mjs} +4 -7
- package/dist/{types-Cd_hszr_.cjs → types-KC4QAoxe.cjs} +29 -34
- package/dist/{types-C93Ob9cU.js → types-hvL8ElAs.js} +8 -13
- package/dist/utils/docloader.test.d.mts +2 -0
- package/dist/utils/{docloader.test.js → docloader.test.mjs} +14 -24
- package/dist/utils/kv-cache.test.d.mts +2 -0
- package/dist/utils/{kv-cache.test.js → kv-cache.test.mjs} +25 -40
- package/dist/utils/mod.cjs +5 -9
- package/dist/utils/mod.d.cts +1 -3
- package/dist/utils/mod.d.ts +1 -3
- package/dist/utils/mod.js +4 -9
- package/dist/vocab/cjs.test.d.mts +2 -0
- package/dist/vocab/cjs.test.mjs +14 -0
- package/dist/vocab/mod.cjs +10 -12
- package/dist/vocab/mod.js +3 -5
- package/package.json +7 -7
- package/dist/compat/transformers.test.d.ts +0 -3
- package/dist/compat/transformers.test.js +0 -87
- package/dist/compat-Bb4NuTUO.js +0 -4
- package/dist/compat-DmDDELst.cjs +0 -4
- package/dist/deno-CbQK8e-e.js +0 -121
- 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 -32
- 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/negotiation.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/webfinger.test.d.ts +0 -3
- package/dist/federation-Bp3HI26G.cjs +0 -350
- package/dist/federation-DaMfqRm4.js +0 -332
- package/dist/middleware-CcXQzfn8.cjs +0 -12
- package/dist/middleware-CoeaBowW.js +0 -12
- package/dist/middleware-vH2jFwC6.js +0 -26
- package/dist/mod-Bh8mqlYw.d.cts +0 -9
- package/dist/mod-D6HodEq7.d.ts +0 -7
- package/dist/mod-DVwHUI_x.d.cts +0 -80
- package/dist/mod-DosD6NsG.d.ts +0 -82
- package/dist/mod-gq_Xfdz8.d.cts +0 -1
- package/dist/nodeinfo/client.test.d.ts +0 -3
- package/dist/nodeinfo/handler.test.d.ts +0 -3
- package/dist/nodeinfo/types.test.d.ts +0 -3
- package/dist/nodeinfo-DoESQxq5.js +0 -4
- package/dist/nodeinfo-DuMYTpbZ.cjs +0 -4
- package/dist/otel/exporter.test.d.ts +0 -3
- package/dist/runtime-c2Njxsry.cjs +0 -17
- package/dist/runtime-poamPCMb.js +0 -13
- 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-BNhspNOf.js +0 -4
- package/dist/sig-vX39WyWI.cjs +0 -4
- package/dist/testing/mod.js +0 -10
- package/dist/utils/docloader.test.d.ts +0 -3
- package/dist/utils/kv-cache.test.d.ts +0 -3
- package/dist/utils-BQ9KqEK9.cjs +0 -4
- package/dist/utils-Dn5OPdSW.js +0 -4
- /package/dist/{mod-AGjRfPjT.d.ts → compat/transformers.test.d.mts} +0 -0
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const __fedify_webfinger = require_chunk.__toESM(require("@fedify/webfinger"));
|
|
21
|
-
const node_url = require_chunk.__toESM(require("node:url"));
|
|
22
|
-
|
|
1
|
+
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
|
+
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
|
+
require("./chunk-DDcVe30Y.cjs");
|
|
4
|
+
const require_transformers = require("./transformers-NeAONrAq.cjs");
|
|
5
|
+
const require_http = require("./http-DKBDoudA.cjs");
|
|
6
|
+
const require_proof = require("./proof-DMu-6A_w.cjs");
|
|
7
|
+
const require_types = require("./types-KC4QAoxe.cjs");
|
|
8
|
+
const require_kv_cache = require("./kv-cache-Dj1Q7TiW.cjs");
|
|
9
|
+
let _logtape_logtape = require("@logtape/logtape");
|
|
10
|
+
let _fedify_vocab = require("@fedify/vocab");
|
|
11
|
+
let _opentelemetry_api = require("@opentelemetry/api");
|
|
12
|
+
let es_toolkit = require("es-toolkit");
|
|
13
|
+
let uri_template_router = require("uri-template-router");
|
|
14
|
+
let url_template = require("url-template");
|
|
15
|
+
let byte_encodings_hex = require("byte-encodings/hex");
|
|
16
|
+
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
17
|
+
let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
18
|
+
let _fedify_webfinger = require("@fedify/webfinger");
|
|
19
|
+
let node_url = require("node:url");
|
|
23
20
|
//#region src/federation/inbox.ts
|
|
24
21
|
var InboxListenerSet = class InboxListenerSet {
|
|
25
22
|
#listeners;
|
|
@@ -41,7 +38,7 @@ var InboxListenerSet = class InboxListenerSet {
|
|
|
41
38
|
if (inboxListeners == null) return null;
|
|
42
39
|
while (true) {
|
|
43
40
|
if (inboxListeners.has(cls)) break;
|
|
44
|
-
if (cls ===
|
|
41
|
+
if (cls === _fedify_vocab.Activity) return null;
|
|
45
42
|
cls = globalThis.Object.getPrototypeOf(cls);
|
|
46
43
|
}
|
|
47
44
|
const listener = inboxListeners.get(cls);
|
|
@@ -55,20 +52,18 @@ var InboxListenerSet = class InboxListenerSet {
|
|
|
55
52
|
}
|
|
56
53
|
};
|
|
57
54
|
async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
|
|
58
|
-
const logger
|
|
55
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
59
56
|
"fedify",
|
|
60
57
|
"federation",
|
|
61
58
|
"inbox"
|
|
62
59
|
]);
|
|
63
60
|
let cacheKey = null;
|
|
64
61
|
if (activity.id != null) {
|
|
65
|
-
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, (0,
|
|
62
|
+
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, (0, _fedify_vocab.getTypeId)(activity).href);
|
|
66
63
|
const strategy = idempotencyStrategy ?? "per-inbox";
|
|
67
64
|
let keyString;
|
|
68
|
-
if (typeof strategy === "function")
|
|
69
|
-
|
|
70
|
-
keyString = result;
|
|
71
|
-
} else switch (strategy) {
|
|
65
|
+
if (typeof strategy === "function") keyString = await strategy(inboxContext, activity);
|
|
66
|
+
else switch (strategy) {
|
|
72
67
|
case "global":
|
|
73
68
|
keyString = activity.id.href;
|
|
74
69
|
break;
|
|
@@ -83,24 +78,23 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
83
78
|
if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
|
|
84
79
|
}
|
|
85
80
|
if (cacheKey != null) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
logger$1.debug("Activity {activityId} has already been processed.", {
|
|
81
|
+
if (await kv.get(cacheKey) === true) {
|
|
82
|
+
logger.debug("Activity {activityId} has already been processed.", {
|
|
89
83
|
activityId: activity.id?.href,
|
|
90
84
|
activity: json,
|
|
91
85
|
recipient
|
|
92
86
|
});
|
|
93
87
|
span.setStatus({
|
|
94
|
-
code:
|
|
88
|
+
code: _opentelemetry_api.SpanStatusCode.UNSET,
|
|
95
89
|
message: `Activity ${activity.id?.href} has already been processed.`
|
|
96
90
|
});
|
|
97
91
|
return "alreadyProcessed";
|
|
98
92
|
}
|
|
99
93
|
}
|
|
100
94
|
if (activity.actorId == null) {
|
|
101
|
-
logger
|
|
95
|
+
logger.error("Missing actor.", { activity: json });
|
|
102
96
|
span.setStatus({
|
|
103
|
-
code:
|
|
97
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
104
98
|
message: "Missing actor."
|
|
105
99
|
});
|
|
106
100
|
return "missingActor";
|
|
@@ -108,7 +102,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
108
102
|
span.setAttribute("activitypub.actor.id", activity.actorId.href);
|
|
109
103
|
if (queue != null) {
|
|
110
104
|
const carrier = {};
|
|
111
|
-
|
|
105
|
+
_opentelemetry_api.propagation.inject(_opentelemetry_api.context.active(), carrier);
|
|
112
106
|
try {
|
|
113
107
|
await queue.enqueue({
|
|
114
108
|
type: "inbox",
|
|
@@ -121,80 +115,78 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
121
115
|
traceContext: carrier
|
|
122
116
|
});
|
|
123
117
|
} catch (error) {
|
|
124
|
-
logger
|
|
118
|
+
logger.error("Failed to enqueue the incoming activity {activityId}:\n{error}", {
|
|
125
119
|
error,
|
|
126
120
|
activityId: activity.id?.href,
|
|
127
121
|
activity: json,
|
|
128
122
|
recipient
|
|
129
123
|
});
|
|
130
124
|
span.setStatus({
|
|
131
|
-
code:
|
|
125
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
132
126
|
message: `Failed to enqueue the incoming activity ${activity.id?.href}.`
|
|
133
127
|
});
|
|
134
128
|
throw error;
|
|
135
129
|
}
|
|
136
|
-
logger
|
|
130
|
+
logger.info("Activity {activityId} is enqueued.", {
|
|
137
131
|
activityId: activity.id?.href,
|
|
138
132
|
activity: json,
|
|
139
133
|
recipient
|
|
140
134
|
});
|
|
141
135
|
return "enqueued";
|
|
142
136
|
}
|
|
143
|
-
tracerProvider = tracerProvider ??
|
|
144
|
-
|
|
145
|
-
return await tracer.startActiveSpan("activitypub.dispatch_inbox_listener", { kind: __opentelemetry_api.SpanKind.INTERNAL }, async (span$1) => {
|
|
137
|
+
tracerProvider = tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
138
|
+
return await tracerProvider.getTracer(require_http.name, require_http.version).startActiveSpan("activitypub.dispatch_inbox_listener", { kind: _opentelemetry_api.SpanKind.INTERNAL }, async (span) => {
|
|
146
139
|
const dispatched = inboxListeners?.dispatchWithClass(activity);
|
|
147
140
|
if (dispatched == null) {
|
|
148
|
-
logger
|
|
141
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
149
142
|
activity: json,
|
|
150
143
|
recipient
|
|
151
144
|
});
|
|
152
|
-
span
|
|
153
|
-
code:
|
|
154
|
-
message: `Unsupported activity type: ${(0,
|
|
145
|
+
span.setStatus({
|
|
146
|
+
code: _opentelemetry_api.SpanStatusCode.UNSET,
|
|
147
|
+
message: `Unsupported activity type: ${(0, _fedify_vocab.getTypeId)(activity).href}`
|
|
155
148
|
});
|
|
156
|
-
span
|
|
149
|
+
span.end();
|
|
157
150
|
return "unsupportedActivity";
|
|
158
151
|
}
|
|
159
152
|
const { class: cls, listener } = dispatched;
|
|
160
|
-
span
|
|
153
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
161
154
|
try {
|
|
162
|
-
await listener(inboxContextFactory(recipient, json, activity?.id?.href, (0,
|
|
155
|
+
await listener(inboxContextFactory(recipient, json, activity?.id?.href, (0, _fedify_vocab.getTypeId)(activity).href), activity);
|
|
163
156
|
} catch (error) {
|
|
164
157
|
try {
|
|
165
158
|
await inboxErrorHandler?.(ctx, error);
|
|
166
|
-
} catch (error
|
|
167
|
-
logger
|
|
168
|
-
error
|
|
159
|
+
} catch (error) {
|
|
160
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
161
|
+
error,
|
|
169
162
|
activityId: activity.id?.href,
|
|
170
163
|
activity: json,
|
|
171
164
|
recipient
|
|
172
165
|
});
|
|
173
166
|
}
|
|
174
|
-
logger
|
|
167
|
+
logger.error("Failed to process the incoming activity {activityId}:\n{error}", {
|
|
175
168
|
error,
|
|
176
169
|
activityId: activity.id?.href,
|
|
177
170
|
activity: json,
|
|
178
171
|
recipient
|
|
179
172
|
});
|
|
180
|
-
span
|
|
181
|
-
code:
|
|
173
|
+
span.setStatus({
|
|
174
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
182
175
|
message: String(error)
|
|
183
176
|
});
|
|
184
|
-
span
|
|
177
|
+
span.end();
|
|
185
178
|
return "error";
|
|
186
179
|
}
|
|
187
180
|
if (cacheKey != null) await kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
188
|
-
logger
|
|
181
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
189
182
|
activityId: activity.id?.href,
|
|
190
183
|
activity: json,
|
|
191
184
|
recipient
|
|
192
185
|
});
|
|
193
|
-
span
|
|
186
|
+
span.end();
|
|
194
187
|
return "success";
|
|
195
188
|
});
|
|
196
189
|
}
|
|
197
|
-
|
|
198
190
|
//#endregion
|
|
199
191
|
//#region src/federation/router.ts
|
|
200
192
|
function cloneInnerRouter(router) {
|
|
@@ -302,7 +294,6 @@ var RouterError = class extends Error {
|
|
|
302
294
|
this.name = "RouterError";
|
|
303
295
|
}
|
|
304
296
|
};
|
|
305
|
-
|
|
306
297
|
//#endregion
|
|
307
298
|
//#region src/federation/builder.ts
|
|
308
299
|
var FederationBuilderImpl = class {
|
|
@@ -339,8 +330,8 @@ var FederationBuilderImpl = class {
|
|
|
339
330
|
this.collectionTypeIds = {};
|
|
340
331
|
}
|
|
341
332
|
async build(options) {
|
|
342
|
-
const { FederationImpl
|
|
343
|
-
const f = new FederationImpl
|
|
333
|
+
const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-C36TOX-2.cjs"));
|
|
334
|
+
const f = new FederationImpl(options);
|
|
344
335
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
345
336
|
f.router = this.router.clone();
|
|
346
337
|
f.router.trailingSlashInsensitive = trailingSlashInsensitiveValue;
|
|
@@ -366,26 +357,26 @@ var FederationBuilderImpl = class {
|
|
|
366
357
|
return f;
|
|
367
358
|
}
|
|
368
359
|
_getTracer() {
|
|
369
|
-
return
|
|
360
|
+
return _opentelemetry_api.trace.getTracer(require_http.name, require_http.version);
|
|
370
361
|
}
|
|
371
362
|
setActorDispatcher(path, dispatcher) {
|
|
372
363
|
if (this.router.has("actor")) throw new RouterError("Actor dispatcher already set.");
|
|
373
364
|
const variables = this.router.add(path, "actor");
|
|
374
365
|
if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for actor dispatcher must have one variable: {identifier}");
|
|
375
|
-
const callbacks = { dispatcher: async (context
|
|
366
|
+
const callbacks = { dispatcher: async (context, identifier) => {
|
|
376
367
|
const actor = await this._getTracer().startActiveSpan("activitypub.dispatch_actor", {
|
|
377
|
-
kind:
|
|
368
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
378
369
|
attributes: { "fedify.actor.identifier": identifier }
|
|
379
370
|
}, async (span) => {
|
|
380
371
|
try {
|
|
381
|
-
const actor
|
|
382
|
-
span.setAttribute("activitypub.actor.id", (actor
|
|
383
|
-
if (actor
|
|
384
|
-
else span.setAttribute("activitypub.actor.type", (0,
|
|
385
|
-
return actor
|
|
372
|
+
const actor = await dispatcher(context, identifier);
|
|
373
|
+
span.setAttribute("activitypub.actor.id", (actor?.id ?? context.getActorUri(identifier)).href);
|
|
374
|
+
if (actor == null) span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
375
|
+
else span.setAttribute("activitypub.actor.type", (0, _fedify_vocab.getTypeId)(actor).href);
|
|
376
|
+
return actor;
|
|
386
377
|
} catch (error) {
|
|
387
378
|
span.setStatus({
|
|
388
|
-
code:
|
|
379
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
389
380
|
message: String(error)
|
|
390
381
|
});
|
|
391
382
|
throw error;
|
|
@@ -394,64 +385,64 @@ var FederationBuilderImpl = class {
|
|
|
394
385
|
}
|
|
395
386
|
});
|
|
396
387
|
if (actor == null) return null;
|
|
397
|
-
const logger
|
|
388
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
398
389
|
"fedify",
|
|
399
390
|
"federation",
|
|
400
391
|
"actor"
|
|
401
392
|
]);
|
|
402
|
-
if (actor.id == null) logger
|
|
403
|
-
else if (actor.id.href != context
|
|
393
|
+
if (actor.id == null) logger.warn("Actor dispatcher returned an actor without an id property. Set the property with Context.getActorUri(identifier).");
|
|
394
|
+
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).");
|
|
404
395
|
if (this.followingCallbacks != null && this.followingCallbacks.dispatcher != null) {
|
|
405
|
-
if (actor.followingId == null) logger
|
|
406
|
-
else if (actor.followingId.href != context
|
|
396
|
+
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).");
|
|
397
|
+
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).");
|
|
407
398
|
}
|
|
408
399
|
if (this.followersCallbacks != null && this.followersCallbacks.dispatcher != null) {
|
|
409
|
-
if (actor.followersId == null) logger
|
|
410
|
-
else if (actor.followersId.href != context
|
|
400
|
+
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).");
|
|
401
|
+
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).");
|
|
411
402
|
}
|
|
412
403
|
if (this.outboxCallbacks != null && this.outboxCallbacks.dispatcher != null) {
|
|
413
|
-
if (actor?.outboxId == null) logger
|
|
414
|
-
else if (actor.outboxId.href != context
|
|
404
|
+
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).");
|
|
405
|
+
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).");
|
|
415
406
|
}
|
|
416
407
|
if (this.likedCallbacks != null && this.likedCallbacks.dispatcher != null) {
|
|
417
|
-
if (actor?.likedId == null) logger
|
|
418
|
-
else if (actor.likedId.href != context
|
|
408
|
+
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).");
|
|
409
|
+
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).");
|
|
419
410
|
}
|
|
420
411
|
if (this.featuredCallbacks != null && this.featuredCallbacks.dispatcher != null) {
|
|
421
|
-
if (actor?.featuredId == null) logger
|
|
422
|
-
else if (actor.featuredId.href != context
|
|
412
|
+
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).");
|
|
413
|
+
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).");
|
|
423
414
|
}
|
|
424
415
|
if (this.featuredTagsCallbacks != null && this.featuredTagsCallbacks.dispatcher != null) {
|
|
425
|
-
if (actor?.featuredTagsId == null) logger
|
|
426
|
-
else if (actor.featuredTagsId.href != context
|
|
416
|
+
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).");
|
|
417
|
+
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).");
|
|
427
418
|
}
|
|
428
419
|
if (this.router.has("inbox")) {
|
|
429
|
-
if (actor.inboxId == null) logger
|
|
430
|
-
else if (actor.inboxId.href != context
|
|
431
|
-
if (actor.endpoints == null || actor.endpoints.sharedInbox == null) logger
|
|
432
|
-
else if (actor.endpoints.sharedInbox.href != context
|
|
420
|
+
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).");
|
|
421
|
+
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).");
|
|
422
|
+
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().");
|
|
423
|
+
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().");
|
|
433
424
|
}
|
|
434
425
|
if (callbacks.keyPairsDispatcher != null) {
|
|
435
|
-
if (actor.publicKeyId == null) logger
|
|
436
|
-
if (actor.assertionMethodId == null) logger
|
|
426
|
+
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).");
|
|
427
|
+
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).");
|
|
437
428
|
}
|
|
438
429
|
return actor;
|
|
439
430
|
} };
|
|
440
431
|
this.actorCallbacks = callbacks;
|
|
441
432
|
const setters = {
|
|
442
|
-
setKeyPairsDispatcher: (dispatcher
|
|
433
|
+
setKeyPairsDispatcher: (dispatcher) => {
|
|
443
434
|
callbacks.keyPairsDispatcher = (ctx, identifier) => this._getTracer().startActiveSpan("activitypub.dispatch_actor_key_pairs", {
|
|
444
|
-
kind:
|
|
435
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
445
436
|
attributes: {
|
|
446
437
|
"activitypub.actor.id": ctx.getActorUri(identifier).href,
|
|
447
438
|
"fedify.actor.identifier": identifier
|
|
448
439
|
}
|
|
449
440
|
}, async (span) => {
|
|
450
441
|
try {
|
|
451
|
-
return await dispatcher
|
|
442
|
+
return await dispatcher(ctx, identifier);
|
|
452
443
|
} catch (e) {
|
|
453
444
|
span.setStatus({
|
|
454
|
-
code:
|
|
445
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
455
446
|
message: String(e)
|
|
456
447
|
});
|
|
457
448
|
throw e;
|
|
@@ -478,8 +469,7 @@ var FederationBuilderImpl = class {
|
|
|
478
469
|
}
|
|
479
470
|
setNodeInfoDispatcher(path, dispatcher) {
|
|
480
471
|
if (this.router.has("nodeInfo")) throw new RouterError("NodeInfo dispatcher already set.");
|
|
481
|
-
|
|
482
|
-
if (variables.size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
|
|
472
|
+
if (this.router.add(path, "nodeInfo").size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
|
|
483
473
|
this.nodeInfoDispatcher = dispatcher;
|
|
484
474
|
}
|
|
485
475
|
setWebFingerLinksDispatcher(dispatcher) {
|
|
@@ -492,9 +482,8 @@ var FederationBuilderImpl = class {
|
|
|
492
482
|
if (variables.size < 1) throw new RouterError("Path for object dispatcher must have at least one variable.");
|
|
493
483
|
const callbacks = {
|
|
494
484
|
dispatcher: (ctx, values) => {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
kind: __opentelemetry_api.SpanKind.SERVER,
|
|
485
|
+
return this._getTracer().startActiveSpan("activitypub.dispatch_object", {
|
|
486
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
498
487
|
attributes: {
|
|
499
488
|
"fedify.object.type": cls.typeId.href,
|
|
500
489
|
...globalThis.Object.fromEntries(globalThis.Object.entries(values).map(([k, v]) => [`fedify.object.values.${k}`, v]))
|
|
@@ -503,12 +492,12 @@ var FederationBuilderImpl = class {
|
|
|
503
492
|
try {
|
|
504
493
|
const object = await dispatcher(ctx, values);
|
|
505
494
|
span.setAttribute("activitypub.object.id", (object?.id ?? ctx.getObjectUri(cls, values)).href);
|
|
506
|
-
if (object == null) span.setStatus({ code:
|
|
507
|
-
else span.setAttribute("activitypub.object.type", (0,
|
|
495
|
+
if (object == null) span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
496
|
+
else span.setAttribute("activitypub.object.type", (0, _fedify_vocab.getTypeId)(object).href);
|
|
508
497
|
return object;
|
|
509
498
|
} catch (e) {
|
|
510
499
|
span.setStatus({
|
|
511
|
-
code:
|
|
500
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
512
501
|
message: String(e)
|
|
513
502
|
});
|
|
514
503
|
throw e;
|
|
@@ -724,8 +713,7 @@ var FederationBuilderImpl = class {
|
|
|
724
713
|
this.inboxPath = inboxPath;
|
|
725
714
|
}
|
|
726
715
|
if (sharedInboxPath != null) {
|
|
727
|
-
|
|
728
|
-
if (siVars.size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
|
|
716
|
+
if (this.router.add(sharedInboxPath, "sharedInbox").size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
|
|
729
717
|
}
|
|
730
718
|
const listeners = this.inboxListeners = new InboxListenerSet();
|
|
731
719
|
const setters = {
|
|
@@ -759,8 +747,7 @@ var FederationBuilderImpl = class {
|
|
|
759
747
|
const routeName = `${collectionType}:${this.#uniqueCollectionId(name)}`;
|
|
760
748
|
if (this.router.has(routeName)) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
|
|
761
749
|
if (this.collectionCallbacks[name] != null) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
|
|
762
|
-
|
|
763
|
-
if (variables.size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
|
|
750
|
+
if (this.router.add(path, routeName).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
|
|
764
751
|
const callbacks = { dispatcher };
|
|
765
752
|
this.collectionCallbacks[name] = callbacks;
|
|
766
753
|
this.collectionTypeIds[name] = itemType;
|
|
@@ -795,8 +782,7 @@ var FederationBuilderImpl = class {
|
|
|
795
782
|
getCollectionPath(name, values) {
|
|
796
783
|
if (!(name in this.collectionCallbacks)) return null;
|
|
797
784
|
const routeName = this.#uniqueCollectionId(name);
|
|
798
|
-
|
|
799
|
-
return path;
|
|
785
|
+
return this.router.build(`collection:${routeName}`, values) ?? this.router.build(`orderedCollection:${routeName}`, values);
|
|
800
786
|
}
|
|
801
787
|
setOutboxPermanentFailureHandler(handler) {
|
|
802
788
|
this.outboxPermanentFailureHandler = handler;
|
|
@@ -822,7 +808,6 @@ var FederationBuilderImpl = class {
|
|
|
822
808
|
function createFederationBuilder() {
|
|
823
809
|
return new FederationBuilderImpl();
|
|
824
810
|
}
|
|
825
|
-
|
|
826
811
|
//#endregion
|
|
827
812
|
//#region src/federation/collection.ts
|
|
828
813
|
/**
|
|
@@ -841,8 +826,8 @@ async function digest(uris) {
|
|
|
841
826
|
if (processed.has(u)) continue;
|
|
842
827
|
processed.add(u);
|
|
843
828
|
const encoded = encoder.encode(u);
|
|
844
|
-
const digest
|
|
845
|
-
for (let i = 0; i < 32; i++) result[i] ^= digest
|
|
829
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", encoded));
|
|
830
|
+
for (let i = 0; i < 32; i++) result[i] ^= digest[i];
|
|
846
831
|
}
|
|
847
832
|
return result;
|
|
848
833
|
}
|
|
@@ -860,12 +845,15 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
|
|
|
860
845
|
const baseUrl = new URL(anyActorId);
|
|
861
846
|
const url = new URL(collectionId);
|
|
862
847
|
url.searchParams.set("base-url", `${baseUrl.origin}/`);
|
|
863
|
-
|
|
864
|
-
return `collectionId="${collectionId}", url="${url}", digest="${hash}"`;
|
|
848
|
+
return `collectionId="${collectionId}", url="${url}", digest="${(0, byte_encodings_hex.encodeHex)(await digest(actorIds))}"`;
|
|
865
849
|
}
|
|
866
|
-
|
|
867
850
|
//#endregion
|
|
868
851
|
//#region src/federation/keycache.ts
|
|
852
|
+
const NULL_KEY_CACHE_VALUE = { _fedify: "key-unavailable" };
|
|
853
|
+
const NULL_KEY_CACHE_TTL = Temporal.Duration.from({ minutes: 5 });
|
|
854
|
+
function isNullKeyCacheValue(value) {
|
|
855
|
+
return typeof value === "object" && value != null && "_fedify" in value && value._fedify === NULL_KEY_CACHE_VALUE._fedify;
|
|
856
|
+
}
|
|
869
857
|
var KvKeyCache = class {
|
|
870
858
|
kv;
|
|
871
859
|
prefix;
|
|
@@ -881,21 +869,25 @@ var KvKeyCache = class {
|
|
|
881
869
|
if (this.nullKeys.has(keyId.href)) return null;
|
|
882
870
|
const serialized = await this.kv.get([...this.prefix, keyId.href]);
|
|
883
871
|
if (serialized == null) return void 0;
|
|
872
|
+
if (isNullKeyCacheValue(serialized)) {
|
|
873
|
+
this.nullKeys.add(keyId.href);
|
|
874
|
+
return null;
|
|
875
|
+
}
|
|
884
876
|
try {
|
|
885
|
-
return await
|
|
877
|
+
return await _fedify_vocab.CryptographicKey.fromJsonLd(serialized, this.options);
|
|
886
878
|
} catch {
|
|
887
879
|
try {
|
|
888
|
-
return await
|
|
880
|
+
return await _fedify_vocab.Multikey.fromJsonLd(serialized, this.options);
|
|
889
881
|
} catch {
|
|
890
882
|
await this.kv.delete([...this.prefix, keyId.href]);
|
|
891
|
-
return
|
|
883
|
+
return;
|
|
892
884
|
}
|
|
893
885
|
}
|
|
894
886
|
}
|
|
895
887
|
async set(keyId, key) {
|
|
896
888
|
if (key == null) {
|
|
897
889
|
this.nullKeys.add(keyId.href);
|
|
898
|
-
await this.kv.
|
|
890
|
+
await this.kv.set([...this.prefix, keyId.href], NULL_KEY_CACHE_VALUE, { ttl: NULL_KEY_CACHE_TTL });
|
|
899
891
|
return;
|
|
900
892
|
}
|
|
901
893
|
this.nullKeys.delete(keyId.href);
|
|
@@ -903,7 +895,6 @@ var KvKeyCache = class {
|
|
|
903
895
|
await this.kv.set([...this.prefix, keyId.href], serialized);
|
|
904
896
|
}
|
|
905
897
|
};
|
|
906
|
-
|
|
907
898
|
//#endregion
|
|
908
899
|
//#region src/federation/negotiation.ts
|
|
909
900
|
function compareSpecs(a, b) {
|
|
@@ -948,8 +939,8 @@ function parseMediaType(str, i) {
|
|
|
948
939
|
function parseAccept(accept) {
|
|
949
940
|
const accepts = accept.split(",").map((p) => p.trim());
|
|
950
941
|
const mediaTypes = [];
|
|
951
|
-
for (const [index, accept
|
|
952
|
-
const mediaType = parseMediaType(accept
|
|
942
|
+
for (const [index, accept] of accepts.entries()) {
|
|
943
|
+
const mediaType = parseMediaType(accept.trim(), index);
|
|
953
944
|
if (mediaType) mediaTypes.push(mediaType);
|
|
954
945
|
}
|
|
955
946
|
return mediaTypes;
|
|
@@ -958,8 +949,7 @@ function getFullType(spec) {
|
|
|
958
949
|
return `${spec.type}/${spec.subtype}`;
|
|
959
950
|
}
|
|
960
951
|
function preferredMediaTypes(accept) {
|
|
961
|
-
|
|
962
|
-
return accepts.filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
952
|
+
return parseAccept(accept === void 0 ? "*/*" : accept ?? "").filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
963
953
|
}
|
|
964
954
|
function acceptsJsonLd(request) {
|
|
965
955
|
const accept = request.headers.get("Accept");
|
|
@@ -968,7 +958,6 @@ function acceptsJsonLd(request) {
|
|
|
968
958
|
if (types[0] === "text/html" || types[0] === "application/xhtml+xml") return false;
|
|
969
959
|
return types.includes("application/activity+json") || types.includes("application/ld+json") || types.includes("application/json");
|
|
970
960
|
}
|
|
971
|
-
|
|
972
961
|
//#endregion
|
|
973
962
|
//#region src/federation/handler.ts
|
|
974
963
|
/**
|
|
@@ -978,25 +967,25 @@ function acceptsJsonLd(request) {
|
|
|
978
967
|
* @param parameters The parameters for handling the actor.
|
|
979
968
|
* @returns A promise that resolves to an HTTP response.
|
|
980
969
|
*/
|
|
981
|
-
async function handleActor(request, { identifier, context
|
|
982
|
-
const logger
|
|
970
|
+
async function handleActor(request, { identifier, context, actorDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
971
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
983
972
|
"fedify",
|
|
984
973
|
"federation",
|
|
985
974
|
"actor"
|
|
986
975
|
]);
|
|
987
976
|
if (actorDispatcher == null) {
|
|
988
|
-
logger
|
|
977
|
+
logger.debug("Actor dispatcher is not set.", { identifier });
|
|
989
978
|
return await onNotFound(request);
|
|
990
979
|
}
|
|
991
|
-
const actor = await actorDispatcher(context
|
|
980
|
+
const actor = await actorDispatcher(context, identifier);
|
|
992
981
|
if (actor == null) {
|
|
993
|
-
logger
|
|
982
|
+
logger.debug("Actor {identifier} not found.", { identifier });
|
|
994
983
|
return await onNotFound(request);
|
|
995
984
|
}
|
|
996
985
|
if (authorizePredicate != null) {
|
|
997
|
-
if (!await authorizePredicate(context
|
|
986
|
+
if (!await authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
998
987
|
}
|
|
999
|
-
const jsonLd = await actor.toJsonLd(context
|
|
988
|
+
const jsonLd = await actor.toJsonLd(context);
|
|
1000
989
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1001
990
|
"Content-Type": "application/activity+json",
|
|
1002
991
|
Vary: "Accept"
|
|
@@ -1009,14 +998,14 @@ async function handleActor(request, { identifier, context: context$2, actorDispa
|
|
|
1009
998
|
* @param parameters The parameters for handling the object.
|
|
1010
999
|
* @returns A promise that resolves to an HTTP response.
|
|
1011
1000
|
*/
|
|
1012
|
-
async function handleObject(request, { values, context
|
|
1001
|
+
async function handleObject(request, { values, context, objectDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
1013
1002
|
if (objectDispatcher == null) return await onNotFound(request);
|
|
1014
|
-
const object = await objectDispatcher(context
|
|
1003
|
+
const object = await objectDispatcher(context, values);
|
|
1015
1004
|
if (object == null) return await onNotFound(request);
|
|
1016
1005
|
if (authorizePredicate != null) {
|
|
1017
|
-
if (!await authorizePredicate(context
|
|
1006
|
+
if (!await authorizePredicate(context, values)) return await onUnauthorized(request);
|
|
1018
1007
|
}
|
|
1019
|
-
const jsonLd = await object.toJsonLd(context
|
|
1008
|
+
const jsonLd = await object.toJsonLd(context);
|
|
1020
1009
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1021
1010
|
"Content-Type": "application/activity+json",
|
|
1022
1011
|
Vary: "Accept"
|
|
@@ -1032,31 +1021,30 @@ async function handleObject(request, { values, context: context$2, objectDispatc
|
|
|
1032
1021
|
* @param parameters The parameters for handling the collection.
|
|
1033
1022
|
* @returns A promise that resolves to an HTTP response.
|
|
1034
1023
|
*/
|
|
1035
|
-
async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context
|
|
1036
|
-
const spanName = name.trim().replace(/\s+/g, "_");
|
|
1037
|
-
tracerProvider = tracerProvider ??
|
|
1038
|
-
const tracer = tracerProvider.getTracer(require_http.
|
|
1039
|
-
const
|
|
1040
|
-
const cursor = url.searchParams.get("cursor");
|
|
1024
|
+
async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound }) {
|
|
1025
|
+
const spanName = name$1.trim().replace(/\s+/g, "_");
|
|
1026
|
+
tracerProvider = tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
1027
|
+
const tracer = tracerProvider.getTracer(require_http.name, require_http.version);
|
|
1028
|
+
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1041
1029
|
if (collectionCallbacks == null) return await onNotFound(request);
|
|
1042
1030
|
let collection;
|
|
1043
1031
|
const baseUri = uriGetter(identifier);
|
|
1044
1032
|
if (cursor == null) {
|
|
1045
|
-
const firstCursor = await collectionCallbacks.firstCursor?.(context
|
|
1046
|
-
const totalItems = filter == null ? await collectionCallbacks.counter?.(context
|
|
1033
|
+
const firstCursor = await collectionCallbacks.firstCursor?.(context, identifier);
|
|
1034
|
+
const totalItems = filter == null ? await collectionCallbacks.counter?.(context, identifier) : void 0;
|
|
1047
1035
|
if (firstCursor == null) {
|
|
1048
1036
|
const itemsOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection ${spanName}`, {
|
|
1049
|
-
kind:
|
|
1037
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
1050
1038
|
attributes: {
|
|
1051
1039
|
"activitypub.collection.id": baseUri.href,
|
|
1052
|
-
"activitypub.collection.type":
|
|
1040
|
+
"activitypub.collection.type": _fedify_vocab.OrderedCollection.typeId.href
|
|
1053
1041
|
}
|
|
1054
1042
|
}, async (span) => {
|
|
1055
1043
|
if (totalItems != null) span.setAttribute("activitypub.collection.total_items", Number(totalItems));
|
|
1056
1044
|
try {
|
|
1057
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1045
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
|
|
1058
1046
|
if (page == null) {
|
|
1059
|
-
span.setStatus({ code:
|
|
1047
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1060
1048
|
return await onNotFound(request);
|
|
1061
1049
|
}
|
|
1062
1050
|
const { items } = page;
|
|
@@ -1064,7 +1052,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1064
1052
|
return items;
|
|
1065
1053
|
} catch (e) {
|
|
1066
1054
|
span.setStatus({
|
|
1067
|
-
code:
|
|
1055
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1068
1056
|
message: String(e)
|
|
1069
1057
|
});
|
|
1070
1058
|
throw e;
|
|
@@ -1073,21 +1061,21 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1073
1061
|
}
|
|
1074
1062
|
});
|
|
1075
1063
|
if (itemsOrResponse instanceof Response) return itemsOrResponse;
|
|
1076
|
-
collection = new
|
|
1064
|
+
collection = new _fedify_vocab.OrderedCollection({
|
|
1077
1065
|
id: baseUri,
|
|
1078
1066
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1079
|
-
items: filterCollectionItems(itemsOrResponse, name, filterPredicate)
|
|
1067
|
+
items: filterCollectionItems(itemsOrResponse, name$1, filterPredicate)
|
|
1080
1068
|
});
|
|
1081
1069
|
} else {
|
|
1082
|
-
const lastCursor = await collectionCallbacks.lastCursor?.(context
|
|
1083
|
-
const first = new URL(context
|
|
1070
|
+
const lastCursor = await collectionCallbacks.lastCursor?.(context, identifier);
|
|
1071
|
+
const first = new URL(context.url);
|
|
1084
1072
|
first.searchParams.set("cursor", firstCursor);
|
|
1085
1073
|
let last = null;
|
|
1086
1074
|
if (lastCursor != null) {
|
|
1087
|
-
last = new URL(context
|
|
1075
|
+
last = new URL(context.url);
|
|
1088
1076
|
last.searchParams.set("cursor", lastCursor);
|
|
1089
1077
|
}
|
|
1090
|
-
collection = new
|
|
1078
|
+
collection = new _fedify_vocab.OrderedCollection({
|
|
1091
1079
|
id: baseUri,
|
|
1092
1080
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1093
1081
|
first,
|
|
@@ -1097,25 +1085,25 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1097
1085
|
} else {
|
|
1098
1086
|
const uri = new URL(baseUri);
|
|
1099
1087
|
uri.searchParams.set("cursor", cursor);
|
|
1100
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name}`, {
|
|
1101
|
-
kind:
|
|
1088
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
|
|
1089
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
1102
1090
|
attributes: {
|
|
1103
1091
|
"activitypub.collection.id": uri.href,
|
|
1104
|
-
"activitypub.collection.type":
|
|
1092
|
+
"activitypub.collection.type": _fedify_vocab.OrderedCollectionPage.typeId.href,
|
|
1105
1093
|
"fedify.collection.cursor": cursor
|
|
1106
1094
|
}
|
|
1107
1095
|
}, async (span) => {
|
|
1108
1096
|
try {
|
|
1109
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1097
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
|
|
1110
1098
|
if (page == null) {
|
|
1111
|
-
span.setStatus({ code:
|
|
1099
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1112
1100
|
return await onNotFound(request);
|
|
1113
1101
|
}
|
|
1114
1102
|
span.setAttribute("fedify.collection.items", page.items.length);
|
|
1115
1103
|
return page;
|
|
1116
1104
|
} catch (e) {
|
|
1117
1105
|
span.setStatus({
|
|
1118
|
-
code:
|
|
1106
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1119
1107
|
message: String(e)
|
|
1120
1108
|
});
|
|
1121
1109
|
throw e;
|
|
@@ -1127,28 +1115,28 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1127
1115
|
const { items, prevCursor, nextCursor } = pageOrResponse;
|
|
1128
1116
|
let prev = null;
|
|
1129
1117
|
if (prevCursor != null) {
|
|
1130
|
-
prev = new URL(context
|
|
1118
|
+
prev = new URL(context.url);
|
|
1131
1119
|
prev.searchParams.set("cursor", prevCursor);
|
|
1132
1120
|
}
|
|
1133
1121
|
let next = null;
|
|
1134
1122
|
if (nextCursor != null) {
|
|
1135
|
-
next = new URL(context
|
|
1123
|
+
next = new URL(context.url);
|
|
1136
1124
|
next.searchParams.set("cursor", nextCursor);
|
|
1137
1125
|
}
|
|
1138
|
-
const partOf = new URL(context
|
|
1126
|
+
const partOf = new URL(context.url);
|
|
1139
1127
|
partOf.searchParams.delete("cursor");
|
|
1140
|
-
collection = new
|
|
1128
|
+
collection = new _fedify_vocab.OrderedCollectionPage({
|
|
1141
1129
|
id: uri,
|
|
1142
1130
|
prev,
|
|
1143
1131
|
next,
|
|
1144
|
-
items: filterCollectionItems(items, name, filterPredicate),
|
|
1132
|
+
items: filterCollectionItems(items, name$1, filterPredicate),
|
|
1145
1133
|
partOf
|
|
1146
1134
|
});
|
|
1147
1135
|
}
|
|
1148
1136
|
if (collectionCallbacks.authorizePredicate != null) {
|
|
1149
|
-
if (!await collectionCallbacks.authorizePredicate(context
|
|
1137
|
+
if (!await collectionCallbacks.authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
1150
1138
|
}
|
|
1151
|
-
const jsonLd = await collection.toJsonLd(context
|
|
1139
|
+
const jsonLd = await collection.toJsonLd(context);
|
|
1152
1140
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1153
1141
|
"Content-Type": "application/activity+json",
|
|
1154
1142
|
Vary: "Accept"
|
|
@@ -1167,12 +1155,12 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1167
1155
|
let logged = false;
|
|
1168
1156
|
for (const item of items) {
|
|
1169
1157
|
let mappedItem;
|
|
1170
|
-
if (item instanceof
|
|
1158
|
+
if (item instanceof _fedify_vocab.Object || item instanceof _fedify_vocab.Link || item instanceof URL) mappedItem = item;
|
|
1171
1159
|
else if (item.id == null) continue;
|
|
1172
1160
|
else mappedItem = item.id;
|
|
1173
1161
|
if (filterPredicate != null && !filterPredicate(item)) {
|
|
1174
1162
|
if (!logged) {
|
|
1175
|
-
(0,
|
|
1163
|
+
(0, _logtape_logtape.getLogger)([
|
|
1176
1164
|
"fedify",
|
|
1177
1165
|
"federation",
|
|
1178
1166
|
"collection"
|
|
@@ -1193,10 +1181,8 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1193
1181
|
* @returns A promise that resolves to an HTTP response.
|
|
1194
1182
|
*/
|
|
1195
1183
|
async function handleInbox(request, options) {
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
return await tracer.startActiveSpan("activitypub.inbox", {
|
|
1199
|
-
kind: options.queue == null ? __opentelemetry_api.SpanKind.SERVER : __opentelemetry_api.SpanKind.PRODUCER,
|
|
1184
|
+
return await (options.tracerProvider ?? _opentelemetry_api.trace.getTracerProvider()).getTracer(require_http.name, require_http.version).startActiveSpan("activitypub.inbox", {
|
|
1185
|
+
kind: options.queue == null ? _opentelemetry_api.SpanKind.SERVER : _opentelemetry_api.SpanKind.PRODUCER,
|
|
1200
1186
|
attributes: { "activitypub.shared_inbox": options.recipient == null }
|
|
1201
1187
|
}, async (span) => {
|
|
1202
1188
|
if (options.recipient != null) span.setAttribute("fedify.inbox.recipient", options.recipient);
|
|
@@ -1204,7 +1190,7 @@ async function handleInbox(request, options) {
|
|
|
1204
1190
|
return await handleInboxInternal(request, options, span);
|
|
1205
1191
|
} catch (e) {
|
|
1206
1192
|
span.setStatus({
|
|
1207
|
-
code:
|
|
1193
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1208
1194
|
message: String(e)
|
|
1209
1195
|
});
|
|
1210
1196
|
throw e;
|
|
@@ -1223,33 +1209,32 @@ async function handleInbox(request, options) {
|
|
|
1223
1209
|
*/
|
|
1224
1210
|
async function handleInboxInternal(request, parameters, span) {
|
|
1225
1211
|
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider } = parameters;
|
|
1226
|
-
const logger
|
|
1212
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
1227
1213
|
"fedify",
|
|
1228
1214
|
"federation",
|
|
1229
1215
|
"inbox"
|
|
1230
1216
|
]);
|
|
1231
1217
|
if (actorDispatcher == null) {
|
|
1232
|
-
logger
|
|
1218
|
+
logger.error("Actor dispatcher is not set.", { recipient });
|
|
1233
1219
|
span.setStatus({
|
|
1234
|
-
code:
|
|
1220
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1235
1221
|
message: "Actor dispatcher is not set."
|
|
1236
1222
|
});
|
|
1237
1223
|
return await onNotFound(request);
|
|
1238
1224
|
} else if (recipient != null) {
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
logger$1.error("Actor {recipient} not found.", { recipient });
|
|
1225
|
+
if (await actorDispatcher(ctx, recipient) == null) {
|
|
1226
|
+
logger.error("Actor {recipient} not found.", { recipient });
|
|
1242
1227
|
span.setStatus({
|
|
1243
|
-
code:
|
|
1228
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1244
1229
|
message: `Actor ${recipient} not found.`
|
|
1245
1230
|
});
|
|
1246
1231
|
return await onNotFound(request);
|
|
1247
1232
|
}
|
|
1248
1233
|
}
|
|
1249
1234
|
if (request.bodyUsed) {
|
|
1250
|
-
logger
|
|
1235
|
+
logger.error("Request body has already been read.", { recipient });
|
|
1251
1236
|
span.setStatus({
|
|
1252
|
-
code:
|
|
1237
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1253
1238
|
message: "Request body has already been read."
|
|
1254
1239
|
});
|
|
1255
1240
|
return new Response("Internal server error.", {
|
|
@@ -1257,9 +1242,9 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1257
1242
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1258
1243
|
});
|
|
1259
1244
|
} else if (request.body?.locked) {
|
|
1260
|
-
logger
|
|
1245
|
+
logger.error("Request body is locked.", { recipient });
|
|
1261
1246
|
span.setStatus({
|
|
1262
|
-
code:
|
|
1247
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1263
1248
|
message: "Request body is locked."
|
|
1264
1249
|
});
|
|
1265
1250
|
return new Response("Internal server error.", {
|
|
@@ -1271,21 +1256,21 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1271
1256
|
try {
|
|
1272
1257
|
json = await request.clone().json();
|
|
1273
1258
|
} catch (error) {
|
|
1274
|
-
logger
|
|
1259
|
+
logger.error("Failed to parse JSON:\n{error}", {
|
|
1275
1260
|
recipient,
|
|
1276
1261
|
error
|
|
1277
1262
|
});
|
|
1278
1263
|
try {
|
|
1279
1264
|
await inboxErrorHandler?.(ctx, error);
|
|
1280
|
-
} catch (error
|
|
1281
|
-
logger
|
|
1282
|
-
error
|
|
1265
|
+
} catch (error) {
|
|
1266
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1267
|
+
error,
|
|
1283
1268
|
activity: json,
|
|
1284
1269
|
recipient
|
|
1285
1270
|
});
|
|
1286
1271
|
}
|
|
1287
1272
|
span.setStatus({
|
|
1288
|
-
code:
|
|
1273
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1289
1274
|
message: `Failed to parse JSON:\n${error}`
|
|
1290
1275
|
});
|
|
1291
1276
|
return new Response("Invalid JSON.", {
|
|
@@ -1304,7 +1289,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1304
1289
|
});
|
|
1305
1290
|
} catch (error) {
|
|
1306
1291
|
if (error instanceof Error && error.name === "jsonld.SyntaxError") {
|
|
1307
|
-
logger
|
|
1292
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
1308
1293
|
recipient,
|
|
1309
1294
|
error
|
|
1310
1295
|
});
|
|
@@ -1318,40 +1303,40 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1318
1303
|
const jsonWithoutSig = require_proof.detachSignature(json);
|
|
1319
1304
|
let activity = null;
|
|
1320
1305
|
if (ldSigVerified) {
|
|
1321
|
-
logger
|
|
1306
|
+
logger.debug("Linked Data Signatures are verified.", {
|
|
1322
1307
|
recipient,
|
|
1323
1308
|
json
|
|
1324
1309
|
});
|
|
1325
|
-
activity = await
|
|
1310
|
+
activity = await _fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1326
1311
|
} else {
|
|
1327
|
-
logger
|
|
1312
|
+
logger.debug("Linked Data Signatures are not verified.", {
|
|
1328
1313
|
recipient,
|
|
1329
1314
|
json
|
|
1330
1315
|
});
|
|
1331
1316
|
try {
|
|
1332
|
-
activity = await require_proof.verifyObject(
|
|
1317
|
+
activity = await require_proof.verifyObject(_fedify_vocab.Activity, jsonWithoutSig, {
|
|
1333
1318
|
contextLoader: ctx.contextLoader,
|
|
1334
1319
|
documentLoader: ctx.documentLoader,
|
|
1335
1320
|
keyCache,
|
|
1336
1321
|
tracerProvider
|
|
1337
1322
|
});
|
|
1338
1323
|
} catch (error) {
|
|
1339
|
-
logger
|
|
1324
|
+
logger.error("Failed to parse activity:\n{error}", {
|
|
1340
1325
|
recipient,
|
|
1341
1326
|
activity: json,
|
|
1342
1327
|
error
|
|
1343
1328
|
});
|
|
1344
1329
|
try {
|
|
1345
1330
|
await inboxErrorHandler?.(ctx, error);
|
|
1346
|
-
} catch (error
|
|
1347
|
-
logger
|
|
1348
|
-
error
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1333
|
+
error,
|
|
1349
1334
|
activity: json,
|
|
1350
1335
|
recipient
|
|
1351
1336
|
});
|
|
1352
1337
|
}
|
|
1353
1338
|
span.setStatus({
|
|
1354
|
-
code:
|
|
1339
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1355
1340
|
message: `Failed to parse activity:\n${error}`
|
|
1356
1341
|
});
|
|
1357
1342
|
return new Response("Invalid activity.", {
|
|
@@ -1359,11 +1344,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1359
1344
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1360
1345
|
});
|
|
1361
1346
|
}
|
|
1362
|
-
if (activity == null) logger
|
|
1347
|
+
if (activity == null) logger.debug("Object Integrity Proofs are not verified.", {
|
|
1363
1348
|
recipient,
|
|
1364
1349
|
activity: json
|
|
1365
1350
|
});
|
|
1366
|
-
else logger
|
|
1351
|
+
else logger.debug("Object Integrity Proofs are verified.", {
|
|
1367
1352
|
recipient,
|
|
1368
1353
|
activity: json
|
|
1369
1354
|
});
|
|
@@ -1379,23 +1364,22 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1379
1364
|
tracerProvider
|
|
1380
1365
|
});
|
|
1381
1366
|
if (key == null) {
|
|
1382
|
-
logger
|
|
1367
|
+
logger.error("Failed to verify the request's HTTP Signatures.", { recipient });
|
|
1383
1368
|
span.setStatus({
|
|
1384
|
-
code:
|
|
1369
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1385
1370
|
message: `Failed to verify the request's HTTP Signatures.`
|
|
1386
1371
|
});
|
|
1387
|
-
|
|
1372
|
+
return new Response("Failed to verify the request signature.", {
|
|
1388
1373
|
status: 401,
|
|
1389
1374
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1390
1375
|
});
|
|
1391
|
-
|
|
1392
|
-
} else logger$1.debug("HTTP Signatures are verified.", { recipient });
|
|
1376
|
+
} else logger.debug("HTTP Signatures are verified.", { recipient });
|
|
1393
1377
|
httpSigKey = key;
|
|
1394
1378
|
}
|
|
1395
|
-
activity = await
|
|
1379
|
+
activity = await _fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1396
1380
|
}
|
|
1397
1381
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
1398
|
-
span.setAttribute("activitypub.activity.type", (0,
|
|
1382
|
+
span.setAttribute("activitypub.activity.type", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
1399
1383
|
span.addEvent("activitypub.activity.received", {
|
|
1400
1384
|
"activitypub.activity.json": JSON.stringify(json),
|
|
1401
1385
|
"activitypub.activity.verified": activity != null,
|
|
@@ -1404,14 +1388,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1404
1388
|
"http_signatures.key_id": httpSigKey?.id?.href ?? ""
|
|
1405
1389
|
});
|
|
1406
1390
|
if (httpSigKey != null && !await require_proof.doesActorOwnKey(activity, httpSigKey, ctx)) {
|
|
1407
|
-
logger
|
|
1391
|
+
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
|
1408
1392
|
activity: json,
|
|
1409
1393
|
recipient,
|
|
1410
1394
|
keyId: httpSigKey.id?.href,
|
|
1411
1395
|
actorId: activity.actorId?.href
|
|
1412
1396
|
});
|
|
1413
1397
|
span.setStatus({
|
|
1414
|
-
code:
|
|
1398
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1415
1399
|
message: `The signer (${httpSigKey.id?.href}) and the actor (${activity.actorId?.href}) do not match.`
|
|
1416
1400
|
});
|
|
1417
1401
|
return new Response("The signer and the actor do not match.", {
|
|
@@ -1471,11 +1455,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1471
1455
|
* @since 1.8.0
|
|
1472
1456
|
*/
|
|
1473
1457
|
const handleCustomCollection = exceptWrapper(_handleCustomCollection);
|
|
1474
|
-
async function _handleCustomCollection(request, { name, values, context
|
|
1458
|
+
async function _handleCustomCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1475
1459
|
verifyDefined(callbacks);
|
|
1476
|
-
await authIfNeeded(context
|
|
1460
|
+
await authIfNeeded(context, values, callbacks);
|
|
1477
1461
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1478
|
-
return await new CustomCollectionHandler(name, values, context
|
|
1462
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, _fedify_vocab.Collection, _fedify_vocab.CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1479
1463
|
}
|
|
1480
1464
|
/**
|
|
1481
1465
|
* Handles an ordered collection request.
|
|
@@ -1489,11 +1473,11 @@ async function _handleCustomCollection(request, { name, values, context: context
|
|
|
1489
1473
|
* @since 1.8.0
|
|
1490
1474
|
*/
|
|
1491
1475
|
const handleOrderedCollection = exceptWrapper(_handleOrderedCollection);
|
|
1492
|
-
async function _handleOrderedCollection(request, { name, values, context
|
|
1476
|
+
async function _handleOrderedCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1493
1477
|
verifyDefined(callbacks);
|
|
1494
|
-
await authIfNeeded(context
|
|
1478
|
+
await authIfNeeded(context, values, callbacks);
|
|
1495
1479
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1496
|
-
return await new CustomCollectionHandler(name, values, context
|
|
1480
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, _fedify_vocab.OrderedCollection, _fedify_vocab.OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1497
1481
|
}
|
|
1498
1482
|
/**
|
|
1499
1483
|
* Handling custom collections with support for pagination and filtering.
|
|
@@ -1543,17 +1527,17 @@ var CustomCollectionHandler = class {
|
|
|
1543
1527
|
* @param CollectionPage The CollectionPage constructor.
|
|
1544
1528
|
* @param filterPredicate Optional filter predicate for items.
|
|
1545
1529
|
*/
|
|
1546
|
-
constructor(name, values, context
|
|
1547
|
-
this.name = name;
|
|
1530
|
+
constructor(name$2, values, context, callbacks, tracerProvider = _opentelemetry_api.trace.getTracerProvider(), Collection, CollectionPage, filterPredicate) {
|
|
1531
|
+
this.name = name$2;
|
|
1548
1532
|
this.values = values;
|
|
1549
|
-
this.context = context
|
|
1533
|
+
this.context = context;
|
|
1550
1534
|
this.callbacks = callbacks;
|
|
1551
1535
|
this.tracerProvider = tracerProvider;
|
|
1552
|
-
this.Collection = Collection
|
|
1553
|
-
this.CollectionPage = CollectionPage
|
|
1536
|
+
this.Collection = Collection;
|
|
1537
|
+
this.CollectionPage = CollectionPage;
|
|
1554
1538
|
this.filterPredicate = filterPredicate;
|
|
1555
1539
|
this.name = this.name.trim().replace(/\s+/g, "_");
|
|
1556
|
-
this.#tracer = this.tracerProvider.getTracer(require_http.
|
|
1540
|
+
this.#tracer = this.tracerProvider.getTracer(require_http.name, require_http.version);
|
|
1557
1541
|
this.#id = new URL(this.context.url);
|
|
1558
1542
|
this.#dispatcher = callbacks.dispatcher.bind(callbacks);
|
|
1559
1543
|
}
|
|
@@ -1582,8 +1566,8 @@ var CustomCollectionHandler = class {
|
|
|
1582
1566
|
*/
|
|
1583
1567
|
async getCollection(cursor = null) {
|
|
1584
1568
|
if (cursor !== null) {
|
|
1585
|
-
const props
|
|
1586
|
-
return new this.CollectionPage(props
|
|
1569
|
+
const props = await this.getPageProps(cursor);
|
|
1570
|
+
return new this.CollectionPage(props);
|
|
1587
1571
|
}
|
|
1588
1572
|
const firstCursor = await this.firstCursor;
|
|
1589
1573
|
const props = typeof firstCursor === "string" ? await this.getProps(firstCursor) : await this.getPropsWithoutCursor();
|
|
@@ -1644,7 +1628,7 @@ var CustomCollectionHandler = class {
|
|
|
1644
1628
|
* @returns A promise that resolves to the page items.
|
|
1645
1629
|
*/
|
|
1646
1630
|
async getPages({ cursor = null, totalItems = null }) {
|
|
1647
|
-
return await this.#tracer.startActiveSpan(`${this.ATTRS.DISPATCH_COLLECTION} ${this.name}`, this.spanOptions(
|
|
1631
|
+
return await this.#tracer.startActiveSpan(`${this.ATTRS.DISPATCH_COLLECTION} ${this.name}`, this.spanOptions(_opentelemetry_api.SpanKind.SERVER, cursor), this.spanPages({
|
|
1648
1632
|
cursor,
|
|
1649
1633
|
totalItems
|
|
1650
1634
|
}));
|
|
@@ -1677,7 +1661,7 @@ var CustomCollectionHandler = class {
|
|
|
1677
1661
|
} catch (e) {
|
|
1678
1662
|
const message = e instanceof Error ? e.message : String(e);
|
|
1679
1663
|
span.setStatus({
|
|
1680
|
-
code:
|
|
1664
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1681
1665
|
message
|
|
1682
1666
|
});
|
|
1683
1667
|
throw e;
|
|
@@ -1731,7 +1715,7 @@ var CustomCollectionHandler = class {
|
|
|
1731
1715
|
* @param value The total items count or a promise that resolves to it.
|
|
1732
1716
|
*/
|
|
1733
1717
|
set totalItems(value) {
|
|
1734
|
-
const toNumber = (value
|
|
1718
|
+
const toNumber = (value) => value == null ? null : Number(value);
|
|
1735
1719
|
this.#totalItems = value instanceof Promise ? value.then(toNumber) : Promise.resolve(toNumber(value));
|
|
1736
1720
|
}
|
|
1737
1721
|
/**
|
|
@@ -1795,9 +1779,9 @@ const verifyDefined = (callbacks) => {
|
|
|
1795
1779
|
* @throws {UnauthorizedError} If authorization fails.
|
|
1796
1780
|
* @since 1.8.0
|
|
1797
1781
|
*/
|
|
1798
|
-
const authIfNeeded = async (context
|
|
1782
|
+
const authIfNeeded = async (context, values, { authorizePredicate: authorize = void 0 }) => {
|
|
1799
1783
|
if (authorize === void 0) return;
|
|
1800
|
-
if (!await authorize(context
|
|
1784
|
+
if (!await authorize(context, values)) throw new UnauthorizedError();
|
|
1801
1785
|
};
|
|
1802
1786
|
/**
|
|
1803
1787
|
* Appends a cursor parameter to a URL if the cursor exists.
|
|
@@ -1883,7 +1867,6 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
1883
1867
|
response.headers.set("Vary", "Accept");
|
|
1884
1868
|
return response;
|
|
1885
1869
|
}
|
|
1886
|
-
|
|
1887
1870
|
//#endregion
|
|
1888
1871
|
//#region src/nodeinfo/handler.ts
|
|
1889
1872
|
/**
|
|
@@ -1893,10 +1876,9 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
1893
1876
|
* @param parameters The parameters for handling the request.
|
|
1894
1877
|
* @returns The response to the request.
|
|
1895
1878
|
*/
|
|
1896
|
-
async function handleNodeInfo(_request, { context
|
|
1897
|
-
const promise = nodeInfoDispatcher(context
|
|
1898
|
-
const
|
|
1899
|
-
const json = require_types.nodeInfoToJson(nodeInfo);
|
|
1879
|
+
async function handleNodeInfo(_request, { context, nodeInfoDispatcher }) {
|
|
1880
|
+
const promise = nodeInfoDispatcher(context);
|
|
1881
|
+
const json = require_types.nodeInfoToJson(promise instanceof Promise ? await promise : promise);
|
|
1900
1882
|
return new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\"" } });
|
|
1901
1883
|
}
|
|
1902
1884
|
/**
|
|
@@ -1906,22 +1888,20 @@ async function handleNodeInfo(_request, { context: context$2, nodeInfoDispatcher
|
|
|
1906
1888
|
* @param context The request context.
|
|
1907
1889
|
* @returns The response to the request.
|
|
1908
1890
|
*/
|
|
1909
|
-
function handleNodeInfoJrd(_request, context
|
|
1891
|
+
function handleNodeInfoJrd(_request, context) {
|
|
1910
1892
|
const links = [];
|
|
1911
1893
|
try {
|
|
1912
1894
|
links.push({
|
|
1913
1895
|
rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
|
|
1914
|
-
href: context
|
|
1896
|
+
href: context.getNodeInfoUri().href,
|
|
1915
1897
|
type: "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\""
|
|
1916
1898
|
});
|
|
1917
1899
|
} catch (e) {
|
|
1918
1900
|
if (!(e instanceof RouterError)) throw e;
|
|
1919
1901
|
}
|
|
1920
|
-
const
|
|
1921
|
-
const response = new Response(JSON.stringify(jrd), { headers: { "Content-Type": "application/jrd+json" } });
|
|
1902
|
+
const response = new Response(JSON.stringify({ links }), { headers: { "Content-Type": "application/jrd+json" } });
|
|
1922
1903
|
return Promise.resolve(response);
|
|
1923
1904
|
}
|
|
1924
|
-
|
|
1925
1905
|
//#endregion
|
|
1926
1906
|
//#region src/federation/retry.ts
|
|
1927
1907
|
/**
|
|
@@ -1952,7 +1932,6 @@ function createExponentialBackoffPolicy(options = {}) {
|
|
|
1952
1932
|
return Temporal.Duration.compare(delay, maxDelay) > 0 ? maxDelay : delay;
|
|
1953
1933
|
};
|
|
1954
1934
|
}
|
|
1955
|
-
|
|
1956
1935
|
//#endregion
|
|
1957
1936
|
//#region src/federation/send.ts
|
|
1958
1937
|
/**
|
|
@@ -1989,10 +1968,9 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
|
|
|
1989
1968
|
* @throws {Error} If the activity fails to send.
|
|
1990
1969
|
*/
|
|
1991
1970
|
function sendActivity(options) {
|
|
1992
|
-
const tracerProvider = options.tracerProvider ??
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
kind: __opentelemetry_api.SpanKind.CLIENT,
|
|
1971
|
+
const tracerProvider = options.tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
1972
|
+
return tracerProvider.getTracer(require_http.name, require_http.version).startActiveSpan("activitypub.send_activity", {
|
|
1973
|
+
kind: _opentelemetry_api.SpanKind.CLIENT,
|
|
1996
1974
|
attributes: { "activitypub.shared_inbox": options.sharedInbox ?? false }
|
|
1997
1975
|
}, async (span) => {
|
|
1998
1976
|
if (options.activityId != null) span.setAttribute("activitypub.activity.id", options.activityId);
|
|
@@ -2004,7 +1982,7 @@ function sendActivity(options) {
|
|
|
2004
1982
|
}, span);
|
|
2005
1983
|
} catch (e) {
|
|
2006
1984
|
span.setStatus({
|
|
2007
|
-
code:
|
|
1985
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2008
1986
|
message: String(e)
|
|
2009
1987
|
});
|
|
2010
1988
|
throw e;
|
|
@@ -2042,7 +2020,7 @@ async function readLimitedResponseBody(response, maxBytes) {
|
|
|
2042
2020
|
return result;
|
|
2043
2021
|
}
|
|
2044
2022
|
async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }, span) {
|
|
2045
|
-
const logger
|
|
2023
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2046
2024
|
"fedify",
|
|
2047
2025
|
"federation",
|
|
2048
2026
|
"outbox"
|
|
@@ -2059,7 +2037,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2059
2037
|
rsaKey = key;
|
|
2060
2038
|
break;
|
|
2061
2039
|
}
|
|
2062
|
-
if (rsaKey == null) logger
|
|
2040
|
+
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.", {
|
|
2063
2041
|
inbox: inbox.href,
|
|
2064
2042
|
keys: keys.map((pair) => ({
|
|
2065
2043
|
keyId: pair.keyId.href,
|
|
@@ -2073,7 +2051,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2073
2051
|
specDeterminer
|
|
2074
2052
|
});
|
|
2075
2053
|
} catch (error) {
|
|
2076
|
-
logger
|
|
2054
|
+
logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
|
|
2077
2055
|
activityId,
|
|
2078
2056
|
inbox: inbox.href,
|
|
2079
2057
|
error
|
|
@@ -2087,7 +2065,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2087
2065
|
} catch (_) {
|
|
2088
2066
|
error = "";
|
|
2089
2067
|
}
|
|
2090
|
-
logger
|
|
2068
|
+
logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
|
|
2091
2069
|
activityId,
|
|
2092
2070
|
inbox: inbox.href,
|
|
2093
2071
|
status: response.status,
|
|
@@ -2139,10 +2117,9 @@ var SendActivityError = class extends Error {
|
|
|
2139
2117
|
this.responseBody = responseBody;
|
|
2140
2118
|
}
|
|
2141
2119
|
};
|
|
2142
|
-
|
|
2143
2120
|
//#endregion
|
|
2144
2121
|
//#region src/federation/webfinger.ts
|
|
2145
|
-
const logger = (0,
|
|
2122
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2146
2123
|
"fedify",
|
|
2147
2124
|
"webfinger",
|
|
2148
2125
|
"server"
|
|
@@ -2156,14 +2133,14 @@ const logger = (0, __logtape_logtape.getLogger)([
|
|
|
2156
2133
|
*/
|
|
2157
2134
|
async function handleWebFinger(request, options) {
|
|
2158
2135
|
if (options.tracer == null) return await handleWebFingerInternal(request, options);
|
|
2159
|
-
return await options.tracer.startActiveSpan("webfinger.handle", { kind:
|
|
2136
|
+
return await options.tracer.startActiveSpan("webfinger.handle", { kind: _opentelemetry_api.SpanKind.SERVER }, async (span) => {
|
|
2160
2137
|
try {
|
|
2161
2138
|
const response = await handleWebFingerInternal(request, options);
|
|
2162
|
-
span.setStatus({ code: response.ok ?
|
|
2139
|
+
span.setStatus({ code: response.ok ? _opentelemetry_api.SpanStatusCode.UNSET : _opentelemetry_api.SpanStatusCode.ERROR });
|
|
2163
2140
|
return response;
|
|
2164
2141
|
} catch (error) {
|
|
2165
2142
|
span.setStatus({
|
|
2166
|
-
code:
|
|
2143
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2167
2144
|
message: String(error)
|
|
2168
2145
|
});
|
|
2169
2146
|
throw error;
|
|
@@ -2172,12 +2149,12 @@ async function handleWebFinger(request, options) {
|
|
|
2172
2149
|
}
|
|
2173
2150
|
});
|
|
2174
2151
|
}
|
|
2175
|
-
async function handleWebFingerInternal(request, { context
|
|
2152
|
+
async function handleWebFingerInternal(request, { context, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
|
|
2176
2153
|
if (actorDispatcher == null) {
|
|
2177
2154
|
logger.error("Actor dispatcher is not set.");
|
|
2178
2155
|
return await onNotFound(request);
|
|
2179
2156
|
}
|
|
2180
|
-
const resource = context
|
|
2157
|
+
const resource = context.url.searchParams.get("resource");
|
|
2181
2158
|
if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
|
|
2182
2159
|
span?.setAttribute("webfinger.resource", resource);
|
|
2183
2160
|
let resourceUrl;
|
|
@@ -2193,26 +2170,26 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2193
2170
|
logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
|
|
2194
2171
|
return username;
|
|
2195
2172
|
}
|
|
2196
|
-
const identifier
|
|
2197
|
-
if (identifier
|
|
2173
|
+
const identifier = await actorHandleMapper(context, username);
|
|
2174
|
+
if (identifier == null) {
|
|
2198
2175
|
logger.error("Actor {username} not found.", { username });
|
|
2199
2176
|
return null;
|
|
2200
2177
|
}
|
|
2201
|
-
return identifier
|
|
2178
|
+
return identifier;
|
|
2202
2179
|
}
|
|
2203
2180
|
let identifier = null;
|
|
2204
|
-
const uriParsed = context
|
|
2181
|
+
const uriParsed = context.parseUri(resourceUrl);
|
|
2205
2182
|
if (uriParsed?.type != "actor") {
|
|
2206
2183
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
2207
2184
|
if (match == null) {
|
|
2208
|
-
const result = await actorAliasMapper?.(context
|
|
2185
|
+
const result = await actorAliasMapper?.(context, resourceUrl);
|
|
2209
2186
|
if (result == null) return await onNotFound(request);
|
|
2210
2187
|
if ("identifier" in result) identifier = result.identifier;
|
|
2211
2188
|
else identifier = await mapUsernameToIdentifier(result.username);
|
|
2212
2189
|
} else {
|
|
2213
2190
|
const portMatch = /:\d+$/.exec(match[2]);
|
|
2214
2191
|
const normalizedHost = portMatch == null ? (0, node_url.domainToASCII)(match[2].toLowerCase()) : (0, node_url.domainToASCII)(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
2215
|
-
if (normalizedHost != context
|
|
2192
|
+
if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
|
|
2216
2193
|
else {
|
|
2217
2194
|
identifier = await mapUsernameToIdentifier(match[1]);
|
|
2218
2195
|
resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
|
|
@@ -2220,17 +2197,17 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2220
2197
|
}
|
|
2221
2198
|
} else identifier = uriParsed.identifier;
|
|
2222
2199
|
if (identifier == null) return await onNotFound(request);
|
|
2223
|
-
const actor = await actorDispatcher(context
|
|
2200
|
+
const actor = await actorDispatcher(context, identifier);
|
|
2224
2201
|
if (actor == null) {
|
|
2225
2202
|
logger.error("Actor {identifier} not found.", { identifier });
|
|
2226
2203
|
return await onNotFound(request);
|
|
2227
2204
|
}
|
|
2228
2205
|
const links = [{
|
|
2229
2206
|
rel: "self",
|
|
2230
|
-
href: context
|
|
2207
|
+
href: context.getActorUri(identifier).href,
|
|
2231
2208
|
type: "application/activity+json"
|
|
2232
2209
|
}];
|
|
2233
|
-
for (const url of actor.urls) if (url instanceof
|
|
2210
|
+
for (const url of actor.urls) if (url instanceof _fedify_vocab.Link && url.href != null) links.push({
|
|
2234
2211
|
rel: url.rel ?? "http://webfinger.net/rel/profile-page",
|
|
2235
2212
|
href: url.href.href,
|
|
2236
2213
|
type: url.mediaType == null ? void 0 : url.mediaType
|
|
@@ -2248,16 +2225,16 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2248
2225
|
});
|
|
2249
2226
|
}
|
|
2250
2227
|
if (webFingerLinksDispatcher != null) {
|
|
2251
|
-
const customLinks = await webFingerLinksDispatcher(context
|
|
2228
|
+
const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
|
|
2252
2229
|
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
2253
2230
|
}
|
|
2254
2231
|
const aliases = [];
|
|
2255
2232
|
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
|
|
2256
|
-
aliases.push(`acct:${actor.preferredUsername}@${host ?? context
|
|
2257
|
-
if (host != null && host !== context
|
|
2233
|
+
aliases.push(`acct:${actor.preferredUsername}@${host ?? context.url.host}`);
|
|
2234
|
+
if (host != null && host !== context.url.host) aliases.push(`acct:${actor.preferredUsername}@${context.url.host}`);
|
|
2258
2235
|
}
|
|
2259
|
-
if (resourceUrl.href !== context
|
|
2260
|
-
if (resourceUrl.protocol === "acct:" && host != null && host !== context
|
|
2236
|
+
if (resourceUrl.href !== context.getActorUri(identifier).href) aliases.push(context.getActorUri(identifier).href);
|
|
2237
|
+
if (resourceUrl.protocol === "acct:" && host != null && host !== context.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
2261
2238
|
const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
|
|
2262
2239
|
aliases.push(`acct:${username}@${host}`);
|
|
2263
2240
|
}
|
|
@@ -2271,7 +2248,6 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2271
2248
|
"Access-Control-Allow-Origin": "*"
|
|
2272
2249
|
} });
|
|
2273
2250
|
}
|
|
2274
|
-
|
|
2275
2251
|
//#endregion
|
|
2276
2252
|
//#region src/federation/middleware.ts
|
|
2277
2253
|
/**
|
|
@@ -2365,7 +2341,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2365
2341
|
this.allowPrivateAddress = allowPrivateAddress ?? false;
|
|
2366
2342
|
this.documentLoaderFactory = options.documentLoaderFactory ?? ((opts) => {
|
|
2367
2343
|
return require_kv_cache.kvCache({
|
|
2368
|
-
loader: (0,
|
|
2344
|
+
loader: (0, _fedify_vocab_runtime.getDocumentLoader)({
|
|
2369
2345
|
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
2370
2346
|
userAgent: opts?.userAgent ?? userAgent
|
|
2371
2347
|
}),
|
|
@@ -2392,35 +2368,35 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2392
2368
|
this.firstKnock = options.firstKnock;
|
|
2393
2369
|
}
|
|
2394
2370
|
get tracerProvider() {
|
|
2395
|
-
return this._tracerProvider ??
|
|
2371
|
+
return this._tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
2396
2372
|
}
|
|
2397
2373
|
_initializeRouter() {
|
|
2398
2374
|
this.router.add("/.well-known/webfinger", "webfinger");
|
|
2399
2375
|
this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
|
|
2400
2376
|
}
|
|
2401
2377
|
_getTracer() {
|
|
2402
|
-
return this.tracerProvider.getTracer(require_http.
|
|
2378
|
+
return this.tracerProvider.getTracer(require_http.name, require_http.version);
|
|
2403
2379
|
}
|
|
2404
2380
|
async _startQueueInternal(ctxData, signal, queue) {
|
|
2405
2381
|
if (this.inboxQueue == null && this.outboxQueue == null) return;
|
|
2406
|
-
const logger
|
|
2382
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2407
2383
|
"fedify",
|
|
2408
2384
|
"federation",
|
|
2409
2385
|
"queue"
|
|
2410
2386
|
]);
|
|
2411
2387
|
const promises = [];
|
|
2412
2388
|
if (this.inboxQueue != null && (queue == null || queue === "inbox") && !this.inboxQueueStarted) {
|
|
2413
|
-
logger
|
|
2389
|
+
logger.debug("Starting an inbox task worker.");
|
|
2414
2390
|
this.inboxQueueStarted = true;
|
|
2415
2391
|
promises.push(this.inboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2416
2392
|
}
|
|
2417
2393
|
if (this.outboxQueue != null && this.outboxQueue !== this.inboxQueue && (queue == null || queue === "outbox") && !this.outboxQueueStarted) {
|
|
2418
|
-
logger
|
|
2394
|
+
logger.debug("Starting an outbox task worker.");
|
|
2419
2395
|
this.outboxQueueStarted = true;
|
|
2420
2396
|
promises.push(this.outboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2421
2397
|
}
|
|
2422
2398
|
if (this.fanoutQueue != null && this.fanoutQueue !== this.inboxQueue && this.fanoutQueue !== this.outboxQueue && (queue == null || queue === "fanout") && !this.fanoutQueueStarted) {
|
|
2423
|
-
logger
|
|
2399
|
+
logger.debug("Starting a fanout task worker.");
|
|
2424
2400
|
this.fanoutQueueStarted = true;
|
|
2425
2401
|
promises.push(this.fanoutQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2426
2402
|
}
|
|
@@ -2428,14 +2404,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2428
2404
|
}
|
|
2429
2405
|
processQueuedTask(contextData, message) {
|
|
2430
2406
|
const tracer = this._getTracer();
|
|
2431
|
-
const extractedContext =
|
|
2432
|
-
return (0,
|
|
2407
|
+
const extractedContext = _opentelemetry_api.propagation.extract(_opentelemetry_api.context.active(), message.traceContext);
|
|
2408
|
+
return (0, _logtape_logtape.withContext)({ messageId: message.id }, async () => {
|
|
2433
2409
|
if (message.type === "fanout") await tracer.startActiveSpan("activitypub.fanout", {
|
|
2434
|
-
kind:
|
|
2410
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
2435
2411
|
attributes: { "activitypub.activity.type": message.activityType }
|
|
2436
2412
|
}, extractedContext, async (span) => {
|
|
2437
2413
|
const spanCtx = span.spanContext();
|
|
2438
|
-
return await (0,
|
|
2414
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2439
2415
|
traceId: spanCtx.traceId,
|
|
2440
2416
|
spanId: spanCtx.spanId
|
|
2441
2417
|
}, async () => {
|
|
@@ -2444,7 +2420,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2444
2420
|
await this.#listenFanoutMessage(contextData, message);
|
|
2445
2421
|
} catch (e) {
|
|
2446
2422
|
span.setStatus({
|
|
2447
|
-
code:
|
|
2423
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2448
2424
|
message: String(e)
|
|
2449
2425
|
});
|
|
2450
2426
|
throw e;
|
|
@@ -2454,14 +2430,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2454
2430
|
});
|
|
2455
2431
|
});
|
|
2456
2432
|
else if (message.type === "outbox") await tracer.startActiveSpan("activitypub.outbox", {
|
|
2457
|
-
kind:
|
|
2433
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
2458
2434
|
attributes: {
|
|
2459
2435
|
"activitypub.activity.type": message.activityType,
|
|
2460
2436
|
"activitypub.activity.retries": message.attempt
|
|
2461
2437
|
}
|
|
2462
2438
|
}, extractedContext, async (span) => {
|
|
2463
2439
|
const spanCtx = span.spanContext();
|
|
2464
|
-
return await (0,
|
|
2440
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2465
2441
|
traceId: spanCtx.traceId,
|
|
2466
2442
|
spanId: spanCtx.spanId
|
|
2467
2443
|
}, async () => {
|
|
@@ -2470,7 +2446,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2470
2446
|
await this.#listenOutboxMessage(contextData, message, span);
|
|
2471
2447
|
} catch (e) {
|
|
2472
2448
|
span.setStatus({
|
|
2473
|
-
code:
|
|
2449
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2474
2450
|
message: String(e)
|
|
2475
2451
|
});
|
|
2476
2452
|
throw e;
|
|
@@ -2480,11 +2456,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2480
2456
|
});
|
|
2481
2457
|
});
|
|
2482
2458
|
else if (message.type === "inbox") await tracer.startActiveSpan("activitypub.inbox", {
|
|
2483
|
-
kind:
|
|
2459
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
2484
2460
|
attributes: { "activitypub.shared_inbox": message.identifier == null }
|
|
2485
2461
|
}, extractedContext, async (span) => {
|
|
2486
2462
|
const spanCtx = span.spanContext();
|
|
2487
|
-
return await (0,
|
|
2463
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2488
2464
|
traceId: spanCtx.traceId,
|
|
2489
2465
|
spanId: spanCtx.spanId
|
|
2490
2466
|
}, async () => {
|
|
@@ -2492,7 +2468,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2492
2468
|
await this.#listenInboxMessage(contextData, message, span);
|
|
2493
2469
|
} catch (e) {
|
|
2494
2470
|
span.setStatus({
|
|
2495
|
-
code:
|
|
2471
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2496
2472
|
message: String(e)
|
|
2497
2473
|
});
|
|
2498
2474
|
throw e;
|
|
@@ -2504,12 +2480,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2504
2480
|
});
|
|
2505
2481
|
}
|
|
2506
2482
|
async #listenFanoutMessage(data, message) {
|
|
2507
|
-
|
|
2483
|
+
(0, _logtape_logtape.getLogger)([
|
|
2508
2484
|
"fedify",
|
|
2509
2485
|
"federation",
|
|
2510
2486
|
"fanout"
|
|
2511
|
-
])
|
|
2512
|
-
logger$1.debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2487
|
+
]).debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2513
2488
|
activityId: message.activityId,
|
|
2514
2489
|
inboxes: globalThis.Object.keys(message.inboxes).length
|
|
2515
2490
|
});
|
|
@@ -2517,7 +2492,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2517
2492
|
keyId: new URL(keyId),
|
|
2518
2493
|
privateKey: await require_http.importJwk(privateKey, "private")
|
|
2519
2494
|
})));
|
|
2520
|
-
const activity = await
|
|
2495
|
+
const activity = await _fedify_vocab.Activity.fromJsonLd(message.activity, {
|
|
2521
2496
|
contextLoader: this.contextLoaderFactory({
|
|
2522
2497
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
2523
2498
|
userAgent: this.userAgent
|
|
@@ -2528,18 +2503,18 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2528
2503
|
}),
|
|
2529
2504
|
tracerProvider: this.tracerProvider
|
|
2530
2505
|
});
|
|
2531
|
-
const context
|
|
2506
|
+
const context = this.#createContext(new URL(message.baseUrl), data, { documentLoader: this.documentLoaderFactory({
|
|
2532
2507
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
2533
2508
|
userAgent: this.userAgent
|
|
2534
2509
|
}) });
|
|
2535
2510
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
2536
2511
|
collectionSync: message.collectionSync,
|
|
2537
2512
|
orderingKey: message.orderingKey,
|
|
2538
|
-
context
|
|
2513
|
+
context
|
|
2539
2514
|
});
|
|
2540
2515
|
}
|
|
2541
2516
|
async #listenOutboxMessage(_, message, span) {
|
|
2542
|
-
const logger
|
|
2517
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2543
2518
|
"fedify",
|
|
2544
2519
|
"federation",
|
|
2545
2520
|
"outbox"
|
|
@@ -2576,25 +2551,25 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2576
2551
|
});
|
|
2577
2552
|
} catch (error) {
|
|
2578
2553
|
span.setStatus({
|
|
2579
|
-
code:
|
|
2554
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2580
2555
|
message: String(error)
|
|
2581
2556
|
});
|
|
2582
2557
|
const loaderOptions = this.#getLoaderOptions(message.baseUrl);
|
|
2583
|
-
const activity = await
|
|
2558
|
+
const activity = await _fedify_vocab.Activity.fromJsonLd(message.activity, {
|
|
2584
2559
|
contextLoader: this.contextLoaderFactory(loaderOptions),
|
|
2585
2560
|
documentLoader: rsaKeyPair == null ? this.documentLoaderFactory(loaderOptions) : this.authenticatedDocumentLoaderFactory(rsaKeyPair, loaderOptions),
|
|
2586
2561
|
tracerProvider: this.tracerProvider
|
|
2587
2562
|
});
|
|
2588
2563
|
try {
|
|
2589
2564
|
await this.onOutboxError?.(error, activity);
|
|
2590
|
-
} catch (error
|
|
2591
|
-
logger
|
|
2565
|
+
} catch (error) {
|
|
2566
|
+
logger.error("An unexpected error occurred in onError handler:\n{error}", {
|
|
2592
2567
|
...logData,
|
|
2593
|
-
error
|
|
2568
|
+
error
|
|
2594
2569
|
});
|
|
2595
2570
|
}
|
|
2596
2571
|
if (error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode)) {
|
|
2597
|
-
logger
|
|
2572
|
+
logger.warn("Permanent delivery failure for activity {activityId} to {inbox} ({status}); not retrying.", {
|
|
2598
2573
|
...logData,
|
|
2599
2574
|
status: error.statusCode
|
|
2600
2575
|
});
|
|
@@ -2610,13 +2585,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2610
2585
|
try {
|
|
2611
2586
|
return [new URL(id)];
|
|
2612
2587
|
} catch {
|
|
2613
|
-
logger
|
|
2588
|
+
logger.warn("Invalid actorId URL in OutboxMessage: {id}", { id });
|
|
2614
2589
|
return [];
|
|
2615
2590
|
}
|
|
2616
2591
|
})
|
|
2617
2592
|
});
|
|
2618
2593
|
} catch (handlerError) {
|
|
2619
|
-
logger
|
|
2594
|
+
logger.error("An unexpected error occurred in outboxPermanentFailureHandler:\n{error}", {
|
|
2620
2595
|
...logData,
|
|
2621
2596
|
error: handlerError
|
|
2622
2597
|
});
|
|
@@ -2625,7 +2600,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2625
2600
|
return;
|
|
2626
2601
|
}
|
|
2627
2602
|
if (this.outboxQueue?.nativeRetrial) {
|
|
2628
|
-
logger
|
|
2603
|
+
logger.error("Failed to send activity {activityId} to {inbox}; backend will handle retry:\n{error}", {
|
|
2629
2604
|
...logData,
|
|
2630
2605
|
error
|
|
2631
2606
|
});
|
|
@@ -2636,7 +2611,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2636
2611
|
attempts: message.attempt
|
|
2637
2612
|
});
|
|
2638
2613
|
if (delay != null) {
|
|
2639
|
-
logger
|
|
2614
|
+
logger.error("Failed to send activity {activityId} to {inbox} (attempt #{attempt}); retry...:\n{error}", {
|
|
2640
2615
|
...logData,
|
|
2641
2616
|
error
|
|
2642
2617
|
});
|
|
@@ -2644,39 +2619,38 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2644
2619
|
...message,
|
|
2645
2620
|
attempt: message.attempt + 1
|
|
2646
2621
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2647
|
-
} else logger
|
|
2622
|
+
} else logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
2648
2623
|
...logData,
|
|
2649
2624
|
error
|
|
2650
2625
|
});
|
|
2651
2626
|
return;
|
|
2652
2627
|
}
|
|
2653
|
-
logger
|
|
2628
|
+
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
2654
2629
|
}
|
|
2655
2630
|
async #listenInboxMessage(ctxData, message, span) {
|
|
2656
|
-
const logger
|
|
2631
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2657
2632
|
"fedify",
|
|
2658
2633
|
"federation",
|
|
2659
2634
|
"inbox"
|
|
2660
2635
|
]);
|
|
2661
2636
|
const baseUrl = new URL(message.baseUrl);
|
|
2662
|
-
let context
|
|
2663
|
-
if (message.identifier != null) context
|
|
2637
|
+
let context = this.#createContext(baseUrl, ctxData);
|
|
2638
|
+
if (message.identifier != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: await context.getDocumentLoader({ identifier: message.identifier }) });
|
|
2664
2639
|
else if (this.sharedInboxKeyDispatcher != null) {
|
|
2665
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
2666
|
-
if (identity != null) context
|
|
2640
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
2641
|
+
if (identity != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
2667
2642
|
}
|
|
2668
|
-
const activity = await
|
|
2669
|
-
span.setAttribute("activitypub.activity.type", (0,
|
|
2643
|
+
const activity = await _fedify_vocab.Activity.fromJsonLd(message.activity, context);
|
|
2644
|
+
span.setAttribute("activitypub.activity.type", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
2670
2645
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2671
2646
|
const cacheKey = activity.id == null ? null : [
|
|
2672
2647
|
...this.kvPrefixes.activityIdempotence,
|
|
2673
|
-
context
|
|
2648
|
+
context.origin,
|
|
2674
2649
|
activity.id.href
|
|
2675
2650
|
];
|
|
2676
2651
|
if (cacheKey != null) {
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
logger$1.debug("Activity {activityId} has already been processed.", {
|
|
2652
|
+
if (await this.kv.get(cacheKey) === true) {
|
|
2653
|
+
logger.debug("Activity {activityId} has already been processed.", {
|
|
2680
2654
|
activityId: activity.id?.href,
|
|
2681
2655
|
activity: message.activity,
|
|
2682
2656
|
recipient: message.identifier
|
|
@@ -2684,32 +2658,32 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2684
2658
|
return;
|
|
2685
2659
|
}
|
|
2686
2660
|
}
|
|
2687
|
-
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind:
|
|
2661
|
+
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: _opentelemetry_api.SpanKind.INTERNAL }, async (span) => {
|
|
2688
2662
|
const dispatched = this.inboxListeners?.dispatchWithClass(activity);
|
|
2689
2663
|
if (dispatched == null) {
|
|
2690
|
-
logger
|
|
2664
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
2691
2665
|
activityId: activity.id?.href,
|
|
2692
2666
|
activity: message.activity,
|
|
2693
2667
|
recipient: message.identifier,
|
|
2694
2668
|
trial: message.attempt
|
|
2695
2669
|
});
|
|
2696
|
-
span
|
|
2697
|
-
code:
|
|
2698
|
-
message: `Unsupported activity type: ${(0,
|
|
2670
|
+
span.setStatus({
|
|
2671
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2672
|
+
message: `Unsupported activity type: ${(0, _fedify_vocab.getTypeId)(activity).href}`
|
|
2699
2673
|
});
|
|
2700
|
-
span
|
|
2674
|
+
span.end();
|
|
2701
2675
|
return;
|
|
2702
2676
|
}
|
|
2703
2677
|
const { class: cls, listener } = dispatched;
|
|
2704
|
-
span
|
|
2678
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
2705
2679
|
try {
|
|
2706
|
-
await listener(context
|
|
2680
|
+
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, (0, _fedify_vocab.getTypeId)(activity).href), activity);
|
|
2707
2681
|
} catch (error) {
|
|
2708
2682
|
try {
|
|
2709
|
-
await this.inboxErrorHandler?.(context
|
|
2710
|
-
} catch (error
|
|
2711
|
-
logger
|
|
2712
|
-
error
|
|
2683
|
+
await this.inboxErrorHandler?.(context, error);
|
|
2684
|
+
} catch (error) {
|
|
2685
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
2686
|
+
error,
|
|
2713
2687
|
trial: message.attempt,
|
|
2714
2688
|
activityId: activity.id?.href,
|
|
2715
2689
|
activity: message.activity,
|
|
@@ -2717,17 +2691,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2717
2691
|
});
|
|
2718
2692
|
}
|
|
2719
2693
|
if (this.inboxQueue?.nativeRetrial) {
|
|
2720
|
-
logger
|
|
2694
|
+
logger.error("Failed to process the incoming activity {activityId}; backend will handle retry:\n{error}", {
|
|
2721
2695
|
error,
|
|
2722
2696
|
activityId: activity.id?.href,
|
|
2723
2697
|
activity: message.activity,
|
|
2724
2698
|
recipient: message.identifier
|
|
2725
2699
|
});
|
|
2726
|
-
span
|
|
2727
|
-
code:
|
|
2700
|
+
span.setStatus({
|
|
2701
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2728
2702
|
message: String(error)
|
|
2729
2703
|
});
|
|
2730
|
-
span
|
|
2704
|
+
span.end();
|
|
2731
2705
|
throw error;
|
|
2732
2706
|
}
|
|
2733
2707
|
const delay = this.inboxRetryPolicy({
|
|
@@ -2735,7 +2709,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2735
2709
|
attempts: message.attempt
|
|
2736
2710
|
});
|
|
2737
2711
|
if (delay != null) {
|
|
2738
|
-
logger
|
|
2712
|
+
logger.error("Failed to process the incoming activity {activityId} (attempt #{attempt}); retry...:\n{error}", {
|
|
2739
2713
|
error,
|
|
2740
2714
|
attempt: message.attempt,
|
|
2741
2715
|
activityId: activity.id?.href,
|
|
@@ -2746,26 +2720,26 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2746
2720
|
...message,
|
|
2747
2721
|
attempt: message.attempt + 1
|
|
2748
2722
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2749
|
-
} else logger
|
|
2723
|
+
} else logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
2750
2724
|
error,
|
|
2751
2725
|
activityId: activity.id?.href,
|
|
2752
2726
|
activity: message.activity,
|
|
2753
2727
|
recipient: message.identifier
|
|
2754
2728
|
});
|
|
2755
|
-
span
|
|
2756
|
-
code:
|
|
2729
|
+
span.setStatus({
|
|
2730
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2757
2731
|
message: String(error)
|
|
2758
2732
|
});
|
|
2759
|
-
span
|
|
2733
|
+
span.end();
|
|
2760
2734
|
return;
|
|
2761
2735
|
}
|
|
2762
2736
|
if (cacheKey != null) await this.kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
2763
|
-
logger
|
|
2737
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
2764
2738
|
activityId: activity.id?.href,
|
|
2765
2739
|
activity: message.activity,
|
|
2766
2740
|
recipient: message.identifier
|
|
2767
2741
|
});
|
|
2768
|
-
span
|
|
2742
|
+
span.end();
|
|
2769
2743
|
});
|
|
2770
2744
|
}
|
|
2771
2745
|
startQueue(contextData, options = {}) {
|
|
@@ -2809,7 +2783,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2809
2783
|
};
|
|
2810
2784
|
}
|
|
2811
2785
|
async sendActivity(keys, inboxes, activity, options) {
|
|
2812
|
-
const logger
|
|
2786
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2813
2787
|
"fedify",
|
|
2814
2788
|
"federation",
|
|
2815
2789
|
"outbox"
|
|
@@ -2843,7 +2817,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2843
2817
|
format: "compact",
|
|
2844
2818
|
contextLoader
|
|
2845
2819
|
});
|
|
2846
|
-
if (rsaKey == null) logger
|
|
2820
|
+
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.", {
|
|
2847
2821
|
activityId,
|
|
2848
2822
|
keys: keys.map((pair) => ({
|
|
2849
2823
|
keyId: pair.keyId.href,
|
|
@@ -2854,7 +2828,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2854
2828
|
contextLoader,
|
|
2855
2829
|
tracerProvider: this.tracerProvider
|
|
2856
2830
|
});
|
|
2857
|
-
if (!proofCreated) logger
|
|
2831
|
+
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.", {
|
|
2858
2832
|
activityId,
|
|
2859
2833
|
keys: keys.map((pair) => ({
|
|
2860
2834
|
keyId: pair.keyId.href,
|
|
@@ -2862,11 +2836,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2862
2836
|
}))
|
|
2863
2837
|
});
|
|
2864
2838
|
if (immediate || this.outboxQueue == null) {
|
|
2865
|
-
if (immediate) logger
|
|
2839
|
+
if (immediate) logger.debug("Sending activity immediately without queue since immediate option is set.", {
|
|
2866
2840
|
activityId: activity.id.href,
|
|
2867
2841
|
activity: jsonLd
|
|
2868
2842
|
});
|
|
2869
|
-
else logger
|
|
2843
|
+
else logger.debug("Sending activity immediately without queue since queue is not set.", {
|
|
2870
2844
|
activityId: activity.id.href,
|
|
2871
2845
|
activity: jsonLd
|
|
2872
2846
|
});
|
|
@@ -2875,7 +2849,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2875
2849
|
keys,
|
|
2876
2850
|
activity: jsonLd,
|
|
2877
2851
|
activityId: activity.id?.href,
|
|
2878
|
-
activityType: (0,
|
|
2852
|
+
activityType: (0, _fedify_vocab.getTypeId)(activity).href,
|
|
2879
2853
|
inbox: new URL(inbox),
|
|
2880
2854
|
sharedInbox: inboxes[inbox].sharedInbox,
|
|
2881
2855
|
headers: collectionSync == null ? void 0 : new Headers({ "Collection-Synchronization": await buildCollectionSynchronizationHeader(collectionSync, inboxes[inbox].actorIds) }),
|
|
@@ -2885,7 +2859,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2885
2859
|
await Promise.all(promises);
|
|
2886
2860
|
return;
|
|
2887
2861
|
}
|
|
2888
|
-
logger
|
|
2862
|
+
logger.debug("Enqueuing activity {activityId} to send later.", {
|
|
2889
2863
|
activityId: activity.id.href,
|
|
2890
2864
|
activity: jsonLd
|
|
2891
2865
|
});
|
|
@@ -2899,7 +2873,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2899
2873
|
}
|
|
2900
2874
|
if (!this.manuallyStartQueue) this._startQueueInternal(ctx.data);
|
|
2901
2875
|
const carrier = {};
|
|
2902
|
-
|
|
2876
|
+
_opentelemetry_api.propagation.inject(_opentelemetry_api.context.active(), carrier);
|
|
2903
2877
|
const messages = [];
|
|
2904
2878
|
for (const inbox in inboxes) {
|
|
2905
2879
|
const inboxOrigin = new URL(inbox).origin;
|
|
@@ -2911,7 +2885,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2911
2885
|
keys: keyJwkPairs,
|
|
2912
2886
|
activity: jsonLd,
|
|
2913
2887
|
activityId: activity.id?.href,
|
|
2914
|
-
activityType: (0,
|
|
2888
|
+
activityType: (0, _fedify_vocab.getTypeId)(activity).href,
|
|
2915
2889
|
inbox,
|
|
2916
2890
|
sharedInbox: inboxes[inbox].sharedInbox,
|
|
2917
2891
|
actorIds: [...inboxes[inbox].actorIds],
|
|
@@ -2929,10 +2903,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2929
2903
|
const { outboxQueue } = this;
|
|
2930
2904
|
if (outboxQueue.enqueueMany == null) {
|
|
2931
2905
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
2932
|
-
const
|
|
2933
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2906
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2934
2907
|
if (errors.length > 0) {
|
|
2935
|
-
logger
|
|
2908
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
2936
2909
|
activityId: activity.id.href,
|
|
2937
2910
|
errors
|
|
2938
2911
|
});
|
|
@@ -2941,10 +2914,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2941
2914
|
}
|
|
2942
2915
|
} else if (orderingKey != null) {
|
|
2943
2916
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
2944
|
-
const
|
|
2945
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2917
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2946
2918
|
if (errors.length > 0) {
|
|
2947
|
-
logger
|
|
2919
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
2948
2920
|
activityId: activity.id.href,
|
|
2949
2921
|
errors
|
|
2950
2922
|
});
|
|
@@ -2954,7 +2926,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2954
2926
|
} else try {
|
|
2955
2927
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
2956
2928
|
} catch (error) {
|
|
2957
|
-
logger
|
|
2929
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
2958
2930
|
activityId: activity.id.href,
|
|
2959
2931
|
error
|
|
2960
2932
|
});
|
|
@@ -2962,27 +2934,26 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2962
2934
|
}
|
|
2963
2935
|
}
|
|
2964
2936
|
fetch(request, options) {
|
|
2965
|
-
|
|
2966
|
-
return (0, __logtape_logtape.withContext)({ requestId }, async () => {
|
|
2937
|
+
return (0, _logtape_logtape.withContext)({ requestId: getRequestId(request) }, async () => {
|
|
2967
2938
|
const tracer = this._getTracer();
|
|
2968
2939
|
return await tracer.startActiveSpan(request.method, {
|
|
2969
|
-
kind:
|
|
2940
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
2970
2941
|
attributes: {
|
|
2971
|
-
[
|
|
2972
|
-
[
|
|
2942
|
+
[_opentelemetry_semantic_conventions.ATTR_HTTP_REQUEST_METHOD]: request.method,
|
|
2943
|
+
[_opentelemetry_semantic_conventions.ATTR_URL_FULL]: request.url
|
|
2973
2944
|
}
|
|
2974
2945
|
}, async (span) => {
|
|
2975
2946
|
const spanCtx = span.spanContext();
|
|
2976
|
-
return await (0,
|
|
2947
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2977
2948
|
traceId: spanCtx.traceId,
|
|
2978
2949
|
spanId: spanCtx.spanId
|
|
2979
2950
|
}, async () => {
|
|
2980
|
-
const logger
|
|
2951
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2981
2952
|
"fedify",
|
|
2982
2953
|
"federation",
|
|
2983
2954
|
"http"
|
|
2984
2955
|
]);
|
|
2985
|
-
if (span.isRecording()) for (const [k, v] of request.headers) span.setAttribute((0,
|
|
2956
|
+
if (span.isRecording()) for (const [k, v] of request.headers) span.setAttribute((0, _opentelemetry_semantic_conventions.ATTR_HTTP_REQUEST_HEADER)(k), [v]);
|
|
2986
2957
|
let response;
|
|
2987
2958
|
try {
|
|
2988
2959
|
response = await this.#fetch(request, {
|
|
@@ -2993,11 +2964,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2993
2964
|
if (acceptsJsonLd(request)) response.headers.set("Vary", "Accept");
|
|
2994
2965
|
} catch (error) {
|
|
2995
2966
|
span.setStatus({
|
|
2996
|
-
code:
|
|
2967
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2997
2968
|
message: `${error}`
|
|
2998
2969
|
});
|
|
2999
2970
|
span.end();
|
|
3000
|
-
logger
|
|
2971
|
+
logger.error("An error occurred while serving request {method} {url}: {error}", {
|
|
3001
2972
|
method: request.method,
|
|
3002
2973
|
url: request.url,
|
|
3003
2974
|
error
|
|
@@ -3005,10 +2976,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3005
2976
|
throw error;
|
|
3006
2977
|
}
|
|
3007
2978
|
if (span.isRecording()) {
|
|
3008
|
-
span.setAttribute(
|
|
3009
|
-
for (const [k, v] of response.headers) span.setAttribute((0,
|
|
2979
|
+
span.setAttribute(_opentelemetry_semantic_conventions.ATTR_HTTP_RESPONSE_STATUS_CODE, response.status);
|
|
2980
|
+
for (const [k, v] of response.headers) span.setAttribute((0, _opentelemetry_semantic_conventions.ATTR_HTTP_RESPONSE_HEADER)(k), [v]);
|
|
3010
2981
|
span.setStatus({
|
|
3011
|
-
code: response.status >= 500 ?
|
|
2982
|
+
code: response.status >= 500 ? _opentelemetry_api.SpanStatusCode.ERROR : _opentelemetry_api.SpanStatusCode.UNSET,
|
|
3012
2983
|
message: response.statusText
|
|
3013
2984
|
});
|
|
3014
2985
|
}
|
|
@@ -3021,9 +2992,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3021
2992
|
url: request.url,
|
|
3022
2993
|
status: response.status
|
|
3023
2994
|
};
|
|
3024
|
-
if (response.status >= 500) logger
|
|
3025
|
-
else if (response.status >= 400) logger
|
|
3026
|
-
else logger
|
|
2995
|
+
if (response.status >= 500) logger.error(logTpl, values);
|
|
2996
|
+
else if (response.status >= 400) logger.warn(logTpl, values);
|
|
2997
|
+
else logger.info(logTpl, values);
|
|
3027
2998
|
return response;
|
|
3028
2999
|
});
|
|
3029
3000
|
});
|
|
@@ -3037,11 +3008,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3037
3008
|
const route = this.router.route(url.pathname);
|
|
3038
3009
|
if (route == null) return await onNotFound(request);
|
|
3039
3010
|
span.updateName(`${request.method} ${route.template}`);
|
|
3040
|
-
let context
|
|
3011
|
+
let context = this.#createContext(request, contextData);
|
|
3041
3012
|
const routeName = route.name.replace(/:.*$/, "");
|
|
3042
3013
|
switch (routeName) {
|
|
3043
3014
|
case "webfinger": return await handleWebFinger(request, {
|
|
3044
|
-
context
|
|
3015
|
+
context,
|
|
3045
3016
|
host: this.origin?.handleHost,
|
|
3046
3017
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3047
3018
|
actorHandleMapper: this.actorCallbacks?.handleMapper,
|
|
@@ -3050,19 +3021,19 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3050
3021
|
onNotFound,
|
|
3051
3022
|
tracer
|
|
3052
3023
|
});
|
|
3053
|
-
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context
|
|
3024
|
+
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context);
|
|
3054
3025
|
case "nodeInfo": return await handleNodeInfo(request, {
|
|
3055
|
-
context
|
|
3026
|
+
context,
|
|
3056
3027
|
nodeInfoDispatcher: this.nodeInfoDispatcher
|
|
3057
3028
|
});
|
|
3058
3029
|
}
|
|
3059
3030
|
if (request.method !== "POST" && !acceptsJsonLd(request)) return await onNotAcceptable(request);
|
|
3060
3031
|
switch (routeName) {
|
|
3061
3032
|
case "actor":
|
|
3062
|
-
context
|
|
3033
|
+
context = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier: route.values.identifier } });
|
|
3063
3034
|
return await handleActor(request, {
|
|
3064
3035
|
identifier: route.values.identifier,
|
|
3065
|
-
context
|
|
3036
|
+
context,
|
|
3066
3037
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3067
3038
|
authorizePredicate: this.actorCallbacks?.authorizePredicate,
|
|
3068
3039
|
onUnauthorized,
|
|
@@ -3072,13 +3043,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3072
3043
|
const typeId = route.name.replace(/^object:/, "");
|
|
3073
3044
|
const callbacks = this.objectCallbacks[typeId];
|
|
3074
3045
|
const cls = this.objectTypeIds[typeId];
|
|
3075
|
-
context
|
|
3046
|
+
context = this.#createContext(request, contextData, { invokedFromObjectDispatcher: {
|
|
3076
3047
|
cls,
|
|
3077
3048
|
values: route.values
|
|
3078
3049
|
} });
|
|
3079
3050
|
return await handleObject(request, {
|
|
3080
3051
|
values: route.values,
|
|
3081
|
-
context
|
|
3052
|
+
context,
|
|
3082
3053
|
objectDispatcher: callbacks?.dispatcher,
|
|
3083
3054
|
authorizePredicate: callbacks?.authorizePredicate,
|
|
3084
3055
|
onUnauthorized,
|
|
@@ -3088,8 +3059,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3088
3059
|
case "outbox": return await handleCollection(request, {
|
|
3089
3060
|
name: "outbox",
|
|
3090
3061
|
identifier: route.values.identifier,
|
|
3091
|
-
uriGetter: context
|
|
3092
|
-
context
|
|
3062
|
+
uriGetter: context.getOutboxUri.bind(context),
|
|
3063
|
+
context,
|
|
3093
3064
|
collectionCallbacks: this.outboxCallbacks,
|
|
3094
3065
|
tracerProvider: this.tracerProvider,
|
|
3095
3066
|
onUnauthorized,
|
|
@@ -3099,24 +3070,24 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3099
3070
|
if (request.method !== "POST") return await handleCollection(request, {
|
|
3100
3071
|
name: "inbox",
|
|
3101
3072
|
identifier: route.values.identifier,
|
|
3102
|
-
uriGetter: context
|
|
3103
|
-
context
|
|
3073
|
+
uriGetter: context.getInboxUri.bind(context),
|
|
3074
|
+
context,
|
|
3104
3075
|
collectionCallbacks: this.inboxCallbacks,
|
|
3105
3076
|
tracerProvider: this.tracerProvider,
|
|
3106
3077
|
onUnauthorized,
|
|
3107
3078
|
onNotFound
|
|
3108
3079
|
});
|
|
3109
|
-
context
|
|
3080
|
+
context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier: route.values.identifier }) });
|
|
3110
3081
|
case "sharedInbox":
|
|
3111
3082
|
if (routeName !== "inbox" && this.sharedInboxKeyDispatcher != null) {
|
|
3112
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
3113
|
-
if (identity != null) context
|
|
3083
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
3084
|
+
if (identity != null) context = this.#createContext(request, contextData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
3114
3085
|
}
|
|
3115
3086
|
if (!this.manuallyStartQueue) this._startQueueInternal(contextData);
|
|
3116
3087
|
return await handleInbox(request, {
|
|
3117
3088
|
recipient: route.values.identifier ?? null,
|
|
3118
|
-
context
|
|
3119
|
-
inboxContextFactory: context
|
|
3089
|
+
context,
|
|
3090
|
+
inboxContextFactory: context.toInboxContext.bind(context),
|
|
3120
3091
|
kv: this.kv,
|
|
3121
3092
|
kvPrefixes: this.kvPrefixes,
|
|
3122
3093
|
queue: this.inboxQueue,
|
|
@@ -3132,8 +3103,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3132
3103
|
case "following": return await handleCollection(request, {
|
|
3133
3104
|
name: "following",
|
|
3134
3105
|
identifier: route.values.identifier,
|
|
3135
|
-
uriGetter: context
|
|
3136
|
-
context
|
|
3106
|
+
uriGetter: context.getFollowingUri.bind(context),
|
|
3107
|
+
context,
|
|
3137
3108
|
collectionCallbacks: this.followingCallbacks,
|
|
3138
3109
|
tracerProvider: this.tracerProvider,
|
|
3139
3110
|
onUnauthorized,
|
|
@@ -3149,14 +3120,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3149
3120
|
return await handleCollection(request, {
|
|
3150
3121
|
name: "followers",
|
|
3151
3122
|
identifier: route.values.identifier,
|
|
3152
|
-
uriGetter: baseUrl == null ? context
|
|
3153
|
-
const uri = context
|
|
3123
|
+
uriGetter: baseUrl == null ? context.getFollowersUri.bind(context) : (identifier) => {
|
|
3124
|
+
const uri = context.getFollowersUri(identifier);
|
|
3154
3125
|
uri.searchParams.set("base-url", baseUrl);
|
|
3155
3126
|
return uri;
|
|
3156
3127
|
},
|
|
3157
|
-
context
|
|
3128
|
+
context,
|
|
3158
3129
|
filter: baseUrl != null ? new URL(baseUrl) : void 0,
|
|
3159
|
-
filterPredicate: baseUrl != null ? (i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl) : void 0,
|
|
3130
|
+
filterPredicate: baseUrl != null ? ((i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl)) : void 0,
|
|
3160
3131
|
collectionCallbacks: this.followersCallbacks,
|
|
3161
3132
|
tracerProvider: this.tracerProvider,
|
|
3162
3133
|
onUnauthorized,
|
|
@@ -3166,8 +3137,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3166
3137
|
case "liked": return await handleCollection(request, {
|
|
3167
3138
|
name: "liked",
|
|
3168
3139
|
identifier: route.values.identifier,
|
|
3169
|
-
uriGetter: context
|
|
3170
|
-
context
|
|
3140
|
+
uriGetter: context.getLikedUri.bind(context),
|
|
3141
|
+
context,
|
|
3171
3142
|
collectionCallbacks: this.likedCallbacks,
|
|
3172
3143
|
tracerProvider: this.tracerProvider,
|
|
3173
3144
|
onUnauthorized,
|
|
@@ -3176,8 +3147,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3176
3147
|
case "featured": return await handleCollection(request, {
|
|
3177
3148
|
name: "featured",
|
|
3178
3149
|
identifier: route.values.identifier,
|
|
3179
|
-
uriGetter: context
|
|
3180
|
-
context
|
|
3150
|
+
uriGetter: context.getFeaturedUri.bind(context),
|
|
3151
|
+
context,
|
|
3181
3152
|
collectionCallbacks: this.featuredCallbacks,
|
|
3182
3153
|
tracerProvider: this.tracerProvider,
|
|
3183
3154
|
onUnauthorized,
|
|
@@ -3186,8 +3157,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3186
3157
|
case "featuredTags": return await handleCollection(request, {
|
|
3187
3158
|
name: "featured tags",
|
|
3188
3159
|
identifier: route.values.identifier,
|
|
3189
|
-
uriGetter: context
|
|
3190
|
-
context
|
|
3160
|
+
uriGetter: context.getFeaturedTagsUri.bind(context),
|
|
3161
|
+
context,
|
|
3191
3162
|
collectionCallbacks: this.featuredTagsCallbacks,
|
|
3192
3163
|
tracerProvider: this.tracerProvider,
|
|
3193
3164
|
onUnauthorized,
|
|
@@ -3198,7 +3169,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3198
3169
|
const callbacks = this.collectionCallbacks[name];
|
|
3199
3170
|
return await handleCustomCollection(request, {
|
|
3200
3171
|
name,
|
|
3201
|
-
context
|
|
3172
|
+
context,
|
|
3202
3173
|
values: route.values,
|
|
3203
3174
|
collectionCallbacks: callbacks,
|
|
3204
3175
|
tracerProvider: this.tracerProvider,
|
|
@@ -3211,7 +3182,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3211
3182
|
const callbacks = this.collectionCallbacks[name];
|
|
3212
3183
|
return await handleOrderedCollection(request, {
|
|
3213
3184
|
name,
|
|
3214
|
-
context
|
|
3185
|
+
context,
|
|
3215
3186
|
values: route.values,
|
|
3216
3187
|
collectionCallbacks: callbacks,
|
|
3217
3188
|
tracerProvider: this.tracerProvider,
|
|
@@ -3302,9 +3273,9 @@ var ContextImpl = class ContextImpl {
|
|
|
3302
3273
|
}
|
|
3303
3274
|
getInboxUri(identifier) {
|
|
3304
3275
|
if (identifier == null) {
|
|
3305
|
-
const path
|
|
3306
|
-
if (path
|
|
3307
|
-
return new URL(path
|
|
3276
|
+
const path = this.federation.router.build("sharedInbox", {});
|
|
3277
|
+
if (path == null) throw new RouterError("No shared inbox path registered.");
|
|
3278
|
+
return new URL(path, this.canonicalOrigin);
|
|
3308
3279
|
}
|
|
3309
3280
|
const path = this.federation.router.build("inbox", { identifier });
|
|
3310
3281
|
if (path == null) throw new RouterError("No inbox path registered.");
|
|
@@ -3390,8 +3361,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3390
3361
|
type: "featuredTags",
|
|
3391
3362
|
identifier
|
|
3392
3363
|
};
|
|
3393
|
-
const
|
|
3394
|
-
const collectionRegex = /* @__PURE__ */ new RegExp(`^(${collectionTypes.join("|")}):(.*)$`);
|
|
3364
|
+
const collectionRegex = new RegExp(`^(${["collection", "orderedCollection"].join("|")}):(.*)$`);
|
|
3395
3365
|
const match = route.name.match(collectionRegex);
|
|
3396
3366
|
if (match !== null) {
|
|
3397
3367
|
const [, type, name] = match;
|
|
@@ -3407,12 +3377,12 @@ var ContextImpl = class ContextImpl {
|
|
|
3407
3377
|
return null;
|
|
3408
3378
|
}
|
|
3409
3379
|
async getActorKeyPairs(identifier) {
|
|
3410
|
-
const logger
|
|
3380
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3411
3381
|
"fedify",
|
|
3412
3382
|
"federation",
|
|
3413
3383
|
"actor"
|
|
3414
3384
|
]);
|
|
3415
|
-
if (this.invokedFromActorKeyPairsDispatcher != null) logger
|
|
3385
|
+
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.", {
|
|
3416
3386
|
getActorKeyPairsIdentifier: identifier,
|
|
3417
3387
|
actorKeyPairsDispatcherIdentifier: this.invokedFromActorKeyPairsDispatcher.identifier
|
|
3418
3388
|
});
|
|
@@ -3420,7 +3390,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3420
3390
|
try {
|
|
3421
3391
|
keyPairs = await this.getKeyPairsFromIdentifier(identifier);
|
|
3422
3392
|
} catch (_) {
|
|
3423
|
-
logger
|
|
3393
|
+
logger.warn("No actor key pairs dispatcher registered.");
|
|
3424
3394
|
return [];
|
|
3425
3395
|
}
|
|
3426
3396
|
const owner = this.getActorUri(identifier);
|
|
@@ -3428,12 +3398,12 @@ var ContextImpl = class ContextImpl {
|
|
|
3428
3398
|
for (const keyPair of keyPairs) {
|
|
3429
3399
|
const newPair = {
|
|
3430
3400
|
...keyPair,
|
|
3431
|
-
cryptographicKey: new
|
|
3401
|
+
cryptographicKey: new _fedify_vocab.CryptographicKey({
|
|
3432
3402
|
id: keyPair.keyId,
|
|
3433
3403
|
owner,
|
|
3434
3404
|
publicKey: keyPair.publicKey
|
|
3435
3405
|
}),
|
|
3436
|
-
multikey: new
|
|
3406
|
+
multikey: new _fedify_vocab.Multikey({
|
|
3437
3407
|
id: keyPair.keyId,
|
|
3438
3408
|
controller: owner,
|
|
3439
3409
|
publicKey: keyPair.publicKey
|
|
@@ -3444,7 +3414,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3444
3414
|
return result;
|
|
3445
3415
|
}
|
|
3446
3416
|
async getKeyPairsFromIdentifier(identifier) {
|
|
3447
|
-
const logger
|
|
3417
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3448
3418
|
"fedify",
|
|
3449
3419
|
"federation",
|
|
3450
3420
|
"actor"
|
|
@@ -3455,7 +3425,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3455
3425
|
actorUri = this.getActorUri(identifier);
|
|
3456
3426
|
} catch (error) {
|
|
3457
3427
|
if (error instanceof RouterError) {
|
|
3458
|
-
logger
|
|
3428
|
+
logger.warn(error.message);
|
|
3459
3429
|
return [];
|
|
3460
3430
|
}
|
|
3461
3431
|
throw error;
|
|
@@ -3464,7 +3434,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3464
3434
|
...this,
|
|
3465
3435
|
invokedFromActorKeyPairsDispatcher: { identifier }
|
|
3466
3436
|
}), identifier);
|
|
3467
|
-
if (keyPairs.length < 1) logger
|
|
3437
|
+
if (keyPairs.length < 1) logger.warn("No key pairs found for actor {identifier}.", { identifier });
|
|
3468
3438
|
let i = 0;
|
|
3469
3439
|
const result = [];
|
|
3470
3440
|
for (const keyPair of keyPairs) {
|
|
@@ -3482,7 +3452,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3482
3452
|
const { privateKey } = keyPair;
|
|
3483
3453
|
if (privateKey.algorithm.name === "RSASSA-PKCS1-v1_5" && privateKey.algorithm.hash.name === "SHA-256") return keyPair;
|
|
3484
3454
|
}
|
|
3485
|
-
(0,
|
|
3455
|
+
(0, _logtape_logtape.getLogger)([
|
|
3486
3456
|
"fedify",
|
|
3487
3457
|
"federation",
|
|
3488
3458
|
"actor"
|
|
@@ -3503,14 +3473,13 @@ var ContextImpl = class ContextImpl {
|
|
|
3503
3473
|
} else identifierPromise = Promise.resolve(identity.identifier);
|
|
3504
3474
|
return identifierPromise.then((identifier) => {
|
|
3505
3475
|
if (identifier == null) return this.documentLoader;
|
|
3506
|
-
|
|
3507
|
-
return keyPair.then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
3476
|
+
return this.getRsaKeyPairFromIdentifier(identifier).then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
3508
3477
|
});
|
|
3509
3478
|
}
|
|
3510
3479
|
return this.federation.authenticatedDocumentLoaderFactory(identity);
|
|
3511
3480
|
}
|
|
3512
3481
|
lookupObject(identifier, options = {}) {
|
|
3513
|
-
return (0,
|
|
3482
|
+
return (0, _fedify_vocab.lookupObject)(identifier, {
|
|
3514
3483
|
...options,
|
|
3515
3484
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3516
3485
|
contextLoader: options.contextLoader ?? this.contextLoader,
|
|
@@ -3520,7 +3489,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3520
3489
|
});
|
|
3521
3490
|
}
|
|
3522
3491
|
traverseCollection(collection, options = {}) {
|
|
3523
|
-
return (0,
|
|
3492
|
+
return (0, _fedify_vocab.traverseCollection)(collection, {
|
|
3524
3493
|
...options,
|
|
3525
3494
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3526
3495
|
contextLoader: options.contextLoader ?? this.contextLoader
|
|
@@ -3538,7 +3507,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3538
3507
|
});
|
|
3539
3508
|
}
|
|
3540
3509
|
lookupWebFinger(resource, options = {}) {
|
|
3541
|
-
return (0,
|
|
3510
|
+
return (0, _fedify_webfinger.lookupWebFinger)(resource, {
|
|
3542
3511
|
...options,
|
|
3543
3512
|
userAgent: options.userAgent ?? this.federation.userAgent,
|
|
3544
3513
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
@@ -3546,11 +3515,10 @@ var ContextImpl = class ContextImpl {
|
|
|
3546
3515
|
});
|
|
3547
3516
|
}
|
|
3548
3517
|
sendActivity(sender, recipients, activity, options = {}) {
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
kind: this.federation.outboxQueue == null || options.immediate ? __opentelemetry_api.SpanKind.CLIENT : __opentelemetry_api.SpanKind.PRODUCER,
|
|
3518
|
+
return this.tracerProvider.getTracer(require_http.name, require_http.version).startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
3519
|
+
kind: this.federation.outboxQueue == null || options.immediate ? _opentelemetry_api.SpanKind.CLIENT : _opentelemetry_api.SpanKind.PRODUCER,
|
|
3552
3520
|
attributes: {
|
|
3553
|
-
"activitypub.activity.type": (0,
|
|
3521
|
+
"activitypub.activity.type": (0, _fedify_vocab.getTypeId)(activity).href,
|
|
3554
3522
|
"activitypub.activity.to": activity.toIds.map((to) => to.href),
|
|
3555
3523
|
"activitypub.activity.cc": activity.toIds.map((cc) => cc.href),
|
|
3556
3524
|
"activitypub.activity.bto": activity.btoIds.map((bto) => bto.href),
|
|
@@ -3562,7 +3530,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3562
3530
|
await this.sendActivityInternal(sender, recipients, activity, options, span);
|
|
3563
3531
|
} catch (e) {
|
|
3564
3532
|
span.setStatus({
|
|
3565
|
-
code:
|
|
3533
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3566
3534
|
message: String(e)
|
|
3567
3535
|
});
|
|
3568
3536
|
throw e;
|
|
@@ -3572,7 +3540,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3572
3540
|
});
|
|
3573
3541
|
}
|
|
3574
3542
|
async sendActivityInternal(sender, recipients, activity, options, span) {
|
|
3575
|
-
const logger
|
|
3543
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3576
3544
|
"fedify",
|
|
3577
3545
|
"federation",
|
|
3578
3546
|
"outbox"
|
|
@@ -3622,7 +3590,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3622
3590
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
3623
3591
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
3624
3592
|
if (activity.actorId == null) {
|
|
3625
|
-
logger
|
|
3593
|
+
logger.error("Activity {activityId} to send does not have an actor.", {
|
|
3626
3594
|
activity,
|
|
3627
3595
|
activityId: activity?.id?.href
|
|
3628
3596
|
});
|
|
@@ -3633,7 +3601,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3633
3601
|
preferSharedInbox: options.preferSharedInbox,
|
|
3634
3602
|
excludeBaseUris: options.excludeBaseUris
|
|
3635
3603
|
});
|
|
3636
|
-
logger
|
|
3604
|
+
logger.debug("Sending activity {activityId} to inboxes:\n{inboxes}", {
|
|
3637
3605
|
inboxes: globalThis.Object.keys(inboxes),
|
|
3638
3606
|
activityId: activity.id?.href,
|
|
3639
3607
|
activity
|
|
@@ -3647,7 +3615,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3647
3615
|
privateKey: await require_http.exportJwk(privateKey)
|
|
3648
3616
|
})));
|
|
3649
3617
|
const carrier = {};
|
|
3650
|
-
|
|
3618
|
+
_opentelemetry_api.propagation.inject(_opentelemetry_api.context.active(), carrier);
|
|
3651
3619
|
const message = {
|
|
3652
3620
|
type: "fanout",
|
|
3653
3621
|
id: crypto.randomUUID(),
|
|
@@ -3662,7 +3630,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3662
3630
|
contextLoader: this.contextLoader
|
|
3663
3631
|
}),
|
|
3664
3632
|
activityId: activity.id?.href,
|
|
3665
|
-
activityType: (0,
|
|
3633
|
+
activityType: (0, _fedify_vocab.getTypeId)(activity).href,
|
|
3666
3634
|
collectionSync: opts.collectionSync,
|
|
3667
3635
|
orderingKey: options.orderingKey,
|
|
3668
3636
|
traceContext: carrier
|
|
@@ -3679,24 +3647,22 @@ var ContextImpl = class ContextImpl {
|
|
|
3679
3647
|
}
|
|
3680
3648
|
if (this.federation.followersCallbacks.firstCursor == null) throw new Error("No first cursor dispatcher registered for followers collection.");
|
|
3681
3649
|
let cursor = await this.federation.followersCallbacks.firstCursor(this, identifier);
|
|
3682
|
-
if (cursor != null) (0,
|
|
3650
|
+
if (cursor != null) (0, _logtape_logtape.getLogger)([
|
|
3683
3651
|
"fedify",
|
|
3684
3652
|
"federation",
|
|
3685
3653
|
"outbox"
|
|
3686
3654
|
]).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 });
|
|
3687
3655
|
while (cursor != null) {
|
|
3688
|
-
const result
|
|
3689
|
-
if (result
|
|
3690
|
-
for (const recipient of result
|
|
3691
|
-
cursor = result
|
|
3656
|
+
const result = await this.federation.followersCallbacks.dispatcher(this, identifier, cursor);
|
|
3657
|
+
if (result == null) break;
|
|
3658
|
+
for (const recipient of result.items) yield recipient;
|
|
3659
|
+
cursor = result.nextCursor ?? null;
|
|
3692
3660
|
}
|
|
3693
3661
|
}
|
|
3694
3662
|
routeActivity(recipient, activity, options = {}) {
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
kind: this.federation.inboxQueue == null || options.immediate ? __opentelemetry_api.SpanKind.INTERNAL : __opentelemetry_api.SpanKind.PRODUCER,
|
|
3699
|
-
attributes: { "activitypub.activity.type": (0, __fedify_vocab.getTypeId)(activity).href }
|
|
3663
|
+
return (this.tracerProvider ?? this.tracerProvider).getTracer(require_http.name, require_http.version).startActiveSpan("activitypub.inbox", {
|
|
3664
|
+
kind: this.federation.inboxQueue == null || options.immediate ? _opentelemetry_api.SpanKind.INTERNAL : _opentelemetry_api.SpanKind.PRODUCER,
|
|
3665
|
+
attributes: { "activitypub.activity.type": (0, _fedify_vocab.getTypeId)(activity).href }
|
|
3700
3666
|
}, async (span) => {
|
|
3701
3667
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
3702
3668
|
if (activity.toIds.length > 0) span.setAttribute("activitypub.activity.to", activity.toIds.map((to) => to.href));
|
|
@@ -3708,11 +3674,11 @@ var ContextImpl = class ContextImpl {
|
|
|
3708
3674
|
if (ok) {
|
|
3709
3675
|
span.setAttribute("activitypub.shared_inbox", recipient == null);
|
|
3710
3676
|
if (recipient != null) span.setAttribute("fedify.inbox.recipient", recipient);
|
|
3711
|
-
} else span.setStatus({ code:
|
|
3677
|
+
} else span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
3712
3678
|
return ok;
|
|
3713
3679
|
} catch (e) {
|
|
3714
3680
|
span.setStatus({
|
|
3715
|
-
code:
|
|
3681
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3716
3682
|
message: String(e)
|
|
3717
3683
|
});
|
|
3718
3684
|
throw e;
|
|
@@ -3722,7 +3688,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3722
3688
|
});
|
|
3723
3689
|
}
|
|
3724
3690
|
async routeActivityInternal(recipient, activity, options = {}, span) {
|
|
3725
|
-
const logger
|
|
3691
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3726
3692
|
"fedify",
|
|
3727
3693
|
"federation",
|
|
3728
3694
|
"inbox"
|
|
@@ -3730,19 +3696,18 @@ var ContextImpl = class ContextImpl {
|
|
|
3730
3696
|
const contextLoader = options.contextLoader ?? this.contextLoader;
|
|
3731
3697
|
const json = await activity.toJsonLd({ contextLoader });
|
|
3732
3698
|
const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, this);
|
|
3733
|
-
|
|
3699
|
+
if (await require_proof.verifyObject(_fedify_vocab.Activity, json, {
|
|
3734
3700
|
contextLoader,
|
|
3735
3701
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3736
3702
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
3737
3703
|
keyCache
|
|
3738
|
-
})
|
|
3739
|
-
|
|
3740
|
-
logger$1.debug("Object Integrity Proofs are not verified.", {
|
|
3704
|
+
}) == null) {
|
|
3705
|
+
logger.debug("Object Integrity Proofs are not verified.", {
|
|
3741
3706
|
recipient,
|
|
3742
3707
|
activity: json
|
|
3743
3708
|
});
|
|
3744
3709
|
if (activity.id == null) {
|
|
3745
|
-
logger
|
|
3710
|
+
logger.debug("Activity is missing an ID; unable to fetch.", {
|
|
3746
3711
|
recipient,
|
|
3747
3712
|
activity: json
|
|
3748
3713
|
});
|
|
@@ -3750,26 +3715,26 @@ var ContextImpl = class ContextImpl {
|
|
|
3750
3715
|
}
|
|
3751
3716
|
const fetched = await this.lookupObject(activity.id, options);
|
|
3752
3717
|
if (fetched == null) {
|
|
3753
|
-
logger
|
|
3718
|
+
logger.debug("Failed to fetch the remote activity object {activityId}.", {
|
|
3754
3719
|
recipient,
|
|
3755
3720
|
activity: json,
|
|
3756
3721
|
activityId: activity.id.href
|
|
3757
3722
|
});
|
|
3758
3723
|
return false;
|
|
3759
|
-
} else if (!(fetched instanceof
|
|
3760
|
-
logger
|
|
3724
|
+
} else if (!(fetched instanceof _fedify_vocab.Activity)) {
|
|
3725
|
+
logger.debug("Fetched object is not an Activity.", {
|
|
3761
3726
|
recipient,
|
|
3762
3727
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3763
3728
|
});
|
|
3764
3729
|
return false;
|
|
3765
3730
|
} else if (fetched.id?.href !== activity.id.href) {
|
|
3766
|
-
logger
|
|
3731
|
+
logger.debug("Fetched activity object has a different ID; failed to verify.", {
|
|
3767
3732
|
recipient,
|
|
3768
3733
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3769
3734
|
});
|
|
3770
3735
|
return false;
|
|
3771
3736
|
} else if (fetched.actorIds.length < 1) {
|
|
3772
|
-
logger
|
|
3737
|
+
logger.debug("Fetched activity object is missing an actor; unable to verify.", {
|
|
3773
3738
|
recipient,
|
|
3774
3739
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3775
3740
|
});
|
|
@@ -3777,15 +3742,15 @@ var ContextImpl = class ContextImpl {
|
|
|
3777
3742
|
}
|
|
3778
3743
|
const activityId = fetched.id;
|
|
3779
3744
|
if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
|
|
3780
|
-
logger
|
|
3745
|
+
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
3781
3746
|
recipient,
|
|
3782
3747
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3783
3748
|
});
|
|
3784
3749
|
return false;
|
|
3785
3750
|
}
|
|
3786
|
-
logger
|
|
3751
|
+
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
3787
3752
|
activity = fetched;
|
|
3788
|
-
} else logger
|
|
3753
|
+
} else logger.debug("Object Integrity Proofs are verified.", {
|
|
3789
3754
|
recipient,
|
|
3790
3755
|
activity: json
|
|
3791
3756
|
});
|
|
@@ -3834,7 +3799,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
|
|
|
3834
3799
|
}
|
|
3835
3800
|
async getActor(identifier) {
|
|
3836
3801
|
if (this.federation.actorCallbacks == null || this.federation.actorCallbacks.dispatcher == null) throw new Error("No actor dispatcher registered.");
|
|
3837
|
-
if (this.#invokedFromActorDispatcher != null) (0,
|
|
3802
|
+
if (this.#invokedFromActorDispatcher != null) (0, _logtape_logtape.getLogger)([
|
|
3838
3803
|
"fedify",
|
|
3839
3804
|
"federation",
|
|
3840
3805
|
"actor"
|
|
@@ -3851,7 +3816,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
|
|
|
3851
3816
|
const callbacks = this.federation.objectCallbacks[cls.typeId.href];
|
|
3852
3817
|
if (callbacks == null) throw new Error("No object dispatcher registered.");
|
|
3853
3818
|
for (const param of callbacks.parameters) if (!(param in values)) throw new TypeError(`Missing parameter: ${param}`);
|
|
3854
|
-
if (this.#invokedFromObjectDispatcher != null) (0,
|
|
3819
|
+
if (this.#invokedFromObjectDispatcher != null) (0, _logtape_logtape.getLogger)(["fedify", "federation"]).warn("RequestContext.getObject({getObjectClass}, {getObjectValues}) is invoked from the object dispatcher ({actorDispatcherClass}, {actorDispatcherValues}); this may cause an infinite loop.", {
|
|
3855
3820
|
getObjectClass: cls.name,
|
|
3856
3821
|
getObjectValues: values,
|
|
3857
3822
|
actorDispatcherClass: this.#invokedFromObjectDispatcher.cls.name,
|
|
@@ -3911,9 +3876,8 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3911
3876
|
});
|
|
3912
3877
|
}
|
|
3913
3878
|
forwardActivity(forwarder, recipients, options) {
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
kind: this.federation.outboxQueue == null || options?.immediate ? __opentelemetry_api.SpanKind.CLIENT : __opentelemetry_api.SpanKind.PRODUCER,
|
|
3879
|
+
return this.tracerProvider.getTracer(require_http.name, require_http.version).startActiveSpan("activitypub.outbox", {
|
|
3880
|
+
kind: this.federation.outboxQueue == null || options?.immediate ? _opentelemetry_api.SpanKind.CLIENT : _opentelemetry_api.SpanKind.PRODUCER,
|
|
3917
3881
|
attributes: { "activitypub.activity.type": this.activityType }
|
|
3918
3882
|
}, async (span) => {
|
|
3919
3883
|
try {
|
|
@@ -3921,7 +3885,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3921
3885
|
await this.forwardActivityInternal(forwarder, recipients, options);
|
|
3922
3886
|
} catch (e) {
|
|
3923
3887
|
span.setStatus({
|
|
3924
|
-
code:
|
|
3888
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3925
3889
|
message: String(e)
|
|
3926
3890
|
});
|
|
3927
3891
|
throw e;
|
|
@@ -3931,7 +3895,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3931
3895
|
});
|
|
3932
3896
|
}
|
|
3933
3897
|
async forwardActivityInternal(forwarder, recipients, options) {
|
|
3934
|
-
const logger
|
|
3898
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3935
3899
|
"fedify",
|
|
3936
3900
|
"federation",
|
|
3937
3901
|
"inbox"
|
|
@@ -3958,14 +3922,13 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3958
3922
|
if (!require_proof.hasSignature(this.activity)) {
|
|
3959
3923
|
let hasProof;
|
|
3960
3924
|
try {
|
|
3961
|
-
|
|
3962
|
-
hasProof = await activity.getProof() != null;
|
|
3925
|
+
hasProof = await (await _fedify_vocab.Activity.fromJsonLd(this.activity, this)).getProof() != null;
|
|
3963
3926
|
} catch {
|
|
3964
3927
|
hasProof = false;
|
|
3965
3928
|
}
|
|
3966
3929
|
if (!hasProof) {
|
|
3967
3930
|
if (options?.skipIfUnsigned) return;
|
|
3968
|
-
logger
|
|
3931
|
+
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.");
|
|
3969
3932
|
}
|
|
3970
3933
|
}
|
|
3971
3934
|
if (recipients === "followers") {
|
|
@@ -3979,14 +3942,14 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3979
3942
|
preferSharedInbox: options?.preferSharedInbox,
|
|
3980
3943
|
excludeBaseUris: options?.excludeBaseUris
|
|
3981
3944
|
});
|
|
3982
|
-
logger
|
|
3945
|
+
logger.debug("Forwarding activity {activityId} to inboxes:\n{inboxes}", {
|
|
3983
3946
|
inboxes: globalThis.Object.keys(inboxes),
|
|
3984
3947
|
activityId: this.activityId,
|
|
3985
3948
|
activity: this.activity
|
|
3986
3949
|
});
|
|
3987
3950
|
if (options?.immediate || this.federation.outboxQueue == null) {
|
|
3988
|
-
if (options?.immediate) logger
|
|
3989
|
-
else logger
|
|
3951
|
+
if (options?.immediate) logger.debug("Forwarding activity immediately without queue since immediate option is set.");
|
|
3952
|
+
else logger.debug("Forwarding activity immediately without queue since queue is not set.");
|
|
3990
3953
|
const promises = [];
|
|
3991
3954
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
3992
3955
|
keys,
|
|
@@ -4001,7 +3964,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4001
3964
|
await Promise.all(promises);
|
|
4002
3965
|
return;
|
|
4003
3966
|
}
|
|
4004
|
-
logger
|
|
3967
|
+
logger.debug("Enqueuing activity {activityId} to forward later.", {
|
|
4005
3968
|
activityId: this.activityId,
|
|
4006
3969
|
activity: this.activity
|
|
4007
3970
|
});
|
|
@@ -4014,7 +3977,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4014
3977
|
});
|
|
4015
3978
|
}
|
|
4016
3979
|
const carrier = {};
|
|
4017
|
-
|
|
3980
|
+
_opentelemetry_api.propagation.inject(_opentelemetry_api.context.active(), carrier);
|
|
4018
3981
|
const orderingKey = options?.orderingKey;
|
|
4019
3982
|
const messages = [];
|
|
4020
3983
|
for (const inbox in inboxes) {
|
|
@@ -4043,10 +4006,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4043
4006
|
const { outboxQueue } = this.federation;
|
|
4044
4007
|
if (outboxQueue.enqueueMany == null) {
|
|
4045
4008
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4046
|
-
const
|
|
4047
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4009
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4048
4010
|
if (errors.length > 0) {
|
|
4049
|
-
logger
|
|
4011
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4050
4012
|
activityId: this.activityId,
|
|
4051
4013
|
errors
|
|
4052
4014
|
});
|
|
@@ -4055,10 +4017,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4055
4017
|
}
|
|
4056
4018
|
} else if (orderingKey != null) {
|
|
4057
4019
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4058
|
-
const
|
|
4059
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4020
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4060
4021
|
if (errors.length > 0) {
|
|
4061
|
-
logger
|
|
4022
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4062
4023
|
activityId: this.activityId,
|
|
4063
4024
|
errors
|
|
4064
4025
|
});
|
|
@@ -4068,7 +4029,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4068
4029
|
} else try {
|
|
4069
4030
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
4070
4031
|
} catch (error) {
|
|
4071
|
-
logger
|
|
4032
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
|
|
4072
4033
|
activityId: this.activityId,
|
|
4073
4034
|
error
|
|
4074
4035
|
});
|
|
@@ -4123,99 +4084,96 @@ function unauthorized(_request) {
|
|
|
4123
4084
|
function getRequestId(request) {
|
|
4124
4085
|
const traceId = request.headers.get("X-Request-Id") || request.headers.get("X-Correlation-Id") || request.headers.get("Traceparent")?.split("-")[1];
|
|
4125
4086
|
if (traceId != null) return traceId;
|
|
4126
|
-
|
|
4127
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
4128
|
-
return `req_${timestamp}${random}`;
|
|
4087
|
+
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
4129
4088
|
}
|
|
4130
|
-
|
|
4131
4089
|
//#endregion
|
|
4132
|
-
Object.defineProperty(exports,
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4090
|
+
Object.defineProperty(exports, "ContextImpl", {
|
|
4091
|
+
enumerable: true,
|
|
4092
|
+
get: function() {
|
|
4093
|
+
return ContextImpl;
|
|
4094
|
+
}
|
|
4137
4095
|
});
|
|
4138
|
-
Object.defineProperty(exports,
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4096
|
+
Object.defineProperty(exports, "FederationImpl", {
|
|
4097
|
+
enumerable: true,
|
|
4098
|
+
get: function() {
|
|
4099
|
+
return FederationImpl;
|
|
4100
|
+
}
|
|
4101
|
+
});
|
|
4102
|
+
Object.defineProperty(exports, "InboxContextImpl", {
|
|
4103
|
+
enumerable: true,
|
|
4104
|
+
get: function() {
|
|
4105
|
+
return InboxContextImpl;
|
|
4106
|
+
}
|
|
4143
4107
|
});
|
|
4144
|
-
Object.defineProperty(exports,
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4108
|
+
Object.defineProperty(exports, "KvSpecDeterminer", {
|
|
4109
|
+
enumerable: true,
|
|
4110
|
+
get: function() {
|
|
4111
|
+
return KvSpecDeterminer;
|
|
4112
|
+
}
|
|
4149
4113
|
});
|
|
4150
|
-
Object.defineProperty(exports,
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4114
|
+
Object.defineProperty(exports, "Router", {
|
|
4115
|
+
enumerable: true,
|
|
4116
|
+
get: function() {
|
|
4117
|
+
return Router;
|
|
4118
|
+
}
|
|
4155
4119
|
});
|
|
4156
|
-
Object.defineProperty(exports,
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4120
|
+
Object.defineProperty(exports, "RouterError", {
|
|
4121
|
+
enumerable: true,
|
|
4122
|
+
get: function() {
|
|
4123
|
+
return RouterError;
|
|
4124
|
+
}
|
|
4161
4125
|
});
|
|
4162
|
-
Object.defineProperty(exports,
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4126
|
+
Object.defineProperty(exports, "SendActivityError", {
|
|
4127
|
+
enumerable: true,
|
|
4128
|
+
get: function() {
|
|
4129
|
+
return SendActivityError;
|
|
4130
|
+
}
|
|
4167
4131
|
});
|
|
4168
|
-
Object.defineProperty(exports,
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4132
|
+
Object.defineProperty(exports, "buildCollectionSynchronizationHeader", {
|
|
4133
|
+
enumerable: true,
|
|
4134
|
+
get: function() {
|
|
4135
|
+
return buildCollectionSynchronizationHeader;
|
|
4136
|
+
}
|
|
4173
4137
|
});
|
|
4174
|
-
Object.defineProperty(exports,
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4138
|
+
Object.defineProperty(exports, "createExponentialBackoffPolicy", {
|
|
4139
|
+
enumerable: true,
|
|
4140
|
+
get: function() {
|
|
4141
|
+
return createExponentialBackoffPolicy;
|
|
4142
|
+
}
|
|
4179
4143
|
});
|
|
4180
|
-
Object.defineProperty(exports,
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4144
|
+
Object.defineProperty(exports, "createFederation", {
|
|
4145
|
+
enumerable: true,
|
|
4146
|
+
get: function() {
|
|
4147
|
+
return createFederation;
|
|
4148
|
+
}
|
|
4185
4149
|
});
|
|
4186
|
-
Object.defineProperty(exports,
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4150
|
+
Object.defineProperty(exports, "createFederationBuilder", {
|
|
4151
|
+
enumerable: true,
|
|
4152
|
+
get: function() {
|
|
4153
|
+
return createFederationBuilder;
|
|
4154
|
+
}
|
|
4191
4155
|
});
|
|
4192
|
-
Object.defineProperty(exports,
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4156
|
+
Object.defineProperty(exports, "digest", {
|
|
4157
|
+
enumerable: true,
|
|
4158
|
+
get: function() {
|
|
4159
|
+
return digest;
|
|
4160
|
+
}
|
|
4197
4161
|
});
|
|
4198
|
-
Object.defineProperty(exports,
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4162
|
+
Object.defineProperty(exports, "handleWebFinger", {
|
|
4163
|
+
enumerable: true,
|
|
4164
|
+
get: function() {
|
|
4165
|
+
return handleWebFinger;
|
|
4166
|
+
}
|
|
4203
4167
|
});
|
|
4204
|
-
Object.defineProperty(exports,
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4168
|
+
Object.defineProperty(exports, "respondWithObject", {
|
|
4169
|
+
enumerable: true,
|
|
4170
|
+
get: function() {
|
|
4171
|
+
return respondWithObject;
|
|
4172
|
+
}
|
|
4209
4173
|
});
|
|
4210
|
-
Object.defineProperty(exports,
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4174
|
+
Object.defineProperty(exports, "respondWithObjectIfAcceptable", {
|
|
4175
|
+
enumerable: true,
|
|
4176
|
+
get: function() {
|
|
4177
|
+
return respondWithObjectIfAcceptable;
|
|
4178
|
+
}
|
|
4215
4179
|
});
|
|
4216
|
-
Object.defineProperty(exports, 'respondWithObjectIfAcceptable', {
|
|
4217
|
-
enumerable: true,
|
|
4218
|
-
get: function () {
|
|
4219
|
-
return respondWithObjectIfAcceptable;
|
|
4220
|
-
}
|
|
4221
|
-
});
|