@fedify/fedify 2.4.0-dev.2169 → 2.4.0-dev.2193
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-B2d_Pt0j.mjs → builder-0onlMY4u.mjs} +26 -6
- package/dist/{circuit-breaker-C5NqoLBJ.mjs → circuit-breaker-XJ53md4S.mjs} +16 -11
- 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-D28gMFqP.mjs → compound-proof-B-Fk6Slo.mjs} +3 -3
- package/dist/{context-BykNUf04.d.ts → context-9T--NSo4.d.ts} +55 -1
- package/dist/{context-L0Fnib9j.d.cts → context-CDcAgm4l.d.cts} +55 -1
- package/dist/{deno-DU8dvnWk.mjs → deno-DB_Sh0LK.mjs} +1 -1
- package/dist/{docloader-CghLH7Zi.mjs → docloader-DpWYYY6a.mjs} +25 -17
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/circuit-breaker.test.mjs +50 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +52 -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/keycache.test.mjs +1 -1
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +182 -13
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +2 -2
- package/dist/federation/mod.d.ts +2 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +5 -5
- 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-gateway-keys.test.mjs +6 -6
- package/dist/federation/portable-inbox.test.mjs +35 -5
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.d.mts +2 -0
- package/dist/federation/portable-route-activity.test.mjs +259 -0
- package/dist/federation/portable.test.mjs +49 -5
- 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-DrNgkLfJ.cjs → federation-BsGo0EH2.cjs} +76 -35
- package/dist/{http-5CJBdU8n.cjs → http-BEivI0TS.cjs} +279 -87
- package/dist/{http-BGpexPO7.js → http-BGmxtpo2.js} +263 -89
- package/dist/{http-Cok5-vIC.d.ts → http-BrwKINQn.d.cts} +29 -1
- package/dist/{http-DC1cqAQ2.d.cts → http-DGx0KOws.d.ts} +29 -1
- package/dist/{http-Bd6rZlJX.mjs → http-DQf9Mw4V.mjs} +180 -92
- package/dist/{key-gIhVZO3p.mjs → key-DA3Yx8p2.mjs} +4 -4
- package/dist/{key-owner-evidence-Bo3yaeL5.mjs → key-owner-evidence-APB6NpSk.mjs} +1 -1
- package/dist/{keycache-PiOM9pM0.mjs → keycache-Da8A8mZa.mjs} +1 -1
- package/dist/{kv-cache-YRi_g8GB.cjs → kv-cache-1hafSoqH.cjs} +23 -15
- package/dist/{kv-cache-iR55fqlk.js → kv-cache-DduYhpee.js} +24 -16
- package/dist/{kv-cache-D0qjSeWY.mjs → kv-cache-OFBvrKh3.mjs} +1 -1
- package/dist/{ld-BsTkRrwF.mjs → ld-C15yzuY6.mjs} +3 -3
- package/dist/{metrics-jUDFfVgi.mjs → metrics-B1H23mlq.mjs} +1 -1
- package/dist/{middleware-Dq-OCmb6.mjs → middleware-BZQnf0nI.mjs} +1 -1
- package/dist/{middleware-Coqgp-K0.mjs → middleware-BqqycC0P.mjs} +52 -36
- package/dist/{middleware-DlxMxVp5.js → middleware-ClaUFaLb.js} +77 -36
- package/dist/{mod-DK0y9fd-.d.ts → mod-B3OBLj5g.d.ts} +1 -1
- package/dist/{mod-B5z_q9TH.d.ts → mod-C5Mwx5ty.d.ts} +5 -1
- package/dist/{mod-CPPqkyV_.d.cts → mod-Cy9VNHVw.d.ts} +14 -3
- package/dist/{mod-BLOXGs6m.d.cts → mod-D58KCqUg.d.cts} +1 -1
- package/dist/{mod--jv6vyrP.d.ts → mod-DoTWIc7F.d.cts} +14 -3
- package/dist/{mod-BA_F2x53.d.cts → mod-Dp3Ij7sw.d.cts} +5 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-D3GoetXS.mjs → owner-BVpZBM-V.mjs} +5 -5
- package/dist/{portable-collection-CnlCamup.cjs → portable-collection-BFSShzwh.cjs} +1 -1
- package/dist/{portable-collection-Bkdh_WpL.js → portable-collection-D535cSz_.js} +1 -1
- package/dist/{portable-collection-C60_acmx.mjs → portable-collection-Dn2GdZdI.mjs} +2 -2
- package/dist/{portable-key-DyF5AnZo.mjs → portable-key-Bmwmq7Y6.mjs} +2 -2
- package/dist/{portable-key-id-Bg259c4Z.mjs → portable-key-id-Ca30-hOa.mjs} +45 -1
- package/dist/{proof-CQAYqWdj.mjs → proof-DrJWKeOl.mjs} +49 -7
- package/dist/{send-DjkQrxt5.mjs → send-CT3a-0Vd.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 +495 -23
- package/dist/sig/key-owner-evidence.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.d.cts +2 -2
- package/dist/sig/mod.d.ts +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-id.test.d.mts +2 -0
- package/dist/sig/portable-key-id.test.mjs +67 -0
- package/dist/sig/portable-key.test.mjs +7 -7
- package/dist/sig/proof.test.mjs +141 -7
- package/dist/{temporal-oRKP803M.mjs → temporal-DNqluyEc.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +52 -0
- package/dist/utils/docloader.test.mjs +93 -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 +7 -7
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
const require_rolldown_runtime = require("./rolldown-runtime-Dmm3t92W.cjs");
|
|
3
3
|
const require_transformers = require("./transformers-BalCrSsr.cjs");
|
|
4
|
-
const require_http = require("./http-
|
|
4
|
+
const require_http = require("./http-BEivI0TS.cjs");
|
|
5
5
|
const require_types = require("./types-poIao40f.cjs");
|
|
6
|
-
const require_portable_collection = require("./portable-collection-
|
|
7
|
-
const require_kv_cache = require("./kv-cache-
|
|
6
|
+
const require_portable_collection = require("./portable-collection-BFSShzwh.cjs");
|
|
7
|
+
const require_kv_cache = require("./kv-cache-1hafSoqH.cjs");
|
|
8
8
|
let _logtape_logtape = require("@logtape/logtape");
|
|
9
9
|
let _fedify_uri_template = require("@fedify/uri-template");
|
|
10
10
|
let _fedify_vocab = require("@fedify/vocab");
|
|
@@ -210,6 +210,7 @@ var FederationBuilderImpl = class {
|
|
|
210
210
|
if (actor.id == null) logger.warn("Actor dispatcher returned an actor without an id property. Set the property with Context.getActorUri(identifier).");
|
|
211
211
|
else if (!portable && actor.id.href != context.getActorUri(identifier).href) logger.warn("Actor dispatcher returned an actor with an id property that does not match the actor URI. Set the property with Context.getActorUri(identifier).");
|
|
212
212
|
if (actor instanceof _fedify_vocab.Tombstone) return actor;
|
|
213
|
+
if (portable && actor.id != null) warnPortableActorGateways(actor.id, actor.gateways);
|
|
213
214
|
if (actor.id != null && (0, _fedify_vocab_runtime_internal_portable_dereference.isCompatibleEf61Iri)(actor.id)) warnCompatibleActorId(actor.id, actor.gateway);
|
|
214
215
|
if (portable) this.#warnPortableCollectionIds(context, identifier, actor);
|
|
215
216
|
if (this.followingCallbacks != null && this.followingCallbacks.dispatcher != null) {
|
|
@@ -813,9 +814,28 @@ function warnMismatchedTombstoneId(context, cls, values, tombstone) {
|
|
|
813
814
|
});
|
|
814
815
|
}
|
|
815
816
|
/**
|
|
817
|
+
* Warns about an FEP-ef61 portable actor whose `gateways` is empty or has
|
|
818
|
+
* an item that is not an HTTP(S) origin, which FEP-ef61 does not allow.
|
|
819
|
+
* Every item is checked, since the list and its URLs can be mutated after
|
|
820
|
+
* the actor is constructed.
|
|
821
|
+
*/
|
|
822
|
+
function warnPortableActorGateways(actorId, gateways) {
|
|
823
|
+
if (gateways.length > 0 && gateways.every(_fedify_vocab_runtime.isGatewayUrl)) return;
|
|
824
|
+
(0, _logtape_logtape.getLogger)([
|
|
825
|
+
"fedify",
|
|
826
|
+
"federation",
|
|
827
|
+
"actor"
|
|
828
|
+
]).warn("Actor dispatcher returned an FEP-ef61 portable actor, {actorId}, whose gateways property is empty or has an item that is not an HTTP(S) origin. FEP-ef61 requires a portable actor to have at least one gateway, and every gateway to be an HTTP(S) URI with an empty path, query, and fragment. Set the gateways property.", {
|
|
829
|
+
actorId: actorId.href,
|
|
830
|
+
gateways: gateways.map((g) => g.href)
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
816
834
|
* Warns about an FEP-ef61 portable actor identified by a compatible identifier
|
|
817
835
|
* that is malformed, or is not on the actor's first gateway, where FEP-ef61
|
|
818
|
-
* requires publishers to construct compatible identifiers.
|
|
836
|
+
* requires publishers to construct compatible identifiers. A missing or
|
|
837
|
+
* invalid first gateway is reported by {@link warnPortableActorGateways}
|
|
838
|
+
* instead.
|
|
819
839
|
*/
|
|
820
840
|
function warnCompatibleActorId(actorId, gateway) {
|
|
821
841
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
@@ -833,8 +853,8 @@ function warnCompatibleActorId(actorId, gateway) {
|
|
|
833
853
|
});
|
|
834
854
|
return;
|
|
835
855
|
}
|
|
836
|
-
if (gateway == null || !(0, _fedify_vocab_runtime.isGatewayUrl)(gateway))
|
|
837
|
-
|
|
856
|
+
if (gateway == null || !(0, _fedify_vocab_runtime.isGatewayUrl)(gateway)) return;
|
|
857
|
+
if (actorId.origin !== gateway.origin) logger.warn("Actor dispatcher returned an actor whose id property, {actorId}, is an FEP-ef61 compatible identifier on another gateway than its first gateway, {gateway}. FEP-ef61 requires publishers to construct compatible identifiers with the first gateway in the actor's gateways.", {
|
|
838
858
|
actorId: actorId.href,
|
|
839
859
|
gateway: gateway.origin
|
|
840
860
|
});
|
|
@@ -886,7 +906,7 @@ var CircuitBreaker = class {
|
|
|
886
906
|
};
|
|
887
907
|
let lastConflictingState;
|
|
888
908
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
889
|
-
const oldState = await this.#get(remoteHost);
|
|
909
|
+
const { state: oldState, raw: oldValue } = await this.#get(remoteHost);
|
|
890
910
|
if (oldState == null || oldState.state === "closed") return {
|
|
891
911
|
type: "send",
|
|
892
912
|
probe: false
|
|
@@ -912,7 +932,7 @@ var CircuitBreaker = class {
|
|
|
912
932
|
state: "half-open",
|
|
913
933
|
halfOpened: now.toString()
|
|
914
934
|
};
|
|
915
|
-
if (await this.#replace(remoteHost,
|
|
935
|
+
if (await this.#replace(remoteHost, oldValue, newState)) return {
|
|
916
936
|
type: "send",
|
|
917
937
|
probe: true
|
|
918
938
|
};
|
|
@@ -934,7 +954,7 @@ var CircuitBreaker = class {
|
|
|
934
954
|
state: "half-open",
|
|
935
955
|
halfOpened: now.toString()
|
|
936
956
|
};
|
|
937
|
-
if (await this.#replace(remoteHost,
|
|
957
|
+
if (await this.#replace(remoteHost, oldValue, newState)) {
|
|
938
958
|
await this.#notifyStateChange(remoteHost, "open", "half-open");
|
|
939
959
|
return {
|
|
940
960
|
type: "send",
|
|
@@ -961,9 +981,9 @@ var CircuitBreaker = class {
|
|
|
961
981
|
async recordSuccess(remoteHost) {
|
|
962
982
|
this.#sweepLegacyStates();
|
|
963
983
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
964
|
-
const oldState = await this.#get(remoteHost);
|
|
984
|
+
const { state: oldState, raw: oldValue } = await this.#get(remoteHost);
|
|
965
985
|
if (oldState == null) return void 0;
|
|
966
|
-
if (await this.#replace(remoteHost,
|
|
986
|
+
if (await this.#replace(remoteHost, oldValue, void 0)) {
|
|
967
987
|
if (oldState.state !== "closed") {
|
|
968
988
|
await this.#notifyStateChange(remoteHost, oldState.state, "closed");
|
|
969
989
|
return {
|
|
@@ -983,7 +1003,7 @@ var CircuitBreaker = class {
|
|
|
983
1003
|
this.#sweepLegacyStates();
|
|
984
1004
|
const now = this.#now();
|
|
985
1005
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
986
|
-
const oldState = await this.#get(remoteHost);
|
|
1006
|
+
const { state: oldState, raw: oldValue } = await this.#get(remoteHost);
|
|
987
1007
|
if (oldState?.state === "open") return void 0;
|
|
988
1008
|
const oldFailures = oldState?.failures.map(Temporal$11.Instant.from) ?? [];
|
|
989
1009
|
const failures = this.#options.pruneFailures([...oldFailures, now], now);
|
|
@@ -1000,7 +1020,7 @@ var CircuitBreaker = class {
|
|
|
1000
1020
|
state: "closed",
|
|
1001
1021
|
failures: failures.map((t) => t.toString())
|
|
1002
1022
|
};
|
|
1003
|
-
if (await this.#replace(remoteHost,
|
|
1023
|
+
if (await this.#replace(remoteHost, oldValue, newState)) {
|
|
1004
1024
|
if (transition != null) {
|
|
1005
1025
|
await this.#notifyStateChange(remoteHost, transition[0], transition[1]);
|
|
1006
1026
|
return {
|
|
@@ -1029,7 +1049,7 @@ var CircuitBreaker = class {
|
|
|
1029
1049
|
}
|
|
1030
1050
|
async getState(remoteHost) {
|
|
1031
1051
|
this.#sweepLegacyStates();
|
|
1032
|
-
return stripStoredCircuitBreakerState(await this.#get(remoteHost));
|
|
1052
|
+
return stripStoredCircuitBreakerState((await this.#get(remoteHost)).state);
|
|
1033
1053
|
}
|
|
1034
1054
|
/**
|
|
1035
1055
|
* The currently running background legacy sweep, if any.
|
|
@@ -1149,9 +1169,14 @@ var CircuitBreaker = class {
|
|
|
1149
1169
|
return Temporal$11.Instant.compare(expiresAt, retryAt) < 0 ? expiresAt : retryAt;
|
|
1150
1170
|
}
|
|
1151
1171
|
async #get(remoteHost) {
|
|
1152
|
-
|
|
1172
|
+
const value = await this.#kv.get(this.#key(remoteHost));
|
|
1173
|
+
const state = parseStoredCircuitBreakerKvState(value);
|
|
1174
|
+
return {
|
|
1175
|
+
state,
|
|
1176
|
+
raw: state == null ? void 0 : value
|
|
1177
|
+
};
|
|
1153
1178
|
}
|
|
1154
|
-
async #replace(remoteHost,
|
|
1179
|
+
async #replace(remoteHost, oldValue, newState) {
|
|
1155
1180
|
const key = this.#key(remoteHost);
|
|
1156
1181
|
const storedState = newState == null ? void 0 : markCircuitBreakerState(newState);
|
|
1157
1182
|
if (this.#kv.cas == null) {
|
|
@@ -1159,7 +1184,7 @@ var CircuitBreaker = class {
|
|
|
1159
1184
|
else await this.#kv.set(key, storedState, this.#setOptions());
|
|
1160
1185
|
return true;
|
|
1161
1186
|
}
|
|
1162
|
-
return await this.#kv.cas(key,
|
|
1187
|
+
return await this.#kv.cas(key, oldValue, storedState, storedState == null ? void 0 : this.#setOptions());
|
|
1163
1188
|
}
|
|
1164
1189
|
#setOptions() {
|
|
1165
1190
|
return this.#options.stateTtl == null ? void 0 : { ttl: this.#options.stateTtl };
|
|
@@ -3787,7 +3812,7 @@ function isInvalidJsonLdError(error) {
|
|
|
3787
3812
|
return name === "UnsafeJsonLdError" || error instanceof require_http.InvalidContextReferenceError || isPermanentRemoteContextError$1(error) || name === "jsonld.SyntaxError" && !isRemoteContextLoadingFailure$1(error);
|
|
3788
3813
|
}
|
|
3789
3814
|
function isValidationTypeError(error) {
|
|
3790
|
-
return error instanceof TypeError && (/^(Invalid JSON-LD:|Invalid type:|Unexpected type:|Invalid @id:)/.test(error.message) || require_http.isInvalidUrlTypeError(error));
|
|
3815
|
+
return error instanceof TypeError && (/^(Invalid JSON-LD:|Invalid type:|Unexpected type:|Invalid @id:|Invalid FEP-ef61 gateway:)/.test(error.message) || require_http.isInvalidUrlTypeError(error));
|
|
3791
3816
|
}
|
|
3792
3817
|
function isPermanentActivityParseError(error) {
|
|
3793
3818
|
return isInvalidJsonLdError(error) || isValidationTypeError(error);
|
|
@@ -3930,7 +3955,11 @@ async function handlePortableObject(request, { values, context, objectDispatcher
|
|
|
3930
3955
|
return await onNotFound(request);
|
|
3931
3956
|
}
|
|
3932
3957
|
if (tombstone || result.reason.type !== "unsecuredCollection" && result.reason.type !== "unsupportedObjectType") {
|
|
3933
|
-
logger.error("Refusing to serve the portable
|
|
3958
|
+
if (result.reason.type === "invalidGateways") logger.error("Refusing to serve the portable actor {portableId}, as its gateways property is missing, empty, or has an item that is not an HTTP(S) origin. FEP-ef61 requires a portable actor to list at least one gateway where it can be retrieved.", {
|
|
3959
|
+
portableId: canonicalId,
|
|
3960
|
+
reason: result.reason.type
|
|
3961
|
+
});
|
|
3962
|
+
else logger.error("Refusing to serve the portable object {portableId}, as it does not satisfy the FEP-ef61 proof policy: {reason}. Portable actors, activities, objects, and tombstones need an Object Integrity Proof made with a key of the DID in their ID.", {
|
|
3934
3963
|
portableId: canonicalId,
|
|
3935
3964
|
reason: result.reason.type
|
|
3936
3965
|
});
|
|
@@ -4049,13 +4078,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
|
|
|
4049
4078
|
* @param parameters The parameters for handling the collection.
|
|
4050
4079
|
* @returns A promise that resolves to an HTTP response.
|
|
4051
4080
|
*/
|
|
4052
|
-
async function handleCollection(request, { name: name$
|
|
4053
|
-
const spanName = name$
|
|
4081
|
+
async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, portable, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
|
|
4082
|
+
const spanName = name$2.trim().replace(/\s+/g, "_");
|
|
4054
4083
|
tracerProvider = tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
4055
4084
|
const tracer = tracerProvider.getTracer(require_http.name, require_http.version);
|
|
4056
4085
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
4057
4086
|
const metricBase = {
|
|
4058
|
-
kind: getCollectionMetricKind(name$
|
|
4087
|
+
kind: getCollectionMetricKind(name$2),
|
|
4059
4088
|
page: cursor != null,
|
|
4060
4089
|
dispatcher: "built_in"
|
|
4061
4090
|
};
|
|
@@ -4101,7 +4130,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
|
|
|
4101
4130
|
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
4102
4131
|
return await onNotFound(request);
|
|
4103
4132
|
}
|
|
4104
|
-
const items = filterCollectionItems(page.items, name$
|
|
4133
|
+
const items = filterCollectionItems(page.items, name$2, filterPredicate);
|
|
4105
4134
|
itemCount = items.length;
|
|
4106
4135
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
4107
4136
|
return items;
|
|
@@ -4143,7 +4172,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
|
|
|
4143
4172
|
} else {
|
|
4144
4173
|
const uri = new URL(portable == null ? baseUri : pageBase);
|
|
4145
4174
|
uri.searchParams.set("cursor", cursor);
|
|
4146
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$
|
|
4175
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
|
|
4147
4176
|
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
4148
4177
|
attributes: {
|
|
4149
4178
|
"activitypub.collection.id": uri.href,
|
|
@@ -4159,7 +4188,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
|
|
|
4159
4188
|
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
4160
4189
|
return await onNotFound(request);
|
|
4161
4190
|
}
|
|
4162
|
-
const items = filterCollectionItems(page.items, name$
|
|
4191
|
+
const items = filterCollectionItems(page.items, name$2, filterPredicate);
|
|
4163
4192
|
itemCount = items.length;
|
|
4164
4193
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
4165
4194
|
return {
|
|
@@ -4667,7 +4696,7 @@ async function handleInbox(request, options) {
|
|
|
4667
4696
|
* @returns A promise that resolves to an HTTP response.
|
|
4668
4697
|
*/
|
|
4669
4698
|
async function handleInboxInternal(request, parameters, span) {
|
|
4670
|
-
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, publicKeyTtl, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, inboxChallengePolicy, meterProvider, tracerProvider, portableInbox } = parameters;
|
|
4699
|
+
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, publicKeyTtl, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, maxHttpSignatures, skipSignatureVerification, inboxChallengePolicy, meterProvider, tracerProvider, portableInbox } = parameters;
|
|
4671
4700
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
4672
4701
|
"fedify",
|
|
4673
4702
|
"federation",
|
|
@@ -4953,6 +4982,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
4953
4982
|
contextLoader: ctx.contextLoader,
|
|
4954
4983
|
documentLoader: ctx.documentLoader,
|
|
4955
4984
|
timeWindow: signatureTimeWindow,
|
|
4985
|
+
maxSignatures: maxHttpSignatures,
|
|
4956
4986
|
keyCache,
|
|
4957
4987
|
meterProvider,
|
|
4958
4988
|
tracerProvider
|
|
@@ -5175,7 +5205,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
5175
5205
|
inbox: portableInbox.recipient.canonicalInboxId
|
|
5176
5206
|
});
|
|
5177
5207
|
else try {
|
|
5178
|
-
await portableInbox.forward(json, activity.id, (0, _fedify_vocab.getTypeId)(activity).href, require_http.listRequestSignatures(request).map((signature) => ({
|
|
5208
|
+
await portableInbox.forward(json, activity.id, (0, _fedify_vocab.getTypeId)(activity).href, require_http.listRequestSignatures(request, maxHttpSignatures).map((signature) => ({
|
|
5179
5209
|
keyId: signature.keyId,
|
|
5180
5210
|
coversDelivery: coversDelivery(signature),
|
|
5181
5211
|
verify: async () => {
|
|
@@ -5349,8 +5379,8 @@ var CustomCollectionHandler = class {
|
|
|
5349
5379
|
* @param CollectionPage The CollectionPage constructor.
|
|
5350
5380
|
* @param filterPredicate Optional filter predicate for items.
|
|
5351
5381
|
*/
|
|
5352
|
-
constructor(name$
|
|
5353
|
-
this.name = name$
|
|
5382
|
+
constructor(name$1, values, context, callbacks, tracerProvider = _opentelemetry_api.trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate, portable) {
|
|
5383
|
+
this.name = name$1;
|
|
5354
5384
|
this.values = values;
|
|
5355
5385
|
this.context = context;
|
|
5356
5386
|
this.callbacks = callbacks;
|
|
@@ -7229,7 +7259,7 @@ function isPermanentRemoteContextError(error) {
|
|
|
7229
7259
|
return isRemoteContextLoadingFailure(error) && typeof details?.url === "string" && !URL.canParse(details.url) && require_http.isClearlyMalformedContextReference(details.url);
|
|
7230
7260
|
}
|
|
7231
7261
|
function isPermanentInboxParseError(error) {
|
|
7232
|
-
return error instanceof Error && (error.name === "UnsafeJsonLdError" || error instanceof require_http.InvalidContextReferenceError || isPermanentRemoteContextError(error) || error.name === "jsonld.SyntaxError" && !isRemoteContextLoadingFailure(error)) || error instanceof TypeError && (/^(Invalid JSON-LD:|Invalid type:|Unexpected type:|Invalid @id:)/.test(error.message) || require_http.isInvalidUrlTypeError(error));
|
|
7262
|
+
return error instanceof Error && (error.name === "UnsafeJsonLdError" || error instanceof require_http.InvalidContextReferenceError || isPermanentRemoteContextError(error) || error.name === "jsonld.SyntaxError" && !isRemoteContextLoadingFailure(error)) || error instanceof TypeError && (/^(Invalid JSON-LD:|Invalid type:|Unexpected type:|Invalid @id:|Invalid FEP-ef61 gateway:)/.test(error.message) || require_http.isInvalidUrlTypeError(error));
|
|
7233
7263
|
}
|
|
7234
7264
|
function hasLinkedDataSignatureJsonLdProcessingError(error) {
|
|
7235
7265
|
if (error.message.startsWith("Maximum deep iterations exceeded")) return true;
|
|
@@ -7246,6 +7276,8 @@ function isLinkedDataSignatureJsonLdProcessingError(error) {
|
|
|
7246
7276
|
* @returns A new {@link Federation} instance.
|
|
7247
7277
|
* @throws {TypeError} If benchmark mode and `meterProvider` are both
|
|
7248
7278
|
* specified.
|
|
7279
|
+
* @throws {RangeError} If {@link FederationOptions.maxHttpSignatures} is not
|
|
7280
|
+
* a positive integer or `Infinity`.
|
|
7249
7281
|
* @since 0.10.0
|
|
7250
7282
|
*/
|
|
7251
7283
|
function createFederation(options) {
|
|
@@ -7272,6 +7304,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
7272
7304
|
onOutboxError;
|
|
7273
7305
|
permanentFailureStatusCodes;
|
|
7274
7306
|
signatureTimeWindow;
|
|
7307
|
+
maxHttpSignatures;
|
|
7275
7308
|
skipSignatureVerification;
|
|
7276
7309
|
outboxRetryPolicy;
|
|
7277
7310
|
inboxRetryPolicy;
|
|
@@ -7300,6 +7333,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
7300
7333
|
const hasCustomLoaderFactory = options.documentLoaderFactory != null || options.contextLoaderFactory != null;
|
|
7301
7334
|
const allowPrivateAddress = options.allowPrivateAddress ?? (benchmarkMode && !hasCustomLoaderFactory ? true : false);
|
|
7302
7335
|
const signatureTimeWindow = options.signatureTimeWindow ?? (benchmarkMode ? false : { hours: 1 });
|
|
7336
|
+
if (options.maxHttpSignatures !== void 0) require_http.validateMaxSignatures(options.maxHttpSignatures, "maxHttpSignatures");
|
|
7303
7337
|
if (benchmarkMode && options.meterProvider != null) throw new TypeError("benchmarkMode requires Fedify to own the meterProvider; OpenTelemetry metric readers cannot be added after a MeterProvider is constructed.");
|
|
7304
7338
|
if (benchmarkMode) {
|
|
7305
7339
|
const relaxations = getBenchmarkRelaxations(allowPrivateAddress, signatureTimeWindow);
|
|
@@ -7392,13 +7426,15 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
7392
7426
|
}
|
|
7393
7427
|
const { userAgent } = options;
|
|
7394
7428
|
this.allowPrivateAddress = allowPrivateAddress;
|
|
7429
|
+
const documentLoaderTimeout = (0, _fedify_vocab_runtime.resolveDocumentLoaderTimeout)(options.documentLoaderTimeout == null ? options.documentLoaderTimeout : Temporal$2.Duration.from(options.documentLoaderTimeout).total("millisecond"));
|
|
7395
7430
|
const userDocumentLoaderFactory = options.documentLoaderFactory;
|
|
7396
7431
|
const userContextLoaderFactory = options.contextLoaderFactory;
|
|
7397
7432
|
const userAuthFactory = options.authenticatedDocumentLoaderFactory;
|
|
7398
7433
|
const builtinDocumentLoaderFactory = (opts) => require_kv_cache.kvCache({
|
|
7399
7434
|
loader: (0, _fedify_vocab_runtime.getDocumentLoader)({
|
|
7400
7435
|
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
7401
|
-
userAgent: opts?.userAgent ?? userAgent
|
|
7436
|
+
userAgent: opts?.userAgent ?? userAgent,
|
|
7437
|
+
timeout: opts?.timeout !== void 0 ? opts.timeout : documentLoaderTimeout
|
|
7402
7438
|
}),
|
|
7403
7439
|
kv: options.kv,
|
|
7404
7440
|
prefix: this.kvPrefixes.remoteDocument,
|
|
@@ -7408,7 +7444,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
7408
7444
|
const builtinContextLoaderFactory = (opts) => require_kv_cache.kvCache({
|
|
7409
7445
|
loader: (0, _fedify_vocab_runtime.getDocumentLoader)({
|
|
7410
7446
|
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
7411
|
-
userAgent: opts?.userAgent ?? userAgent
|
|
7447
|
+
userAgent: opts?.userAgent ?? userAgent,
|
|
7448
|
+
timeout: opts?.timeout !== void 0 ? opts.timeout : documentLoaderTimeout
|
|
7412
7449
|
}),
|
|
7413
7450
|
kv: options.kv,
|
|
7414
7451
|
prefix: this.kvPrefixes.remoteDocument,
|
|
@@ -7429,6 +7466,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
7429
7466
|
this.authenticatedDocumentLoaderFactory = (identity, factoryOpts) => require_http.instrumentDocumentLoader(userAuthFactory != null ? userAuthFactory(identity, factoryOpts) : require_kv_cache.getAuthenticatedDocumentLoader(identity, {
|
|
7430
7467
|
allowPrivateAddress: factoryOpts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
7431
7468
|
userAgent: factoryOpts?.userAgent ?? userAgent,
|
|
7469
|
+
timeout: factoryOpts?.timeout !== void 0 ? factoryOpts.timeout : documentLoaderTimeout,
|
|
7432
7470
|
specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, options.firstKnock, { specTtl: this.httpMessageSignaturesSpecTtl }),
|
|
7433
7471
|
tracerProvider: this.tracerProvider
|
|
7434
7472
|
}), {
|
|
@@ -7440,6 +7478,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
7440
7478
|
this.onOutboxError = options.onOutboxError;
|
|
7441
7479
|
this.permanentFailureStatusCodes = options.permanentFailureStatusCodes ?? [404, 410];
|
|
7442
7480
|
this.signatureTimeWindow = signatureTimeWindow;
|
|
7481
|
+
this.maxHttpSignatures = options.maxHttpSignatures ?? 3;
|
|
7443
7482
|
this.skipSignatureVerification = options.skipSignatureVerification ?? false;
|
|
7444
7483
|
this.inboxChallengePolicy = options.inboxChallengePolicy;
|
|
7445
7484
|
this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy();
|
|
@@ -9065,6 +9104,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
9065
9104
|
unverifiedActivityHandler: this.unverifiedActivityHandler,
|
|
9066
9105
|
onNotFound,
|
|
9067
9106
|
signatureTimeWindow: this.signatureTimeWindow,
|
|
9107
|
+
maxHttpSignatures: this.maxHttpSignatures,
|
|
9068
9108
|
skipSignatureVerification: this.skipSignatureVerification,
|
|
9069
9109
|
inboxChallengePolicy: this.inboxChallengePolicy,
|
|
9070
9110
|
meterProvider: this.meterProvider,
|
|
@@ -10053,7 +10093,7 @@ var ContextImpl = class ContextImpl {
|
|
|
10053
10093
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
10054
10094
|
});
|
|
10055
10095
|
return false;
|
|
10056
|
-
} else if (fetched.id
|
|
10096
|
+
} else if (fetched.id == null || !require_http.isSameObjectId(fetched.id, activity.id)) {
|
|
10057
10097
|
logger.debug("Fetched activity object has a different ID; failed to verify.", {
|
|
10058
10098
|
recipient,
|
|
10059
10099
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
@@ -10066,8 +10106,8 @@ var ContextImpl = class ContextImpl {
|
|
|
10066
10106
|
});
|
|
10067
10107
|
return false;
|
|
10068
10108
|
}
|
|
10069
|
-
const
|
|
10070
|
-
if (!fetched.actorIds.every((actor) => actor
|
|
10109
|
+
const activityOrigin = require_http.getAuthenticationOrigin(fetched.id);
|
|
10110
|
+
if (activityOrigin == null || !fetched.actorIds.every((actor) => require_http.getAuthenticationOrigin(actor) === activityOrigin)) {
|
|
10071
10111
|
logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
|
|
10072
10112
|
recipient,
|
|
10073
10113
|
activity: await fetched.toJsonLd({ contextLoader })
|
|
@@ -10203,6 +10243,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
|
|
|
10203
10243
|
contextLoader: options.contextLoader ?? this.contextLoader,
|
|
10204
10244
|
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
10205
10245
|
timeWindow: this.federation.signatureTimeWindow,
|
|
10246
|
+
maxSignatures: this.federation.maxHttpSignatures,
|
|
10206
10247
|
meterProvider: this.meterProvider,
|
|
10207
10248
|
tracerProvider: options.tracerProvider ?? this.tracerProvider
|
|
10208
10249
|
});
|