@fedify/fedify 2.3.15-dev.2482 → 2.3.15
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-CocMrVkL.mjs → builder-B6vSXYxn.mjs} +2 -2
- package/dist/{client-CAM_bQXx.d.cts → client-BIBzqEIp.d.cts} +0 -1
- package/dist/{client-1He2YuBF.mjs → client-DpUNYKla.mjs} +113 -64
- package/dist/{client-CSddvgWN.d.ts → client-jE7oGvRh.d.ts} +0 -1
- 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/{context-MOrCC7yl.d.cts → context-CE_Tj_Oc.d.cts} +28 -2
- package/dist/{context-BWbdE_MZ.d.ts → context-H_5tZXg-.d.ts} +28 -2
- package/dist/{deno-po8iekMB.mjs → deno-BCuL3mid.mjs} +1 -1
- package/dist/docloader-D2dr1_6B.mjs +125 -0
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +5 -5
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +390 -29
- 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/send.test.mjs +498 -88
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-Cdu8BGtv.js → http-BkjxY3U0.js} +172 -103
- package/dist/{http-BNCLeQJ-.mjs → http-CSDcThvz.mjs} +196 -98
- package/dist/{http-DQmNpfym.d.ts → http-CZPYFK3b.d.cts} +1 -2
- package/dist/{http-DiWQB8Mr.d.cts → http-DmP0sr2l.d.ts} +1 -2
- package/dist/{http-WcSdFbt1.cjs → http-gOkAiIe1.cjs} +173 -104
- package/dist/{inbox-g1sd_Vjn.mjs → inbox-BHxez4d5.mjs} +2 -2
- package/dist/{key-BR2TRTXR.mjs → key-D8IMQ72M.mjs} +2 -2
- package/dist/{kv-cache-Bw_gduSm.cjs → kv-cache-Alm5UmJa.cjs} +59 -17
- package/dist/{kv-cache-8SigUtvX.mjs → kv-cache-Blr9nDDp.mjs} +1 -1
- package/dist/{kv-cache-C0AqpjoS.js → kv-cache-CkXgU-ak.js} +60 -18
- package/dist/{ld-CSNsWdYE.mjs → ld-CVxxE1Pp.mjs} +3 -3
- package/dist/{metrics-BS7YzLVA.mjs → metrics-SYIZHFf_.mjs} +1 -1
- package/dist/{middleware-D-SL8Bkj.cjs → middleware-4yPyyoF5.cjs} +236 -98
- package/dist/{middleware-B1RRLN7m.mjs → middleware-CfskJGfV.mjs} +80 -40
- package/dist/{middleware-Dlo7NnZl.mjs → middleware-D3JWfiCu.mjs} +1 -1
- package/dist/{middleware-WL-JfDiK.js → middleware-DhN7c65B.js} +237 -99
- package/dist/{mod-LmD03uRA.d.ts → mod-CDFFESfL.d.ts} +1 -1
- package/dist/{mod-Bid79LFU.d.cts → mod-C_gFmeNq.d.cts} +1 -1
- package/dist/{mod-Co1M3Ux0.d.cts → mod-DDVkmZ_h.d.cts} +2 -8
- package/dist/{mod-B6PwkUMU.d.cts → mod-DDjtbkZO.d.cts} +1 -1
- package/dist/{mod-Br8yJNcE.d.ts → mod-DMjhnFbg.d.ts} +2 -8
- package/dist/{mod-TLEvgT1i.d.ts → mod-HQXFvOHs.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 +337 -19
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.d.cts +1 -1
- package/dist/nodeinfo/mod.d.ts +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/otel/exporter.test.mjs +292 -30
- package/dist/otel/mod.cjs +36 -30
- package/dist/otel/mod.d.cts +13 -0
- package/dist/otel/mod.d.ts +13 -0
- package/dist/otel/mod.js +36 -30
- package/dist/{owner-DeggvxcG.mjs → owner-BluLVPf0.mjs} +2 -2
- package/dist/{proof-teNNYmFh.cjs → proof-CR-HwI0l.cjs} +1 -1
- package/dist/{proof-DMcUrrp8.mjs → proof-Co6nQBVR.mjs} +3 -3
- package/dist/{proof-v-IzWx7x.js → proof-Dg0d9QBo.js} +1 -1
- package/dist/{send-BsthcvPG.mjs → send-D_DnqOFA.mjs} +171 -73
- package/dist/sig/http.test.mjs +528 -2
- package/dist/sig/key.test.mjs +2 -2
- 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/proof.test.mjs +1 -1
- package/dist/{temporal-Cji8Y8eQ.mjs → temporal-B8FUNkXB.mjs} +1 -1
- package/dist/testing/mod.d.mts +26 -0
- package/dist/{types-miAYfiGO.js → types-B1_pRFE_.js} +112 -63
- package/dist/{types-DRPjmHVV.cjs → types-DOvyymM4.cjs} +111 -62
- package/dist/utils/docloader.test.mjs +318 -34
- 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 +8 -8
- package/dist/docloader-BVj35vgR.mjs +0 -83
|
@@ -9,15 +9,15 @@ import { t as assertRejects } from "../assert_rejects-D1HYAik3.mjs";
|
|
|
9
9
|
import { n as assertInstanceOf, t as assert } from "../assert-CEO06XCw.mjs";
|
|
10
10
|
import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
|
|
11
11
|
import { t as assertStrictEquals } from "../assert_strict_equals-XEgZAlrj.mjs";
|
|
12
|
-
import { g as recordInboxActivity } from "../metrics-
|
|
13
|
-
import {
|
|
12
|
+
import { g as recordInboxActivity } from "../metrics-SYIZHFf_.mjs";
|
|
13
|
+
import { c as signRequest, u as verifyRequest } from "../http-CSDcThvz.mjs";
|
|
14
14
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-BAK-tUlf.mjs";
|
|
15
|
-
import {
|
|
15
|
+
import { n as getAuthenticatedDocumentLoader } from "../docloader-D2dr1_6B.mjs";
|
|
16
16
|
import { t as MemoryKvStore } from "../kv-mI4Ix2EU.mjs";
|
|
17
|
-
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-
|
|
18
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
19
|
-
import { i as verifyObject, r as signObject } from "../proof-
|
|
20
|
-
import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-
|
|
17
|
+
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-CVxxE1Pp.mjs";
|
|
18
|
+
import { t as doesActorOwnKey } from "../owner-BluLVPf0.mjs";
|
|
19
|
+
import { i as verifyObject, r as signObject } from "../proof-Co6nQBVR.mjs";
|
|
20
|
+
import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-CfskJGfV.mjs";
|
|
21
21
|
import { t as CircuitBreaker } from "../circuit-breaker-D1fxthDI.mjs";
|
|
22
22
|
import { t as markCircuitBreakerLegacySweepDone } from "../circuit-breaker-test-utils-CAdwjgMi.mjs";
|
|
23
23
|
import { configure, reset } from "@logtape/logtape";
|
|
@@ -27,9 +27,9 @@ import { Create, Offer, Person, getTypeId, lookupObject } from "@fedify/vocab";
|
|
|
27
27
|
import { SpanStatusCode, metrics } from "@opentelemetry/api";
|
|
28
28
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
29
29
|
import { FetchError, UrlError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
30
|
-
import dns from "node:dns/promises";
|
|
31
30
|
import serialize from "json-canon";
|
|
32
31
|
import { DataPointType, MeterProvider as MeterProvider$1, MetricReader } from "@opentelemetry/sdk-metrics";
|
|
32
|
+
import dns from "node:dns/promises";
|
|
33
33
|
//#region ../fixture/src/fixtures/example.com/create.json
|
|
34
34
|
var id$2 = "https://example.com/create";
|
|
35
35
|
var create_default = {
|
|
@@ -94,7 +94,7 @@ var person2_default = {
|
|
|
94
94
|
};
|
|
95
95
|
//#endregion
|
|
96
96
|
//#region src/federation/middleware.test.ts
|
|
97
|
-
const documentLoader = getDocumentLoader();
|
|
97
|
+
const documentLoader = getDocumentLoader({ allowPrivateAddress: true });
|
|
98
98
|
let logtapeLock = Promise.resolve();
|
|
99
99
|
async function withLogtapeLock(fn) {
|
|
100
100
|
const run = logtapeLock.then(fn, fn);
|
|
@@ -649,7 +649,8 @@ test({
|
|
|
649
649
|
const federation = createFederation({
|
|
650
650
|
kv,
|
|
651
651
|
documentLoaderFactory: () => rejectingLoader,
|
|
652
|
-
contextLoaderFactory: () => mockDocumentLoader
|
|
652
|
+
contextLoaderFactory: () => mockDocumentLoader,
|
|
653
|
+
authenticatedDocumentLoaderFactory: (identity) => getAuthenticatedDocumentLoader(identity, { allowPrivateAddress: true })
|
|
653
654
|
});
|
|
654
655
|
let ctx = federation.createContext(new URL("https://example.com:1234/"), 123);
|
|
655
656
|
assertEquals(ctx.data, 123);
|
|
@@ -760,7 +761,7 @@ test({
|
|
|
760
761
|
documentUrl: "https://example.com/auth-check",
|
|
761
762
|
document: true
|
|
762
763
|
});
|
|
763
|
-
assertEquals(await ctx.lookupObject("https://example.com/object"), null);
|
|
764
|
+
assertEquals(await withDnsLookup(() => Promise.reject(/* @__PURE__ */ new Error("Resolver unavailable")), () => ctx.lookupObject("https://example.com/object")), null);
|
|
764
765
|
await assertRejects(() => ctx.sendActivity({ identifier: "handle" }, [], new vocab.Create({})), TypeError, "The activity to send must have at least one actor property.");
|
|
765
766
|
await ctx.sendActivity({ identifier: "handle" }, [], new vocab.Create({ actor: new URL("https://example.com/users/handle") }));
|
|
766
767
|
esm_default.get("https://example.com/object", () => new Response(JSON.stringify({
|
|
@@ -1009,7 +1010,7 @@ test({
|
|
|
1009
1010
|
assertStrictEquals(clone.contextLoader, ctx.contextLoader);
|
|
1010
1011
|
assertStrictEquals(clone.federation, ctx.federation);
|
|
1011
1012
|
});
|
|
1012
|
-
esm_default.get("
|
|
1013
|
+
esm_default.get("path:/.well-known/nodeinfo", (cl) => {
|
|
1013
1014
|
const headers = cl.options.headers ?? {};
|
|
1014
1015
|
assertEquals(new Headers(headers).get("User-Agent"), "CustomUserAgent/1.2.3");
|
|
1015
1016
|
return new Response(JSON.stringify({ links: [{
|
|
@@ -1017,7 +1018,7 @@ test({
|
|
|
1017
1018
|
href: "https://example.com/nodeinfo/2.1"
|
|
1018
1019
|
}] }));
|
|
1019
1020
|
});
|
|
1020
|
-
esm_default.get("
|
|
1021
|
+
esm_default.get("path:/nodeinfo/2.1", (cl) => {
|
|
1021
1022
|
const headers = cl.options.headers ?? {};
|
|
1022
1023
|
assertEquals(new Headers(headers).get("User-Agent"), "CustomUserAgent/1.2.3");
|
|
1023
1024
|
return new Response(JSON.stringify({
|
|
@@ -1038,7 +1039,11 @@ test({
|
|
|
1038
1039
|
kv,
|
|
1039
1040
|
userAgent: "CustomUserAgent/1.2.3"
|
|
1040
1041
|
}).createContext(new URL("https://example.com/"), 123);
|
|
1041
|
-
|
|
1042
|
+
const lookupExample = () => Promise.resolve([{
|
|
1043
|
+
address: "93.184.215.14",
|
|
1044
|
+
family: 4
|
|
1045
|
+
}]);
|
|
1046
|
+
assertEquals(await withDnsLookup(lookupExample, () => ctx.lookupNodeInfo("https://example.com/")), {
|
|
1042
1047
|
software: {
|
|
1043
1048
|
name: "foo",
|
|
1044
1049
|
version: "1.2.3"
|
|
@@ -1050,7 +1055,7 @@ test({
|
|
|
1050
1055
|
localComments: 456
|
|
1051
1056
|
}
|
|
1052
1057
|
});
|
|
1053
|
-
assertEquals(await ctx.lookupNodeInfo("https://example.com/", { parse: "none" }), {
|
|
1058
|
+
assertEquals(await withDnsLookup(lookupExample, () => ctx.lookupNodeInfo("https://example.com/", { parse: "none" })), {
|
|
1054
1059
|
software: {
|
|
1055
1060
|
name: "foo",
|
|
1056
1061
|
version: "1.2.3"
|
|
@@ -1234,6 +1239,343 @@ test("Federation.fetch() verifies signatures over unencoded path colons", async
|
|
|
1234
1239
|
assertEquals(federation.createContext(new URL(canonical), void 0).getInboxUri(identifier).href, canonical);
|
|
1235
1240
|
});
|
|
1236
1241
|
});
|
|
1242
|
+
test("RequestContext signature checks", async (t) => {
|
|
1243
|
+
const [tracerProvider, exporter] = createTestTracerProvider();
|
|
1244
|
+
const keyId = rsaPublicKey3.id.href;
|
|
1245
|
+
const ownerId = rsaPublicKey3.ownerId.href;
|
|
1246
|
+
const request = await signRequest(new Request("https://example.com/"), rsaPrivateKey3, rsaPublicKey3.id);
|
|
1247
|
+
function setup(options = {}) {
|
|
1248
|
+
const loads = {
|
|
1249
|
+
key: 0,
|
|
1250
|
+
owner: 0
|
|
1251
|
+
};
|
|
1252
|
+
const loader = async (url, loaderOptions) => {
|
|
1253
|
+
if (url === keyId) loads.key++;
|
|
1254
|
+
else if (url === ownerId) loads.owner++;
|
|
1255
|
+
await options.gate;
|
|
1256
|
+
return await (options.load ?? mockDocumentLoader)(url, loaderOptions);
|
|
1257
|
+
};
|
|
1258
|
+
const federation = createFederation({
|
|
1259
|
+
kv: new MemoryKvStore(),
|
|
1260
|
+
documentLoaderFactory: () => loader,
|
|
1261
|
+
contextLoaderFactory: () => mockDocumentLoader,
|
|
1262
|
+
tracerProvider: options.tracerProvider ?? tracerProvider
|
|
1263
|
+
});
|
|
1264
|
+
return {
|
|
1265
|
+
ctx: federation.createContext(options.request ?? new Request(request), void 0),
|
|
1266
|
+
loads,
|
|
1267
|
+
loader,
|
|
1268
|
+
federation
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
try {
|
|
1272
|
+
for (const mode of [
|
|
1273
|
+
"keys",
|
|
1274
|
+
"owners",
|
|
1275
|
+
"warm owners",
|
|
1276
|
+
"mixed"
|
|
1277
|
+
]) await t.step(`coalesces ${mode}`, async () => {
|
|
1278
|
+
exporter.clear();
|
|
1279
|
+
let release;
|
|
1280
|
+
const { ctx, loads, loader } = setup({ gate: new Promise((resolve) => release = resolve) });
|
|
1281
|
+
if (mode === "warm owners") {
|
|
1282
|
+
release();
|
|
1283
|
+
assert(await ctx.getSignedKey());
|
|
1284
|
+
}
|
|
1285
|
+
const results = Promise.all(Array.from({ length: 8 }, (_, i) => {
|
|
1286
|
+
const options = i % 2 === 0 ? {} : {
|
|
1287
|
+
documentLoader: loader,
|
|
1288
|
+
contextLoader: ctx.contextLoader,
|
|
1289
|
+
tracerProvider
|
|
1290
|
+
};
|
|
1291
|
+
return mode === "keys" || mode === "mixed" && i % 2 === 0 ? ctx.getSignedKey(options) : ctx.getSignedKeyOwner(options);
|
|
1292
|
+
}));
|
|
1293
|
+
release();
|
|
1294
|
+
for (const result of await results) assert(result != null);
|
|
1295
|
+
assertEquals(loads, {
|
|
1296
|
+
key: 1,
|
|
1297
|
+
owner: mode === "keys" ? 0 : 1
|
|
1298
|
+
});
|
|
1299
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 1);
|
|
1300
|
+
assert(await ctx.getSignedKey());
|
|
1301
|
+
if (mode !== "keys") assert(await ctx.getSignedKeyOwner());
|
|
1302
|
+
assertEquals(loads, {
|
|
1303
|
+
key: 1,
|
|
1304
|
+
owner: mode === "keys" ? 0 : 1
|
|
1305
|
+
});
|
|
1306
|
+
});
|
|
1307
|
+
await t.step("memoizes null keys", async () => {
|
|
1308
|
+
exporter.clear();
|
|
1309
|
+
const { ctx, loads } = setup({ load: () => Promise.reject(/* @__PURE__ */ new Error("unavailable")) });
|
|
1310
|
+
for (let i = 0; i < 3; i++) {
|
|
1311
|
+
assertEquals(await ctx.getSignedKey(), null);
|
|
1312
|
+
assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1313
|
+
}
|
|
1314
|
+
assertEquals(loads, {
|
|
1315
|
+
key: 1,
|
|
1316
|
+
owner: 0
|
|
1317
|
+
});
|
|
1318
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 1);
|
|
1319
|
+
assert(await ctx.getSignedKey({ documentLoader: mockDocumentLoader }));
|
|
1320
|
+
assert(await ctx.getSignedKeyOwner({ documentLoader: mockDocumentLoader }));
|
|
1321
|
+
});
|
|
1322
|
+
await t.step("coalesces key-owner FetchError results", async () => {
|
|
1323
|
+
const { ctx, loads } = setup({ load: async (url, options) => {
|
|
1324
|
+
if (url === ownerId) throw new FetchError(new URL(url), "HTTP 401: Unauthorized");
|
|
1325
|
+
return await mockDocumentLoader(url, options);
|
|
1326
|
+
} });
|
|
1327
|
+
assert(await ctx.getSignedKey());
|
|
1328
|
+
assertEquals(await Promise.all(Array.from({ length: 8 }, () => ctx.getSignedKeyOwner())), Array(8).fill(null));
|
|
1329
|
+
assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1330
|
+
assertEquals(loads, {
|
|
1331
|
+
key: 1,
|
|
1332
|
+
owner: 1
|
|
1333
|
+
});
|
|
1334
|
+
assert(await ctx.getSignedKeyOwner({ documentLoader: mockDocumentLoader }));
|
|
1335
|
+
});
|
|
1336
|
+
await t.step("memoizes unsigned requests", async () => {
|
|
1337
|
+
exporter.clear();
|
|
1338
|
+
const { ctx, loads } = setup({ request: new Request("https://example.com/") });
|
|
1339
|
+
for (let i = 0; i < 3; i++) {
|
|
1340
|
+
assertEquals(await ctx.getSignedKey(), null);
|
|
1341
|
+
assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1342
|
+
}
|
|
1343
|
+
assertEquals(loads, {
|
|
1344
|
+
key: 0,
|
|
1345
|
+
owner: 0
|
|
1346
|
+
});
|
|
1347
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 1);
|
|
1348
|
+
});
|
|
1349
|
+
await t.step("memoizes null owners without trusting a key's owner claim", async () => {
|
|
1350
|
+
const { ctx, loads } = setup({ load: async (url, options) => url === ownerId ? {
|
|
1351
|
+
documentUrl: url,
|
|
1352
|
+
contextUrl: null,
|
|
1353
|
+
document: {
|
|
1354
|
+
...person2_default,
|
|
1355
|
+
publicKey: []
|
|
1356
|
+
}
|
|
1357
|
+
} : await mockDocumentLoader(url, options) });
|
|
1358
|
+
assert(await ctx.getSignedKey());
|
|
1359
|
+
assertEquals(await Promise.all(Array.from({ length: 8 }, () => ctx.getSignedKeyOwner())), Array(8).fill(null));
|
|
1360
|
+
for (let i = 0; i < 3; i++) assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1361
|
+
assertEquals(loads, {
|
|
1362
|
+
key: 1,
|
|
1363
|
+
owner: 1
|
|
1364
|
+
});
|
|
1365
|
+
assert(await ctx.getSignedKeyOwner({ documentLoader: mockDocumentLoader }));
|
|
1366
|
+
assert(await ctx.getSignedKeyOwner());
|
|
1367
|
+
});
|
|
1368
|
+
await t.step("isolates concurrent document loaders before success", async () => {
|
|
1369
|
+
const { ctx, loads } = setup();
|
|
1370
|
+
let otherLoads = 0;
|
|
1371
|
+
const otherLoader = async (url, options) => {
|
|
1372
|
+
otherLoads++;
|
|
1373
|
+
if (url === ownerId) return {
|
|
1374
|
+
documentUrl: url,
|
|
1375
|
+
contextUrl: null,
|
|
1376
|
+
document: {
|
|
1377
|
+
...person2_default,
|
|
1378
|
+
name: "Other view"
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1381
|
+
return await mockDocumentLoader(url, options);
|
|
1382
|
+
};
|
|
1383
|
+
const [first, second] = await Promise.all([ctx.getSignedKeyOwner(), ctx.getSignedKeyOwner({ documentLoader: otherLoader })]);
|
|
1384
|
+
assertEquals(first?.name, "Jane Doe");
|
|
1385
|
+
assertEquals(second?.name, "Other view");
|
|
1386
|
+
const cached = await ctx.getSignedKeyOwner();
|
|
1387
|
+
assert(cached === first || cached === second);
|
|
1388
|
+
assertStrictEquals(await ctx.getSignedKeyOwner({ documentLoader: otherLoader }), cached);
|
|
1389
|
+
assertEquals(loads, {
|
|
1390
|
+
key: 1,
|
|
1391
|
+
owner: 1
|
|
1392
|
+
});
|
|
1393
|
+
assertEquals(otherLoads, 2);
|
|
1394
|
+
});
|
|
1395
|
+
await t.step("preserves in-flight null while another loader succeeds", async () => {
|
|
1396
|
+
exporter.clear();
|
|
1397
|
+
let release;
|
|
1398
|
+
const gate = new Promise((resolve) => release = resolve);
|
|
1399
|
+
const { ctx, loads } = setup({ load: async () => {
|
|
1400
|
+
await gate;
|
|
1401
|
+
throw new TypeError("fetch failed");
|
|
1402
|
+
} });
|
|
1403
|
+
const failed = Promise.all([ctx.getSignedKey(), ctx.getSignedKeyOwner()]);
|
|
1404
|
+
const owner = await ctx.getSignedKeyOwner({ documentLoader: mockDocumentLoader });
|
|
1405
|
+
assert(owner);
|
|
1406
|
+
release();
|
|
1407
|
+
assertEquals(await failed, [null, null]);
|
|
1408
|
+
assertStrictEquals(await ctx.getSignedKeyOwner(), owner);
|
|
1409
|
+
assert(await ctx.getSignedKey());
|
|
1410
|
+
assertEquals(loads, {
|
|
1411
|
+
key: 1,
|
|
1412
|
+
owner: 0
|
|
1413
|
+
});
|
|
1414
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 2);
|
|
1415
|
+
});
|
|
1416
|
+
await t.step("isolates context loaders", async () => {
|
|
1417
|
+
exporter.clear();
|
|
1418
|
+
const { ctx, loads } = setup();
|
|
1419
|
+
const otherContextLoader = (url, options) => mockDocumentLoader(url, options);
|
|
1420
|
+
await Promise.all([ctx.getSignedKeyOwner(), ctx.getSignedKeyOwner({ contextLoader: otherContextLoader })]);
|
|
1421
|
+
assertEquals(loads, {
|
|
1422
|
+
key: 2,
|
|
1423
|
+
owner: 2
|
|
1424
|
+
});
|
|
1425
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 2);
|
|
1426
|
+
});
|
|
1427
|
+
await t.step("shares work across tracer providers", async () => {
|
|
1428
|
+
exporter.clear();
|
|
1429
|
+
const [otherProvider, otherExporter] = createTestTracerProvider();
|
|
1430
|
+
try {
|
|
1431
|
+
const { ctx, loads } = setup();
|
|
1432
|
+
await Promise.all([
|
|
1433
|
+
ctx.getSignedKeyOwner(),
|
|
1434
|
+
ctx.getSignedKeyOwner({ tracerProvider: otherProvider }),
|
|
1435
|
+
ctx.getSignedKey(),
|
|
1436
|
+
ctx.getSignedKey({ tracerProvider: otherProvider })
|
|
1437
|
+
]);
|
|
1438
|
+
assert(await ctx.getSignedKeyOwner({ tracerProvider: otherProvider }));
|
|
1439
|
+
assertEquals(loads, {
|
|
1440
|
+
key: 1,
|
|
1441
|
+
owner: 1
|
|
1442
|
+
});
|
|
1443
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 1);
|
|
1444
|
+
assertEquals(otherExporter.getSpans("http_signatures.verify").length, 0);
|
|
1445
|
+
} finally {
|
|
1446
|
+
await otherProvider.shutdown();
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
await t.step("reuses success with a fresh authorization loader", async () => {
|
|
1450
|
+
exporter.clear();
|
|
1451
|
+
const { ctx, loads } = setup();
|
|
1452
|
+
let freshLoads = 0;
|
|
1453
|
+
const freshLoader = (url, options) => {
|
|
1454
|
+
freshLoads++;
|
|
1455
|
+
return mockDocumentLoader(url, options);
|
|
1456
|
+
};
|
|
1457
|
+
const key = await ctx.getSignedKey({ documentLoader: freshLoader });
|
|
1458
|
+
assert(key);
|
|
1459
|
+
assertStrictEquals(await ctx.getSignedKey(), key);
|
|
1460
|
+
const owner = await ctx.getSignedKeyOwner();
|
|
1461
|
+
assert(owner);
|
|
1462
|
+
assertStrictEquals(await ctx.getSignedKeyOwner({ documentLoader: freshLoader }), owner);
|
|
1463
|
+
assertEquals(loads, {
|
|
1464
|
+
key: 0,
|
|
1465
|
+
owner: 1
|
|
1466
|
+
});
|
|
1467
|
+
assertEquals(freshLoads, 1);
|
|
1468
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 1);
|
|
1469
|
+
});
|
|
1470
|
+
await t.step("retains a transient owner lookup failure as null", async () => {
|
|
1471
|
+
let fail = true;
|
|
1472
|
+
const { ctx, loads } = setup({ load: async (url, options) => {
|
|
1473
|
+
if (url === ownerId && fail) throw new TypeError("fetch failed");
|
|
1474
|
+
return await mockDocumentLoader(url, options);
|
|
1475
|
+
} });
|
|
1476
|
+
assert(await ctx.getSignedKey());
|
|
1477
|
+
assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1478
|
+
fail = false;
|
|
1479
|
+
assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1480
|
+
assertEquals(loads, {
|
|
1481
|
+
key: 1,
|
|
1482
|
+
owner: 1
|
|
1483
|
+
});
|
|
1484
|
+
assert(await ctx.getSignedKeyOwner({ documentLoader: mockDocumentLoader }));
|
|
1485
|
+
});
|
|
1486
|
+
await t.step("rechecks an owner after another loader verifies the key", async () => {
|
|
1487
|
+
let fail = true;
|
|
1488
|
+
const { ctx, loads } = setup({ load: async (url, options) => {
|
|
1489
|
+
if (url === keyId && fail) throw new TypeError("fetch failed");
|
|
1490
|
+
return await mockDocumentLoader(url, options);
|
|
1491
|
+
} });
|
|
1492
|
+
assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1493
|
+
fail = false;
|
|
1494
|
+
assertEquals(await ctx.getSignedKeyOwner(), null);
|
|
1495
|
+
assertEquals(loads, {
|
|
1496
|
+
key: 1,
|
|
1497
|
+
owner: 0
|
|
1498
|
+
});
|
|
1499
|
+
assert(await ctx.getSignedKey({ documentLoader: mockDocumentLoader }));
|
|
1500
|
+
assertEquals((await ctx.getSignedKeyOwner())?.id?.href, ownerId);
|
|
1501
|
+
assertEquals(loads, {
|
|
1502
|
+
key: 1,
|
|
1503
|
+
owner: 1
|
|
1504
|
+
});
|
|
1505
|
+
});
|
|
1506
|
+
await t.step("retries unexpected key rejections from a rejection handler", async () => {
|
|
1507
|
+
exporter.clear();
|
|
1508
|
+
const failure = /* @__PURE__ */ new Error("transient context loader failure");
|
|
1509
|
+
let rejectContext = true;
|
|
1510
|
+
const contextLoader = async (url, options) => {
|
|
1511
|
+
if (rejectContext) throw failure;
|
|
1512
|
+
return await mockDocumentLoader(url, options);
|
|
1513
|
+
};
|
|
1514
|
+
const { ctx, loads } = setup();
|
|
1515
|
+
const options = { contextLoader };
|
|
1516
|
+
const failedKeys = Promise.allSettled([
|
|
1517
|
+
ctx.getSignedKey(options),
|
|
1518
|
+
ctx.getSignedKeyOwner(options),
|
|
1519
|
+
ctx.getSignedKey(options)
|
|
1520
|
+
]);
|
|
1521
|
+
const recovery = ctx.getSignedKey(options).catch(() => {
|
|
1522
|
+
rejectContext = false;
|
|
1523
|
+
return ctx.getSignedKey(options);
|
|
1524
|
+
});
|
|
1525
|
+
for (const result of await failedKeys) assertEquals(result.status, "rejected");
|
|
1526
|
+
assert(await recovery);
|
|
1527
|
+
assertEquals(loads, {
|
|
1528
|
+
key: 2,
|
|
1529
|
+
owner: 0
|
|
1530
|
+
});
|
|
1531
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 2);
|
|
1532
|
+
});
|
|
1533
|
+
await t.step("retries owner rejections while retaining the verified key", async () => {
|
|
1534
|
+
exporter.clear();
|
|
1535
|
+
let rejectContext = false;
|
|
1536
|
+
const contextLoader = async (url, options) => {
|
|
1537
|
+
if (rejectContext) throw new Error("transient owner context failure");
|
|
1538
|
+
return await mockDocumentLoader(url, options);
|
|
1539
|
+
};
|
|
1540
|
+
const { ctx, loads } = setup();
|
|
1541
|
+
const options = { contextLoader };
|
|
1542
|
+
assert(await ctx.getSignedKey(options));
|
|
1543
|
+
assertEquals(loads, {
|
|
1544
|
+
key: 1,
|
|
1545
|
+
owner: 0
|
|
1546
|
+
});
|
|
1547
|
+
rejectContext = true;
|
|
1548
|
+
const failures = await Promise.allSettled([ctx.getSignedKeyOwner(options), ctx.getSignedKeyOwner(options)]);
|
|
1549
|
+
for (const result of failures) assertEquals(result.status, "rejected");
|
|
1550
|
+
assertEquals(loads, {
|
|
1551
|
+
key: 1,
|
|
1552
|
+
owner: 1
|
|
1553
|
+
});
|
|
1554
|
+
rejectContext = false;
|
|
1555
|
+
assert(await ctx.getSignedKeyOwner(options));
|
|
1556
|
+
assertEquals(loads, {
|
|
1557
|
+
key: 1,
|
|
1558
|
+
owner: 2
|
|
1559
|
+
});
|
|
1560
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 1);
|
|
1561
|
+
});
|
|
1562
|
+
await t.step("keeps clones and separate requests independent", async () => {
|
|
1563
|
+
exporter.clear();
|
|
1564
|
+
const { ctx, loads, federation } = setup();
|
|
1565
|
+
assert(await ctx.getSignedKeyOwner());
|
|
1566
|
+
const clone = ctx.clone(void 0);
|
|
1567
|
+
const separate = federation.createContext(new Request(request), void 0);
|
|
1568
|
+
await Promise.all([clone.getSignedKeyOwner(), separate.getSignedKeyOwner()]);
|
|
1569
|
+
assertEquals(loads, {
|
|
1570
|
+
key: 3,
|
|
1571
|
+
owner: 3
|
|
1572
|
+
});
|
|
1573
|
+
assertEquals(exporter.getSpans("http_signatures.verify").length, 3);
|
|
1574
|
+
});
|
|
1575
|
+
} finally {
|
|
1576
|
+
await tracerProvider.shutdown();
|
|
1577
|
+
}
|
|
1578
|
+
});
|
|
1237
1579
|
test("Federation.fetch() [rfc9421] multiple POST signatures", async (t) => {
|
|
1238
1580
|
for (const validSecond of [true, false]) await t.step(validSecond ? "valid second signature" : "both signatures invalid", async () => {
|
|
1239
1581
|
const inbox = [];
|
|
@@ -1277,7 +1619,7 @@ test("Federation.fetch()", async (t) => {
|
|
|
1277
1619
|
kv,
|
|
1278
1620
|
documentLoaderFactory: () => mockDocumentLoader,
|
|
1279
1621
|
authenticatedDocumentLoaderFactory(identity) {
|
|
1280
|
-
const docLoader = getAuthenticatedDocumentLoader(identity);
|
|
1622
|
+
const docLoader = getAuthenticatedDocumentLoader(identity, { allowPrivateAddress: true });
|
|
1281
1623
|
return (url) => {
|
|
1282
1624
|
if (new URL(url).host === "example.com") return docLoader(url);
|
|
1283
1625
|
return mockDocumentLoader(url);
|
|
@@ -1728,7 +2070,7 @@ test("Federation.setInboxListeners()", async (t) => {
|
|
|
1728
2070
|
kv,
|
|
1729
2071
|
documentLoaderFactory: () => mockDocumentLoader,
|
|
1730
2072
|
authenticatedDocumentLoaderFactory(identity) {
|
|
1731
|
-
const docLoader = getAuthenticatedDocumentLoader(identity);
|
|
2073
|
+
const docLoader = getAuthenticatedDocumentLoader(identity, { allowPrivateAddress: true });
|
|
1732
2074
|
return (url) => {
|
|
1733
2075
|
const urlObj = new URL(url);
|
|
1734
2076
|
authenticatedRequests.push([url, identity.keyId.href]);
|
|
@@ -2051,7 +2393,7 @@ test("Federation.setInboxListeners()", async (t) => {
|
|
|
2051
2393
|
kv,
|
|
2052
2394
|
documentLoaderFactory: () => mockDocumentLoader,
|
|
2053
2395
|
authenticatedDocumentLoaderFactory(identity) {
|
|
2054
|
-
const docLoader = getAuthenticatedDocumentLoader(identity);
|
|
2396
|
+
const docLoader = getAuthenticatedDocumentLoader(identity, { allowPrivateAddress: true });
|
|
2055
2397
|
return (url) => {
|
|
2056
2398
|
if (new URL(url).host === "example.com") return docLoader(url);
|
|
2057
2399
|
return mockDocumentLoader(url);
|
|
@@ -2264,10 +2606,11 @@ test("Federation.setOutboxListeners()", async (t) => {
|
|
|
2264
2606
|
sinks: ["buffer"]
|
|
2265
2607
|
}]
|
|
2266
2608
|
});
|
|
2267
|
-
const federation =
|
|
2609
|
+
const federation = new FederationImpl({
|
|
2268
2610
|
kv,
|
|
2269
2611
|
documentLoaderFactory: () => mockDocumentLoader
|
|
2270
2612
|
});
|
|
2613
|
+
federation.allowPrivateAddress = true;
|
|
2271
2614
|
federation.setActorDispatcher("/users/{identifier}", (_ctx, identifier) => identifier === "john" ? new vocab.Person({}) : null).setKeyPairsDispatcher(() => [{
|
|
2272
2615
|
privateKey: rsaPrivateKey2,
|
|
2273
2616
|
publicKey: rsaPublicKey2.publicKey
|
|
@@ -2370,10 +2713,11 @@ test("Federation.setOutboxListeners()", async (t) => {
|
|
|
2370
2713
|
sinks: ["buffer"]
|
|
2371
2714
|
}]
|
|
2372
2715
|
});
|
|
2373
|
-
const federation =
|
|
2716
|
+
const federation = new FederationImpl({
|
|
2374
2717
|
kv,
|
|
2375
2718
|
documentLoaderFactory: () => mockDocumentLoader
|
|
2376
2719
|
});
|
|
2720
|
+
federation.allowPrivateAddress = true;
|
|
2377
2721
|
federation.setActorDispatcher("/{identifier}", (_ctx, identifier) => identifier === "person2" ? new vocab.Person({}) : null).setKeyPairsDispatcher(() => [{
|
|
2378
2722
|
privateKey: rsaPrivateKey2,
|
|
2379
2723
|
publicKey: rsaPublicKey2.publicKey
|
|
@@ -2605,7 +2949,7 @@ test("FederationImpl.sendActivity()", async (t) => {
|
|
|
2605
2949
|
});
|
|
2606
2950
|
const federation = new FederationImpl({
|
|
2607
2951
|
kv: new MemoryKvStore(),
|
|
2608
|
-
|
|
2952
|
+
allowPrivateAddress: true
|
|
2609
2953
|
});
|
|
2610
2954
|
const context = federation.createContext(new URL("https://example.com/"));
|
|
2611
2955
|
await t.step("success", async () => {
|
|
@@ -6193,7 +6537,7 @@ test("ContextImpl.sendActivity()", async (t) => {
|
|
|
6193
6537
|
const kv = new MemoryKvStore();
|
|
6194
6538
|
const federation = new FederationImpl({
|
|
6195
6539
|
kv,
|
|
6196
|
-
|
|
6540
|
+
allowPrivateAddress: true
|
|
6197
6541
|
});
|
|
6198
6542
|
federation.setActorDispatcher("/{identifier}", async (ctx, identifier) => {
|
|
6199
6543
|
if (identifier !== "1") return null;
|
|
@@ -6316,11 +6660,13 @@ test("ContextImpl.sendActivity()", async (t) => {
|
|
|
6316
6660
|
});
|
|
6317
6661
|
await t.step("records recipient span attributes correctly", async () => {
|
|
6318
6662
|
const [tracerProvider, exporter] = createTestTracerProvider();
|
|
6319
|
-
const
|
|
6663
|
+
const federation3 = new FederationImpl({
|
|
6320
6664
|
kv,
|
|
6321
6665
|
contextLoaderFactory: () => mockDocumentLoader,
|
|
6322
6666
|
tracerProvider
|
|
6323
|
-
})
|
|
6667
|
+
});
|
|
6668
|
+
federation3.allowPrivateAddress = true;
|
|
6669
|
+
const ctx = federation3.createContext(new URL("https://example.com/"), void 0);
|
|
6324
6670
|
const activity = new vocab.Create({
|
|
6325
6671
|
id: new URL("https://example.com/activity/telemetry"),
|
|
6326
6672
|
actor: new URL("https://example.com/person"),
|
|
@@ -6354,7 +6700,7 @@ test("ContextImpl.sendActivity()", async (t) => {
|
|
|
6354
6700
|
};
|
|
6355
6701
|
const federation2 = new FederationImpl({
|
|
6356
6702
|
kv,
|
|
6357
|
-
|
|
6703
|
+
allowPrivateAddress: true,
|
|
6358
6704
|
queue
|
|
6359
6705
|
});
|
|
6360
6706
|
federation2.setActorDispatcher("/{identifier}", async (ctx, identifier) => {
|
|
@@ -6525,7 +6871,7 @@ test("ContextImpl.sendActivity()", async (t) => {
|
|
|
6525
6871
|
const asyncEnqueued = [];
|
|
6526
6872
|
const fed = new FederationImpl({
|
|
6527
6873
|
kv,
|
|
6528
|
-
|
|
6874
|
+
allowPrivateAddress: true,
|
|
6529
6875
|
queue: {
|
|
6530
6876
|
enqueue(message) {
|
|
6531
6877
|
return new Promise((resolve) => {
|
|
@@ -6752,10 +7098,10 @@ test({
|
|
|
6752
7098
|
const signedInvite = await signObject(new vocab.Invite({ actor: new URL("https://example.com/person2") }), ed25519PrivateKey, ed25519Multikey.id);
|
|
6753
7099
|
assert(await ctx.routeActivity("id", signedInvite));
|
|
6754
7100
|
assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
|
|
6755
|
-
assertFalse(await ctx.routeActivity(null, new vocab.Create({
|
|
7101
|
+
assertFalse(await withDnsLookup(() => Promise.reject(/* @__PURE__ */ new Error("Resolver unavailable")), () => ctx.routeActivity(null, new vocab.Create({
|
|
6756
7102
|
id: new URL("https://example.com/not-found"),
|
|
6757
7103
|
actor: new URL("https://example.com/person")
|
|
6758
|
-
})));
|
|
7104
|
+
}))));
|
|
6759
7105
|
assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
|
|
6760
7106
|
assertFalse(await ctx.routeActivity(null, new vocab.Create({
|
|
6761
7107
|
id: new URL("https://example.com/person"),
|
|
@@ -7261,7 +7607,7 @@ test("InboxContextImpl.forwardActivity()", async (t) => {
|
|
|
7261
7607
|
const kv = new MemoryKvStore();
|
|
7262
7608
|
const federation = new FederationImpl({
|
|
7263
7609
|
kv,
|
|
7264
|
-
|
|
7610
|
+
allowPrivateAddress: true
|
|
7265
7611
|
});
|
|
7266
7612
|
await t.step("skip", async () => {
|
|
7267
7613
|
await new InboxContextImpl(null, {
|
|
@@ -7384,6 +7730,7 @@ test("InboxContextImpl.forwardActivity()", async (t) => {
|
|
|
7384
7730
|
contextLoaderFactory: () => mockDocumentLoader,
|
|
7385
7731
|
tracerProvider
|
|
7386
7732
|
});
|
|
7733
|
+
federationWithTracing.allowPrivateAddress = true;
|
|
7387
7734
|
await new InboxContextImpl(null, await signJsonLd({
|
|
7388
7735
|
"@context": "https://www.w3.org/ns/activitystreams",
|
|
7389
7736
|
"type": "Create",
|
|
@@ -7576,5 +7923,19 @@ test("Federation.fetch() bounds inbox bodies before dispatch", async () => {
|
|
|
7576
7923
|
}), { contextData: void 0 })).status, 202);
|
|
7577
7924
|
assert(dispatched);
|
|
7578
7925
|
});
|
|
7926
|
+
/**
|
|
7927
|
+
* Runs the given function while `node:dns/promises`' `lookup()`, which the
|
|
7928
|
+
* default public fetch resolves hostnames with, is replaced, so that no test
|
|
7929
|
+
* depends on the real DNS.
|
|
7930
|
+
*/
|
|
7931
|
+
async function withDnsLookup(lookup, fn) {
|
|
7932
|
+
const originalLookup = dns.lookup;
|
|
7933
|
+
dns.lookup = lookup;
|
|
7934
|
+
try {
|
|
7935
|
+
return await fn();
|
|
7936
|
+
} finally {
|
|
7937
|
+
dns.lookup = originalLookup;
|
|
7938
|
+
}
|
|
7939
|
+
}
|
|
7579
7940
|
//#endregion
|
|
7580
7941
|
export {};
|
package/dist/federation/mod.cjs
CHANGED
|
@@ -2,7 +2,7 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
4
|
require("../chunk-DDcVe30Y.cjs");
|
|
5
|
-
const require_middleware = require("../middleware-
|
|
5
|
+
const require_middleware = require("../middleware-4yPyyoF5.cjs");
|
|
6
6
|
let _logtape_logtape = require("@logtape/logtape");
|
|
7
7
|
let _fedify_uri_template = require("@fedify/uri-template");
|
|
8
8
|
let es_toolkit = require("es-toolkit");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as CustomCollectionCursor, A as Rfc6570Expression, At as parseCircuitBreakerKvState, B as createFederationBuilder, C as FederationStartQueueOptions, Ct as CircuitBreakerFailurePolicy, D as InboxListenerSetters, Dt as CircuitBreakerStateChange, E as InboxChallengePolicy, Et as CircuitBreakerState, F as CreateExponentialBackoffPolicyOptions, G as ActorDispatcher, H as respondWithObject, I as RetryContext, J as AuthorizePredicate, K as ActorHandleMapper, L as RetryPolicy, M as FederationOrigin, N as FederationQueueOptions, O as ObjectCallbackSetters, Ot as NormalizedCircuitBreakerOptions, P as createFederation, Q as CustomCollectionCounter, R as createExponentialBackoffPolicy, S as FederationOptions, St as CircuitBreakerCreateOptions, T as IdempotencyStrategy, Tt as CircuitBreakerOptions, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as ActorAliasMapper, X as CollectionCursor, Y as CollectionCounter, Z as CollectionDispatcher, _ as Federatable, _t as buildCollectionSynchronizationHeader, a as GetSignedKeyOptions, at as ObjectDispatcher, b as FederationBuilder, bt as CircuitBreakerActivityDrop, c as ParseUriResult, ct as OutboxListenerErrorHandler, d as SendActivityOptions, dt as UnverifiedActivityHandler, et as CustomCollectionDispatcher, f as SendActivityOptionsForCollection, ft as UnverifiedActivityReason, g as CustomCollectionCallbackSetters, gt as PageItems, h as ConstructorWithTypeId, ht as SenderKeyPair, i as GetActorOptions, it as ObjectAuthorizePredicate, j as FederationKvPrefixes, k as OutboxListenerSetters, kt as normalizeCircuitBreakerOptions, l as RequestContext, lt as OutboxPermanentFailureHandler, m as CollectionCallbackSetters, mt as SendActivityError, n as Context, nt as InboxListener, o as InboxContext, ot as OutboxErrorHandler, p as ActorCallbackSetters, pt as WebFingerLinksDispatcher, q as ActorKeyPairsDispatcher, r as ForwardActivityOptions, rt as NodeInfoDispatcher, s as OutboxContext, st as OutboxListener, t as ActorKeyPair, tt as InboxErrorHandler, u as RouteActivityOptions, ut as SharedInboxKeyDispatcher, v as Federation, vt as digest, w as IdempotencyKeyCallback, wt as CircuitBreakerKvState, x as FederationFetchOptions, xt as CircuitBreakerBeforeSendDecision, y as FederationBenchmarkOptions, yt as CircuitBreaker, z as Message } from "../context-
|
|
2
|
+
import { $ as CustomCollectionCursor, A as Rfc6570Expression, At as parseCircuitBreakerKvState, B as createFederationBuilder, C as FederationStartQueueOptions, Ct as CircuitBreakerFailurePolicy, D as InboxListenerSetters, Dt as CircuitBreakerStateChange, E as InboxChallengePolicy, Et as CircuitBreakerState, F as CreateExponentialBackoffPolicyOptions, G as ActorDispatcher, H as respondWithObject, I as RetryContext, J as AuthorizePredicate, K as ActorHandleMapper, L as RetryPolicy, M as FederationOrigin, N as FederationQueueOptions, O as ObjectCallbackSetters, Ot as NormalizedCircuitBreakerOptions, P as createFederation, Q as CustomCollectionCounter, R as createExponentialBackoffPolicy, S as FederationOptions, St as CircuitBreakerCreateOptions, T as IdempotencyStrategy, Tt as CircuitBreakerOptions, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as ActorAliasMapper, X as CollectionCursor, Y as CollectionCounter, Z as CollectionDispatcher, _ as Federatable, _t as buildCollectionSynchronizationHeader, a as GetSignedKeyOptions, at as ObjectDispatcher, b as FederationBuilder, bt as CircuitBreakerActivityDrop, c as ParseUriResult, ct as OutboxListenerErrorHandler, d as SendActivityOptions, dt as UnverifiedActivityHandler, et as CustomCollectionDispatcher, f as SendActivityOptionsForCollection, ft as UnverifiedActivityReason, g as CustomCollectionCallbackSetters, gt as PageItems, h as ConstructorWithTypeId, ht as SenderKeyPair, i as GetActorOptions, it as ObjectAuthorizePredicate, j as FederationKvPrefixes, k as OutboxListenerSetters, kt as normalizeCircuitBreakerOptions, l as RequestContext, lt as OutboxPermanentFailureHandler, m as CollectionCallbackSetters, mt as SendActivityError, n as Context, nt as InboxListener, o as InboxContext, ot as OutboxErrorHandler, p as ActorCallbackSetters, pt as WebFingerLinksDispatcher, q as ActorKeyPairsDispatcher, r as ForwardActivityOptions, rt as NodeInfoDispatcher, s as OutboxContext, st as OutboxListener, t as ActorKeyPair, tt as InboxErrorHandler, u as RouteActivityOptions, ut as SharedInboxKeyDispatcher, v as Federation, vt as digest, w as IdempotencyKeyCallback, wt as CircuitBreakerKvState, x as FederationFetchOptions, xt as CircuitBreakerBeforeSendDecision, y as FederationBenchmarkOptions, yt as CircuitBreaker, z as Message } from "../context-CE_Tj_Oc.cjs";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-CZKl1IUS.cjs";
|
|
4
4
|
import { a as MessageQueueEnqueueOptions, i as MessageQueueDepth, n as InProcessMessageQueueOptions, o as MessageQueueListenOptions, r as MessageQueue, s as ParallelMessageQueue, t as InProcessMessageQueue } from "../mq-D8uSFzxe.cjs";
|
|
5
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
5
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-DDjtbkZO.cjs";
|
|
6
6
|
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CircuitBreaker, CircuitBreakerActivityDrop, CircuitBreakerBeforeSendDecision, CircuitBreakerCreateOptions, CircuitBreakerFailurePolicy, CircuitBreakerKvState, CircuitBreakerOptions, CircuitBreakerState, CircuitBreakerStateChange, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBenchmarkOptions, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetActorOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MemoryKvStore, Message, MessageQueue, MessageQueueDepth, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, NormalizedCircuitBreakerOptions, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxContext, OutboxErrorHandler, OutboxListener, OutboxListenerErrorHandler, OutboxListenerSetters, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as CustomCollectionCursor, A as Rfc6570Expression, At as parseCircuitBreakerKvState, B as createFederationBuilder, C as FederationStartQueueOptions, Ct as CircuitBreakerFailurePolicy, D as InboxListenerSetters, Dt as CircuitBreakerStateChange, E as InboxChallengePolicy, Et as CircuitBreakerState, F as CreateExponentialBackoffPolicyOptions, G as ActorDispatcher, H as respondWithObject, I as RetryContext, J as AuthorizePredicate, K as ActorHandleMapper, L as RetryPolicy, M as FederationOrigin, N as FederationQueueOptions, O as ObjectCallbackSetters, Ot as NormalizedCircuitBreakerOptions, P as createFederation, Q as CustomCollectionCounter, R as createExponentialBackoffPolicy, S as FederationOptions, St as CircuitBreakerCreateOptions, T as IdempotencyStrategy, Tt as CircuitBreakerOptions, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as ActorAliasMapper, X as CollectionCursor, Y as CollectionCounter, Z as CollectionDispatcher, _ as Federatable, _t as buildCollectionSynchronizationHeader, a as GetSignedKeyOptions, at as ObjectDispatcher, b as FederationBuilder, bt as CircuitBreakerActivityDrop, c as ParseUriResult, ct as OutboxListenerErrorHandler, d as SendActivityOptions, dt as UnverifiedActivityHandler, et as CustomCollectionDispatcher, f as SendActivityOptionsForCollection, ft as UnverifiedActivityReason, g as CustomCollectionCallbackSetters, gt as PageItems, h as ConstructorWithTypeId, ht as SenderKeyPair, i as GetActorOptions, it as ObjectAuthorizePredicate, j as FederationKvPrefixes, k as OutboxListenerSetters, kt as normalizeCircuitBreakerOptions, l as RequestContext, lt as OutboxPermanentFailureHandler, m as CollectionCallbackSetters, mt as SendActivityError, n as Context, nt as InboxListener, o as InboxContext, ot as OutboxErrorHandler, p as ActorCallbackSetters, pt as WebFingerLinksDispatcher, q as ActorKeyPairsDispatcher, r as ForwardActivityOptions, rt as NodeInfoDispatcher, s as OutboxContext, st as OutboxListener, t as ActorKeyPair, tt as InboxErrorHandler, u as RouteActivityOptions, ut as SharedInboxKeyDispatcher, v as Federation, vt as digest, w as IdempotencyKeyCallback, wt as CircuitBreakerKvState, x as FederationFetchOptions, xt as CircuitBreakerBeforeSendDecision, y as FederationBenchmarkOptions, yt as CircuitBreaker, z as Message } from "../context-
|
|
2
|
+
import { $ as CustomCollectionCursor, A as Rfc6570Expression, At as parseCircuitBreakerKvState, B as createFederationBuilder, C as FederationStartQueueOptions, Ct as CircuitBreakerFailurePolicy, D as InboxListenerSetters, Dt as CircuitBreakerStateChange, E as InboxChallengePolicy, Et as CircuitBreakerState, F as CreateExponentialBackoffPolicyOptions, G as ActorDispatcher, H as respondWithObject, I as RetryContext, J as AuthorizePredicate, K as ActorHandleMapper, L as RetryPolicy, M as FederationOrigin, N as FederationQueueOptions, O as ObjectCallbackSetters, Ot as NormalizedCircuitBreakerOptions, P as createFederation, Q as CustomCollectionCounter, R as createExponentialBackoffPolicy, S as FederationOptions, St as CircuitBreakerCreateOptions, T as IdempotencyStrategy, Tt as CircuitBreakerOptions, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as ActorAliasMapper, X as CollectionCursor, Y as CollectionCounter, Z as CollectionDispatcher, _ as Federatable, _t as buildCollectionSynchronizationHeader, a as GetSignedKeyOptions, at as ObjectDispatcher, b as FederationBuilder, bt as CircuitBreakerActivityDrop, c as ParseUriResult, ct as OutboxListenerErrorHandler, d as SendActivityOptions, dt as UnverifiedActivityHandler, et as CustomCollectionDispatcher, f as SendActivityOptionsForCollection, ft as UnverifiedActivityReason, g as CustomCollectionCallbackSetters, gt as PageItems, h as ConstructorWithTypeId, ht as SenderKeyPair, i as GetActorOptions, it as ObjectAuthorizePredicate, j as FederationKvPrefixes, k as OutboxListenerSetters, kt as normalizeCircuitBreakerOptions, l as RequestContext, lt as OutboxPermanentFailureHandler, m as CollectionCallbackSetters, mt as SendActivityError, n as Context, nt as InboxListener, o as InboxContext, ot as OutboxErrorHandler, p as ActorCallbackSetters, pt as WebFingerLinksDispatcher, q as ActorKeyPairsDispatcher, r as ForwardActivityOptions, rt as NodeInfoDispatcher, s as OutboxContext, st as OutboxListener, t as ActorKeyPair, tt as InboxErrorHandler, u as RouteActivityOptions, ut as SharedInboxKeyDispatcher, v as Federation, vt as digest, w as IdempotencyKeyCallback, wt as CircuitBreakerKvState, x as FederationFetchOptions, xt as CircuitBreakerBeforeSendDecision, y as FederationBenchmarkOptions, yt as CircuitBreaker, z as Message } from "../context-H_5tZXg-.js";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-CxaI4eGo.js";
|
|
4
4
|
import { a as MessageQueueEnqueueOptions, i as MessageQueueDepth, n as InProcessMessageQueueOptions, o as MessageQueueListenOptions, r as MessageQueue, s as ParallelMessageQueue, t as InProcessMessageQueue } from "../mq-D-nlpY04.js";
|
|
5
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
5
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-CDFFESfL.js";
|
|
6
6
|
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CircuitBreaker, CircuitBreakerActivityDrop, CircuitBreakerBeforeSendDecision, CircuitBreakerCreateOptions, CircuitBreakerFailurePolicy, CircuitBreakerKvState, CircuitBreakerOptions, CircuitBreakerState, CircuitBreakerStateChange, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBenchmarkOptions, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetActorOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MemoryKvStore, Message, MessageQueue, MessageQueueDepth, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, NormalizedCircuitBreakerOptions, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxContext, OutboxErrorHandler, OutboxListener, OutboxListenerErrorHandler, OutboxListenerSetters, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "../middleware-
|
|
3
|
+
import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "../middleware-DhN7c65B.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import { Router as Router$1, RouterError as RouterError$1, assertPath, isPath } from "@fedify/uri-template";
|
|
6
6
|
import { isEqual } from "es-toolkit";
|