@fedify/fedify 2.0.7 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{assert-MZs1qjMx.js → assert-ddO5KLpe.mjs} +5 -9
- package/dist/{assert_equals-DSbWqCm3.js → assert_equals-Ew3jOFa3.mjs} +55 -69
- package/dist/{assert_instance_of-DHz7EHNU.js → assert_instance_of-C4Ri6VuN.mjs} +5 -9
- package/dist/{assert_not_equals-C80BG-_5.js → assert_not_equals--wG9hV7u.mjs} +6 -13
- package/dist/{assert_rejects-Ce45JcFg.js → assert_rejects-B-qJtC9Z.mjs} +6 -11
- package/dist/{assert_throws-BNXdRGWP.js → assert_throws-4NwKEy2q.mjs} +5 -10
- package/dist/{builder-DA7Qgx_F.js → builder-DDoQaGOu.mjs} +32 -41
- package/dist/{chunk-CGaQZ11T.cjs → chunk-DDcVe30Y.cjs} +23 -24
- package/dist/{chunk-DJNbSFdH.js → chunk-nlSIicah.js} +8 -8
- package/dist/{client-CoCIaTNO.js → client-A1UrnX6I.mjs} +9 -13
- package/dist/{client-BxMZiQaD.d.ts → client-AtlibPOU.d.ts} +1 -1
- package/dist/{client-C97KOq3x.d.cts → client-z-8dc-e1.d.cts} +1 -1
- package/dist/{collection-CcnIw1qY.js → collection-ChgDTHLz.mjs} +7 -12
- package/dist/compat/mod.cjs +5 -8
- package/dist/compat/mod.d.cts +78 -6
- package/dist/compat/mod.d.ts +78 -6
- package/dist/compat/mod.js +4 -8
- package/dist/compat/transformers.test.mjs +62 -0
- package/dist/{context-D3QkEtZd.d.cts → context-CNIt-Qn7.d.cts} +9 -18
- package/dist/{context-DZJhUmzF.d.ts → context-Dyg7P1qW.d.ts} +9 -18
- package/dist/{context-pa9aIrwp.js → context-Juj6bdHC.mjs} +7 -11
- package/dist/deno-CuVDEdyj.mjs +8 -0
- package/dist/{docloader-CJeSPcS_.js → docloader-BPq9yzC_.mjs} +8 -14
- package/dist/{esm-nLm00z9V.js → esm-DVILvP5e.mjs} +50 -89
- package/dist/federation/builder.test.d.mts +2 -0
- package/dist/federation/{builder.test.js → builder.test.mjs} +19 -38
- package/dist/federation/collection.test.d.mts +2 -0
- package/dist/federation/collection.test.mjs +21 -0
- package/dist/federation/handler.test.d.mts +2 -0
- package/dist/federation/{handler.test.js → handler.test.mjs} +26 -56
- package/dist/federation/idempotency.test.d.mts +2 -0
- package/dist/federation/{idempotency.test.js → idempotency.test.mjs} +31 -62
- package/dist/federation/inbox.test.d.mts +2 -0
- package/dist/federation/{inbox.test.js → inbox.test.mjs} +8 -12
- package/dist/federation/keycache.test.d.mts +2 -0
- package/dist/federation/{keycache.test.js → keycache.test.mjs} +13 -13
- package/dist/federation/kv.test.d.mts +2 -0
- package/dist/federation/{kv.test.js → kv.test.mjs} +11 -22
- package/dist/federation/middleware.test.d.mts +2 -0
- package/dist/federation/{middleware.test.js → middleware.test.mjs} +146 -225
- package/dist/federation/mod.cjs +327 -16
- package/dist/federation/mod.d.cts +3 -6
- package/dist/federation/mod.d.ts +3 -6
- package/dist/federation/mod.js +322 -13
- package/dist/federation/mq.test.d.mts +2 -0
- package/dist/federation/{mq.test.js → mq.test.mjs} +21 -35
- package/dist/federation/negotiation.test.d.mts +2 -0
- package/dist/federation/{negotiation.test.js → negotiation.test.mjs} +9 -16
- package/dist/federation/retry.test.d.mts +2 -0
- package/dist/federation/{retry.test.js → retry.test.mjs} +8 -11
- package/dist/federation/router.test.d.mts +2 -0
- package/dist/federation/{router.test.js → router.test.mjs} +11 -16
- package/dist/federation/send.test.d.mts +2 -0
- package/dist/federation/{send.test.js → send.test.mjs} +22 -29
- package/dist/federation/webfinger.test.d.mts +2 -0
- package/dist/federation/{webfinger.test.js → webfinger.test.mjs} +22 -55
- package/dist/{http-DkHdFfrc.d.ts → http-B2wiNmSo.d.ts} +1 -6
- package/dist/{http-B3vAjAtl.js → http-Bz7avX57.js} +39 -159
- package/dist/{http-Cz3MlXAZ.d.cts → http-C_tEAiZj.d.cts} +1 -6
- package/dist/{http-CjaLjnRN.js → http-DI213UHg.mjs} +31 -35
- package/dist/{http-CQ7TiYUI.cjs → http-DKBDoudA.cjs} +119 -233
- package/dist/{inbox-B33isX44.js → inbox-Bdn-CSRd.mjs} +18 -26
- package/dist/{key-Cga1p73u.js → key-DzJf84o7.mjs} +12 -19
- package/dist/{keycache-DRxpZ5r9.js → keycache-DaQ3ndaJ.mjs} +15 -10
- package/dist/{keys-ZbcByPg9.js → keys-CtZLJq76.mjs} +5 -9
- package/dist/{kv-QzKcOQgP.js → kv-BrZHNugx.mjs} +6 -10
- package/dist/{kv-BL4nlICN.d.cts → kv-CbLNp3zQ.d.cts} +1 -1
- package/dist/{kv-DXEUEP6z.d.ts → kv-GFYnFoOl.d.ts} +1 -1
- package/dist/{kv-cache-CFdy0BpZ.js → kv-cache-DBd7BezJ.js} +6 -13
- package/dist/{kv-cache--qyREO7e.cjs → kv-cache-Dj1Q7TiW.cjs} +27 -34
- package/dist/{kv-cache-El7We5sy.js → kv-cache-OWmRLHir.mjs} +4 -8
- package/dist/{ld-BWSOukKj.js → ld-DczS1fLK.mjs} +17 -31
- package/dist/middleware-B5CiOImA.mjs +5 -0
- package/dist/{middleware-CP7JdsGq.js → middleware-BKNu57ZI.js} +331 -365
- package/dist/middleware-C36TOX-2.cjs +4 -0
- package/dist/{middleware-Scz2k9eL.cjs → middleware-CyjmpK70.cjs} +523 -565
- package/dist/{middleware-BI1VCuPT.js → middleware-DoHz9oIo.mjs} +260 -292
- package/dist/{mod-DPkRU3EK.d.cts → mod-1xhgsHef.d.cts} +2 -2
- package/dist/{mod-DUWcVv49.d.ts → mod-BGtYJZKu.d.ts} +2 -2
- package/dist/{mod-DXsQakeS.d.cts → mod-Bld7oeqf.d.cts} +3 -3
- package/dist/{mod-DnSsduJF.d.ts → mod-BnAKGh2w.d.ts} +2 -2
- package/dist/{mod-CwZXZJ9d.d.ts → mod-DTOUyCce.d.ts} +3 -3
- package/dist/{mod-Di3W5OdP.d.cts → mod-DWoQffTD.d.cts} +2 -2
- package/dist/mod.cjs +29 -68
- package/dist/mod.d.cts +11 -14
- package/dist/mod.d.ts +11 -15
- package/dist/mod.js +17 -65
- package/dist/{negotiation-5NPJL6zp.js → negotiation-BehA2uul.mjs} +7 -11
- package/dist/nodeinfo/client.test.d.mts +2 -0
- package/dist/nodeinfo/{client.test.js → client.test.mjs} +22 -40
- package/dist/nodeinfo/handler.test.d.mts +2 -0
- package/dist/nodeinfo/{handler.test.js → handler.test.mjs} +13 -42
- package/dist/nodeinfo/mod.cjs +5 -8
- package/dist/nodeinfo/mod.d.cts +2 -3
- package/dist/nodeinfo/mod.d.ts +2 -3
- package/dist/nodeinfo/mod.js +4 -8
- package/dist/nodeinfo/types.test.d.mts +2 -0
- package/dist/nodeinfo/{types.test.js → types.test.mjs} +9 -16
- package/dist/otel/exporter.test.d.mts +2 -0
- package/dist/otel/{exporter.test.js → exporter.test.mjs} +117 -169
- package/dist/otel/mod.cjs +15 -20
- package/dist/otel/mod.d.cts +2 -2
- package/dist/otel/mod.d.ts +2 -2
- package/dist/otel/mod.js +8 -14
- package/dist/{owner-gd0Q9FuU.d.ts → owner-74ARJ5TL.d.ts} +1 -1
- package/dist/{owner-1AbPBOOZ.d.cts → owner-CptqhsOy.d.cts} +1 -1
- package/dist/{owner-HASxJJP1.js → owner-DXMGUEOr.mjs} +11 -16
- package/dist/{proof-BwfRl5J4.js → proof-C-7NljBU.js} +33 -59
- package/dist/{proof-BXt2Oi8t.js → proof-CEOujj0L.mjs} +21 -33
- package/dist/{proof-BYZ4hcgN.cjs → proof-DMu-6A_w.cjs} +133 -157
- package/dist/{retry-D4GJ670a.js → retry-Ddbq3AcK.mjs} +4 -7
- package/dist/{router-D9eI0s4b.js → router-CrMLXoOr.mjs} +4 -8
- package/dist/runtime/mod.cjs +11 -13
- package/dist/runtime/mod.d.cts +6 -2
- package/dist/runtime/mod.d.ts +0 -1
- package/dist/runtime/mod.js +4 -7
- package/dist/{send-BF3omx5-.js → send-DIfrLTB_.mjs} +8 -13
- package/dist/sig/http.test.d.mts +2 -0
- package/dist/sig/{http.test.js → http.test.mjs} +160 -199
- package/dist/sig/key.test.d.mts +2 -0
- package/dist/sig/{key.test.js → key.test.mjs} +11 -18
- package/dist/sig/ld.test.d.mts +2 -0
- package/dist/sig/{ld.test.js → ld.test.mjs} +22 -35
- package/dist/sig/mod.cjs +6 -9
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +5 -9
- package/dist/sig/owner.test.d.mts +2 -0
- package/dist/sig/{owner.test.js → owner.test.mjs} +19 -34
- package/dist/sig/proof.test.d.mts +2 -0
- package/dist/sig/{proof.test.js → proof.test.mjs} +16 -27
- package/dist/{std__assert-DWivtrGR.js → std__assert-Duiq_YC9.mjs} +12 -24
- package/dist/testing/{mod.d.ts → mod.d.mts} +26 -78
- package/dist/testing/mod.mjs +6 -0
- package/dist/{transformers-3g8GZwkZ.cjs → transformers-NeAONrAq.cjs} +20 -25
- package/dist/{transformers-C3FLHUd6.js → transformers-ve6e2xcg.js} +3 -7
- package/dist/{types-CPz01LGH.js → types-C37hquWI.mjs} +4 -7
- package/dist/{types-Cd_hszr_.cjs → types-KC4QAoxe.cjs} +29 -34
- package/dist/{types-C93Ob9cU.js → types-hvL8ElAs.js} +8 -13
- package/dist/utils/docloader.test.d.mts +2 -0
- package/dist/utils/{docloader.test.js → docloader.test.mjs} +14 -24
- package/dist/utils/kv-cache.test.d.mts +2 -0
- package/dist/utils/{kv-cache.test.js → kv-cache.test.mjs} +25 -40
- package/dist/utils/mod.cjs +5 -9
- package/dist/utils/mod.d.cts +1 -3
- package/dist/utils/mod.d.ts +1 -3
- package/dist/utils/mod.js +4 -9
- package/dist/vocab/cjs.test.d.mts +2 -0
- package/dist/vocab/cjs.test.mjs +14 -0
- package/dist/vocab/mod.cjs +10 -12
- package/dist/vocab/mod.js +3 -5
- package/package.json +7 -7
- package/dist/compat/transformers.test.d.ts +0 -3
- package/dist/compat/transformers.test.js +0 -87
- package/dist/compat-Bb4NuTUO.js +0 -4
- package/dist/compat-DmDDELst.cjs +0 -4
- package/dist/deno-CbQK8e-e.js +0 -121
- package/dist/federation/builder.test.d.ts +0 -3
- package/dist/federation/collection.test.d.ts +0 -3
- package/dist/federation/collection.test.js +0 -32
- package/dist/federation/handler.test.d.ts +0 -3
- package/dist/federation/idempotency.test.d.ts +0 -3
- package/dist/federation/inbox.test.d.ts +0 -3
- package/dist/federation/keycache.test.d.ts +0 -3
- package/dist/federation/kv.test.d.ts +0 -3
- package/dist/federation/middleware.test.d.ts +0 -3
- package/dist/federation/mq.test.d.ts +0 -3
- package/dist/federation/negotiation.test.d.ts +0 -3
- package/dist/federation/retry.test.d.ts +0 -3
- package/dist/federation/router.test.d.ts +0 -3
- package/dist/federation/send.test.d.ts +0 -3
- package/dist/federation/webfinger.test.d.ts +0 -3
- package/dist/federation-Bp3HI26G.cjs +0 -350
- package/dist/federation-DaMfqRm4.js +0 -332
- package/dist/middleware-CcXQzfn8.cjs +0 -12
- package/dist/middleware-CoeaBowW.js +0 -12
- package/dist/middleware-vH2jFwC6.js +0 -26
- package/dist/mod-Bh8mqlYw.d.cts +0 -9
- package/dist/mod-D6HodEq7.d.ts +0 -7
- package/dist/mod-DVwHUI_x.d.cts +0 -80
- package/dist/mod-DosD6NsG.d.ts +0 -82
- package/dist/mod-gq_Xfdz8.d.cts +0 -1
- package/dist/nodeinfo/client.test.d.ts +0 -3
- package/dist/nodeinfo/handler.test.d.ts +0 -3
- package/dist/nodeinfo/types.test.d.ts +0 -3
- package/dist/nodeinfo-DoESQxq5.js +0 -4
- package/dist/nodeinfo-DuMYTpbZ.cjs +0 -4
- package/dist/otel/exporter.test.d.ts +0 -3
- package/dist/runtime-c2Njxsry.cjs +0 -17
- package/dist/runtime-poamPCMb.js +0 -13
- package/dist/sig/http.test.d.ts +0 -3
- package/dist/sig/key.test.d.ts +0 -3
- package/dist/sig/ld.test.d.ts +0 -3
- package/dist/sig/owner.test.d.ts +0 -3
- package/dist/sig/proof.test.d.ts +0 -3
- package/dist/sig-BNhspNOf.js +0 -4
- package/dist/sig-vX39WyWI.cjs +0 -4
- package/dist/testing/mod.js +0 -10
- package/dist/utils/docloader.test.d.ts +0 -3
- package/dist/utils/kv-cache.test.d.ts +0 -3
- package/dist/utils-BQ9KqEK9.cjs +0 -4
- package/dist/utils-Dn5OPdSW.js +0 -4
- /package/dist/{mod-AGjRfPjT.d.ts → compat/transformers.test.d.mts} +0 -0
|
@@ -1,34 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { createExponentialBackoffPolicy } from "./retry-D4GJ670a.js";
|
|
23
|
-
import { SendActivityError, extractInboxes, sendActivity } from "./send-BF3omx5-.js";
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { n as RouterError } from "./router-CrMLXoOr.mjs";
|
|
5
|
+
import { n as version, t as name } from "./deno-CuVDEdyj.mjs";
|
|
6
|
+
import { a as validateCryptoKey, i as importJwk, t as exportJwk } from "./key-DzJf84o7.mjs";
|
|
7
|
+
import { l as verifyRequest } from "./http-DI213UHg.mjs";
|
|
8
|
+
import { t as getAuthenticatedDocumentLoader } from "./docloader-BPq9yzC_.mjs";
|
|
9
|
+
import { n as kvCache } from "./kv-cache-OWmRLHir.mjs";
|
|
10
|
+
import { a as signJsonLd, i as hasSignature, o as verifyJsonLd, r as detachSignature } from "./ld-DczS1fLK.mjs";
|
|
11
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-DXMGUEOr.mjs";
|
|
12
|
+
import { n as signObject, r as verifyObject } from "./proof-CEOujj0L.mjs";
|
|
13
|
+
import { t as getNodeInfo } from "./client-A1UrnX6I.mjs";
|
|
14
|
+
import { t as nodeInfoToJson } from "./types-C37hquWI.mjs";
|
|
15
|
+
import { n as routeActivity } from "./inbox-Bdn-CSRd.mjs";
|
|
16
|
+
import { t as FederationBuilderImpl } from "./builder-DDoQaGOu.mjs";
|
|
17
|
+
import { t as buildCollectionSynchronizationHeader } from "./collection-ChgDTHLz.mjs";
|
|
18
|
+
import { t as KvKeyCache } from "./keycache-DaQ3ndaJ.mjs";
|
|
19
|
+
import { t as acceptsJsonLd } from "./negotiation-BehA2uul.mjs";
|
|
20
|
+
import { t as createExponentialBackoffPolicy } from "./retry-Ddbq3AcK.mjs";
|
|
21
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-DIfrLTB_.mjs";
|
|
24
22
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
25
|
-
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
26
23
|
import { lookupWebFinger } from "@fedify/webfinger";
|
|
27
|
-
import { getLogger, withContext } from "@logtape/logtape";
|
|
28
24
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
25
|
+
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
26
|
+
import { getLogger, withContext } from "@logtape/logtape";
|
|
29
27
|
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";
|
|
30
28
|
import { domainToASCII } from "node:url";
|
|
31
|
-
|
|
32
29
|
//#region src/compat/transformers.ts
|
|
33
30
|
const logger$1 = getLogger([
|
|
34
31
|
"fedify",
|
|
@@ -53,9 +50,9 @@ const logger$1 = getLogger([
|
|
|
53
50
|
* @return The activity with an ID assigned.
|
|
54
51
|
* @since 1.4.0
|
|
55
52
|
*/
|
|
56
|
-
function autoIdAssigner(activity, context
|
|
53
|
+
function autoIdAssigner(activity, context) {
|
|
57
54
|
if (activity.id != null) return activity;
|
|
58
|
-
const id = new URL(`/#${activity.constructor.name}/${crypto.randomUUID()}`, context
|
|
55
|
+
const id = new URL(`/#${activity.constructor.name}/${crypto.randomUUID()}`, context.origin);
|
|
59
56
|
logger$1.warn("As the activity to send does not have an id, a new id {id} has been generated for it. However, it is recommended to explicitly set the id for the activity.", { id: id.href });
|
|
60
57
|
return activity.clone({ id });
|
|
61
58
|
}
|
|
@@ -118,7 +115,6 @@ function actorDehydrator(activity, _context) {
|
|
|
118
115
|
function getDefaultActivityTransformers() {
|
|
119
116
|
return [autoIdAssigner, actorDehydrator];
|
|
120
117
|
}
|
|
121
|
-
|
|
122
118
|
//#endregion
|
|
123
119
|
//#region src/nodeinfo/handler.ts
|
|
124
120
|
/**
|
|
@@ -128,10 +124,9 @@ function getDefaultActivityTransformers() {
|
|
|
128
124
|
* @param parameters The parameters for handling the request.
|
|
129
125
|
* @returns The response to the request.
|
|
130
126
|
*/
|
|
131
|
-
async function handleNodeInfo(_request, { context
|
|
132
|
-
const promise = nodeInfoDispatcher(context
|
|
133
|
-
const
|
|
134
|
-
const json = nodeInfoToJson(nodeInfo);
|
|
127
|
+
async function handleNodeInfo(_request, { context, nodeInfoDispatcher }) {
|
|
128
|
+
const promise = nodeInfoDispatcher(context);
|
|
129
|
+
const json = nodeInfoToJson(promise instanceof Promise ? await promise : promise);
|
|
135
130
|
return new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\"" } });
|
|
136
131
|
}
|
|
137
132
|
/**
|
|
@@ -141,22 +136,20 @@ async function handleNodeInfo(_request, { context: context$1, nodeInfoDispatcher
|
|
|
141
136
|
* @param context The request context.
|
|
142
137
|
* @returns The response to the request.
|
|
143
138
|
*/
|
|
144
|
-
function handleNodeInfoJrd(_request, context
|
|
139
|
+
function handleNodeInfoJrd(_request, context) {
|
|
145
140
|
const links = [];
|
|
146
141
|
try {
|
|
147
142
|
links.push({
|
|
148
143
|
rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
|
|
149
|
-
href: context
|
|
144
|
+
href: context.getNodeInfoUri().href,
|
|
150
145
|
type: "application/json; profile=\"http://nodeinfo.diaspora.software/ns/schema/2.1#\""
|
|
151
146
|
});
|
|
152
147
|
} catch (e) {
|
|
153
148
|
if (!(e instanceof RouterError)) throw e;
|
|
154
149
|
}
|
|
155
|
-
const
|
|
156
|
-
const response = new Response(JSON.stringify(jrd), { headers: { "Content-Type": "application/jrd+json" } });
|
|
150
|
+
const response = new Response(JSON.stringify({ links }), { headers: { "Content-Type": "application/jrd+json" } });
|
|
157
151
|
return Promise.resolve(response);
|
|
158
152
|
}
|
|
159
|
-
|
|
160
153
|
//#endregion
|
|
161
154
|
//#region src/federation/handler.ts
|
|
162
155
|
/**
|
|
@@ -166,25 +159,25 @@ function handleNodeInfoJrd(_request, context$1) {
|
|
|
166
159
|
* @param parameters The parameters for handling the actor.
|
|
167
160
|
* @returns A promise that resolves to an HTTP response.
|
|
168
161
|
*/
|
|
169
|
-
async function handleActor(request, { identifier, context
|
|
170
|
-
const logger
|
|
162
|
+
async function handleActor(request, { identifier, context, actorDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
163
|
+
const logger = getLogger([
|
|
171
164
|
"fedify",
|
|
172
165
|
"federation",
|
|
173
166
|
"actor"
|
|
174
167
|
]);
|
|
175
168
|
if (actorDispatcher == null) {
|
|
176
|
-
logger
|
|
169
|
+
logger.debug("Actor dispatcher is not set.", { identifier });
|
|
177
170
|
return await onNotFound(request);
|
|
178
171
|
}
|
|
179
|
-
const actor = await actorDispatcher(context
|
|
172
|
+
const actor = await actorDispatcher(context, identifier);
|
|
180
173
|
if (actor == null) {
|
|
181
|
-
logger
|
|
174
|
+
logger.debug("Actor {identifier} not found.", { identifier });
|
|
182
175
|
return await onNotFound(request);
|
|
183
176
|
}
|
|
184
177
|
if (authorizePredicate != null) {
|
|
185
|
-
if (!await authorizePredicate(context
|
|
178
|
+
if (!await authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
186
179
|
}
|
|
187
|
-
const jsonLd = await actor.toJsonLd(context
|
|
180
|
+
const jsonLd = await actor.toJsonLd(context);
|
|
188
181
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
189
182
|
"Content-Type": "application/activity+json",
|
|
190
183
|
Vary: "Accept"
|
|
@@ -197,14 +190,14 @@ async function handleActor(request, { identifier, context: context$1, actorDispa
|
|
|
197
190
|
* @param parameters The parameters for handling the object.
|
|
198
191
|
* @returns A promise that resolves to an HTTP response.
|
|
199
192
|
*/
|
|
200
|
-
async function handleObject(request, { values, context
|
|
193
|
+
async function handleObject(request, { values, context, objectDispatcher, authorizePredicate, onNotFound, onUnauthorized }) {
|
|
201
194
|
if (objectDispatcher == null) return await onNotFound(request);
|
|
202
|
-
const object = await objectDispatcher(context
|
|
195
|
+
const object = await objectDispatcher(context, values);
|
|
203
196
|
if (object == null) return await onNotFound(request);
|
|
204
197
|
if (authorizePredicate != null) {
|
|
205
|
-
if (!await authorizePredicate(context
|
|
198
|
+
if (!await authorizePredicate(context, values)) return await onUnauthorized(request);
|
|
206
199
|
}
|
|
207
|
-
const jsonLd = await object.toJsonLd(context
|
|
200
|
+
const jsonLd = await object.toJsonLd(context);
|
|
208
201
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
209
202
|
"Content-Type": "application/activity+json",
|
|
210
203
|
Vary: "Accept"
|
|
@@ -220,18 +213,17 @@ async function handleObject(request, { values, context: context$1, objectDispatc
|
|
|
220
213
|
* @param parameters The parameters for handling the collection.
|
|
221
214
|
* @returns A promise that resolves to an HTTP response.
|
|
222
215
|
*/
|
|
223
|
-
async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context
|
|
224
|
-
const spanName = name.trim().replace(/\s+/g, "_");
|
|
216
|
+
async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound }) {
|
|
217
|
+
const spanName = name$1.trim().replace(/\s+/g, "_");
|
|
225
218
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
226
|
-
const tracer = tracerProvider.getTracer(
|
|
227
|
-
const
|
|
228
|
-
const cursor = url.searchParams.get("cursor");
|
|
219
|
+
const tracer = tracerProvider.getTracer(name, version);
|
|
220
|
+
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
229
221
|
if (collectionCallbacks == null) return await onNotFound(request);
|
|
230
222
|
let collection;
|
|
231
223
|
const baseUri = uriGetter(identifier);
|
|
232
224
|
if (cursor == null) {
|
|
233
|
-
const firstCursor = await collectionCallbacks.firstCursor?.(context
|
|
234
|
-
const totalItems = filter == null ? await collectionCallbacks.counter?.(context
|
|
225
|
+
const firstCursor = await collectionCallbacks.firstCursor?.(context, identifier);
|
|
226
|
+
const totalItems = filter == null ? await collectionCallbacks.counter?.(context, identifier) : void 0;
|
|
235
227
|
if (firstCursor == null) {
|
|
236
228
|
const itemsOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection ${spanName}`, {
|
|
237
229
|
kind: SpanKind.SERVER,
|
|
@@ -242,7 +234,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
242
234
|
}, async (span) => {
|
|
243
235
|
if (totalItems != null) span.setAttribute("activitypub.collection.total_items", Number(totalItems));
|
|
244
236
|
try {
|
|
245
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
237
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
|
|
246
238
|
if (page == null) {
|
|
247
239
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
248
240
|
return await onNotFound(request);
|
|
@@ -264,15 +256,15 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
264
256
|
collection = new OrderedCollection({
|
|
265
257
|
id: baseUri,
|
|
266
258
|
totalItems: totalItems == null ? null : Number(totalItems),
|
|
267
|
-
items: filterCollectionItems(itemsOrResponse, name, filterPredicate)
|
|
259
|
+
items: filterCollectionItems(itemsOrResponse, name$1, filterPredicate)
|
|
268
260
|
});
|
|
269
261
|
} else {
|
|
270
|
-
const lastCursor = await collectionCallbacks.lastCursor?.(context
|
|
271
|
-
const first = new URL(context
|
|
262
|
+
const lastCursor = await collectionCallbacks.lastCursor?.(context, identifier);
|
|
263
|
+
const first = new URL(context.url);
|
|
272
264
|
first.searchParams.set("cursor", firstCursor);
|
|
273
265
|
let last = null;
|
|
274
266
|
if (lastCursor != null) {
|
|
275
|
-
last = new URL(context
|
|
267
|
+
last = new URL(context.url);
|
|
276
268
|
last.searchParams.set("cursor", lastCursor);
|
|
277
269
|
}
|
|
278
270
|
collection = new OrderedCollection({
|
|
@@ -285,7 +277,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
285
277
|
} else {
|
|
286
278
|
const uri = new URL(baseUri);
|
|
287
279
|
uri.searchParams.set("cursor", cursor);
|
|
288
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name}`, {
|
|
280
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
|
|
289
281
|
kind: SpanKind.SERVER,
|
|
290
282
|
attributes: {
|
|
291
283
|
"activitypub.collection.id": uri.href,
|
|
@@ -294,7 +286,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
294
286
|
}
|
|
295
287
|
}, async (span) => {
|
|
296
288
|
try {
|
|
297
|
-
const page = await collectionCallbacks.dispatcher(context
|
|
289
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
|
|
298
290
|
if (page == null) {
|
|
299
291
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
300
292
|
return await onNotFound(request);
|
|
@@ -315,28 +307,28 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
|
|
|
315
307
|
const { items, prevCursor, nextCursor } = pageOrResponse;
|
|
316
308
|
let prev = null;
|
|
317
309
|
if (prevCursor != null) {
|
|
318
|
-
prev = new URL(context
|
|
310
|
+
prev = new URL(context.url);
|
|
319
311
|
prev.searchParams.set("cursor", prevCursor);
|
|
320
312
|
}
|
|
321
313
|
let next = null;
|
|
322
314
|
if (nextCursor != null) {
|
|
323
|
-
next = new URL(context
|
|
315
|
+
next = new URL(context.url);
|
|
324
316
|
next.searchParams.set("cursor", nextCursor);
|
|
325
317
|
}
|
|
326
|
-
const partOf = new URL(context
|
|
318
|
+
const partOf = new URL(context.url);
|
|
327
319
|
partOf.searchParams.delete("cursor");
|
|
328
320
|
collection = new OrderedCollectionPage({
|
|
329
321
|
id: uri,
|
|
330
322
|
prev,
|
|
331
323
|
next,
|
|
332
|
-
items: filterCollectionItems(items, name, filterPredicate),
|
|
324
|
+
items: filterCollectionItems(items, name$1, filterPredicate),
|
|
333
325
|
partOf
|
|
334
326
|
});
|
|
335
327
|
}
|
|
336
328
|
if (collectionCallbacks.authorizePredicate != null) {
|
|
337
|
-
if (!await collectionCallbacks.authorizePredicate(context
|
|
329
|
+
if (!await collectionCallbacks.authorizePredicate(context, identifier)) return await onUnauthorized(request);
|
|
338
330
|
}
|
|
339
|
-
const jsonLd = await collection.toJsonLd(context
|
|
331
|
+
const jsonLd = await collection.toJsonLd(context);
|
|
340
332
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
341
333
|
"Content-Type": "application/activity+json",
|
|
342
334
|
Vary: "Accept"
|
|
@@ -381,9 +373,7 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
|
381
373
|
* @returns A promise that resolves to an HTTP response.
|
|
382
374
|
*/
|
|
383
375
|
async function handleInbox(request, options) {
|
|
384
|
-
|
|
385
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
386
|
-
return await tracer.startActiveSpan("activitypub.inbox", {
|
|
376
|
+
return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("activitypub.inbox", {
|
|
387
377
|
kind: options.queue == null ? SpanKind.SERVER : SpanKind.PRODUCER,
|
|
388
378
|
attributes: { "activitypub.shared_inbox": options.recipient == null }
|
|
389
379
|
}, async (span) => {
|
|
@@ -411,22 +401,21 @@ async function handleInbox(request, options) {
|
|
|
411
401
|
*/
|
|
412
402
|
async function handleInboxInternal(request, parameters, span) {
|
|
413
403
|
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider } = parameters;
|
|
414
|
-
const logger
|
|
404
|
+
const logger = getLogger([
|
|
415
405
|
"fedify",
|
|
416
406
|
"federation",
|
|
417
407
|
"inbox"
|
|
418
408
|
]);
|
|
419
409
|
if (actorDispatcher == null) {
|
|
420
|
-
logger
|
|
410
|
+
logger.error("Actor dispatcher is not set.", { recipient });
|
|
421
411
|
span.setStatus({
|
|
422
412
|
code: SpanStatusCode.ERROR,
|
|
423
413
|
message: "Actor dispatcher is not set."
|
|
424
414
|
});
|
|
425
415
|
return await onNotFound(request);
|
|
426
416
|
} else if (recipient != null) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
logger$2.error("Actor {recipient} not found.", { recipient });
|
|
417
|
+
if (await actorDispatcher(ctx, recipient) == null) {
|
|
418
|
+
logger.error("Actor {recipient} not found.", { recipient });
|
|
430
419
|
span.setStatus({
|
|
431
420
|
code: SpanStatusCode.ERROR,
|
|
432
421
|
message: `Actor ${recipient} not found.`
|
|
@@ -435,7 +424,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
435
424
|
}
|
|
436
425
|
}
|
|
437
426
|
if (request.bodyUsed) {
|
|
438
|
-
logger
|
|
427
|
+
logger.error("Request body has already been read.", { recipient });
|
|
439
428
|
span.setStatus({
|
|
440
429
|
code: SpanStatusCode.ERROR,
|
|
441
430
|
message: "Request body has already been read."
|
|
@@ -445,7 +434,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
445
434
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
446
435
|
});
|
|
447
436
|
} else if (request.body?.locked) {
|
|
448
|
-
logger
|
|
437
|
+
logger.error("Request body is locked.", { recipient });
|
|
449
438
|
span.setStatus({
|
|
450
439
|
code: SpanStatusCode.ERROR,
|
|
451
440
|
message: "Request body is locked."
|
|
@@ -459,15 +448,15 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
459
448
|
try {
|
|
460
449
|
json = await request.clone().json();
|
|
461
450
|
} catch (error) {
|
|
462
|
-
logger
|
|
451
|
+
logger.error("Failed to parse JSON:\n{error}", {
|
|
463
452
|
recipient,
|
|
464
453
|
error
|
|
465
454
|
});
|
|
466
455
|
try {
|
|
467
456
|
await inboxErrorHandler?.(ctx, error);
|
|
468
|
-
} catch (error
|
|
469
|
-
logger
|
|
470
|
-
error
|
|
457
|
+
} catch (error) {
|
|
458
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
459
|
+
error,
|
|
471
460
|
activity: json,
|
|
472
461
|
recipient
|
|
473
462
|
});
|
|
@@ -492,7 +481,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
492
481
|
});
|
|
493
482
|
} catch (error) {
|
|
494
483
|
if (error instanceof Error && error.name === "jsonld.SyntaxError") {
|
|
495
|
-
logger
|
|
484
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
496
485
|
recipient,
|
|
497
486
|
error
|
|
498
487
|
});
|
|
@@ -506,13 +495,13 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
506
495
|
const jsonWithoutSig = detachSignature(json);
|
|
507
496
|
let activity = null;
|
|
508
497
|
if (ldSigVerified) {
|
|
509
|
-
logger
|
|
498
|
+
logger.debug("Linked Data Signatures are verified.", {
|
|
510
499
|
recipient,
|
|
511
500
|
json
|
|
512
501
|
});
|
|
513
502
|
activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
514
503
|
} else {
|
|
515
|
-
logger
|
|
504
|
+
logger.debug("Linked Data Signatures are not verified.", {
|
|
516
505
|
recipient,
|
|
517
506
|
json
|
|
518
507
|
});
|
|
@@ -524,16 +513,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
524
513
|
tracerProvider
|
|
525
514
|
});
|
|
526
515
|
} catch (error) {
|
|
527
|
-
logger
|
|
516
|
+
logger.error("Failed to parse activity:\n{error}", {
|
|
528
517
|
recipient,
|
|
529
518
|
activity: json,
|
|
530
519
|
error
|
|
531
520
|
});
|
|
532
521
|
try {
|
|
533
522
|
await inboxErrorHandler?.(ctx, error);
|
|
534
|
-
} catch (error
|
|
535
|
-
logger
|
|
536
|
-
error
|
|
523
|
+
} catch (error) {
|
|
524
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
525
|
+
error,
|
|
537
526
|
activity: json,
|
|
538
527
|
recipient
|
|
539
528
|
});
|
|
@@ -547,11 +536,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
547
536
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
548
537
|
});
|
|
549
538
|
}
|
|
550
|
-
if (activity == null) logger
|
|
539
|
+
if (activity == null) logger.debug("Object Integrity Proofs are not verified.", {
|
|
551
540
|
recipient,
|
|
552
541
|
activity: json
|
|
553
542
|
});
|
|
554
|
-
else logger
|
|
543
|
+
else logger.debug("Object Integrity Proofs are verified.", {
|
|
555
544
|
recipient,
|
|
556
545
|
activity: json
|
|
557
546
|
});
|
|
@@ -567,17 +556,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
567
556
|
tracerProvider
|
|
568
557
|
});
|
|
569
558
|
if (key == null) {
|
|
570
|
-
logger
|
|
559
|
+
logger.error("Failed to verify the request's HTTP Signatures.", { recipient });
|
|
571
560
|
span.setStatus({
|
|
572
561
|
code: SpanStatusCode.ERROR,
|
|
573
562
|
message: `Failed to verify the request's HTTP Signatures.`
|
|
574
563
|
});
|
|
575
|
-
|
|
564
|
+
return new Response("Failed to verify the request signature.", {
|
|
576
565
|
status: 401,
|
|
577
566
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
578
567
|
});
|
|
579
|
-
|
|
580
|
-
} else logger$2.debug("HTTP Signatures are verified.", { recipient });
|
|
568
|
+
} else logger.debug("HTTP Signatures are verified.", { recipient });
|
|
581
569
|
httpSigKey = key;
|
|
582
570
|
}
|
|
583
571
|
activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
@@ -592,7 +580,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
592
580
|
"http_signatures.key_id": httpSigKey?.id?.href ?? ""
|
|
593
581
|
});
|
|
594
582
|
if (httpSigKey != null && !await doesActorOwnKey(activity, httpSigKey, ctx)) {
|
|
595
|
-
logger
|
|
583
|
+
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
|
596
584
|
activity: json,
|
|
597
585
|
recipient,
|
|
598
586
|
keyId: httpSigKey.id?.href,
|
|
@@ -659,11 +647,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
659
647
|
* @since 1.8.0
|
|
660
648
|
*/
|
|
661
649
|
const handleCustomCollection = exceptWrapper(_handleCustomCollection);
|
|
662
|
-
async function _handleCustomCollection(request, { name, values, context
|
|
650
|
+
async function _handleCustomCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
663
651
|
verifyDefined(callbacks);
|
|
664
|
-
await authIfNeeded(context
|
|
652
|
+
await authIfNeeded(context, values, callbacks);
|
|
665
653
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
666
|
-
return await new CustomCollectionHandler(name, values, context
|
|
654
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, Collection, CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
667
655
|
}
|
|
668
656
|
/**
|
|
669
657
|
* Handles an ordered collection request.
|
|
@@ -677,11 +665,11 @@ async function _handleCustomCollection(request, { name, values, context: context
|
|
|
677
665
|
* @since 1.8.0
|
|
678
666
|
*/
|
|
679
667
|
const handleOrderedCollection = exceptWrapper(_handleOrderedCollection);
|
|
680
|
-
async function _handleOrderedCollection(request, { name, values, context
|
|
668
|
+
async function _handleOrderedCollection(request, { name, values, context, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
|
|
681
669
|
verifyDefined(callbacks);
|
|
682
|
-
await authIfNeeded(context
|
|
670
|
+
await authIfNeeded(context, values, callbacks);
|
|
683
671
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
684
|
-
return await new CustomCollectionHandler(name, values, context
|
|
672
|
+
return await new CustomCollectionHandler(name, values, context, callbacks, tracerProvider, OrderedCollection, OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
|
|
685
673
|
}
|
|
686
674
|
/**
|
|
687
675
|
* Handling custom collections with support for pagination and filtering.
|
|
@@ -731,17 +719,17 @@ var CustomCollectionHandler = class {
|
|
|
731
719
|
* @param CollectionPage The CollectionPage constructor.
|
|
732
720
|
* @param filterPredicate Optional filter predicate for items.
|
|
733
721
|
*/
|
|
734
|
-
constructor(name, values, context
|
|
735
|
-
this.name = name;
|
|
722
|
+
constructor(name$2, values, context, callbacks, tracerProvider = trace.getTracerProvider(), Collection, CollectionPage, filterPredicate) {
|
|
723
|
+
this.name = name$2;
|
|
736
724
|
this.values = values;
|
|
737
|
-
this.context = context
|
|
725
|
+
this.context = context;
|
|
738
726
|
this.callbacks = callbacks;
|
|
739
727
|
this.tracerProvider = tracerProvider;
|
|
740
|
-
this.Collection = Collection
|
|
741
|
-
this.CollectionPage = CollectionPage
|
|
728
|
+
this.Collection = Collection;
|
|
729
|
+
this.CollectionPage = CollectionPage;
|
|
742
730
|
this.filterPredicate = filterPredicate;
|
|
743
731
|
this.name = this.name.trim().replace(/\s+/g, "_");
|
|
744
|
-
this.#tracer = this.tracerProvider.getTracer(
|
|
732
|
+
this.#tracer = this.tracerProvider.getTracer(name, version);
|
|
745
733
|
this.#id = new URL(this.context.url);
|
|
746
734
|
this.#dispatcher = callbacks.dispatcher.bind(callbacks);
|
|
747
735
|
}
|
|
@@ -770,8 +758,8 @@ var CustomCollectionHandler = class {
|
|
|
770
758
|
*/
|
|
771
759
|
async getCollection(cursor = null) {
|
|
772
760
|
if (cursor !== null) {
|
|
773
|
-
const props
|
|
774
|
-
return new this.CollectionPage(props
|
|
761
|
+
const props = await this.getPageProps(cursor);
|
|
762
|
+
return new this.CollectionPage(props);
|
|
775
763
|
}
|
|
776
764
|
const firstCursor = await this.firstCursor;
|
|
777
765
|
const props = typeof firstCursor === "string" ? await this.getProps(firstCursor) : await this.getPropsWithoutCursor();
|
|
@@ -919,7 +907,7 @@ var CustomCollectionHandler = class {
|
|
|
919
907
|
* @param value The total items count or a promise that resolves to it.
|
|
920
908
|
*/
|
|
921
909
|
set totalItems(value) {
|
|
922
|
-
const toNumber = (value
|
|
910
|
+
const toNumber = (value) => value == null ? null : Number(value);
|
|
923
911
|
this.#totalItems = value instanceof Promise ? value.then(toNumber) : Promise.resolve(toNumber(value));
|
|
924
912
|
}
|
|
925
913
|
/**
|
|
@@ -983,9 +971,9 @@ const verifyDefined = (callbacks) => {
|
|
|
983
971
|
* @throws {UnauthorizedError} If authorization fails.
|
|
984
972
|
* @since 1.8.0
|
|
985
973
|
*/
|
|
986
|
-
const authIfNeeded = async (context
|
|
974
|
+
const authIfNeeded = async (context, values, { authorizePredicate: authorize = void 0 }) => {
|
|
987
975
|
if (authorize === void 0) return;
|
|
988
|
-
if (!await authorize(context
|
|
976
|
+
if (!await authorize(context, values)) throw new UnauthorizedError();
|
|
989
977
|
};
|
|
990
978
|
/**
|
|
991
979
|
* Appends a cursor parameter to a URL if the cursor exists.
|
|
@@ -1071,7 +1059,6 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
1071
1059
|
response.headers.set("Vary", "Accept");
|
|
1072
1060
|
return response;
|
|
1073
1061
|
}
|
|
1074
|
-
|
|
1075
1062
|
//#endregion
|
|
1076
1063
|
//#region src/federation/webfinger.ts
|
|
1077
1064
|
const logger = getLogger([
|
|
@@ -1104,12 +1091,12 @@ async function handleWebFinger(request, options) {
|
|
|
1104
1091
|
}
|
|
1105
1092
|
});
|
|
1106
1093
|
}
|
|
1107
|
-
async function handleWebFingerInternal(request, { context
|
|
1094
|
+
async function handleWebFingerInternal(request, { context, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
|
|
1108
1095
|
if (actorDispatcher == null) {
|
|
1109
1096
|
logger.error("Actor dispatcher is not set.");
|
|
1110
1097
|
return await onNotFound(request);
|
|
1111
1098
|
}
|
|
1112
|
-
const resource = context
|
|
1099
|
+
const resource = context.url.searchParams.get("resource");
|
|
1113
1100
|
if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
|
|
1114
1101
|
span?.setAttribute("webfinger.resource", resource);
|
|
1115
1102
|
let resourceUrl;
|
|
@@ -1125,26 +1112,26 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
1125
1112
|
logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
|
|
1126
1113
|
return username;
|
|
1127
1114
|
}
|
|
1128
|
-
const identifier
|
|
1129
|
-
if (identifier
|
|
1115
|
+
const identifier = await actorHandleMapper(context, username);
|
|
1116
|
+
if (identifier == null) {
|
|
1130
1117
|
logger.error("Actor {username} not found.", { username });
|
|
1131
1118
|
return null;
|
|
1132
1119
|
}
|
|
1133
|
-
return identifier
|
|
1120
|
+
return identifier;
|
|
1134
1121
|
}
|
|
1135
1122
|
let identifier = null;
|
|
1136
|
-
const uriParsed = context
|
|
1123
|
+
const uriParsed = context.parseUri(resourceUrl);
|
|
1137
1124
|
if (uriParsed?.type != "actor") {
|
|
1138
1125
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
1139
1126
|
if (match == null) {
|
|
1140
|
-
const result = await actorAliasMapper?.(context
|
|
1127
|
+
const result = await actorAliasMapper?.(context, resourceUrl);
|
|
1141
1128
|
if (result == null) return await onNotFound(request);
|
|
1142
1129
|
if ("identifier" in result) identifier = result.identifier;
|
|
1143
1130
|
else identifier = await mapUsernameToIdentifier(result.username);
|
|
1144
1131
|
} else {
|
|
1145
1132
|
const portMatch = /:\d+$/.exec(match[2]);
|
|
1146
1133
|
const normalizedHost = portMatch == null ? domainToASCII(match[2].toLowerCase()) : domainToASCII(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
1147
|
-
if (normalizedHost != context
|
|
1134
|
+
if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
|
|
1148
1135
|
else {
|
|
1149
1136
|
identifier = await mapUsernameToIdentifier(match[1]);
|
|
1150
1137
|
resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
|
|
@@ -1152,14 +1139,14 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
1152
1139
|
}
|
|
1153
1140
|
} else identifier = uriParsed.identifier;
|
|
1154
1141
|
if (identifier == null) return await onNotFound(request);
|
|
1155
|
-
const actor = await actorDispatcher(context
|
|
1142
|
+
const actor = await actorDispatcher(context, identifier);
|
|
1156
1143
|
if (actor == null) {
|
|
1157
1144
|
logger.error("Actor {identifier} not found.", { identifier });
|
|
1158
1145
|
return await onNotFound(request);
|
|
1159
1146
|
}
|
|
1160
1147
|
const links = [{
|
|
1161
1148
|
rel: "self",
|
|
1162
|
-
href: context
|
|
1149
|
+
href: context.getActorUri(identifier).href,
|
|
1163
1150
|
type: "application/activity+json"
|
|
1164
1151
|
}];
|
|
1165
1152
|
for (const url of actor.urls) if (url instanceof Link && url.href != null) links.push({
|
|
@@ -1180,16 +1167,16 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
1180
1167
|
});
|
|
1181
1168
|
}
|
|
1182
1169
|
if (webFingerLinksDispatcher != null) {
|
|
1183
|
-
const customLinks = await webFingerLinksDispatcher(context
|
|
1170
|
+
const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
|
|
1184
1171
|
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
1185
1172
|
}
|
|
1186
1173
|
const aliases = [];
|
|
1187
1174
|
if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
|
|
1188
|
-
aliases.push(`acct:${actor.preferredUsername}@${host ?? context
|
|
1189
|
-
if (host != null && host !== context
|
|
1175
|
+
aliases.push(`acct:${actor.preferredUsername}@${host ?? context.url.host}`);
|
|
1176
|
+
if (host != null && host !== context.url.host) aliases.push(`acct:${actor.preferredUsername}@${context.url.host}`);
|
|
1190
1177
|
}
|
|
1191
|
-
if (resourceUrl.href !== context
|
|
1192
|
-
if (resourceUrl.protocol === "acct:" && host != null && host !== context
|
|
1178
|
+
if (resourceUrl.href !== context.getActorUri(identifier).href) aliases.push(context.getActorUri(identifier).href);
|
|
1179
|
+
if (resourceUrl.protocol === "acct:" && host != null && host !== context.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
1193
1180
|
const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
|
|
1194
1181
|
aliases.push(`acct:${username}@${host}`);
|
|
1195
1182
|
}
|
|
@@ -1203,7 +1190,6 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
|
|
|
1203
1190
|
"Access-Control-Allow-Origin": "*"
|
|
1204
1191
|
} });
|
|
1205
1192
|
}
|
|
1206
|
-
|
|
1207
1193
|
//#endregion
|
|
1208
1194
|
//#region src/federation/middleware.ts
|
|
1209
1195
|
/**
|
|
@@ -1331,28 +1317,28 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1331
1317
|
this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
|
|
1332
1318
|
}
|
|
1333
1319
|
_getTracer() {
|
|
1334
|
-
return this.tracerProvider.getTracer(
|
|
1320
|
+
return this.tracerProvider.getTracer(name, version);
|
|
1335
1321
|
}
|
|
1336
1322
|
async _startQueueInternal(ctxData, signal, queue) {
|
|
1337
1323
|
if (this.inboxQueue == null && this.outboxQueue == null) return;
|
|
1338
|
-
const logger
|
|
1324
|
+
const logger = getLogger([
|
|
1339
1325
|
"fedify",
|
|
1340
1326
|
"federation",
|
|
1341
1327
|
"queue"
|
|
1342
1328
|
]);
|
|
1343
1329
|
const promises = [];
|
|
1344
1330
|
if (this.inboxQueue != null && (queue == null || queue === "inbox") && !this.inboxQueueStarted) {
|
|
1345
|
-
logger
|
|
1331
|
+
logger.debug("Starting an inbox task worker.");
|
|
1346
1332
|
this.inboxQueueStarted = true;
|
|
1347
1333
|
promises.push(this.inboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
1348
1334
|
}
|
|
1349
1335
|
if (this.outboxQueue != null && this.outboxQueue !== this.inboxQueue && (queue == null || queue === "outbox") && !this.outboxQueueStarted) {
|
|
1350
|
-
logger
|
|
1336
|
+
logger.debug("Starting an outbox task worker.");
|
|
1351
1337
|
this.outboxQueueStarted = true;
|
|
1352
1338
|
promises.push(this.outboxQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
1353
1339
|
}
|
|
1354
1340
|
if (this.fanoutQueue != null && this.fanoutQueue !== this.inboxQueue && this.fanoutQueue !== this.outboxQueue && (queue == null || queue === "fanout") && !this.fanoutQueueStarted) {
|
|
1355
|
-
logger
|
|
1341
|
+
logger.debug("Starting a fanout task worker.");
|
|
1356
1342
|
this.fanoutQueueStarted = true;
|
|
1357
1343
|
promises.push(this.fanoutQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
1358
1344
|
}
|
|
@@ -1436,12 +1422,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1436
1422
|
});
|
|
1437
1423
|
}
|
|
1438
1424
|
async #listenFanoutMessage(data, message) {
|
|
1439
|
-
|
|
1425
|
+
getLogger([
|
|
1440
1426
|
"fedify",
|
|
1441
1427
|
"federation",
|
|
1442
1428
|
"fanout"
|
|
1443
|
-
])
|
|
1444
|
-
logger$2.debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
1429
|
+
]).debug("Fanning out activity {activityId} to {inboxes} inbox(es)...", {
|
|
1445
1430
|
activityId: message.activityId,
|
|
1446
1431
|
inboxes: globalThis.Object.keys(message.inboxes).length
|
|
1447
1432
|
});
|
|
@@ -1460,18 +1445,18 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1460
1445
|
}),
|
|
1461
1446
|
tracerProvider: this.tracerProvider
|
|
1462
1447
|
});
|
|
1463
|
-
const context
|
|
1448
|
+
const context = this.#createContext(new URL(message.baseUrl), data, { documentLoader: this.documentLoaderFactory({
|
|
1464
1449
|
allowPrivateAddress: this.allowPrivateAddress,
|
|
1465
1450
|
userAgent: this.userAgent
|
|
1466
1451
|
}) });
|
|
1467
1452
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
1468
1453
|
collectionSync: message.collectionSync,
|
|
1469
1454
|
orderingKey: message.orderingKey,
|
|
1470
|
-
context
|
|
1455
|
+
context
|
|
1471
1456
|
});
|
|
1472
1457
|
}
|
|
1473
1458
|
async #listenOutboxMessage(_, message, span) {
|
|
1474
|
-
const logger
|
|
1459
|
+
const logger = getLogger([
|
|
1475
1460
|
"fedify",
|
|
1476
1461
|
"federation",
|
|
1477
1462
|
"outbox"
|
|
@@ -1519,14 +1504,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1519
1504
|
});
|
|
1520
1505
|
try {
|
|
1521
1506
|
await this.onOutboxError?.(error, activity);
|
|
1522
|
-
} catch (error
|
|
1523
|
-
logger
|
|
1507
|
+
} catch (error) {
|
|
1508
|
+
logger.error("An unexpected error occurred in onError handler:\n{error}", {
|
|
1524
1509
|
...logData,
|
|
1525
|
-
error
|
|
1510
|
+
error
|
|
1526
1511
|
});
|
|
1527
1512
|
}
|
|
1528
1513
|
if (error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode)) {
|
|
1529
|
-
logger
|
|
1514
|
+
logger.warn("Permanent delivery failure for activity {activityId} to {inbox} ({status}); not retrying.", {
|
|
1530
1515
|
...logData,
|
|
1531
1516
|
status: error.statusCode
|
|
1532
1517
|
});
|
|
@@ -1542,13 +1527,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1542
1527
|
try {
|
|
1543
1528
|
return [new URL(id)];
|
|
1544
1529
|
} catch {
|
|
1545
|
-
logger
|
|
1530
|
+
logger.warn("Invalid actorId URL in OutboxMessage: {id}", { id });
|
|
1546
1531
|
return [];
|
|
1547
1532
|
}
|
|
1548
1533
|
})
|
|
1549
1534
|
});
|
|
1550
1535
|
} catch (handlerError) {
|
|
1551
|
-
logger
|
|
1536
|
+
logger.error("An unexpected error occurred in outboxPermanentFailureHandler:\n{error}", {
|
|
1552
1537
|
...logData,
|
|
1553
1538
|
error: handlerError
|
|
1554
1539
|
});
|
|
@@ -1557,7 +1542,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1557
1542
|
return;
|
|
1558
1543
|
}
|
|
1559
1544
|
if (this.outboxQueue?.nativeRetrial) {
|
|
1560
|
-
logger
|
|
1545
|
+
logger.error("Failed to send activity {activityId} to {inbox}; backend will handle retry:\n{error}", {
|
|
1561
1546
|
...logData,
|
|
1562
1547
|
error
|
|
1563
1548
|
});
|
|
@@ -1568,7 +1553,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1568
1553
|
attempts: message.attempt
|
|
1569
1554
|
});
|
|
1570
1555
|
if (delay != null) {
|
|
1571
|
-
logger
|
|
1556
|
+
logger.error("Failed to send activity {activityId} to {inbox} (attempt #{attempt}); retry...:\n{error}", {
|
|
1572
1557
|
...logData,
|
|
1573
1558
|
error
|
|
1574
1559
|
});
|
|
@@ -1576,39 +1561,38 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1576
1561
|
...message,
|
|
1577
1562
|
attempt: message.attempt + 1
|
|
1578
1563
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
1579
|
-
} else logger
|
|
1564
|
+
} else logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
1580
1565
|
...logData,
|
|
1581
1566
|
error
|
|
1582
1567
|
});
|
|
1583
1568
|
return;
|
|
1584
1569
|
}
|
|
1585
|
-
logger
|
|
1570
|
+
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
1586
1571
|
}
|
|
1587
1572
|
async #listenInboxMessage(ctxData, message, span) {
|
|
1588
|
-
const logger
|
|
1573
|
+
const logger = getLogger([
|
|
1589
1574
|
"fedify",
|
|
1590
1575
|
"federation",
|
|
1591
1576
|
"inbox"
|
|
1592
1577
|
]);
|
|
1593
1578
|
const baseUrl = new URL(message.baseUrl);
|
|
1594
|
-
let context
|
|
1595
|
-
if (message.identifier != null) context
|
|
1579
|
+
let context = this.#createContext(baseUrl, ctxData);
|
|
1580
|
+
if (message.identifier != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: await context.getDocumentLoader({ identifier: message.identifier }) });
|
|
1596
1581
|
else if (this.sharedInboxKeyDispatcher != null) {
|
|
1597
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
1598
|
-
if (identity != null) context
|
|
1582
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
1583
|
+
if (identity != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
1599
1584
|
}
|
|
1600
|
-
const activity = await Activity.fromJsonLd(message.activity, context
|
|
1585
|
+
const activity = await Activity.fromJsonLd(message.activity, context);
|
|
1601
1586
|
span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
|
|
1602
1587
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
1603
1588
|
const cacheKey = activity.id == null ? null : [
|
|
1604
1589
|
...this.kvPrefixes.activityIdempotence,
|
|
1605
|
-
context
|
|
1590
|
+
context.origin,
|
|
1606
1591
|
activity.id.href
|
|
1607
1592
|
];
|
|
1608
1593
|
if (cacheKey != null) {
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
logger$2.debug("Activity {activityId} has already been processed.", {
|
|
1594
|
+
if (await this.kv.get(cacheKey) === true) {
|
|
1595
|
+
logger.debug("Activity {activityId} has already been processed.", {
|
|
1612
1596
|
activityId: activity.id?.href,
|
|
1613
1597
|
activity: message.activity,
|
|
1614
1598
|
recipient: message.identifier
|
|
@@ -1616,32 +1600,32 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1616
1600
|
return;
|
|
1617
1601
|
}
|
|
1618
1602
|
}
|
|
1619
|
-
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span
|
|
1603
|
+
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
|
|
1620
1604
|
const dispatched = this.inboxListeners?.dispatchWithClass(activity);
|
|
1621
1605
|
if (dispatched == null) {
|
|
1622
|
-
logger
|
|
1606
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
1623
1607
|
activityId: activity.id?.href,
|
|
1624
1608
|
activity: message.activity,
|
|
1625
1609
|
recipient: message.identifier,
|
|
1626
1610
|
trial: message.attempt
|
|
1627
1611
|
});
|
|
1628
|
-
span
|
|
1612
|
+
span.setStatus({
|
|
1629
1613
|
code: SpanStatusCode.ERROR,
|
|
1630
1614
|
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
1631
1615
|
});
|
|
1632
|
-
span
|
|
1616
|
+
span.end();
|
|
1633
1617
|
return;
|
|
1634
1618
|
}
|
|
1635
1619
|
const { class: cls, listener } = dispatched;
|
|
1636
|
-
span
|
|
1620
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
1637
1621
|
try {
|
|
1638
|
-
await listener(context
|
|
1622
|
+
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, getTypeId(activity).href), activity);
|
|
1639
1623
|
} catch (error) {
|
|
1640
1624
|
try {
|
|
1641
|
-
await this.inboxErrorHandler?.(context
|
|
1642
|
-
} catch (error
|
|
1643
|
-
logger
|
|
1644
|
-
error
|
|
1625
|
+
await this.inboxErrorHandler?.(context, error);
|
|
1626
|
+
} catch (error) {
|
|
1627
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1628
|
+
error,
|
|
1645
1629
|
trial: message.attempt,
|
|
1646
1630
|
activityId: activity.id?.href,
|
|
1647
1631
|
activity: message.activity,
|
|
@@ -1649,17 +1633,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1649
1633
|
});
|
|
1650
1634
|
}
|
|
1651
1635
|
if (this.inboxQueue?.nativeRetrial) {
|
|
1652
|
-
logger
|
|
1636
|
+
logger.error("Failed to process the incoming activity {activityId}; backend will handle retry:\n{error}", {
|
|
1653
1637
|
error,
|
|
1654
1638
|
activityId: activity.id?.href,
|
|
1655
1639
|
activity: message.activity,
|
|
1656
1640
|
recipient: message.identifier
|
|
1657
1641
|
});
|
|
1658
|
-
span
|
|
1642
|
+
span.setStatus({
|
|
1659
1643
|
code: SpanStatusCode.ERROR,
|
|
1660
1644
|
message: String(error)
|
|
1661
1645
|
});
|
|
1662
|
-
span
|
|
1646
|
+
span.end();
|
|
1663
1647
|
throw error;
|
|
1664
1648
|
}
|
|
1665
1649
|
const delay = this.inboxRetryPolicy({
|
|
@@ -1667,7 +1651,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1667
1651
|
attempts: message.attempt
|
|
1668
1652
|
});
|
|
1669
1653
|
if (delay != null) {
|
|
1670
|
-
logger
|
|
1654
|
+
logger.error("Failed to process the incoming activity {activityId} (attempt #{attempt}); retry...:\n{error}", {
|
|
1671
1655
|
error,
|
|
1672
1656
|
attempt: message.attempt,
|
|
1673
1657
|
activityId: activity.id?.href,
|
|
@@ -1678,26 +1662,26 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1678
1662
|
...message,
|
|
1679
1663
|
attempt: message.attempt + 1
|
|
1680
1664
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
1681
|
-
} else logger
|
|
1665
|
+
} else logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
1682
1666
|
error,
|
|
1683
1667
|
activityId: activity.id?.href,
|
|
1684
1668
|
activity: message.activity,
|
|
1685
1669
|
recipient: message.identifier
|
|
1686
1670
|
});
|
|
1687
|
-
span
|
|
1671
|
+
span.setStatus({
|
|
1688
1672
|
code: SpanStatusCode.ERROR,
|
|
1689
1673
|
message: String(error)
|
|
1690
1674
|
});
|
|
1691
|
-
span
|
|
1675
|
+
span.end();
|
|
1692
1676
|
return;
|
|
1693
1677
|
}
|
|
1694
1678
|
if (cacheKey != null) await this.kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
1695
|
-
logger
|
|
1679
|
+
logger.info("Activity {activityId} has been processed.", {
|
|
1696
1680
|
activityId: activity.id?.href,
|
|
1697
1681
|
activity: message.activity,
|
|
1698
1682
|
recipient: message.identifier
|
|
1699
1683
|
});
|
|
1700
|
-
span
|
|
1684
|
+
span.end();
|
|
1701
1685
|
});
|
|
1702
1686
|
}
|
|
1703
1687
|
startQueue(contextData, options = {}) {
|
|
@@ -1741,7 +1725,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1741
1725
|
};
|
|
1742
1726
|
}
|
|
1743
1727
|
async sendActivity(keys, inboxes, activity, options) {
|
|
1744
|
-
const logger
|
|
1728
|
+
const logger = getLogger([
|
|
1745
1729
|
"fedify",
|
|
1746
1730
|
"federation",
|
|
1747
1731
|
"outbox"
|
|
@@ -1775,7 +1759,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1775
1759
|
format: "compact",
|
|
1776
1760
|
contextLoader
|
|
1777
1761
|
});
|
|
1778
|
-
if (rsaKey == null) logger
|
|
1762
|
+
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.", {
|
|
1779
1763
|
activityId,
|
|
1780
1764
|
keys: keys.map((pair) => ({
|
|
1781
1765
|
keyId: pair.keyId.href,
|
|
@@ -1786,7 +1770,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1786
1770
|
contextLoader,
|
|
1787
1771
|
tracerProvider: this.tracerProvider
|
|
1788
1772
|
});
|
|
1789
|
-
if (!proofCreated) logger
|
|
1773
|
+
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.", {
|
|
1790
1774
|
activityId,
|
|
1791
1775
|
keys: keys.map((pair) => ({
|
|
1792
1776
|
keyId: pair.keyId.href,
|
|
@@ -1794,11 +1778,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1794
1778
|
}))
|
|
1795
1779
|
});
|
|
1796
1780
|
if (immediate || this.outboxQueue == null) {
|
|
1797
|
-
if (immediate) logger
|
|
1781
|
+
if (immediate) logger.debug("Sending activity immediately without queue since immediate option is set.", {
|
|
1798
1782
|
activityId: activity.id.href,
|
|
1799
1783
|
activity: jsonLd
|
|
1800
1784
|
});
|
|
1801
|
-
else logger
|
|
1785
|
+
else logger.debug("Sending activity immediately without queue since queue is not set.", {
|
|
1802
1786
|
activityId: activity.id.href,
|
|
1803
1787
|
activity: jsonLd
|
|
1804
1788
|
});
|
|
@@ -1817,7 +1801,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1817
1801
|
await Promise.all(promises);
|
|
1818
1802
|
return;
|
|
1819
1803
|
}
|
|
1820
|
-
logger
|
|
1804
|
+
logger.debug("Enqueuing activity {activityId} to send later.", {
|
|
1821
1805
|
activityId: activity.id.href,
|
|
1822
1806
|
activity: jsonLd
|
|
1823
1807
|
});
|
|
@@ -1861,10 +1845,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1861
1845
|
const { outboxQueue } = this;
|
|
1862
1846
|
if (outboxQueue.enqueueMany == null) {
|
|
1863
1847
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
1864
|
-
const
|
|
1865
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
1848
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
1866
1849
|
if (errors.length > 0) {
|
|
1867
|
-
logger
|
|
1850
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
1868
1851
|
activityId: activity.id.href,
|
|
1869
1852
|
errors
|
|
1870
1853
|
});
|
|
@@ -1873,10 +1856,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1873
1856
|
}
|
|
1874
1857
|
} else if (orderingKey != null) {
|
|
1875
1858
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
1876
|
-
const
|
|
1877
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
1859
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
1878
1860
|
if (errors.length > 0) {
|
|
1879
|
-
logger
|
|
1861
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
1880
1862
|
activityId: activity.id.href,
|
|
1881
1863
|
errors
|
|
1882
1864
|
});
|
|
@@ -1886,7 +1868,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1886
1868
|
} else try {
|
|
1887
1869
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
1888
1870
|
} catch (error) {
|
|
1889
|
-
logger
|
|
1871
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
1890
1872
|
activityId: activity.id.href,
|
|
1891
1873
|
error
|
|
1892
1874
|
});
|
|
@@ -1894,8 +1876,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1894
1876
|
}
|
|
1895
1877
|
}
|
|
1896
1878
|
fetch(request, options) {
|
|
1897
|
-
|
|
1898
|
-
return withContext({ requestId }, async () => {
|
|
1879
|
+
return withContext({ requestId: getRequestId(request) }, async () => {
|
|
1899
1880
|
const tracer = this._getTracer();
|
|
1900
1881
|
return await tracer.startActiveSpan(request.method, {
|
|
1901
1882
|
kind: SpanKind.SERVER,
|
|
@@ -1909,7 +1890,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1909
1890
|
traceId: spanCtx.traceId,
|
|
1910
1891
|
spanId: spanCtx.spanId
|
|
1911
1892
|
}, async () => {
|
|
1912
|
-
const logger
|
|
1893
|
+
const logger = getLogger([
|
|
1913
1894
|
"fedify",
|
|
1914
1895
|
"federation",
|
|
1915
1896
|
"http"
|
|
@@ -1929,7 +1910,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1929
1910
|
message: `${error}`
|
|
1930
1911
|
});
|
|
1931
1912
|
span.end();
|
|
1932
|
-
logger
|
|
1913
|
+
logger.error("An error occurred while serving request {method} {url}: {error}", {
|
|
1933
1914
|
method: request.method,
|
|
1934
1915
|
url: request.url,
|
|
1935
1916
|
error
|
|
@@ -1953,9 +1934,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1953
1934
|
url: request.url,
|
|
1954
1935
|
status: response.status
|
|
1955
1936
|
};
|
|
1956
|
-
if (response.status >= 500) logger
|
|
1957
|
-
else if (response.status >= 400) logger
|
|
1958
|
-
else logger
|
|
1937
|
+
if (response.status >= 500) logger.error(logTpl, values);
|
|
1938
|
+
else if (response.status >= 400) logger.warn(logTpl, values);
|
|
1939
|
+
else logger.info(logTpl, values);
|
|
1959
1940
|
return response;
|
|
1960
1941
|
});
|
|
1961
1942
|
});
|
|
@@ -1969,11 +1950,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1969
1950
|
const route = this.router.route(url.pathname);
|
|
1970
1951
|
if (route == null) return await onNotFound(request);
|
|
1971
1952
|
span.updateName(`${request.method} ${route.template}`);
|
|
1972
|
-
let context
|
|
1953
|
+
let context = this.#createContext(request, contextData);
|
|
1973
1954
|
const routeName = route.name.replace(/:.*$/, "");
|
|
1974
1955
|
switch (routeName) {
|
|
1975
1956
|
case "webfinger": return await handleWebFinger(request, {
|
|
1976
|
-
context
|
|
1957
|
+
context,
|
|
1977
1958
|
host: this.origin?.handleHost,
|
|
1978
1959
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
1979
1960
|
actorHandleMapper: this.actorCallbacks?.handleMapper,
|
|
@@ -1982,19 +1963,19 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1982
1963
|
onNotFound,
|
|
1983
1964
|
tracer
|
|
1984
1965
|
});
|
|
1985
|
-
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context
|
|
1966
|
+
case "nodeInfoJrd": return await handleNodeInfoJrd(request, context);
|
|
1986
1967
|
case "nodeInfo": return await handleNodeInfo(request, {
|
|
1987
|
-
context
|
|
1968
|
+
context,
|
|
1988
1969
|
nodeInfoDispatcher: this.nodeInfoDispatcher
|
|
1989
1970
|
});
|
|
1990
1971
|
}
|
|
1991
1972
|
if (request.method !== "POST" && !acceptsJsonLd(request)) return await onNotAcceptable(request);
|
|
1992
1973
|
switch (routeName) {
|
|
1993
1974
|
case "actor":
|
|
1994
|
-
context
|
|
1975
|
+
context = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier: route.values.identifier } });
|
|
1995
1976
|
return await handleActor(request, {
|
|
1996
1977
|
identifier: route.values.identifier,
|
|
1997
|
-
context
|
|
1978
|
+
context,
|
|
1998
1979
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
|
1999
1980
|
authorizePredicate: this.actorCallbacks?.authorizePredicate,
|
|
2000
1981
|
onUnauthorized,
|
|
@@ -2004,13 +1985,13 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2004
1985
|
const typeId = route.name.replace(/^object:/, "");
|
|
2005
1986
|
const callbacks = this.objectCallbacks[typeId];
|
|
2006
1987
|
const cls = this.objectTypeIds[typeId];
|
|
2007
|
-
context
|
|
1988
|
+
context = this.#createContext(request, contextData, { invokedFromObjectDispatcher: {
|
|
2008
1989
|
cls,
|
|
2009
1990
|
values: route.values
|
|
2010
1991
|
} });
|
|
2011
1992
|
return await handleObject(request, {
|
|
2012
1993
|
values: route.values,
|
|
2013
|
-
context
|
|
1994
|
+
context,
|
|
2014
1995
|
objectDispatcher: callbacks?.dispatcher,
|
|
2015
1996
|
authorizePredicate: callbacks?.authorizePredicate,
|
|
2016
1997
|
onUnauthorized,
|
|
@@ -2020,8 +2001,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2020
2001
|
case "outbox": return await handleCollection(request, {
|
|
2021
2002
|
name: "outbox",
|
|
2022
2003
|
identifier: route.values.identifier,
|
|
2023
|
-
uriGetter: context
|
|
2024
|
-
context
|
|
2004
|
+
uriGetter: context.getOutboxUri.bind(context),
|
|
2005
|
+
context,
|
|
2025
2006
|
collectionCallbacks: this.outboxCallbacks,
|
|
2026
2007
|
tracerProvider: this.tracerProvider,
|
|
2027
2008
|
onUnauthorized,
|
|
@@ -2031,24 +2012,24 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2031
2012
|
if (request.method !== "POST") return await handleCollection(request, {
|
|
2032
2013
|
name: "inbox",
|
|
2033
2014
|
identifier: route.values.identifier,
|
|
2034
|
-
uriGetter: context
|
|
2035
|
-
context
|
|
2015
|
+
uriGetter: context.getInboxUri.bind(context),
|
|
2016
|
+
context,
|
|
2036
2017
|
collectionCallbacks: this.inboxCallbacks,
|
|
2037
2018
|
tracerProvider: this.tracerProvider,
|
|
2038
2019
|
onUnauthorized,
|
|
2039
2020
|
onNotFound
|
|
2040
2021
|
});
|
|
2041
|
-
context
|
|
2022
|
+
context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier: route.values.identifier }) });
|
|
2042
2023
|
case "sharedInbox":
|
|
2043
2024
|
if (routeName !== "inbox" && this.sharedInboxKeyDispatcher != null) {
|
|
2044
|
-
const identity = await this.sharedInboxKeyDispatcher(context
|
|
2045
|
-
if (identity != null) context
|
|
2025
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
2026
|
+
if (identity != null) context = this.#createContext(request, contextData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
2046
2027
|
}
|
|
2047
2028
|
if (!this.manuallyStartQueue) this._startQueueInternal(contextData);
|
|
2048
2029
|
return await handleInbox(request, {
|
|
2049
2030
|
recipient: route.values.identifier ?? null,
|
|
2050
|
-
context
|
|
2051
|
-
inboxContextFactory: context
|
|
2031
|
+
context,
|
|
2032
|
+
inboxContextFactory: context.toInboxContext.bind(context),
|
|
2052
2033
|
kv: this.kv,
|
|
2053
2034
|
kvPrefixes: this.kvPrefixes,
|
|
2054
2035
|
queue: this.inboxQueue,
|
|
@@ -2064,8 +2045,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2064
2045
|
case "following": return await handleCollection(request, {
|
|
2065
2046
|
name: "following",
|
|
2066
2047
|
identifier: route.values.identifier,
|
|
2067
|
-
uriGetter: context
|
|
2068
|
-
context
|
|
2048
|
+
uriGetter: context.getFollowingUri.bind(context),
|
|
2049
|
+
context,
|
|
2069
2050
|
collectionCallbacks: this.followingCallbacks,
|
|
2070
2051
|
tracerProvider: this.tracerProvider,
|
|
2071
2052
|
onUnauthorized,
|
|
@@ -2081,14 +2062,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2081
2062
|
return await handleCollection(request, {
|
|
2082
2063
|
name: "followers",
|
|
2083
2064
|
identifier: route.values.identifier,
|
|
2084
|
-
uriGetter: baseUrl == null ? context
|
|
2085
|
-
const uri = context
|
|
2065
|
+
uriGetter: baseUrl == null ? context.getFollowersUri.bind(context) : (identifier) => {
|
|
2066
|
+
const uri = context.getFollowersUri(identifier);
|
|
2086
2067
|
uri.searchParams.set("base-url", baseUrl);
|
|
2087
2068
|
return uri;
|
|
2088
2069
|
},
|
|
2089
|
-
context
|
|
2070
|
+
context,
|
|
2090
2071
|
filter: baseUrl != null ? new URL(baseUrl) : void 0,
|
|
2091
|
-
filterPredicate: baseUrl != null ? (i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl) : void 0,
|
|
2072
|
+
filterPredicate: baseUrl != null ? ((i) => (i instanceof URL ? i.href : i.id?.href ?? "").startsWith(baseUrl)) : void 0,
|
|
2092
2073
|
collectionCallbacks: this.followersCallbacks,
|
|
2093
2074
|
tracerProvider: this.tracerProvider,
|
|
2094
2075
|
onUnauthorized,
|
|
@@ -2098,8 +2079,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2098
2079
|
case "liked": return await handleCollection(request, {
|
|
2099
2080
|
name: "liked",
|
|
2100
2081
|
identifier: route.values.identifier,
|
|
2101
|
-
uriGetter: context
|
|
2102
|
-
context
|
|
2082
|
+
uriGetter: context.getLikedUri.bind(context),
|
|
2083
|
+
context,
|
|
2103
2084
|
collectionCallbacks: this.likedCallbacks,
|
|
2104
2085
|
tracerProvider: this.tracerProvider,
|
|
2105
2086
|
onUnauthorized,
|
|
@@ -2108,8 +2089,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2108
2089
|
case "featured": return await handleCollection(request, {
|
|
2109
2090
|
name: "featured",
|
|
2110
2091
|
identifier: route.values.identifier,
|
|
2111
|
-
uriGetter: context
|
|
2112
|
-
context
|
|
2092
|
+
uriGetter: context.getFeaturedUri.bind(context),
|
|
2093
|
+
context,
|
|
2113
2094
|
collectionCallbacks: this.featuredCallbacks,
|
|
2114
2095
|
tracerProvider: this.tracerProvider,
|
|
2115
2096
|
onUnauthorized,
|
|
@@ -2118,8 +2099,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2118
2099
|
case "featuredTags": return await handleCollection(request, {
|
|
2119
2100
|
name: "featured tags",
|
|
2120
2101
|
identifier: route.values.identifier,
|
|
2121
|
-
uriGetter: context
|
|
2122
|
-
context
|
|
2102
|
+
uriGetter: context.getFeaturedTagsUri.bind(context),
|
|
2103
|
+
context,
|
|
2123
2104
|
collectionCallbacks: this.featuredTagsCallbacks,
|
|
2124
2105
|
tracerProvider: this.tracerProvider,
|
|
2125
2106
|
onUnauthorized,
|
|
@@ -2130,7 +2111,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2130
2111
|
const callbacks = this.collectionCallbacks[name];
|
|
2131
2112
|
return await handleCustomCollection(request, {
|
|
2132
2113
|
name,
|
|
2133
|
-
context
|
|
2114
|
+
context,
|
|
2134
2115
|
values: route.values,
|
|
2135
2116
|
collectionCallbacks: callbacks,
|
|
2136
2117
|
tracerProvider: this.tracerProvider,
|
|
@@ -2143,7 +2124,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2143
2124
|
const callbacks = this.collectionCallbacks[name];
|
|
2144
2125
|
return await handleOrderedCollection(request, {
|
|
2145
2126
|
name,
|
|
2146
|
-
context
|
|
2127
|
+
context,
|
|
2147
2128
|
values: route.values,
|
|
2148
2129
|
collectionCallbacks: callbacks,
|
|
2149
2130
|
tracerProvider: this.tracerProvider,
|
|
@@ -2234,9 +2215,9 @@ var ContextImpl = class ContextImpl {
|
|
|
2234
2215
|
}
|
|
2235
2216
|
getInboxUri(identifier) {
|
|
2236
2217
|
if (identifier == null) {
|
|
2237
|
-
const path
|
|
2238
|
-
if (path
|
|
2239
|
-
return new URL(path
|
|
2218
|
+
const path = this.federation.router.build("sharedInbox", {});
|
|
2219
|
+
if (path == null) throw new RouterError("No shared inbox path registered.");
|
|
2220
|
+
return new URL(path, this.canonicalOrigin);
|
|
2240
2221
|
}
|
|
2241
2222
|
const path = this.federation.router.build("inbox", { identifier });
|
|
2242
2223
|
if (path == null) throw new RouterError("No inbox path registered.");
|
|
@@ -2322,8 +2303,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2322
2303
|
type: "featuredTags",
|
|
2323
2304
|
identifier
|
|
2324
2305
|
};
|
|
2325
|
-
const
|
|
2326
|
-
const collectionRegex = /* @__PURE__ */ new RegExp(`^(${collectionTypes.join("|")}):(.*)$`);
|
|
2306
|
+
const collectionRegex = new RegExp(`^(${["collection", "orderedCollection"].join("|")}):(.*)$`);
|
|
2327
2307
|
const match = route.name.match(collectionRegex);
|
|
2328
2308
|
if (match !== null) {
|
|
2329
2309
|
const [, type, name] = match;
|
|
@@ -2339,12 +2319,12 @@ var ContextImpl = class ContextImpl {
|
|
|
2339
2319
|
return null;
|
|
2340
2320
|
}
|
|
2341
2321
|
async getActorKeyPairs(identifier) {
|
|
2342
|
-
const logger
|
|
2322
|
+
const logger = getLogger([
|
|
2343
2323
|
"fedify",
|
|
2344
2324
|
"federation",
|
|
2345
2325
|
"actor"
|
|
2346
2326
|
]);
|
|
2347
|
-
if (this.invokedFromActorKeyPairsDispatcher != null) logger
|
|
2327
|
+
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.", {
|
|
2348
2328
|
getActorKeyPairsIdentifier: identifier,
|
|
2349
2329
|
actorKeyPairsDispatcherIdentifier: this.invokedFromActorKeyPairsDispatcher.identifier
|
|
2350
2330
|
});
|
|
@@ -2352,7 +2332,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2352
2332
|
try {
|
|
2353
2333
|
keyPairs = await this.getKeyPairsFromIdentifier(identifier);
|
|
2354
2334
|
} catch (_) {
|
|
2355
|
-
logger
|
|
2335
|
+
logger.warn("No actor key pairs dispatcher registered.");
|
|
2356
2336
|
return [];
|
|
2357
2337
|
}
|
|
2358
2338
|
const owner = this.getActorUri(identifier);
|
|
@@ -2376,7 +2356,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2376
2356
|
return result;
|
|
2377
2357
|
}
|
|
2378
2358
|
async getKeyPairsFromIdentifier(identifier) {
|
|
2379
|
-
const logger
|
|
2359
|
+
const logger = getLogger([
|
|
2380
2360
|
"fedify",
|
|
2381
2361
|
"federation",
|
|
2382
2362
|
"actor"
|
|
@@ -2387,7 +2367,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2387
2367
|
actorUri = this.getActorUri(identifier);
|
|
2388
2368
|
} catch (error) {
|
|
2389
2369
|
if (error instanceof RouterError) {
|
|
2390
|
-
logger
|
|
2370
|
+
logger.warn(error.message);
|
|
2391
2371
|
return [];
|
|
2392
2372
|
}
|
|
2393
2373
|
throw error;
|
|
@@ -2396,7 +2376,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2396
2376
|
...this,
|
|
2397
2377
|
invokedFromActorKeyPairsDispatcher: { identifier }
|
|
2398
2378
|
}), identifier);
|
|
2399
|
-
if (keyPairs.length < 1) logger
|
|
2379
|
+
if (keyPairs.length < 1) logger.warn("No key pairs found for actor {identifier}.", { identifier });
|
|
2400
2380
|
let i = 0;
|
|
2401
2381
|
const result = [];
|
|
2402
2382
|
for (const keyPair of keyPairs) {
|
|
@@ -2435,8 +2415,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2435
2415
|
} else identifierPromise = Promise.resolve(identity.identifier);
|
|
2436
2416
|
return identifierPromise.then((identifier) => {
|
|
2437
2417
|
if (identifier == null) return this.documentLoader;
|
|
2438
|
-
|
|
2439
|
-
return keyPair.then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
2418
|
+
return this.getRsaKeyPairFromIdentifier(identifier).then((pair) => pair == null ? this.documentLoader : this.federation.authenticatedDocumentLoaderFactory(pair));
|
|
2440
2419
|
});
|
|
2441
2420
|
}
|
|
2442
2421
|
return this.federation.authenticatedDocumentLoaderFactory(identity);
|
|
@@ -2478,8 +2457,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2478
2457
|
});
|
|
2479
2458
|
}
|
|
2480
2459
|
sendActivity(sender, recipients, activity, options = {}) {
|
|
2481
|
-
|
|
2482
|
-
return tracer.startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
2460
|
+
return this.tracerProvider.getTracer(name, version).startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
2483
2461
|
kind: this.federation.outboxQueue == null || options.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
2484
2462
|
attributes: {
|
|
2485
2463
|
"activitypub.activity.type": getTypeId(activity).href,
|
|
@@ -2504,7 +2482,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2504
2482
|
});
|
|
2505
2483
|
}
|
|
2506
2484
|
async sendActivityInternal(sender, recipients, activity, options, span) {
|
|
2507
|
-
const logger
|
|
2485
|
+
const logger = getLogger([
|
|
2508
2486
|
"fedify",
|
|
2509
2487
|
"federation",
|
|
2510
2488
|
"outbox"
|
|
@@ -2554,7 +2532,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2554
2532
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
2555
2533
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
2556
2534
|
if (activity.actorId == null) {
|
|
2557
|
-
logger
|
|
2535
|
+
logger.error("Activity {activityId} to send does not have an actor.", {
|
|
2558
2536
|
activity,
|
|
2559
2537
|
activityId: activity?.id?.href
|
|
2560
2538
|
});
|
|
@@ -2565,7 +2543,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2565
2543
|
preferSharedInbox: options.preferSharedInbox,
|
|
2566
2544
|
excludeBaseUris: options.excludeBaseUris
|
|
2567
2545
|
});
|
|
2568
|
-
logger
|
|
2546
|
+
logger.debug("Sending activity {activityId} to inboxes:\n{inboxes}", {
|
|
2569
2547
|
inboxes: globalThis.Object.keys(inboxes),
|
|
2570
2548
|
activityId: activity.id?.href,
|
|
2571
2549
|
activity
|
|
@@ -2617,16 +2595,14 @@ var ContextImpl = class ContextImpl {
|
|
|
2617
2595
|
"outbox"
|
|
2618
2596
|
]).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 });
|
|
2619
2597
|
while (cursor != null) {
|
|
2620
|
-
const result
|
|
2621
|
-
if (result
|
|
2622
|
-
for (const recipient of result
|
|
2623
|
-
cursor = result
|
|
2598
|
+
const result = await this.federation.followersCallbacks.dispatcher(this, identifier, cursor);
|
|
2599
|
+
if (result == null) break;
|
|
2600
|
+
for (const recipient of result.items) yield recipient;
|
|
2601
|
+
cursor = result.nextCursor ?? null;
|
|
2624
2602
|
}
|
|
2625
2603
|
}
|
|
2626
2604
|
routeActivity(recipient, activity, options = {}) {
|
|
2627
|
-
|
|
2628
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
2629
|
-
return tracer.startActiveSpan("activitypub.inbox", {
|
|
2605
|
+
return (this.tracerProvider ?? this.tracerProvider).getTracer(name, version).startActiveSpan("activitypub.inbox", {
|
|
2630
2606
|
kind: this.federation.inboxQueue == null || options.immediate ? SpanKind.INTERNAL : SpanKind.PRODUCER,
|
|
2631
2607
|
attributes: { "activitypub.activity.type": getTypeId(activity).href }
|
|
2632
2608
|
}, async (span) => {
|
|
@@ -2654,7 +2630,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2654
2630
|
});
|
|
2655
2631
|
}
|
|
2656
2632
|
async routeActivityInternal(recipient, activity, options = {}, span) {
|
|
2657
|
-
const logger
|
|
2633
|
+
const logger = getLogger([
|
|
2658
2634
|
"fedify",
|
|
2659
2635
|
"federation",
|
|
2660
2636
|
"inbox"
|
|
@@ -2662,19 +2638,18 @@ var ContextImpl = class ContextImpl {
|
|
|
2662
2638
|
const contextLoader = options.contextLoader ?? this.contextLoader;
|
|
2663
2639
|
const json = await activity.toJsonLd({ contextLoader });
|
|
2664
2640
|
const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, this);
|
|
2665
|
-
|
|
2641
|
+
if (await verifyObject(Activity, json, {
|
|
2666
2642
|
contextLoader,
|
|
2667
2643
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
2668
2644
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
2669
2645
|
keyCache
|
|
2670
|
-
})
|
|
2671
|
-
|
|
2672
|
-
logger$2.debug("Object Integrity Proofs are not verified.", {
|
|
2646
|
+
}) == null) {
|
|
2647
|
+
logger.debug("Object Integrity Proofs are not verified.", {
|
|
2673
2648
|
recipient,
|
|
2674
2649
|
activity: json
|
|
2675
2650
|
});
|
|
2676
2651
|
if (activity.id == null) {
|
|
2677
|
-
logger
|
|
2652
|
+
logger.debug("Activity is missing an ID; unable to fetch.", {
|
|
2678
2653
|
recipient,
|
|
2679
2654
|
activity: json
|
|
2680
2655
|
});
|
|
@@ -2682,26 +2657,26 @@ var ContextImpl = class ContextImpl {
|
|
|
2682
2657
|
}
|
|
2683
2658
|
const fetched = await this.lookupObject(activity.id, options);
|
|
2684
2659
|
if (fetched == null) {
|
|
2685
|
-
logger
|
|
2660
|
+
logger.debug("Failed to fetch the remote activity object {activityId}.", {
|
|
2686
2661
|
recipient,
|
|
2687
2662
|
activity: json,
|
|
2688
2663
|
activityId: activity.id.href
|
|
2689
2664
|
});
|
|
2690
2665
|
return false;
|
|
2691
2666
|
} else if (!(fetched instanceof Activity)) {
|
|
2692
|
-
logger
|
|
2667
|
+
logger.debug("Fetched object is not an Activity.", {
|
|
2693
2668
|
recipient,
|
|
2694
2669
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
2695
2670
|
});
|
|
2696
2671
|
return false;
|
|
2697
2672
|
} else if (fetched.id?.href !== activity.id.href) {
|
|
2698
|
-
logger
|
|
2673
|
+
logger.debug("Fetched activity object has a different ID; failed to verify.", {
|
|
2699
2674
|
recipient,
|
|
2700
2675
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
2701
2676
|
});
|
|
2702
2677
|
return false;
|
|
2703
2678
|
} else if (fetched.actorIds.length < 1) {
|
|
2704
|
-
logger
|
|
2679
|
+
logger.debug("Fetched activity object is missing an actor; unable to verify.", {
|
|
2705
2680
|
recipient,
|
|
2706
2681
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
2707
2682
|
});
|
|
@@ -2709,15 +2684,15 @@ var ContextImpl = class ContextImpl {
|
|
|
2709
2684
|
}
|
|
2710
2685
|
const activityId = fetched.id;
|
|
2711
2686
|
if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
|
|
2712
|
-
logger
|
|
2687
|
+
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
2713
2688
|
recipient,
|
|
2714
2689
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
2715
2690
|
});
|
|
2716
2691
|
return false;
|
|
2717
2692
|
}
|
|
2718
|
-
logger
|
|
2693
|
+
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
2719
2694
|
activity = fetched;
|
|
2720
|
-
} else logger
|
|
2695
|
+
} else logger.debug("Object Integrity Proofs are verified.", {
|
|
2721
2696
|
recipient,
|
|
2722
2697
|
activity: json
|
|
2723
2698
|
});
|
|
@@ -2843,8 +2818,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
2843
2818
|
});
|
|
2844
2819
|
}
|
|
2845
2820
|
forwardActivity(forwarder, recipients, options) {
|
|
2846
|
-
|
|
2847
|
-
return tracer.startActiveSpan("activitypub.outbox", {
|
|
2821
|
+
return this.tracerProvider.getTracer(name, version).startActiveSpan("activitypub.outbox", {
|
|
2848
2822
|
kind: this.federation.outboxQueue == null || options?.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
2849
2823
|
attributes: { "activitypub.activity.type": this.activityType }
|
|
2850
2824
|
}, async (span) => {
|
|
@@ -2863,7 +2837,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
2863
2837
|
});
|
|
2864
2838
|
}
|
|
2865
2839
|
async forwardActivityInternal(forwarder, recipients, options) {
|
|
2866
|
-
const logger
|
|
2840
|
+
const logger = getLogger([
|
|
2867
2841
|
"fedify",
|
|
2868
2842
|
"federation",
|
|
2869
2843
|
"inbox"
|
|
@@ -2890,14 +2864,13 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
2890
2864
|
if (!hasSignature(this.activity)) {
|
|
2891
2865
|
let hasProof;
|
|
2892
2866
|
try {
|
|
2893
|
-
|
|
2894
|
-
hasProof = await activity.getProof() != null;
|
|
2867
|
+
hasProof = await (await Activity.fromJsonLd(this.activity, this)).getProof() != null;
|
|
2895
2868
|
} catch {
|
|
2896
2869
|
hasProof = false;
|
|
2897
2870
|
}
|
|
2898
2871
|
if (!hasProof) {
|
|
2899
2872
|
if (options?.skipIfUnsigned) return;
|
|
2900
|
-
logger
|
|
2873
|
+
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.");
|
|
2901
2874
|
}
|
|
2902
2875
|
}
|
|
2903
2876
|
if (recipients === "followers") {
|
|
@@ -2911,14 +2884,14 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
2911
2884
|
preferSharedInbox: options?.preferSharedInbox,
|
|
2912
2885
|
excludeBaseUris: options?.excludeBaseUris
|
|
2913
2886
|
});
|
|
2914
|
-
logger
|
|
2887
|
+
logger.debug("Forwarding activity {activityId} to inboxes:\n{inboxes}", {
|
|
2915
2888
|
inboxes: globalThis.Object.keys(inboxes),
|
|
2916
2889
|
activityId: this.activityId,
|
|
2917
2890
|
activity: this.activity
|
|
2918
2891
|
});
|
|
2919
2892
|
if (options?.immediate || this.federation.outboxQueue == null) {
|
|
2920
|
-
if (options?.immediate) logger
|
|
2921
|
-
else logger
|
|
2893
|
+
if (options?.immediate) logger.debug("Forwarding activity immediately without queue since immediate option is set.");
|
|
2894
|
+
else logger.debug("Forwarding activity immediately without queue since queue is not set.");
|
|
2922
2895
|
const promises = [];
|
|
2923
2896
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
2924
2897
|
keys,
|
|
@@ -2933,7 +2906,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
2933
2906
|
await Promise.all(promises);
|
|
2934
2907
|
return;
|
|
2935
2908
|
}
|
|
2936
|
-
logger
|
|
2909
|
+
logger.debug("Enqueuing activity {activityId} to forward later.", {
|
|
2937
2910
|
activityId: this.activityId,
|
|
2938
2911
|
activity: this.activity
|
|
2939
2912
|
});
|
|
@@ -2975,10 +2948,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
2975
2948
|
const { outboxQueue } = this.federation;
|
|
2976
2949
|
if (outboxQueue.enqueueMany == null) {
|
|
2977
2950
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
2978
|
-
const
|
|
2979
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2951
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2980
2952
|
if (errors.length > 0) {
|
|
2981
|
-
logger
|
|
2953
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
2982
2954
|
activityId: this.activityId,
|
|
2983
2955
|
errors
|
|
2984
2956
|
});
|
|
@@ -2987,10 +2959,9 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
2987
2959
|
}
|
|
2988
2960
|
} else if (orderingKey != null) {
|
|
2989
2961
|
const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
|
|
2990
|
-
const
|
|
2991
|
-
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2962
|
+
const errors = (await Promise.allSettled(promises)).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
2992
2963
|
if (errors.length > 0) {
|
|
2993
|
-
logger
|
|
2964
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
2994
2965
|
activityId: this.activityId,
|
|
2995
2966
|
errors
|
|
2996
2967
|
});
|
|
@@ -3000,7 +2971,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
3000
2971
|
} else try {
|
|
3001
2972
|
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
3002
2973
|
} catch (error) {
|
|
3003
|
-
logger
|
|
2974
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
|
|
3004
2975
|
activityId: this.activityId,
|
|
3005
2976
|
error
|
|
3006
2977
|
});
|
|
@@ -3055,10 +3026,7 @@ function unauthorized(_request) {
|
|
|
3055
3026
|
function getRequestId(request) {
|
|
3056
3027
|
const traceId = request.headers.get("X-Request-Id") || request.headers.get("X-Correlation-Id") || request.headers.get("Traceparent")?.split("-")[1];
|
|
3057
3028
|
if (traceId != null) return traceId;
|
|
3058
|
-
|
|
3059
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
3060
|
-
return `req_${timestamp}${random}`;
|
|
3029
|
+
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
3061
3030
|
}
|
|
3062
|
-
|
|
3063
3031
|
//#endregion
|
|
3064
|
-
export {
|
|
3032
|
+
export { autoIdAssigner as _, createFederation as a, handleCollection as c, handleObject as d, respondWithObject as f, actorDehydrator as g, handleNodeInfoJrd as h, KvSpecDeterminer as i, handleCustomCollection as l, handleNodeInfo as m, FederationImpl as n, handleWebFinger as o, respondWithObjectIfAcceptable as p, InboxContextImpl as r, handleActor as s, ContextImpl as t, handleInbox as u };
|