@fedify/fedify 2.0.8 → 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-B5cKln9v.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-CBHh0rC5.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} +11 -15
- 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-C_RwU_oN.js → http-Bz7avX57.js} +25 -156
- package/dist/{http-Cz3MlXAZ.d.cts → http-C_tEAiZj.d.cts} +1 -6
- package/dist/{http-Br3-1dRf.js → http-DI213UHg.mjs} +17 -33
- package/dist/{http-DGs_78tx.cjs → http-DKBDoudA.cjs} +110 -235
- package/dist/{inbox-3bZUqDLE.js → inbox-Bdn-CSRd.mjs} +18 -26
- package/dist/{key-D7Y_J9kt.js → key-DzJf84o7.mjs} +12 -19
- package/dist/{keycache-BASM0rrX.js → keycache-DaQ3ndaJ.mjs} +5 -9
- 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-CMM5VJsc.js → kv-cache-DBd7BezJ.js} +6 -13
- package/dist/{kv-cache-9PANi4tA.cjs → kv-cache-Dj1Q7TiW.cjs} +27 -34
- package/dist/{kv-cache-El7We5sy.js → kv-cache-OWmRLHir.mjs} +4 -8
- package/dist/{ld-Bjq9Z4St.js → ld-DczS1fLK.mjs} +17 -31
- package/dist/middleware-B5CiOImA.mjs +5 -0
- package/dist/{middleware-Bj30TZll.js → middleware-BKNu57ZI.js} +320 -363
- package/dist/middleware-C36TOX-2.cjs +4 -0
- package/dist/{middleware-CQeA5yF7.cjs → middleware-CyjmpK70.cjs} +513 -564
- package/dist/{middleware-DozhKfB6.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-CImU2dKz.js → owner-DXMGUEOr.mjs} +11 -16
- package/dist/{proof-BygvN4r5.js → proof-C-7NljBU.js} +32 -58
- package/dist/{proof-DLL0MLmV.js → proof-CEOujj0L.mjs} +21 -33
- package/dist/{proof-UhA5do8k.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-DbW03azY.js → send-DIfrLTB_.mjs} +8 -13
- package/dist/sig/http.test.d.mts +2 -0
- package/dist/sig/{http.test.js → http.test.mjs} +117 -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-4w047OFk.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-B73ZyDmk.js +0 -12
- package/dist/middleware-Dr61i4Jo.cjs +0 -12
- package/dist/middleware-_1PYruC5.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,10 +845,8 @@ 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
|
|
869
852
|
const NULL_KEY_CACHE_VALUE = { _fedify: "key-unavailable" };
|
|
@@ -891,13 +874,13 @@ var KvKeyCache = class {
|
|
|
891
874
|
return null;
|
|
892
875
|
}
|
|
893
876
|
try {
|
|
894
|
-
return await
|
|
877
|
+
return await _fedify_vocab.CryptographicKey.fromJsonLd(serialized, this.options);
|
|
895
878
|
} catch {
|
|
896
879
|
try {
|
|
897
|
-
return await
|
|
880
|
+
return await _fedify_vocab.Multikey.fromJsonLd(serialized, this.options);
|
|
898
881
|
} catch {
|
|
899
882
|
await this.kv.delete([...this.prefix, keyId.href]);
|
|
900
|
-
return
|
|
883
|
+
return;
|
|
901
884
|
}
|
|
902
885
|
}
|
|
903
886
|
}
|
|
@@ -912,7 +895,6 @@ var KvKeyCache = class {
|
|
|
912
895
|
await this.kv.set([...this.prefix, keyId.href], serialized);
|
|
913
896
|
}
|
|
914
897
|
};
|
|
915
|
-
|
|
916
898
|
//#endregion
|
|
917
899
|
//#region src/federation/negotiation.ts
|
|
918
900
|
function compareSpecs(a, b) {
|
|
@@ -957,8 +939,8 @@ function parseMediaType(str, i) {
|
|
|
957
939
|
function parseAccept(accept) {
|
|
958
940
|
const accepts = accept.split(",").map((p) => p.trim());
|
|
959
941
|
const mediaTypes = [];
|
|
960
|
-
for (const [index, accept
|
|
961
|
-
const mediaType = parseMediaType(accept
|
|
942
|
+
for (const [index, accept] of accepts.entries()) {
|
|
943
|
+
const mediaType = parseMediaType(accept.trim(), index);
|
|
962
944
|
if (mediaType) mediaTypes.push(mediaType);
|
|
963
945
|
}
|
|
964
946
|
return mediaTypes;
|
|
@@ -967,8 +949,7 @@ function getFullType(spec) {
|
|
|
967
949
|
return `${spec.type}/${spec.subtype}`;
|
|
968
950
|
}
|
|
969
951
|
function preferredMediaTypes(accept) {
|
|
970
|
-
|
|
971
|
-
return accepts.filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
952
|
+
return parseAccept(accept === void 0 ? "*/*" : accept ?? "").filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
972
953
|
}
|
|
973
954
|
function acceptsJsonLd(request) {
|
|
974
955
|
const accept = request.headers.get("Accept");
|
|
@@ -977,7 +958,6 @@ function acceptsJsonLd(request) {
|
|
|
977
958
|
if (types[0] === "text/html" || types[0] === "application/xhtml+xml") return false;
|
|
978
959
|
return types.includes("application/activity+json") || types.includes("application/ld+json") || types.includes("application/json");
|
|
979
960
|
}
|
|
980
|
-
|
|
981
961
|
//#endregion
|
|
982
962
|
//#region src/federation/handler.ts
|
|
983
963
|
/**
|
|
@@ -987,25 +967,25 @@ function acceptsJsonLd(request) {
|
|
|
987
967
|
* @param parameters The parameters for handling the actor.
|
|
988
968
|
* @returns A promise that resolves to an HTTP response.
|
|
989
969
|
*/
|
|
990
|
-
async function handleActor(request, { identifier, context
|
|
991
|
-
const logger
|
|
970
|
+
async function handleActor(request, { identifier, context, actorDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
971
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
992
972
|
"fedify",
|
|
993
973
|
"federation",
|
|
994
974
|
"actor"
|
|
995
975
|
]);
|
|
996
976
|
if (actorDispatcher == null) {
|
|
997
|
-
logger
|
|
977
|
+
logger.debug("Actor dispatcher is not set.", { identifier });
|
|
998
978
|
return await onNotFound(request);
|
|
999
979
|
}
|
|
1000
|
-
const actor = await actorDispatcher(context
|
|
980
|
+
const actor = await actorDispatcher(context, identifier);
|
|
1001
981
|
if (actor == null) {
|
|
1002
|
-
logger
|
|
982
|
+
logger.debug("Actor {identifier} not found.", { identifier });
|
|
1003
983
|
return await onNotFound(request);
|
|
1004
984
|
}
|
|
1005
985
|
if (authorizePredicate != null) {
|
|
1006
|
-
if (!await authorizePredicate(context
|
|
986
|
+
if (!await authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
1007
987
|
}
|
|
1008
|
-
const jsonLd = await actor.toJsonLd(context
|
|
988
|
+
const jsonLd = await actor.toJsonLd(context);
|
|
1009
989
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1010
990
|
"Content-Type": "application/activity+json",
|
|
1011
991
|
Vary: "Accept"
|
|
@@ -1018,14 +998,14 @@ async function handleActor(request, { identifier, context: context$2, actorDispa
|
|
|
1018
998
|
* @param parameters The parameters for handling the object.
|
|
1019
999
|
* @returns A promise that resolves to an HTTP response.
|
|
1020
1000
|
*/
|
|
1021
|
-
async function handleObject(request, { values, context
|
|
1001
|
+
async function handleObject(request, { values, context, objectDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
1022
1002
|
if (objectDispatcher == null) return await onNotFound(request);
|
|
1023
|
-
const object = await objectDispatcher(context
|
|
1003
|
+
const object = await objectDispatcher(context, values);
|
|
1024
1004
|
if (object == null) return await onNotFound(request);
|
|
1025
1005
|
if (authorizePredicate != null) {
|
|
1026
|
-
if (!await authorizePredicate(context
|
|
1006
|
+
if (!await authorizePredicate(context, values)) return await onUnauthorized(request);
|
|
1027
1007
|
}
|
|
1028
|
-
const jsonLd = await object.toJsonLd(context
|
|
1008
|
+
const jsonLd = await object.toJsonLd(context);
|
|
1029
1009
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1030
1010
|
"Content-Type": "application/activity+json",
|
|
1031
1011
|
Vary: "Accept"
|
|
@@ -1041,31 +1021,30 @@ async function handleObject(request, { values, context: context$2, objectDispatc
|
|
|
1041
1021
|
* @param parameters The parameters for handling the collection.
|
|
1042
1022
|
* @returns A promise that resolves to an HTTP response.
|
|
1043
1023
|
*/
|
|
1044
|
-
async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context
|
|
1045
|
-
const spanName = name.trim().replace(/\s+/g, "_");
|
|
1046
|
-
tracerProvider = tracerProvider ??
|
|
1047
|
-
const tracer = tracerProvider.getTracer(require_http.
|
|
1048
|
-
const
|
|
1049
|
-
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");
|
|
1050
1029
|
if (collectionCallbacks == null) return await onNotFound(request);
|
|
1051
1030
|
let collection;
|
|
1052
1031
|
const baseUri = uriGetter(identifier);
|
|
1053
1032
|
if (cursor == null) {
|
|
1054
|
-
const firstCursor = await collectionCallbacks.firstCursor?.(context
|
|
1055
|
-
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;
|
|
1056
1035
|
if (firstCursor == null) {
|
|
1057
1036
|
const itemsOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection ${spanName}`, {
|
|
1058
|
-
kind:
|
|
1037
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
1059
1038
|
attributes: {
|
|
1060
1039
|
"activitypub.collection.id": baseUri.href,
|
|
1061
|
-
"activitypub.collection.type":
|
|
1040
|
+
"activitypub.collection.type": _fedify_vocab.OrderedCollection.typeId.href
|
|
1062
1041
|
}
|
|
1063
1042
|
}, async (span) => {
|
|
1064
1043
|
if (totalItems != null) span.setAttribute("activitypub.collection.total_items", Number(totalItems));
|
|
1065
1044
|
try {
|
|
1066
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1045
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
|
|
1067
1046
|
if (page == null) {
|
|
1068
|
-
span.setStatus({ code:
|
|
1047
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1069
1048
|
return await onNotFound(request);
|
|
1070
1049
|
}
|
|
1071
1050
|
const { items } = page;
|
|
@@ -1073,7 +1052,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1073
1052
|
return items;
|
|
1074
1053
|
} catch (e) {
|
|
1075
1054
|
span.setStatus({
|
|
1076
|
-
code:
|
|
1055
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1077
1056
|
message: String(e)
|
|
1078
1057
|
});
|
|
1079
1058
|
throw e;
|
|
@@ -1082,21 +1061,21 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1082
1061
|
}
|
|
1083
1062
|
});
|
|
1084
1063
|
if (itemsOrResponse instanceof Response) return itemsOrResponse;
|
|
1085
|
-
collection = new
|
|
1064
|
+
collection = new _fedify_vocab.OrderedCollection({
|
|
1086
1065
|
id: baseUri,
|
|
1087
1066
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1088
|
-
items: filterCollectionItems(itemsOrResponse, name, filterPredicate)
|
|
1067
|
+
items: filterCollectionItems(itemsOrResponse, name$1, filterPredicate)
|
|
1089
1068
|
});
|
|
1090
1069
|
} else {
|
|
1091
|
-
const lastCursor = await collectionCallbacks.lastCursor?.(context
|
|
1092
|
-
const first = new URL(context
|
|
1070
|
+
const lastCursor = await collectionCallbacks.lastCursor?.(context, identifier);
|
|
1071
|
+
const first = new URL(context.url);
|
|
1093
1072
|
first.searchParams.set("cursor", firstCursor);
|
|
1094
1073
|
let last = null;
|
|
1095
1074
|
if (lastCursor != null) {
|
|
1096
|
-
last = new URL(context
|
|
1075
|
+
last = new URL(context.url);
|
|
1097
1076
|
last.searchParams.set("cursor", lastCursor);
|
|
1098
1077
|
}
|
|
1099
|
-
collection = new
|
|
1078
|
+
collection = new _fedify_vocab.OrderedCollection({
|
|
1100
1079
|
id: baseUri,
|
|
1101
1080
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1102
1081
|
first,
|
|
@@ -1106,25 +1085,25 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1106
1085
|
} else {
|
|
1107
1086
|
const uri = new URL(baseUri);
|
|
1108
1087
|
uri.searchParams.set("cursor", cursor);
|
|
1109
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name}`, {
|
|
1110
|
-
kind:
|
|
1088
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
|
|
1089
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
1111
1090
|
attributes: {
|
|
1112
1091
|
"activitypub.collection.id": uri.href,
|
|
1113
|
-
"activitypub.collection.type":
|
|
1092
|
+
"activitypub.collection.type": _fedify_vocab.OrderedCollectionPage.typeId.href,
|
|
1114
1093
|
"fedify.collection.cursor": cursor
|
|
1115
1094
|
}
|
|
1116
1095
|
}, async (span) => {
|
|
1117
1096
|
try {
|
|
1118
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1097
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
|
|
1119
1098
|
if (page == null) {
|
|
1120
|
-
span.setStatus({ code:
|
|
1099
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1121
1100
|
return await onNotFound(request);
|
|
1122
1101
|
}
|
|
1123
1102
|
span.setAttribute("fedify.collection.items", page.items.length);
|
|
1124
1103
|
return page;
|
|
1125
1104
|
} catch (e) {
|
|
1126
1105
|
span.setStatus({
|
|
1127
|
-
code:
|
|
1106
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1128
1107
|
message: String(e)
|
|
1129
1108
|
});
|
|
1130
1109
|
throw e;
|
|
@@ -1136,28 +1115,28 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1136
1115
|
const { items, prevCursor, nextCursor } = pageOrResponse;
|
|
1137
1116
|
let prev = null;
|
|
1138
1117
|
if (prevCursor != null) {
|
|
1139
|
-
prev = new URL(context
|
|
1118
|
+
prev = new URL(context.url);
|
|
1140
1119
|
prev.searchParams.set("cursor", prevCursor);
|
|
1141
1120
|
}
|
|
1142
1121
|
let next = null;
|
|
1143
1122
|
if (nextCursor != null) {
|
|
1144
|
-
next = new URL(context
|
|
1123
|
+
next = new URL(context.url);
|
|
1145
1124
|
next.searchParams.set("cursor", nextCursor);
|
|
1146
1125
|
}
|
|
1147
|
-
const partOf = new URL(context
|
|
1126
|
+
const partOf = new URL(context.url);
|
|
1148
1127
|
partOf.searchParams.delete("cursor");
|
|
1149
|
-
collection = new
|
|
1128
|
+
collection = new _fedify_vocab.OrderedCollectionPage({
|
|
1150
1129
|
id: uri,
|
|
1151
1130
|
prev,
|
|
1152
1131
|
next,
|
|
1153
|
-
items: filterCollectionItems(items, name, filterPredicate),
|
|
1132
|
+
items: filterCollectionItems(items, name$1, filterPredicate),
|
|
1154
1133
|
partOf
|
|
1155
1134
|
});
|
|
1156
1135
|
}
|
|
1157
1136
|
if (collectionCallbacks.authorizePredicate != null) {
|
|
1158
|
-
if (!await collectionCallbacks.authorizePredicate(context
|
|
1137
|
+
if (!await collectionCallbacks.authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
1159
1138
|
}
|
|
1160
|
-
const jsonLd = await collection.toJsonLd(context
|
|
1139
|
+
const jsonLd = await collection.toJsonLd(context);
|
|
1161
1140
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1162
1141
|
"Content-Type": "application/activity+json",
|
|
1163
1142
|
Vary: "Accept"
|
|
@@ -1176,12 +1155,12 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1176
1155
|
let logged = false;
|
|
1177
1156
|
for (const item of items) {
|
|
1178
1157
|
let mappedItem;
|
|
1179
|
-
if (item instanceof
|
|
1158
|
+
if (item instanceof _fedify_vocab.Object || item instanceof _fedify_vocab.Link || item instanceof URL) mappedItem = item;
|
|
1180
1159
|
else if (item.id == null) continue;
|
|
1181
1160
|
else mappedItem = item.id;
|
|
1182
1161
|
if (filterPredicate != null && !filterPredicate(item)) {
|
|
1183
1162
|
if (!logged) {
|
|
1184
|
-
(0,
|
|
1163
|
+
(0, _logtape_logtape.getLogger)([
|
|
1185
1164
|
"fedify",
|
|
1186
1165
|
"federation",
|
|
1187
1166
|
"collection"
|
|
@@ -1202,10 +1181,8 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1202
1181
|
* @returns A promise that resolves to an HTTP response.
|
|
1203
1182
|
*/
|
|
1204
1183
|
async function handleInbox(request, options) {
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
return await tracer.startActiveSpan("activitypub.inbox", {
|
|
1208
|
-
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,
|
|
1209
1186
|
attributes: { "activitypub.shared_inbox": options.recipient == null }
|
|
1210
1187
|
}, async (span) => {
|
|
1211
1188
|
if (options.recipient != null) span.setAttribute("fedify.inbox.recipient", options.recipient);
|
|
@@ -1213,7 +1190,7 @@ async function handleInbox(request, options) {
|
|
|
1213
1190
|
return await handleInboxInternal(request, options, span);
|
|
1214
1191
|
} catch (e) {
|
|
1215
1192
|
span.setStatus({
|
|
1216
|
-
code:
|
|
1193
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1217
1194
|
message: String(e)
|
|
1218
1195
|
});
|
|
1219
1196
|
throw e;
|
|
@@ -1232,33 +1209,32 @@ async function handleInbox(request, options) {
|
|
|
1232
1209
|
*/
|
|
1233
1210
|
async function handleInboxInternal(request, parameters, span) {
|
|
1234
1211
|
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider } = parameters;
|
|
1235
|
-
const logger
|
|
1212
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
1236
1213
|
"fedify",
|
|
1237
1214
|
"federation",
|
|
1238
1215
|
"inbox"
|
|
1239
1216
|
]);
|
|
1240
1217
|
if (actorDispatcher == null) {
|
|
1241
|
-
logger
|
|
1218
|
+
logger.error("Actor dispatcher is not set.", { recipient });
|
|
1242
1219
|
span.setStatus({
|
|
1243
|
-
code:
|
|
1220
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1244
1221
|
message: "Actor dispatcher is not set."
|
|
1245
1222
|
});
|
|
1246
1223
|
return await onNotFound(request);
|
|
1247
1224
|
} else if (recipient != null) {
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
logger$1.error("Actor {recipient} not found.", { recipient });
|
|
1225
|
+
if (await actorDispatcher(ctx, recipient) == null) {
|
|
1226
|
+
logger.error("Actor {recipient} not found.", { recipient });
|
|
1251
1227
|
span.setStatus({
|
|
1252
|
-
code:
|
|
1228
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1253
1229
|
message: `Actor ${recipient} not found.`
|
|
1254
1230
|
});
|
|
1255
1231
|
return await onNotFound(request);
|
|
1256
1232
|
}
|
|
1257
1233
|
}
|
|
1258
1234
|
if (request.bodyUsed) {
|
|
1259
|
-
logger
|
|
1235
|
+
logger.error("Request body has already been read.", { recipient });
|
|
1260
1236
|
span.setStatus({
|
|
1261
|
-
code:
|
|
1237
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1262
1238
|
message: "Request body has already been read."
|
|
1263
1239
|
});
|
|
1264
1240
|
return new Response("Internal server error.", {
|
|
@@ -1266,9 +1242,9 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1266
1242
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1267
1243
|
});
|
|
1268
1244
|
} else if (request.body?.locked) {
|
|
1269
|
-
logger
|
|
1245
|
+
logger.error("Request body is locked.", { recipient });
|
|
1270
1246
|
span.setStatus({
|
|
1271
|
-
code:
|
|
1247
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1272
1248
|
message: "Request body is locked."
|
|
1273
1249
|
});
|
|
1274
1250
|
return new Response("Internal server error.", {
|
|
@@ -1280,21 +1256,21 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1280
1256
|
try {
|
|
1281
1257
|
json = await request.clone().json();
|
|
1282
1258
|
} catch (error) {
|
|
1283
|
-
logger
|
|
1259
|
+
logger.error("Failed to parse JSON:\n{error}", {
|
|
1284
1260
|
recipient,
|
|
1285
1261
|
error
|
|
1286
1262
|
});
|
|
1287
1263
|
try {
|
|
1288
1264
|
await inboxErrorHandler?.(ctx, error);
|
|
1289
|
-
} catch (error
|
|
1290
|
-
logger
|
|
1291
|
-
error
|
|
1265
|
+
} catch (error) {
|
|
1266
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1267
|
+
error,
|
|
1292
1268
|
activity: json,
|
|
1293
1269
|
recipient
|
|
1294
1270
|
});
|
|
1295
1271
|
}
|
|
1296
1272
|
span.setStatus({
|
|
1297
|
-
code:
|
|
1273
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1298
1274
|
message: `Failed to parse JSON:\n${error}`
|
|
1299
1275
|
});
|
|
1300
1276
|
return new Response("Invalid JSON.", {
|
|
@@ -1313,7 +1289,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1313
1289
|
});
|
|
1314
1290
|
} catch (error) {
|
|
1315
1291
|
if (error instanceof Error && error.name === "jsonld.SyntaxError") {
|
|
1316
|
-
logger
|
|
1292
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
1317
1293
|
recipient,
|
|
1318
1294
|
error
|
|
1319
1295
|
});
|
|
@@ -1327,40 +1303,40 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1327
1303
|
const jsonWithoutSig = require_proof.detachSignature(json);
|
|
1328
1304
|
let activity = null;
|
|
1329
1305
|
if (ldSigVerified) {
|
|
1330
|
-
logger
|
|
1306
|
+
logger.debug("Linked Data Signatures are verified.", {
|
|
1331
1307
|
recipient,
|
|
1332
1308
|
json
|
|
1333
1309
|
});
|
|
1334
|
-
activity = await
|
|
1310
|
+
activity = await _fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1335
1311
|
} else {
|
|
1336
|
-
logger
|
|
1312
|
+
logger.debug("Linked Data Signatures are not verified.", {
|
|
1337
1313
|
recipient,
|
|
1338
1314
|
json
|
|
1339
1315
|
});
|
|
1340
1316
|
try {
|
|
1341
|
-
activity = await require_proof.verifyObject(
|
|
1317
|
+
activity = await require_proof.verifyObject(_fedify_vocab.Activity, jsonWithoutSig, {
|
|
1342
1318
|
contextLoader: ctx.contextLoader,
|
|
1343
1319
|
documentLoader: ctx.documentLoader,
|
|
1344
1320
|
keyCache,
|
|
1345
1321
|
tracerProvider
|
|
1346
1322
|
});
|
|
1347
1323
|
} catch (error) {
|
|
1348
|
-
logger
|
|
1324
|
+
logger.error("Failed to parse activity:\n{error}", {
|
|
1349
1325
|
recipient,
|
|
1350
1326
|
activity: json,
|
|
1351
1327
|
error
|
|
1352
1328
|
});
|
|
1353
1329
|
try {
|
|
1354
1330
|
await inboxErrorHandler?.(ctx, error);
|
|
1355
|
-
} catch (error
|
|
1356
|
-
logger
|
|
1357
|
-
error
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1333
|
+
error,
|
|
1358
1334
|
activity: json,
|
|
1359
1335
|
recipient
|
|
1360
1336
|
});
|
|
1361
1337
|
}
|
|
1362
1338
|
span.setStatus({
|
|
1363
|
-
code:
|
|
1339
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1364
1340
|
message: `Failed to parse activity:\n${error}`
|
|
1365
1341
|
});
|
|
1366
1342
|
return new Response("Invalid activity.", {
|
|
@@ -1368,11 +1344,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1368
1344
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1369
1345
|
});
|
|
1370
1346
|
}
|
|
1371
|
-
if (activity == null) logger
|
|
1347
|
+
if (activity == null) logger.debug("Object Integrity Proofs are not verified.", {
|
|
1372
1348
|
recipient,
|
|
1373
1349
|
activity: json
|
|
1374
1350
|
});
|
|
1375
|
-
else logger
|
|
1351
|
+
else logger.debug("Object Integrity Proofs are verified.", {
|
|
1376
1352
|
recipient,
|
|
1377
1353
|
activity: json
|
|
1378
1354
|
});
|
|
@@ -1388,23 +1364,22 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1388
1364
|
tracerProvider
|
|
1389
1365
|
});
|
|
1390
1366
|
if (key == null) {
|
|
1391
|
-
logger
|
|
1367
|
+
logger.error("Failed to verify the request's HTTP Signatures.", { recipient });
|
|
1392
1368
|
span.setStatus({
|
|
1393
|
-
code:
|
|
1369
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1394
1370
|
message: `Failed to verify the request's HTTP Signatures.`
|
|
1395
1371
|
});
|
|
1396
|
-
|
|
1372
|
+
return new Response("Failed to verify the request signature.", {
|
|
1397
1373
|
status: 401,
|
|
1398
1374
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1399
1375
|
});
|
|
1400
|
-
|
|
1401
|
-
} else logger$1.debug("HTTP Signatures are verified.", { recipient });
|
|
1376
|
+
} else logger.debug("HTTP Signatures are verified.", { recipient });
|
|
1402
1377
|
httpSigKey = key;
|
|
1403
1378
|
}
|
|
1404
|
-
activity = await
|
|
1379
|
+
activity = await _fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1405
1380
|
}
|
|
1406
1381
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
1407
|
-
span.setAttribute("activitypub.activity.type", (0,
|
|
1382
|
+
span.setAttribute("activitypub.activity.type", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
1408
1383
|
span.addEvent("activitypub.activity.received", {
|
|
1409
1384
|
"activitypub.activity.json": JSON.stringify(json),
|
|
1410
1385
|
"activitypub.activity.verified": activity != null,
|
|
@@ -1413,14 +1388,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1413
1388
|
"http_signatures.key_id": httpSigKey?.id?.href ?? ""
|
|
1414
1389
|
});
|
|
1415
1390
|
if (httpSigKey != null && !await require_proof.doesActorOwnKey(activity, httpSigKey, ctx)) {
|
|
1416
|
-
logger
|
|
1391
|
+
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
|
1417
1392
|
activity: json,
|
|
1418
1393
|
recipient,
|
|
1419
1394
|
keyId: httpSigKey.id?.href,
|
|
1420
1395
|
actorId: activity.actorId?.href
|
|
1421
1396
|
});
|
|
1422
1397
|
span.setStatus({
|
|
1423
|
-
code:
|
|
1398
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1424
1399
|
message: `The signer (${httpSigKey.id?.href}) and the actor (${activity.actorId?.href}) do not match.`
|
|
1425
1400
|
});
|
|
1426
1401
|
return new Response("The signer and the actor do not match.", {
|
|
@@ -1480,11 +1455,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1480
1455
|
* @since 1.8.0
|
|
1481
1456
|
*/
|
|
1482
1457
|
const handleCustomCollection = exceptWrapper(_handleCustomCollection);
|
|
1483
|
-
async function _handleCustomCollection(request, { name, values, context
|
|
1458
|
+
async function _handleCustomCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1484
1459
|
verifyDefined(callbacks);
|
|
1485
|
-
await authIfNeeded(context
|
|
1460
|
+
await authIfNeeded(context, values, callbacks);
|
|
1486
1461
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1487
|
-
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);
|
|
1488
1463
|
}
|
|
1489
1464
|
/**
|
|
1490
1465
|
* Handles an ordered collection request.
|
|
@@ -1498,11 +1473,11 @@ async function _handleCustomCollection(request, { name, values, context: context
|
|
|
1498
1473
|
* @since 1.8.0
|
|
1499
1474
|
*/
|
|
1500
1475
|
const handleOrderedCollection = exceptWrapper(_handleOrderedCollection);
|
|
1501
|
-
async function _handleOrderedCollection(request, { name, values, context
|
|
1476
|
+
async function _handleOrderedCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1502
1477
|
verifyDefined(callbacks);
|
|
1503
|
-
await authIfNeeded(context
|
|
1478
|
+
await authIfNeeded(context, values, callbacks);
|
|
1504
1479
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1505
|
-
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);
|
|
1506
1481
|
}
|
|
1507
1482
|
/**
|
|
1508
1483
|
* Handling custom collections with support for pagination and filtering.
|
|
@@ -1552,17 +1527,17 @@ var CustomCollectionHandler = class {
|
|
|
1552
1527
|
* @param CollectionPage The CollectionPage constructor.
|
|
1553
1528
|
* @param filterPredicate Optional filter predicate for items.
|
|
1554
1529
|
*/
|
|
1555
|
-
constructor(name, values, context
|
|
1556
|
-
this.name = name;
|
|
1530
|
+
constructor(name$2, values, context, callbacks, tracerProvider = _opentelemetry_api.trace.getTracerProvider(), Collection, CollectionPage, filterPredicate) {
|
|
1531
|
+
this.name = name$2;
|
|
1557
1532
|
this.values = values;
|
|
1558
|
-
this.context = context
|
|
1533
|
+
this.context = context;
|
|
1559
1534
|
this.callbacks = callbacks;
|
|
1560
1535
|
this.tracerProvider = tracerProvider;
|
|
1561
|
-
this.Collection = Collection
|
|
1562
|
-
this.CollectionPage = CollectionPage
|
|
1536
|
+
this.Collection = Collection;
|
|
1537
|
+
this.CollectionPage = CollectionPage;
|
|
1563
1538
|
this.filterPredicate = filterPredicate;
|
|
1564
1539
|
this.name = this.name.trim().replace(/\s+/g, "_");
|
|
1565
|
-
this.#tracer = this.tracerProvider.getTracer(require_http.
|
|
1540
|
+
this.#tracer = this.tracerProvider.getTracer(require_http.name, require_http.version);
|
|
1566
1541
|
this.#id = new URL(this.context.url);
|
|
1567
1542
|
this.#dispatcher = callbacks.dispatcher.bind(callbacks);
|
|
1568
1543
|
}
|
|
@@ -1591,8 +1566,8 @@ var CustomCollectionHandler = class {
|
|
|
1591
1566
|
*/
|
|
1592
1567
|
async getCollection(cursor = null) {
|
|
1593
1568
|
if (cursor !== null) {
|
|
1594
|
-
const props
|
|
1595
|
-
return new this.CollectionPage(props
|
|
1569
|
+
const props = await this.getPageProps(cursor);
|
|
1570
|
+
return new this.CollectionPage(props);
|
|
1596
1571
|
}
|
|
1597
1572
|
const firstCursor = await this.firstCursor;
|
|
1598
1573
|
const props = typeof firstCursor === "string" ? await this.getProps(firstCursor) : await this.getPropsWithoutCursor();
|
|
@@ -1653,7 +1628,7 @@ var CustomCollectionHandler = class {
|
|
|
1653
1628
|
* @returns A promise that resolves to the page items.
|
|
1654
1629
|
*/
|
|
1655
1630
|
async getPages({ cursor = null, totalItems = null }) {
|
|
1656
|
-
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({
|
|
1657
1632
|
cursor,
|
|
1658
1633
|
totalItems
|
|
1659
1634
|
}));
|
|
@@ -1686,7 +1661,7 @@ var CustomCollectionHandler = class {
|
|
|
1686
1661
|
} catch (e) {
|
|
1687
1662
|
const message = e instanceof Error ? e.message : String(e);
|
|
1688
1663
|
span.setStatus({
|
|
1689
|
-
code:
|
|
1664
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1690
1665
|
message
|
|
1691
1666
|
});
|
|
1692
1667
|
throw e;
|
|
@@ -1740,7 +1715,7 @@ var CustomCollectionHandler = class {
|
|
|
1740
1715
|
* @param value The total items count or a promise that resolves to it.
|
|
1741
1716
|
*/
|
|
1742
1717
|
set totalItems(value) {
|
|
1743
|
-
const toNumber = (value
|
|
1718
|
+
const toNumber = (value) => value == null ? null : Number(value);
|
|
1744
1719
|
this.#totalItems = value instanceof Promise ? value.then(toNumber) : Promise.resolve(toNumber(value));
|
|
1745
1720
|
}
|
|
1746
1721
|
/**
|
|
@@ -1804,9 +1779,9 @@ const verifyDefined = (callbacks) => {
|
|
|
1804
1779
|
* @throws {UnauthorizedError} If authorization fails.
|
|
1805
1780
|
* @since 1.8.0
|
|
1806
1781
|
*/
|
|
1807
|
-
const authIfNeeded = async (context
|
|
1782
|
+
const authIfNeeded = async (context, values, { authorizePredicate: authorize = void 0 }) => {
|
|
1808
1783
|
if (authorize === void 0) return;
|
|
1809
|
-
if (!await authorize(context
|
|
1784
|
+
if (!await authorize(context, values)) throw new UnauthorizedError();
|
|
1810
1785
|
};
|
|
1811
1786
|
/**
|
|
1812
1787
|
* Appends a cursor parameter to a URL if the cursor exists.
|
|
@@ -1892,7 +1867,6 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
1892
1867
|
response.headers.set("Vary", "Accept");
|
|
1893
1868
|
return response;
|
|
1894
1869
|
}
|
|
1895
|
-
|
|
1896
1870
|
//#endregion
|
|
1897
1871
|
//#region src/nodeinfo/handler.ts
|
|
1898
1872
|
/**
|
|
@@ -1902,10 +1876,9 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
1902
1876
|
* @param parameters The parameters for handling the request.
|
|
1903
1877
|
* @returns The response to the request.
|
|
1904
1878
|
*/
|
|
1905
|
-
async function handleNodeInfo(_request, { context
|
|
1906
|
-
const promise = nodeInfoDispatcher(context
|
|
1907
|
-
const
|
|
1908
|
-
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);
|
|
1909
1882
|
return new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\"" } });
|
|
1910
1883
|
}
|
|
1911
1884
|
/**
|
|
@@ -1915,22 +1888,20 @@ async function handleNodeInfo(_request, { context: context$2, nodeInfoDispatcher
|
|
|
1915
1888
|
* @param context The request context.
|
|
1916
1889
|
* @returns The response to the request.
|
|
1917
1890
|
*/
|
|
1918
|
-
function handleNodeInfoJrd(_request, context
|
|
1891
|
+
function handleNodeInfoJrd(_request, context) {
|
|
1919
1892
|
const links = [];
|
|
1920
1893
|
try {
|
|
1921
1894
|
links.push({
|
|
1922
1895
|
rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
|
|
1923
|
-
href: context
|
|
1896
|
+
href: context.getNodeInfoUri().href,
|
|
1924
1897
|
type: "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\""
|
|
1925
1898
|
});
|
|
1926
1899
|
} catch (e) {
|
|
1927
1900
|
if (!(e instanceof RouterError)) throw e;
|
|
1928
1901
|
}
|
|
1929
|
-
const
|
|
1930
|
-
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" } });
|
|
1931
1903
|
return Promise.resolve(response);
|
|
1932
1904
|
}
|
|
1933
|
-
|
|
1934
1905
|
//#endregion
|
|
1935
1906
|
//#region src/federation/retry.ts
|
|
1936
1907
|
/**
|
|
@@ -1961,7 +1932,6 @@ function createExponentialBackoffPolicy(options = {}) {
|
|
|
1961
1932
|
return Temporal.Duration.compare(delay, maxDelay) > 0 ? maxDelay : delay;
|
|
1962
1933
|
};
|
|
1963
1934
|
}
|
|
1964
|
-
|
|
1965
1935
|
//#endregion
|
|
1966
1936
|
//#region src/federation/send.ts
|
|
1967
1937
|
/**
|
|
@@ -1998,10 +1968,9 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
|
|
|
1998
1968
|
* @throws {Error} If the activity fails to send.
|
|
1999
1969
|
*/
|
|
2000
1970
|
function sendActivity(options) {
|
|
2001
|
-
const tracerProvider = options.tracerProvider ??
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
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,
|
|
2005
1974
|
attributes: { "activitypub.shared_inbox": options.sharedInbox ?? false }
|
|
2006
1975
|
}, async (span) => {
|
|
2007
1976
|
if (options.activityId != null) span.setAttribute("activitypub.activity.id", options.activityId);
|
|
@@ -2013,7 +1982,7 @@ function sendActivity(options) {
|
|
|
2013
1982
|
}, span);
|
|
2014
1983
|
} catch (e) {
|
|
2015
1984
|
span.setStatus({
|
|
2016
|
-
code:
|
|
1985
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2017
1986
|
message: String(e)
|
|
2018
1987
|
});
|
|
2019
1988
|
throw e;
|
|
@@ -2051,7 +2020,7 @@ async function readLimitedResponseBody(response, maxBytes) {
|
|
|
2051
2020
|
return result;
|
|
2052
2021
|
}
|
|
2053
2022
|
async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }, span) {
|
|
2054
|
-
const logger
|
|
2023
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2055
2024
|
"fedify",
|
|
2056
2025
|
"federation",
|
|
2057
2026
|
"outbox"
|
|
@@ -2068,7 +2037,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2068
2037
|
rsaKey = key;
|
|
2069
2038
|
break;
|
|
2070
2039
|
}
|
|
2071
|
-
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.", {
|
|
2072
2041
|
inbox: inbox.href,
|
|
2073
2042
|
keys: keys.map((pair) => ({
|
|
2074
2043
|
keyId: pair.keyId.href,
|
|
@@ -2082,7 +2051,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2082
2051
|
specDeterminer
|
|
2083
2052
|
});
|
|
2084
2053
|
} catch (error) {
|
|
2085
|
-
logger
|
|
2054
|
+
logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
|
|
2086
2055
|
activityId,
|
|
2087
2056
|
inbox: inbox.href,
|
|
2088
2057
|
error
|
|
@@ -2096,7 +2065,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2096
2065
|
} catch (_) {
|
|
2097
2066
|
error = "";
|
|
2098
2067
|
}
|
|
2099
|
-
logger
|
|
2068
|
+
logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
|
|
2100
2069
|
activityId,
|
|
2101
2070
|
inbox: inbox.href,
|
|
2102
2071
|
status: response.status,
|
|
@@ -2148,10 +2117,9 @@ var SendActivityError = class extends Error {
|
|
|
2148
2117
|
this.responseBody = responseBody;
|
|
2149
2118
|
}
|
|
2150
2119
|
};
|
|
2151
|
-
|
|
2152
2120
|
//#endregion
|
|
2153
2121
|
//#region src/federation/webfinger.ts
|
|
2154
|
-
const logger = (0,
|
|
2122
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2155
2123
|
"fedify",
|
|
2156
2124
|
"webfinger",
|
|
2157
2125
|
"server"
|
|
@@ -2165,14 +2133,14 @@ const logger = (0, __logtape_logtape.getLogger)([
|
|
|
2165
2133
|
*/
|
|
2166
2134
|
async function handleWebFinger(request, options) {
|
|
2167
2135
|
if (options.tracer == null) return await handleWebFingerInternal(request, options);
|
|
2168
|
-
return await options.tracer.startActiveSpan("webfinger.handle", { kind:
|
|
2136
|
+
return await options.tracer.startActiveSpan("webfinger.handle", { kind: _opentelemetry_api.SpanKind.SERVER }, async (span) => {
|
|
2169
2137
|
try {
|
|
2170
2138
|
const response = await handleWebFingerInternal(request, options);
|
|
2171
|
-
span.setStatus({ code: response.ok ?
|
|
2139
|
+
span.setStatus({ code: response.ok ? _opentelemetry_api.SpanStatusCode.UNSET : _opentelemetry_api.SpanStatusCode.ERROR });
|
|
2172
2140
|
return response;
|
|
2173
2141
|
} catch (error) {
|
|
2174
2142
|
span.setStatus({
|
|
2175
|
-
code:
|
|
2143
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2176
2144
|
message: String(error)
|
|
2177
2145
|
});
|
|
2178
2146
|
throw error;
|
|
@@ -2181,12 +2149,12 @@ async function handleWebFinger(request, options) {
|
|
|
2181
2149
|
}
|
|
2182
2150
|
});
|
|
2183
2151
|
}
|
|
2184
|
-
async function handleWebFingerInternal(request, { context
|
|
2152
|
+
async function handleWebFingerInternal(request, { context, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
|
|
2185
2153
|
if (actorDispatcher == null) {
|
|
2186
2154
|
logger.error("Actor dispatcher is not set.");
|
|
2187
2155
|
return await onNotFound(request);
|
|
2188
2156
|
}
|
|
2189
|
-
const resource = context
|
|
2157
|
+
const resource = context.url.searchParams.get("resource");
|
|
2190
2158
|
if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
|
|
2191
2159
|
span?.setAttribute("webfinger.resource", resource);
|
|
2192
2160
|
let resourceUrl;
|
|
@@ -2202,26 +2170,26 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2202
2170
|
logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
|
|
2203
2171
|
return username;
|
|
2204
2172
|
}
|
|
2205
|
-
const identifier
|
|
2206
|
-
if (identifier
|
|
2173
|
+
const identifier = await actorHandleMapper(context, username);
|
|
2174
|
+
if (identifier == null) {
|
|
2207
2175
|
logger.error("Actor {username} not found.", { username });
|
|
2208
2176
|
return null;
|
|
2209
2177
|
}
|
|
2210
|
-
return identifier
|
|
2178
|
+
return identifier;
|
|
2211
2179
|
}
|
|
2212
2180
|
let identifier = null;
|
|
2213
|
-
const uriParsed = context
|
|
2181
|
+
const uriParsed = context.parseUri(resourceUrl);
|
|
2214
2182
|
if (uriParsed?.type != "actor") {
|
|
2215
2183
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
2216
2184
|
if (match == null) {
|
|
2217
|
-
const result = await actorAliasMapper?.(context
|
|
2185
|
+
const result = await actorAliasMapper?.(context, resourceUrl);
|
|
2218
2186
|
if (result == null) return await onNotFound(request);
|
|
2219
2187
|
if ("identifier" in result) identifier = result.identifier;
|
|
2220
2188
|
else identifier = await mapUsernameToIdentifier(result.username);
|
|
2221
2189
|
} else {
|
|
2222
2190
|
const portMatch = /:\d+$/.exec(match[2]);
|
|
2223
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];
|
|
2224
|
-
if (normalizedHost != context
|
|
2192
|
+
if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
|
|
2225
2193
|
else {
|
|
2226
2194
|
identifier = await mapUsernameToIdentifier(match[1]);
|
|
2227
2195
|
resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
|
|
@@ -2229,17 +2197,17 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2229
2197
|
}
|
|
2230
2198
|
} else identifier = uriParsed.identifier;
|
|
2231
2199
|
if (identifier == null) return await onNotFound(request);
|
|
2232
|
-
const actor = await actorDispatcher(context
|
|
2200
|
+
const actor = await actorDispatcher(context, identifier);
|
|
2233
2201
|
if (actor == null) {
|
|
2234
2202
|
logger.error("Actor {identifier} not found.", { identifier });
|
|
2235
2203
|
return await onNotFound(request);
|
|
2236
2204
|
}
|
|
2237
2205
|
const links = [{
|
|
2238
2206
|
rel: "self",
|
|
2239
|
-
href: context
|
|
2207
|
+
href: context.getActorUri(identifier).href,
|
|
2240
2208
|
type: "application/activity+json"
|
|
2241
2209
|
}];
|
|
2242
|
-
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({
|
|
2243
2211
|
rel: url.rel ?? "http://webfinger.net/rel/profile-page",
|
|
2244
2212
|
href: url.href.href,
|
|
2245
2213
|
type: url.mediaType == null ? void 0 : url.mediaType
|
|
@@ -2257,16 +2225,16 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2257
2225
|
});
|
|
2258
2226
|
}
|
|
2259
2227
|
if (webFingerLinksDispatcher != null) {
|
|
2260
|
-
const customLinks = await webFingerLinksDispatcher(context
|
|
2228
|
+
const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
|
|
2261
2229
|
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
2262
2230
|
}
|
|
2263
2231
|
const aliases = [];
|
|
2264
2232
|
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
|
|
2265
|
-
aliases.push(`acct:${actor.preferredUsername}@${host ?? context
|
|
2266
|
-
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}`);
|
|
2267
2235
|
}
|
|
2268
|
-
if (resourceUrl.href !== context
|
|
2269
|
-
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}`)) {
|
|
2270
2238
|
const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
|
|
2271
2239
|
aliases.push(`acct:${username}@${host}`);
|
|
2272
2240
|
}
|
|
@@ -2280,7 +2248,6 @@ async function handleWebFingerInternal(request, { context: context$2, host, acto
|
|
|
2280
2248
|
"Access-Control-Allow-Origin": "*"
|
|
2281
2249
|
} });
|
|
2282
2250
|
}
|
|
2283
|
-
|
|
2284
2251
|
//#endregion
|
|
2285
2252
|
//#region src/federation/middleware.ts
|
|
2286
2253
|
/**
|
|
@@ -2374,7 +2341,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2374
2341
|
this.allowPrivateAddress = allowPrivateAddress ?? false;
|
|
2375
2342
|
this.documentLoaderFactory = options.documentLoaderFactory ?? ((opts) => {
|
|
2376
2343
|
return require_kv_cache.kvCache({
|
|
2377
|
-
loader: (0,
|
|
2344
|
+
loader: (0, _fedify_vocab_runtime.getDocumentLoader)({
|
|
2378
2345
|
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
2379
2346
|
userAgent: opts?.userAgent ?? userAgent
|
|
2380
2347
|
}),
|
|
@@ -2401,35 +2368,35 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2401
2368
|
this.firstKnock = options.firstKnock;
|
|
2402
2369
|
}
|
|
2403
2370
|
get tracerProvider() {
|
|
2404
|
-
return this._tracerProvider ??
|
|
2371
|
+
return this._tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
2405
2372
|
}
|
|
2406
2373
|
_initializeRouter() {
|
|
2407
2374
|
this.router.add("/.well-known/webfinger", "webfinger");
|
|
2408
2375
|
this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
|
|
2409
2376
|
}
|
|
2410
2377
|
_getTracer() {
|
|
2411
|
-
return this.tracerProvider.getTracer(require_http.
|
|
2378
|
+
return this.tracerProvider.getTracer(require_http.name, require_http.version);
|
|
2412
2379
|
}
|
|
2413
2380
|
async _startQueueInternal(ctxData, signal, queue) {
|
|
2414
2381
|
if (this.inboxQueue == null && this.outboxQueue == null) return;
|
|
2415
|
-
const logger
|
|
2382
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2416
2383
|
"fedify",
|
|
2417
2384
|
"federation",
|
|
2418
2385
|
"queue"
|
|
2419
2386
|
]);
|
|
2420
2387
|
const promises = [];
|
|
2421
2388
|
if (this.inboxQueue != null && (queue == null || queue === "inbox") && !this.inboxQueueStarted) {
|
|
2422
|
-
logger
|
|
2389
|
+
logger.debug("Starting an inbox task worker.");
|
|
2423
2390
|
this.inboxQueueStarted = true;
|
|
2424
2391
|
promises.push(this.inboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2425
2392
|
}
|
|
2426
2393
|
if (this.outboxQueue != null && this.outboxQueue !== this.inboxQueue && (queue == null || queue === "outbox") && !this.outboxQueueStarted) {
|
|
2427
|
-
logger
|
|
2394
|
+
logger.debug("Starting an outbox task worker.");
|
|
2428
2395
|
this.outboxQueueStarted = true;
|
|
2429
2396
|
promises.push(this.outboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2430
2397
|
}
|
|
2431
2398
|
if (this.fanoutQueue != null && this.fanoutQueue !== this.inboxQueue && this.fanoutQueue !== this.outboxQueue && (queue == null || queue === "fanout") && !this.fanoutQueueStarted) {
|
|
2432
|
-
logger
|
|
2399
|
+
logger.debug("Starting a fanout task worker.");
|
|
2433
2400
|
this.fanoutQueueStarted = true;
|
|
2434
2401
|
promises.push(this.fanoutQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2435
2402
|
}
|
|
@@ -2437,14 +2404,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2437
2404
|
}
|
|
2438
2405
|
processQueuedTask(contextData, message) {
|
|
2439
2406
|
const tracer = this._getTracer();
|
|
2440
|
-
const extractedContext =
|
|
2441
|
-
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 () => {
|
|
2442
2409
|
if (message.type === "fanout") await tracer.startActiveSpan("activitypub.fanout", {
|
|
2443
|
-
kind:
|
|
2410
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
2444
2411
|
attributes: { "activitypub.activity.type": message.activityType }
|
|
2445
2412
|
}, extractedContext, async (span) => {
|
|
2446
2413
|
const spanCtx = span.spanContext();
|
|
2447
|
-
return await (0,
|
|
2414
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2448
2415
|
traceId: spanCtx.traceId,
|
|
2449
2416
|
spanId: spanCtx.spanId
|
|
2450
2417
|
}, async () => {
|
|
@@ -2453,7 +2420,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2453
2420
|
await this.#listenFanoutMessage(contextData, message);
|
|
2454
2421
|
} catch (e) {
|
|
2455
2422
|
span.setStatus({
|
|
2456
|
-
code:
|
|
2423
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2457
2424
|
message: String(e)
|
|
2458
2425
|
});
|
|
2459
2426
|
throw e;
|
|
@@ -2463,14 +2430,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2463
2430
|
});
|
|
2464
2431
|
});
|
|
2465
2432
|
else if (message.type === "outbox") await tracer.startActiveSpan("activitypub.outbox", {
|
|
2466
|
-
kind:
|
|
2433
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
2467
2434
|
attributes: {
|
|
2468
2435
|
"activitypub.activity.type": message.activityType,
|
|
2469
2436
|
"activitypub.activity.retries": message.attempt
|
|
2470
2437
|
}
|
|
2471
2438
|
}, extractedContext, async (span) => {
|
|
2472
2439
|
const spanCtx = span.spanContext();
|
|
2473
|
-
return await (0,
|
|
2440
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2474
2441
|
traceId: spanCtx.traceId,
|
|
2475
2442
|
spanId: spanCtx.spanId
|
|
2476
2443
|
}, async () => {
|
|
@@ -2479,7 +2446,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2479
2446
|
await this.#listenOutboxMessage(contextData, message, span);
|
|
2480
2447
|
} catch (e) {
|
|
2481
2448
|
span.setStatus({
|
|
2482
|
-
code:
|
|
2449
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2483
2450
|
message: String(e)
|
|
2484
2451
|
});
|
|
2485
2452
|
throw e;
|
|
@@ -2489,11 +2456,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2489
2456
|
});
|
|
2490
2457
|
});
|
|
2491
2458
|
else if (message.type === "inbox") await tracer.startActiveSpan("activitypub.inbox", {
|
|
2492
|
-
kind:
|
|
2459
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
2493
2460
|
attributes: { "activitypub.shared_inbox": message.identifier == null }
|
|
2494
2461
|
}, extractedContext, async (span) => {
|
|
2495
2462
|
const spanCtx = span.spanContext();
|
|
2496
|
-
return await (0,
|
|
2463
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2497
2464
|
traceId: spanCtx.traceId,
|
|
2498
2465
|
spanId: spanCtx.spanId
|
|
2499
2466
|
}, async () => {
|
|
@@ -2501,7 +2468,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2501
2468
|
await this.#listenInboxMessage(contextData, message, span);
|
|
2502
2469
|
} catch (e) {
|
|
2503
2470
|
span.setStatus({
|
|
2504
|
-
code:
|
|
2471
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2505
2472
|
message: String(e)
|
|
2506
2473
|
});
|
|
2507
2474
|
throw e;
|
|
@@ -2513,12 +2480,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2513
2480
|
});
|
|
2514
2481
|
}
|
|
2515
2482
|
async #listenFanoutMessage(data, message) {
|
|
2516
|
-
|
|
2483
|
+
(0, _logtape_logtape.getLogger)([
|
|
2517
2484
|
"fedify",
|
|
2518
2485
|
"federation",
|
|
2519
2486
|
"fanout"
|
|
2520
|
-
])
|
|
2521
|
-
logger$1.debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2487
|
+
]).debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2522
2488
|
activityId: message.activityId,
|
|
2523
2489
|
inboxes: globalThis.Object.keys(message.inboxes).length
|
|
2524
2490
|
});
|
|
@@ -2526,7 +2492,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2526
2492
|
keyId: new URL(keyId),
|
|
2527
2493
|
privateKey: await require_http.importJwk(privateKey, "private")
|
|
2528
2494
|
})));
|
|
2529
|
-
const activity = await
|
|
2495
|
+
const activity = await _fedify_vocab.Activity.fromJsonLd(message.activity, {
|
|
2530
2496
|
contextLoader: this.contextLoaderFactory({
|
|
2531
2497
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
2532
2498
|
userAgent: this.userAgent
|
|
@@ -2537,18 +2503,18 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2537
2503
|
}),
|
|
2538
2504
|
tracerProvider: this.tracerProvider
|
|
2539
2505
|
});
|
|
2540
|
-
const context
|
|
2506
|
+
const context = this.#createContext(new URL(message.baseUrl), data, { documentLoader: this.documentLoaderFactory({
|
|
2541
2507
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
2542
2508
|
userAgent: this.userAgent
|
|
2543
2509
|
}) });
|
|
2544
2510
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
2545
2511
|
collectionSync: message.collectionSync,
|
|
2546
2512
|
orderingKey: message.orderingKey,
|
|
2547
|
-
context
|
|
2513
|
+
context
|
|
2548
2514
|
});
|
|
2549
2515
|
}
|
|
2550
2516
|
async #listenOutboxMessage(_, message, span) {
|
|
2551
|
-
const logger
|
|
2517
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2552
2518
|
"fedify",
|
|
2553
2519
|
"federation",
|
|
2554
2520
|
"outbox"
|
|
@@ -2585,25 +2551,25 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2585
2551
|
});
|
|
2586
2552
|
} catch (error) {
|
|
2587
2553
|
span.setStatus({
|
|
2588
|
-
code:
|
|
2554
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2589
2555
|
message: String(error)
|
|
2590
2556
|
});
|
|
2591
2557
|
const loaderOptions = this.#getLoaderOptions(message.baseUrl);
|
|
2592
|
-
const activity = await
|
|
2558
|
+
const activity = await _fedify_vocab.Activity.fromJsonLd(message.activity, {
|
|
2593
2559
|
contextLoader: this.contextLoaderFactory(loaderOptions),
|
|
2594
2560
|
documentLoader: rsaKeyPair == null ? this.documentLoaderFactory(loaderOptions) : this.authenticatedDocumentLoaderFactory(rsaKeyPair, loaderOptions),
|
|
2595
2561
|
tracerProvider: this.tracerProvider
|
|
2596
2562
|
});
|
|
2597
2563
|
try {
|
|
2598
2564
|
await this.onOutboxError?.(error, activity);
|
|
2599
|
-
} catch (error
|
|
2600
|
-
logger
|
|
2565
|
+
} catch (error) {
|
|
2566
|
+
logger.error("An unexpected error occurred in onError handler:\n{error}", {
|
|
2601
2567
|
...logData,
|
|
2602
|
-
error
|
|
2568
|
+
error
|
|
2603
2569
|
});
|
|
2604
2570
|
}
|
|
2605
2571
|
if (error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode)) {
|
|
2606
|
-
logger
|
|
2572
|
+
logger.warn("Permanent delivery failure for activity {activityId} to {inbox} ({status}); not retrying.", {
|
|
2607
2573
|
...logData,
|
|
2608
2574
|
status: error.statusCode
|
|
2609
2575
|
});
|
|
@@ -2619,13 +2585,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2619
2585
|
try {
|
|
2620
2586
|
return [new URL(id)];
|
|
2621
2587
|
} catch {
|
|
2622
|
-
logger
|
|
2588
|
+
logger.warn("Invalid actorId URL in OutboxMessage: {id}", { id });
|
|
2623
2589
|
return [];
|
|
2624
2590
|
}
|
|
2625
2591
|
})
|
|
2626
2592
|
});
|
|
2627
2593
|
} catch (handlerError) {
|
|
2628
|
-
logger
|
|
2594
|
+
logger.error("An unexpected error occurred in outboxPermanentFailureHandler:\n{error}", {
|
|
2629
2595
|
...logData,
|
|
2630
2596
|
error: handlerError
|
|
2631
2597
|
});
|
|
@@ -2634,7 +2600,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2634
2600
|
return;
|
|
2635
2601
|
}
|
|
2636
2602
|
if (this.outboxQueue?.nativeRetrial) {
|
|
2637
|
-
logger
|
|
2603
|
+
logger.error("Failed to send activity {activityId} to {inbox}; backend will handle retry:\n{error}", {
|
|
2638
2604
|
...logData,
|
|
2639
2605
|
error
|
|
2640
2606
|
});
|
|
@@ -2645,7 +2611,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2645
2611
|
attempts: message.attempt
|
|
2646
2612
|
});
|
|
2647
2613
|
if (delay != null) {
|
|
2648
|
-
logger
|
|
2614
|
+
logger.error("Failed to send activity {activityId} to {inbox} (attempt #{attempt}); retry...:\n{error}", {
|
|
2649
2615
|
...logData,
|
|
2650
2616
|
error
|
|
2651
2617
|
});
|
|
@@ -2653,39 +2619,38 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2653
2619
|
...message,
|
|
2654
2620
|
attempt: message.attempt + 1
|
|
2655
2621
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2656
|
-
} else logger
|
|
2622
|
+
} else logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
2657
2623
|
...logData,
|
|
2658
2624
|
error
|
|
2659
2625
|
});
|
|
2660
2626
|
return;
|
|
2661
2627
|
}
|
|
2662
|
-
logger
|
|
2628
|
+
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
2663
2629
|
}
|
|
2664
2630
|
async #listenInboxMessage(ctxData, message, span) {
|
|
2665
|
-
const logger
|
|
2631
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2666
2632
|
"fedify",
|
|
2667
2633
|
"federation",
|
|
2668
2634
|
"inbox"
|
|
2669
2635
|
]);
|
|
2670
2636
|
const baseUrl = new URL(message.baseUrl);
|
|
2671
|
-
let context
|
|
2672
|
-
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 }) });
|
|
2673
2639
|
else if (this.sharedInboxKeyDispatcher != null) {
|
|
2674
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
2675
|
-
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) });
|
|
2676
2642
|
}
|
|
2677
|
-
const activity = await
|
|
2678
|
-
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);
|
|
2679
2645
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2680
2646
|
const cacheKey = activity.id == null ? null : [
|
|
2681
2647
|
...this.kvPrefixes.activityIdempotence,
|
|
2682
|
-
context
|
|
2648
|
+
context.origin,
|
|
2683
2649
|
activity.id.href
|
|
2684
2650
|
];
|
|
2685
2651
|
if (cacheKey != null) {
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
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.", {
|
|
2689
2654
|
activityId: activity.id?.href,
|
|
2690
2655
|
activity: message.activity,
|
|
2691
2656
|
recipient: message.identifier
|
|
@@ -2693,32 +2658,32 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2693
2658
|
return;
|
|
2694
2659
|
}
|
|
2695
2660
|
}
|
|
2696
|
-
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) => {
|
|
2697
2662
|
const dispatched = this.inboxListeners?.dispatchWithClass(activity);
|
|
2698
2663
|
if (dispatched == null) {
|
|
2699
|
-
logger
|
|
2664
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
2700
2665
|
activityId: activity.id?.href,
|
|
2701
2666
|
activity: message.activity,
|
|
2702
2667
|
recipient: message.identifier,
|
|
2703
2668
|
trial: message.attempt
|
|
2704
2669
|
});
|
|
2705
|
-
span
|
|
2706
|
-
code:
|
|
2707
|
-
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}`
|
|
2708
2673
|
});
|
|
2709
|
-
span
|
|
2674
|
+
span.end();
|
|
2710
2675
|
return;
|
|
2711
2676
|
}
|
|
2712
2677
|
const { class: cls, listener } = dispatched;
|
|
2713
|
-
span
|
|
2678
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
2714
2679
|
try {
|
|
2715
|
-
await listener(context
|
|
2680
|
+
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, (0, _fedify_vocab.getTypeId)(activity).href), activity);
|
|
2716
2681
|
} catch (error) {
|
|
2717
2682
|
try {
|
|
2718
|
-
await this.inboxErrorHandler?.(context
|
|
2719
|
-
} catch (error
|
|
2720
|
-
logger
|
|
2721
|
-
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,
|
|
2722
2687
|
trial: message.attempt,
|
|
2723
2688
|
activityId: activity.id?.href,
|
|
2724
2689
|
activity: message.activity,
|
|
@@ -2726,17 +2691,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2726
2691
|
});
|
|
2727
2692
|
}
|
|
2728
2693
|
if (this.inboxQueue?.nativeRetrial) {
|
|
2729
|
-
logger
|
|
2694
|
+
logger.error("Failed to process the incoming activity {activityId}; backend will handle retry:\n{error}", {
|
|
2730
2695
|
error,
|
|
2731
2696
|
activityId: activity.id?.href,
|
|
2732
2697
|
activity: message.activity,
|
|
2733
2698
|
recipient: message.identifier
|
|
2734
2699
|
});
|
|
2735
|
-
span
|
|
2736
|
-
code:
|
|
2700
|
+
span.setStatus({
|
|
2701
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2737
2702
|
message: String(error)
|
|
2738
2703
|
});
|
|
2739
|
-
span
|
|
2704
|
+
span.end();
|
|
2740
2705
|
throw error;
|
|
2741
2706
|
}
|
|
2742
2707
|
const delay = this.inboxRetryPolicy({
|
|
@@ -2744,7 +2709,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2744
2709
|
attempts: message.attempt
|
|
2745
2710
|
});
|
|
2746
2711
|
if (delay != null) {
|
|
2747
|
-
logger
|
|
2712
|
+
logger.error("Failed to process the incoming activity {activityId} (attempt #{attempt}); retry...:\n{error}", {
|
|
2748
2713
|
error,
|
|
2749
2714
|
attempt: message.attempt,
|
|
2750
2715
|
activityId: activity.id?.href,
|
|
@@ -2755,26 +2720,26 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2755
2720
|
...message,
|
|
2756
2721
|
attempt: message.attempt + 1
|
|
2757
2722
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2758
|
-
} else logger
|
|
2723
|
+
} else logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
2759
2724
|
error,
|
|
2760
2725
|
activityId: activity.id?.href,
|
|
2761
2726
|
activity: message.activity,
|
|
2762
2727
|
recipient: message.identifier
|
|
2763
2728
|
});
|
|
2764
|
-
span
|
|
2765
|
-
code:
|
|
2729
|
+
span.setStatus({
|
|
2730
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2766
2731
|
message: String(error)
|
|
2767
2732
|
});
|
|
2768
|
-
span
|
|
2733
|
+
span.end();
|
|
2769
2734
|
return;
|
|
2770
2735
|
}
|
|
2771
2736
|
if (cacheKey != null) await this.kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
2772
|
-
logger
|
|
2737
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
2773
2738
|
activityId: activity.id?.href,
|
|
2774
2739
|
activity: message.activity,
|
|
2775
2740
|
recipient: message.identifier
|
|
2776
2741
|
});
|
|
2777
|
-
span
|
|
2742
|
+
span.end();
|
|
2778
2743
|
});
|
|
2779
2744
|
}
|
|
2780
2745
|
startQueue(contextData, options = {}) {
|
|
@@ -2818,7 +2783,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2818
2783
|
};
|
|
2819
2784
|
}
|
|
2820
2785
|
async sendActivity(keys, inboxes, activity, options) {
|
|
2821
|
-
const logger
|
|
2786
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2822
2787
|
"fedify",
|
|
2823
2788
|
"federation",
|
|
2824
2789
|
"outbox"
|
|
@@ -2852,7 +2817,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2852
2817
|
format: "compact",
|
|
2853
2818
|
contextLoader
|
|
2854
2819
|
});
|
|
2855
|
-
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.", {
|
|
2856
2821
|
activityId,
|
|
2857
2822
|
keys: keys.map((pair) => ({
|
|
2858
2823
|
keyId: pair.keyId.href,
|
|
@@ -2863,7 +2828,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2863
2828
|
contextLoader,
|
|
2864
2829
|
tracerProvider: this.tracerProvider
|
|
2865
2830
|
});
|
|
2866
|
-
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.", {
|
|
2867
2832
|
activityId,
|
|
2868
2833
|
keys: keys.map((pair) => ({
|
|
2869
2834
|
keyId: pair.keyId.href,
|
|
@@ -2871,11 +2836,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2871
2836
|
}))
|
|
2872
2837
|
});
|
|
2873
2838
|
if (immediate || this.outboxQueue == null) {
|
|
2874
|
-
if (immediate) logger
|
|
2839
|
+
if (immediate) logger.debug("Sending activity immediately without queue since immediate option is set.", {
|
|
2875
2840
|
activityId: activity.id.href,
|
|
2876
2841
|
activity: jsonLd
|
|
2877
2842
|
});
|
|
2878
|
-
else logger
|
|
2843
|
+
else logger.debug("Sending activity immediately without queue since queue is not set.", {
|
|
2879
2844
|
activityId: activity.id.href,
|
|
2880
2845
|
activity: jsonLd
|
|
2881
2846
|
});
|
|
@@ -2884,7 +2849,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2884
2849
|
keys,
|
|
2885
2850
|
activity: jsonLd,
|
|
2886
2851
|
activityId: activity.id?.href,
|
|
2887
|
-
activityType: (0,
|
|
2852
|
+
activityType: (0, _fedify_vocab.getTypeId)(activity).href,
|
|
2888
2853
|
inbox: new URL(inbox),
|
|
2889
2854
|
sharedInbox: inboxes[inbox].sharedInbox,
|
|
2890
2855
|
headers: collectionSync == null ? void 0 : new Headers({ "Collection-Synchronization": await buildCollectionSynchronizationHeader(collectionSync, inboxes[inbox].actorIds) }),
|
|
@@ -2894,7 +2859,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2894
2859
|
await Promise.all(promises);
|
|
2895
2860
|
return;
|
|
2896
2861
|
}
|
|
2897
|
-
logger
|
|
2862
|
+
logger.debug("Enqueuing activity {activityId} to send later.", {
|
|
2898
2863
|
activityId: activity.id.href,
|
|
2899
2864
|
activity: jsonLd
|
|
2900
2865
|
});
|
|
@@ -2908,7 +2873,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2908
2873
|
}
|
|
2909
2874
|
if (!this.manuallyStartQueue) this._startQueueInternal(ctx.data);
|
|
2910
2875
|
const carrier = {};
|
|
2911
|
-
|
|
2876
|
+
_opentelemetry_api.propagation.inject(_opentelemetry_api.context.active(), carrier);
|
|
2912
2877
|
const messages = [];
|
|
2913
2878
|
for (const inbox in inboxes) {
|
|
2914
2879
|
const inboxOrigin = new URL(inbox).origin;
|
|
@@ -2920,7 +2885,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2920
2885
|
keys: keyJwkPairs,
|
|
2921
2886
|
activity: jsonLd,
|
|
2922
2887
|
activityId: activity.id?.href,
|
|
2923
|
-
activityType: (0,
|
|
2888
|
+
activityType: (0, _fedify_vocab.getTypeId)(activity).href,
|
|
2924
2889
|
inbox,
|
|
2925
2890
|
sharedInbox: inboxes[inbox].sharedInbox,
|
|
2926
2891
|
actorIds: [...inboxes[inbox].actorIds],
|
|
@@ -2938,10 +2903,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2938
2903
|
const { outboxQueue } = this;
|
|
2939
2904
|
if (outboxQueue.enqueueMany == null) {
|
|
2940
2905
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
2941
|
-
const
|
|
2942
|
-
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);
|
|
2943
2907
|
if (errors.length > 0) {
|
|
2944
|
-
logger
|
|
2908
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
2945
2909
|
activityId: activity.id.href,
|
|
2946
2910
|
errors
|
|
2947
2911
|
});
|
|
@@ -2950,10 +2914,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2950
2914
|
}
|
|
2951
2915
|
} else if (orderingKey != null) {
|
|
2952
2916
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
2953
|
-
const
|
|
2954
|
-
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);
|
|
2955
2918
|
if (errors.length > 0) {
|
|
2956
|
-
logger
|
|
2919
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
2957
2920
|
activityId: activity.id.href,
|
|
2958
2921
|
errors
|
|
2959
2922
|
});
|
|
@@ -2963,7 +2926,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2963
2926
|
} else try {
|
|
2964
2927
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
2965
2928
|
} catch (error) {
|
|
2966
|
-
logger
|
|
2929
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
2967
2930
|
activityId: activity.id.href,
|
|
2968
2931
|
error
|
|
2969
2932
|
});
|
|
@@ -2971,27 +2934,26 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2971
2934
|
}
|
|
2972
2935
|
}
|
|
2973
2936
|
fetch(request, options) {
|
|
2974
|
-
|
|
2975
|
-
return (0, __logtape_logtape.withContext)({ requestId }, async () => {
|
|
2937
|
+
return (0, _logtape_logtape.withContext)({ requestId: getRequestId(request) }, async () => {
|
|
2976
2938
|
const tracer = this._getTracer();
|
|
2977
2939
|
return await tracer.startActiveSpan(request.method, {
|
|
2978
|
-
kind:
|
|
2940
|
+
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
2979
2941
|
attributes: {
|
|
2980
|
-
[
|
|
2981
|
-
[
|
|
2942
|
+
[_opentelemetry_semantic_conventions.ATTR_HTTP_REQUEST_METHOD]: request.method,
|
|
2943
|
+
[_opentelemetry_semantic_conventions.ATTR_URL_FULL]: request.url
|
|
2982
2944
|
}
|
|
2983
2945
|
}, async (span) => {
|
|
2984
2946
|
const spanCtx = span.spanContext();
|
|
2985
|
-
return await (0,
|
|
2947
|
+
return await (0, _logtape_logtape.withContext)({
|
|
2986
2948
|
traceId: spanCtx.traceId,
|
|
2987
2949
|
spanId: spanCtx.spanId
|
|
2988
2950
|
}, async () => {
|
|
2989
|
-
const logger
|
|
2951
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
2990
2952
|
"fedify",
|
|
2991
2953
|
"federation",
|
|
2992
2954
|
"http"
|
|
2993
2955
|
]);
|
|
2994
|
-
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]);
|
|
2995
2957
|
let response;
|
|
2996
2958
|
try {
|
|
2997
2959
|
response = await this.#fetch(request, {
|
|
@@ -3002,11 +2964,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3002
2964
|
if (acceptsJsonLd(request)) response.headers.set("Vary", "Accept");
|
|
3003
2965
|
} catch (error) {
|
|
3004
2966
|
span.setStatus({
|
|
3005
|
-
code:
|
|
2967
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3006
2968
|
message: `${error}`
|
|
3007
2969
|
});
|
|
3008
2970
|
span.end();
|
|
3009
|
-
logger
|
|
2971
|
+
logger.error("An error occurred while serving request {method} {url}: {error}", {
|
|
3010
2972
|
method: request.method,
|
|
3011
2973
|
url: request.url,
|
|
3012
2974
|
error
|
|
@@ -3014,10 +2976,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3014
2976
|
throw error;
|
|
3015
2977
|
}
|
|
3016
2978
|
if (span.isRecording()) {
|
|
3017
|
-
span.setAttribute(
|
|
3018
|
-
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]);
|
|
3019
2981
|
span.setStatus({
|
|
3020
|
-
code: response.status >= 500 ?
|
|
2982
|
+
code: response.status >= 500 ? _opentelemetry_api.SpanStatusCode.ERROR : _opentelemetry_api.SpanStatusCode.UNSET,
|
|
3021
2983
|
message: response.statusText
|
|
3022
2984
|
});
|
|
3023
2985
|
}
|
|
@@ -3030,9 +2992,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3030
2992
|
url: request.url,
|
|
3031
2993
|
status: response.status
|
|
3032
2994
|
};
|
|
3033
|
-
if (response.status >= 500) logger
|
|
3034
|
-
else if (response.status >= 400) logger
|
|
3035
|
-
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);
|
|
3036
2998
|
return response;
|
|
3037
2999
|
});
|
|
3038
3000
|
});
|
|
@@ -3046,11 +3008,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3046
3008
|
const route = this.router.route(url.pathname);
|
|
3047
3009
|
if (route == null) return await onNotFound(request);
|
|
3048
3010
|
span.updateName(`${request.method} ${route.template}`);
|
|
3049
|
-
let context
|
|
3011
|
+
let context = this.#createContext(request, contextData);
|
|
3050
3012
|
const routeName = route.name.replace(/:.*$/, "");
|
|
3051
3013
|
switch (routeName) {
|
|
3052
3014
|
case "webfinger": return await handleWebFinger(request, {
|
|
3053
|
-
context
|
|
3015
|
+
context,
|
|
3054
3016
|
host: this.origin?.handleHost,
|
|
3055
3017
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3056
3018
|
actorHandleMapper: this.actorCallbacks?.handleMapper,
|
|
@@ -3059,19 +3021,19 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3059
3021
|
onNotFound,
|
|
3060
3022
|
tracer
|
|
3061
3023
|
});
|
|
3062
|
-
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context
|
|
3024
|
+
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context);
|
|
3063
3025
|
case "nodeInfo": return await handleNodeInfo(request, {
|
|
3064
|
-
context
|
|
3026
|
+
context,
|
|
3065
3027
|
nodeInfoDispatcher: this.nodeInfoDispatcher
|
|
3066
3028
|
});
|
|
3067
3029
|
}
|
|
3068
3030
|
if (request.method !== "POST" && !acceptsJsonLd(request)) return await onNotAcceptable(request);
|
|
3069
3031
|
switch (routeName) {
|
|
3070
3032
|
case "actor":
|
|
3071
|
-
context
|
|
3033
|
+
context = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier: route.values.identifier } });
|
|
3072
3034
|
return await handleActor(request, {
|
|
3073
3035
|
identifier: route.values.identifier,
|
|
3074
|
-
context
|
|
3036
|
+
context,
|
|
3075
3037
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3076
3038
|
authorizePredicate: this.actorCallbacks?.authorizePredicate,
|
|
3077
3039
|
onUnauthorized,
|
|
@@ -3081,13 +3043,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3081
3043
|
const typeId = route.name.replace(/^object:/, "");
|
|
3082
3044
|
const callbacks = this.objectCallbacks[typeId];
|
|
3083
3045
|
const cls = this.objectTypeIds[typeId];
|
|
3084
|
-
context
|
|
3046
|
+
context = this.#createContext(request, contextData, { invokedFromObjectDispatcher: {
|
|
3085
3047
|
cls,
|
|
3086
3048
|
values: route.values
|
|
3087
3049
|
} });
|
|
3088
3050
|
return await handleObject(request, {
|
|
3089
3051
|
values: route.values,
|
|
3090
|
-
context
|
|
3052
|
+
context,
|
|
3091
3053
|
objectDispatcher: callbacks?.dispatcher,
|
|
3092
3054
|
authorizePredicate: callbacks?.authorizePredicate,
|
|
3093
3055
|
onUnauthorized,
|
|
@@ -3097,8 +3059,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3097
3059
|
case "outbox": return await handleCollection(request, {
|
|
3098
3060
|
name: "outbox",
|
|
3099
3061
|
identifier: route.values.identifier,
|
|
3100
|
-
uriGetter: context
|
|
3101
|
-
context
|
|
3062
|
+
uriGetter: context.getOutboxUri.bind(context),
|
|
3063
|
+
context,
|
|
3102
3064
|
collectionCallbacks: this.outboxCallbacks,
|
|
3103
3065
|
tracerProvider: this.tracerProvider,
|
|
3104
3066
|
onUnauthorized,
|
|
@@ -3108,24 +3070,24 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3108
3070
|
if (request.method !== "POST") return await handleCollection(request, {
|
|
3109
3071
|
name: "inbox",
|
|
3110
3072
|
identifier: route.values.identifier,
|
|
3111
|
-
uriGetter: context
|
|
3112
|
-
context
|
|
3073
|
+
uriGetter: context.getInboxUri.bind(context),
|
|
3074
|
+
context,
|
|
3113
3075
|
collectionCallbacks: this.inboxCallbacks,
|
|
3114
3076
|
tracerProvider: this.tracerProvider,
|
|
3115
3077
|
onUnauthorized,
|
|
3116
3078
|
onNotFound
|
|
3117
3079
|
});
|
|
3118
|
-
context
|
|
3080
|
+
context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier: route.values.identifier }) });
|
|
3119
3081
|
case "sharedInbox":
|
|
3120
3082
|
if (routeName !== "inbox" && this.sharedInboxKeyDispatcher != null) {
|
|
3121
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
3122
|
-
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) });
|
|
3123
3085
|
}
|
|
3124
3086
|
if (!this.manuallyStartQueue) this._startQueueInternal(contextData);
|
|
3125
3087
|
return await handleInbox(request, {
|
|
3126
3088
|
recipient: route.values.identifier ?? null,
|
|
3127
|
-
context
|
|
3128
|
-
inboxContextFactory: context
|
|
3089
|
+
context,
|
|
3090
|
+
inboxContextFactory: context.toInboxContext.bind(context),
|
|
3129
3091
|
kv: this.kv,
|
|
3130
3092
|
kvPrefixes: this.kvPrefixes,
|
|
3131
3093
|
queue: this.inboxQueue,
|
|
@@ -3141,8 +3103,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3141
3103
|
case "following": return await handleCollection(request, {
|
|
3142
3104
|
name: "following",
|
|
3143
3105
|
identifier: route.values.identifier,
|
|
3144
|
-
uriGetter: context
|
|
3145
|
-
context
|
|
3106
|
+
uriGetter: context.getFollowingUri.bind(context),
|
|
3107
|
+
context,
|
|
3146
3108
|
collectionCallbacks: this.followingCallbacks,
|
|
3147
3109
|
tracerProvider: this.tracerProvider,
|
|
3148
3110
|
onUnauthorized,
|
|
@@ -3158,14 +3120,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3158
3120
|
return await handleCollection(request, {
|
|
3159
3121
|
name: "followers",
|
|
3160
3122
|
identifier: route.values.identifier,
|
|
3161
|
-
uriGetter: baseUrl == null ? context
|
|
3162
|
-
const uri = context
|
|
3123
|
+
uriGetter: baseUrl == null ? context.getFollowersUri.bind(context) : (identifier) => {
|
|
3124
|
+
const uri = context.getFollowersUri(identifier);
|
|
3163
3125
|
uri.searchParams.set("base-url", baseUrl);
|
|
3164
3126
|
return uri;
|
|
3165
3127
|
},
|
|
3166
|
-
context
|
|
3128
|
+
context,
|
|
3167
3129
|
filter: baseUrl != null ? new URL(baseUrl) : void 0,
|
|
3168
|
-
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,
|
|
3169
3131
|
collectionCallbacks: this.followersCallbacks,
|
|
3170
3132
|
tracerProvider: this.tracerProvider,
|
|
3171
3133
|
onUnauthorized,
|
|
@@ -3175,8 +3137,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3175
3137
|
case "liked": return await handleCollection(request, {
|
|
3176
3138
|
name: "liked",
|
|
3177
3139
|
identifier: route.values.identifier,
|
|
3178
|
-
uriGetter: context
|
|
3179
|
-
context
|
|
3140
|
+
uriGetter: context.getLikedUri.bind(context),
|
|
3141
|
+
context,
|
|
3180
3142
|
collectionCallbacks: this.likedCallbacks,
|
|
3181
3143
|
tracerProvider: this.tracerProvider,
|
|
3182
3144
|
onUnauthorized,
|
|
@@ -3185,8 +3147,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3185
3147
|
case "featured": return await handleCollection(request, {
|
|
3186
3148
|
name: "featured",
|
|
3187
3149
|
identifier: route.values.identifier,
|
|
3188
|
-
uriGetter: context
|
|
3189
|
-
context
|
|
3150
|
+
uriGetter: context.getFeaturedUri.bind(context),
|
|
3151
|
+
context,
|
|
3190
3152
|
collectionCallbacks: this.featuredCallbacks,
|
|
3191
3153
|
tracerProvider: this.tracerProvider,
|
|
3192
3154
|
onUnauthorized,
|
|
@@ -3195,8 +3157,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3195
3157
|
case "featuredTags": return await handleCollection(request, {
|
|
3196
3158
|
name: "featured tags",
|
|
3197
3159
|
identifier: route.values.identifier,
|
|
3198
|
-
uriGetter: context
|
|
3199
|
-
context
|
|
3160
|
+
uriGetter: context.getFeaturedTagsUri.bind(context),
|
|
3161
|
+
context,
|
|
3200
3162
|
collectionCallbacks: this.featuredTagsCallbacks,
|
|
3201
3163
|
tracerProvider: this.tracerProvider,
|
|
3202
3164
|
onUnauthorized,
|
|
@@ -3207,7 +3169,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3207
3169
|
const callbacks = this.collectionCallbacks[name];
|
|
3208
3170
|
return await handleCustomCollection(request, {
|
|
3209
3171
|
name,
|
|
3210
|
-
context
|
|
3172
|
+
context,
|
|
3211
3173
|
values: route.values,
|
|
3212
3174
|
collectionCallbacks: callbacks,
|
|
3213
3175
|
tracerProvider: this.tracerProvider,
|
|
@@ -3220,7 +3182,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3220
3182
|
const callbacks = this.collectionCallbacks[name];
|
|
3221
3183
|
return await handleOrderedCollection(request, {
|
|
3222
3184
|
name,
|
|
3223
|
-
context
|
|
3185
|
+
context,
|
|
3224
3186
|
values: route.values,
|
|
3225
3187
|
collectionCallbacks: callbacks,
|
|
3226
3188
|
tracerProvider: this.tracerProvider,
|
|
@@ -3311,9 +3273,9 @@ var ContextImpl = class ContextImpl {
|
|
|
3311
3273
|
}
|
|
3312
3274
|
getInboxUri(identifier) {
|
|
3313
3275
|
if (identifier == null) {
|
|
3314
|
-
const path
|
|
3315
|
-
if (path
|
|
3316
|
-
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);
|
|
3317
3279
|
}
|
|
3318
3280
|
const path = this.federation.router.build("inbox", { identifier });
|
|
3319
3281
|
if (path == null) throw new RouterError("No inbox path registered.");
|
|
@@ -3399,8 +3361,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3399
3361
|
type: "featuredTags",
|
|
3400
3362
|
identifier
|
|
3401
3363
|
};
|
|
3402
|
-
const
|
|
3403
|
-
const collectionRegex = /* @__PURE__ */ new RegExp(`^(${collectionTypes.join("|")}):(.*)$`);
|
|
3364
|
+
const collectionRegex = new RegExp(`^(${["collection", "orderedCollection"].join("|")}):(.*)$`);
|
|
3404
3365
|
const match = route.name.match(collectionRegex);
|
|
3405
3366
|
if (match !== null) {
|
|
3406
3367
|
const [, type, name] = match;
|
|
@@ -3416,12 +3377,12 @@ var ContextImpl = class ContextImpl {
|
|
|
3416
3377
|
return null;
|
|
3417
3378
|
}
|
|
3418
3379
|
async getActorKeyPairs(identifier) {
|
|
3419
|
-
const logger
|
|
3380
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3420
3381
|
"fedify",
|
|
3421
3382
|
"federation",
|
|
3422
3383
|
"actor"
|
|
3423
3384
|
]);
|
|
3424
|
-
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.", {
|
|
3425
3386
|
getActorKeyPairsIdentifier: identifier,
|
|
3426
3387
|
actorKeyPairsDispatcherIdentifier: this.invokedFromActorKeyPairsDispatcher.identifier
|
|
3427
3388
|
});
|
|
@@ -3429,7 +3390,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3429
3390
|
try {
|
|
3430
3391
|
keyPairs = await this.getKeyPairsFromIdentifier(identifier);
|
|
3431
3392
|
} catch (_) {
|
|
3432
|
-
logger
|
|
3393
|
+
logger.warn("No actor key pairs dispatcher registered.");
|
|
3433
3394
|
return [];
|
|
3434
3395
|
}
|
|
3435
3396
|
const owner = this.getActorUri(identifier);
|
|
@@ -3437,12 +3398,12 @@ var ContextImpl = class ContextImpl {
|
|
|
3437
3398
|
for (const keyPair of keyPairs) {
|
|
3438
3399
|
const newPair = {
|
|
3439
3400
|
...keyPair,
|
|
3440
|
-
cryptographicKey: new
|
|
3401
|
+
cryptographicKey: new _fedify_vocab.CryptographicKey({
|
|
3441
3402
|
id: keyPair.keyId,
|
|
3442
3403
|
owner,
|
|
3443
3404
|
publicKey: keyPair.publicKey
|
|
3444
3405
|
}),
|
|
3445
|
-
multikey: new
|
|
3406
|
+
multikey: new _fedify_vocab.Multikey({
|
|
3446
3407
|
id: keyPair.keyId,
|
|
3447
3408
|
controller: owner,
|
|
3448
3409
|
publicKey: keyPair.publicKey
|
|
@@ -3453,7 +3414,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3453
3414
|
return result;
|
|
3454
3415
|
}
|
|
3455
3416
|
async getKeyPairsFromIdentifier(identifier) {
|
|
3456
|
-
const logger
|
|
3417
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3457
3418
|
"fedify",
|
|
3458
3419
|
"federation",
|
|
3459
3420
|
"actor"
|
|
@@ -3464,7 +3425,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3464
3425
|
actorUri = this.getActorUri(identifier);
|
|
3465
3426
|
} catch (error) {
|
|
3466
3427
|
if (error instanceof RouterError) {
|
|
3467
|
-
logger
|
|
3428
|
+
logger.warn(error.message);
|
|
3468
3429
|
return [];
|
|
3469
3430
|
}
|
|
3470
3431
|
throw error;
|
|
@@ -3473,7 +3434,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3473
3434
|
...this,
|
|
3474
3435
|
invokedFromActorKeyPairsDispatcher: { identifier }
|
|
3475
3436
|
}), identifier);
|
|
3476
|
-
if (keyPairs.length < 1) logger
|
|
3437
|
+
if (keyPairs.length < 1) logger.warn("No key pairs found for actor {identifier}.", { identifier });
|
|
3477
3438
|
let i = 0;
|
|
3478
3439
|
const result = [];
|
|
3479
3440
|
for (const keyPair of keyPairs) {
|
|
@@ -3491,7 +3452,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3491
3452
|
const { privateKey } = keyPair;
|
|
3492
3453
|
if (privateKey.algorithm.name === "RSASSA-PKCS1-v1_5" && privateKey.algorithm.hash.name === "SHA-256") return keyPair;
|
|
3493
3454
|
}
|
|
3494
|
-
(0,
|
|
3455
|
+
(0, _logtape_logtape.getLogger)([
|
|
3495
3456
|
"fedify",
|
|
3496
3457
|
"federation",
|
|
3497
3458
|
"actor"
|
|
@@ -3512,14 +3473,13 @@ var ContextImpl = class ContextImpl {
|
|
|
3512
3473
|
} else identifierPromise = Promise.resolve(identity.identifier);
|
|
3513
3474
|
return identifierPromise.then((identifier) => {
|
|
3514
3475
|
if (identifier == null) return this.documentLoader;
|
|
3515
|
-
|
|
3516
|
-
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));
|
|
3517
3477
|
});
|
|
3518
3478
|
}
|
|
3519
3479
|
return this.federation.authenticatedDocumentLoaderFactory(identity);
|
|
3520
3480
|
}
|
|
3521
3481
|
lookupObject(identifier, options = {}) {
|
|
3522
|
-
return (0,
|
|
3482
|
+
return (0, _fedify_vocab.lookupObject)(identifier, {
|
|
3523
3483
|
...options,
|
|
3524
3484
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3525
3485
|
contextLoader: options.contextLoader ?? this.contextLoader,
|
|
@@ -3529,7 +3489,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3529
3489
|
});
|
|
3530
3490
|
}
|
|
3531
3491
|
traverseCollection(collection, options = {}) {
|
|
3532
|
-
return (0,
|
|
3492
|
+
return (0, _fedify_vocab.traverseCollection)(collection, {
|
|
3533
3493
|
...options,
|
|
3534
3494
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3535
3495
|
contextLoader: options.contextLoader ?? this.contextLoader
|
|
@@ -3547,7 +3507,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3547
3507
|
});
|
|
3548
3508
|
}
|
|
3549
3509
|
lookupWebFinger(resource, options = {}) {
|
|
3550
|
-
return (0,
|
|
3510
|
+
return (0, _fedify_webfinger.lookupWebFinger)(resource, {
|
|
3551
3511
|
...options,
|
|
3552
3512
|
userAgent: options.userAgent ?? this.federation.userAgent,
|
|
3553
3513
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
@@ -3555,11 +3515,10 @@ var ContextImpl = class ContextImpl {
|
|
|
3555
3515
|
});
|
|
3556
3516
|
}
|
|
3557
3517
|
sendActivity(sender, recipients, activity, options = {}) {
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
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,
|
|
3561
3520
|
attributes: {
|
|
3562
|
-
"activitypub.activity.type": (0,
|
|
3521
|
+
"activitypub.activity.type": (0, _fedify_vocab.getTypeId)(activity).href,
|
|
3563
3522
|
"activitypub.activity.to": activity.toIds.map((to) => to.href),
|
|
3564
3523
|
"activitypub.activity.cc": activity.toIds.map((cc) => cc.href),
|
|
3565
3524
|
"activitypub.activity.bto": activity.btoIds.map((bto) => bto.href),
|
|
@@ -3571,7 +3530,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3571
3530
|
await this.sendActivityInternal(sender, recipients, activity, options, span);
|
|
3572
3531
|
} catch (e) {
|
|
3573
3532
|
span.setStatus({
|
|
3574
|
-
code:
|
|
3533
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3575
3534
|
message: String(e)
|
|
3576
3535
|
});
|
|
3577
3536
|
throw e;
|
|
@@ -3581,7 +3540,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3581
3540
|
});
|
|
3582
3541
|
}
|
|
3583
3542
|
async sendActivityInternal(sender, recipients, activity, options, span) {
|
|
3584
|
-
const logger
|
|
3543
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3585
3544
|
"fedify",
|
|
3586
3545
|
"federation",
|
|
3587
3546
|
"outbox"
|
|
@@ -3631,7 +3590,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3631
3590
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
3632
3591
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
3633
3592
|
if (activity.actorId == null) {
|
|
3634
|
-
logger
|
|
3593
|
+
logger.error("Activity {activityId} to send does not have an actor.", {
|
|
3635
3594
|
activity,
|
|
3636
3595
|
activityId: activity?.id?.href
|
|
3637
3596
|
});
|
|
@@ -3642,7 +3601,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3642
3601
|
preferSharedInbox: options.preferSharedInbox,
|
|
3643
3602
|
excludeBaseUris: options.excludeBaseUris
|
|
3644
3603
|
});
|
|
3645
|
-
logger
|
|
3604
|
+
logger.debug("Sending activity {activityId} to inboxes:\n{inboxes}", {
|
|
3646
3605
|
inboxes: globalThis.Object.keys(inboxes),
|
|
3647
3606
|
activityId: activity.id?.href,
|
|
3648
3607
|
activity
|
|
@@ -3656,7 +3615,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3656
3615
|
privateKey: await require_http.exportJwk(privateKey)
|
|
3657
3616
|
})));
|
|
3658
3617
|
const carrier = {};
|
|
3659
|
-
|
|
3618
|
+
_opentelemetry_api.propagation.inject(_opentelemetry_api.context.active(), carrier);
|
|
3660
3619
|
const message = {
|
|
3661
3620
|
type: "fanout",
|
|
3662
3621
|
id: crypto.randomUUID(),
|
|
@@ -3671,7 +3630,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3671
3630
|
contextLoader: this.contextLoader
|
|
3672
3631
|
}),
|
|
3673
3632
|
activityId: activity.id?.href,
|
|
3674
|
-
activityType: (0,
|
|
3633
|
+
activityType: (0, _fedify_vocab.getTypeId)(activity).href,
|
|
3675
3634
|
collectionSync: opts.collectionSync,
|
|
3676
3635
|
orderingKey: options.orderingKey,
|
|
3677
3636
|
traceContext: carrier
|
|
@@ -3688,24 +3647,22 @@ var ContextImpl = class ContextImpl {
|
|
|
3688
3647
|
}
|
|
3689
3648
|
if (this.federation.followersCallbacks.firstCursor == null) throw new Error("No first cursor dispatcher registered for followers collection.");
|
|
3690
3649
|
let cursor = await this.federation.followersCallbacks.firstCursor(this, identifier);
|
|
3691
|
-
if (cursor != null) (0,
|
|
3650
|
+
if (cursor != null) (0, _logtape_logtape.getLogger)([
|
|
3692
3651
|
"fedify",
|
|
3693
3652
|
"federation",
|
|
3694
3653
|
"outbox"
|
|
3695
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 });
|
|
3696
3655
|
while (cursor != null) {
|
|
3697
|
-
const result
|
|
3698
|
-
if (result
|
|
3699
|
-
for (const recipient of result
|
|
3700
|
-
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;
|
|
3701
3660
|
}
|
|
3702
3661
|
}
|
|
3703
3662
|
routeActivity(recipient, activity, options = {}) {
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
kind: this.federation.inboxQueue == null || options.immediate ? __opentelemetry_api.SpanKind.INTERNAL : __opentelemetry_api.SpanKind.PRODUCER,
|
|
3708
|
-
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 }
|
|
3709
3666
|
}, async (span) => {
|
|
3710
3667
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
3711
3668
|
if (activity.toIds.length > 0) span.setAttribute("activitypub.activity.to", activity.toIds.map((to) => to.href));
|
|
@@ -3717,11 +3674,11 @@ var ContextImpl = class ContextImpl {
|
|
|
3717
3674
|
if (ok) {
|
|
3718
3675
|
span.setAttribute("activitypub.shared_inbox", recipient == null);
|
|
3719
3676
|
if (recipient != null) span.setAttribute("fedify.inbox.recipient", recipient);
|
|
3720
|
-
} else span.setStatus({ code:
|
|
3677
|
+
} else span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
3721
3678
|
return ok;
|
|
3722
3679
|
} catch (e) {
|
|
3723
3680
|
span.setStatus({
|
|
3724
|
-
code:
|
|
3681
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3725
3682
|
message: String(e)
|
|
3726
3683
|
});
|
|
3727
3684
|
throw e;
|
|
@@ -3731,7 +3688,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3731
3688
|
});
|
|
3732
3689
|
}
|
|
3733
3690
|
async routeActivityInternal(recipient, activity, options = {}, span) {
|
|
3734
|
-
const logger
|
|
3691
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3735
3692
|
"fedify",
|
|
3736
3693
|
"federation",
|
|
3737
3694
|
"inbox"
|
|
@@ -3739,19 +3696,18 @@ var ContextImpl = class ContextImpl {
|
|
|
3739
3696
|
const contextLoader = options.contextLoader ?? this.contextLoader;
|
|
3740
3697
|
const json = await activity.toJsonLd({ contextLoader });
|
|
3741
3698
|
const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, this);
|
|
3742
|
-
|
|
3699
|
+
if (await require_proof.verifyObject(_fedify_vocab.Activity, json, {
|
|
3743
3700
|
contextLoader,
|
|
3744
3701
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3745
3702
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
3746
3703
|
keyCache
|
|
3747
|
-
})
|
|
3748
|
-
|
|
3749
|
-
logger$1.debug("Object Integrity Proofs are not verified.", {
|
|
3704
|
+
}) == null) {
|
|
3705
|
+
logger.debug("Object Integrity Proofs are not verified.", {
|
|
3750
3706
|
recipient,
|
|
3751
3707
|
activity: json
|
|
3752
3708
|
});
|
|
3753
3709
|
if (activity.id == null) {
|
|
3754
|
-
logger
|
|
3710
|
+
logger.debug("Activity is missing an ID; unable to fetch.", {
|
|
3755
3711
|
recipient,
|
|
3756
3712
|
activity: json
|
|
3757
3713
|
});
|
|
@@ -3759,26 +3715,26 @@ var ContextImpl = class ContextImpl {
|
|
|
3759
3715
|
}
|
|
3760
3716
|
const fetched = await this.lookupObject(activity.id, options);
|
|
3761
3717
|
if (fetched == null) {
|
|
3762
|
-
logger
|
|
3718
|
+
logger.debug("Failed to fetch the remote activity object {activityId}.", {
|
|
3763
3719
|
recipient,
|
|
3764
3720
|
activity: json,
|
|
3765
3721
|
activityId: activity.id.href
|
|
3766
3722
|
});
|
|
3767
3723
|
return false;
|
|
3768
|
-
} else if (!(fetched instanceof
|
|
3769
|
-
logger
|
|
3724
|
+
} else if (!(fetched instanceof _fedify_vocab.Activity)) {
|
|
3725
|
+
logger.debug("Fetched object is not an Activity.", {
|
|
3770
3726
|
recipient,
|
|
3771
3727
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3772
3728
|
});
|
|
3773
3729
|
return false;
|
|
3774
3730
|
} else if (fetched.id?.href !== activity.id.href) {
|
|
3775
|
-
logger
|
|
3731
|
+
logger.debug("Fetched activity object has a different ID; failed to verify.", {
|
|
3776
3732
|
recipient,
|
|
3777
3733
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3778
3734
|
});
|
|
3779
3735
|
return false;
|
|
3780
3736
|
} else if (fetched.actorIds.length < 1) {
|
|
3781
|
-
logger
|
|
3737
|
+
logger.debug("Fetched activity object is missing an actor; unable to verify.", {
|
|
3782
3738
|
recipient,
|
|
3783
3739
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3784
3740
|
});
|
|
@@ -3786,15 +3742,15 @@ var ContextImpl = class ContextImpl {
|
|
|
3786
3742
|
}
|
|
3787
3743
|
const activityId = fetched.id;
|
|
3788
3744
|
if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
|
|
3789
|
-
logger
|
|
3745
|
+
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
3790
3746
|
recipient,
|
|
3791
3747
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3792
3748
|
});
|
|
3793
3749
|
return false;
|
|
3794
3750
|
}
|
|
3795
|
-
logger
|
|
3751
|
+
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
3796
3752
|
activity = fetched;
|
|
3797
|
-
} else logger
|
|
3753
|
+
} else logger.debug("Object Integrity Proofs are verified.", {
|
|
3798
3754
|
recipient,
|
|
3799
3755
|
activity: json
|
|
3800
3756
|
});
|
|
@@ -3843,7 +3799,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
|
|
|
3843
3799
|
}
|
|
3844
3800
|
async getActor(identifier) {
|
|
3845
3801
|
if (this.federation.actorCallbacks == null || this.federation.actorCallbacks.dispatcher == null) throw new Error("No actor dispatcher registered.");
|
|
3846
|
-
if (this.#invokedFromActorDispatcher != null) (0,
|
|
3802
|
+
if (this.#invokedFromActorDispatcher != null) (0, _logtape_logtape.getLogger)([
|
|
3847
3803
|
"fedify",
|
|
3848
3804
|
"federation",
|
|
3849
3805
|
"actor"
|
|
@@ -3860,7 +3816,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
|
|
|
3860
3816
|
const callbacks = this.federation.objectCallbacks[cls.typeId.href];
|
|
3861
3817
|
if (callbacks == null) throw new Error("No object dispatcher registered.");
|
|
3862
3818
|
for (const param of callbacks.parameters) if (!(param in values)) throw new TypeError(`Missing parameter: ${param}`);
|
|
3863
|
-
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.", {
|
|
3864
3820
|
getObjectClass: cls.name,
|
|
3865
3821
|
getObjectValues: values,
|
|
3866
3822
|
actorDispatcherClass: this.#invokedFromObjectDispatcher.cls.name,
|
|
@@ -3920,9 +3876,8 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3920
3876
|
});
|
|
3921
3877
|
}
|
|
3922
3878
|
forwardActivity(forwarder, recipients, options) {
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
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,
|
|
3926
3881
|
attributes: { "activitypub.activity.type": this.activityType }
|
|
3927
3882
|
}, async (span) => {
|
|
3928
3883
|
try {
|
|
@@ -3930,7 +3885,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3930
3885
|
await this.forwardActivityInternal(forwarder, recipients, options);
|
|
3931
3886
|
} catch (e) {
|
|
3932
3887
|
span.setStatus({
|
|
3933
|
-
code:
|
|
3888
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3934
3889
|
message: String(e)
|
|
3935
3890
|
});
|
|
3936
3891
|
throw e;
|
|
@@ -3940,7 +3895,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3940
3895
|
});
|
|
3941
3896
|
}
|
|
3942
3897
|
async forwardActivityInternal(forwarder, recipients, options) {
|
|
3943
|
-
const logger
|
|
3898
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
3944
3899
|
"fedify",
|
|
3945
3900
|
"federation",
|
|
3946
3901
|
"inbox"
|
|
@@ -3967,14 +3922,13 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3967
3922
|
if (!require_proof.hasSignature(this.activity)) {
|
|
3968
3923
|
let hasProof;
|
|
3969
3924
|
try {
|
|
3970
|
-
|
|
3971
|
-
hasProof = await activity.getProof() != null;
|
|
3925
|
+
hasProof = await (await _fedify_vocab.Activity.fromJsonLd(this.activity, this)).getProof() != null;
|
|
3972
3926
|
} catch {
|
|
3973
3927
|
hasProof = false;
|
|
3974
3928
|
}
|
|
3975
3929
|
if (!hasProof) {
|
|
3976
3930
|
if (options?.skipIfUnsigned) return;
|
|
3977
|
-
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.");
|
|
3978
3932
|
}
|
|
3979
3933
|
}
|
|
3980
3934
|
if (recipients === "followers") {
|
|
@@ -3988,14 +3942,14 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3988
3942
|
preferSharedInbox: options?.preferSharedInbox,
|
|
3989
3943
|
excludeBaseUris: options?.excludeBaseUris
|
|
3990
3944
|
});
|
|
3991
|
-
logger
|
|
3945
|
+
logger.debug("Forwarding activity {activityId} to inboxes:\n{inboxes}", {
|
|
3992
3946
|
inboxes: globalThis.Object.keys(inboxes),
|
|
3993
3947
|
activityId: this.activityId,
|
|
3994
3948
|
activity: this.activity
|
|
3995
3949
|
});
|
|
3996
3950
|
if (options?.immediate || this.federation.outboxQueue == null) {
|
|
3997
|
-
if (options?.immediate) logger
|
|
3998
|
-
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.");
|
|
3999
3953
|
const promises = [];
|
|
4000
3954
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
4001
3955
|
keys,
|
|
@@ -4010,7 +3964,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4010
3964
|
await Promise.all(promises);
|
|
4011
3965
|
return;
|
|
4012
3966
|
}
|
|
4013
|
-
logger
|
|
3967
|
+
logger.debug("Enqueuing activity {activityId} to forward later.", {
|
|
4014
3968
|
activityId: this.activityId,
|
|
4015
3969
|
activity: this.activity
|
|
4016
3970
|
});
|
|
@@ -4023,7 +3977,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4023
3977
|
});
|
|
4024
3978
|
}
|
|
4025
3979
|
const carrier = {};
|
|
4026
|
-
|
|
3980
|
+
_opentelemetry_api.propagation.inject(_opentelemetry_api.context.active(), carrier);
|
|
4027
3981
|
const orderingKey = options?.orderingKey;
|
|
4028
3982
|
const messages = [];
|
|
4029
3983
|
for (const inbox in inboxes) {
|
|
@@ -4052,10 +4006,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4052
4006
|
const { outboxQueue } = this.federation;
|
|
4053
4007
|
if (outboxQueue.enqueueMany == null) {
|
|
4054
4008
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4055
|
-
const
|
|
4056
|
-
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);
|
|
4057
4010
|
if (errors.length > 0) {
|
|
4058
|
-
logger
|
|
4011
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4059
4012
|
activityId: this.activityId,
|
|
4060
4013
|
errors
|
|
4061
4014
|
});
|
|
@@ -4064,10 +4017,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4064
4017
|
}
|
|
4065
4018
|
} else if (orderingKey != null) {
|
|
4066
4019
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4067
|
-
const
|
|
4068
|
-
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);
|
|
4069
4021
|
if (errors.length > 0) {
|
|
4070
|
-
logger
|
|
4022
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4071
4023
|
activityId: this.activityId,
|
|
4072
4024
|
errors
|
|
4073
4025
|
});
|
|
@@ -4077,7 +4029,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4077
4029
|
} else try {
|
|
4078
4030
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
4079
4031
|
} catch (error) {
|
|
4080
|
-
logger
|
|
4032
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
|
|
4081
4033
|
activityId: this.activityId,
|
|
4082
4034
|
error
|
|
4083
4035
|
});
|
|
@@ -4132,99 +4084,96 @@ function unauthorized(_request) {
|
|
|
4132
4084
|
function getRequestId(request) {
|
|
4133
4085
|
const traceId = request.headers.get("X-Request-Id") || request.headers.get("X-Correlation-Id") || request.headers.get("Traceparent")?.split("-")[1];
|
|
4134
4086
|
if (traceId != null) return traceId;
|
|
4135
|
-
|
|
4136
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
4137
|
-
return `req_${timestamp}${random}`;
|
|
4087
|
+
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
4138
4088
|
}
|
|
4139
|
-
|
|
4140
4089
|
//#endregion
|
|
4141
|
-
Object.defineProperty(exports,
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4090
|
+
Object.defineProperty(exports, "ContextImpl", {
|
|
4091
|
+
enumerable: true,
|
|
4092
|
+
get: function() {
|
|
4093
|
+
return ContextImpl;
|
|
4094
|
+
}
|
|
4146
4095
|
});
|
|
4147
|
-
Object.defineProperty(exports,
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4096
|
+
Object.defineProperty(exports, "FederationImpl", {
|
|
4097
|
+
enumerable: true,
|
|
4098
|
+
get: function() {
|
|
4099
|
+
return FederationImpl;
|
|
4100
|
+
}
|
|
4152
4101
|
});
|
|
4153
|
-
Object.defineProperty(exports,
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4102
|
+
Object.defineProperty(exports, "InboxContextImpl", {
|
|
4103
|
+
enumerable: true,
|
|
4104
|
+
get: function() {
|
|
4105
|
+
return InboxContextImpl;
|
|
4106
|
+
}
|
|
4107
|
+
});
|
|
4108
|
+
Object.defineProperty(exports, "KvSpecDeterminer", {
|
|
4109
|
+
enumerable: true,
|
|
4110
|
+
get: function() {
|
|
4111
|
+
return KvSpecDeterminer;
|
|
4112
|
+
}
|
|
4158
4113
|
});
|
|
4159
|
-
Object.defineProperty(exports,
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4114
|
+
Object.defineProperty(exports, "Router", {
|
|
4115
|
+
enumerable: true,
|
|
4116
|
+
get: function() {
|
|
4117
|
+
return Router;
|
|
4118
|
+
}
|
|
4164
4119
|
});
|
|
4165
|
-
Object.defineProperty(exports,
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4120
|
+
Object.defineProperty(exports, "RouterError", {
|
|
4121
|
+
enumerable: true,
|
|
4122
|
+
get: function() {
|
|
4123
|
+
return RouterError;
|
|
4124
|
+
}
|
|
4170
4125
|
});
|
|
4171
|
-
Object.defineProperty(exports,
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4126
|
+
Object.defineProperty(exports, "SendActivityError", {
|
|
4127
|
+
enumerable: true,
|
|
4128
|
+
get: function() {
|
|
4129
|
+
return SendActivityError;
|
|
4130
|
+
}
|
|
4176
4131
|
});
|
|
4177
|
-
Object.defineProperty(exports,
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4132
|
+
Object.defineProperty(exports, "buildCollectionSynchronizationHeader", {
|
|
4133
|
+
enumerable: true,
|
|
4134
|
+
get: function() {
|
|
4135
|
+
return buildCollectionSynchronizationHeader;
|
|
4136
|
+
}
|
|
4182
4137
|
});
|
|
4183
|
-
Object.defineProperty(exports,
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4138
|
+
Object.defineProperty(exports, "createExponentialBackoffPolicy", {
|
|
4139
|
+
enumerable: true,
|
|
4140
|
+
get: function() {
|
|
4141
|
+
return createExponentialBackoffPolicy;
|
|
4142
|
+
}
|
|
4188
4143
|
});
|
|
4189
|
-
Object.defineProperty(exports,
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4144
|
+
Object.defineProperty(exports, "createFederation", {
|
|
4145
|
+
enumerable: true,
|
|
4146
|
+
get: function() {
|
|
4147
|
+
return createFederation;
|
|
4148
|
+
}
|
|
4194
4149
|
});
|
|
4195
|
-
Object.defineProperty(exports,
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4150
|
+
Object.defineProperty(exports, "createFederationBuilder", {
|
|
4151
|
+
enumerable: true,
|
|
4152
|
+
get: function() {
|
|
4153
|
+
return createFederationBuilder;
|
|
4154
|
+
}
|
|
4200
4155
|
});
|
|
4201
|
-
Object.defineProperty(exports,
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4156
|
+
Object.defineProperty(exports, "digest", {
|
|
4157
|
+
enumerable: true,
|
|
4158
|
+
get: function() {
|
|
4159
|
+
return digest;
|
|
4160
|
+
}
|
|
4206
4161
|
});
|
|
4207
|
-
Object.defineProperty(exports,
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4162
|
+
Object.defineProperty(exports, "handleWebFinger", {
|
|
4163
|
+
enumerable: true,
|
|
4164
|
+
get: function() {
|
|
4165
|
+
return handleWebFinger;
|
|
4166
|
+
}
|
|
4212
4167
|
});
|
|
4213
|
-
Object.defineProperty(exports,
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4168
|
+
Object.defineProperty(exports, "respondWithObject", {
|
|
4169
|
+
enumerable: true,
|
|
4170
|
+
get: function() {
|
|
4171
|
+
return respondWithObject;
|
|
4172
|
+
}
|
|
4218
4173
|
});
|
|
4219
|
-
Object.defineProperty(exports,
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4174
|
+
Object.defineProperty(exports, "respondWithObjectIfAcceptable", {
|
|
4175
|
+
enumerable: true,
|
|
4176
|
+
get: function() {
|
|
4177
|
+
return respondWithObjectIfAcceptable;
|
|
4178
|
+
}
|
|
4224
4179
|
});
|
|
4225
|
-
Object.defineProperty(exports, 'respondWithObjectIfAcceptable', {
|
|
4226
|
-
enumerable: true,
|
|
4227
|
-
get: function () {
|
|
4228
|
-
return respondWithObjectIfAcceptable;
|
|
4229
|
-
}
|
|
4230
|
-
});
|