@fedify/fedify 2.3.12 → 2.3.14
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_rejects-DN60FHPX.mjs → assert_rejects-D1HYAik3.mjs} +2 -20
- package/dist/{assert_throws-BOkhLGYc.mjs → assert_throws-BbSMEFKo.mjs} +19 -1
- package/dist/{builder-B6ixdT3y.mjs → builder-C6yXExXl.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +2 -2
- package/dist/{deno-D4dcoVfF.mjs → deno-y3L4Oa94.mjs} +1 -1
- package/dist/{docloader-NOKfswJV.mjs → docloader-yuyzZC9a.mjs} +6 -2
- package/dist/federation/builder.test.mjs +3 -3
- package/dist/federation/circuit-breaker.test.mjs +3 -3
- package/dist/federation/collection.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +262 -9
- package/dist/federation/idempotency.test.mjs +3 -3
- package/dist/federation/inbox.test.mjs +25 -1
- package/dist/federation/keycache.test.mjs +19 -8
- package/dist/federation/kv.test.mjs +1 -1
- package/dist/federation/metrics.test.mjs +3 -3
- package/dist/federation/middleware.test.mjs +177 -15
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/mq.test.mjs +4 -3
- package/dist/federation/negotiation.test.mjs +4 -4
- package/dist/federation/retry.test.mjs +1 -1
- package/dist/federation/router.test.mjs +3 -4
- package/dist/federation/send.test.mjs +7 -6
- package/dist/federation/temporal.test.mjs +4 -4
- package/dist/federation/webfinger.test.mjs +2 -2
- package/dist/{http-HjidyDfF.mjs → http-BCSf1KIY.mjs} +3 -3
- package/dist/{http-D_Xrr6kp.cjs → http-D77Wjrcg.cjs} +17 -3
- package/dist/{http-DkyUBs_T.js → http-DNM9KyIO.js} +17 -3
- package/dist/inbox-NObX26c9.mjs +180 -0
- package/dist/{key-Dg-NXm4K.mjs → key-APURZ0ky.mjs} +18 -4
- package/dist/{keycache-Dkc_sflV.mjs → keycache-BimEQucx.mjs} +1 -1
- package/dist/{kv-cache-BwnC6JGt.cjs → kv-cache-Bg4utAuv.cjs} +5 -1
- package/dist/{kv-cache-BpVwvcSI.mjs → kv-cache-C69dzgQi.mjs} +1 -1
- package/dist/{kv-cache-BhGeZk_o.js → kv-cache-LBCwHNLu.js} +5 -1
- package/dist/{ld-C1wveXXf.mjs → ld-BoLqbDaL.mjs} +3 -3
- package/dist/{metrics-cIaMxG0v.mjs → metrics-DBSl8wEr.mjs} +1 -1
- package/dist/{middleware-DhOFTXmo.cjs → middleware-BQUQ0pPl.cjs} +107 -35
- package/dist/{middleware-CnrzVu9i.js → middleware-CRd1JmuL.js} +107 -35
- package/dist/{middleware-I-XlrRVl.mjs → middleware-CZ8tI1qL.mjs} +97 -195
- package/dist/{middleware-VxPpU0h_.mjs → middleware-DAqo2eOY.mjs} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/client.test.mjs +2 -2
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/nodeinfo/types.test.mjs +2 -2
- package/dist/otel/exporter.test.mjs +1 -1
- package/dist/{owner-CFKfE85G.mjs → owner-DjKvngeb.mjs} +2 -2
- package/dist/{proof-DBxu6g2K.cjs → proof-CWTnYhjS.cjs} +1 -1
- package/dist/{proof-DtpGEj0u.mjs → proof-D2oFOdNA.mjs} +3 -3
- package/dist/{proof-HU__qtUD.js → proof-s9sy44kx.js} +1 -1
- package/dist/{send-CwMea5r6.mjs → send-xDK5UnL-.mjs} +3 -3
- package/dist/sig/http.test.mjs +7 -7
- package/dist/sig/key.test.mjs +200 -6
- package/dist/sig/ld.test.mjs +50 -5
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +49 -4
- package/dist/sig/proof.test.mjs +56 -4
- package/dist/{std__assert-BvGuO4xO.mjs → std__assert-BjJn2daJ.mjs} +2 -2
- package/dist/{temporal-ClSXyHyu.mjs → temporal-C6icc5n9.mjs} +1 -1
- package/dist/utils/docloader.test.mjs +178 -39
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +6 -6
- /package/dist/{assert-jSdZMYam.mjs → assert-CEO06XCw.mjs} +0 -0
- /package/dist/{circuit-breaker-test-utils-Dm5MM6l9.mjs → circuit-breaker-test-utils-CAdwjgMi.mjs} +0 -0
- /package/dist/{negotiation-CDW-_gUU.mjs → negotiation-DDstyBvc.mjs} +0 -0
- /package/dist/{retry-_VvV0h9f.mjs → retry-CXg_MBI-.mjs} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-
|
|
4
|
+
import { n as version, t as name } from "./deno-y3L4Oa94.mjs";
|
|
5
|
+
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-DBSl8wEr.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -148,16 +148,23 @@ async function importJwk(jwk, type) {
|
|
|
148
148
|
/**
|
|
149
149
|
* Fetches the document that the given actor URI dereferences to, and returns
|
|
150
150
|
* the actor only if the host that served the document is authoritative for
|
|
151
|
-
* the id the document claims.
|
|
151
|
+
* the id the document claims, and that id is the actor that was asked for.
|
|
152
152
|
*
|
|
153
153
|
* Only the origin that serves an actor id can speak for it. Without that
|
|
154
154
|
* rule any host could serve a document describing somebody else's actor—and
|
|
155
155
|
* listing its own keys as that actor's.
|
|
156
156
|
*
|
|
157
|
+
* The returned actor always has exactly the requested `actorId` as its `id`.
|
|
158
|
+
* A document loader follows redirects and alternate document links, so the
|
|
159
|
+
* document an actor id leads to may describe a different actor altogether,
|
|
160
|
+
* on the same origin or on another; accepting it would attribute that other
|
|
161
|
+
* actor's keys to the requested one. See GHSA-8863-8468-7hq7.
|
|
162
|
+
*
|
|
157
163
|
* @param actorId The URI of the actor to fetch.
|
|
158
164
|
* @param options Options for fetching the document.
|
|
159
165
|
* @returns The actor, or `null` if the document cannot be fetched, is not an
|
|
160
|
-
* actor,
|
|
166
|
+
* actor, belongs to another origin, or describes an actor other
|
|
167
|
+
* than the requested one.
|
|
161
168
|
* @internal
|
|
162
169
|
*/
|
|
163
170
|
async function fetchActorDocument(actorId, options = {}) {
|
|
@@ -212,6 +219,13 @@ async function fetchActorDocumentInternal(actorId, options, propagateContextFetc
|
|
|
212
219
|
});
|
|
213
220
|
return null;
|
|
214
221
|
}
|
|
222
|
+
if (object.id.href !== actorId.href) {
|
|
223
|
+
logger.debug("The document fetched for the actor {actorId} is the actor {documentActorId} instead; refusing to treat it as the requested actor's document.", {
|
|
224
|
+
actorId: actorId.href,
|
|
225
|
+
documentActorId: object.id.href
|
|
226
|
+
});
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
215
229
|
return object;
|
|
216
230
|
}
|
|
217
231
|
/**
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { CryptographicKey, Multikey } from "@fedify/vocab";
|
|
5
5
|
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
6
6
|
//#region src/federation/keycache.ts
|
|
7
|
-
const KEY_CACHE_GENERATION = "
|
|
7
|
+
const KEY_CACHE_GENERATION = "3";
|
|
8
8
|
var KvKeyCache = class {
|
|
9
9
|
kv;
|
|
10
10
|
prefix;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
require("./chunk-DDcVe30Y.cjs");
|
|
4
|
-
const require_http = require("./http-
|
|
4
|
+
const require_http = require("./http-D77Wjrcg.cjs");
|
|
5
5
|
let _logtape_logtape = require("@logtape/logtape");
|
|
6
6
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
7
7
|
let es_toolkit = require("es-toolkit");
|
|
@@ -58,6 +58,10 @@ function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedi
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
async function validateUrl(url) {
|
|
61
|
+
const parsedUrl = new URL(url);
|
|
62
|
+
const protocol = parsedUrl.protocol;
|
|
63
|
+
if (protocol !== "http:" && protocol !== "https:") throw new _fedify_vocab_runtime.UrlError(`Unsupported protocol: ${protocol}`);
|
|
64
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new _fedify_vocab_runtime.UrlError("URLs with credentials are not allowed");
|
|
61
65
|
if (!allowPrivateAddress) try {
|
|
62
66
|
await (0, _fedify_vocab_runtime.validatePublicUrl)(url);
|
|
63
67
|
} catch (error) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { p as recordDocumentCache } from "./metrics-
|
|
4
|
+
import { p as recordDocumentCache } from "./metrics-DBSl8wEr.mjs";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
import { preloadedContexts } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/utils/kv-cache.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { T as recordDocumentCache, f as validateCryptoKey, t as doubleKnock } from "./http-
|
|
3
|
+
import { T as recordDocumentCache, f as validateCryptoKey, t as doubleKnock } from "./http-DNM9KyIO.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import { FetchError, UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
6
6
|
import { curry } from "es-toolkit";
|
|
@@ -57,6 +57,10 @@ function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedi
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
async function validateUrl(url) {
|
|
60
|
+
const parsedUrl = new URL(url);
|
|
61
|
+
const protocol = parsedUrl.protocol;
|
|
62
|
+
if (protocol !== "http:" && protocol !== "https:") throw new UrlError(`Unsupported protocol: ${protocol}`);
|
|
63
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new UrlError("URLs with credentials are not allowed");
|
|
60
64
|
if (!allowPrivateAddress) try {
|
|
61
65
|
await validatePublicUrl(url);
|
|
62
66
|
} catch (error) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
-
import { r as fetchKey, s as validateCryptoKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-y3L4Oa94.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-DBSl8wEr.mjs";
|
|
6
|
+
import { r as fetchKey, s as validateCryptoKey } from "./key-APURZ0ky.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
9
9
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-y3L4Oa94.mjs";
|
|
5
5
|
import { metrics } from "@opentelemetry/api";
|
|
6
6
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/federation/metrics.ts
|
|
@@ -2,10 +2,10 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
const require_chunk = require("./chunk-DDcVe30Y.cjs");
|
|
4
4
|
const require_transformers = require("./transformers-NeAONrAq.cjs");
|
|
5
|
-
const require_http = require("./http-
|
|
5
|
+
const require_http = require("./http-D77Wjrcg.cjs");
|
|
6
6
|
const require_types = require("./types-DRPjmHVV.cjs");
|
|
7
|
-
const require_proof = require("./proof-
|
|
8
|
-
const require_kv_cache = require("./kv-cache-
|
|
7
|
+
const require_proof = require("./proof-CWTnYhjS.cjs");
|
|
8
|
+
const require_kv_cache = require("./kv-cache-Bg4utAuv.cjs");
|
|
9
9
|
let _logtape_logtape = require("@logtape/logtape");
|
|
10
10
|
let _fedify_uri_template = require("@fedify/uri-template");
|
|
11
11
|
let _fedify_vocab = require("@fedify/vocab");
|
|
@@ -1264,12 +1264,34 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
|
|
|
1264
1264
|
}
|
|
1265
1265
|
//#endregion
|
|
1266
1266
|
//#region src/federation/inbox.ts
|
|
1267
|
+
/**
|
|
1268
|
+
* Checks whether an activity's ID and all of its actor IDs have the same
|
|
1269
|
+
* non-opaque origin. Activities without an ID have no origin to authenticate.
|
|
1270
|
+
*
|
|
1271
|
+
* The caller is responsible for rejecting a missing primary actor ID before
|
|
1272
|
+
* relying on this check.
|
|
1273
|
+
* @internal
|
|
1274
|
+
*/
|
|
1275
|
+
function actorsHaveSameOrigin(activity) {
|
|
1276
|
+
if (activity.id == null) return true;
|
|
1277
|
+
const origin = activity.id.origin;
|
|
1278
|
+
return origin !== "null" && activity.actorIds.every((actor) => actor.origin === origin);
|
|
1279
|
+
}
|
|
1267
1280
|
async function routeActivity({ context: ctx, json, originalJson, normalizedActivity, ldSignatureVerified, activity, recipient, inboxListeners, inboxContextFactory, listenerInboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, meterProvider, tracerProvider, idempotencyStrategy }) {
|
|
1268
1281
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
1269
1282
|
"fedify",
|
|
1270
1283
|
"federation",
|
|
1271
1284
|
"inbox"
|
|
1272
1285
|
]);
|
|
1286
|
+
if (activity.actorId == null) {
|
|
1287
|
+
logger.error("Missing actor.", { activity: json });
|
|
1288
|
+
span.setStatus({
|
|
1289
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1290
|
+
message: "Missing actor."
|
|
1291
|
+
});
|
|
1292
|
+
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
1293
|
+
return "missingActor";
|
|
1294
|
+
}
|
|
1273
1295
|
let cacheKey = null;
|
|
1274
1296
|
if (activity.id != null) {
|
|
1275
1297
|
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, (0, _fedify_vocab.getTypeId)(activity).href);
|
|
@@ -1305,15 +1327,6 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
|
|
|
1305
1327
|
return "alreadyProcessed";
|
|
1306
1328
|
}
|
|
1307
1329
|
}
|
|
1308
|
-
if (activity.actorId == null) {
|
|
1309
|
-
logger.error("Missing actor.", { activity: json });
|
|
1310
|
-
span.setStatus({
|
|
1311
|
-
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1312
|
-
message: "Missing actor."
|
|
1313
|
-
});
|
|
1314
|
-
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
1315
|
-
return "missingActor";
|
|
1316
|
-
}
|
|
1317
1330
|
span.setAttribute("activitypub.actor.id", activity.actorId.href);
|
|
1318
1331
|
if (queue != null) {
|
|
1319
1332
|
const carrier = {};
|
|
@@ -1422,7 +1435,7 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
|
|
|
1422
1435
|
}
|
|
1423
1436
|
//#endregion
|
|
1424
1437
|
//#region src/federation/keycache.ts
|
|
1425
|
-
const KEY_CACHE_GENERATION = "
|
|
1438
|
+
const KEY_CACHE_GENERATION = "3";
|
|
1426
1439
|
var KvKeyCache = class {
|
|
1427
1440
|
kv;
|
|
1428
1441
|
prefix;
|
|
@@ -1848,13 +1861,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
|
|
|
1848
1861
|
* @param parameters The parameters for handling the collection.
|
|
1849
1862
|
* @returns A promise that resolves to an HTTP response.
|
|
1850
1863
|
*/
|
|
1851
|
-
async function handleCollection(request, { name: name$
|
|
1852
|
-
const spanName = name$
|
|
1864
|
+
async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
|
|
1865
|
+
const spanName = name$1.trim().replace(/\s+/g, "_");
|
|
1853
1866
|
tracerProvider = tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
1854
1867
|
const tracer = tracerProvider.getTracer(require_http.name, require_http.version);
|
|
1855
1868
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1856
1869
|
const metricBase = {
|
|
1857
|
-
kind: getCollectionMetricKind(name$
|
|
1870
|
+
kind: getCollectionMetricKind(name$1),
|
|
1858
1871
|
page: cursor != null,
|
|
1859
1872
|
dispatcher: "built_in"
|
|
1860
1873
|
};
|
|
@@ -1895,7 +1908,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
1895
1908
|
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1896
1909
|
return await onNotFound(request);
|
|
1897
1910
|
}
|
|
1898
|
-
const items = filterCollectionItems(page.items, name$
|
|
1911
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
1899
1912
|
itemCount = items.length;
|
|
1900
1913
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
1901
1914
|
return items;
|
|
@@ -1935,7 +1948,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
1935
1948
|
} else {
|
|
1936
1949
|
const uri = new URL(baseUri);
|
|
1937
1950
|
uri.searchParams.set("cursor", cursor);
|
|
1938
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$
|
|
1951
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
|
|
1939
1952
|
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
1940
1953
|
attributes: {
|
|
1941
1954
|
"activitypub.collection.id": uri.href,
|
|
@@ -1951,7 +1964,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
1951
1964
|
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1952
1965
|
return await onNotFound(request);
|
|
1953
1966
|
}
|
|
1954
|
-
const items = filterCollectionItems(page.items, name$
|
|
1967
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
1955
1968
|
itemCount = items.length;
|
|
1956
1969
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
1957
1970
|
return {
|
|
@@ -2660,6 +2673,36 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2660
2673
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
2661
2674
|
}
|
|
2662
2675
|
}
|
|
2676
|
+
if (activity.actorId == null) {
|
|
2677
|
+
logger.error("Missing actor.", {
|
|
2678
|
+
activity: json,
|
|
2679
|
+
recipient
|
|
2680
|
+
});
|
|
2681
|
+
span.setStatus({
|
|
2682
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2683
|
+
message: "Missing actor."
|
|
2684
|
+
});
|
|
2685
|
+
return new Response("Missing actor.", {
|
|
2686
|
+
status: 400,
|
|
2687
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2688
|
+
});
|
|
2689
|
+
}
|
|
2690
|
+
if (!skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
2691
|
+
logger.error("The activity ({activityId}) and its actors do not have the same origin.", {
|
|
2692
|
+
activity: json,
|
|
2693
|
+
recipient,
|
|
2694
|
+
activityId: activity.id.href,
|
|
2695
|
+
actorIds: activity.actorIds.map((actor) => actor.href)
|
|
2696
|
+
});
|
|
2697
|
+
span.setStatus({
|
|
2698
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2699
|
+
message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
|
|
2700
|
+
});
|
|
2701
|
+
return new Response("The activity and its actors do not have the same origin.", {
|
|
2702
|
+
status: 401,
|
|
2703
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2704
|
+
});
|
|
2705
|
+
}
|
|
2663
2706
|
const routeResult = await routeActivity({
|
|
2664
2707
|
context: ctx,
|
|
2665
2708
|
json,
|
|
@@ -2827,8 +2870,8 @@ var CustomCollectionHandler = class {
|
|
|
2827
2870
|
* @param CollectionPage The CollectionPage constructor.
|
|
2828
2871
|
* @param filterPredicate Optional filter predicate for items.
|
|
2829
2872
|
*/
|
|
2830
|
-
constructor(name$
|
|
2831
|
-
this.name = name$
|
|
2873
|
+
constructor(name$2, values, context, callbacks, tracerProvider = _opentelemetry_api.trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
|
|
2874
|
+
this.name = name$2;
|
|
2832
2875
|
this.values = values;
|
|
2833
2876
|
this.context = context;
|
|
2834
2877
|
this.callbacks = callbacks;
|
|
@@ -5061,6 +5104,35 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
5061
5104
|
span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
5062
5105
|
listenerSpan.setAttribute("activitypub.activity.id", activity.id.href);
|
|
5063
5106
|
}
|
|
5107
|
+
if (activity.actorId == null) {
|
|
5108
|
+
logger.error("Missing actor in queued incoming activity.", {
|
|
5109
|
+
activityId: activity.id?.href,
|
|
5110
|
+
activity: message.activity,
|
|
5111
|
+
recipient: message.identifier
|
|
5112
|
+
});
|
|
5113
|
+
listenerSpan.setStatus({
|
|
5114
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
5115
|
+
message: "Missing actor."
|
|
5116
|
+
});
|
|
5117
|
+
require_http.recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
5118
|
+
listenerSpan.end();
|
|
5119
|
+
return;
|
|
5120
|
+
}
|
|
5121
|
+
if (!this.skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
5122
|
+
logger.error("The queued activity ({activityId}) and its actors do not have the same origin.", {
|
|
5123
|
+
activityId: activity.id.href,
|
|
5124
|
+
actorIds: activity.actorIds.map((actor) => actor.href),
|
|
5125
|
+
activity: message.activity,
|
|
5126
|
+
recipient: message.identifier
|
|
5127
|
+
});
|
|
5128
|
+
listenerSpan.setStatus({
|
|
5129
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
5130
|
+
message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
|
|
5131
|
+
});
|
|
5132
|
+
require_http.recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
5133
|
+
listenerSpan.end();
|
|
5134
|
+
return;
|
|
5135
|
+
}
|
|
5064
5136
|
cacheKey = activity.id == null ? null : [
|
|
5065
5137
|
...this.kvPrefixes.activityIdempotence,
|
|
5066
5138
|
context.origin,
|
|
@@ -6323,20 +6395,6 @@ var ContextImpl = class ContextImpl {
|
|
|
6323
6395
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
6324
6396
|
});
|
|
6325
6397
|
return false;
|
|
6326
|
-
} else if (fetched.actorIds.length < 1) {
|
|
6327
|
-
logger.debug("Fetched activity object is missing an actor; unable to verify.", {
|
|
6328
|
-
recipient,
|
|
6329
|
-
activity: await fetched.toJsonLd({ contextLoader })
|
|
6330
|
-
});
|
|
6331
|
-
return false;
|
|
6332
|
-
}
|
|
6333
|
-
const activityId = fetched.id;
|
|
6334
|
-
if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
|
|
6335
|
-
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
6336
|
-
recipient,
|
|
6337
|
-
activity: await fetched.toJsonLd({ contextLoader })
|
|
6338
|
-
});
|
|
6339
|
-
return false;
|
|
6340
6398
|
}
|
|
6341
6399
|
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
6342
6400
|
activity = fetched;
|
|
@@ -6345,6 +6403,20 @@ var ContextImpl = class ContextImpl {
|
|
|
6345
6403
|
recipient,
|
|
6346
6404
|
activity: json
|
|
6347
6405
|
});
|
|
6406
|
+
if (activity.actorId == null) {
|
|
6407
|
+
logger.debug("Activity is missing an actor; unable to verify.", {
|
|
6408
|
+
recipient,
|
|
6409
|
+
activity: json
|
|
6410
|
+
});
|
|
6411
|
+
return false;
|
|
6412
|
+
}
|
|
6413
|
+
if (activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
6414
|
+
logger.debug("Activity has actors from different origins; unable to verify.", {
|
|
6415
|
+
recipient,
|
|
6416
|
+
activity: json
|
|
6417
|
+
});
|
|
6418
|
+
return false;
|
|
6419
|
+
}
|
|
6348
6420
|
const routeResult = await routeActivity({
|
|
6349
6421
|
context: this,
|
|
6350
6422
|
json,
|
|
@@ -2,10 +2,10 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
import { t as __exportAll } from "./chunk-CRNNMoPX.js";
|
|
4
4
|
import { r as getDefaultActivityTransformers } from "./transformers-BGMIq1cs.js";
|
|
5
|
-
import { A as recordWebFingerHandle, C as recordCollectionRequest, D as recordInboxActivity, E as recordFanoutRecipients, I as name, L as version, M as formatAcceptSignature, O as recordOutboxActivity, S as recordCollectionPageItems, _ as instrumentDocumentLoader, a as verifyRequestDetailed, b as recordCircuitBreakerStateChange, d as importJwk, f as validateCryptoKey, g as getRemoteHost, h as getFederationMetrics, i as verifyRequest, j as registerQueueDepthGauge, k as recordOutboxEnqueue, m as getDurationMs, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, v as isAbortError, w as recordCollectionTotalItems, x as recordCollectionDispatchDuration } from "./http-
|
|
5
|
+
import { A as recordWebFingerHandle, C as recordCollectionRequest, D as recordInboxActivity, E as recordFanoutRecipients, I as name, L as version, M as formatAcceptSignature, O as recordOutboxActivity, S as recordCollectionPageItems, _ as instrumentDocumentLoader, a as verifyRequestDetailed, b as recordCircuitBreakerStateChange, d as importJwk, f as validateCryptoKey, g as getRemoteHost, h as getFederationMetrics, i as verifyRequest, j as registerQueueDepthGauge, k as recordOutboxEnqueue, m as getDurationMs, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, v as isAbortError, w as recordCollectionTotalItems, x as recordCollectionDispatchDuration } from "./http-DNM9KyIO.js";
|
|
6
6
|
import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-miAYfiGO.js";
|
|
7
|
-
import { _ as hasSignatureLike, b as signJsonLd, c as getKeyOwner, f as compactJsonLd, g as hasSignature, h as getNormalizationContextLoader, i as verifyObject, l as InvalidContextReferenceError, m as detachSignature, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, r as signObject, s as doesActorOwnKey, u as assertSafeJsonLd, v as isClearlyMalformedContextReference, w as wrapContextLoaderForJsonLd, x as verifyCompactJsonLd, y as isInvalidUrlTypeError } from "./proof-
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
7
|
+
import { _ as hasSignatureLike, b as signJsonLd, c as getKeyOwner, f as compactJsonLd, g as hasSignature, h as getNormalizationContextLoader, i as verifyObject, l as InvalidContextReferenceError, m as detachSignature, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, r as signObject, s as doesActorOwnKey, u as assertSafeJsonLd, v as isClearlyMalformedContextReference, w as wrapContextLoaderForJsonLd, x as verifyCompactJsonLd, y as isInvalidUrlTypeError } from "./proof-s9sy44kx.js";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-LBCwHNLu.js";
|
|
9
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
10
10
|
import { Router, RouterError, assertPath } from "@fedify/uri-template";
|
|
11
11
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
@@ -1263,12 +1263,34 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
|
|
|
1263
1263
|
}
|
|
1264
1264
|
//#endregion
|
|
1265
1265
|
//#region src/federation/inbox.ts
|
|
1266
|
+
/**
|
|
1267
|
+
* Checks whether an activity's ID and all of its actor IDs have the same
|
|
1268
|
+
* non-opaque origin. Activities without an ID have no origin to authenticate.
|
|
1269
|
+
*
|
|
1270
|
+
* The caller is responsible for rejecting a missing primary actor ID before
|
|
1271
|
+
* relying on this check.
|
|
1272
|
+
* @internal
|
|
1273
|
+
*/
|
|
1274
|
+
function actorsHaveSameOrigin(activity) {
|
|
1275
|
+
if (activity.id == null) return true;
|
|
1276
|
+
const origin = activity.id.origin;
|
|
1277
|
+
return origin !== "null" && activity.actorIds.every((actor) => actor.origin === origin);
|
|
1278
|
+
}
|
|
1266
1279
|
async function routeActivity({ context: ctx, json, originalJson, normalizedActivity, ldSignatureVerified, activity, recipient, inboxListeners, inboxContextFactory, listenerInboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, meterProvider, tracerProvider, idempotencyStrategy }) {
|
|
1267
1280
|
const logger = getLogger([
|
|
1268
1281
|
"fedify",
|
|
1269
1282
|
"federation",
|
|
1270
1283
|
"inbox"
|
|
1271
1284
|
]);
|
|
1285
|
+
if (activity.actorId == null) {
|
|
1286
|
+
logger.error("Missing actor.", { activity: json });
|
|
1287
|
+
span.setStatus({
|
|
1288
|
+
code: SpanStatusCode.ERROR,
|
|
1289
|
+
message: "Missing actor."
|
|
1290
|
+
});
|
|
1291
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
1292
|
+
return "missingActor";
|
|
1293
|
+
}
|
|
1272
1294
|
let cacheKey = null;
|
|
1273
1295
|
if (activity.id != null) {
|
|
1274
1296
|
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
|
|
@@ -1304,15 +1326,6 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
|
|
|
1304
1326
|
return "alreadyProcessed";
|
|
1305
1327
|
}
|
|
1306
1328
|
}
|
|
1307
|
-
if (activity.actorId == null) {
|
|
1308
|
-
logger.error("Missing actor.", { activity: json });
|
|
1309
|
-
span.setStatus({
|
|
1310
|
-
code: SpanStatusCode.ERROR,
|
|
1311
|
-
message: "Missing actor."
|
|
1312
|
-
});
|
|
1313
|
-
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
1314
|
-
return "missingActor";
|
|
1315
|
-
}
|
|
1316
1329
|
span.setAttribute("activitypub.actor.id", activity.actorId.href);
|
|
1317
1330
|
if (queue != null) {
|
|
1318
1331
|
const carrier = {};
|
|
@@ -1421,7 +1434,7 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
|
|
|
1421
1434
|
}
|
|
1422
1435
|
//#endregion
|
|
1423
1436
|
//#region src/federation/keycache.ts
|
|
1424
|
-
const KEY_CACHE_GENERATION = "
|
|
1437
|
+
const KEY_CACHE_GENERATION = "3";
|
|
1425
1438
|
var KvKeyCache = class {
|
|
1426
1439
|
kv;
|
|
1427
1440
|
prefix;
|
|
@@ -1847,13 +1860,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
|
|
|
1847
1860
|
* @param parameters The parameters for handling the collection.
|
|
1848
1861
|
* @returns A promise that resolves to an HTTP response.
|
|
1849
1862
|
*/
|
|
1850
|
-
async function handleCollection(request, { name: name$
|
|
1851
|
-
const spanName = name$
|
|
1863
|
+
async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
|
|
1864
|
+
const spanName = name$1.trim().replace(/\s+/g, "_");
|
|
1852
1865
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
1853
1866
|
const tracer = tracerProvider.getTracer(name, version);
|
|
1854
1867
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1855
1868
|
const metricBase = {
|
|
1856
|
-
kind: getCollectionMetricKind(name$
|
|
1869
|
+
kind: getCollectionMetricKind(name$1),
|
|
1857
1870
|
page: cursor != null,
|
|
1858
1871
|
dispatcher: "built_in"
|
|
1859
1872
|
};
|
|
@@ -1894,7 +1907,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
1894
1907
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1895
1908
|
return await onNotFound(request);
|
|
1896
1909
|
}
|
|
1897
|
-
const items = filterCollectionItems(page.items, name$
|
|
1910
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
1898
1911
|
itemCount = items.length;
|
|
1899
1912
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
1900
1913
|
return items;
|
|
@@ -1934,7 +1947,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
1934
1947
|
} else {
|
|
1935
1948
|
const uri = new URL(baseUri);
|
|
1936
1949
|
uri.searchParams.set("cursor", cursor);
|
|
1937
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$
|
|
1950
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
|
|
1938
1951
|
kind: SpanKind.SERVER,
|
|
1939
1952
|
attributes: {
|
|
1940
1953
|
"activitypub.collection.id": uri.href,
|
|
@@ -1950,7 +1963,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
1950
1963
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1951
1964
|
return await onNotFound(request);
|
|
1952
1965
|
}
|
|
1953
|
-
const items = filterCollectionItems(page.items, name$
|
|
1966
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
1954
1967
|
itemCount = items.length;
|
|
1955
1968
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
1956
1969
|
return {
|
|
@@ -2659,6 +2672,36 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2659
2672
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
2660
2673
|
}
|
|
2661
2674
|
}
|
|
2675
|
+
if (activity.actorId == null) {
|
|
2676
|
+
logger.error("Missing actor.", {
|
|
2677
|
+
activity: json,
|
|
2678
|
+
recipient
|
|
2679
|
+
});
|
|
2680
|
+
span.setStatus({
|
|
2681
|
+
code: SpanStatusCode.ERROR,
|
|
2682
|
+
message: "Missing actor."
|
|
2683
|
+
});
|
|
2684
|
+
return new Response("Missing actor.", {
|
|
2685
|
+
status: 400,
|
|
2686
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2687
|
+
});
|
|
2688
|
+
}
|
|
2689
|
+
if (!skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
2690
|
+
logger.error("The activity ({activityId}) and its actors do not have the same origin.", {
|
|
2691
|
+
activity: json,
|
|
2692
|
+
recipient,
|
|
2693
|
+
activityId: activity.id.href,
|
|
2694
|
+
actorIds: activity.actorIds.map((actor) => actor.href)
|
|
2695
|
+
});
|
|
2696
|
+
span.setStatus({
|
|
2697
|
+
code: SpanStatusCode.ERROR,
|
|
2698
|
+
message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
|
|
2699
|
+
});
|
|
2700
|
+
return new Response("The activity and its actors do not have the same origin.", {
|
|
2701
|
+
status: 401,
|
|
2702
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2662
2705
|
const routeResult = await routeActivity({
|
|
2663
2706
|
context: ctx,
|
|
2664
2707
|
json,
|
|
@@ -2826,8 +2869,8 @@ var CustomCollectionHandler = class {
|
|
|
2826
2869
|
* @param CollectionPage The CollectionPage constructor.
|
|
2827
2870
|
* @param filterPredicate Optional filter predicate for items.
|
|
2828
2871
|
*/
|
|
2829
|
-
constructor(name$
|
|
2830
|
-
this.name = name$
|
|
2872
|
+
constructor(name$2, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
|
|
2873
|
+
this.name = name$2;
|
|
2831
2874
|
this.values = values;
|
|
2832
2875
|
this.context = context;
|
|
2833
2876
|
this.callbacks = callbacks;
|
|
@@ -5060,6 +5103,35 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
5060
5103
|
span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
5061
5104
|
listenerSpan.setAttribute("activitypub.activity.id", activity.id.href);
|
|
5062
5105
|
}
|
|
5106
|
+
if (activity.actorId == null) {
|
|
5107
|
+
logger.error("Missing actor in queued incoming activity.", {
|
|
5108
|
+
activityId: activity.id?.href,
|
|
5109
|
+
activity: message.activity,
|
|
5110
|
+
recipient: message.identifier
|
|
5111
|
+
});
|
|
5112
|
+
listenerSpan.setStatus({
|
|
5113
|
+
code: SpanStatusCode.ERROR,
|
|
5114
|
+
message: "Missing actor."
|
|
5115
|
+
});
|
|
5116
|
+
recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
5117
|
+
listenerSpan.end();
|
|
5118
|
+
return;
|
|
5119
|
+
}
|
|
5120
|
+
if (!this.skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
5121
|
+
logger.error("The queued activity ({activityId}) and its actors do not have the same origin.", {
|
|
5122
|
+
activityId: activity.id.href,
|
|
5123
|
+
actorIds: activity.actorIds.map((actor) => actor.href),
|
|
5124
|
+
activity: message.activity,
|
|
5125
|
+
recipient: message.identifier
|
|
5126
|
+
});
|
|
5127
|
+
listenerSpan.setStatus({
|
|
5128
|
+
code: SpanStatusCode.ERROR,
|
|
5129
|
+
message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
|
|
5130
|
+
});
|
|
5131
|
+
recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
5132
|
+
listenerSpan.end();
|
|
5133
|
+
return;
|
|
5134
|
+
}
|
|
5063
5135
|
cacheKey = activity.id == null ? null : [
|
|
5064
5136
|
...this.kvPrefixes.activityIdempotence,
|
|
5065
5137
|
context.origin,
|
|
@@ -6322,20 +6394,6 @@ var ContextImpl = class ContextImpl {
|
|
|
6322
6394
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
6323
6395
|
});
|
|
6324
6396
|
return false;
|
|
6325
|
-
} else if (fetched.actorIds.length < 1) {
|
|
6326
|
-
logger.debug("Fetched activity object is missing an actor; unable to verify.", {
|
|
6327
|
-
recipient,
|
|
6328
|
-
activity: await fetched.toJsonLd({ contextLoader })
|
|
6329
|
-
});
|
|
6330
|
-
return false;
|
|
6331
|
-
}
|
|
6332
|
-
const activityId = fetched.id;
|
|
6333
|
-
if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
|
|
6334
|
-
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
6335
|
-
recipient,
|
|
6336
|
-
activity: await fetched.toJsonLd({ contextLoader })
|
|
6337
|
-
});
|
|
6338
|
-
return false;
|
|
6339
6397
|
}
|
|
6340
6398
|
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
6341
6399
|
activity = fetched;
|
|
@@ -6344,6 +6402,20 @@ var ContextImpl = class ContextImpl {
|
|
|
6344
6402
|
recipient,
|
|
6345
6403
|
activity: json
|
|
6346
6404
|
});
|
|
6405
|
+
if (activity.actorId == null) {
|
|
6406
|
+
logger.debug("Activity is missing an actor; unable to verify.", {
|
|
6407
|
+
recipient,
|
|
6408
|
+
activity: json
|
|
6409
|
+
});
|
|
6410
|
+
return false;
|
|
6411
|
+
}
|
|
6412
|
+
if (activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
6413
|
+
logger.debug("Activity has actors from different origins; unable to verify.", {
|
|
6414
|
+
recipient,
|
|
6415
|
+
activity: json
|
|
6416
|
+
});
|
|
6417
|
+
return false;
|
|
6418
|
+
}
|
|
6347
6419
|
const routeResult = await routeActivity({
|
|
6348
6420
|
context: this,
|
|
6349
6421
|
json,
|