@fedify/fedify 1.9.9 → 1.9.11
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/{actor-DILKT_HU.cjs → actor-BaIbAIQ4.cjs} +187 -187
- package/dist/{actor-DVET8NhO.mjs → actor-BgNoo4Eo.mjs} +1 -1
- package/dist/{actor-MDInzRdc.js → actor-I6MTQt65.js} +187 -187
- package/dist/{authdocloader-hwjRHw8X.cjs → authdocloader-BML29LEF.cjs} +3 -3
- package/dist/{authdocloader-DLvikTbR.mjs → authdocloader-CQRL6xBg.mjs} +3 -3
- package/dist/{authdocloader-DRG9qnz7.js → authdocloader-DGVNFUsJ.js} +3 -3
- package/dist/{builder-DfInnU0K.mjs → builder-B8VNNUzm.mjs} +4 -4
- package/dist/{client-DuRbuCIQ.mjs → client-Cjo9kYUV.mjs} +1 -1
- package/dist/compat/mod.cjs +1 -1
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +3 -3
- package/dist/{context-Cf8s07xm.d.ts → context-CNkTuNIm.d.ts} +48 -6
- package/dist/{context-Crmwowsw.d.cts → context-jX79cwCB.d.cts} +48 -6
- package/dist/{docloader-BZfjD0Xt.cjs → docloader-CB5WT9yk.cjs} +12 -3
- package/dist/{docloader-ivt5xNwJ.js → docloader-XzYOPh6W.js} +12 -3
- package/dist/{esm-D0urVWqo.mjs → esm-Br6fmrGY.mjs} +1 -1
- package/dist/federation/builder.test.mjs +3 -3
- package/dist/federation/collection.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +1361 -45
- package/dist/federation/idempotency.test.mjs +5 -5
- package/dist/federation/inbox.test.mjs +3 -3
- package/dist/federation/keycache.test.mjs +3 -3
- package/dist/federation/kv.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +1586 -82
- package/dist/federation/mod.cjs +2 -2
- package/dist/federation/mod.d.cts +1 -1
- package/dist/federation/mod.d.ts +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/mq.test.mjs +3 -3
- package/dist/federation/retry.test.mjs +2 -2
- package/dist/federation/router.test.mjs +2 -2
- package/dist/federation/send.test.mjs +7 -7
- package/dist/federation/temporal.test.d.mts +2 -0
- package/dist/federation/temporal.test.mjs +71 -0
- package/dist/{http-Dbj7ZT3b.js → http-CXpt61mo.js} +3 -3
- package/dist/{http-CsSHezSz.mjs → http-GSUEBn2H.mjs} +2 -2
- package/dist/{http-8jvVkJos.cjs → http-L4148RPe.cjs} +3 -3
- package/dist/{inbox-D7U8Ysvc.mjs → inbox-DRfIo1Ox.mjs} +7 -4
- package/dist/{key-Bbuzt358.mjs → key-73aMUDcO.mjs} +2 -2
- package/dist/{key-Bg3Rr_bi.mjs → key-CqxBq3-S.mjs} +1 -1
- package/dist/{key-CUorXS6k.cjs → key-D3E68McA.cjs} +2 -2
- package/dist/{key-C2e_Yz1s.js → key-DtaAm2V1.js} +2 -2
- package/dist/{key-Bl8yte5W.cjs → key-Yfx6HgfZ.cjs} +1 -1
- package/dist/{keycache-Dpm1JlAw.mjs → keycache-tpX1dxwp.mjs} +1 -1
- package/dist/{keys-CZlvPl27.mjs → keys-B9pkL0lY.mjs} +1 -1
- package/dist/ld-DqEigU4F.mjs +548 -0
- package/dist/{lookup-BnvWOvmD.cjs → lookup-BK6z2RO5.cjs} +1 -1
- package/dist/{lookup-DhIULso8.mjs → lookup-DA92hMtK.mjs} +1 -1
- package/dist/{lookup-BOFQeNi_.js → lookup-DDOc-i0I.js} +1 -1
- package/dist/{middleware-BD8iV5GL.cjs → middleware-CcRfmHUw.cjs} +404 -78
- package/dist/{middleware-D0zludVl.js → middleware-D72Tt9sq.js} +401 -76
- package/dist/{middleware-BBjNkISH.mjs → middleware-DNRnMI46.mjs} +313 -80
- package/dist/{middleware-TO6qMFz0.cjs → middleware-DfCM9WFN.cjs} +1 -1
- package/dist/{middleware-DauQ1R8p.mjs → middleware-ufTj15Ba.mjs} +1 -1
- package/dist/mod.cjs +10 -10
- package/dist/mod.d.cts +1 -1
- package/dist/mod.d.ts +1 -1
- package/dist/mod.js +9 -9
- package/dist/nodeinfo/client.test.mjs +3 -3
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/nodeinfo/semver.test.mjs +1 -1
- package/dist/nodeinfo/types.test.mjs +1 -1
- package/dist/{owner-CAvCysNj.mjs → owner-C7rjJog4.mjs} +3 -3
- package/dist/{proof-2V3jxAdE.cjs → proof-BZb-g5fh.cjs} +347 -5
- package/dist/{proof-C99DO0SE.js → proof-CjgdsMq_.js} +300 -6
- package/dist/{proof-DkUAJViu.mjs → proof-GWFCtXCY.mjs} +2 -2
- package/dist/runtime/authdocloader.test.mjs +6 -6
- package/dist/runtime/docloader.test.mjs +3 -3
- package/dist/runtime/key.test.mjs +3 -3
- package/dist/runtime/langstr.test.mjs +2 -2
- package/dist/runtime/link.test.mjs +2 -2
- package/dist/runtime/mod.cjs +3 -3
- package/dist/runtime/mod.js +3 -3
- package/dist/runtime/multibase/multibase.test.mjs +2 -2
- package/dist/runtime/url.test.mjs +5 -2
- package/dist/{send-BxjL4pnG.mjs → send-B1cXA43r.mjs} +2 -2
- package/dist/sig/http.test.mjs +6 -6
- package/dist/sig/key.test.mjs +4 -4
- package/dist/sig/ld.test.mjs +561 -5
- package/dist/sig/mod.cjs +3 -3
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.mjs +5 -5
- package/dist/sig/proof.test.mjs +4 -4
- package/dist/temporal-DE-KwUkP.mjs +95 -0
- package/dist/testing/docloader.test.mjs +1 -1
- package/dist/testing/mod.d.mts +48 -6
- package/dist/testing/mod.mjs +1 -1
- package/dist/{testing-eYbMkj5P.mjs → testing-Brx3i-JJ.mjs} +2 -2
- package/dist/{transformers-DW7EyHh4.cjs → transformers-v2GoHgHn.cjs} +1 -1
- package/dist/{types-dHLDn_7H.js → types-CRRb96yX.js} +1 -1
- package/dist/{types-B0U2QC2Q.cjs → types-Ck12MwLI.cjs} +1 -1
- package/dist/vocab/actor.test.mjs +4 -4
- package/dist/vocab/cjs.test.mjs +1 -1
- package/dist/vocab/lookup.test.mjs +4 -4
- package/dist/vocab/mod.cjs +3 -3
- package/dist/vocab/mod.js +3 -3
- package/dist/vocab/type.test.mjs +2 -2
- package/dist/vocab/vocab.test.mjs +3 -3
- package/dist/{vocab-CG-IqKPs.mjs → vocab-D9ewcFHJ.mjs} +197 -188
- package/dist/webfinger/handler.test.mjs +3 -3
- package/dist/webfinger/lookup.test.mjs +3 -3
- package/dist/webfinger/mod.cjs +1 -1
- package/dist/webfinger/mod.js +1 -1
- package/dist/x/cfworkers.cjs +1 -1
- package/dist/x/cfworkers.test.mjs +1 -1
- package/dist/x/hono.cjs +1 -1
- package/dist/x/hono.d.cts +1 -1
- package/dist/x/hono.d.ts +1 -1
- package/dist/x/sveltekit.cjs +1 -1
- package/dist/x/sveltekit.d.cts +1 -1
- package/dist/x/sveltekit.d.ts +1 -1
- package/package.json +1 -1
- package/dist/ld-iU-MUtGB.mjs +0 -254
- /package/dist/{denokv-CoSB_Eps.mjs → denokv-NJPMXyK0.mjs} +0 -0
- /package/dist/{retry-Ddbq3AcK.mjs → retry-B_E3V_Dx.mjs} +0 -0
|
@@ -2,17 +2,18 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
import { t as __exportAll } from "./rolldown-runtime-C7fyD9f2.js";
|
|
4
4
|
import { r as getDefaultActivityTransformers } from "./transformers-BV4OeK9o.js";
|
|
5
|
-
import { d as name, f as version, i as getDocumentLoader, s as kvCache } from "./docloader-
|
|
6
|
-
import { G as Multikey, Tt as getTypeId, V as Link, X as OrderedCollectionPage, Y as OrderedCollection, _ as CollectionPage, g as Collection, q as Object$1, s as Activity, y as CryptographicKey } from "./actor-
|
|
7
|
-
import { t as lookupWebFinger } from "./lookup-
|
|
8
|
-
import { i as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-
|
|
9
|
-
import { r as verifyRequest, t as doubleKnock } from "./http-
|
|
10
|
-
import { a as doesActorOwnKey,
|
|
11
|
-
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-
|
|
12
|
-
import { t as getAuthenticatedDocumentLoader } from "./authdocloader-
|
|
5
|
+
import { d as name, f as version, i as getDocumentLoader, s as kvCache } from "./docloader-XzYOPh6W.js";
|
|
6
|
+
import { G as Multikey, Tt as getTypeId, V as Link, X as OrderedCollectionPage, Y as OrderedCollection, _ as CollectionPage, g as Collection, q as Object$1, s as Activity, y as CryptographicKey } from "./actor-I6MTQt65.js";
|
|
7
|
+
import { t as lookupWebFinger } from "./lookup-DDOc-i0I.js";
|
|
8
|
+
import { i as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-DtaAm2V1.js";
|
|
9
|
+
import { r as verifyRequest, t as doubleKnock } from "./http-CXpt61mo.js";
|
|
10
|
+
import { _ as signJsonLd, a as doesActorOwnKey, c as assertSafeJsonLd, f as detachSignature, g as isInvalidUrlTypeError, h as isClearlyMalformedContextReference, m as hasSignature, n as signObject, o as getKeyOwner, p as getNormalizationContextLoader, r as verifyObject, s as InvalidContextReferenceError, u as compactJsonLd, v as verifyCompactJsonLd, x as wrapContextLoaderForJsonLd } from "./proof-CjgdsMq_.js";
|
|
11
|
+
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-CRRb96yX.js";
|
|
12
|
+
import { t as getAuthenticatedDocumentLoader } from "./authdocloader-DGVNFUsJ.js";
|
|
13
13
|
import { lookupObject, traverseCollection } from "./vocab/mod.js";
|
|
14
14
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
15
15
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
16
|
+
import jsonld from "jsonld";
|
|
16
17
|
import { encodeHex } from "byte-encodings/hex";
|
|
17
18
|
import { cloneDeep } from "es-toolkit";
|
|
18
19
|
import { Router } from "uri-template-router";
|
|
@@ -54,7 +55,7 @@ var InboxListenerSet = class InboxListenerSet {
|
|
|
54
55
|
}
|
|
55
56
|
};
|
|
56
57
|
let warnedAboutDefaultIdempotency = false;
|
|
57
|
-
async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
|
|
58
|
+
async function routeActivity({ context: ctx, json, originalJson, normalizedActivity, ldSignatureVerified, activity, recipient, inboxListeners, inboxContextFactory, listenerInboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
|
|
58
59
|
const logger = getLogger([
|
|
59
60
|
"fedify",
|
|
60
61
|
"federation",
|
|
@@ -115,7 +116,9 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
115
116
|
type: "inbox",
|
|
116
117
|
id: crypto.randomUUID(),
|
|
117
118
|
baseUrl: ctx.origin,
|
|
118
|
-
activity: json,
|
|
119
|
+
activity: originalJson ?? json,
|
|
120
|
+
...normalizedActivity == null ? {} : { normalizedActivity },
|
|
121
|
+
...ldSignatureVerified == null ? {} : { ldSignatureVerified },
|
|
119
122
|
identifier: recipient,
|
|
120
123
|
attempt: 0,
|
|
121
124
|
started: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -159,7 +162,8 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
159
162
|
const { class: cls, listener } = dispatched;
|
|
160
163
|
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
161
164
|
try {
|
|
162
|
-
|
|
165
|
+
const contextFactory = listenerInboxContextFactory ?? inboxContextFactory;
|
|
166
|
+
await listener(contextFactory(recipient, contextFactory === inboxContextFactory ? json : originalJson ?? json, activity?.id?.href, getTypeId(activity).href), activity);
|
|
163
167
|
} catch (error) {
|
|
164
168
|
try {
|
|
165
169
|
await inboxErrorHandler?.(ctx, error);
|
|
@@ -999,7 +1003,123 @@ function preferredMediaTypes(accept) {
|
|
|
999
1003
|
return parseAccept(accept === void 0 ? "*/*" : accept ?? "").filter(isQuality).sort(compareSpecs).map(getFullType);
|
|
1000
1004
|
}
|
|
1001
1005
|
//#endregion
|
|
1006
|
+
//#region src/federation/temporal.ts
|
|
1007
|
+
function isPlainObject(value) {
|
|
1008
|
+
return typeof value === "object" && value != null && !Array.isArray(value);
|
|
1009
|
+
}
|
|
1010
|
+
function normalizeDateTimeLiteral(value) {
|
|
1011
|
+
return value.substring(19).match(/[Z+-]/) ? value : value + "Z";
|
|
1012
|
+
}
|
|
1013
|
+
function isMalformedDateTimeLiteral(value) {
|
|
1014
|
+
if (typeof value !== "string") return false;
|
|
1015
|
+
try {
|
|
1016
|
+
Temporal.Instant.from(normalizeDateTimeLiteral(value));
|
|
1017
|
+
return false;
|
|
1018
|
+
} catch {
|
|
1019
|
+
return true;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
function isMalformedDurationLiteral(value) {
|
|
1023
|
+
if (typeof value !== "string") return false;
|
|
1024
|
+
try {
|
|
1025
|
+
Temporal.Duration.from(value);
|
|
1026
|
+
return false;
|
|
1027
|
+
} catch {
|
|
1028
|
+
return true;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
const TEMPORAL_DATE_TIME_IRIS = new Set([
|
|
1032
|
+
"https://www.w3.org/ns/activitystreams#deleted",
|
|
1033
|
+
"https://www.w3.org/ns/activitystreams#endTime",
|
|
1034
|
+
"https://www.w3.org/ns/activitystreams#published",
|
|
1035
|
+
"https://www.w3.org/ns/activitystreams#startTime",
|
|
1036
|
+
"https://www.w3.org/ns/activitystreams#updated",
|
|
1037
|
+
"http://purl.org/dc/terms/created",
|
|
1038
|
+
"https://w3id.org/security#created"
|
|
1039
|
+
]);
|
|
1040
|
+
const TEMPORAL_DURATION_IRIS = new Set(["https://www.w3.org/ns/activitystreams#duration"]);
|
|
1041
|
+
const QUESTION_CLOSED_IRI = "https://www.w3.org/ns/activitystreams#closed";
|
|
1042
|
+
const XSD_DATE_TIME_IRI = "http://www.w3.org/2001/XMLSchema#dateTime";
|
|
1043
|
+
function hasMalformedExpandedDateTimeLiteral(value) {
|
|
1044
|
+
if (Array.isArray(value)) return value.some(hasMalformedExpandedDateTimeLiteral);
|
|
1045
|
+
return isPlainObject(value) && "@value" in value && isMalformedDateTimeLiteral(value["@value"]);
|
|
1046
|
+
}
|
|
1047
|
+
function hasMalformedExpandedQuestionClosedLiteral(value) {
|
|
1048
|
+
if (Array.isArray(value)) return value.some(hasMalformedExpandedQuestionClosedLiteral);
|
|
1049
|
+
if (!isPlainObject(value) || !("@value" in value)) return false;
|
|
1050
|
+
const literal = value["@value"];
|
|
1051
|
+
if (typeof literal === "boolean") return false;
|
|
1052
|
+
if (typeof literal !== "string") return false;
|
|
1053
|
+
if (value["@type"] !== XSD_DATE_TIME_IRI) return false;
|
|
1054
|
+
if (new Date(literal).toString() === "Invalid Date") return false;
|
|
1055
|
+
return isMalformedDateTimeLiteral(literal);
|
|
1056
|
+
}
|
|
1057
|
+
function hasMalformedExpandedDurationLiteral(value) {
|
|
1058
|
+
if (Array.isArray(value)) return value.some(hasMalformedExpandedDurationLiteral);
|
|
1059
|
+
return isPlainObject(value) && "@value" in value && isMalformedDurationLiteral(value["@value"]);
|
|
1060
|
+
}
|
|
1061
|
+
function hasMalformedKnownTemporalLiteralInternal(value, visited) {
|
|
1062
|
+
if (Array.isArray(value)) return value.some((item) => hasMalformedKnownTemporalLiteralInternal(item, visited));
|
|
1063
|
+
if (!isPlainObject(value)) return false;
|
|
1064
|
+
if (visited.has(value)) return false;
|
|
1065
|
+
visited.add(value);
|
|
1066
|
+
if ("@value" in value) return false;
|
|
1067
|
+
for (const [key, child] of Object.entries(value)) {
|
|
1068
|
+
if (TEMPORAL_DATE_TIME_IRIS.has(key)) {
|
|
1069
|
+
if (hasMalformedExpandedDateTimeLiteral(child)) return true;
|
|
1070
|
+
continue;
|
|
1071
|
+
}
|
|
1072
|
+
if (key === QUESTION_CLOSED_IRI) {
|
|
1073
|
+
if (hasMalformedExpandedQuestionClosedLiteral(child)) return true;
|
|
1074
|
+
continue;
|
|
1075
|
+
}
|
|
1076
|
+
if (TEMPORAL_DURATION_IRIS.has(key)) {
|
|
1077
|
+
if (hasMalformedExpandedDurationLiteral(child)) return true;
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
if (hasMalformedKnownTemporalLiteralInternal(child, visited)) return true;
|
|
1081
|
+
}
|
|
1082
|
+
return false;
|
|
1083
|
+
}
|
|
1084
|
+
async function hasMalformedKnownTemporalLiteral(value, contextLoader) {
|
|
1085
|
+
try {
|
|
1086
|
+
return hasMalformedKnownTemporalLiteralInternal(await jsonld.expand(value, {
|
|
1087
|
+
documentLoader: getNormalizationContextLoader(contextLoader),
|
|
1088
|
+
keepFreeFloatingNodes: true
|
|
1089
|
+
}), /* @__PURE__ */ new Set());
|
|
1090
|
+
} catch {
|
|
1091
|
+
return false;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
//#endregion
|
|
1002
1095
|
//#region src/federation/handler.ts
|
|
1096
|
+
const rawInboxContextFactorySymbol = Symbol("fedify.rawInboxContextFactory");
|
|
1097
|
+
function isRemoteContextLoadingFailure$1(error) {
|
|
1098
|
+
return error instanceof Error && typeof error.details === "object" && error.details != null && error.details.code === "loading remote context failed";
|
|
1099
|
+
}
|
|
1100
|
+
function isPermanentRemoteContextError$1(error) {
|
|
1101
|
+
if (!(error instanceof Error) || error.name !== "jsonld.InvalidUrl") return false;
|
|
1102
|
+
const details = error.details;
|
|
1103
|
+
if (details?.code === "invalid remote context") return true;
|
|
1104
|
+
return isRemoteContextLoadingFailure$1(error) && typeof details?.url === "string" && !URL.canParse(details.url) && isClearlyMalformedContextReference(details.url);
|
|
1105
|
+
}
|
|
1106
|
+
function isInvalidJsonLdError(error) {
|
|
1107
|
+
if (!(error instanceof Error)) return false;
|
|
1108
|
+
const name = error.name;
|
|
1109
|
+
return name === "UnsafeJsonLdError" || error instanceof InvalidContextReferenceError || isPermanentRemoteContextError$1(error) || name === "jsonld.SyntaxError" && !isRemoteContextLoadingFailure$1(error);
|
|
1110
|
+
}
|
|
1111
|
+
function isValidationTypeError(error) {
|
|
1112
|
+
return error instanceof TypeError && (/^(Invalid JSON-LD:|Invalid type:|Unexpected type:)/.test(error.message) || isInvalidUrlTypeError(error));
|
|
1113
|
+
}
|
|
1114
|
+
function isPermanentActivityParseError(error) {
|
|
1115
|
+
return isInvalidJsonLdError(error) || isValidationTypeError(error);
|
|
1116
|
+
}
|
|
1117
|
+
function hasHttpSignatureHeaders(request) {
|
|
1118
|
+
return request.headers.has("Signature") || request.headers.has("Signature-Input");
|
|
1119
|
+
}
|
|
1120
|
+
function hasObjectIntegrityProof(json) {
|
|
1121
|
+
return typeof json === "object" && json != null && "proof" in json;
|
|
1122
|
+
}
|
|
1003
1123
|
function acceptsJsonLd(request) {
|
|
1004
1124
|
const accept = request.headers.get("Accept");
|
|
1005
1125
|
const types = accept ? preferredMediaTypes(accept) : ["*/*"];
|
|
@@ -1383,35 +1503,120 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1383
1503
|
});
|
|
1384
1504
|
}
|
|
1385
1505
|
const keyCache = new KvKeyCache(kv, kvPrefixes.publicKey, ctx);
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1506
|
+
const jsonWithoutSig = detachSignature(json);
|
|
1507
|
+
const hasLdSignature = hasSignature(json);
|
|
1508
|
+
const canAttemptAlternateAuthAfterLdSignatureFailure = skipSignatureVerification || hasHttpSignatureHeaders(request) || hasObjectIntegrityProof(jsonWithoutSig);
|
|
1509
|
+
let deferredLdSignatureError = void 0;
|
|
1510
|
+
const respondInvalidActivity = async (error) => {
|
|
1511
|
+
logger.error("Failed to parse activity:\n{error}", {
|
|
1512
|
+
recipient,
|
|
1513
|
+
activity: json,
|
|
1514
|
+
error
|
|
1393
1515
|
});
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1516
|
+
try {
|
|
1517
|
+
await inboxErrorHandler?.(ctx, error);
|
|
1518
|
+
} catch (error) {
|
|
1519
|
+
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
1520
|
+
error,
|
|
1521
|
+
activity: json,
|
|
1522
|
+
recipient
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
span.setStatus({
|
|
1526
|
+
code: SpanStatusCode.ERROR,
|
|
1527
|
+
message: `Failed to parse activity:\n${error}`
|
|
1528
|
+
});
|
|
1529
|
+
return new Response("Invalid activity.", {
|
|
1530
|
+
status: 400,
|
|
1531
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1532
|
+
});
|
|
1533
|
+
};
|
|
1534
|
+
let compactedJson = json;
|
|
1535
|
+
let compactedJsonWithoutSig = jsonWithoutSig;
|
|
1536
|
+
let ldSigVerified = false;
|
|
1537
|
+
if (hasLdSignature) {
|
|
1538
|
+
try {
|
|
1539
|
+
compactedJson = await compactJsonLd(json, ctx.contextLoader);
|
|
1540
|
+
} catch (error) {
|
|
1541
|
+
if (isInvalidJsonLdError(error)) {
|
|
1542
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
1543
|
+
recipient,
|
|
1544
|
+
error
|
|
1545
|
+
});
|
|
1546
|
+
return new Response("Invalid JSON-LD.", {
|
|
1547
|
+
status: 400,
|
|
1548
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1549
|
+
});
|
|
1550
|
+
}
|
|
1551
|
+
if (!canAttemptAlternateAuthAfterLdSignatureFailure) throw error;
|
|
1552
|
+
if (!skipSignatureVerification) deferredLdSignatureError = error;
|
|
1553
|
+
logger.debug("Failed to normalize JSON-LD for Linked Data Signatures; deferring to another authentication path only if it verifies:\n{error}", {
|
|
1397
1554
|
recipient,
|
|
1398
1555
|
error
|
|
1399
1556
|
});
|
|
1400
|
-
return new Response("Invalid JSON-LD.", {
|
|
1401
|
-
status: 400,
|
|
1402
|
-
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1403
|
-
});
|
|
1404
1557
|
}
|
|
1405
|
-
|
|
1558
|
+
if (compactedJson !== json) {
|
|
1559
|
+
compactedJsonWithoutSig = detachSignature(compactedJson);
|
|
1560
|
+
try {
|
|
1561
|
+
ldSigVerified = await verifyCompactJsonLd(compactedJson, {
|
|
1562
|
+
contextLoader: ctx.contextLoader,
|
|
1563
|
+
documentLoader: ctx.documentLoader,
|
|
1564
|
+
keyCache,
|
|
1565
|
+
tracerProvider
|
|
1566
|
+
});
|
|
1567
|
+
} catch (error) {
|
|
1568
|
+
if (error instanceof RangeError && await hasMalformedKnownTemporalLiteral(compactedJsonWithoutSig, ctx.contextLoader)) return await respondInvalidActivity(error);
|
|
1569
|
+
if (isInvalidJsonLdError(error)) {
|
|
1570
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
1571
|
+
recipient,
|
|
1572
|
+
error
|
|
1573
|
+
});
|
|
1574
|
+
return new Response("Invalid JSON-LD.", {
|
|
1575
|
+
status: 400,
|
|
1576
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
if (!canAttemptAlternateAuthAfterLdSignatureFailure) throw error;
|
|
1580
|
+
if (!skipSignatureVerification) try {
|
|
1581
|
+
await Object$1.fromJsonLd(compactedJson, {
|
|
1582
|
+
contextLoader: getNormalizationContextLoader(ctx.contextLoader),
|
|
1583
|
+
documentLoader: ctx.documentLoader,
|
|
1584
|
+
tracerProvider
|
|
1585
|
+
});
|
|
1586
|
+
} catch (parseError) {
|
|
1587
|
+
if (parseError instanceof RangeError && await hasMalformedKnownTemporalLiteral(compactedJsonWithoutSig, ctx.contextLoader)) return await respondInvalidActivity(parseError);
|
|
1588
|
+
if (isInvalidJsonLdError(parseError)) {
|
|
1589
|
+
logger.error("Failed to parse JSON-LD:\n{error}", {
|
|
1590
|
+
recipient,
|
|
1591
|
+
error: parseError
|
|
1592
|
+
});
|
|
1593
|
+
return new Response("Invalid JSON-LD.", {
|
|
1594
|
+
status: 400,
|
|
1595
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
deferredLdSignatureError = parseError;
|
|
1599
|
+
}
|
|
1600
|
+
ldSigVerified = false;
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1406
1603
|
}
|
|
1407
|
-
const jsonWithoutSig = detachSignature(json);
|
|
1408
1604
|
let activity = null;
|
|
1409
1605
|
if (ldSigVerified) {
|
|
1410
1606
|
logger.debug("Linked Data Signatures are verified.", {
|
|
1411
1607
|
recipient,
|
|
1412
1608
|
json
|
|
1413
1609
|
});
|
|
1414
|
-
|
|
1610
|
+
try {
|
|
1611
|
+
activity = await Activity.fromJsonLd(compactedJsonWithoutSig, {
|
|
1612
|
+
...ctx,
|
|
1613
|
+
contextLoader: getNormalizationContextLoader(ctx.contextLoader)
|
|
1614
|
+
});
|
|
1615
|
+
} catch (error) {
|
|
1616
|
+
if (error instanceof RangeError && await hasMalformedKnownTemporalLiteral(compactedJsonWithoutSig, ctx.contextLoader)) return await respondInvalidActivity(error);
|
|
1617
|
+
if (!isPermanentActivityParseError(error)) throw error;
|
|
1618
|
+
return await respondInvalidActivity(error);
|
|
1619
|
+
}
|
|
1415
1620
|
} else {
|
|
1416
1621
|
logger.debug("Linked Data Signatures are not verified.", {
|
|
1417
1622
|
recipient,
|
|
@@ -1419,12 +1624,21 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1419
1624
|
});
|
|
1420
1625
|
try {
|
|
1421
1626
|
activity = await verifyObject(Activity, jsonWithoutSig, {
|
|
1422
|
-
contextLoader: ctx.contextLoader,
|
|
1627
|
+
contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader),
|
|
1423
1628
|
documentLoader: ctx.documentLoader,
|
|
1424
1629
|
keyCache,
|
|
1425
1630
|
tracerProvider
|
|
1426
1631
|
});
|
|
1427
1632
|
} catch (error) {
|
|
1633
|
+
if (error instanceof RangeError && await hasMalformedKnownTemporalLiteral(jsonWithoutSig, ctx.contextLoader)) return await respondInvalidActivity(error);
|
|
1634
|
+
if (deferredLdSignatureError != null) {
|
|
1635
|
+
logger.debug("Object Integrity Proof fallback did not supersede a deferred Linked Data Signature failure:\n{error}", {
|
|
1636
|
+
recipient,
|
|
1637
|
+
error
|
|
1638
|
+
});
|
|
1639
|
+
activity = null;
|
|
1640
|
+
}
|
|
1641
|
+
if (!isPermanentActivityParseError(error)) throw error;
|
|
1428
1642
|
logger.error("Failed to parse activity:\n{error}", {
|
|
1429
1643
|
recipient,
|
|
1430
1644
|
activity: json,
|
|
@@ -1468,6 +1682,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1468
1682
|
tracerProvider
|
|
1469
1683
|
});
|
|
1470
1684
|
if (key == null) {
|
|
1685
|
+
if (deferredLdSignatureError != null) throw deferredLdSignatureError;
|
|
1471
1686
|
logger.error("Failed to verify the request's HTTP Signatures.", { recipient });
|
|
1472
1687
|
span.setStatus({
|
|
1473
1688
|
code: SpanStatusCode.ERROR,
|
|
@@ -1480,11 +1695,20 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1480
1695
|
} else logger.debug("HTTP Signatures are verified.", { recipient });
|
|
1481
1696
|
httpSigKey = key;
|
|
1482
1697
|
}
|
|
1483
|
-
|
|
1698
|
+
try {
|
|
1699
|
+
activity = await Activity.fromJsonLd(jsonWithoutSig, {
|
|
1700
|
+
...ctx,
|
|
1701
|
+
contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader)
|
|
1702
|
+
});
|
|
1703
|
+
} catch (error) {
|
|
1704
|
+
if (!isPermanentActivityParseError(error)) throw error;
|
|
1705
|
+
return await respondInvalidActivity(error);
|
|
1706
|
+
}
|
|
1484
1707
|
}
|
|
1485
1708
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
1486
1709
|
span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
|
|
1487
1710
|
if (httpSigKey != null && !await doesActorOwnKey(activity, httpSigKey, ctx)) {
|
|
1711
|
+
if (deferredLdSignatureError != null) throw deferredLdSignatureError;
|
|
1488
1712
|
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
|
1489
1713
|
activity: json,
|
|
1490
1714
|
recipient,
|
|
@@ -1503,10 +1727,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1503
1727
|
const routeResult = await routeActivity({
|
|
1504
1728
|
context: ctx,
|
|
1505
1729
|
json,
|
|
1730
|
+
originalJson: json,
|
|
1731
|
+
normalizedActivity: hasLdSignature && compactedJson !== json ? compactedJson : void 0,
|
|
1732
|
+
ldSignatureVerified: hasLdSignature ? ldSigVerified : void 0,
|
|
1506
1733
|
activity,
|
|
1507
1734
|
recipient,
|
|
1508
1735
|
inboxListeners,
|
|
1509
1736
|
inboxContextFactory,
|
|
1737
|
+
listenerInboxContextFactory: ldSigVerified ? inboxContextFactory[rawInboxContextFactorySymbol] : void 0,
|
|
1510
1738
|
inboxErrorHandler,
|
|
1511
1739
|
kv,
|
|
1512
1740
|
kvPrefixes,
|
|
@@ -2325,6 +2553,18 @@ var middleware_exports = /* @__PURE__ */ __exportAll({
|
|
|
2325
2553
|
KvSpecDeterminer: () => KvSpecDeterminer,
|
|
2326
2554
|
createFederation: () => createFederation
|
|
2327
2555
|
});
|
|
2556
|
+
function isRemoteContextLoadingFailure(error) {
|
|
2557
|
+
return error instanceof Error && typeof error.details === "object" && error.details != null && error.details.code === "loading remote context failed";
|
|
2558
|
+
}
|
|
2559
|
+
function isPermanentRemoteContextError(error) {
|
|
2560
|
+
if (!(error instanceof Error) || error.name !== "jsonld.InvalidUrl") return false;
|
|
2561
|
+
const details = error.details;
|
|
2562
|
+
if (details?.code === "invalid remote context") return true;
|
|
2563
|
+
return isRemoteContextLoadingFailure(error) && typeof details?.url === "string" && !URL.canParse(details.url) && isClearlyMalformedContextReference(details.url);
|
|
2564
|
+
}
|
|
2565
|
+
function isPermanentInboxParseError(error) {
|
|
2566
|
+
return error instanceof Error && (error.name === "UnsafeJsonLdError" || error instanceof InvalidContextReferenceError || isPermanentRemoteContextError(error) || error.name === "jsonld.SyntaxError" && !isRemoteContextLoadingFailure(error)) || error instanceof TypeError && (/^(Invalid JSON-LD:|Invalid type:|Unexpected type:)/.test(error.message) || isInvalidUrlTypeError(error));
|
|
2567
|
+
}
|
|
2328
2568
|
/**
|
|
2329
2569
|
* Create a new {@link Federation} instance.
|
|
2330
2570
|
* @param parameters Parameters for initializing the instance.
|
|
@@ -2656,7 +2896,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2656
2896
|
}
|
|
2657
2897
|
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
2658
2898
|
}
|
|
2659
|
-
async #listenInboxMessage(ctxData, message,
|
|
2899
|
+
async #listenInboxMessage(ctxData, message, _span) {
|
|
2660
2900
|
const logger = getLogger([
|
|
2661
2901
|
"fedify",
|
|
2662
2902
|
"federation",
|
|
@@ -2669,60 +2909,28 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2669
2909
|
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
2670
2910
|
if (identity != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity || "handle" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
2671
2911
|
}
|
|
2672
|
-
const activity = await Activity.fromJsonLd(message.activity, context);
|
|
2673
|
-
span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
|
|
2674
|
-
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2675
|
-
const cacheKey = activity.id == null ? null : [
|
|
2676
|
-
...this.kvPrefixes.activityIdempotence,
|
|
2677
|
-
context.origin,
|
|
2678
|
-
activity.id.href
|
|
2679
|
-
];
|
|
2680
|
-
if (cacheKey != null) {
|
|
2681
|
-
if (await this.kv.get(cacheKey) === true) {
|
|
2682
|
-
logger.debug("Activity {activityId} has already been processed.", {
|
|
2683
|
-
activityId: activity.id?.href,
|
|
2684
|
-
activity: message.activity,
|
|
2685
|
-
recipient: message.identifier
|
|
2686
|
-
});
|
|
2687
|
-
return;
|
|
2688
|
-
}
|
|
2689
|
-
}
|
|
2690
2912
|
await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
activityId: activity.id?.href,
|
|
2695
|
-
activity: message.activity,
|
|
2696
|
-
recipient: message.identifier,
|
|
2697
|
-
trial: message.attempt
|
|
2698
|
-
});
|
|
2699
|
-
span.setStatus({
|
|
2700
|
-
code: SpanStatusCode.ERROR,
|
|
2701
|
-
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
2702
|
-
});
|
|
2703
|
-
span.end();
|
|
2704
|
-
return;
|
|
2705
|
-
}
|
|
2706
|
-
const { class: cls, listener } = dispatched;
|
|
2707
|
-
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
2708
|
-
try {
|
|
2709
|
-
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, getTypeId(activity).href), activity);
|
|
2710
|
-
} catch (error) {
|
|
2913
|
+
let activity = null;
|
|
2914
|
+
let cacheKey = null;
|
|
2915
|
+
const reportInboxError = async (error) => {
|
|
2711
2916
|
try {
|
|
2712
2917
|
await this.inboxErrorHandler?.(context, error);
|
|
2713
2918
|
} catch (error) {
|
|
2714
2919
|
logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
|
|
2715
2920
|
error,
|
|
2716
2921
|
trial: message.attempt,
|
|
2717
|
-
activityId: activity
|
|
2922
|
+
activityId: activity?.id?.href,
|
|
2718
2923
|
activity: message.activity,
|
|
2719
2924
|
recipient: message.identifier
|
|
2720
2925
|
});
|
|
2721
2926
|
}
|
|
2927
|
+
};
|
|
2928
|
+
const handleRetriableFailure = async (error) => {
|
|
2929
|
+
await reportInboxError(error);
|
|
2722
2930
|
if (this.inboxQueue?.nativeRetrial) {
|
|
2723
2931
|
logger.error("Failed to process the incoming activity {activityId}; backend will handle retry:\n{error}", {
|
|
2724
2932
|
error,
|
|
2725
|
-
activityId: activity
|
|
2933
|
+
activityId: activity?.id?.href,
|
|
2726
2934
|
activity: message.activity,
|
|
2727
2935
|
recipient: message.identifier
|
|
2728
2936
|
});
|
|
@@ -2741,17 +2949,25 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2741
2949
|
logger.error("Failed to process the incoming activity {activityId} (attempt #{attempt}); retry...:\n{error}", {
|
|
2742
2950
|
error,
|
|
2743
2951
|
attempt: message.attempt,
|
|
2744
|
-
activityId: activity
|
|
2952
|
+
activityId: activity?.id?.href,
|
|
2745
2953
|
activity: message.activity,
|
|
2746
2954
|
recipient: message.identifier
|
|
2747
2955
|
});
|
|
2956
|
+
if (this.inboxQueue == null) {
|
|
2957
|
+
span.setStatus({
|
|
2958
|
+
code: SpanStatusCode.ERROR,
|
|
2959
|
+
message: String(error)
|
|
2960
|
+
});
|
|
2961
|
+
span.end();
|
|
2962
|
+
throw error;
|
|
2963
|
+
}
|
|
2748
2964
|
await this.inboxQueue?.enqueue({
|
|
2749
2965
|
...message,
|
|
2750
2966
|
attempt: message.attempt + 1
|
|
2751
2967
|
}, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
2752
2968
|
} else logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
2753
2969
|
error,
|
|
2754
|
-
activityId: activity
|
|
2970
|
+
activityId: activity?.id?.href,
|
|
2755
2971
|
activity: message.activity,
|
|
2756
2972
|
recipient: message.identifier
|
|
2757
2973
|
});
|
|
@@ -2760,11 +2976,108 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2760
2976
|
message: String(error)
|
|
2761
2977
|
});
|
|
2762
2978
|
span.end();
|
|
2979
|
+
};
|
|
2980
|
+
let dispatched;
|
|
2981
|
+
let parseInput = void 0;
|
|
2982
|
+
let parseContextLoader = context.contextLoader;
|
|
2983
|
+
try {
|
|
2984
|
+
const hasSignatureField = hasSignature(message.activity);
|
|
2985
|
+
const shouldParseFromNormalizedSignedPayload = message.ldSignatureVerified === true || message.normalizedActivity != null || message.ldSignatureVerified == null && hasSignatureField;
|
|
2986
|
+
const parseContext = hasSignatureField ? {
|
|
2987
|
+
...context,
|
|
2988
|
+
contextLoader: getNormalizationContextLoader(context.contextLoader)
|
|
2989
|
+
} : {
|
|
2990
|
+
...context,
|
|
2991
|
+
contextLoader: wrapContextLoaderForJsonLd(context.contextLoader)
|
|
2992
|
+
};
|
|
2993
|
+
parseContextLoader = parseContext.contextLoader;
|
|
2994
|
+
let normalizedActivity;
|
|
2995
|
+
if (shouldParseFromNormalizedSignedPayload) {
|
|
2996
|
+
normalizedActivity = message.normalizedActivity ?? await compactJsonLd(message.activity, context.contextLoader);
|
|
2997
|
+
assertSafeJsonLd(normalizedActivity);
|
|
2998
|
+
}
|
|
2999
|
+
parseInput = shouldParseFromNormalizedSignedPayload ? detachSignature(normalizedActivity) : hasSignatureField ? detachSignature(message.activity) : message.activity;
|
|
3000
|
+
activity = await Activity.fromJsonLd(parseInput, parseContext);
|
|
3001
|
+
span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
|
|
3002
|
+
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
3003
|
+
cacheKey = activity.id == null ? null : [
|
|
3004
|
+
...this.kvPrefixes.activityIdempotence,
|
|
3005
|
+
context.origin,
|
|
3006
|
+
activity.id.href
|
|
3007
|
+
];
|
|
3008
|
+
if (cacheKey != null) {
|
|
3009
|
+
if (await this.kv.get(cacheKey) === true) {
|
|
3010
|
+
logger.debug("Activity {activityId} has already been processed.", {
|
|
3011
|
+
activityId: activity.id?.href,
|
|
3012
|
+
activity: message.activity,
|
|
3013
|
+
recipient: message.identifier
|
|
3014
|
+
});
|
|
3015
|
+
span.end();
|
|
3016
|
+
return;
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
dispatched = this.inboxListeners?.dispatchWithClass(activity);
|
|
3020
|
+
} catch (error) {
|
|
3021
|
+
if (activity == null && error instanceof RangeError && await hasMalformedKnownTemporalLiteral(parseInput, parseContextLoader)) {
|
|
3022
|
+
await reportInboxError(error);
|
|
3023
|
+
logger.error("Failed to parse the queued incoming activity {activityId}:\n{error}", {
|
|
3024
|
+
error,
|
|
3025
|
+
trial: message.attempt,
|
|
3026
|
+
activityId: null,
|
|
3027
|
+
activity: message.activity,
|
|
3028
|
+
recipient: message.identifier
|
|
3029
|
+
});
|
|
3030
|
+
span.setStatus({
|
|
3031
|
+
code: SpanStatusCode.ERROR,
|
|
3032
|
+
message: String(error)
|
|
3033
|
+
});
|
|
3034
|
+
span.end();
|
|
3035
|
+
return;
|
|
3036
|
+
}
|
|
3037
|
+
if (isPermanentInboxParseError(error)) {
|
|
3038
|
+
await reportInboxError(error);
|
|
3039
|
+
logger.error("Failed to parse the queued incoming activity {activityId}:\n{error}", {
|
|
3040
|
+
error,
|
|
3041
|
+
trial: message.attempt,
|
|
3042
|
+
activityId: activity?.id?.href,
|
|
3043
|
+
activity: message.activity,
|
|
3044
|
+
recipient: message.identifier
|
|
3045
|
+
});
|
|
3046
|
+
span.setStatus({
|
|
3047
|
+
code: SpanStatusCode.ERROR,
|
|
3048
|
+
message: String(error)
|
|
3049
|
+
});
|
|
3050
|
+
span.end();
|
|
3051
|
+
return;
|
|
3052
|
+
}
|
|
3053
|
+
await handleRetriableFailure(error);
|
|
3054
|
+
return;
|
|
3055
|
+
}
|
|
3056
|
+
if (dispatched == null) {
|
|
3057
|
+
logger.error("Unsupported activity type:\n{activity}", {
|
|
3058
|
+
activityId: activity.id?.href,
|
|
3059
|
+
activity: message.activity,
|
|
3060
|
+
recipient: message.identifier,
|
|
3061
|
+
trial: message.attempt
|
|
3062
|
+
});
|
|
3063
|
+
span.setStatus({
|
|
3064
|
+
code: SpanStatusCode.ERROR,
|
|
3065
|
+
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
3066
|
+
});
|
|
3067
|
+
span.end();
|
|
3068
|
+
return;
|
|
3069
|
+
}
|
|
3070
|
+
const { class: cls, listener } = dispatched;
|
|
3071
|
+
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
3072
|
+
try {
|
|
3073
|
+
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, getTypeId(activity).href), activity);
|
|
3074
|
+
} catch (error) {
|
|
3075
|
+
await handleRetriableFailure(error);
|
|
2763
3076
|
return;
|
|
2764
3077
|
}
|
|
2765
3078
|
if (cacheKey != null) await this.kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
2766
3079
|
logger.info("Activity {activityId} has been processed.", {
|
|
2767
|
-
activityId: activity
|
|
3080
|
+
activityId: activity?.id?.href,
|
|
2768
3081
|
activity: message.activity,
|
|
2769
3082
|
recipient: message.identifier
|
|
2770
3083
|
});
|
|
@@ -3086,16 +3399,18 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3086
3399
|
onNotAcceptable
|
|
3087
3400
|
});
|
|
3088
3401
|
context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier: route.values.identifier ?? route.values.handle }) });
|
|
3089
|
-
case "sharedInbox":
|
|
3402
|
+
case "sharedInbox": {
|
|
3090
3403
|
if (routeName !== "inbox" && this.sharedInboxKeyDispatcher != null) {
|
|
3091
3404
|
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
3092
3405
|
if (identity != null) context = this.#createContext(request, contextData, { documentLoader: "identifier" in identity || "username" in identity || "handle" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
3093
3406
|
}
|
|
3094
3407
|
if (!this.manuallyStartQueue) this._startQueueInternal(contextData);
|
|
3408
|
+
const inboxContextFactory = context.toInboxContext.bind(context);
|
|
3409
|
+
inboxContextFactory[rawInboxContextFactorySymbol] = context.toInboxContext.bind(context);
|
|
3095
3410
|
return await handleInbox(request, {
|
|
3096
3411
|
recipient: route.values.identifier ?? route.values.handle ?? null,
|
|
3097
3412
|
context,
|
|
3098
|
-
inboxContextFactory
|
|
3413
|
+
inboxContextFactory,
|
|
3099
3414
|
kv: this.kv,
|
|
3100
3415
|
kvPrefixes: this.kvPrefixes,
|
|
3101
3416
|
queue: this.inboxQueue,
|
|
@@ -3108,6 +3423,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3108
3423
|
tracerProvider: this.tracerProvider,
|
|
3109
3424
|
idempotencyStrategy: this.idempotencyStrategy
|
|
3110
3425
|
});
|
|
3426
|
+
}
|
|
3111
3427
|
case "following": return await handleCollection(request, {
|
|
3112
3428
|
name: "following",
|
|
3113
3429
|
identifier: route.values.identifier ?? route.values.handle,
|
|
@@ -3858,6 +4174,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3858
4174
|
const routeResult = await routeActivity({
|
|
3859
4175
|
context: this,
|
|
3860
4176
|
json,
|
|
4177
|
+
ldSignatureVerified: false,
|
|
3861
4178
|
activity,
|
|
3862
4179
|
recipient,
|
|
3863
4180
|
inboxListeners: this.federation.inboxListeners,
|
|
@@ -3956,6 +4273,14 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
|
|
|
3956
4273
|
};
|
|
3957
4274
|
var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
3958
4275
|
recipient;
|
|
4276
|
+
/**
|
|
4277
|
+
* The original received activity payload.
|
|
4278
|
+
*
|
|
4279
|
+
* Fedify may normalize a Linked Data Signature payload internally for safe
|
|
4280
|
+
* parsing, but forwarding must keep the sender's payload unchanged so
|
|
4281
|
+
* third-party signatures/proofs remain intact.
|
|
4282
|
+
* @internal
|
|
4283
|
+
*/
|
|
3959
4284
|
activity;
|
|
3960
4285
|
activityId;
|
|
3961
4286
|
activityType;
|