@fedify/fedify 2.4.0-dev.2212 → 2.4.0-dev.2228
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/{builder-CKAVFvcH.mjs → builder-Wx64uCV2.mjs} +10 -2
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-BP5SOdXv.mjs → compound-proof-B647GUyL.mjs} +2 -2
- package/dist/{context-Bl_Y7T_3.d.cts → context-B6X-t8gI.d.cts} +1 -1
- package/dist/{context-DMd11IAu.d.ts → context-CtI307_A.d.ts} +1 -1
- package/dist/{deno-BKp9fYB3.mjs → deno-9flirCWb.mjs} +1 -1
- package/dist/{docloader-BjJreYQU.mjs → docloader-pjAbs1lc.mjs} +2 -2
- package/dist/federation/builder.test.mjs +37 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +5 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +123 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +3 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +248 -6
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +4 -4
- package/dist/federation/portable-delivery.test.mjs +2 -2
- package/dist/federation/portable-gateway-keys.test.mjs +4 -4
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +80 -3
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-B-0EXZPH.cjs → federation-DiycMKQx.cjs} +262 -36
- package/dist/{http-Di8yiDMY.js → http-CHqz_Jp6.js} +1 -1
- package/dist/{http-ByBlnY3D.cjs → http-DC5DyShJ.cjs} +1 -1
- package/dist/{http--IGUT1mg.mjs → http-DysQjjJe.mjs} +4 -4
- package/dist/{key-ChfV9C3v.mjs → key-TtgqklZ1.mjs} +2 -2
- package/dist/{kv-BhNbN8Ed.d.cts → kv-B2mzK5tl.d.cts} +3 -2
- package/dist/{kv-BhNbN8Ed.d.ts → kv-B2mzK5tl.d.ts} +3 -2
- package/dist/{kv-cache-DFIUR-E5.mjs → kv-cache-B7g5Tvl0.mjs} +1 -1
- package/dist/{kv-cache-DpwDPt9V.js → kv-cache-CgYK8siN.js} +1 -1
- package/dist/{kv-cache-BDwUzxBJ.cjs → kv-cache-CsNDrjVT.cjs} +1 -1
- package/dist/{ld-DBBVabBC.mjs → ld-CHYUee-s.mjs} +3 -3
- package/dist/{metrics-DPQKFkiJ.mjs → metrics-X1lpKWRK.mjs} +1 -1
- package/dist/{middleware-VXGLiHtY.js → middleware-D2scpP9Q.js} +262 -36
- package/dist/{middleware-BW7-tHAG.mjs → middleware-DoAk0Q3s.mjs} +251 -33
- package/dist/{middleware-G9zpxUsD.mjs → middleware-ndPtgYYI.mjs} +1 -1
- package/dist/{mod-C5Mwx5ty.d.ts → mod-B8MI1mpi.d.ts} +1 -1
- package/dist/{mod-BVNGHgVr.d.ts → mod-BhTaDR5H.d.ts} +1 -1
- package/dist/{mod-Cyy1Wahy.d.cts → mod-C7_2j7VT.d.cts} +1 -1
- package/dist/{mod-Dp3Ij7sw.d.cts → mod-DFL6IxYQ.d.cts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +4 -4
- package/dist/mod.d.ts +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/otel/mod.d.cts +1 -1
- package/dist/otel/mod.d.ts +1 -1
- package/dist/{owner-BW5VsXG3.mjs → owner-BP_ouAvi.mjs} +3 -3
- package/dist/{portable-collection-FTPa5D91.js → portable-collection-4SnmDcTc.js} +1 -1
- package/dist/{portable-collection-CXcAlwei.cjs → portable-collection-Cz9K1Tas.cjs} +1 -1
- package/dist/{portable-collection-Ct99JsBe.mjs → portable-collection-SqxusPj7.mjs} +2 -2
- package/dist/{portable-key-U3lW06QJ.mjs → portable-key-DYr6MZUl.mjs} +1 -1
- package/dist/{proof-MFz2960e.mjs → proof-B-iLzyva.mjs} +4 -4
- package/dist/{send-Duj8xys1.mjs → send-D0nNms3Q.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-key.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +5 -3
- package/dist/{temporal-CVcPKB1N.mjs → temporal-39Ixir8d.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +3 -2
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +6 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
|
-
const require_http = require("./http-
|
|
2
|
+
const require_http = require("./http-DC5DyShJ.cjs");
|
|
3
3
|
let _logtape_logtape = require("@logtape/logtape");
|
|
4
4
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
5
5
|
let es_toolkit = require("es-toolkit");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "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 { c as validateCryptoKey, i as fetchKey, t as bypassKeyCacheReads } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-9flirCWb.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-X1lpKWRK.mjs";
|
|
6
|
+
import { c as validateCryptoKey, i as fetchKey, t as bypassKeyCacheReads } from "./key-TtgqklZ1.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 "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-9flirCWb.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 @@ import { Temporal } from "temporal-polyfill";
|
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
import { t as __exportAll } from "./rolldown-runtime-BC-Eo5Mj.js";
|
|
4
4
|
import { r as getDefaultActivityTransformers } from "./transformers-DAtXl_Kc.js";
|
|
5
|
-
import { $ as instrumentDocumentLoader, A as hasSignature, At as name, C as InvalidContextReferenceError, Ct as hasPortableActor, Dt as isPortableUri, E as compactJsonLd, Et as isPortableKeyId, F as verifyCompactJsonLd, G as validateCryptoKey, M as isClearlyMalformedContextReference, N as isInvalidUrlTypeError, O as detachSignature, Ot as isSameObjectId, P as signJsonLd, Q as getRemoteHost, R as wrapContextLoaderForJsonLd, S as normalizeOutgoingActivityJsonLd, St as getRawCanonicalPortableId, Tt as isPortableId, W as importJwk, X as getDurationMs, Z as getFederationMetrics, _ as verifyObject, at as recordCollectionTotalItems, b as verifyPortableObjectProofWithRoot, bt as getGatewayKeyBase, c as verifyRequestDetailed, ct as recordInboxActivity, d as InvalidPortableObjectIdError, dt as recordWebFingerHandle, et as isAbortError, f as classifyFep2277CoreType, ft as registerQueueDepthGauge, g as verifyMapLocalProof, h as signObject, i as selectRequestSignature, it as recordCollectionRequest, j as hasSignatureLike, jt as version, k as getNormalizationContextLoader, lt as recordOutboxActivity, m as hasProofLike, mt as formatAcceptSignature, n as listRequestSignatures, nt as recordCollectionDispatchDuration, o as validateMaxSignatures, pt as preloadedOnlyDocumentLoader, q as MAX_PORTABLE_KEY_TTL, r as parseRfc9421SignatureInput, rt as recordCollectionPageItems, s as verifyRequest, st as recordFanoutRecipients, t as doubleKnock, tt as recordCircuitBreakerStateChange, ut as recordOutboxEnqueue, v as verifyPortableObjectProof, vt as getAuthenticationOrigin, w as assertSafeJsonLd, wt as isCompatibleKeyId, xt as getPortableDid, y as verifyPortableObjectProofPolicy, yt as getCanonicalPortableId, z as exportJwk } from "./http-
|
|
5
|
+
import { $ as instrumentDocumentLoader, A as hasSignature, At as name, C as InvalidContextReferenceError, Ct as hasPortableActor, Dt as isPortableUri, E as compactJsonLd, Et as isPortableKeyId, F as verifyCompactJsonLd, G as validateCryptoKey, M as isClearlyMalformedContextReference, N as isInvalidUrlTypeError, O as detachSignature, Ot as isSameObjectId, P as signJsonLd, Q as getRemoteHost, R as wrapContextLoaderForJsonLd, S as normalizeOutgoingActivityJsonLd, St as getRawCanonicalPortableId, Tt as isPortableId, W as importJwk, X as getDurationMs, Z as getFederationMetrics, _ as verifyObject, at as recordCollectionTotalItems, b as verifyPortableObjectProofWithRoot, bt as getGatewayKeyBase, c as verifyRequestDetailed, ct as recordInboxActivity, d as InvalidPortableObjectIdError, dt as recordWebFingerHandle, et as isAbortError, f as classifyFep2277CoreType, ft as registerQueueDepthGauge, g as verifyMapLocalProof, h as signObject, i as selectRequestSignature, it as recordCollectionRequest, j as hasSignatureLike, jt as version, k as getNormalizationContextLoader, lt as recordOutboxActivity, m as hasProofLike, mt as formatAcceptSignature, n as listRequestSignatures, nt as recordCollectionDispatchDuration, o as validateMaxSignatures, pt as preloadedOnlyDocumentLoader, q as MAX_PORTABLE_KEY_TTL, r as parseRfc9421SignatureInput, rt as recordCollectionPageItems, s as verifyRequest, st as recordFanoutRecipients, t as doubleKnock, tt as recordCircuitBreakerStateChange, ut as recordOutboxEnqueue, v as verifyPortableObjectProof, vt as getAuthenticationOrigin, w as assertSafeJsonLd, wt as isCompatibleKeyId, xt as getPortableDid, y as verifyPortableObjectProofPolicy, yt as getCanonicalPortableId, z as exportJwk } from "./http-CHqz_Jp6.js";
|
|
6
6
|
import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-_S2_MeLF.js";
|
|
7
|
-
import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "./portable-collection-
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
7
|
+
import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "./portable-collection-4SnmDcTc.js";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-CgYK8siN.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, PUBLIC_COLLECTION, Tombstone, getTypeId, isActor, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
@@ -118,6 +118,7 @@ var FederationBuilderImpl = class {
|
|
|
118
118
|
* Symbol registry for unique identification of unnamed symbols.
|
|
119
119
|
*/
|
|
120
120
|
#symbolRegistry = /* @__PURE__ */ new Map();
|
|
121
|
+
#collectionNames = /* @__PURE__ */ new Map();
|
|
121
122
|
constructor() {
|
|
122
123
|
this.router = new Router();
|
|
123
124
|
this.objectCallbacks = {};
|
|
@@ -147,6 +148,8 @@ var FederationBuilderImpl = class {
|
|
|
147
148
|
f.objectTypeIds = { ...this.objectTypeIds };
|
|
148
149
|
f.collectionCallbacks = { ...this.collectionCallbacks };
|
|
149
150
|
f.collectionTypeIds = { ...this.collectionTypeIds };
|
|
151
|
+
f.#symbolRegistry = new Map(this.#symbolRegistry);
|
|
152
|
+
f.#collectionNames = new Map(this.#collectionNames);
|
|
150
153
|
f.inboxPath = this.inboxPath;
|
|
151
154
|
f.outboxPath = this.outboxPath;
|
|
152
155
|
f.inboxCallbacks = this.inboxCallbacks == null ? void 0 : { ...this.inboxCallbacks };
|
|
@@ -678,6 +681,7 @@ var FederationBuilderImpl = class {
|
|
|
678
681
|
if (this.collectionCallbacks[name] != null) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
|
|
679
682
|
assertPath(path);
|
|
680
683
|
if (Router.variables(path).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
|
|
684
|
+
this.#collectionNames.set(routeName, name);
|
|
681
685
|
this.router.add(path, routeName);
|
|
682
686
|
const callbacks = { dispatcher };
|
|
683
687
|
this.collectionCallbacks[name] = callbacks;
|
|
@@ -719,6 +723,10 @@ var FederationBuilderImpl = class {
|
|
|
719
723
|
const routeName = this.#uniqueCollectionId(name);
|
|
720
724
|
return this.router.build(`collection:${routeName}`, values) ?? this.router.build(`orderedCollection:${routeName}`, values);
|
|
721
725
|
}
|
|
726
|
+
/** Resolves a custom collection route to its original name. */
|
|
727
|
+
getCollectionName(routeName) {
|
|
728
|
+
return this.#collectionNames.get(routeName) ?? routeName.replace(/^(collection|orderedCollection):/, "");
|
|
729
|
+
}
|
|
722
730
|
setOutboxPermanentFailureHandler(handler) {
|
|
723
731
|
this.outboxPermanentFailureHandler = handler;
|
|
724
732
|
}
|
|
@@ -1448,7 +1456,7 @@ const textEncoder = new TextEncoder();
|
|
|
1448
1456
|
function isPortableIdValue(value) {
|
|
1449
1457
|
return typeof value === "string" && isPortableId(value);
|
|
1450
1458
|
}
|
|
1451
|
-
function isJsonMap(value) {
|
|
1459
|
+
function isJsonMap$1(value) {
|
|
1452
1460
|
return typeof value === "object" && value != null && !Array.isArray(value);
|
|
1453
1461
|
}
|
|
1454
1462
|
function isCompoundProofJsonObject(value) {
|
|
@@ -1514,7 +1522,7 @@ function addBytes(statistics, bytes, limits, path) {
|
|
|
1514
1522
|
if (statistics.byteLength > limits.maxBytes) return limitExceeded("bytes", limits.maxBytes, statistics.byteLength, path);
|
|
1515
1523
|
}
|
|
1516
1524
|
function inspectJsonTree(root, limits) {
|
|
1517
|
-
if (!isJsonMap(root)) return {
|
|
1525
|
+
if (!isJsonMap$1(root)) return {
|
|
1518
1526
|
status: "unsupported",
|
|
1519
1527
|
reason: {
|
|
1520
1528
|
type: "invalidJsonTree",
|
|
@@ -1577,7 +1585,7 @@ function inspectJsonTree(root, limits) {
|
|
|
1577
1585
|
insideProof: current.insideProof,
|
|
1578
1586
|
insideContext: current.insideContext
|
|
1579
1587
|
});
|
|
1580
|
-
} else if (isJsonMap(value)) {
|
|
1588
|
+
} else if (isJsonMap$1(value)) {
|
|
1581
1589
|
const prototype = Object.getPrototypeOf(value);
|
|
1582
1590
|
if (seen.has(value) || !hasOnlyDataProperties(value) || prototype !== Object.prototype && prototype !== null) return {
|
|
1583
1591
|
status: "unsupported",
|
|
@@ -1598,7 +1606,7 @@ function inspectJsonTree(root, limits) {
|
|
|
1598
1606
|
if (hasDirectProof) {
|
|
1599
1607
|
statistics.proofCount++;
|
|
1600
1608
|
if (statistics.proofCount > limits.maxProofs) return limitExceeded("proofs", limits.maxProofs, statistics.proofCount, childPath(current.path, "proof"));
|
|
1601
|
-
if (!isJsonMap(value.proof)) return {
|
|
1609
|
+
if (!isJsonMap$1(value.proof)) return {
|
|
1602
1610
|
status: "unsupported",
|
|
1603
1611
|
reason: {
|
|
1604
1612
|
type: "unsupportedProofShape",
|
|
@@ -1773,7 +1781,7 @@ function inspectCompoundPortableObjectApplicability(json, limits) {
|
|
|
1773
1781
|
iterator: value.values(),
|
|
1774
1782
|
depth: frame.depth + 1
|
|
1775
1783
|
});
|
|
1776
|
-
} else if (isJsonMap(value)) {
|
|
1784
|
+
} else if (isJsonMap$1(value)) {
|
|
1777
1785
|
mapCount++;
|
|
1778
1786
|
if (mapCount > limits.maxMaps) return "indeterminate";
|
|
1779
1787
|
if ([value.id, value["@id"]].some(isPortableIdValue)) return "present";
|
|
@@ -1869,7 +1877,7 @@ function containsCompoundPortableObject(json) {
|
|
|
1869
1877
|
* @internal
|
|
1870
1878
|
*/
|
|
1871
1879
|
function findUnsupportedCompoundProofShape(json) {
|
|
1872
|
-
return findInJsonMaps(json, (map, path) => Object.hasOwn(map, "proof") && !isJsonMap(map.proof) ? childPath(path, "proof") : void 0) ?? null;
|
|
1880
|
+
return findInJsonMaps(json, (map, path) => Object.hasOwn(map, "proof") && !isJsonMap$1(map.proof) ? childPath(path, "proof") : void 0) ?? null;
|
|
1873
1881
|
}
|
|
1874
1882
|
/**
|
|
1875
1883
|
* Discovers direct literal proof-bearing maps in an immutable JSON snapshot.
|
|
@@ -2071,13 +2079,13 @@ async function isEmbeddedPortableKey(parent, member, key, parentId) {
|
|
|
2071
2079
|
}
|
|
2072
2080
|
if (expanded.length !== 1 || hasGraphKeyword(expanded)) return false;
|
|
2073
2081
|
const node = expanded[0];
|
|
2074
|
-
if (!isJsonMap(node) || typeof node["@id"] !== "string" || getCanonicalPortableIdOf(node["@id"]) !== parentPortableId) return false;
|
|
2082
|
+
if (!isJsonMap$1(node) || typeof node["@id"] !== "string" || getCanonicalPortableIdOf(node["@id"]) !== parentPortableId) return false;
|
|
2075
2083
|
const properties = Object.keys(node).filter((property) => property !== "@id" && property !== "@type");
|
|
2076
2084
|
if (properties.length !== 1 || properties[0] !== `${SECURITY}${member}`) return false;
|
|
2077
2085
|
const values = node[properties[0]];
|
|
2078
2086
|
if (!Array.isArray(values) || values.length !== 1) return false;
|
|
2079
2087
|
const expandedKey = values[0];
|
|
2080
|
-
if (!isJsonMap(expandedKey) || expandedKey["@id"] !== literalIds[0] || Object.keys(expandedKey).some((property) => !KEY_PROPERTIES.has(property))) return false;
|
|
2088
|
+
if (!isJsonMap$1(expandedKey) || expandedKey["@id"] !== literalIds[0] || Object.keys(expandedKey).some((property) => !KEY_PROPERTIES.has(property))) return false;
|
|
2081
2089
|
const types = expandedKey["@type"];
|
|
2082
2090
|
if (types !== void 0 && (!Array.isArray(types) || types.some((type) => typeof type !== "string" || !KEY_TYPES.has(type)))) return false;
|
|
2083
2091
|
const pem = expandedKey[`${SECURITY}publicKeyPem`];
|
|
@@ -2088,7 +2096,7 @@ async function isEmbeddedPortableKey(parent, member, key, parentId) {
|
|
|
2088
2096
|
for (const property of [`${SECURITY}owner`, `${SECURITY}controller`]) {
|
|
2089
2097
|
const owners = expandedKey[property];
|
|
2090
2098
|
if (owners === void 0) continue;
|
|
2091
|
-
if (!Array.isArray(owners) || owners.length !== 1 || !isJsonMap(owners[0]) || Object.keys(owners[0]).length !== 1 || typeof owners[0]["@id"] !== "string" || getCanonicalPortableIdOf(owners[0]["@id"]) !== parentPortableId) return false;
|
|
2099
|
+
if (!Array.isArray(owners) || owners.length !== 1 || !isJsonMap$1(owners[0]) || Object.keys(owners[0]).length !== 1 || typeof owners[0]["@id"] !== "string" || getCanonicalPortableIdOf(owners[0]["@id"]) !== parentPortableId) return false;
|
|
2092
2100
|
}
|
|
2093
2101
|
return true;
|
|
2094
2102
|
}
|
|
@@ -2131,7 +2139,7 @@ function isSimpleContext(context) {
|
|
|
2131
2139
|
}
|
|
2132
2140
|
function hasGraphKeyword(value) {
|
|
2133
2141
|
if (Array.isArray(value)) return value.some(hasGraphKeyword);
|
|
2134
|
-
if (!isJsonMap(value)) return false;
|
|
2142
|
+
if (!isJsonMap$1(value)) return false;
|
|
2135
2143
|
return Object.entries(value).some(([key, child]) => key === "@graph" || key === "@included" || key === "@reverse" || hasGraphKeyword(child));
|
|
2136
2144
|
}
|
|
2137
2145
|
/**
|
|
@@ -2141,7 +2149,7 @@ function hasGraphKeyword(value) {
|
|
|
2141
2149
|
function isSingleStringValue(values, datatype) {
|
|
2142
2150
|
if (!Array.isArray(values) || values.length !== 1) return false;
|
|
2143
2151
|
const value = values[0];
|
|
2144
|
-
if (!isJsonMap(value) || typeof value["@value"] !== "string") return false;
|
|
2152
|
+
if (!isJsonMap$1(value) || typeof value["@value"] !== "string") return false;
|
|
2145
2153
|
const keys = Object.keys(value);
|
|
2146
2154
|
return keys.length === 1 || datatype != null && keys.length === 2 && value["@type"] === datatype;
|
|
2147
2155
|
}
|
|
@@ -2196,7 +2204,7 @@ async function verifyServedPortableObjects(json, options = {}) {
|
|
|
2196
2204
|
const maps = collected.maps;
|
|
2197
2205
|
const discovered = /* @__PURE__ */ new Map();
|
|
2198
2206
|
const ids = maps.map((candidate) => candidate.id);
|
|
2199
|
-
const rootId = isJsonMap(json) ? [json.id, json["@id"]].find(isPortableIdValue) : void 0;
|
|
2207
|
+
const rootId = isJsonMap$1(json) ? [json.id, json["@id"]].find(isPortableIdValue) : void 0;
|
|
2200
2208
|
if (rootId != null) ids.push(rootId);
|
|
2201
2209
|
for (const id of ids) discovered.set(id, (discovered.get(id) ?? 0) + 1);
|
|
2202
2210
|
let hidden;
|
|
@@ -2241,7 +2249,7 @@ function findHiddenPortableObject(expanded, discovered) {
|
|
|
2241
2249
|
pending.push(...value);
|
|
2242
2250
|
continue;
|
|
2243
2251
|
}
|
|
2244
|
-
if (!isJsonMap(value)) continue;
|
|
2252
|
+
if (!isJsonMap$1(value)) continue;
|
|
2245
2253
|
const id = value["@id"];
|
|
2246
2254
|
if (isPortableIdValue(id) && Object.keys(value).some((key) => key !== "@id")) {
|
|
2247
2255
|
const count = remaining.get(id) ?? 0;
|
|
@@ -2332,7 +2340,7 @@ function collectServedPortableMaps(json) {
|
|
|
2332
2340
|
}
|
|
2333
2341
|
async function checkServedPortableMap({ map, contexts }, options) {
|
|
2334
2342
|
if (Object.hasOwn(map, "proof")) {
|
|
2335
|
-
if (!isJsonMap(map.proof)) return "unsupportedProofShape";
|
|
2343
|
+
if (!isJsonMap$1(map.proof)) return "unsupportedProofShape";
|
|
2336
2344
|
if (!Object.hasOwn(map, "@context")) return "missingContext";
|
|
2337
2345
|
try {
|
|
2338
2346
|
const policy = await verifyPortableObjectProofPolicy(map, await verifyMapLocalProof(map, options), options);
|
|
@@ -2353,11 +2361,185 @@ async function checkServedPortableMap({ map, contexts }, options) {
|
|
|
2353
2361
|
} catch {
|
|
2354
2362
|
return "unsupportedContext";
|
|
2355
2363
|
}
|
|
2356
|
-
if (expanded.length !== 1 || !isJsonMap(expanded[0])) return "invalidPortableObject";
|
|
2364
|
+
if (expanded.length !== 1 || !isJsonMap$1(expanded[0])) return "invalidPortableObject";
|
|
2357
2365
|
const type = classifyFep2277CoreType(expanded[0]);
|
|
2358
2366
|
return UNSECURED_CORE_TYPES.has(type) ? null : "missingProof";
|
|
2359
2367
|
}
|
|
2360
2368
|
//#endregion
|
|
2369
|
+
//#region src/federation/compatible-id-warning.ts
|
|
2370
|
+
/** Returns a verified first gateway, without dereferencing the actor. */
|
|
2371
|
+
async function getLocalFirstGateway(context, ownerId, did) {
|
|
2372
|
+
try {
|
|
2373
|
+
const parsed = context.parseUri(ownerId, { portable: true });
|
|
2374
|
+
if (parsed?.type !== "actor" || parsed.authority !== did) return null;
|
|
2375
|
+
return firstGateway(await context.getActor(parsed.identifier), did);
|
|
2376
|
+
} catch (error) {
|
|
2377
|
+
getLogger([
|
|
2378
|
+
"fedify",
|
|
2379
|
+
"federation",
|
|
2380
|
+
"object"
|
|
2381
|
+
]).debug("Could not check the first gateway of {ownerId}: {error}", {
|
|
2382
|
+
ownerId: ownerId.href,
|
|
2383
|
+
error
|
|
2384
|
+
});
|
|
2385
|
+
return null;
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
function firstGateway(actor, did) {
|
|
2389
|
+
if (actor?.id == null || getPortableDid(actor.id) !== did) return null;
|
|
2390
|
+
const gateway = actor.gateway;
|
|
2391
|
+
return gateway != null && isGatewayUrl(gateway) ? gateway : null;
|
|
2392
|
+
}
|
|
2393
|
+
/** Looks for an actor already embedded in the document being published. */
|
|
2394
|
+
function getEmbeddedFirstGateway(json, ownerId, did) {
|
|
2395
|
+
const owner = getCanonicalPortableId(ownerId);
|
|
2396
|
+
if (owner == null) return null;
|
|
2397
|
+
return visitJsonMaps(json, (map) => {
|
|
2398
|
+
const id = parseMapId(map, isJsonMap(json) ? json : null);
|
|
2399
|
+
if (id == null || getCanonicalPortableId(id) !== owner) return;
|
|
2400
|
+
const gateways = map.gateways ?? map["https://w3id.org/fep/ef61/gateways"];
|
|
2401
|
+
const first = Array.isArray(gateways) ? gateways[0] : isJsonMap(gateways) && Array.isArray(gateways["@list"]) ? gateways["@list"][0] : null;
|
|
2402
|
+
const address = typeof first === "string" ? first : isJsonMap(first) ? first.id ?? first["@id"] : null;
|
|
2403
|
+
if (typeof address !== "string") return;
|
|
2404
|
+
try {
|
|
2405
|
+
const gateway = new URL(address);
|
|
2406
|
+
if (getPortableDid(id) === did && isGatewayUrl(gateway)) return gateway;
|
|
2407
|
+
} catch (error) {
|
|
2408
|
+
if (!(error instanceof TypeError)) throw error;
|
|
2409
|
+
}
|
|
2410
|
+
}) ?? null;
|
|
2411
|
+
}
|
|
2412
|
+
function isJsonMap(value) {
|
|
2413
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
2414
|
+
}
|
|
2415
|
+
/** Warns only when the publisher's actual first gateway is known. */
|
|
2416
|
+
function warnCompatibleId(id, did, gateway, kind) {
|
|
2417
|
+
if (!isCompatibleEf61Iri(id) || getPortableDid(id) !== did || id.origin === gateway.origin) return;
|
|
2418
|
+
getLogger([
|
|
2419
|
+
"fedify",
|
|
2420
|
+
"federation",
|
|
2421
|
+
kind === "activity" ? "outbox" : "object"
|
|
2422
|
+
]).warn("The {kind} {id} has an FEP-ef61 compatible identifier on another gateway than its owner's first gateway, {gateway}. FEP-ef61 requires publishers to use the first gateway in the actor's gateways.", {
|
|
2423
|
+
kind,
|
|
2424
|
+
id: id.href,
|
|
2425
|
+
gateway: gateway.origin
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2428
|
+
/** Reads the root ID without dereferencing or expanding the document. */
|
|
2429
|
+
function getCompactRootId(json) {
|
|
2430
|
+
return isJsonMap(json) ? parseMapId(json, json) : null;
|
|
2431
|
+
}
|
|
2432
|
+
/** Checks an activity and its embedded objects against each one's owner. */
|
|
2433
|
+
async function warnCompatibleIdsInJson(json, context) {
|
|
2434
|
+
const root = isJsonMap(json) ? json : null;
|
|
2435
|
+
const rootOwners = root == null ? [] : ownerIds(root, "actor", root);
|
|
2436
|
+
const gateways = /* @__PURE__ */ new Map();
|
|
2437
|
+
const maps = [];
|
|
2438
|
+
visitJsonMaps(json, (map, path) => {
|
|
2439
|
+
maps.push({
|
|
2440
|
+
map,
|
|
2441
|
+
path
|
|
2442
|
+
});
|
|
2443
|
+
});
|
|
2444
|
+
for (const { map, path } of maps) {
|
|
2445
|
+
const id = parseMapId(map, root);
|
|
2446
|
+
if (id == null || !isCompatibleEf61Iri(id)) continue;
|
|
2447
|
+
const type = map.type ?? map["@type"];
|
|
2448
|
+
if ((Array.isArray(type) ? type : [type]).some((t) => typeof t === "string" && /(?:^|[#/:])(CryptographicKey|Multikey|JsonWebKey|Key)$/.test(t))) continue;
|
|
2449
|
+
const did = getPortableDid(id);
|
|
2450
|
+
if (did == null) continue;
|
|
2451
|
+
const owners = path === "" ? rootOwners : [
|
|
2452
|
+
...ownerIds(map, "actor", root),
|
|
2453
|
+
...ownerIds(map, "attributedTo", root),
|
|
2454
|
+
...rootOwners
|
|
2455
|
+
];
|
|
2456
|
+
for (const ownerId of owners) {
|
|
2457
|
+
if (getPortableDid(ownerId) !== did) continue;
|
|
2458
|
+
const key = getCanonicalPortableId(ownerId);
|
|
2459
|
+
if (key == null) continue;
|
|
2460
|
+
let gateway = gateways.get(key);
|
|
2461
|
+
if (gateway === void 0) {
|
|
2462
|
+
gateway = getEmbeddedFirstGateway(json, ownerId, did) ?? (context == null ? null : await getLocalFirstGateway(context, ownerId, did));
|
|
2463
|
+
gateways.set(key, gateway);
|
|
2464
|
+
}
|
|
2465
|
+
if (gateway != null) {
|
|
2466
|
+
warnCompatibleId(id, did, gateway, path === "" ? "activity" : "object");
|
|
2467
|
+
break;
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
function ownerIds(map, term, root) {
|
|
2473
|
+
const iri = `https://www.w3.org/ns/activitystreams#${term}`;
|
|
2474
|
+
const values = [map[term], map[iri]];
|
|
2475
|
+
for (const context of [map["@context"], root?.["@context"]]) for (const [alias, definition] of localContextEntries(context)) {
|
|
2476
|
+
const mapped = typeof definition === "string" ? definition : isJsonMap(definition) ? definition["@id"] : null;
|
|
2477
|
+
if (mapped === iri || mapped === `as:${term}`) values.push(map[alias]);
|
|
2478
|
+
}
|
|
2479
|
+
return values.flatMap((value) => parseOwnerIds(value, root));
|
|
2480
|
+
}
|
|
2481
|
+
function localContextEntries(context) {
|
|
2482
|
+
if (Array.isArray(context)) return context.flatMap(localContextEntries);
|
|
2483
|
+
return isJsonMap(context) ? Object.entries(context) : [];
|
|
2484
|
+
}
|
|
2485
|
+
function parseOwnerIds(value, root) {
|
|
2486
|
+
if (Array.isArray(value)) return value.flatMap((item) => parseOwnerIds(item, root));
|
|
2487
|
+
if (isJsonMap(value)) {
|
|
2488
|
+
const id = parseMapId(value, root);
|
|
2489
|
+
return id == null ? [] : [id];
|
|
2490
|
+
}
|
|
2491
|
+
if (typeof value !== "string") return [];
|
|
2492
|
+
try {
|
|
2493
|
+
return [parseIri(value)];
|
|
2494
|
+
} catch (error) {
|
|
2495
|
+
if (error instanceof TypeError) return [];
|
|
2496
|
+
throw error;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
function parseMapId(map, root) {
|
|
2500
|
+
let raw = map["@id"] ?? map.id;
|
|
2501
|
+
for (const context of [map["@context"], root?.["@context"]]) for (const [alias, definition] of localContextEntries(context)) if ((typeof definition === "string" ? definition : isJsonMap(definition) ? definition["@id"] : null) === "@id" && typeof map[alias] === "string") {
|
|
2502
|
+
raw = map[alias];
|
|
2503
|
+
break;
|
|
2504
|
+
}
|
|
2505
|
+
if (typeof raw !== "string") return null;
|
|
2506
|
+
try {
|
|
2507
|
+
return parseIri(raw);
|
|
2508
|
+
} catch (error) {
|
|
2509
|
+
if (error instanceof TypeError) return null;
|
|
2510
|
+
throw error;
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
function visitJsonMaps(json, visit) {
|
|
2514
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2515
|
+
const pending = [{
|
|
2516
|
+
value: json,
|
|
2517
|
+
path: ""
|
|
2518
|
+
}];
|
|
2519
|
+
while (pending.length > 0) {
|
|
2520
|
+
const { value, path } = pending.pop();
|
|
2521
|
+
if (value == null || typeof value !== "object" || seen.has(value)) continue;
|
|
2522
|
+
seen.add(value);
|
|
2523
|
+
if (Array.isArray(value)) {
|
|
2524
|
+
for (let i = value.length - 1; i >= 0; i--) pending.push({
|
|
2525
|
+
value: value[i],
|
|
2526
|
+
path: `${path}/${i}`
|
|
2527
|
+
});
|
|
2528
|
+
continue;
|
|
2529
|
+
}
|
|
2530
|
+
const map = value;
|
|
2531
|
+
const result = visit(map, path);
|
|
2532
|
+
if (result !== void 0) return result;
|
|
2533
|
+
for (const key of Object.keys(map).reverse()) {
|
|
2534
|
+
if (key === "proof" || key === "@context") continue;
|
|
2535
|
+
pending.push({
|
|
2536
|
+
value: map[key],
|
|
2537
|
+
path: `${path}/${key}`
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
//#endregion
|
|
2361
2543
|
//#region src/federation/audience.ts
|
|
2362
2544
|
const AS_NAMESPACE = "https://www.w3.org/ns/activitystreams#";
|
|
2363
2545
|
/**
|
|
@@ -4147,6 +4329,7 @@ async function handleObject(request, { values, context, objectDispatcher, author
|
|
|
4147
4329
|
Vary: "Accept"
|
|
4148
4330
|
}
|
|
4149
4331
|
});
|
|
4332
|
+
await warnServedCompatibleObject(context, object, getCompactRootId(jsonLd));
|
|
4150
4333
|
return new Response(JSON.stringify(jsonLd), { headers: {
|
|
4151
4334
|
"Content-Type": "application/activity+json",
|
|
4152
4335
|
Vary: "Accept"
|
|
@@ -4250,6 +4433,7 @@ async function handlePortableObject(request, { values, context, objectDispatcher
|
|
|
4250
4433
|
return portableObjectInternalServerError(request);
|
|
4251
4434
|
}
|
|
4252
4435
|
}
|
|
4436
|
+
if (!tombstone) await warnServedCompatibleObject(context, object, servedId);
|
|
4253
4437
|
const headers = new Headers({
|
|
4254
4438
|
"Content-Type": PORTABLE_OBJECT_CONTENT_TYPE,
|
|
4255
4439
|
Vary: "Accept"
|
|
@@ -4260,6 +4444,32 @@ async function handlePortableObject(request, { values, context, objectDispatcher
|
|
|
4260
4444
|
headers
|
|
4261
4445
|
});
|
|
4262
4446
|
}
|
|
4447
|
+
async function warnServedCompatibleObject(context, object, serializedId) {
|
|
4448
|
+
try {
|
|
4449
|
+
if (isActor(object)) return;
|
|
4450
|
+
const id = typeof serializedId === "string" ? parseIri(serializedId) : serializedId ?? object.id;
|
|
4451
|
+
if (id == null || !isCompatibleEf61Iri(id)) return;
|
|
4452
|
+
const did = getPortableDid(id);
|
|
4453
|
+
if (did == null) return;
|
|
4454
|
+
const ownerIds = object instanceof Activity ? object.actorIds : object.attributionIds;
|
|
4455
|
+
for (const ownerId of ownerIds) {
|
|
4456
|
+
if (getPortableDid(ownerId) !== did) continue;
|
|
4457
|
+
const gateway = await getLocalFirstGateway(context, ownerId, did);
|
|
4458
|
+
if (gateway == null) continue;
|
|
4459
|
+
warnCompatibleId(id, did, gateway, object instanceof Activity ? "activity" : "object");
|
|
4460
|
+
break;
|
|
4461
|
+
}
|
|
4462
|
+
} catch (error) {
|
|
4463
|
+
getLogger([
|
|
4464
|
+
"fedify",
|
|
4465
|
+
"federation",
|
|
4466
|
+
"object"
|
|
4467
|
+
]).debug("Could not check the first gateway of {objectId}: {error}", {
|
|
4468
|
+
objectId: object.id?.href,
|
|
4469
|
+
error
|
|
4470
|
+
});
|
|
4471
|
+
}
|
|
4472
|
+
}
|
|
4263
4473
|
function isRequestedPortableObject(object, canonicalId) {
|
|
4264
4474
|
return object.id != null && getCanonicalPortableId(object.id) === canonicalId;
|
|
4265
4475
|
}
|
|
@@ -4363,13 +4573,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
|
|
|
4363
4573
|
* @param parameters The parameters for handling the collection.
|
|
4364
4574
|
* @returns A promise that resolves to an HTTP response.
|
|
4365
4575
|
*/
|
|
4366
|
-
async function handleCollection(request, { name: name$
|
|
4367
|
-
const spanName = name$
|
|
4576
|
+
async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, portable, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
|
|
4577
|
+
const spanName = name$1.trim().replace(/\s+/g, "_");
|
|
4368
4578
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
4369
4579
|
const tracer = tracerProvider.getTracer(name, version);
|
|
4370
4580
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
4371
4581
|
const metricBase = {
|
|
4372
|
-
kind: getCollectionMetricKind(name$
|
|
4582
|
+
kind: getCollectionMetricKind(name$1),
|
|
4373
4583
|
page: cursor != null,
|
|
4374
4584
|
dispatcher: "built_in"
|
|
4375
4585
|
};
|
|
@@ -4415,7 +4625,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
4415
4625
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
4416
4626
|
return await onNotFound(request);
|
|
4417
4627
|
}
|
|
4418
|
-
const items = filterCollectionItems(page.items, name$
|
|
4628
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
4419
4629
|
itemCount = items.length;
|
|
4420
4630
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
4421
4631
|
return items;
|
|
@@ -4457,7 +4667,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
4457
4667
|
} else {
|
|
4458
4668
|
const uri = new URL(portable == null ? baseUri : pageBase);
|
|
4459
4669
|
uri.searchParams.set("cursor", cursor);
|
|
4460
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$
|
|
4670
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
|
|
4461
4671
|
kind: SpanKind.SERVER,
|
|
4462
4672
|
attributes: {
|
|
4463
4673
|
"activitypub.collection.id": uri.href,
|
|
@@ -4473,7 +4683,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
4473
4683
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
4474
4684
|
return await onNotFound(request);
|
|
4475
4685
|
}
|
|
4476
|
-
const items = filterCollectionItems(page.items, name$
|
|
4686
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
4477
4687
|
itemCount = items.length;
|
|
4478
4688
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
4479
4689
|
return {
|
|
@@ -5664,8 +5874,8 @@ var CustomCollectionHandler = class {
|
|
|
5664
5874
|
* @param CollectionPage The CollectionPage constructor.
|
|
5665
5875
|
* @param filterPredicate Optional filter predicate for items.
|
|
5666
5876
|
*/
|
|
5667
|
-
constructor(name$
|
|
5668
|
-
this.name = name$
|
|
5877
|
+
constructor(name$2, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate, portable) {
|
|
5878
|
+
this.name = name$2;
|
|
5669
5879
|
this.values = values;
|
|
5670
5880
|
this.context = context;
|
|
5671
5881
|
this.callbacks = callbacks;
|
|
@@ -9411,10 +9621,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
9411
9621
|
onNotFound
|
|
9412
9622
|
});
|
|
9413
9623
|
case "collection": {
|
|
9414
|
-
const name = route.name
|
|
9624
|
+
const name = this.getCollectionName(route.name);
|
|
9415
9625
|
const callbacks = this.collectionCallbacks[name];
|
|
9416
9626
|
return await handleCustomCollection(request, {
|
|
9417
|
-
name,
|
|
9627
|
+
name: String(name),
|
|
9418
9628
|
context,
|
|
9419
9629
|
values: route.values,
|
|
9420
9630
|
collectionCallbacks: callbacks,
|
|
@@ -9425,10 +9635,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
9425
9635
|
});
|
|
9426
9636
|
}
|
|
9427
9637
|
case "orderedCollection": {
|
|
9428
|
-
const name = route.name
|
|
9638
|
+
const name = this.getCollectionName(route.name);
|
|
9429
9639
|
const callbacks = this.collectionCallbacks[name];
|
|
9430
9640
|
return await handleOrderedCollection(request, {
|
|
9431
|
-
name,
|
|
9641
|
+
name: String(name),
|
|
9432
9642
|
context,
|
|
9433
9643
|
values: route.values,
|
|
9434
9644
|
collectionCallbacks: callbacks,
|
|
@@ -10194,8 +10404,10 @@ var ContextImpl = class ContextImpl {
|
|
|
10194
10404
|
const collectionRegex = new RegExp(`^(${["collection", "orderedCollection"].join("|")}):(.*)$`);
|
|
10195
10405
|
const match = route.name.match(collectionRegex);
|
|
10196
10406
|
if (match !== null) {
|
|
10197
|
-
const [, type
|
|
10407
|
+
const [, type] = match;
|
|
10408
|
+
const name = this.federation.getCollectionName(route.name);
|
|
10198
10409
|
const cls = this.federation.collectionTypeIds[name];
|
|
10410
|
+
if (cls == null) return null;
|
|
10199
10411
|
return {
|
|
10200
10412
|
type,
|
|
10201
10413
|
name,
|
|
@@ -10496,17 +10708,26 @@ var ContextImpl = class ContextImpl {
|
|
|
10496
10708
|
activityId: activity.id?.href,
|
|
10497
10709
|
activity
|
|
10498
10710
|
});
|
|
10711
|
+
const activityJsonLd = await activity.toJsonLd({
|
|
10712
|
+
format: "compact",
|
|
10713
|
+
contextLoader: this.contextLoader
|
|
10714
|
+
});
|
|
10715
|
+
try {
|
|
10716
|
+
await warnCompatibleIdsInJson(activityJsonLd, this instanceof RequestContextImpl && !this.isInActorDispatcher() ? this : void 0);
|
|
10717
|
+
} catch (error) {
|
|
10718
|
+
logger.debug("Could not check the first gateway of activity {activityId}: {error}", {
|
|
10719
|
+
activityId: activity.id?.href,
|
|
10720
|
+
error
|
|
10721
|
+
});
|
|
10722
|
+
}
|
|
10499
10723
|
if (this.federation.fanoutQueue == null || options.immediate || options.fanout === "skip" || (options.fanout ?? "auto") === "auto" && globalThis.Object.keys(inboxes).length < FANOUT_THRESHOLD) {
|
|
10500
10724
|
await this.federation.sendActivity(keys, inboxes, activity, {
|
|
10501
10725
|
...opts,
|
|
10726
|
+
activityJsonLd,
|
|
10502
10727
|
normalizeExistingProofs: proofCreated || options.normalizeExistingProofs
|
|
10503
10728
|
});
|
|
10504
10729
|
return true;
|
|
10505
10730
|
}
|
|
10506
|
-
const activityJsonLd = await activity.toJsonLd({
|
|
10507
|
-
format: "compact",
|
|
10508
|
-
contextLoader: this.contextLoader
|
|
10509
|
-
});
|
|
10510
10731
|
assertSupportedCompoundProofShape(activityJsonLd, activity.id?.href);
|
|
10511
10732
|
const keyJwkPairs = await Promise.all(keys.map(async ({ keyId, privateKey }) => ({
|
|
10512
10733
|
keyId: keyId.href,
|
|
@@ -10598,7 +10819,7 @@ var ContextImpl = class ContextImpl {
|
|
|
10598
10819
|
"inbox"
|
|
10599
10820
|
]);
|
|
10600
10821
|
const contextLoader = options.contextLoader ?? this.contextLoader;
|
|
10601
|
-
|
|
10822
|
+
let json = await activity.toJsonLd({ contextLoader });
|
|
10602
10823
|
const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, {
|
|
10603
10824
|
documentLoader: this.documentLoader,
|
|
10604
10825
|
contextLoader: this.contextLoader,
|
|
@@ -10660,6 +10881,7 @@ var ContextImpl = class ContextImpl {
|
|
|
10660
10881
|
}
|
|
10661
10882
|
logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
|
|
10662
10883
|
activity = fetched;
|
|
10884
|
+
json = await fetched.toJsonLd({ contextLoader });
|
|
10663
10885
|
} else logger.debug("Object Integrity Proofs are verified.", {
|
|
10664
10886
|
recipient,
|
|
10665
10887
|
activity: json
|
|
@@ -10688,6 +10910,10 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
|
|
|
10688
10910
|
#invokedFromActorDispatcher;
|
|
10689
10911
|
#invokedFromObjectDispatcher;
|
|
10690
10912
|
request;
|
|
10913
|
+
/** Whether a diagnostic actor lookup would re-enter the actor dispatcher. */
|
|
10914
|
+
isInActorDispatcher() {
|
|
10915
|
+
return this.#invokedFromActorDispatcher != null;
|
|
10916
|
+
}
|
|
10691
10917
|
url = void 0;
|
|
10692
10918
|
portableRequest;
|
|
10693
10919
|
constructor(options) {
|