@fedify/fedify 2.0.28-dev.1974 → 2.0.28-dev.1982
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_instance_of-C4Ri6VuN.mjs → assert-BhQd8QHP.mjs} +19 -1
- package/dist/{builder-DBKy92BX.mjs → builder-DG5rS_Zv.mjs} +3 -3
- package/dist/{client-HLLGHiTU.mjs → client-glFHmpn4.mjs} +78 -4
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +3 -4
- package/dist/{context-DnsFj3yK.d.ts → context-B21klrfz.d.ts} +4 -3
- package/dist/{context-CJZHWLmz.d.cts → context-M_MxoQgC.d.cts} +4 -3
- package/dist/{deno-CGtm12Ft.mjs → deno-eqaJj6JL.mjs} +1 -1
- package/dist/{docloader-_hXTUC-b.mjs → docloader-BXUqhXNd.mjs} +2 -2
- package/dist/federation/builder.test.mjs +2 -2
- package/dist/federation/collection.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +125 -8
- package/dist/federation/idempotency.test.mjs +4 -4
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/keycache.test.mjs +44 -10
- package/dist/federation/kv.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +99 -11
- 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/mq.test.mjs +1 -1
- package/dist/federation/negotiation.test.mjs +2 -2
- package/dist/federation/retry.test.mjs +1 -1
- package/dist/federation/router.test.mjs +1 -1
- package/dist/federation/send.test.mjs +138 -6
- package/dist/federation/temporal.test.mjs +2 -2
- package/dist/federation/webfinger.test.mjs +2 -2
- package/dist/{http-BuaGj55w.cjs → http-BgOlx4n1.cjs} +163 -3
- package/dist/{http-C4D0ajx0.d.ts → http-Bs6thuCC.d.cts} +2 -2
- package/dist/{http--P33qRwW.mjs → http-Bu3NxfGb.mjs} +2 -2
- package/dist/{http-RYvZHWMc.d.cts → http-CDupyfOc.d.ts} +2 -2
- package/dist/{http-BP1pVF9m.js → http-CwcG2wDs.js} +152 -4
- package/dist/{inbox-BZNyUPzW.mjs → inbox-Hou2ZAjv.mjs} +1 -1
- package/dist/{key-rC9mW1U5.mjs → key-bSphUqhB.mjs} +152 -4
- package/dist/{keycache-DaQ3ndaJ.mjs → keycache-D239uGT9.mjs} +12 -4
- package/dist/{kv-cache-BVqMp1RC.cjs → kv-cache-B8GaLaNy.cjs} +1 -1
- package/dist/{kv-cache-CKg5W012.js → kv-cache-lbswb9pg.js} +1 -1
- package/dist/{ld-CN2nacLy.mjs → ld-D0uFMLmq.mjs} +2 -2
- package/dist/{middleware-DcmlYd2c.cjs → middleware-BKpP3cnZ.cjs} +1 -1
- package/dist/{middleware-DpEJSmjy.mjs → middleware-BuVM1K-J.mjs} +30 -19
- package/dist/{middleware-sbzAVAzo.mjs → middleware-DXPBIbm6.mjs} +1 -1
- package/dist/{middleware-BXwn4gnl.cjs → middleware-D_7wZH27.cjs} +90 -14
- package/dist/{middleware-CwIT91Nc.js → middleware-DomxFoLd.js} +90 -14
- package/dist/{mod-B2zB0rDg.d.cts → mod-Bt0eg_Lv.d.cts} +1 -1
- package/dist/{mod-COgmn-UO.d.ts → mod-D24V_w-K.d.ts} +1 -1
- package/dist/{mod-43DJyETz.d.cts → mod-Dp5dfH-i.d.cts} +1 -1
- package/dist/{mod-CiQNNAQL.d.ts → mod-E7YM72JZ.d.ts} +1 -1
- package/dist/{mod-CB6pc2pw.d.cts → mod-IOWUF5Yr.d.cts} +1 -1
- package/dist/{mod-CD1youdZ.d.ts → mod-XucBiDNd.d.ts} +1 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +6 -6
- package/dist/mod.d.ts +6 -6
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +28 -1
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/nodeinfo/types.test.mjs +1 -1
- package/dist/otel/exporter.test.mjs +1 -1
- package/dist/{owner-DEvZuyOE.d.cts → owner-B3hNQCG8.d.cts} +11 -0
- package/dist/owner-Bzg6w7eA.mjs +175 -0
- package/dist/{owner-CnngXDNJ.d.ts → owner-CiBPcC6F.d.ts} +11 -0
- package/dist/{proof-CpEH24hi.mjs → proof-CgLA51pO.mjs} +2 -2
- package/dist/{proof-ftbx50PI.js → proof-DsJHFTkx.js} +112 -58
- package/dist/{proof-BTKH7fe9.cjs → proof-xCEe8t7U.cjs} +112 -58
- package/dist/{send-pXXMu19o.mjs → send-D89-FDX-.mjs} +64 -6
- package/dist/sig/http.test.mjs +4 -4
- package/dist/sig/key.test.mjs +169 -2
- package/dist/sig/ld.test.mjs +56 -4
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +105 -6
- package/dist/sig/proof.test.mjs +72 -3
- package/dist/{temporal-B4rBDksp.mjs → temporal-DPJlkHh3.mjs} +1 -1
- package/dist/{types-m8u9L86X.cjs → types-DWs-qZaY.cjs} +94 -2
- package/dist/{types-DTONwNqL.js → types-sXITXcWa.js} +78 -4
- package/dist/utils/docloader.test.mjs +28 -4
- 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 +5 -5
- package/dist/assert-ddO5KLpe.mjs +0 -23
- package/dist/owner-CFgyZgkz.mjs +0 -120
- /package/dist/{collection-ChgDTHLz.mjs → collection-DI6YzYpd.mjs} +0 -0
- /package/dist/{keys-CtZLJq76.mjs → keys-CCxRJhWa.mjs} +0 -0
- /package/dist/{kv-cache-DqEKe5E0.mjs → kv-cache-BrjuJue8.mjs} +0 -0
- /package/dist/{kv-BrZHNugx.mjs → kv-mI4Ix2EU.mjs} +0 -0
- /package/dist/{negotiation-BehA2uul.mjs → negotiation-TWEs6Cl8.mjs} +0 -0
- /package/dist/{retry-B_E3V_Dx.mjs → retry-Ddbq3AcK.mjs} +0 -0
- /package/dist/{types-C37hquWI.mjs → types-MNlFfxjv.mjs} +0 -0
|
@@ -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-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const require_kv_cache = require("./kv-cache-
|
|
5
|
+
const require_http = require("./http-BgOlx4n1.cjs");
|
|
6
|
+
const require_types = require("./types-DWs-qZaY.cjs");
|
|
7
|
+
const require_proof = require("./proof-xCEe8t7U.cjs");
|
|
8
|
+
const require_kv_cache = require("./kv-cache-B8GaLaNy.cjs");
|
|
9
9
|
let _logtape_logtape = require("@logtape/logtape");
|
|
10
10
|
let _fedify_vocab = require("@fedify/vocab");
|
|
11
11
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -335,7 +335,7 @@ var FederationBuilderImpl = class {
|
|
|
335
335
|
this.collectionTypeIds = {};
|
|
336
336
|
}
|
|
337
337
|
async build(options) {
|
|
338
|
-
const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-
|
|
338
|
+
const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-BKpP3cnZ.cjs"));
|
|
339
339
|
const f = new FederationImpl(options);
|
|
340
340
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
341
341
|
f.router = this.router.clone();
|
|
@@ -858,6 +858,7 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
|
|
|
858
858
|
//#region src/federation/keycache.ts
|
|
859
859
|
const NULL_KEY_CACHE_VALUE = { _fedify: "key-unavailable" };
|
|
860
860
|
const NULL_KEY_CACHE_TTL = Temporal.Duration.from({ minutes: 5 });
|
|
861
|
+
const KEY_CACHE_GENERATION = "2";
|
|
861
862
|
function isNullKeyCacheValue(value) {
|
|
862
863
|
return typeof value === "object" && value != null && "_fedify" in value && value._fedify === NULL_KEY_CACHE_VALUE._fedify;
|
|
863
864
|
}
|
|
@@ -872,9 +873,16 @@ var KvKeyCache = class {
|
|
|
872
873
|
this.nullKeys = /* @__PURE__ */ new Set();
|
|
873
874
|
this.options = options;
|
|
874
875
|
}
|
|
876
|
+
#entryKey(keyId) {
|
|
877
|
+
return [
|
|
878
|
+
...this.prefix,
|
|
879
|
+
KEY_CACHE_GENERATION,
|
|
880
|
+
keyId.href
|
|
881
|
+
];
|
|
882
|
+
}
|
|
875
883
|
async get(keyId) {
|
|
876
884
|
if (this.nullKeys.has(keyId.href)) return null;
|
|
877
|
-
const serialized = await this.kv.get(
|
|
885
|
+
const serialized = await this.kv.get(this.#entryKey(keyId));
|
|
878
886
|
if (serialized == null) return void 0;
|
|
879
887
|
if (isNullKeyCacheValue(serialized)) {
|
|
880
888
|
this.nullKeys.add(keyId.href);
|
|
@@ -886,7 +894,7 @@ var KvKeyCache = class {
|
|
|
886
894
|
try {
|
|
887
895
|
return await _fedify_vocab.Multikey.fromJsonLd(serialized, this.options);
|
|
888
896
|
} catch {
|
|
889
|
-
await this.kv.delete(
|
|
897
|
+
await this.kv.delete(this.#entryKey(keyId));
|
|
890
898
|
return;
|
|
891
899
|
}
|
|
892
900
|
}
|
|
@@ -894,12 +902,12 @@ var KvKeyCache = class {
|
|
|
894
902
|
async set(keyId, key) {
|
|
895
903
|
if (key == null) {
|
|
896
904
|
this.nullKeys.add(keyId.href);
|
|
897
|
-
await this.kv.set(
|
|
905
|
+
await this.kv.set(this.#entryKey(keyId), NULL_KEY_CACHE_VALUE, { ttl: NULL_KEY_CACHE_TTL });
|
|
898
906
|
return;
|
|
899
907
|
}
|
|
900
908
|
this.nullKeys.delete(keyId.href);
|
|
901
909
|
const serialized = await key.toJsonLd(this.options);
|
|
902
|
-
await this.kv.set(
|
|
910
|
+
await this.kv.set(this.#entryKey(keyId), serialized);
|
|
903
911
|
}
|
|
904
912
|
};
|
|
905
913
|
//#endregion
|
|
@@ -1377,8 +1385,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1377
1385
|
}
|
|
1378
1386
|
let json;
|
|
1379
1387
|
try {
|
|
1380
|
-
json = await request.clone().
|
|
1388
|
+
json = JSON.parse(await require_types.readBoundedText(request.clone(), require_types.MAX_BODY_SIZE, request.url));
|
|
1381
1389
|
} catch (error) {
|
|
1390
|
+
if (error instanceof require_types.BodyTooLargeError) {
|
|
1391
|
+
request.body?.cancel(error).catch(() => {});
|
|
1392
|
+
span.setStatus({
|
|
1393
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
1394
|
+
message: String(error)
|
|
1395
|
+
});
|
|
1396
|
+
return new Response("Inbox body too large.", { status: 413 });
|
|
1397
|
+
}
|
|
1382
1398
|
logger.error("Failed to parse JSON:\n{error}", {
|
|
1383
1399
|
recipient,
|
|
1384
1400
|
error
|
|
@@ -2250,18 +2266,31 @@ async function readLimitedResponseBody(response, maxBytes) {
|
|
|
2250
2266
|
if (truncated) result += "… (truncated)";
|
|
2251
2267
|
return result;
|
|
2252
2268
|
}
|
|
2253
|
-
async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }, span) {
|
|
2269
|
+
async function sendActivityInternal({ activity, activityId, keys, inbox, allowPrivateAddress, headers, specDeterminer, tracerProvider }, span) {
|
|
2254
2270
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
2255
2271
|
"fedify",
|
|
2256
2272
|
"federation",
|
|
2257
2273
|
"outbox"
|
|
2258
2274
|
]);
|
|
2275
|
+
async function validateUrl(url) {
|
|
2276
|
+
if (!allowPrivateAddress) try {
|
|
2277
|
+
await (0, _fedify_vocab_runtime.validatePublicUrl)(url);
|
|
2278
|
+
} catch (error) {
|
|
2279
|
+
if (error instanceof _fedify_vocab_runtime.UrlError) logger.error("Disallowed private URL: {url}", {
|
|
2280
|
+
url,
|
|
2281
|
+
error
|
|
2282
|
+
});
|
|
2283
|
+
throw error;
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
await validateUrl(inbox.href);
|
|
2259
2287
|
headers = new Headers(headers);
|
|
2260
2288
|
headers.set("Content-Type", "application/activity+json");
|
|
2261
2289
|
const request = new Request(inbox, {
|
|
2262
2290
|
method: "POST",
|
|
2263
2291
|
headers,
|
|
2264
|
-
body: JSON.stringify(activity)
|
|
2292
|
+
body: JSON.stringify(activity),
|
|
2293
|
+
redirect: "manual"
|
|
2265
2294
|
});
|
|
2266
2295
|
let rsaKey = null;
|
|
2267
2296
|
for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
|
@@ -2277,9 +2306,10 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2277
2306
|
});
|
|
2278
2307
|
let response;
|
|
2279
2308
|
try {
|
|
2280
|
-
response = rsaKey == null ? await
|
|
2309
|
+
response = rsaKey == null ? await fetchWithValidatedRedirects(request, validateUrl) : await require_http.doubleKnock(request, rsaKey, {
|
|
2281
2310
|
tracerProvider,
|
|
2282
|
-
specDeterminer
|
|
2311
|
+
specDeterminer,
|
|
2312
|
+
validateRedirect: validateUrl
|
|
2283
2313
|
});
|
|
2284
2314
|
} catch (error) {
|
|
2285
2315
|
logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
|
|
@@ -2311,6 +2341,49 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2311
2341
|
"activitypub.activity.id": activityId ?? ""
|
|
2312
2342
|
});
|
|
2313
2343
|
}
|
|
2344
|
+
async function fetchWithValidatedRedirects(request, validateUrl) {
|
|
2345
|
+
let body = await request.clone().text();
|
|
2346
|
+
for (let redirects = 0;; redirects++) {
|
|
2347
|
+
const response = await fetch(request, { redirect: "manual" });
|
|
2348
|
+
const location = response.headers.get("Location");
|
|
2349
|
+
if (![
|
|
2350
|
+
301,
|
|
2351
|
+
302,
|
|
2352
|
+
303,
|
|
2353
|
+
307,
|
|
2354
|
+
308
|
|
2355
|
+
].includes(response.status) || location == null) return response;
|
|
2356
|
+
await response.body?.cancel();
|
|
2357
|
+
if (redirects >= 20) throw new TypeError("Too many redirects");
|
|
2358
|
+
const url = new URL(location, request.url);
|
|
2359
|
+
await validateUrl(url.href);
|
|
2360
|
+
const headers = new Headers(request.headers);
|
|
2361
|
+
if (url.origin !== new URL(request.url).origin) {
|
|
2362
|
+
headers.delete("Authorization");
|
|
2363
|
+
headers.delete("Proxy-Authorization");
|
|
2364
|
+
headers.delete("Cookie");
|
|
2365
|
+
headers.delete("Host");
|
|
2366
|
+
}
|
|
2367
|
+
let method = request.method;
|
|
2368
|
+
if ((response.status === 301 || response.status === 302) && method === "POST" || response.status === 303 && method !== "GET" && method !== "HEAD") {
|
|
2369
|
+
method = "GET";
|
|
2370
|
+
body = void 0;
|
|
2371
|
+
for (const name of [
|
|
2372
|
+
"Content-Encoding",
|
|
2373
|
+
"Content-Language",
|
|
2374
|
+
"Content-Length",
|
|
2375
|
+
"Content-Location",
|
|
2376
|
+
"Content-Type"
|
|
2377
|
+
]) headers.delete(name);
|
|
2378
|
+
}
|
|
2379
|
+
request = new Request(url, {
|
|
2380
|
+
method,
|
|
2381
|
+
headers,
|
|
2382
|
+
body,
|
|
2383
|
+
redirect: "manual"
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2314
2387
|
/**
|
|
2315
2388
|
* An error that is thrown when an activity fails to send to a remote inbox.
|
|
2316
2389
|
* It contains structured information about the failure, including the HTTP
|
|
@@ -2809,6 +2882,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2809
2882
|
}
|
|
2810
2883
|
try {
|
|
2811
2884
|
await sendActivity({
|
|
2885
|
+
allowPrivateAddress: this.allowPrivateAddress,
|
|
2812
2886
|
keys,
|
|
2813
2887
|
activity: message.activity,
|
|
2814
2888
|
activityId: message.activityId,
|
|
@@ -3200,6 +3274,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3200
3274
|
});
|
|
3201
3275
|
const promises = [];
|
|
3202
3276
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
3277
|
+
allowPrivateAddress: this.allowPrivateAddress,
|
|
3203
3278
|
keys,
|
|
3204
3279
|
activity: jsonLd,
|
|
3205
3280
|
activityId: activity.id?.href,
|
|
@@ -4340,6 +4415,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4340
4415
|
else logger.debug("Forwarding activity immediately without queue since queue is not set.");
|
|
4341
4416
|
const promises = [];
|
|
4342
4417
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
4418
|
+
allowPrivateAddress: this.federation.allowPrivateAddress,
|
|
4343
4419
|
keys,
|
|
4344
4420
|
activity: this.activity,
|
|
4345
4421
|
activityId: this.activityId,
|
|
@@ -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 { c as
|
|
6
|
-
import {
|
|
7
|
-
import { n as
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
5
|
+
import { c as importJwk, d as name, f as version, i as exportJwk, l as validateCryptoKey, r as verifyRequest, t as doubleKnock } from "./http-CwcG2wDs.js";
|
|
6
|
+
import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-sXITXcWa.js";
|
|
7
|
+
import { _ as signJsonLd, a as doesActorOwnKey, c as assertSafeJsonLd, f as detachSignature, g as isInvalidUrlTypeError, h as isClearlyMalformedContextReference, m as hasSignature, n as signObject, o as getKeyOwner, p as getNormalizationContextLoader, r as verifyObject, s as InvalidContextReferenceError, u as compactJsonLd, v as verifyCompactJsonLd, x as wrapContextLoaderForJsonLd } from "./proof-DsJHFTkx.js";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-lbswb9pg.js";
|
|
9
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
10
10
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
11
11
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
@@ -13,7 +13,7 @@ import { cloneDeep } from "es-toolkit";
|
|
|
13
13
|
import { Router } from "uri-template-router";
|
|
14
14
|
import { parseTemplate } from "url-template";
|
|
15
15
|
import { encodeHex } from "byte-encodings/hex";
|
|
16
|
-
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
16
|
+
import { UrlError, getDocumentLoader, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
17
17
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
18
18
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
19
19
|
import { lookupWebFinger } from "@fedify/webfinger";
|
|
@@ -857,6 +857,7 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
|
|
|
857
857
|
//#region src/federation/keycache.ts
|
|
858
858
|
const NULL_KEY_CACHE_VALUE = { _fedify: "key-unavailable" };
|
|
859
859
|
const NULL_KEY_CACHE_TTL = Temporal.Duration.from({ minutes: 5 });
|
|
860
|
+
const KEY_CACHE_GENERATION = "2";
|
|
860
861
|
function isNullKeyCacheValue(value) {
|
|
861
862
|
return typeof value === "object" && value != null && "_fedify" in value && value._fedify === NULL_KEY_CACHE_VALUE._fedify;
|
|
862
863
|
}
|
|
@@ -871,9 +872,16 @@ var KvKeyCache = class {
|
|
|
871
872
|
this.nullKeys = /* @__PURE__ */ new Set();
|
|
872
873
|
this.options = options;
|
|
873
874
|
}
|
|
875
|
+
#entryKey(keyId) {
|
|
876
|
+
return [
|
|
877
|
+
...this.prefix,
|
|
878
|
+
KEY_CACHE_GENERATION,
|
|
879
|
+
keyId.href
|
|
880
|
+
];
|
|
881
|
+
}
|
|
874
882
|
async get(keyId) {
|
|
875
883
|
if (this.nullKeys.has(keyId.href)) return null;
|
|
876
|
-
const serialized = await this.kv.get(
|
|
884
|
+
const serialized = await this.kv.get(this.#entryKey(keyId));
|
|
877
885
|
if (serialized == null) return void 0;
|
|
878
886
|
if (isNullKeyCacheValue(serialized)) {
|
|
879
887
|
this.nullKeys.add(keyId.href);
|
|
@@ -885,7 +893,7 @@ var KvKeyCache = class {
|
|
|
885
893
|
try {
|
|
886
894
|
return await Multikey.fromJsonLd(serialized, this.options);
|
|
887
895
|
} catch {
|
|
888
|
-
await this.kv.delete(
|
|
896
|
+
await this.kv.delete(this.#entryKey(keyId));
|
|
889
897
|
return;
|
|
890
898
|
}
|
|
891
899
|
}
|
|
@@ -893,12 +901,12 @@ var KvKeyCache = class {
|
|
|
893
901
|
async set(keyId, key) {
|
|
894
902
|
if (key == null) {
|
|
895
903
|
this.nullKeys.add(keyId.href);
|
|
896
|
-
await this.kv.set(
|
|
904
|
+
await this.kv.set(this.#entryKey(keyId), NULL_KEY_CACHE_VALUE, { ttl: NULL_KEY_CACHE_TTL });
|
|
897
905
|
return;
|
|
898
906
|
}
|
|
899
907
|
this.nullKeys.delete(keyId.href);
|
|
900
908
|
const serialized = await key.toJsonLd(this.options);
|
|
901
|
-
await this.kv.set(
|
|
909
|
+
await this.kv.set(this.#entryKey(keyId), serialized);
|
|
902
910
|
}
|
|
903
911
|
};
|
|
904
912
|
//#endregion
|
|
@@ -1376,8 +1384,16 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
1376
1384
|
}
|
|
1377
1385
|
let json;
|
|
1378
1386
|
try {
|
|
1379
|
-
json = await request.clone().
|
|
1387
|
+
json = JSON.parse(await readBoundedText(request.clone(), MAX_BODY_SIZE, request.url));
|
|
1380
1388
|
} catch (error) {
|
|
1389
|
+
if (error instanceof BodyTooLargeError) {
|
|
1390
|
+
request.body?.cancel(error).catch(() => {});
|
|
1391
|
+
span.setStatus({
|
|
1392
|
+
code: SpanStatusCode.ERROR,
|
|
1393
|
+
message: String(error)
|
|
1394
|
+
});
|
|
1395
|
+
return new Response("Inbox body too large.", { status: 413 });
|
|
1396
|
+
}
|
|
1381
1397
|
logger.error("Failed to parse JSON:\n{error}", {
|
|
1382
1398
|
recipient,
|
|
1383
1399
|
error
|
|
@@ -2249,18 +2265,31 @@ async function readLimitedResponseBody(response, maxBytes) {
|
|
|
2249
2265
|
if (truncated) result += "… (truncated)";
|
|
2250
2266
|
return result;
|
|
2251
2267
|
}
|
|
2252
|
-
async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }, span) {
|
|
2268
|
+
async function sendActivityInternal({ activity, activityId, keys, inbox, allowPrivateAddress, headers, specDeterminer, tracerProvider }, span) {
|
|
2253
2269
|
const logger = getLogger([
|
|
2254
2270
|
"fedify",
|
|
2255
2271
|
"federation",
|
|
2256
2272
|
"outbox"
|
|
2257
2273
|
]);
|
|
2274
|
+
async function validateUrl(url) {
|
|
2275
|
+
if (!allowPrivateAddress) try {
|
|
2276
|
+
await validatePublicUrl(url);
|
|
2277
|
+
} catch (error) {
|
|
2278
|
+
if (error instanceof UrlError) logger.error("Disallowed private URL: {url}", {
|
|
2279
|
+
url,
|
|
2280
|
+
error
|
|
2281
|
+
});
|
|
2282
|
+
throw error;
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
await validateUrl(inbox.href);
|
|
2258
2286
|
headers = new Headers(headers);
|
|
2259
2287
|
headers.set("Content-Type", "application/activity+json");
|
|
2260
2288
|
const request = new Request(inbox, {
|
|
2261
2289
|
method: "POST",
|
|
2262
2290
|
headers,
|
|
2263
|
-
body: JSON.stringify(activity)
|
|
2291
|
+
body: JSON.stringify(activity),
|
|
2292
|
+
redirect: "manual"
|
|
2264
2293
|
});
|
|
2265
2294
|
let rsaKey = null;
|
|
2266
2295
|
for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
|
@@ -2276,9 +2305,10 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2276
2305
|
});
|
|
2277
2306
|
let response;
|
|
2278
2307
|
try {
|
|
2279
|
-
response = rsaKey == null ? await
|
|
2308
|
+
response = rsaKey == null ? await fetchWithValidatedRedirects(request, validateUrl) : await doubleKnock(request, rsaKey, {
|
|
2280
2309
|
tracerProvider,
|
|
2281
|
-
specDeterminer
|
|
2310
|
+
specDeterminer,
|
|
2311
|
+
validateRedirect: validateUrl
|
|
2282
2312
|
});
|
|
2283
2313
|
} catch (error) {
|
|
2284
2314
|
logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
|
|
@@ -2310,6 +2340,49 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
2310
2340
|
"activitypub.activity.id": activityId ?? ""
|
|
2311
2341
|
});
|
|
2312
2342
|
}
|
|
2343
|
+
async function fetchWithValidatedRedirects(request, validateUrl) {
|
|
2344
|
+
let body = await request.clone().text();
|
|
2345
|
+
for (let redirects = 0;; redirects++) {
|
|
2346
|
+
const response = await fetch(request, { redirect: "manual" });
|
|
2347
|
+
const location = response.headers.get("Location");
|
|
2348
|
+
if (![
|
|
2349
|
+
301,
|
|
2350
|
+
302,
|
|
2351
|
+
303,
|
|
2352
|
+
307,
|
|
2353
|
+
308
|
|
2354
|
+
].includes(response.status) || location == null) return response;
|
|
2355
|
+
await response.body?.cancel();
|
|
2356
|
+
if (redirects >= 20) throw new TypeError("Too many redirects");
|
|
2357
|
+
const url = new URL(location, request.url);
|
|
2358
|
+
await validateUrl(url.href);
|
|
2359
|
+
const headers = new Headers(request.headers);
|
|
2360
|
+
if (url.origin !== new URL(request.url).origin) {
|
|
2361
|
+
headers.delete("Authorization");
|
|
2362
|
+
headers.delete("Proxy-Authorization");
|
|
2363
|
+
headers.delete("Cookie");
|
|
2364
|
+
headers.delete("Host");
|
|
2365
|
+
}
|
|
2366
|
+
let method = request.method;
|
|
2367
|
+
if ((response.status === 301 || response.status === 302) && method === "POST" || response.status === 303 && method !== "GET" && method !== "HEAD") {
|
|
2368
|
+
method = "GET";
|
|
2369
|
+
body = void 0;
|
|
2370
|
+
for (const name of [
|
|
2371
|
+
"Content-Encoding",
|
|
2372
|
+
"Content-Language",
|
|
2373
|
+
"Content-Length",
|
|
2374
|
+
"Content-Location",
|
|
2375
|
+
"Content-Type"
|
|
2376
|
+
]) headers.delete(name);
|
|
2377
|
+
}
|
|
2378
|
+
request = new Request(url, {
|
|
2379
|
+
method,
|
|
2380
|
+
headers,
|
|
2381
|
+
body,
|
|
2382
|
+
redirect: "manual"
|
|
2383
|
+
});
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2313
2386
|
/**
|
|
2314
2387
|
* An error that is thrown when an activity fails to send to a remote inbox.
|
|
2315
2388
|
* It contains structured information about the failure, including the HTTP
|
|
@@ -2815,6 +2888,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2815
2888
|
}
|
|
2816
2889
|
try {
|
|
2817
2890
|
await sendActivity({
|
|
2891
|
+
allowPrivateAddress: this.allowPrivateAddress,
|
|
2818
2892
|
keys,
|
|
2819
2893
|
activity: message.activity,
|
|
2820
2894
|
activityId: message.activityId,
|
|
@@ -3206,6 +3280,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3206
3280
|
});
|
|
3207
3281
|
const promises = [];
|
|
3208
3282
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
3283
|
+
allowPrivateAddress: this.allowPrivateAddress,
|
|
3209
3284
|
keys,
|
|
3210
3285
|
activity: jsonLd,
|
|
3211
3286
|
activityId: activity.id?.href,
|
|
@@ -4346,6 +4421,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
|
|
|
4346
4421
|
else logger.debug("Forwarding activity immediately without queue since queue is not set.");
|
|
4347
4422
|
const promises = [];
|
|
4348
4423
|
for (const inbox in inboxes) promises.push(sendActivity({
|
|
4424
|
+
allowPrivateAddress: this.federation.allowPrivateAddress,
|
|
4349
4425
|
keys,
|
|
4350
4426
|
activity: this.activity,
|
|
4351
4427
|
activityId: this.activityId,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { n as HttpMessageSignaturesSpecDeterminer } from "./http-
|
|
2
|
+
import { n as HttpMessageSignaturesSpecDeterminer } from "./http-Bs6thuCC.cjs";
|
|
3
3
|
import { n as KvStore, t as KvKey } from "./kv-gJ8LYbxX.cjs";
|
|
4
4
|
import { DocumentLoader, DocumentLoaderFactoryOptions } from "@fedify/vocab-runtime";
|
|
5
5
|
import { TracerProvider } from "@opentelemetry/api";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, mt as WebFingerLinksDispatcher, s as RequestContext } from "./context-
|
|
2
|
+
import { X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, mt as WebFingerLinksDispatcher, s as RequestContext } from "./context-B21klrfz.js";
|
|
3
3
|
import { Span, Tracer } from "@opentelemetry/api";
|
|
4
4
|
|
|
5
5
|
//#region src/federation/webfinger.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, mt as WebFingerLinksDispatcher, s as RequestContext } from "./context-
|
|
2
|
+
import { X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, mt as WebFingerLinksDispatcher, s as RequestContext } from "./context-M_MxoQgC.cjs";
|
|
3
3
|
import { Span, Tracer } from "@opentelemetry/api";
|
|
4
4
|
|
|
5
5
|
//#region src/federation/webfinger.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { l as KeyCache } from "./http-
|
|
2
|
+
import { l as KeyCache } from "./http-CDupyfOc.js";
|
|
3
3
|
import { CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1 } from "@fedify/vocab";
|
|
4
4
|
import { TracerProvider } from "@opentelemetry/api";
|
|
5
5
|
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { l as KeyCache } from "./http-
|
|
2
|
+
import { l as KeyCache } from "./http-Bs6thuCC.cjs";
|
|
3
3
|
import { CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1 } from "@fedify/vocab";
|
|
4
4
|
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
5
5
|
import { TracerProvider } from "@opentelemetry/api";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { n as HttpMessageSignaturesSpecDeterminer } from "./http-
|
|
2
|
+
import { n as HttpMessageSignaturesSpecDeterminer } from "./http-CDupyfOc.js";
|
|
3
3
|
import { n as KvStore, t as KvKey } from "./kv-D6hNiMTK.js";
|
|
4
4
|
import { TracerProvider } from "@opentelemetry/api";
|
|
5
5
|
import { DocumentLoader, DocumentLoaderFactoryOptions } from "@fedify/vocab-runtime";
|
package/dist/mod.cjs
CHANGED
|
@@ -4,11 +4,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
4
4
|
require("./chunk-DDcVe30Y.cjs");
|
|
5
5
|
const require_transformers = require("./transformers-NeAONrAq.cjs");
|
|
6
6
|
require("./compat/mod.cjs");
|
|
7
|
-
const require_http = require("./http-
|
|
8
|
-
const require_middleware = require("./middleware-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const require_kv_cache = require("./kv-cache-
|
|
7
|
+
const require_http = require("./http-BgOlx4n1.cjs");
|
|
8
|
+
const require_middleware = require("./middleware-D_7wZH27.cjs");
|
|
9
|
+
const require_types = require("./types-DWs-qZaY.cjs");
|
|
10
|
+
const require_proof = require("./proof-xCEe8t7U.cjs");
|
|
11
|
+
const require_kv_cache = require("./kv-cache-B8GaLaNy.cjs");
|
|
12
12
|
const require_federation_mod = require("./federation/mod.cjs");
|
|
13
13
|
require("./nodeinfo/mod.cjs");
|
|
14
14
|
require("./runtime/mod.cjs");
|
package/dist/mod.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
2
|
import { a as InboundService, c as OutboundService, d as Software, f as Usage, i as parseNodeInfo, l as Protocol, n as ParseNodeInfoOptions, o as JsonValue, p as nodeInfoToJson, r as getNodeInfo, s as NodeInfo, t as GetNodeInfoOptions, u as Services } from "./client-CAM_bQXx.cjs";
|
|
3
|
-
import { a as signRequest, c as FetchKeyResult, d as fetchKey, f as generateCryptoKeyPair, i as VerifyRequestOptions, l as KeyCache, n as HttpMessageSignaturesSpecDeterminer, o as verifyRequest, p as importJwk, r as SignRequestOptions, s as FetchKeyOptions, t as HttpMessageSignaturesSpec, u as exportJwk } from "./http-
|
|
4
|
-
import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-
|
|
5
|
-
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, bt as ActivityTransformer, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "./context-
|
|
3
|
+
import { a as signRequest, c as FetchKeyResult, d as fetchKey, f as generateCryptoKeyPair, i as VerifyRequestOptions, l as KeyCache, n as HttpMessageSignaturesSpecDeterminer, o as verifyRequest, p as importJwk, r as SignRequestOptions, s as FetchKeyOptions, t as HttpMessageSignaturesSpec, u as exportJwk } from "./http-Bs6thuCC.cjs";
|
|
4
|
+
import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-B3hNQCG8.cjs";
|
|
5
|
+
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, bt as ActivityTransformer, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "./context-M_MxoQgC.cjs";
|
|
6
6
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "./kv-gJ8LYbxX.cjs";
|
|
7
7
|
import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "./compat/mod.cjs";
|
|
8
|
-
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "./mod-
|
|
9
|
-
import { _ as verifyJsonLd, a as createProof, c as verifyProof, d as VerifyJsonLdOptions, f as VerifySignatureOptions, g as signJsonLd, h as detachSignature, i as VerifyProofOptions, l as CreateSignatureOptions, m as createSignature, n as SignObjectOptions, o as signObject, p as attachSignature, r as VerifyObjectOptions, s as verifyObject, t as CreateProofOptions, u as SignJsonLdOptions, v as verifySignature } from "./mod-
|
|
10
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-
|
|
8
|
+
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "./mod-Dp5dfH-i.cjs";
|
|
9
|
+
import { _ as verifyJsonLd, a as createProof, c as verifyProof, d as VerifyJsonLdOptions, f as VerifySignatureOptions, g as signJsonLd, h as detachSignature, i as VerifyProofOptions, l as CreateSignatureOptions, m as createSignature, n as SignObjectOptions, o as signObject, p as attachSignature, r as VerifyObjectOptions, s as verifyObject, t as CreateProofOptions, u as SignJsonLdOptions, v as verifySignature } from "./mod-IOWUF5Yr.cjs";
|
|
10
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-Bt0eg_Lv.cjs";
|
|
11
11
|
export * from "@fedify/vocab-runtime";
|
|
12
12
|
|
|
13
13
|
//#region src/mod.d.ts
|
package/dist/mod.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
2
|
import { a as InboundService, c as OutboundService, d as Software, f as Usage, i as parseNodeInfo, l as Protocol, n as ParseNodeInfoOptions, o as JsonValue, p as nodeInfoToJson, r as getNodeInfo, s as NodeInfo, t as GetNodeInfoOptions, u as Services } from "./client-CSddvgWN.js";
|
|
3
|
-
import { a as signRequest, c as FetchKeyResult, d as fetchKey, f as generateCryptoKeyPair, i as VerifyRequestOptions, l as KeyCache, n as HttpMessageSignaturesSpecDeterminer, o as verifyRequest, p as importJwk, r as SignRequestOptions, s as FetchKeyOptions, t as HttpMessageSignaturesSpec, u as exportJwk } from "./http-
|
|
4
|
-
import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-
|
|
5
|
-
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, bt as ActivityTransformer, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "./context-
|
|
3
|
+
import { a as signRequest, c as FetchKeyResult, d as fetchKey, f as generateCryptoKeyPair, i as VerifyRequestOptions, l as KeyCache, n as HttpMessageSignaturesSpecDeterminer, o as verifyRequest, p as importJwk, r as SignRequestOptions, s as FetchKeyOptions, t as HttpMessageSignaturesSpec, u as exportJwk } from "./http-CDupyfOc.js";
|
|
4
|
+
import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-CiBPcC6F.js";
|
|
5
|
+
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, bt as ActivityTransformer, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "./context-B21klrfz.js";
|
|
6
6
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "./kv-D6hNiMTK.js";
|
|
7
7
|
import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "./compat/mod.js";
|
|
8
|
-
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "./mod-
|
|
9
|
-
import { _ as verifyJsonLd, a as createProof, c as verifyProof, d as VerifyJsonLdOptions, f as VerifySignatureOptions, g as signJsonLd, h as detachSignature, i as VerifyProofOptions, l as CreateSignatureOptions, m as createSignature, n as SignObjectOptions, o as signObject, p as attachSignature, r as VerifyObjectOptions, s as verifyObject, t as CreateProofOptions, u as SignJsonLdOptions, v as verifySignature } from "./mod-
|
|
10
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-
|
|
8
|
+
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "./mod-D24V_w-K.js";
|
|
9
|
+
import { _ as verifyJsonLd, a as createProof, c as verifyProof, d as VerifyJsonLdOptions, f as VerifySignatureOptions, g as signJsonLd, h as detachSignature, i as VerifyProofOptions, l as CreateSignatureOptions, m as createSignature, n as SignObjectOptions, o as signObject, p as attachSignature, r as VerifyObjectOptions, s as verifyObject, t as CreateProofOptions, u as SignJsonLdOptions, v as verifySignature } from "./mod-E7YM72JZ.js";
|
|
10
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-XucBiDNd.js";
|
|
11
11
|
export * from "@fedify/vocab-runtime";
|
|
12
12
|
|
|
13
13
|
//#region src/mod.d.ts
|
package/dist/mod.js
CHANGED
|
@@ -3,11 +3,11 @@ import { URLPattern } from "urlpattern-polyfill";
|
|
|
3
3
|
import "./chunk-CRNNMoPX.js";
|
|
4
4
|
import { n as autoIdAssigner, r as getDefaultActivityTransformers, t as actorDehydrator } from "./transformers-BGMIq1cs.js";
|
|
5
5
|
import "./compat/mod.js";
|
|
6
|
-
import {
|
|
7
|
-
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "./middleware-
|
|
8
|
-
import {
|
|
9
|
-
import { n as
|
|
10
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
6
|
+
import { c as importJwk, i as exportJwk, n as signRequest, o as fetchKey, r as verifyRequest, s as generateCryptoKeyPair } from "./http-CwcG2wDs.js";
|
|
7
|
+
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "./middleware-DomxFoLd.js";
|
|
8
|
+
import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "./types-sXITXcWa.js";
|
|
9
|
+
import { _ as signJsonLd, a as doesActorOwnKey, b as verifySignature, d as createSignature, f as detachSignature, i as verifyProof, l as attachSignature, n as signObject, o as getKeyOwner, r as verifyObject, t as createProof, y as verifyJsonLd } from "./proof-DsJHFTkx.js";
|
|
10
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-lbswb9pg.js";
|
|
11
11
|
import { InProcessMessageQueue, MemoryKvStore, ParallelMessageQueue } from "./federation/mod.js";
|
|
12
12
|
import "./nodeinfo/mod.js";
|
|
13
13
|
import "./runtime/mod.js";
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as esm_default } from "../esm-DVILvP5e.mjs";
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-Duiq_YC9.mjs";
|
|
7
|
-
import { a as parseProtocol, c as parseUsage, i as parseOutboundService, n as parseInboundService, o as parseServices, r as parseNodeInfo, s as parseSoftware, t as getNodeInfo } from "../client-
|
|
7
|
+
import { a as parseProtocol, c as parseUsage, i as parseOutboundService, n as parseInboundService, o as parseServices, r as parseNodeInfo, s as parseSoftware, t as getNodeInfo } from "../client-glFHmpn4.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/nodeinfo/client.test.ts
|
|
10
10
|
test("getNodeInfo()", async (t) => {
|
|
@@ -967,5 +967,32 @@ test("parseUsage()", () => {
|
|
|
967
967
|
localComments: 456
|
|
968
968
|
});
|
|
969
969
|
});
|
|
970
|
+
test("getNodeInfo() bounds both discovery and document responses", async () => {
|
|
971
|
+
esm_default.mockGlobal();
|
|
972
|
+
const base = "https://8.8.8.8";
|
|
973
|
+
const descriptor = { links: [{
|
|
974
|
+
rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
|
|
975
|
+
href: `${base}/nodeinfo`
|
|
976
|
+
}] };
|
|
977
|
+
let oversizedDescriptor = true;
|
|
978
|
+
let oversizedDocument = true;
|
|
979
|
+
const data = { padding: "a".repeat(256) };
|
|
980
|
+
try {
|
|
981
|
+
esm_default.get(`${base}/.well-known/nodeinfo`, () => new Response(JSON.stringify(descriptor), { headers: oversizedDescriptor ? { "Content-Length": String(16777217) } : {} }));
|
|
982
|
+
esm_default.get(`${base}/nodeinfo`, () => new Response(JSON.stringify(data), { headers: oversizedDocument ? { "Content-Length": String(16777217) } : {} }));
|
|
983
|
+
assertEquals(await getNodeInfo(base), void 0);
|
|
984
|
+
assertEquals(esm_default.callHistory.calls(`${base}/nodeinfo`).length, 0);
|
|
985
|
+
oversizedDescriptor = false;
|
|
986
|
+
assertEquals(await getNodeInfo(base), void 0);
|
|
987
|
+
assertEquals(await getNodeInfo(`${base}/nodeinfo`, {
|
|
988
|
+
direct: true,
|
|
989
|
+
parse: "none"
|
|
990
|
+
}), void 0);
|
|
991
|
+
oversizedDocument = false;
|
|
992
|
+
assertEquals(await getNodeInfo(base, { parse: "none" }), data);
|
|
993
|
+
} finally {
|
|
994
|
+
esm_default.hardReset();
|
|
995
|
+
}
|
|
996
|
+
});
|
|
970
997
|
//#endregion
|
|
971
998
|
export {};
|
|
@@ -4,8 +4,8 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { n as createRequestContext } from "../context-Juj6bdHC.mjs";
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-Duiq_YC9.mjs";
|
|
7
|
-
import { t as MemoryKvStore } from "../kv-
|
|
8
|
-
import { a as createFederation, h as handleNodeInfoJrd, m as handleNodeInfo } from "../middleware-
|
|
7
|
+
import { t as MemoryKvStore } from "../kv-mI4Ix2EU.mjs";
|
|
8
|
+
import { a as createFederation, h as handleNodeInfoJrd, m as handleNodeInfo } from "../middleware-BuVM1K-J.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
//#region src/nodeinfo/handler.test.ts
|
|
11
11
|
test("handleNodeInfo()", async () => {
|
package/dist/nodeinfo/mod.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
-
const require_types = require("../types-
|
|
4
|
+
const require_types = require("../types-DWs-qZaY.cjs");
|
|
5
5
|
exports.getNodeInfo = require_types.getNodeInfo;
|
|
6
6
|
exports.nodeInfoToJson = require_types.nodeInfoToJson;
|
|
7
7
|
exports.parseNodeInfo = require_types.parseNodeInfo;
|
package/dist/nodeinfo/mod.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "../types-
|
|
3
|
+
import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "../types-sXITXcWa.js";
|
|
4
4
|
export { getNodeInfo, nodeInfoToJson, parseNodeInfo };
|