@fedify/fedify 2.1.1 → 2.1.3
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/{accept-D7sAxyNa.js → accept-Dd__NiUL.mjs} +10 -8
- 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-f3m3epl3.js → assert_not_equals--wG9hV7u.mjs} +6 -13
- package/dist/{assert_rejects-0h7I2Esa.js → assert_rejects-B-qJtC9Z.mjs} +6 -11
- package/dist/{assert_throws-rjdMBf31.js → assert_throws-4NwKEy2q.mjs} +5 -10
- package/dist/{builder-DbKYZdSy.js → builder-BKo51w-F.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-BxMZiQaD.d.ts → client-AtlibPOU.d.ts} +1 -1
- package/dist/{client-CoCIaTNO.js → client-DEpOVgY1.mjs} +9 -13
- package/dist/{client-C97KOq3x.d.cts → client-z-8dc-e1.d.cts} +1 -1
- package/dist/{collection-CSzG2j1P.js → collection-BD6-SZ6O.mjs} +7 -12
- package/dist/compat/mod.cjs +5 -8
- package/dist/compat/mod.d.cts +78 -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-DyJjQQ_H.d.ts → context-BOiMZBu5.d.ts} +9 -18
- package/dist/{context-BcqA-0BL.d.cts → context-BhZVy7RB.d.cts} +9 -18
- package/dist/{context-Aqenou7c.js → context-Juj6bdHC.mjs} +7 -11
- package/dist/deno-D5r_9RvZ.mjs +8 -0
- package/dist/{docloader-Ck0SCLXX.js → docloader-B9CXCw8i.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} +21 -44
- 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} +69 -131
- package/dist/federation/idempotency.test.d.mts +2 -0
- package/dist/federation/{idempotency.test.js → idempotency.test.mjs} +31 -63
- package/dist/federation/inbox.test.d.mts +2 -0
- package/dist/federation/{inbox.test.js → inbox.test.mjs} +8 -12
- package/dist/federation/keycache.test.d.mts +2 -0
- package/dist/federation/{keycache.test.js → keycache.test.mjs} +13 -19
- 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} +173 -262
- 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 -30
- package/dist/federation/webfinger.test.d.mts +2 -0
- package/dist/federation/{webfinger.test.js → webfinger.test.mjs} +22 -56
- package/dist/{http-DFzT4YFG.js → http-B53alCGi.mjs} +23 -43
- package/dist/{http-ca2xny58.cjs → http-BngkmEhl.cjs} +177 -302
- package/dist/{http-BudnHZE2.d.cts → http-CrGuipxe.d.cts} +1 -6
- package/dist/{http-EUQ6crVa.js → http-PS3wuU8D.js} +53 -184
- package/dist/{http-Dax_FIBo.d.ts → http-aQzN9Ayi.d.ts} +1 -6
- package/dist/{inbox-BMLz_-pL.js → inbox-CHsLu5ai.mjs} +18 -26
- package/dist/{key-CypuWa94.js → key-D9Np_ZXl.mjs} +29 -37
- package/dist/{keycache-CpGWAUbj.js → keycache-CCSwkQcY.mjs} +5 -10
- package/dist/{keys-BFve7QQv.js → keys-BAK-tUlf.mjs} +5 -9
- 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-Bw2F2ABq.js → kv-cache-B01V7s3h.mjs} +4 -8
- package/dist/{kv-cache-SKgbvvu4.js → kv-cache-B2Qi5MGv.js} +6 -13
- package/dist/{kv-cache-BBJFLMW5.cjs → kv-cache-YCtINZK4.cjs} +27 -34
- package/dist/{kv-QzKcOQgP.js → kv-tL2TOE9X.mjs} +6 -10
- package/dist/{ld-CXLtTc0G.js → ld-BaxRFhDd.mjs} +17 -31
- package/dist/{middleware-CL6XaAFy.cjs → middleware-Bsv-7iX7.cjs} +532 -587
- package/dist/middleware-C37OmOz_.mjs +5 -0
- package/dist/middleware-CelV2xrI.cjs +4 -0
- package/dist/{middleware-CvS6hWm3.js → middleware-Dn1kk96N.js} +335 -382
- package/dist/{middleware-BHJ0xm0L.js → middleware-dFn6ozt5.mjs} +282 -317
- package/dist/{mod-Bx9jcLB8.d.cts → mod-B505FZBC.d.cts} +3 -3
- package/dist/{mod-em2Il1eD.d.cts → mod-Bp_CzKd4.d.cts} +2 -2
- package/dist/{mod-Cs2dYEwI.d.ts → mod-D7PAuO6k.d.ts} +3 -3
- package/dist/{mod-D6MdymW7.d.ts → mod-DKOAow7a.d.ts} +2 -2
- package/dist/{mod-Coe7KEgX.d.cts → mod-DoJBjjnO.d.cts} +2 -2
- package/dist/{mod-D6dOd--H.d.ts → mod-DvxszxXC.d.ts} +2 -2
- package/dist/mod.cjs +29 -74
- package/dist/mod.d.cts +11 -14
- package/dist/mod.d.ts +11 -15
- package/dist/mod.js +17 -71
- package/dist/{negotiation-BlAuS_nr.js → negotiation-DnsfFF8I.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 -43
- 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} +124 -178
- 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-CwMai3jn.js → owner-dxM51u36.mjs} +11 -16
- package/dist/{proof-ZuJBOUoi.js → proof-CH5U0k7G.mjs} +21 -33
- package/dist/{proof-sCID81Ua.cjs → proof-D39qiki3.cjs} +133 -157
- package/dist/{proof-6Zw1FW7t.js → proof-Dpgqx9RS.js} +32 -58
- package/dist/{retry-mqLf4b-R.js → retry-B_E3V_Dx.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-BW73dy6Q.js → send-D1-4ZnQq.mjs} +8 -13
- package/dist/sig/accept.test.d.mts +2 -0
- package/dist/sig/{accept.test.js → accept.test.mjs} +35 -70
- package/dist/sig/http.test.d.mts +2 -0
- package/dist/sig/{http.test.js → http.test.mjs} +166 -280
- 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-X-_kMxKM.js → std__assert-Duiq_YC9.mjs} +12 -24
- package/dist/testing/{mod.d.ts → mod.d.mts} +26 -90
- 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-DCP0WLdt.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 -25
- 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 +8 -8
- package/dist/compat/transformers.test.d.ts +0 -3
- package/dist/compat/transformers.test.js +0 -88
- package/dist/compat-Bb4NuTUO.js +0 -4
- package/dist/compat-DmDDELst.cjs +0 -4
- package/dist/deno-DH972JvX.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-B8FJuMM0.js +0 -27
- package/dist/middleware-BVp930fR.js +0 -12
- package/dist/middleware-BvGP-uXy.cjs +0 -12
- package/dist/mod-B7QkWzrL.d.cts +0 -80
- package/dist/mod-Bh8mqlYw.d.cts +0 -9
- package/dist/mod-D6HodEq7.d.ts +0 -7
- package/dist/mod-SMHOMNpZ.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/accept.test.d.ts +0 -3
- 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,12 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { getAuthenticatedDocumentLoader, kvCache } from "./kv-cache-SKgbvvu4.js";
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
import { t as __exportAll } from "./chunk-nlSIicah.js";
|
|
4
|
+
import { r as getDefaultActivityTransformers } from "./transformers-ve6e2xcg.js";
|
|
5
|
+
import { _ as version, a as verifyRequestDetailed, d as validateCryptoKey, f as formatAcceptSignature, g as name, i as verifyRequest, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, u as importJwk } from "./http-PS3wuU8D.js";
|
|
6
|
+
import { a as doesActorOwnKey, d as signJsonLd, f as verifyJsonLd, l as detachSignature, n as signObject, o as getKeyOwner, r as verifyObject, u as hasSignature } from "./proof-Dpgqx9RS.js";
|
|
7
|
+
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-hvL8ElAs.js";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-B2Qi5MGv.js";
|
|
10
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
11
10
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
12
11
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
@@ -18,7 +17,6 @@ import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
|
18
17
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
19
18
|
import { lookupWebFinger } from "@fedify/webfinger";
|
|
20
19
|
import { domainToASCII } from "node:url";
|
|
21
|
-
|
|
22
20
|
//#region src/federation/inbox.ts
|
|
23
21
|
var InboxListenerSet = class InboxListenerSet {
|
|
24
22
|
#listeners;
|
|
@@ -54,7 +52,7 @@ var InboxListenerSet = class InboxListenerSet {
|
|
|
54
52
|
}
|
|
55
53
|
};
|
|
56
54
|
async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
|
|
57
|
-
const logger
|
|
55
|
+
const logger = getLogger([
|
|
58
56
|
"fedify",
|
|
59
57
|
"federation",
|
|
60
58
|
"inbox"
|
|
@@ -64,10 +62,8 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
64
62
|
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
|
|
65
63
|
const strategy = idempotencyStrategy ?? "per-inbox";
|
|
66
64
|
let keyString;
|
|
67
|
-
if (typeof strategy === "function")
|
|
68
|
-
|
|
69
|
-
keyString = result;
|
|
70
|
-
} else switch (strategy) {
|
|
65
|
+
if (typeof strategy === "function") keyString = await strategy(inboxContext, activity);
|
|
66
|
+
else switch (strategy) {
|
|
71
67
|
case "global":
|
|
72
68
|
keyString = activity.id.href;
|
|
73
69
|
break;
|
|
@@ -82,9 +78,8 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
82
78
|
if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
|
|
83
79
|
}
|
|
84
80
|
if (cacheKey != null) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
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.", {
|
|
88
83
|
activityId: activity.id?.href,
|
|
89
84
|
activity: json,
|
|
90
85
|
recipient
|
|
@@ -97,7 +92,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
97
92
|
}
|
|
98
93
|
}
|
|
99
94
|
if (activity.actorId == null) {
|
|
100
|
-
logger
|
|
95
|
+
logger.error("Missing actor.", { activity: json });
|
|
101
96
|
span.setStatus({
|
|
102
97
|
code: SpanStatusCode.ERROR,
|
|
103
98
|
message: "Missing actor."
|
|
@@ -120,7 +115,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
120
115
|
traceContext: carrier
|
|
121
116
|
});
|
|
122
117
|
} catch (error) {
|
|
123
|
-
logger
|
|
118
|
+
logger.error("Failed to enqueue the incoming activity {activityId}:\n{error}", {
|
|
124
119
|
error,
|
|
125
120
|
activityId: activity.id?.href,
|
|
126
121
|
activity: json,
|
|
@@ -132,7 +127,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
132
127
|
});
|
|
133
128
|
throw error;
|
|
134
129
|
}
|
|
135
|
-
logger
|
|
130
|
+
logger.info("Activity {activityId} is enqueued.", {
|
|
136
131
|
activityId: activity.id?.href,
|
|
137
132
|
activity: json,
|
|
138
133
|
recipient
|
|
@@ -140,60 +135,58 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
140
135
|
return "enqueued";
|
|
141
136
|
}
|
|
142
137
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
143
|
-
|
|
144
|
-
return await tracer.startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span$1) => {
|
|
138
|
+
return await tracerProvider.getTracer(name, version).startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
|
|
145
139
|
const dispatched = inboxListeners?.dispatchWithClass(activity);
|
|
146
140
|
if (dispatched == null) {
|
|
147
|
-
logger
|
|
141
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
148
142
|
activity: json,
|
|
149
143
|
recipient
|
|
150
144
|
});
|
|
151
|
-
span
|
|
145
|
+
span.setStatus({
|
|
152
146
|
code: SpanStatusCode.UNSET,
|
|
153
147
|
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
154
148
|
});
|
|
155
|
-
span
|
|
149
|
+
span.end();
|
|
156
150
|
return "unsupportedActivity";
|
|
157
151
|
}
|
|
158
152
|
const { class: cls, listener } = dispatched;
|
|
159
|
-
span
|
|
153
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
160
154
|
try {
|
|
161
155
|
await listener(inboxContextFactory(recipient, json, activity?.id?.href, getTypeId(activity).href), activity);
|
|
162
156
|
} catch (error) {
|
|
163
157
|
try {
|
|
164
158
|
await inboxErrorHandler?.(ctx, error);
|
|
165
|
-
} catch (error
|
|
166
|
-
logger
|
|
167
|
-
error
|
|
159
|
+
} catch (error) {
|
|
160
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
161
|
+
error,
|
|
168
162
|
activityId: activity.id?.href,
|
|
169
163
|
activity: json,
|
|
170
164
|
recipient
|
|
171
165
|
});
|
|
172
166
|
}
|
|
173
|
-
logger
|
|
167
|
+
logger.error("Failed to process the incoming activity {activityId}:\n{error}", {
|
|
174
168
|
error,
|
|
175
169
|
activityId: activity.id?.href,
|
|
176
170
|
activity: json,
|
|
177
171
|
recipient
|
|
178
172
|
});
|
|
179
|
-
span
|
|
173
|
+
span.setStatus({
|
|
180
174
|
code: SpanStatusCode.ERROR,
|
|
181
175
|
message: String(error)
|
|
182
176
|
});
|
|
183
|
-
span
|
|
177
|
+
span.end();
|
|
184
178
|
return "error";
|
|
185
179
|
}
|
|
186
180
|
if (cacheKey != null) await kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
187
|
-
logger
|
|
181
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
188
182
|
activityId: activity.id?.href,
|
|
189
183
|
activity: json,
|
|
190
184
|
recipient
|
|
191
185
|
});
|
|
192
|
-
span
|
|
186
|
+
span.end();
|
|
193
187
|
return "success";
|
|
194
188
|
});
|
|
195
189
|
}
|
|
196
|
-
|
|
197
190
|
//#endregion
|
|
198
191
|
//#region src/federation/router.ts
|
|
199
192
|
function cloneInnerRouter(router) {
|
|
@@ -301,7 +294,6 @@ var RouterError = class extends Error {
|
|
|
301
294
|
this.name = "RouterError";
|
|
302
295
|
}
|
|
303
296
|
};
|
|
304
|
-
|
|
305
297
|
//#endregion
|
|
306
298
|
//#region src/federation/builder.ts
|
|
307
299
|
var FederationBuilderImpl = class {
|
|
@@ -339,8 +331,8 @@ var FederationBuilderImpl = class {
|
|
|
339
331
|
this.collectionTypeIds = {};
|
|
340
332
|
}
|
|
341
333
|
async build(options) {
|
|
342
|
-
const { FederationImpl
|
|
343
|
-
const f = new FederationImpl
|
|
334
|
+
const { FederationImpl } = await Promise.resolve().then(() => middleware_exports);
|
|
335
|
+
const f = new FederationImpl(options);
|
|
344
336
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
345
337
|
f.router = this.router.clone();
|
|
346
338
|
f.router.trailingSlashInsensitive = trailingSlashInsensitiveValue;
|
|
@@ -367,23 +359,23 @@ var FederationBuilderImpl = class {
|
|
|
367
359
|
return f;
|
|
368
360
|
}
|
|
369
361
|
_getTracer() {
|
|
370
|
-
return trace.getTracer(
|
|
362
|
+
return trace.getTracer(name, version);
|
|
371
363
|
}
|
|
372
364
|
setActorDispatcher(path, dispatcher) {
|
|
373
365
|
if (this.router.has("actor")) throw new RouterError("Actor dispatcher already set.");
|
|
374
366
|
const variables = this.router.add(path, "actor");
|
|
375
367
|
if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for actor dispatcher must have one variable: {identifier}");
|
|
376
|
-
const callbacks = { dispatcher: async (context
|
|
368
|
+
const callbacks = { dispatcher: async (context, identifier) => {
|
|
377
369
|
const actor = await this._getTracer().startActiveSpan("activitypub.dispatch_actor", {
|
|
378
370
|
kind: SpanKind.SERVER,
|
|
379
371
|
attributes: { "fedify.actor.identifier": identifier }
|
|
380
372
|
}, async (span) => {
|
|
381
373
|
try {
|
|
382
|
-
const actor
|
|
383
|
-
span.setAttribute("activitypub.actor.id", (actor
|
|
384
|
-
if (actor
|
|
385
|
-
else span.setAttribute("activitypub.actor.type", getTypeId(actor
|
|
386
|
-
return actor
|
|
374
|
+
const actor = await dispatcher(context, identifier);
|
|
375
|
+
span.setAttribute("activitypub.actor.id", (actor?.id ?? context.getActorUri(identifier)).href);
|
|
376
|
+
if (actor == null) span.setStatus({ code: SpanStatusCode.ERROR });
|
|
377
|
+
else span.setAttribute("activitypub.actor.type", getTypeId(actor).href);
|
|
378
|
+
return actor;
|
|
387
379
|
} catch (error) {
|
|
388
380
|
span.setStatus({
|
|
389
381
|
code: SpanStatusCode.ERROR,
|
|
@@ -395,52 +387,52 @@ var FederationBuilderImpl = class {
|
|
|
395
387
|
}
|
|
396
388
|
});
|
|
397
389
|
if (actor == null) return null;
|
|
398
|
-
const logger
|
|
390
|
+
const logger = getLogger([
|
|
399
391
|
"fedify",
|
|
400
392
|
"federation",
|
|
401
393
|
"actor"
|
|
402
394
|
]);
|
|
403
|
-
if (actor.id == null) logger
|
|
404
|
-
else if (actor.id.href != context
|
|
395
|
+
if (actor.id == null) logger.warn("Actor dispatcher returned an actor without an id property. Set the property with Context.getActorUri(identifier).");
|
|
396
|
+
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).");
|
|
405
397
|
if (this.followingCallbacks != null && this.followingCallbacks.dispatcher != null) {
|
|
406
|
-
if (actor.followingId == null) logger
|
|
407
|
-
else if (actor.followingId.href != context
|
|
398
|
+
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).");
|
|
399
|
+
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).");
|
|
408
400
|
}
|
|
409
401
|
if (this.followersCallbacks != null && this.followersCallbacks.dispatcher != null) {
|
|
410
|
-
if (actor.followersId == null) logger
|
|
411
|
-
else if (actor.followersId.href != context
|
|
402
|
+
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).");
|
|
403
|
+
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).");
|
|
412
404
|
}
|
|
413
405
|
if (this.outboxCallbacks != null && this.outboxCallbacks.dispatcher != null) {
|
|
414
|
-
if (actor?.outboxId == null) logger
|
|
415
|
-
else if (actor.outboxId.href != context
|
|
406
|
+
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).");
|
|
407
|
+
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).");
|
|
416
408
|
}
|
|
417
409
|
if (this.likedCallbacks != null && this.likedCallbacks.dispatcher != null) {
|
|
418
|
-
if (actor?.likedId == null) logger
|
|
419
|
-
else if (actor.likedId.href != context
|
|
410
|
+
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).");
|
|
411
|
+
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).");
|
|
420
412
|
}
|
|
421
413
|
if (this.featuredCallbacks != null && this.featuredCallbacks.dispatcher != null) {
|
|
422
|
-
if (actor?.featuredId == null) logger
|
|
423
|
-
else if (actor.featuredId.href != context
|
|
414
|
+
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).");
|
|
415
|
+
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).");
|
|
424
416
|
}
|
|
425
417
|
if (this.featuredTagsCallbacks != null && this.featuredTagsCallbacks.dispatcher != null) {
|
|
426
|
-
if (actor?.featuredTagsId == null) logger
|
|
427
|
-
else if (actor.featuredTagsId.href != context
|
|
418
|
+
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).");
|
|
419
|
+
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).");
|
|
428
420
|
}
|
|
429
421
|
if (this.router.has("inbox")) {
|
|
430
|
-
if (actor.inboxId == null) logger
|
|
431
|
-
else if (actor.inboxId.href != context
|
|
432
|
-
if (actor.endpoints == null || actor.endpoints.sharedInbox == null) logger
|
|
433
|
-
else if (actor.endpoints.sharedInbox.href != context
|
|
422
|
+
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).");
|
|
423
|
+
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).");
|
|
424
|
+
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().");
|
|
425
|
+
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().");
|
|
434
426
|
}
|
|
435
427
|
if (callbacks.keyPairsDispatcher != null) {
|
|
436
|
-
if (actor.publicKeyId == null) logger
|
|
437
|
-
if (actor.assertionMethodId == null) logger
|
|
428
|
+
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).");
|
|
429
|
+
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).");
|
|
438
430
|
}
|
|
439
431
|
return actor;
|
|
440
432
|
} };
|
|
441
433
|
this.actorCallbacks = callbacks;
|
|
442
434
|
const setters = {
|
|
443
|
-
setKeyPairsDispatcher: (dispatcher
|
|
435
|
+
setKeyPairsDispatcher: (dispatcher) => {
|
|
444
436
|
callbacks.keyPairsDispatcher = (ctx, identifier) => this._getTracer().startActiveSpan("activitypub.dispatch_actor_key_pairs", {
|
|
445
437
|
kind: SpanKind.SERVER,
|
|
446
438
|
attributes: {
|
|
@@ -449,7 +441,7 @@ var FederationBuilderImpl = class {
|
|
|
449
441
|
}
|
|
450
442
|
}, async (span) => {
|
|
451
443
|
try {
|
|
452
|
-
return await dispatcher
|
|
444
|
+
return await dispatcher(ctx, identifier);
|
|
453
445
|
} catch (e) {
|
|
454
446
|
span.setStatus({
|
|
455
447
|
code: SpanStatusCode.ERROR,
|
|
@@ -479,8 +471,7 @@ var FederationBuilderImpl = class {
|
|
|
479
471
|
}
|
|
480
472
|
setNodeInfoDispatcher(path, dispatcher) {
|
|
481
473
|
if (this.router.has("nodeInfo")) throw new RouterError("NodeInfo dispatcher already set.");
|
|
482
|
-
|
|
483
|
-
if (variables.size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
|
|
474
|
+
if (this.router.add(path, "nodeInfo").size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
|
|
484
475
|
this.nodeInfoDispatcher = dispatcher;
|
|
485
476
|
}
|
|
486
477
|
setWebFingerLinksDispatcher(dispatcher) {
|
|
@@ -493,8 +484,7 @@ var FederationBuilderImpl = class {
|
|
|
493
484
|
if (variables.size < 1) throw new RouterError("Path for object dispatcher must have at least one variable.");
|
|
494
485
|
const callbacks = {
|
|
495
486
|
dispatcher: (ctx, values) => {
|
|
496
|
-
|
|
497
|
-
return tracer.startActiveSpan("activitypub.dispatch_object", {
|
|
487
|
+
return this._getTracer().startActiveSpan("activitypub.dispatch_object", {
|
|
498
488
|
kind: SpanKind.SERVER,
|
|
499
489
|
attributes: {
|
|
500
490
|
"fedify.object.type": cls.typeId.href,
|
|
@@ -725,8 +715,7 @@ var FederationBuilderImpl = class {
|
|
|
725
715
|
this.inboxPath = inboxPath;
|
|
726
716
|
}
|
|
727
717
|
if (sharedInboxPath != null) {
|
|
728
|
-
|
|
729
|
-
if (siVars.size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
|
|
718
|
+
if (this.router.add(sharedInboxPath, "sharedInbox").size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
|
|
730
719
|
}
|
|
731
720
|
const listeners = this.inboxListeners = new InboxListenerSet();
|
|
732
721
|
const setters = {
|
|
@@ -764,8 +753,7 @@ var FederationBuilderImpl = class {
|
|
|
764
753
|
const routeName = `${collectionType}:${this.#uniqueCollectionId(name)}`;
|
|
765
754
|
if (this.router.has(routeName)) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
|
|
766
755
|
if (this.collectionCallbacks[name] != null) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
|
|
767
|
-
|
|
768
|
-
if (variables.size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
|
|
756
|
+
if (this.router.add(path, routeName).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
|
|
769
757
|
const callbacks = { dispatcher };
|
|
770
758
|
this.collectionCallbacks[name] = callbacks;
|
|
771
759
|
this.collectionTypeIds[name] = itemType;
|
|
@@ -800,8 +788,7 @@ var FederationBuilderImpl = class {
|
|
|
800
788
|
getCollectionPath(name, values) {
|
|
801
789
|
if (!(name in this.collectionCallbacks)) return null;
|
|
802
790
|
const routeName = this.#uniqueCollectionId(name);
|
|
803
|
-
|
|
804
|
-
return path;
|
|
791
|
+
return this.router.build(`collection:${routeName}`, values) ?? this.router.build(`orderedCollection:${routeName}`, values);
|
|
805
792
|
}
|
|
806
793
|
setOutboxPermanentFailureHandler(handler) {
|
|
807
794
|
this.outboxPermanentFailureHandler = handler;
|
|
@@ -827,7 +814,6 @@ var FederationBuilderImpl = class {
|
|
|
827
814
|
function createFederationBuilder() {
|
|
828
815
|
return new FederationBuilderImpl();
|
|
829
816
|
}
|
|
830
|
-
|
|
831
817
|
//#endregion
|
|
832
818
|
//#region src/federation/collection.ts
|
|
833
819
|
/**
|
|
@@ -846,8 +832,8 @@ async function digest(uris) {
|
|
|
846
832
|
if (processed.has(u)) continue;
|
|
847
833
|
processed.add(u);
|
|
848
834
|
const encoded = encoder.encode(u);
|
|
849
|
-
const digest
|
|
850
|
-
for (let i = 0; i < 32; i++) result[i] ^= digest
|
|
835
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", encoded));
|
|
836
|
+
for (let i = 0; i < 32; i++) result[i] ^= digest[i];
|
|
851
837
|
}
|
|
852
838
|
return result;
|
|
853
839
|
}
|
|
@@ -865,10 +851,8 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
|
|
|
865
851
|
const baseUrl = new URL(anyActorId);
|
|
866
852
|
const url = new URL(collectionId);
|
|
867
853
|
url.searchParams.set("base-url", `${baseUrl.origin}/`);
|
|
868
|
-
|
|
869
|
-
return `collectionId="${collectionId}", url="${url}", digest="${hash}"`;
|
|
854
|
+
return `collectionId="${collectionId}", url="${url}", digest="${encodeHex(await digest(actorIds))}"`;
|
|
870
855
|
}
|
|
871
|
-
|
|
872
856
|
//#endregion
|
|
873
857
|
//#region src/federation/keycache.ts
|
|
874
858
|
var KvKeyCache = class {
|
|
@@ -910,7 +894,7 @@ var KvKeyCache = class {
|
|
|
910
894
|
return await Multikey.fromJsonLd(serialized, this.options);
|
|
911
895
|
} catch {
|
|
912
896
|
await this.kv.delete([...this.prefix, keyId.href]);
|
|
913
|
-
return
|
|
897
|
+
return;
|
|
914
898
|
}
|
|
915
899
|
}
|
|
916
900
|
}
|
|
@@ -940,7 +924,6 @@ var KvKeyCache = class {
|
|
|
940
924
|
error.name = cached.errorName;
|
|
941
925
|
return { error };
|
|
942
926
|
}
|
|
943
|
-
return void 0;
|
|
944
927
|
}
|
|
945
928
|
async setFetchError(keyId, error) {
|
|
946
929
|
if (error == null) {
|
|
@@ -962,7 +945,6 @@ var KvKeyCache = class {
|
|
|
962
945
|
}, { ttl: this.unavailableKeyTtl });
|
|
963
946
|
}
|
|
964
947
|
};
|
|
965
|
-
|
|
966
948
|
//#endregion
|
|
967
949
|
//#region src/federation/negotiation.ts
|
|
968
950
|
function compareSpecs(a, b) {
|
|
@@ -1007,8 +989,8 @@ function parseMediaType(str, i) {
|
|
|
1007
989
|
function parseAccept(accept) {
|
|
1008
990
|
const accepts = accept.split(",").map((p) => p.trim());
|
|
1009
991
|
const mediaTypes = [];
|
|
1010
|
-
for (const [index, accept
|
|
1011
|
-
const mediaType = parseMediaType(accept
|
|
992
|
+
for (const [index, accept] of accepts.entries()) {
|
|
993
|
+
const mediaType = parseMediaType(accept.trim(), index);
|
|
1012
994
|
if (mediaType) mediaTypes.push(mediaType);
|
|
1013
995
|
}
|
|
1014
996
|
return mediaTypes;
|
|
@@ -1017,8 +999,7 @@ function getFullType(spec) {
|
|
|
1017
999
|
return `${spec.type}/${spec.subtype}`;
|
|
1018
1000
|
}
|
|
1019
1001
|
function preferredMediaTypes(accept) {
|
|
1020
|
-
|
|
1021
|
-
return accepts.filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
1002
|
+
return parseAccept(accept === void 0 ? "*/*" : accept ?? "").filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
1022
1003
|
}
|
|
1023
1004
|
function acceptsJsonLd(request) {
|
|
1024
1005
|
const accept = request.headers.get("Accept");
|
|
@@ -1027,7 +1008,6 @@ function acceptsJsonLd(request) {
|
|
|
1027
1008
|
if (types[0] === "text/html" || types[0] === "application/xhtml+xml") return false;
|
|
1028
1009
|
return types.includes("application/activity+json") || types.includes("application/ld+json") || types.includes("application/json");
|
|
1029
1010
|
}
|
|
1030
|
-
|
|
1031
1011
|
//#endregion
|
|
1032
1012
|
//#region src/federation/handler.ts
|
|
1033
1013
|
/**
|
|
@@ -1037,25 +1017,25 @@ function acceptsJsonLd(request) {
|
|
|
1037
1017
|
* @param parameters The parameters for handling the actor.
|
|
1038
1018
|
* @returns A promise that resolves to an HTTP response.
|
|
1039
1019
|
*/
|
|
1040
|
-
async function handleActor(request, { identifier, context
|
|
1041
|
-
const logger
|
|
1020
|
+
async function handleActor(request, { identifier, context, actorDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
1021
|
+
const logger = getLogger([
|
|
1042
1022
|
"fedify",
|
|
1043
1023
|
"federation",
|
|
1044
1024
|
"actor"
|
|
1045
1025
|
]);
|
|
1046
1026
|
if (actorDispatcher == null) {
|
|
1047
|
-
logger
|
|
1027
|
+
logger.debug("Actor dispatcher is not set.", { identifier });
|
|
1048
1028
|
return await onNotFound(request);
|
|
1049
1029
|
}
|
|
1050
|
-
const actor = await actorDispatcher(context
|
|
1030
|
+
const actor = await actorDispatcher(context, identifier);
|
|
1051
1031
|
if (actor == null) {
|
|
1052
|
-
logger
|
|
1032
|
+
logger.debug("Actor {identifier} not found.", { identifier });
|
|
1053
1033
|
return await onNotFound(request);
|
|
1054
1034
|
}
|
|
1055
1035
|
if (authorizePredicate != null) {
|
|
1056
|
-
if (!await authorizePredicate(context
|
|
1036
|
+
if (!await authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
1057
1037
|
}
|
|
1058
|
-
const jsonLd = await actor.toJsonLd(context
|
|
1038
|
+
const jsonLd = await actor.toJsonLd(context);
|
|
1059
1039
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1060
1040
|
"Content-Type": "application/activity+json",
|
|
1061
1041
|
Vary: "Accept"
|
|
@@ -1068,14 +1048,14 @@ async function handleActor(request, { identifier, context: context$1, actorDispa
|
|
|
1068
1048
|
* @param parameters The parameters for handling the object.
|
|
1069
1049
|
* @returns A promise that resolves to an HTTP response.
|
|
1070
1050
|
*/
|
|
1071
|
-
async function handleObject(request, { values, context
|
|
1051
|
+
async function handleObject(request, { values, context, objectDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
1072
1052
|
if (objectDispatcher == null) return await onNotFound(request);
|
|
1073
|
-
const object = await objectDispatcher(context
|
|
1053
|
+
const object = await objectDispatcher(context, values);
|
|
1074
1054
|
if (object == null) return await onNotFound(request);
|
|
1075
1055
|
if (authorizePredicate != null) {
|
|
1076
|
-
if (!await authorizePredicate(context
|
|
1056
|
+
if (!await authorizePredicate(context, values)) return await onUnauthorized(request);
|
|
1077
1057
|
}
|
|
1078
|
-
const jsonLd = await object.toJsonLd(context
|
|
1058
|
+
const jsonLd = await object.toJsonLd(context);
|
|
1079
1059
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1080
1060
|
"Content-Type": "application/activity+json",
|
|
1081
1061
|
Vary: "Accept"
|
|
@@ -1091,18 +1071,17 @@ async function handleObject(request, { values, context: context$1, objectDispatc
|
|
|
1091
1071
|
* @param parameters The parameters for handling the collection.
|
|
1092
1072
|
* @returns A promise that resolves to an HTTP response.
|
|
1093
1073
|
*/
|
|
1094
|
-
async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context
|
|
1095
|
-
const spanName = name.trim().replace(/\s+/g, "_");
|
|
1074
|
+
async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound }) {
|
|
1075
|
+
const spanName = name$2.trim().replace(/\s+/g, "_");
|
|
1096
1076
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
1097
|
-
const tracer = tracerProvider.getTracer(
|
|
1098
|
-
const
|
|
1099
|
-
const cursor = url.searchParams.get("cursor");
|
|
1077
|
+
const tracer = tracerProvider.getTracer(name, version);
|
|
1078
|
+
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1100
1079
|
if (collectionCallbacks == null) return await onNotFound(request);
|
|
1101
1080
|
let collection;
|
|
1102
1081
|
const baseUri = uriGetter(identifier);
|
|
1103
1082
|
if (cursor == null) {
|
|
1104
|
-
const firstCursor = await collectionCallbacks.firstCursor?.(context
|
|
1105
|
-
const totalItems = filter == null ? await collectionCallbacks.counter?.(context
|
|
1083
|
+
const firstCursor = await collectionCallbacks.firstCursor?.(context, identifier);
|
|
1084
|
+
const totalItems = filter == null ? await collectionCallbacks.counter?.(context, identifier) : void 0;
|
|
1106
1085
|
if (firstCursor == null) {
|
|
1107
1086
|
const itemsOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection ${spanName}`, {
|
|
1108
1087
|
kind: SpanKind.SERVER,
|
|
@@ -1113,7 +1092,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1113
1092
|
}, async (span) => {
|
|
1114
1093
|
if (totalItems != null) span.setAttribute("activitypub.collection.total_items", Number(totalItems));
|
|
1115
1094
|
try {
|
|
1116
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1095
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
|
|
1117
1096
|
if (page == null) {
|
|
1118
1097
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1119
1098
|
return await onNotFound(request);
|
|
@@ -1135,15 +1114,15 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1135
1114
|
collection = new OrderedCollection({
|
|
1136
1115
|
id: baseUri,
|
|
1137
1116
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
1138
|
-
items: filterCollectionItems(itemsOrResponse, name, filterPredicate)
|
|
1117
|
+
items: filterCollectionItems(itemsOrResponse, name$2, filterPredicate)
|
|
1139
1118
|
});
|
|
1140
1119
|
} else {
|
|
1141
|
-
const lastCursor = await collectionCallbacks.lastCursor?.(context
|
|
1142
|
-
const first = new URL(context
|
|
1120
|
+
const lastCursor = await collectionCallbacks.lastCursor?.(context, identifier);
|
|
1121
|
+
const first = new URL(context.url);
|
|
1143
1122
|
first.searchParams.set("cursor", firstCursor);
|
|
1144
1123
|
let last = null;
|
|
1145
1124
|
if (lastCursor != null) {
|
|
1146
|
-
last = new URL(context
|
|
1125
|
+
last = new URL(context.url);
|
|
1147
1126
|
last.searchParams.set("cursor", lastCursor);
|
|
1148
1127
|
}
|
|
1149
1128
|
collection = new OrderedCollection({
|
|
@@ -1156,7 +1135,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1156
1135
|
} else {
|
|
1157
1136
|
const uri = new URL(baseUri);
|
|
1158
1137
|
uri.searchParams.set("cursor", cursor);
|
|
1159
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name}`, {
|
|
1138
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
|
|
1160
1139
|
kind: SpanKind.SERVER,
|
|
1161
1140
|
attributes: {
|
|
1162
1141
|
"activitypub.collection.id": uri.href,
|
|
@@ -1165,7 +1144,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1165
1144
|
}
|
|
1166
1145
|
}, async (span) => {
|
|
1167
1146
|
try {
|
|
1168
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
1147
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
|
|
1169
1148
|
if (page == null) {
|
|
1170
1149
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1171
1150
|
return await onNotFound(request);
|
|
@@ -1186,28 +1165,28 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
1186
1165
|
const { items, prevCursor, nextCursor } = pageOrResponse;
|
|
1187
1166
|
let prev = null;
|
|
1188
1167
|
if (prevCursor != null) {
|
|
1189
|
-
prev = new URL(context
|
|
1168
|
+
prev = new URL(context.url);
|
|
1190
1169
|
prev.searchParams.set("cursor", prevCursor);
|
|
1191
1170
|
}
|
|
1192
1171
|
let next = null;
|
|
1193
1172
|
if (nextCursor != null) {
|
|
1194
|
-
next = new URL(context
|
|
1173
|
+
next = new URL(context.url);
|
|
1195
1174
|
next.searchParams.set("cursor", nextCursor);
|
|
1196
1175
|
}
|
|
1197
|
-
const partOf = new URL(context
|
|
1176
|
+
const partOf = new URL(context.url);
|
|
1198
1177
|
partOf.searchParams.delete("cursor");
|
|
1199
1178
|
collection = new OrderedCollectionPage({
|
|
1200
1179
|
id: uri,
|
|
1201
1180
|
prev,
|
|
1202
1181
|
next,
|
|
1203
|
-
items: filterCollectionItems(items, name, filterPredicate),
|
|
1182
|
+
items: filterCollectionItems(items, name$2, filterPredicate),
|
|
1204
1183
|
partOf
|
|
1205
1184
|
});
|
|
1206
1185
|
}
|
|
1207
1186
|
if (collectionCallbacks.authorizePredicate != null) {
|
|
1208
|
-
if (!await collectionCallbacks.authorizePredicate(context
|
|
1187
|
+
if (!await collectionCallbacks.authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
1209
1188
|
}
|
|
1210
|
-
const jsonLd = await collection.toJsonLd(context
|
|
1189
|
+
const jsonLd = await collection.toJsonLd(context);
|
|
1211
1190
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
1212
1191
|
"Content-Type": "application/activity+json",
|
|
1213
1192
|
Vary: "Accept"
|
|
@@ -1252,9 +1231,7 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
1252
1231
|
* @returns A promise that resolves to an HTTP response.
|
|
1253
1232
|
*/
|
|
1254
1233
|
async function handleInbox(request, options) {
|
|
1255
|
-
|
|
1256
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
1257
|
-
return await tracer.startActiveSpan("activitypub.inbox", {
|
|
1234
|
+
return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("activitypub.inbox", {
|
|
1258
1235
|
kind: options.queue == null ? SpanKind.SERVER : SpanKind.PRODUCER,
|
|
1259
1236
|
attributes: { "activitypub.shared_inbox": options.recipient == null }
|
|
1260
1237
|
}, async (span) => {
|
|
@@ -1282,22 +1259,21 @@ async function handleInbox(request, options) {
|
|
|
1282
1259
|
*/
|
|
1283
1260
|
async function handleInboxInternal(request, parameters, span) {
|
|
1284
1261
|
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, inboxChallengePolicy, tracerProvider } = parameters;
|
|
1285
|
-
const logger
|
|
1262
|
+
const logger = getLogger([
|
|
1286
1263
|
"fedify",
|
|
1287
1264
|
"federation",
|
|
1288
1265
|
"inbox"
|
|
1289
1266
|
]);
|
|
1290
1267
|
if (actorDispatcher == null) {
|
|
1291
|
-
logger
|
|
1268
|
+
logger.error("Actor dispatcher is not set.", { recipient });
|
|
1292
1269
|
span.setStatus({
|
|
1293
1270
|
code: SpanStatusCode.ERROR,
|
|
1294
1271
|
message: "Actor dispatcher is not set."
|
|
1295
1272
|
});
|
|
1296
1273
|
return await onNotFound(request);
|
|
1297
1274
|
} else if (recipient != null) {
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
logger$1.error("Actor {recipient} not found.", { recipient });
|
|
1275
|
+
if (await actorDispatcher(ctx, recipient) == null) {
|
|
1276
|
+
logger.error("Actor {recipient} not found.", { recipient });
|
|
1301
1277
|
span.setStatus({
|
|
1302
1278
|
code: SpanStatusCode.ERROR,
|
|
1303
1279
|
message: `Actor ${recipient} not found.`
|
|
@@ -1306,7 +1282,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1306
1282
|
}
|
|
1307
1283
|
}
|
|
1308
1284
|
if (request.bodyUsed) {
|
|
1309
|
-
logger
|
|
1285
|
+
logger.error("Request body has already been read.", { recipient });
|
|
1310
1286
|
span.setStatus({
|
|
1311
1287
|
code: SpanStatusCode.ERROR,
|
|
1312
1288
|
message: "Request body has already been read."
|
|
@@ -1316,7 +1292,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1316
1292
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1317
1293
|
});
|
|
1318
1294
|
} else if (request.body?.locked) {
|
|
1319
|
-
logger
|
|
1295
|
+
logger.error("Request body is locked.", { recipient });
|
|
1320
1296
|
span.setStatus({
|
|
1321
1297
|
code: SpanStatusCode.ERROR,
|
|
1322
1298
|
message: "Request body is locked."
|
|
@@ -1330,15 +1306,15 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1330
1306
|
try {
|
|
1331
1307
|
json = await request.clone().json();
|
|
1332
1308
|
} catch (error) {
|
|
1333
|
-
logger
|
|
1309
|
+
logger.error("Failed to parse JSON:\n{error}", {
|
|
1334
1310
|
recipient,
|
|
1335
1311
|
error
|
|
1336
1312
|
});
|
|
1337
1313
|
try {
|
|
1338
1314
|
await inboxErrorHandler?.(ctx, error);
|
|
1339
|
-
} catch (error
|
|
1340
|
-
logger
|
|
1341
|
-
error
|
|
1315
|
+
} catch (error) {
|
|
1316
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1317
|
+
error,
|
|
1342
1318
|
activity: json,
|
|
1343
1319
|
recipient
|
|
1344
1320
|
});
|
|
@@ -1363,7 +1339,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1363
1339
|
});
|
|
1364
1340
|
} catch (error) {
|
|
1365
1341
|
if (error instanceof Error && error.name === "jsonld.SyntaxError") {
|
|
1366
|
-
logger
|
|
1342
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
1367
1343
|
recipient,
|
|
1368
1344
|
error
|
|
1369
1345
|
});
|
|
@@ -1378,14 +1354,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1378
1354
|
let activity = null;
|
|
1379
1355
|
let activityVerified = false;
|
|
1380
1356
|
if (ldSigVerified) {
|
|
1381
|
-
logger
|
|
1357
|
+
logger.debug("Linked Data Signatures are verified.", {
|
|
1382
1358
|
recipient,
|
|
1383
1359
|
json
|
|
1384
1360
|
});
|
|
1385
1361
|
activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1386
1362
|
activityVerified = true;
|
|
1387
1363
|
} else {
|
|
1388
|
-
logger
|
|
1364
|
+
logger.debug("Linked Data Signatures are not verified.", {
|
|
1389
1365
|
recipient,
|
|
1390
1366
|
json
|
|
1391
1367
|
});
|
|
@@ -1397,16 +1373,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1397
1373
|
tracerProvider
|
|
1398
1374
|
});
|
|
1399
1375
|
} catch (error) {
|
|
1400
|
-
logger
|
|
1376
|
+
logger.error("Failed to parse activity:\n{error}", {
|
|
1401
1377
|
recipient,
|
|
1402
1378
|
activity: json,
|
|
1403
1379
|
error
|
|
1404
1380
|
});
|
|
1405
1381
|
try {
|
|
1406
1382
|
await inboxErrorHandler?.(ctx, error);
|
|
1407
|
-
} catch (error
|
|
1408
|
-
logger
|
|
1409
|
-
error
|
|
1383
|
+
} catch (error) {
|
|
1384
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1385
|
+
error,
|
|
1410
1386
|
activity: json,
|
|
1411
1387
|
recipient
|
|
1412
1388
|
});
|
|
@@ -1420,12 +1396,12 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1420
1396
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1421
1397
|
});
|
|
1422
1398
|
}
|
|
1423
|
-
if (activity == null) logger
|
|
1399
|
+
if (activity == null) logger.debug("Object Integrity Proofs are not verified.", {
|
|
1424
1400
|
recipient,
|
|
1425
1401
|
activity: json
|
|
1426
1402
|
});
|
|
1427
1403
|
else {
|
|
1428
|
-
logger
|
|
1404
|
+
logger.debug("Object Integrity Proofs are verified.", {
|
|
1429
1405
|
recipient,
|
|
1430
1406
|
activity: json
|
|
1431
1407
|
});
|
|
@@ -1445,7 +1421,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1445
1421
|
});
|
|
1446
1422
|
if (verification.verified === false) {
|
|
1447
1423
|
const reason = verification.reason;
|
|
1448
|
-
logger
|
|
1424
|
+
logger.error("Failed to verify the request's HTTP Signatures.", {
|
|
1449
1425
|
recipient,
|
|
1450
1426
|
reason: reason.type,
|
|
1451
1427
|
keyId: "keyId" in reason ? reason.keyId?.href : void 0
|
|
@@ -1458,16 +1434,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1458
1434
|
try {
|
|
1459
1435
|
activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
1460
1436
|
} catch (error) {
|
|
1461
|
-
logger
|
|
1437
|
+
logger.error("Failed to parse activity:\n{error}", {
|
|
1462
1438
|
recipient,
|
|
1463
1439
|
activity: json,
|
|
1464
1440
|
error
|
|
1465
1441
|
});
|
|
1466
1442
|
try {
|
|
1467
1443
|
await inboxErrorHandler?.(ctx, error);
|
|
1468
|
-
} catch (error
|
|
1469
|
-
logger
|
|
1470
|
-
error
|
|
1444
|
+
} catch (error) {
|
|
1445
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1446
|
+
error,
|
|
1471
1447
|
activity: json,
|
|
1472
1448
|
recipient
|
|
1473
1449
|
});
|
|
@@ -1494,16 +1470,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1494
1470
|
try {
|
|
1495
1471
|
response = await unverifiedActivityHandler(ctx, activity, reason);
|
|
1496
1472
|
} catch (error) {
|
|
1497
|
-
logger
|
|
1473
|
+
logger.error("An unexpected error occurred in unverified activity handler:\n{error}", {
|
|
1498
1474
|
error,
|
|
1499
1475
|
activity: json,
|
|
1500
1476
|
recipient
|
|
1501
1477
|
});
|
|
1502
1478
|
try {
|
|
1503
1479
|
await inboxErrorHandler?.(ctx, error);
|
|
1504
|
-
} catch (error
|
|
1505
|
-
logger
|
|
1506
|
-
error
|
|
1480
|
+
} catch (error) {
|
|
1481
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1482
|
+
error,
|
|
1507
1483
|
activity: json,
|
|
1508
1484
|
recipient
|
|
1509
1485
|
});
|
|
@@ -1514,7 +1490,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1514
1490
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
1515
1491
|
} else {
|
|
1516
1492
|
if (inboxChallengePolicy?.enabled && inboxChallengePolicy.requestNonce) pendingNonceLabel = verification.signatureLabel;
|
|
1517
|
-
logger
|
|
1493
|
+
logger.debug("HTTP Signatures are verified.", { recipient });
|
|
1518
1494
|
activityVerified = true;
|
|
1519
1495
|
}
|
|
1520
1496
|
httpSigKey = verification.key;
|
|
@@ -1531,7 +1507,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1531
1507
|
"http_signatures.key_id": httpSigKey?.id?.href ?? ""
|
|
1532
1508
|
});
|
|
1533
1509
|
if (httpSigKey != null && !await doesActorOwnKey(activity, httpSigKey, ctx)) {
|
|
1534
|
-
logger
|
|
1510
|
+
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
|
1535
1511
|
activity: json,
|
|
1536
1512
|
recipient,
|
|
1537
1513
|
keyId: httpSigKey.id?.href,
|
|
@@ -1547,9 +1523,8 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1547
1523
|
});
|
|
1548
1524
|
}
|
|
1549
1525
|
if (pendingNonceLabel != null) {
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
logger$1.error("Signature nonce verification failed (missing, expired, or replayed).", { recipient });
|
|
1526
|
+
if (!await verifySignatureNonce(request, kv, kvPrefixes.acceptSignatureNonce, pendingNonceLabel)) {
|
|
1527
|
+
logger.error("Signature nonce verification failed (missing, expired, or replayed).", { recipient });
|
|
1553
1528
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
1554
1529
|
}
|
|
1555
1530
|
}
|
|
@@ -1605,11 +1580,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1605
1580
|
* @since 1.8.0
|
|
1606
1581
|
*/
|
|
1607
1582
|
const handleCustomCollection = exceptWrapper(_handleCustomCollection);
|
|
1608
|
-
async function _handleCustomCollection(request, { name, values, context
|
|
1583
|
+
async function _handleCustomCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1609
1584
|
verifyDefined(callbacks);
|
|
1610
|
-
await authIfNeeded(context
|
|
1585
|
+
await authIfNeeded(context, values, callbacks);
|
|
1611
1586
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1612
|
-
return await new CustomCollectionHandler(name, values, context
|
|
1587
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, Collection, CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1613
1588
|
}
|
|
1614
1589
|
/**
|
|
1615
1590
|
* Handles an ordered collection request.
|
|
@@ -1623,11 +1598,11 @@ async function _handleCustomCollection(request, { name, values, context: context
|
|
|
1623
1598
|
* @since 1.8.0
|
|
1624
1599
|
*/
|
|
1625
1600
|
const handleOrderedCollection = exceptWrapper(_handleOrderedCollection);
|
|
1626
|
-
async function _handleOrderedCollection(request, { name, values, context
|
|
1601
|
+
async function _handleOrderedCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
1627
1602
|
verifyDefined(callbacks);
|
|
1628
|
-
await authIfNeeded(context
|
|
1603
|
+
await authIfNeeded(context, values, callbacks);
|
|
1629
1604
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1630
|
-
return await new CustomCollectionHandler(name, values, context
|
|
1605
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, OrderedCollection, OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
1631
1606
|
}
|
|
1632
1607
|
/**
|
|
1633
1608
|
* Handling custom collections with support for pagination and filtering.
|
|
@@ -1677,17 +1652,17 @@ var CustomCollectionHandler = class {
|
|
|
1677
1652
|
* @param CollectionPage The CollectionPage constructor.
|
|
1678
1653
|
* @param filterPredicate Optional filter predicate for items.
|
|
1679
1654
|
*/
|
|
1680
|
-
constructor(name, values, context
|
|
1681
|
-
this.name = name;
|
|
1655
|
+
constructor(name$1, values, context, callbacks, tracerProvider = trace.getTracerProvider(), Collection, CollectionPage, filterPredicate) {
|
|
1656
|
+
this.name = name$1;
|
|
1682
1657
|
this.values = values;
|
|
1683
|
-
this.context = context
|
|
1658
|
+
this.context = context;
|
|
1684
1659
|
this.callbacks = callbacks;
|
|
1685
1660
|
this.tracerProvider = tracerProvider;
|
|
1686
|
-
this.Collection = Collection
|
|
1687
|
-
this.CollectionPage = CollectionPage
|
|
1661
|
+
this.Collection = Collection;
|
|
1662
|
+
this.CollectionPage = CollectionPage;
|
|
1688
1663
|
this.filterPredicate = filterPredicate;
|
|
1689
1664
|
this.name = this.name.trim().replace(/\s+/g, "_");
|
|
1690
|
-
this.#tracer = this.tracerProvider.getTracer(
|
|
1665
|
+
this.#tracer = this.tracerProvider.getTracer(name, version);
|
|
1691
1666
|
this.#id = new URL(this.context.url);
|
|
1692
1667
|
this.#dispatcher = callbacks.dispatcher.bind(callbacks);
|
|
1693
1668
|
}
|
|
@@ -1716,8 +1691,8 @@ var CustomCollectionHandler = class {
|
|
|
1716
1691
|
*/
|
|
1717
1692
|
async getCollection(cursor = null) {
|
|
1718
1693
|
if (cursor !== null) {
|
|
1719
|
-
const props
|
|
1720
|
-
return new this.CollectionPage(props
|
|
1694
|
+
const props = await this.getPageProps(cursor);
|
|
1695
|
+
return new this.CollectionPage(props);
|
|
1721
1696
|
}
|
|
1722
1697
|
const firstCursor = await this.firstCursor;
|
|
1723
1698
|
const props = typeof firstCursor === "string" ? await this.getProps(firstCursor) : await this.getPropsWithoutCursor();
|
|
@@ -1865,7 +1840,7 @@ var CustomCollectionHandler = class {
|
|
|
1865
1840
|
* @param value The total items count or a promise that resolves to it.
|
|
1866
1841
|
*/
|
|
1867
1842
|
set totalItems(value) {
|
|
1868
|
-
const toNumber = (value
|
|
1843
|
+
const toNumber = (value) => value == null ? null : Number(value);
|
|
1869
1844
|
this.#totalItems = value instanceof Promise ? value.then(toNumber) : Promise.resolve(toNumber(value));
|
|
1870
1845
|
}
|
|
1871
1846
|
/**
|
|
@@ -1929,9 +1904,9 @@ const verifyDefined = (callbacks) => {
|
|
|
1929
1904
|
* @throws {UnauthorizedError} If authorization fails.
|
|
1930
1905
|
* @since 1.8.0
|
|
1931
1906
|
*/
|
|
1932
|
-
const authIfNeeded = async (context
|
|
1907
|
+
const authIfNeeded = async (context, values, { authorizePredicate: authorize = void 0 }) => {
|
|
1933
1908
|
if (authorize === void 0) return;
|
|
1934
|
-
if (!await authorize(context
|
|
1909
|
+
if (!await authorize(context, values)) throw new UnauthorizedError();
|
|
1935
1910
|
};
|
|
1936
1911
|
/**
|
|
1937
1912
|
* Appends a cursor parameter to a URL if the cursor exists.
|
|
@@ -2033,8 +2008,7 @@ async function verifySignatureNonce(request, kv, noncePrefix, verifiedLabel) {
|
|
|
2033
2008
|
if (nonce == null) return false;
|
|
2034
2009
|
const key = [...noncePrefix, nonce];
|
|
2035
2010
|
if (kv.cas != null) return await kv.cas(key, true, void 0);
|
|
2036
|
-
|
|
2037
|
-
if (stored != null) {
|
|
2011
|
+
if (await kv.get(key) != null) {
|
|
2038
2012
|
await kv.delete(key);
|
|
2039
2013
|
return true;
|
|
2040
2014
|
}
|
|
@@ -2059,18 +2033,16 @@ async function buildAcceptSignatureHeader(policy, kv, noncePrefix) {
|
|
|
2059
2033
|
const parameters = { created: true };
|
|
2060
2034
|
if (policy.requestNonce) {
|
|
2061
2035
|
const nonce = generateNonce();
|
|
2062
|
-
|
|
2063
|
-
await setKey(kv, key, policy);
|
|
2036
|
+
await setKey(kv, [...noncePrefix, nonce], policy);
|
|
2064
2037
|
parameters.nonce = nonce;
|
|
2065
2038
|
}
|
|
2066
2039
|
const baseComponents = policy.components ?? DEF_COMPONENTS;
|
|
2067
|
-
const components = uniq(MIN_COMPONENTS.concat(baseComponents)).filter((c) => c !== "@status").map((v) => ({
|
|
2068
|
-
value: v,
|
|
2069
|
-
params: {}
|
|
2070
|
-
}));
|
|
2071
2040
|
return formatAcceptSignature([{
|
|
2072
2041
|
label: "sig1",
|
|
2073
|
-
components
|
|
2042
|
+
components: uniq(MIN_COMPONENTS.concat(baseComponents)).filter((c) => c !== "@status").map((v) => ({
|
|
2043
|
+
value: v,
|
|
2044
|
+
params: {}
|
|
2045
|
+
})),
|
|
2074
2046
|
parameters
|
|
2075
2047
|
}]);
|
|
2076
2048
|
}
|
|
@@ -2090,7 +2062,6 @@ const MIN_COMPONENTS = [
|
|
|
2090
2062
|
"@target-uri",
|
|
2091
2063
|
"@authority"
|
|
2092
2064
|
];
|
|
2093
|
-
|
|
2094
2065
|
//#endregion
|
|
2095
2066
|
//#region src/nodeinfo/handler.ts
|
|
2096
2067
|
/**
|
|
@@ -2100,10 +2071,9 @@ const MIN_COMPONENTS = [
|
|
|
2100
2071
|
* @param parameters The parameters for handling the request.
|
|
2101
2072
|
* @returns The response to the request.
|
|
2102
2073
|
*/
|
|
2103
|
-
async function handleNodeInfo(_request, { context
|
|
2104
|
-
const promise = nodeInfoDispatcher(context
|
|
2105
|
-
const
|
|
2106
|
-
const json = nodeInfoToJson(nodeInfo);
|
|
2074
|
+
async function handleNodeInfo(_request, { context, nodeInfoDispatcher }) {
|
|
2075
|
+
const promise = nodeInfoDispatcher(context);
|
|
2076
|
+
const json = nodeInfoToJson(promise instanceof Promise ? await promise : promise);
|
|
2107
2077
|
return new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\"" } });
|
|
2108
2078
|
}
|
|
2109
2079
|
/**
|
|
@@ -2113,22 +2083,20 @@ async function handleNodeInfo(_request, { context: context$1, nodeInfoDispatcher
|
|
|
2113
2083
|
* @param context The request context.
|
|
2114
2084
|
* @returns The response to the request.
|
|
2115
2085
|
*/
|
|
2116
|
-
function handleNodeInfoJrd(_request, context
|
|
2086
|
+
function handleNodeInfoJrd(_request, context) {
|
|
2117
2087
|
const links = [];
|
|
2118
2088
|
try {
|
|
2119
2089
|
links.push({
|
|
2120
2090
|
rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
|
|
2121
|
-
href: context
|
|
2091
|
+
href: context.getNodeInfoUri().href,
|
|
2122
2092
|
type: "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\""
|
|
2123
2093
|
});
|
|
2124
2094
|
} catch (e) {
|
|
2125
2095
|
if (!(e instanceof RouterError)) throw e;
|
|
2126
2096
|
}
|
|
2127
|
-
const
|
|
2128
|
-
const response = new Response(JSON.stringify(jrd), { headers: { "Content-Type": "application/jrd+json" } });
|
|
2097
|
+
const response = new Response(JSON.stringify({ links }), { headers: { "Content-Type": "application/jrd+json" } });
|
|
2129
2098
|
return Promise.resolve(response);
|
|
2130
2099
|
}
|
|
2131
|
-
|
|
2132
2100
|
//#endregion
|
|
2133
2101
|
//#region src/federation/retry.ts
|
|
2134
2102
|
/**
|
|
@@ -2159,7 +2127,6 @@ function createExponentialBackoffPolicy(options = {}) {
|
|
|
2159
2127
|
return Temporal.Duration.compare(delay, maxDelay) > 0 ? maxDelay : delay;
|
|
2160
2128
|
};
|
|
2161
2129
|
}
|
|
2162
|
-
|
|
2163
2130
|
//#endregion
|
|
2164
2131
|
//#region src/federation/send.ts
|
|
2165
2132
|
/**
|
|
@@ -2197,8 +2164,7 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
|
|
|
2197
2164
|
*/
|
|
2198
2165
|
function sendActivity(options) {
|
|
2199
2166
|
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
2200
|
-
|
|
2201
|
-
return tracer.startActiveSpan("activitypub.send_activity", {
|
|
2167
|
+
return tracerProvider.getTracer(name, version).startActiveSpan("activitypub.send_activity", {
|
|
2202
2168
|
kind: SpanKind.CLIENT,
|
|
2203
2169
|
attributes: { "activitypub.shared_inbox": options.sharedInbox ?? false }
|
|
2204
2170
|
}, async (span) => {
|
|
@@ -2249,7 +2215,7 @@ async function readLimitedResponseBody(response, maxBytes) {
|
|
|
2249
2215
|
return result;
|
|
2250
2216
|
}
|
|
2251
2217
|
async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }, span) {
|
|
2252
|
-
const logger
|
|
2218
|
+
const logger = getLogger([
|
|
2253
2219
|
"fedify",
|
|
2254
2220
|
"federation",
|
|
2255
2221
|
"outbox"
|
|
@@ -2266,7 +2232,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2266
2232
|
rsaKey = key;
|
|
2267
2233
|
break;
|
|
2268
2234
|
}
|
|
2269
|
-
if (rsaKey == null) logger
|
|
2235
|
+
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.", {
|
|
2270
2236
|
inbox: inbox.href,
|
|
2271
2237
|
keys: keys.map((pair) => ({
|
|
2272
2238
|
keyId: pair.keyId.href,
|
|
@@ -2280,7 +2246,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2280
2246
|
specDeterminer
|
|
2281
2247
|
});
|
|
2282
2248
|
} catch (error) {
|
|
2283
|
-
logger
|
|
2249
|
+
logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
|
|
2284
2250
|
activityId,
|
|
2285
2251
|
inbox: inbox.href,
|
|
2286
2252
|
error
|
|
@@ -2294,7 +2260,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2294
2260
|
} catch (_) {
|
|
2295
2261
|
error = "";
|
|
2296
2262
|
}
|
|
2297
|
-
logger
|
|
2263
|
+
logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
|
|
2298
2264
|
activityId,
|
|
2299
2265
|
inbox: inbox.href,
|
|
2300
2266
|
status: response.status,
|
|
@@ -2346,7 +2312,6 @@ var SendActivityError = class extends Error {
|
|
|
2346
2312
|
this.responseBody = responseBody;
|
|
2347
2313
|
}
|
|
2348
2314
|
};
|
|
2349
|
-
|
|
2350
2315
|
//#endregion
|
|
2351
2316
|
//#region src/federation/webfinger.ts
|
|
2352
2317
|
const logger = getLogger([
|
|
@@ -2379,12 +2344,12 @@ async function handleWebFinger(request, options) {
|
|
|
2379
2344
|
}
|
|
2380
2345
|
});
|
|
2381
2346
|
}
|
|
2382
|
-
async function handleWebFingerInternal(request, { context
|
|
2347
|
+
async function handleWebFingerInternal(request, { context, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
|
|
2383
2348
|
if (actorDispatcher == null) {
|
|
2384
2349
|
logger.error("Actor dispatcher is not set.");
|
|
2385
2350
|
return await onNotFound(request);
|
|
2386
2351
|
}
|
|
2387
|
-
const resource = context
|
|
2352
|
+
const resource = context.url.searchParams.get("resource");
|
|
2388
2353
|
if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
|
|
2389
2354
|
span?.setAttribute("webfinger.resource", resource);
|
|
2390
2355
|
let resourceUrl;
|
|
@@ -2400,26 +2365,26 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2400
2365
|
logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
|
|
2401
2366
|
return username;
|
|
2402
2367
|
}
|
|
2403
|
-
const identifier
|
|
2404
|
-
if (identifier
|
|
2368
|
+
const identifier = await actorHandleMapper(context, username);
|
|
2369
|
+
if (identifier == null) {
|
|
2405
2370
|
logger.error("Actor {username} not found.", { username });
|
|
2406
2371
|
return null;
|
|
2407
2372
|
}
|
|
2408
|
-
return identifier
|
|
2373
|
+
return identifier;
|
|
2409
2374
|
}
|
|
2410
2375
|
let identifier = null;
|
|
2411
|
-
const uriParsed = context
|
|
2376
|
+
const uriParsed = context.parseUri(resourceUrl);
|
|
2412
2377
|
if (uriParsed?.type != "actor") {
|
|
2413
2378
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
2414
2379
|
if (match == null) {
|
|
2415
|
-
const result = await actorAliasMapper?.(context
|
|
2380
|
+
const result = await actorAliasMapper?.(context, resourceUrl);
|
|
2416
2381
|
if (result == null) return await onNotFound(request);
|
|
2417
2382
|
if ("identifier" in result) identifier = result.identifier;
|
|
2418
2383
|
else identifier = await mapUsernameToIdentifier(result.username);
|
|
2419
2384
|
} else {
|
|
2420
2385
|
const portMatch = /:\d+$/.exec(match[2]);
|
|
2421
2386
|
const normalizedHost = portMatch == null ? domainToASCII(match[2].toLowerCase()) : domainToASCII(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
2422
|
-
if (normalizedHost != context
|
|
2387
|
+
if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
|
|
2423
2388
|
else {
|
|
2424
2389
|
identifier = await mapUsernameToIdentifier(match[1]);
|
|
2425
2390
|
resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
|
|
@@ -2427,14 +2392,14 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2427
2392
|
}
|
|
2428
2393
|
} else identifier = uriParsed.identifier;
|
|
2429
2394
|
if (identifier == null) return await onNotFound(request);
|
|
2430
|
-
const actor = await actorDispatcher(context
|
|
2395
|
+
const actor = await actorDispatcher(context, identifier);
|
|
2431
2396
|
if (actor == null) {
|
|
2432
2397
|
logger.error("Actor {identifier} not found.", { identifier });
|
|
2433
2398
|
return await onNotFound(request);
|
|
2434
2399
|
}
|
|
2435
2400
|
const links = [{
|
|
2436
2401
|
rel: "self",
|
|
2437
|
-
href: context
|
|
2402
|
+
href: context.getActorUri(identifier).href,
|
|
2438
2403
|
type: "application/activity+json"
|
|
2439
2404
|
}];
|
|
2440
2405
|
for (const url of actor.urls) if (url instanceof Link && url.href != null) links.push({
|
|
@@ -2455,16 +2420,16 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2455
2420
|
});
|
|
2456
2421
|
}
|
|
2457
2422
|
if (webFingerLinksDispatcher != null) {
|
|
2458
|
-
const customLinks = await webFingerLinksDispatcher(context
|
|
2423
|
+
const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
|
|
2459
2424
|
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
2460
2425
|
}
|
|
2461
2426
|
const aliases = [];
|
|
2462
2427
|
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
|
|
2463
|
-
aliases.push(`acct:${actor.preferredUsername}@${host ?? context
|
|
2464
|
-
if (host != null && host !== context
|
|
2428
|
+
aliases.push(`acct:${actor.preferredUsername}@${host ?? context.url.host}`);
|
|
2429
|
+
if (host != null && host !== context.url.host) aliases.push(`acct:${actor.preferredUsername}@${context.url.host}`);
|
|
2465
2430
|
}
|
|
2466
|
-
if (resourceUrl.href !== context
|
|
2467
|
-
if (resourceUrl.protocol === "acct:" && host != null && host !== context
|
|
2431
|
+
if (resourceUrl.href !== context.getActorUri(identifier).href) aliases.push(context.getActorUri(identifier).href);
|
|
2432
|
+
if (resourceUrl.protocol === "acct:" && host != null && host !== context.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
2468
2433
|
const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
|
|
2469
2434
|
aliases.push(`acct:${username}@${host}`);
|
|
2470
2435
|
}
|
|
@@ -2478,9 +2443,15 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
2478
2443
|
"Access-Control-Allow-Origin": "*"
|
|
2479
2444
|
} });
|
|
2480
2445
|
}
|
|
2481
|
-
|
|
2482
2446
|
//#endregion
|
|
2483
2447
|
//#region src/federation/middleware.ts
|
|
2448
|
+
var middleware_exports = /* @__PURE__ */ __exportAll({
|
|
2449
|
+
ContextImpl: () => ContextImpl,
|
|
2450
|
+
FederationImpl: () => FederationImpl,
|
|
2451
|
+
InboxContextImpl: () => InboxContextImpl,
|
|
2452
|
+
KvSpecDeterminer: () => KvSpecDeterminer,
|
|
2453
|
+
createFederation: () => createFederation
|
|
2454
|
+
});
|
|
2484
2455
|
/**
|
|
2485
2456
|
* Create a new {@link Federation} instance.
|
|
2486
2457
|
* @param parameters Parameters for initializing the instance.
|
|
@@ -2609,28 +2580,28 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2609
2580
|
this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
|
|
2610
2581
|
}
|
|
2611
2582
|
_getTracer() {
|
|
2612
|
-
return this.tracerProvider.getTracer(
|
|
2583
|
+
return this.tracerProvider.getTracer(name, version);
|
|
2613
2584
|
}
|
|
2614
2585
|
async _startQueueInternal(ctxData, signal, queue) {
|
|
2615
2586
|
if (this.inboxQueue == null && this.outboxQueue == null) return;
|
|
2616
|
-
const logger
|
|
2587
|
+
const logger = getLogger([
|
|
2617
2588
|
"fedify",
|
|
2618
2589
|
"federation",
|
|
2619
2590
|
"queue"
|
|
2620
2591
|
]);
|
|
2621
2592
|
const promises = [];
|
|
2622
2593
|
if (this.inboxQueue != null && (queue == null || queue === "inbox") && !this.inboxQueueStarted) {
|
|
2623
|
-
logger
|
|
2594
|
+
logger.debug("Starting an inbox task worker.");
|
|
2624
2595
|
this.inboxQueueStarted = true;
|
|
2625
2596
|
promises.push(this.inboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2626
2597
|
}
|
|
2627
2598
|
if (this.outboxQueue != null && this.outboxQueue !== this.inboxQueue && (queue == null || queue === "outbox") && !this.outboxQueueStarted) {
|
|
2628
|
-
logger
|
|
2599
|
+
logger.debug("Starting an outbox task worker.");
|
|
2629
2600
|
this.outboxQueueStarted = true;
|
|
2630
2601
|
promises.push(this.outboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2631
2602
|
}
|
|
2632
2603
|
if (this.fanoutQueue != null && this.fanoutQueue !== this.inboxQueue && this.fanoutQueue !== this.outboxQueue && (queue == null || queue === "fanout") && !this.fanoutQueueStarted) {
|
|
2633
|
-
logger
|
|
2604
|
+
logger.debug("Starting a fanout task worker.");
|
|
2634
2605
|
this.fanoutQueueStarted = true;
|
|
2635
2606
|
promises.push(this.fanoutQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2636
2607
|
}
|
|
@@ -2714,12 +2685,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2714
2685
|
});
|
|
2715
2686
|
}
|
|
2716
2687
|
async #listenFanoutMessage(data, message) {
|
|
2717
|
-
|
|
2688
|
+
getLogger([
|
|
2718
2689
|
"fedify",
|
|
2719
2690
|
"federation",
|
|
2720
2691
|
"fanout"
|
|
2721
|
-
])
|
|
2722
|
-
logger$1.debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2692
|
+
]).debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
2723
2693
|
activityId: message.activityId,
|
|
2724
2694
|
inboxes: globalThis.Object.keys(message.inboxes).length
|
|
2725
2695
|
});
|
|
@@ -2738,18 +2708,18 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2738
2708
|
}),
|
|
2739
2709
|
tracerProvider: this.tracerProvider
|
|
2740
2710
|
});
|
|
2741
|
-
const context
|
|
2711
|
+
const context = this.#createContext(new URL(message.baseUrl), data, { documentLoader: this.documentLoaderFactory({
|
|
2742
2712
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
2743
2713
|
userAgent: this.userAgent
|
|
2744
2714
|
}) });
|
|
2745
2715
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
2746
2716
|
collectionSync: message.collectionSync,
|
|
2747
2717
|
orderingKey: message.orderingKey,
|
|
2748
|
-
context
|
|
2718
|
+
context
|
|
2749
2719
|
});
|
|
2750
2720
|
}
|
|
2751
2721
|
async #listenOutboxMessage(_, message, span) {
|
|
2752
|
-
const logger
|
|
2722
|
+
const logger = getLogger([
|
|
2753
2723
|
"fedify",
|
|
2754
2724
|
"federation",
|
|
2755
2725
|
"outbox"
|
|
@@ -2797,14 +2767,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2797
2767
|
});
|
|
2798
2768
|
try {
|
|
2799
2769
|
await this.onOutboxError?.(error, activity);
|
|
2800
|
-
} catch (error
|
|
2801
|
-
logger
|
|
2770
|
+
} catch (error) {
|
|
2771
|
+
logger.error("An unexpected error occurred in onError handler:\n{error}", {
|
|
2802
2772
|
...logData,
|
|
2803
|
-
error
|
|
2773
|
+
error
|
|
2804
2774
|
});
|
|
2805
2775
|
}
|
|
2806
2776
|
if (error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode)) {
|
|
2807
|
-
logger
|
|
2777
|
+
logger.warn("Permanent delivery failure for activity {activityId} to {inbox} ({status}); not retrying.", {
|
|
2808
2778
|
...logData,
|
|
2809
2779
|
status: error.statusCode
|
|
2810
2780
|
});
|
|
@@ -2820,13 +2790,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2820
2790
|
try {
|
|
2821
2791
|
return [new URL(id)];
|
|
2822
2792
|
} catch {
|
|
2823
|
-
logger
|
|
2793
|
+
logger.warn("Invalid actorId URL in OutboxMessage: {id}", { id });
|
|
2824
2794
|
return [];
|
|
2825
2795
|
}
|
|
2826
2796
|
})
|
|
2827
2797
|
});
|
|
2828
2798
|
} catch (handlerError) {
|
|
2829
|
-
logger
|
|
2799
|
+
logger.error("An unexpected error occurred in outboxPermanentFailureHandler:\n{error}", {
|
|
2830
2800
|
...logData,
|
|
2831
2801
|
error: handlerError
|
|
2832
2802
|
});
|
|
@@ -2835,7 +2805,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2835
2805
|
return;
|
|
2836
2806
|
}
|
|
2837
2807
|
if (this.outboxQueue?.nativeRetrial) {
|
|
2838
|
-
logger
|
|
2808
|
+
logger.error("Failed to send activity {activityId} to {inbox}; backend will handle retry:\n{error}", {
|
|
2839
2809
|
...logData,
|
|
2840
2810
|
error
|
|
2841
2811
|
});
|
|
@@ -2846,7 +2816,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2846
2816
|
attempts: message.attempt
|
|
2847
2817
|
});
|
|
2848
2818
|
if (delay != null) {
|
|
2849
|
-
logger
|
|
2819
|
+
logger.error("Failed to send activity {activityId} to {inbox} (attempt #{attempt}); retry...:\n{error}", {
|
|
2850
2820
|
...logData,
|
|
2851
2821
|
error
|
|
2852
2822
|
});
|
|
@@ -2854,39 +2824,38 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2854
2824
|
...message,
|
|
2855
2825
|
attempt: message.attempt + 1
|
|
2856
2826
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2857
|
-
} else logger
|
|
2827
|
+
} else logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
2858
2828
|
...logData,
|
|
2859
2829
|
error
|
|
2860
2830
|
});
|
|
2861
2831
|
return;
|
|
2862
2832
|
}
|
|
2863
|
-
logger
|
|
2833
|
+
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
2864
2834
|
}
|
|
2865
2835
|
async #listenInboxMessage(ctxData, message, span) {
|
|
2866
|
-
const logger
|
|
2836
|
+
const logger = getLogger([
|
|
2867
2837
|
"fedify",
|
|
2868
2838
|
"federation",
|
|
2869
2839
|
"inbox"
|
|
2870
2840
|
]);
|
|
2871
2841
|
const baseUrl = new URL(message.baseUrl);
|
|
2872
|
-
let context
|
|
2873
|
-
if (message.identifier != null) context
|
|
2842
|
+
let context = this.#createContext(baseUrl, ctxData);
|
|
2843
|
+
if (message.identifier != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: await context.getDocumentLoader({ identifier: message.identifier }) });
|
|
2874
2844
|
else if (this.sharedInboxKeyDispatcher != null) {
|
|
2875
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
2876
|
-
if (identity != null) context
|
|
2845
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
2846
|
+
if (identity != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
2877
2847
|
}
|
|
2878
|
-
const activity = await Activity.fromJsonLd(message.activity, context
|
|
2848
|
+
const activity = await Activity.fromJsonLd(message.activity, context);
|
|
2879
2849
|
span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
|
|
2880
2850
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2881
2851
|
const cacheKey = activity.id == null ? null : [
|
|
2882
2852
|
...this.kvPrefixes.activityIdempotence,
|
|
2883
|
-
context
|
|
2853
|
+
context.origin,
|
|
2884
2854
|
activity.id.href
|
|
2885
2855
|
];
|
|
2886
2856
|
if (cacheKey != null) {
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
logger$1.debug("Activity {activityId} has already been processed.", {
|
|
2857
|
+
if (await this.kv.get(cacheKey) === true) {
|
|
2858
|
+
logger.debug("Activity {activityId} has already been processed.", {
|
|
2890
2859
|
activityId: activity.id?.href,
|
|
2891
2860
|
activity: message.activity,
|
|
2892
2861
|
recipient: message.identifier
|
|
@@ -2894,32 +2863,32 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2894
2863
|
return;
|
|
2895
2864
|
}
|
|
2896
2865
|
}
|
|
2897
|
-
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span
|
|
2866
|
+
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
|
|
2898
2867
|
const dispatched = this.inboxListeners?.dispatchWithClass(activity);
|
|
2899
2868
|
if (dispatched == null) {
|
|
2900
|
-
logger
|
|
2869
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
2901
2870
|
activityId: activity.id?.href,
|
|
2902
2871
|
activity: message.activity,
|
|
2903
2872
|
recipient: message.identifier,
|
|
2904
2873
|
trial: message.attempt
|
|
2905
2874
|
});
|
|
2906
|
-
span
|
|
2875
|
+
span.setStatus({
|
|
2907
2876
|
code: SpanStatusCode.ERROR,
|
|
2908
2877
|
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
2909
2878
|
});
|
|
2910
|
-
span
|
|
2879
|
+
span.end();
|
|
2911
2880
|
return;
|
|
2912
2881
|
}
|
|
2913
2882
|
const { class: cls, listener } = dispatched;
|
|
2914
|
-
span
|
|
2883
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
2915
2884
|
try {
|
|
2916
|
-
await listener(context
|
|
2885
|
+
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, getTypeId(activity).href), activity);
|
|
2917
2886
|
} catch (error) {
|
|
2918
2887
|
try {
|
|
2919
|
-
await this.inboxErrorHandler?.(context
|
|
2920
|
-
} catch (error
|
|
2921
|
-
logger
|
|
2922
|
-
error
|
|
2888
|
+
await this.inboxErrorHandler?.(context, error);
|
|
2889
|
+
} catch (error) {
|
|
2890
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
2891
|
+
error,
|
|
2923
2892
|
trial: message.attempt,
|
|
2924
2893
|
activityId: activity.id?.href,
|
|
2925
2894
|
activity: message.activity,
|
|
@@ -2927,17 +2896,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2927
2896
|
});
|
|
2928
2897
|
}
|
|
2929
2898
|
if (this.inboxQueue?.nativeRetrial) {
|
|
2930
|
-
logger
|
|
2899
|
+
logger.error("Failed to process the incoming activity {activityId}; backend will handle retry:\n{error}", {
|
|
2931
2900
|
error,
|
|
2932
2901
|
activityId: activity.id?.href,
|
|
2933
2902
|
activity: message.activity,
|
|
2934
2903
|
recipient: message.identifier
|
|
2935
2904
|
});
|
|
2936
|
-
span
|
|
2905
|
+
span.setStatus({
|
|
2937
2906
|
code: SpanStatusCode.ERROR,
|
|
2938
2907
|
message: String(error)
|
|
2939
2908
|
});
|
|
2940
|
-
span
|
|
2909
|
+
span.end();
|
|
2941
2910
|
throw error;
|
|
2942
2911
|
}
|
|
2943
2912
|
const delay = this.inboxRetryPolicy({
|
|
@@ -2945,7 +2914,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2945
2914
|
attempts: message.attempt
|
|
2946
2915
|
});
|
|
2947
2916
|
if (delay != null) {
|
|
2948
|
-
logger
|
|
2917
|
+
logger.error("Failed to process the incoming activity {activityId} (attempt #{attempt}); retry...:\n{error}", {
|
|
2949
2918
|
error,
|
|
2950
2919
|
attempt: message.attempt,
|
|
2951
2920
|
activityId: activity.id?.href,
|
|
@@ -2956,26 +2925,26 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2956
2925
|
...message,
|
|
2957
2926
|
attempt: message.attempt + 1
|
|
2958
2927
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2959
|
-
} else logger
|
|
2928
|
+
} else logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
2960
2929
|
error,
|
|
2961
2930
|
activityId: activity.id?.href,
|
|
2962
2931
|
activity: message.activity,
|
|
2963
2932
|
recipient: message.identifier
|
|
2964
2933
|
});
|
|
2965
|
-
span
|
|
2934
|
+
span.setStatus({
|
|
2966
2935
|
code: SpanStatusCode.ERROR,
|
|
2967
2936
|
message: String(error)
|
|
2968
2937
|
});
|
|
2969
|
-
span
|
|
2938
|
+
span.end();
|
|
2970
2939
|
return;
|
|
2971
2940
|
}
|
|
2972
2941
|
if (cacheKey != null) await this.kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
2973
|
-
logger
|
|
2942
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
2974
2943
|
activityId: activity.id?.href,
|
|
2975
2944
|
activity: message.activity,
|
|
2976
2945
|
recipient: message.identifier
|
|
2977
2946
|
});
|
|
2978
|
-
span
|
|
2947
|
+
span.end();
|
|
2979
2948
|
});
|
|
2980
2949
|
}
|
|
2981
2950
|
startQueue(contextData, options = {}) {
|
|
@@ -3019,7 +2988,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3019
2988
|
};
|
|
3020
2989
|
}
|
|
3021
2990
|
async sendActivity(keys, inboxes, activity, options) {
|
|
3022
|
-
const logger
|
|
2991
|
+
const logger = getLogger([
|
|
3023
2992
|
"fedify",
|
|
3024
2993
|
"federation",
|
|
3025
2994
|
"outbox"
|
|
@@ -3053,7 +3022,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3053
3022
|
format: "compact",
|
|
3054
3023
|
contextLoader
|
|
3055
3024
|
});
|
|
3056
|
-
if (rsaKey == null) logger
|
|
3025
|
+
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.", {
|
|
3057
3026
|
activityId,
|
|
3058
3027
|
keys: keys.map((pair) => ({
|
|
3059
3028
|
keyId: pair.keyId.href,
|
|
@@ -3064,7 +3033,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3064
3033
|
contextLoader,
|
|
3065
3034
|
tracerProvider: this.tracerProvider
|
|
3066
3035
|
});
|
|
3067
|
-
if (!proofCreated) logger
|
|
3036
|
+
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.", {
|
|
3068
3037
|
activityId,
|
|
3069
3038
|
keys: keys.map((pair) => ({
|
|
3070
3039
|
keyId: pair.keyId.href,
|
|
@@ -3072,11 +3041,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3072
3041
|
}))
|
|
3073
3042
|
});
|
|
3074
3043
|
if (immediate || this.outboxQueue == null) {
|
|
3075
|
-
if (immediate) logger
|
|
3044
|
+
if (immediate) logger.debug("Sending activity immediately without queue since immediate option is set.", {
|
|
3076
3045
|
activityId: activity.id.href,
|
|
3077
3046
|
activity: jsonLd
|
|
3078
3047
|
});
|
|
3079
|
-
else logger
|
|
3048
|
+
else logger.debug("Sending activity immediately without queue since queue is not set.", {
|
|
3080
3049
|
activityId: activity.id.href,
|
|
3081
3050
|
activity: jsonLd
|
|
3082
3051
|
});
|
|
@@ -3095,7 +3064,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3095
3064
|
await Promise.all(promises);
|
|
3096
3065
|
return;
|
|
3097
3066
|
}
|
|
3098
|
-
logger
|
|
3067
|
+
logger.debug("Enqueuing activity {activityId} to send later.", {
|
|
3099
3068
|
activityId: activity.id.href,
|
|
3100
3069
|
activity: jsonLd
|
|
3101
3070
|
});
|
|
@@ -3139,10 +3108,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3139
3108
|
const { outboxQueue } = this;
|
|
3140
3109
|
if (outboxQueue.enqueueMany == null) {
|
|
3141
3110
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
3142
|
-
const
|
|
3143
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
3111
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
3144
3112
|
if (errors.length > 0) {
|
|
3145
|
-
logger
|
|
3113
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
3146
3114
|
activityId: activity.id.href,
|
|
3147
3115
|
errors
|
|
3148
3116
|
});
|
|
@@ -3151,10 +3119,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3151
3119
|
}
|
|
3152
3120
|
} else if (orderingKey != null) {
|
|
3153
3121
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
3154
|
-
const
|
|
3155
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
3122
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
3156
3123
|
if (errors.length > 0) {
|
|
3157
|
-
logger
|
|
3124
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
3158
3125
|
activityId: activity.id.href,
|
|
3159
3126
|
errors
|
|
3160
3127
|
});
|
|
@@ -3164,7 +3131,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3164
3131
|
} else try {
|
|
3165
3132
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
3166
3133
|
} catch (error) {
|
|
3167
|
-
logger
|
|
3134
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
3168
3135
|
activityId: activity.id.href,
|
|
3169
3136
|
error
|
|
3170
3137
|
});
|
|
@@ -3172,8 +3139,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3172
3139
|
}
|
|
3173
3140
|
}
|
|
3174
3141
|
fetch(request, options) {
|
|
3175
|
-
|
|
3176
|
-
return withContext({ requestId }, async () => {
|
|
3142
|
+
return withContext({ requestId: getRequestId(request) }, async () => {
|
|
3177
3143
|
const tracer = this._getTracer();
|
|
3178
3144
|
return await tracer.startActiveSpan(request.method, {
|
|
3179
3145
|
kind: SpanKind.SERVER,
|
|
@@ -3187,7 +3153,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3187
3153
|
traceId: spanCtx.traceId,
|
|
3188
3154
|
spanId: spanCtx.spanId
|
|
3189
3155
|
}, async () => {
|
|
3190
|
-
const logger
|
|
3156
|
+
const logger = getLogger([
|
|
3191
3157
|
"fedify",
|
|
3192
3158
|
"federation",
|
|
3193
3159
|
"http"
|
|
@@ -3207,7 +3173,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3207
3173
|
message: `${error}`
|
|
3208
3174
|
});
|
|
3209
3175
|
span.end();
|
|
3210
|
-
logger
|
|
3176
|
+
logger.error("An error occurred while serving request {method} {url}: {error}", {
|
|
3211
3177
|
method: request.method,
|
|
3212
3178
|
url: request.url,
|
|
3213
3179
|
error
|
|
@@ -3231,9 +3197,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3231
3197
|
url: request.url,
|
|
3232
3198
|
status: response.status
|
|
3233
3199
|
};
|
|
3234
|
-
if (response.status >= 500) logger
|
|
3235
|
-
else if (response.status >= 400) logger
|
|
3236
|
-
else logger
|
|
3200
|
+
if (response.status >= 500) logger.error(logTpl, values);
|
|
3201
|
+
else if (response.status >= 400) logger.warn(logTpl, values);
|
|
3202
|
+
else logger.info(logTpl, values);
|
|
3237
3203
|
return response;
|
|
3238
3204
|
});
|
|
3239
3205
|
});
|
|
@@ -3247,11 +3213,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3247
3213
|
const route = this.router.route(url.pathname);
|
|
3248
3214
|
if (route == null) return await onNotFound(request);
|
|
3249
3215
|
span.updateName(`${request.method} ${route.template}`);
|
|
3250
|
-
let context
|
|
3216
|
+
let context = this.#createContext(request, contextData);
|
|
3251
3217
|
const routeName = route.name.replace(/:.*$/, "");
|
|
3252
3218
|
switch (routeName) {
|
|
3253
3219
|
case "webfinger": return await handleWebFinger(request, {
|
|
3254
|
-
context
|
|
3220
|
+
context,
|
|
3255
3221
|
host: this.origin?.handleHost,
|
|
3256
3222
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3257
3223
|
actorHandleMapper: this.actorCallbacks?.handleMapper,
|
|
@@ -3260,19 +3226,19 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3260
3226
|
onNotFound,
|
|
3261
3227
|
tracer
|
|
3262
3228
|
});
|
|
3263
|
-
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context
|
|
3229
|
+
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context);
|
|
3264
3230
|
case "nodeInfo": return await handleNodeInfo(request, {
|
|
3265
|
-
context
|
|
3231
|
+
context,
|
|
3266
3232
|
nodeInfoDispatcher: this.nodeInfoDispatcher
|
|
3267
3233
|
});
|
|
3268
3234
|
}
|
|
3269
3235
|
if (request.method !== "POST" && !acceptsJsonLd(request)) return await onNotAcceptable(request);
|
|
3270
3236
|
switch (routeName) {
|
|
3271
3237
|
case "actor":
|
|
3272
|
-
context
|
|
3238
|
+
context = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier: route.values.identifier } });
|
|
3273
3239
|
return await handleActor(request, {
|
|
3274
3240
|
identifier: route.values.identifier,
|
|
3275
|
-
context
|
|
3241
|
+
context,
|
|
3276
3242
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
3277
3243
|
authorizePredicate: this.actorCallbacks?.authorizePredicate,
|
|
3278
3244
|
onUnauthorized,
|
|
@@ -3282,13 +3248,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3282
3248
|
const typeId = route.name.replace(/^object:/, "");
|
|
3283
3249
|
const callbacks = this.objectCallbacks[typeId];
|
|
3284
3250
|
const cls = this.objectTypeIds[typeId];
|
|
3285
|
-
context
|
|
3251
|
+
context = this.#createContext(request, contextData, { invokedFromObjectDispatcher: {
|
|
3286
3252
|
cls,
|
|
3287
3253
|
values: route.values
|
|
3288
3254
|
} });
|
|
3289
3255
|
return await handleObject(request, {
|
|
3290
3256
|
values: route.values,
|
|
3291
|
-
context
|
|
3257
|
+
context,
|
|
3292
3258
|
objectDispatcher: callbacks?.dispatcher,
|
|
3293
3259
|
authorizePredicate: callbacks?.authorizePredicate,
|
|
3294
3260
|
onUnauthorized,
|
|
@@ -3298,8 +3264,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3298
3264
|
case "outbox": return await handleCollection(request, {
|
|
3299
3265
|
name: "outbox",
|
|
3300
3266
|
identifier: route.values.identifier,
|
|
3301
|
-
uriGetter: context
|
|
3302
|
-
context
|
|
3267
|
+
uriGetter: context.getOutboxUri.bind(context),
|
|
3268
|
+
context,
|
|
3303
3269
|
collectionCallbacks: this.outboxCallbacks,
|
|
3304
3270
|
tracerProvider: this.tracerProvider,
|
|
3305
3271
|
onUnauthorized,
|
|
@@ -3309,24 +3275,24 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3309
3275
|
if (request.method !== "POST") return await handleCollection(request, {
|
|
3310
3276
|
name: "inbox",
|
|
3311
3277
|
identifier: route.values.identifier,
|
|
3312
|
-
uriGetter: context
|
|
3313
|
-
context
|
|
3278
|
+
uriGetter: context.getInboxUri.bind(context),
|
|
3279
|
+
context,
|
|
3314
3280
|
collectionCallbacks: this.inboxCallbacks,
|
|
3315
3281
|
tracerProvider: this.tracerProvider,
|
|
3316
3282
|
onUnauthorized,
|
|
3317
3283
|
onNotFound
|
|
3318
3284
|
});
|
|
3319
|
-
context
|
|
3285
|
+
context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier: route.values.identifier }) });
|
|
3320
3286
|
case "sharedInbox":
|
|
3321
3287
|
if (routeName !== "inbox" && this.sharedInboxKeyDispatcher != null) {
|
|
3322
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
3323
|
-
if (identity != null) context
|
|
3288
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
3289
|
+
if (identity != null) context = this.#createContext(request, contextData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
3324
3290
|
}
|
|
3325
3291
|
if (!this.manuallyStartQueue) this._startQueueInternal(contextData);
|
|
3326
3292
|
return await handleInbox(request, {
|
|
3327
3293
|
recipient: route.values.identifier ?? null,
|
|
3328
|
-
context
|
|
3329
|
-
inboxContextFactory: context
|
|
3294
|
+
context,
|
|
3295
|
+
inboxContextFactory: context.toInboxContext.bind(context),
|
|
3330
3296
|
kv: this.kv,
|
|
3331
3297
|
kvPrefixes: this.kvPrefixes,
|
|
3332
3298
|
queue: this.inboxQueue,
|
|
@@ -3344,8 +3310,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3344
3310
|
case "following": return await handleCollection(request, {
|
|
3345
3311
|
name: "following",
|
|
3346
3312
|
identifier: route.values.identifier,
|
|
3347
|
-
uriGetter: context
|
|
3348
|
-
context
|
|
3313
|
+
uriGetter: context.getFollowingUri.bind(context),
|
|
3314
|
+
context,
|
|
3349
3315
|
collectionCallbacks: this.followingCallbacks,
|
|
3350
3316
|
tracerProvider: this.tracerProvider,
|
|
3351
3317
|
onUnauthorized,
|
|
@@ -3361,14 +3327,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3361
3327
|
return await handleCollection(request, {
|
|
3362
3328
|
name: "followers",
|
|
3363
3329
|
identifier: route.values.identifier,
|
|
3364
|
-
uriGetter: baseUrl == null ? context
|
|
3365
|
-
const uri = context
|
|
3330
|
+
uriGetter: baseUrl == null ? context.getFollowersUri.bind(context) : (identifier) => {
|
|
3331
|
+
const uri = context.getFollowersUri(identifier);
|
|
3366
3332
|
uri.searchParams.set("base-url", baseUrl);
|
|
3367
3333
|
return uri;
|
|
3368
3334
|
},
|
|
3369
|
-
context
|
|
3335
|
+
context,
|
|
3370
3336
|
filter: baseUrl != null ? new URL(baseUrl) : void 0,
|
|
3371
|
-
filterPredicate: baseUrl != null ? (i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl) : void 0,
|
|
3337
|
+
filterPredicate: baseUrl != null ? ((i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl)) : void 0,
|
|
3372
3338
|
collectionCallbacks: this.followersCallbacks,
|
|
3373
3339
|
tracerProvider: this.tracerProvider,
|
|
3374
3340
|
onUnauthorized,
|
|
@@ -3378,8 +3344,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3378
3344
|
case "liked": return await handleCollection(request, {
|
|
3379
3345
|
name: "liked",
|
|
3380
3346
|
identifier: route.values.identifier,
|
|
3381
|
-
uriGetter: context
|
|
3382
|
-
context
|
|
3347
|
+
uriGetter: context.getLikedUri.bind(context),
|
|
3348
|
+
context,
|
|
3383
3349
|
collectionCallbacks: this.likedCallbacks,
|
|
3384
3350
|
tracerProvider: this.tracerProvider,
|
|
3385
3351
|
onUnauthorized,
|
|
@@ -3388,8 +3354,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3388
3354
|
case "featured": return await handleCollection(request, {
|
|
3389
3355
|
name: "featured",
|
|
3390
3356
|
identifier: route.values.identifier,
|
|
3391
|
-
uriGetter: context
|
|
3392
|
-
context
|
|
3357
|
+
uriGetter: context.getFeaturedUri.bind(context),
|
|
3358
|
+
context,
|
|
3393
3359
|
collectionCallbacks: this.featuredCallbacks,
|
|
3394
3360
|
tracerProvider: this.tracerProvider,
|
|
3395
3361
|
onUnauthorized,
|
|
@@ -3398,8 +3364,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3398
3364
|
case "featuredTags": return await handleCollection(request, {
|
|
3399
3365
|
name: "featured tags",
|
|
3400
3366
|
identifier: route.values.identifier,
|
|
3401
|
-
uriGetter: context
|
|
3402
|
-
context
|
|
3367
|
+
uriGetter: context.getFeaturedTagsUri.bind(context),
|
|
3368
|
+
context,
|
|
3403
3369
|
collectionCallbacks: this.featuredTagsCallbacks,
|
|
3404
3370
|
tracerProvider: this.tracerProvider,
|
|
3405
3371
|
onUnauthorized,
|
|
@@ -3410,7 +3376,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3410
3376
|
const callbacks = this.collectionCallbacks[name];
|
|
3411
3377
|
return await handleCustomCollection(request, {
|
|
3412
3378
|
name,
|
|
3413
|
-
context
|
|
3379
|
+
context,
|
|
3414
3380
|
values: route.values,
|
|
3415
3381
|
collectionCallbacks: callbacks,
|
|
3416
3382
|
tracerProvider: this.tracerProvider,
|
|
@@ -3423,7 +3389,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3423
3389
|
const callbacks = this.collectionCallbacks[name];
|
|
3424
3390
|
return await handleOrderedCollection(request, {
|
|
3425
3391
|
name,
|
|
3426
|
-
context
|
|
3392
|
+
context,
|
|
3427
3393
|
values: route.values,
|
|
3428
3394
|
collectionCallbacks: callbacks,
|
|
3429
3395
|
tracerProvider: this.tracerProvider,
|
|
@@ -3514,9 +3480,9 @@ var ContextImpl = class ContextImpl {
|
|
|
3514
3480
|
}
|
|
3515
3481
|
getInboxUri(identifier) {
|
|
3516
3482
|
if (identifier == null) {
|
|
3517
|
-
const path
|
|
3518
|
-
if (path
|
|
3519
|
-
return new URL(path
|
|
3483
|
+
const path = this.federation.router.build("sharedInbox", {});
|
|
3484
|
+
if (path == null) throw new RouterError("No shared inbox path registered.");
|
|
3485
|
+
return new URL(path, this.canonicalOrigin);
|
|
3520
3486
|
}
|
|
3521
3487
|
const path = this.federation.router.build("inbox", { identifier });
|
|
3522
3488
|
if (path == null) throw new RouterError("No inbox path registered.");
|
|
@@ -3602,8 +3568,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3602
3568
|
type: "featuredTags",
|
|
3603
3569
|
identifier
|
|
3604
3570
|
};
|
|
3605
|
-
const
|
|
3606
|
-
const collectionRegex = /* @__PURE__ */ new RegExp(`^(${collectionTypes.join("|")}):(.*)$`);
|
|
3571
|
+
const collectionRegex = new RegExp(`^(${["collection", "orderedCollection"].join("|")}):(.*)$`);
|
|
3607
3572
|
const match = route.name.match(collectionRegex);
|
|
3608
3573
|
if (match !== null) {
|
|
3609
3574
|
const [, type, name] = match;
|
|
@@ -3619,12 +3584,12 @@ var ContextImpl = class ContextImpl {
|
|
|
3619
3584
|
return null;
|
|
3620
3585
|
}
|
|
3621
3586
|
async getActorKeyPairs(identifier) {
|
|
3622
|
-
const logger
|
|
3587
|
+
const logger = getLogger([
|
|
3623
3588
|
"fedify",
|
|
3624
3589
|
"federation",
|
|
3625
3590
|
"actor"
|
|
3626
3591
|
]);
|
|
3627
|
-
if (this.invokedFromActorKeyPairsDispatcher != null) logger
|
|
3592
|
+
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.", {
|
|
3628
3593
|
getActorKeyPairsIdentifier: identifier,
|
|
3629
3594
|
actorKeyPairsDispatcherIdentifier: this.invokedFromActorKeyPairsDispatcher.identifier
|
|
3630
3595
|
});
|
|
@@ -3632,7 +3597,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3632
3597
|
try {
|
|
3633
3598
|
keyPairs = await this.getKeyPairsFromIdentifier(identifier);
|
|
3634
3599
|
} catch (_) {
|
|
3635
|
-
logger
|
|
3600
|
+
logger.warn("No actor key pairs dispatcher registered.");
|
|
3636
3601
|
return [];
|
|
3637
3602
|
}
|
|
3638
3603
|
const owner = this.getActorUri(identifier);
|
|
@@ -3656,7 +3621,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3656
3621
|
return result;
|
|
3657
3622
|
}
|
|
3658
3623
|
async getKeyPairsFromIdentifier(identifier) {
|
|
3659
|
-
const logger
|
|
3624
|
+
const logger = getLogger([
|
|
3660
3625
|
"fedify",
|
|
3661
3626
|
"federation",
|
|
3662
3627
|
"actor"
|
|
@@ -3667,7 +3632,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3667
3632
|
actorUri = this.getActorUri(identifier);
|
|
3668
3633
|
} catch (error) {
|
|
3669
3634
|
if (error instanceof RouterError) {
|
|
3670
|
-
logger
|
|
3635
|
+
logger.warn(error.message);
|
|
3671
3636
|
return [];
|
|
3672
3637
|
}
|
|
3673
3638
|
throw error;
|
|
@@ -3676,7 +3641,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3676
3641
|
...this,
|
|
3677
3642
|
invokedFromActorKeyPairsDispatcher: { identifier }
|
|
3678
3643
|
}), identifier);
|
|
3679
|
-
if (keyPairs.length < 1) logger
|
|
3644
|
+
if (keyPairs.length < 1) logger.warn("No key pairs found for actor {identifier}.", { identifier });
|
|
3680
3645
|
let i = 0;
|
|
3681
3646
|
const result = [];
|
|
3682
3647
|
for (const keyPair of keyPairs) {
|
|
@@ -3715,8 +3680,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3715
3680
|
} else identifierPromise = Promise.resolve(identity.identifier);
|
|
3716
3681
|
return identifierPromise.then((identifier) => {
|
|
3717
3682
|
if (identifier == null) return this.documentLoader;
|
|
3718
|
-
|
|
3719
|
-
return keyPair.then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
3683
|
+
return this.getRsaKeyPairFromIdentifier(identifier).then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
3720
3684
|
});
|
|
3721
3685
|
}
|
|
3722
3686
|
return this.federation.authenticatedDocumentLoaderFactory(identity);
|
|
@@ -3758,8 +3722,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3758
3722
|
});
|
|
3759
3723
|
}
|
|
3760
3724
|
sendActivity(sender, recipients, activity, options = {}) {
|
|
3761
|
-
|
|
3762
|
-
return tracer.startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
3725
|
+
return this.tracerProvider.getTracer(name, version).startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
3763
3726
|
kind: this.federation.outboxQueue == null || options.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
3764
3727
|
attributes: {
|
|
3765
3728
|
"activitypub.activity.type": getTypeId(activity).href,
|
|
@@ -3784,7 +3747,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3784
3747
|
});
|
|
3785
3748
|
}
|
|
3786
3749
|
async sendActivityInternal(sender, recipients, activity, options, span) {
|
|
3787
|
-
const logger
|
|
3750
|
+
const logger = getLogger([
|
|
3788
3751
|
"fedify",
|
|
3789
3752
|
"federation",
|
|
3790
3753
|
"outbox"
|
|
@@ -3834,7 +3797,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3834
3797
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
3835
3798
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
3836
3799
|
if (activity.actorId == null) {
|
|
3837
|
-
logger
|
|
3800
|
+
logger.error("Activity {activityId} to send does not have an actor.", {
|
|
3838
3801
|
activity,
|
|
3839
3802
|
activityId: activity?.id?.href
|
|
3840
3803
|
});
|
|
@@ -3845,7 +3808,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3845
3808
|
preferSharedInbox: options.preferSharedInbox,
|
|
3846
3809
|
excludeBaseUris: options.excludeBaseUris
|
|
3847
3810
|
});
|
|
3848
|
-
logger
|
|
3811
|
+
logger.debug("Sending activity {activityId} to inboxes:\n{inboxes}", {
|
|
3849
3812
|
inboxes: globalThis.Object.keys(inboxes),
|
|
3850
3813
|
activityId: activity.id?.href,
|
|
3851
3814
|
activity
|
|
@@ -3897,16 +3860,14 @@ var ContextImpl = class ContextImpl {
|
|
|
3897
3860
|
"outbox"
|
|
3898
3861
|
]).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 });
|
|
3899
3862
|
while (cursor != null) {
|
|
3900
|
-
const result
|
|
3901
|
-
if (result
|
|
3902
|
-
for (const recipient of result
|
|
3903
|
-
cursor = result
|
|
3863
|
+
const result = await this.federation.followersCallbacks.dispatcher(this, identifier, cursor);
|
|
3864
|
+
if (result == null) break;
|
|
3865
|
+
for (const recipient of result.items) yield recipient;
|
|
3866
|
+
cursor = result.nextCursor ?? null;
|
|
3904
3867
|
}
|
|
3905
3868
|
}
|
|
3906
3869
|
routeActivity(recipient, activity, options = {}) {
|
|
3907
|
-
|
|
3908
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
3909
|
-
return tracer.startActiveSpan("activitypub.inbox", {
|
|
3870
|
+
return (this.tracerProvider ?? this.tracerProvider).getTracer(name, version).startActiveSpan("activitypub.inbox", {
|
|
3910
3871
|
kind: this.federation.inboxQueue == null || options.immediate ? SpanKind.INTERNAL : SpanKind.PRODUCER,
|
|
3911
3872
|
attributes: { "activitypub.activity.type": getTypeId(activity).href }
|
|
3912
3873
|
}, async (span) => {
|
|
@@ -3934,7 +3895,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3934
3895
|
});
|
|
3935
3896
|
}
|
|
3936
3897
|
async routeActivityInternal(recipient, activity, options = {}, span) {
|
|
3937
|
-
const logger
|
|
3898
|
+
const logger = getLogger([
|
|
3938
3899
|
"fedify",
|
|
3939
3900
|
"federation",
|
|
3940
3901
|
"inbox"
|
|
@@ -3942,19 +3903,18 @@ var ContextImpl = class ContextImpl {
|
|
|
3942
3903
|
const contextLoader = options.contextLoader ?? this.contextLoader;
|
|
3943
3904
|
const json = await activity.toJsonLd({ contextLoader });
|
|
3944
3905
|
const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, this);
|
|
3945
|
-
|
|
3906
|
+
if (await verifyObject(Activity, json, {
|
|
3946
3907
|
contextLoader,
|
|
3947
3908
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
3948
3909
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
3949
3910
|
keyCache
|
|
3950
|
-
})
|
|
3951
|
-
|
|
3952
|
-
logger$1.debug("Object Integrity Proofs are not verified.", {
|
|
3911
|
+
}) == null) {
|
|
3912
|
+
logger.debug("Object Integrity Proofs are not verified.", {
|
|
3953
3913
|
recipient,
|
|
3954
3914
|
activity: json
|
|
3955
3915
|
});
|
|
3956
3916
|
if (activity.id == null) {
|
|
3957
|
-
logger
|
|
3917
|
+
logger.debug("Activity is missing an ID; unable to fetch.", {
|
|
3958
3918
|
recipient,
|
|
3959
3919
|
activity: json
|
|
3960
3920
|
});
|
|
@@ -3962,26 +3922,26 @@ var ContextImpl = class ContextImpl {
|
|
|
3962
3922
|
}
|
|
3963
3923
|
const fetched = await this.lookupObject(activity.id, options);
|
|
3964
3924
|
if (fetched == null) {
|
|
3965
|
-
logger
|
|
3925
|
+
logger.debug("Failed to fetch the remote activity object {activityId}.", {
|
|
3966
3926
|
recipient,
|
|
3967
3927
|
activity: json,
|
|
3968
3928
|
activityId: activity.id.href
|
|
3969
3929
|
});
|
|
3970
3930
|
return false;
|
|
3971
3931
|
} else if (!(fetched instanceof Activity)) {
|
|
3972
|
-
logger
|
|
3932
|
+
logger.debug("Fetched object is not an Activity.", {
|
|
3973
3933
|
recipient,
|
|
3974
3934
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3975
3935
|
});
|
|
3976
3936
|
return false;
|
|
3977
3937
|
} else if (fetched.id?.href !== activity.id.href) {
|
|
3978
|
-
logger
|
|
3938
|
+
logger.debug("Fetched activity object has a different ID; failed to verify.", {
|
|
3979
3939
|
recipient,
|
|
3980
3940
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3981
3941
|
});
|
|
3982
3942
|
return false;
|
|
3983
3943
|
} else if (fetched.actorIds.length < 1) {
|
|
3984
|
-
logger
|
|
3944
|
+
logger.debug("Fetched activity object is missing an actor; unable to verify.", {
|
|
3985
3945
|
recipient,
|
|
3986
3946
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3987
3947
|
});
|
|
@@ -3989,15 +3949,15 @@ var ContextImpl = class ContextImpl {
|
|
|
3989
3949
|
}
|
|
3990
3950
|
const activityId = fetched.id;
|
|
3991
3951
|
if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
|
|
3992
|
-
logger
|
|
3952
|
+
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
3993
3953
|
recipient,
|
|
3994
3954
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
3995
3955
|
});
|
|
3996
3956
|
return false;
|
|
3997
3957
|
}
|
|
3998
|
-
logger
|
|
3958
|
+
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
3999
3959
|
activity = fetched;
|
|
4000
|
-
} else logger
|
|
3960
|
+
} else logger.debug("Object Integrity Proofs are verified.", {
|
|
4001
3961
|
recipient,
|
|
4002
3962
|
activity: json
|
|
4003
3963
|
});
|
|
@@ -4139,8 +4099,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4139
4099
|
});
|
|
4140
4100
|
}
|
|
4141
4101
|
forwardActivity(forwarder, recipients, options) {
|
|
4142
|
-
|
|
4143
|
-
return tracer.startActiveSpan("activitypub.outbox", {
|
|
4102
|
+
return this.tracerProvider.getTracer(name, version).startActiveSpan("activitypub.outbox", {
|
|
4144
4103
|
kind: this.federation.outboxQueue == null || options?.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
4145
4104
|
attributes: { "activitypub.activity.type": this.activityType }
|
|
4146
4105
|
}, async (span) => {
|
|
@@ -4159,7 +4118,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4159
4118
|
});
|
|
4160
4119
|
}
|
|
4161
4120
|
async forwardActivityInternal(forwarder, recipients, options) {
|
|
4162
|
-
const logger
|
|
4121
|
+
const logger = getLogger([
|
|
4163
4122
|
"fedify",
|
|
4164
4123
|
"federation",
|
|
4165
4124
|
"inbox"
|
|
@@ -4186,14 +4145,13 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4186
4145
|
if (!hasSignature(this.activity)) {
|
|
4187
4146
|
let hasProof;
|
|
4188
4147
|
try {
|
|
4189
|
-
|
|
4190
|
-
hasProof = await activity.getProof() != null;
|
|
4148
|
+
hasProof = await (await Activity.fromJsonLd(this.activity, this)).getProof() != null;
|
|
4191
4149
|
} catch {
|
|
4192
4150
|
hasProof = false;
|
|
4193
4151
|
}
|
|
4194
4152
|
if (!hasProof) {
|
|
4195
4153
|
if (options?.skipIfUnsigned) return;
|
|
4196
|
-
logger
|
|
4154
|
+
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.");
|
|
4197
4155
|
}
|
|
4198
4156
|
}
|
|
4199
4157
|
if (recipients === "followers") {
|
|
@@ -4207,14 +4165,14 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4207
4165
|
preferSharedInbox: options?.preferSharedInbox,
|
|
4208
4166
|
excludeBaseUris: options?.excludeBaseUris
|
|
4209
4167
|
});
|
|
4210
|
-
logger
|
|
4168
|
+
logger.debug("Forwarding activity {activityId} to inboxes:\n{inboxes}", {
|
|
4211
4169
|
inboxes: globalThis.Object.keys(inboxes),
|
|
4212
4170
|
activityId: this.activityId,
|
|
4213
4171
|
activity: this.activity
|
|
4214
4172
|
});
|
|
4215
4173
|
if (options?.immediate || this.federation.outboxQueue == null) {
|
|
4216
|
-
if (options?.immediate) logger
|
|
4217
|
-
else logger
|
|
4174
|
+
if (options?.immediate) logger.debug("Forwarding activity immediately without queue since immediate option is set.");
|
|
4175
|
+
else logger.debug("Forwarding activity immediately without queue since queue is not set.");
|
|
4218
4176
|
const promises = [];
|
|
4219
4177
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
4220
4178
|
keys,
|
|
@@ -4229,7 +4187,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4229
4187
|
await Promise.all(promises);
|
|
4230
4188
|
return;
|
|
4231
4189
|
}
|
|
4232
|
-
logger
|
|
4190
|
+
logger.debug("Enqueuing activity {activityId} to forward later.", {
|
|
4233
4191
|
activityId: this.activityId,
|
|
4234
4192
|
activity: this.activity
|
|
4235
4193
|
});
|
|
@@ -4271,10 +4229,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4271
4229
|
const { outboxQueue } = this.federation;
|
|
4272
4230
|
if (outboxQueue.enqueueMany == null) {
|
|
4273
4231
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4274
|
-
const
|
|
4275
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4232
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4276
4233
|
if (errors.length > 0) {
|
|
4277
|
-
logger
|
|
4234
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4278
4235
|
activityId: this.activityId,
|
|
4279
4236
|
errors
|
|
4280
4237
|
});
|
|
@@ -4283,10 +4240,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4283
4240
|
}
|
|
4284
4241
|
} else if (orderingKey != null) {
|
|
4285
4242
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
4286
|
-
const
|
|
4287
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4243
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4288
4244
|
if (errors.length > 0) {
|
|
4289
|
-
logger
|
|
4245
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4290
4246
|
activityId: this.activityId,
|
|
4291
4247
|
errors
|
|
4292
4248
|
});
|
|
@@ -4296,7 +4252,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4296
4252
|
} else try {
|
|
4297
4253
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
4298
4254
|
} catch (error) {
|
|
4299
|
-
logger
|
|
4255
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
|
|
4300
4256
|
activityId: this.activityId,
|
|
4301
4257
|
error
|
|
4302
4258
|
});
|
|
@@ -4351,10 +4307,7 @@ function unauthorized(_request) {
|
|
|
4351
4307
|
function getRequestId(request) {
|
|
4352
4308
|
const traceId = request.headers.get("X-Request-Id") || request.headers.get("X-Correlation-Id") || request.headers.get("Traceparent")?.split("-")[1];
|
|
4353
4309
|
if (traceId != null) return traceId;
|
|
4354
|
-
|
|
4355
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
4356
|
-
return `req_${timestamp}${random}`;
|
|
4310
|
+
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
4357
4311
|
}
|
|
4358
|
-
|
|
4359
4312
|
//#endregion
|
|
4360
|
-
export {
|
|
4313
|
+
export { createExponentialBackoffPolicy as a, buildCollectionSynchronizationHeader as c, Router$1 as d, RouterError as f, SendActivityError as i, digest as l, middleware_exports as n, respondWithObject as o, handleWebFinger as r, respondWithObjectIfAcceptable as s, createFederation as t, createFederationBuilder as u };
|