@fedify/fedify 2.4.0-dev.1599 → 2.4.0-dev.1634
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-BvCI7Xch.mjs → builder-DYAAegyy.mjs} +24 -2
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{context-C7Sbmci2.mjs → context-BJXxPElm.mjs} +2 -1
- package/dist/{context-GfQA-CqB.d.ts → context-Zii1f5xS.d.ts} +97 -1
- package/dist/{context-BLe0NPtZ.d.cts → context-lxX6I7as.d.cts} +97 -1
- package/dist/{deno-BCt09TJn.mjs → deno-C30u61BX.mjs} +1 -1
- package/dist/{docloader-BrRjFwOp.mjs → docloader-C8JfZ3bD.mjs} +2 -2
- package/dist/federation/builder.test.mjs +11 -1
- package/dist/federation/handler.test.mjs +6 -4
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +456 -8
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +3 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +2 -2
- package/dist/federation/tasks/tasks.test.mjs +3 -3
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +2 -2
- package/dist/{http-yainOC9t.mjs → http-DJEaNMSB.mjs} +3 -3
- package/dist/{http--wLYmH1x.js → http-D_cl_PbN.js} +1 -1
- package/dist/{http-zJsVCnKu.cjs → http-DiMJDFtd.cjs} +1 -1
- package/dist/{key-DcLwG7x4.mjs → key-C1tsoBAW.mjs} +2 -2
- package/dist/{kv-cache-BPu_M3-N.cjs → kv-cache-BInLi0Ro.cjs} +1 -1
- package/dist/{kv-cache-SZL9uu3V.mjs → kv-cache-D9Tia3Td.mjs} +1 -1
- package/dist/{kv-cache-0TGAGm8S.js → kv-cache-EL9jIFqA.js} +1 -1
- package/dist/{ld-B-jskR-q.mjs → ld-CDBNQmZD.mjs} +3 -3
- package/dist/{metrics-C-pKLuAU.mjs → metrics-De7b7Hgb.mjs} +1 -1
- package/dist/{middleware-D1POKL1d.js → middleware-8oyKaRYF.js} +245 -3
- package/dist/{middleware-DLzOFLD5.cjs → middleware-BPHpdYl4.cjs} +245 -3
- package/dist/{middleware-DGEQ07xT.mjs → middleware-CPlgpBML.mjs} +232 -12
- package/dist/{middleware-HFQkD-r8.mjs → middleware-DloBgcWp.mjs} +1 -1
- package/dist/{mod-Cmr39iWq.d.ts → mod-DLc2Ot6f.d.ts} +1 -1
- package/dist/{mod-B8Efb9qp.d.cts → mod-gOlPDuT8.d.cts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +4 -4
- package/dist/mod.d.ts +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/{owner-CeJuB8wq.mjs → owner-CB3dPva0.mjs} +2 -2
- package/dist/{proof-BkQosXrd.cjs → proof-BI4Wn6Ur.cjs} +13 -2
- package/dist/{proof-917XYw_e.mjs → proof-BqDtIxGz.mjs} +16 -4
- package/dist/{proof-Bri1zUVM.js → proof-DT5SgzkH.js} +14 -3
- package/dist/{send-CDi3XQ0V.mjs → send-ClWims8x.mjs} +3 -3
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +138 -1
- package/dist/{temporal-jusSJxbN.mjs → temporal-DyITEDcU.mjs} +1 -1
- package/dist/testing/mod.d.mts +96 -0
- package/dist/testing/mod.mjs +2 -2
- package/dist/{testing-C3vgUK0b.mjs → testing-CO7ftO8A.mjs} +1 -1
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +7 -7
|
@@ -3,7 +3,7 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as esm_default } from "../esm-yYQfPhIY.mjs";
|
|
5
5
|
import { t as MemoryKvStore } from "../kv-CXBAok3k.mjs";
|
|
6
|
-
import { a as numberSchema, r as envelopeSchema, t as MockQueue } from "../testing-
|
|
6
|
+
import { a as numberSchema, r as envelopeSchema, t as MockQueue } from "../testing-CO7ftO8A.mjs";
|
|
7
7
|
import { t as assertEquals } from "../assert_equals-BV7oLMxm.mjs";
|
|
8
8
|
import { r as assertExists } from "../std__assert-B2NnY9bq.mjs";
|
|
9
9
|
import { r as assertFalse, t as assertRejects } from "../assert_rejects-EgstcQy5.mjs";
|
|
@@ -12,14 +12,14 @@ import { t as assertThrows } from "../assert_throws-NiFfqbnH.mjs";
|
|
|
12
12
|
import { t as assertNotEquals } from "../assert_not_equals-EPJPoxuf.mjs";
|
|
13
13
|
import { t as assertStrictEquals } from "../assert_strict_equals-Ec20AUwa.mjs";
|
|
14
14
|
import { t as assert } from "../assert-CJ1KXcvv.mjs";
|
|
15
|
-
import { g as recordInboxActivity } from "../metrics-
|
|
16
|
-
import { l as verifyRequest, s as signRequest } from "../http-
|
|
15
|
+
import { g as recordInboxActivity } from "../metrics-De7b7Hgb.mjs";
|
|
16
|
+
import { l as verifyRequest, s as signRequest } from "../http-DJEaNMSB.mjs";
|
|
17
17
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-Dbyd7bhl.mjs";
|
|
18
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
19
|
-
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-
|
|
20
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
21
|
-
import { i as verifyObject, r as signObject } from "../proof-
|
|
22
|
-
import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-
|
|
18
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-C8JfZ3bD.mjs";
|
|
19
|
+
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-CDBNQmZD.mjs";
|
|
20
|
+
import { t as doesActorOwnKey } from "../owner-CB3dPva0.mjs";
|
|
21
|
+
import { i as verifyObject, r as signObject } from "../proof-BqDtIxGz.mjs";
|
|
22
|
+
import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-CPlgpBML.mjs";
|
|
23
23
|
import { t as CircuitBreaker } from "../circuit-breaker-CBGyz5F7.mjs";
|
|
24
24
|
import { t as TaskCodec } from "../codec-BBga-FWI.mjs";
|
|
25
25
|
import { configure, reset } from "@logtape/logtape";
|
|
@@ -2417,6 +2417,454 @@ test("Federation.setOutboxListeners()", async (t) => {
|
|
|
2417
2417
|
assertEquals(enqueuedMetrics[0].attributes["fedify.queue.task.attempt"], 0);
|
|
2418
2418
|
});
|
|
2419
2419
|
});
|
|
2420
|
+
function makeUploadForm(options = {}) {
|
|
2421
|
+
const { file = true, object = JSON.stringify({
|
|
2422
|
+
"@context": "https://www.w3.org/ns/activitystreams",
|
|
2423
|
+
type: "Image",
|
|
2424
|
+
name: "A cat"
|
|
2425
|
+
}) } = options;
|
|
2426
|
+
const form = new FormData();
|
|
2427
|
+
if (file) form.append("file", new File([new Uint8Array([
|
|
2428
|
+
1,
|
|
2429
|
+
2,
|
|
2430
|
+
3
|
|
2431
|
+
])], "cat.png", { type: "image/png" }));
|
|
2432
|
+
if (object != null) form.append("object", new Blob([object], { type: "application/json" }));
|
|
2433
|
+
return form;
|
|
2434
|
+
}
|
|
2435
|
+
test("Federation.setMediaUploader()", async (t) => {
|
|
2436
|
+
const kv = new MemoryKvStore();
|
|
2437
|
+
await t.step("path validation", () => {
|
|
2438
|
+
const federation = createFederation({
|
|
2439
|
+
kv,
|
|
2440
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2441
|
+
});
|
|
2442
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2443
|
+
assertThrows(() => federation.setMediaUploader("/users/{identifier}/media2", () => Promise.resolve(new URL("https://example.com/"))), RouterError);
|
|
2444
|
+
});
|
|
2445
|
+
await t.step("getMediaUploaderUri() builds the endpoint URI", () => {
|
|
2446
|
+
const federation = createFederation({
|
|
2447
|
+
kv,
|
|
2448
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2449
|
+
});
|
|
2450
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2451
|
+
assertEquals(federation.createContext(new URL("https://example.com/"), void 0).getMediaUploaderUri("alice").href, "https://example.com/users/alice/media");
|
|
2452
|
+
});
|
|
2453
|
+
await t.step("returns 201 Created when the callback returns an object", async () => {
|
|
2454
|
+
const federation = createFederation({
|
|
2455
|
+
kv,
|
|
2456
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2457
|
+
});
|
|
2458
|
+
federation.setActorDispatcher("/users/{identifier}", (_ctx, identifier) => identifier === "john" ? new vocab.Person({}) : null);
|
|
2459
|
+
federation.setObjectDispatcher(vocab.Image, "/objects/{uuid}", (_ctx, values) => new vocab.Image({ name: `Image ${values.uuid}` }));
|
|
2460
|
+
let receivedFileType;
|
|
2461
|
+
let receivedName;
|
|
2462
|
+
federation.setMediaUploader("/users/{identifier}/media", (ctx, _identifier, file, object) => {
|
|
2463
|
+
receivedFileType = file.type;
|
|
2464
|
+
receivedName = typeof object.name === "string" ? object.name : object.name?.toString();
|
|
2465
|
+
return Promise.resolve(new vocab.Image({
|
|
2466
|
+
id: ctx.getObjectUri(vocab.Image, { uuid: "abc" }),
|
|
2467
|
+
url: new URL("https://example.com/files/abc.png"),
|
|
2468
|
+
mediaType: file.type,
|
|
2469
|
+
name: object.name
|
|
2470
|
+
}));
|
|
2471
|
+
}).authorize((_ctx, identifier) => identifier === "john");
|
|
2472
|
+
const response = await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2473
|
+
method: "POST",
|
|
2474
|
+
body: makeUploadForm()
|
|
2475
|
+
}), { contextData: void 0 });
|
|
2476
|
+
assertEquals(response.status, 201);
|
|
2477
|
+
assertEquals(response.headers.get("location"), "https://example.com/objects/abc");
|
|
2478
|
+
assertEquals(receivedFileType, "image/png");
|
|
2479
|
+
assertEquals(receivedName, "A cat");
|
|
2480
|
+
assertEquals((await response.json()).id, "https://example.com/objects/abc");
|
|
2481
|
+
});
|
|
2482
|
+
await t.step("returns 202 Accepted when the callback returns a URL", async () => {
|
|
2483
|
+
const federation = createFederation({
|
|
2484
|
+
kv,
|
|
2485
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2486
|
+
});
|
|
2487
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2488
|
+
federation.setObjectDispatcher(vocab.Video, "/videos/{uuid}", (_ctx, values) => new vocab.Video({ name: `Video ${values.uuid}` }));
|
|
2489
|
+
federation.setMediaUploader("/users/{identifier}/media", (ctx) => Promise.resolve(ctx.getObjectUri(vocab.Video, { uuid: "xyz" }))).authorize(() => true);
|
|
2490
|
+
const response = await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2491
|
+
method: "POST",
|
|
2492
|
+
body: makeUploadForm()
|
|
2493
|
+
}), { contextData: void 0 });
|
|
2494
|
+
assertEquals(response.status, 202);
|
|
2495
|
+
assertEquals(response.headers.get("location"), "https://example.com/videos/xyz");
|
|
2496
|
+
assertEquals(await response.text(), "");
|
|
2497
|
+
});
|
|
2498
|
+
await t.step("accepts the object field as a plain text part", async () => {
|
|
2499
|
+
const federation = createFederation({
|
|
2500
|
+
kv,
|
|
2501
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2502
|
+
});
|
|
2503
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2504
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/pending")));
|
|
2505
|
+
const form = new FormData();
|
|
2506
|
+
form.append("file", new File([new Uint8Array([
|
|
2507
|
+
1,
|
|
2508
|
+
2,
|
|
2509
|
+
3
|
|
2510
|
+
])], "cat.png", { type: "image/png" }));
|
|
2511
|
+
form.append("object", JSON.stringify({
|
|
2512
|
+
"@context": "https://www.w3.org/ns/activitystreams",
|
|
2513
|
+
type: "Image",
|
|
2514
|
+
name: "A cat"
|
|
2515
|
+
}));
|
|
2516
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2517
|
+
method: "POST",
|
|
2518
|
+
body: form
|
|
2519
|
+
}), { contextData: void 0 })).status, 202);
|
|
2520
|
+
});
|
|
2521
|
+
await t.step("415 when the request is not multipart/form-data", async () => {
|
|
2522
|
+
const federation = createFederation({
|
|
2523
|
+
kv,
|
|
2524
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2525
|
+
});
|
|
2526
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2527
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2528
|
+
method: "POST",
|
|
2529
|
+
body: JSON.stringify({ type: "Image" }),
|
|
2530
|
+
headers: { "content-type": "application/json" }
|
|
2531
|
+
}), { contextData: void 0 })).status, 415);
|
|
2532
|
+
});
|
|
2533
|
+
await t.step("500 when the returned object has no id (no Location possible)", async () => {
|
|
2534
|
+
const federation = createFederation({
|
|
2535
|
+
kv,
|
|
2536
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2537
|
+
});
|
|
2538
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2539
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new vocab.Image({ name: "no id" })));
|
|
2540
|
+
const response = await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2541
|
+
method: "POST",
|
|
2542
|
+
body: makeUploadForm()
|
|
2543
|
+
}), { contextData: void 0 });
|
|
2544
|
+
assertEquals(response.status, 500);
|
|
2545
|
+
assertEquals(response.headers.get("location"), null);
|
|
2546
|
+
});
|
|
2547
|
+
await t.step("500 when the callback returns null (defensive)", async () => {
|
|
2548
|
+
const federation = createFederation({
|
|
2549
|
+
kv,
|
|
2550
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2551
|
+
});
|
|
2552
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2553
|
+
federation.setMediaUploader("/users/{identifier}/media", (() => Promise.resolve(null)));
|
|
2554
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2555
|
+
method: "POST",
|
|
2556
|
+
body: makeUploadForm()
|
|
2557
|
+
}), { contextData: void 0 })).status, 500);
|
|
2558
|
+
});
|
|
2559
|
+
await t.step("500 when serializing the returned object throws", async () => {
|
|
2560
|
+
const federation = createFederation({
|
|
2561
|
+
kv,
|
|
2562
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2563
|
+
});
|
|
2564
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2565
|
+
federation.setMediaUploader("/users/{identifier}/media", () => {
|
|
2566
|
+
const image = new vocab.Image({ id: new URL("https://example.com/objects/x") });
|
|
2567
|
+
image.toJsonLd = () => Promise.reject(/* @__PURE__ */ new Error("serialization boom"));
|
|
2568
|
+
return Promise.resolve(image);
|
|
2569
|
+
});
|
|
2570
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2571
|
+
method: "POST",
|
|
2572
|
+
body: makeUploadForm()
|
|
2573
|
+
}), { contextData: void 0 })).status, 500);
|
|
2574
|
+
});
|
|
2575
|
+
await t.step("400 when the file field is missing", async () => {
|
|
2576
|
+
const federation = createFederation({
|
|
2577
|
+
kv,
|
|
2578
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2579
|
+
});
|
|
2580
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2581
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2582
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2583
|
+
method: "POST",
|
|
2584
|
+
body: makeUploadForm({ file: false })
|
|
2585
|
+
}), { contextData: void 0 })).status, 400);
|
|
2586
|
+
});
|
|
2587
|
+
await t.step("400 when the object field is missing", async () => {
|
|
2588
|
+
const federation = createFederation({
|
|
2589
|
+
kv,
|
|
2590
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2591
|
+
});
|
|
2592
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2593
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2594
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2595
|
+
method: "POST",
|
|
2596
|
+
body: makeUploadForm({ object: null })
|
|
2597
|
+
}), { contextData: void 0 })).status, 400);
|
|
2598
|
+
});
|
|
2599
|
+
await t.step("400 when the object field is unparseable", async () => {
|
|
2600
|
+
const federation = createFederation({
|
|
2601
|
+
kv,
|
|
2602
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2603
|
+
});
|
|
2604
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2605
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2606
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2607
|
+
method: "POST",
|
|
2608
|
+
body: makeUploadForm({ object: "{ not json" })
|
|
2609
|
+
}), { contextData: void 0 })).status, 400);
|
|
2610
|
+
});
|
|
2611
|
+
await t.step("401 when authorize returns false", async () => {
|
|
2612
|
+
const federation = createFederation({
|
|
2613
|
+
kv,
|
|
2614
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2615
|
+
});
|
|
2616
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2617
|
+
let called = false;
|
|
2618
|
+
federation.setMediaUploader("/users/{identifier}/media", () => {
|
|
2619
|
+
called = true;
|
|
2620
|
+
return Promise.resolve(new URL("https://example.com/"));
|
|
2621
|
+
}).authorize(() => false);
|
|
2622
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2623
|
+
method: "POST",
|
|
2624
|
+
body: makeUploadForm()
|
|
2625
|
+
}), { contextData: void 0 })).status, 401);
|
|
2626
|
+
assertEquals(called, false);
|
|
2627
|
+
});
|
|
2628
|
+
await t.step("authorize hook can read request headers", async () => {
|
|
2629
|
+
const federation = createFederation({
|
|
2630
|
+
kv,
|
|
2631
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2632
|
+
});
|
|
2633
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2634
|
+
let seenAuthorization = null;
|
|
2635
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/pending"))).authorize((ctx) => {
|
|
2636
|
+
seenAuthorization = ctx.request.headers.get("authorization");
|
|
2637
|
+
return seenAuthorization === "Bearer ok";
|
|
2638
|
+
});
|
|
2639
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2640
|
+
method: "POST",
|
|
2641
|
+
headers: { authorization: "Bearer ok" },
|
|
2642
|
+
body: makeUploadForm()
|
|
2643
|
+
}), { contextData: void 0 })).status, 202);
|
|
2644
|
+
assertEquals(seenAuthorization, "Bearer ok");
|
|
2645
|
+
});
|
|
2646
|
+
await t.step("authorize hook can read the request body, and the upload still succeeds", async () => {
|
|
2647
|
+
const federation = createFederation({
|
|
2648
|
+
kv,
|
|
2649
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2650
|
+
});
|
|
2651
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2652
|
+
let authorizeBodyLength = -1;
|
|
2653
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/pending"))).authorize(async (ctx) => {
|
|
2654
|
+
authorizeBodyLength = (await ctx.request.arrayBuffer()).byteLength;
|
|
2655
|
+
return authorizeBodyLength > 0;
|
|
2656
|
+
});
|
|
2657
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2658
|
+
method: "POST",
|
|
2659
|
+
body: makeUploadForm()
|
|
2660
|
+
}), { contextData: void 0 })).status, 202);
|
|
2661
|
+
assert(authorizeBodyLength > 0);
|
|
2662
|
+
});
|
|
2663
|
+
await t.step("404 when the actor does not exist (callback not invoked)", async () => {
|
|
2664
|
+
const federation = createFederation({
|
|
2665
|
+
kv,
|
|
2666
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2667
|
+
});
|
|
2668
|
+
federation.setActorDispatcher("/users/{identifier}", (_ctx, identifier) => identifier === "john" ? new vocab.Person({}) : null);
|
|
2669
|
+
let called = false;
|
|
2670
|
+
federation.setMediaUploader("/users/{identifier}/media", () => {
|
|
2671
|
+
called = true;
|
|
2672
|
+
return Promise.resolve(new URL("https://example.com/"));
|
|
2673
|
+
});
|
|
2674
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/no-one/media", {
|
|
2675
|
+
method: "POST",
|
|
2676
|
+
body: makeUploadForm()
|
|
2677
|
+
}), { contextData: void 0 })).status, 404);
|
|
2678
|
+
assertEquals(called, false);
|
|
2679
|
+
});
|
|
2680
|
+
await t.step("404 for a missing actor takes precedence over authorization", async () => {
|
|
2681
|
+
const federation = createFederation({
|
|
2682
|
+
kv,
|
|
2683
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2684
|
+
});
|
|
2685
|
+
federation.setActorDispatcher("/users/{identifier}", (_ctx, identifier) => identifier === "john" ? new vocab.Person({}) : null);
|
|
2686
|
+
let authorizeCalled = false;
|
|
2687
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/"))).authorize(() => {
|
|
2688
|
+
authorizeCalled = true;
|
|
2689
|
+
return false;
|
|
2690
|
+
});
|
|
2691
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/no-one/media", {
|
|
2692
|
+
method: "POST",
|
|
2693
|
+
body: makeUploadForm()
|
|
2694
|
+
}), { contextData: void 0 })).status, 404);
|
|
2695
|
+
assertEquals(authorizeCalled, false);
|
|
2696
|
+
});
|
|
2697
|
+
await t.step("400 when the body errors during the authorization read", async () => {
|
|
2698
|
+
const federation = createFederation({
|
|
2699
|
+
kv,
|
|
2700
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2701
|
+
});
|
|
2702
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2703
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/"))).authorize(() => true);
|
|
2704
|
+
const erroringBody = new ReadableStream({ pull(controller) {
|
|
2705
|
+
controller.error(/* @__PURE__ */ new Error("stream boom"));
|
|
2706
|
+
} });
|
|
2707
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2708
|
+
method: "POST",
|
|
2709
|
+
headers: { "content-type": "multipart/form-data; boundary=abc" },
|
|
2710
|
+
body: erroringBody,
|
|
2711
|
+
duplex: "half"
|
|
2712
|
+
}), { contextData: void 0 })).status, 400);
|
|
2713
|
+
});
|
|
2714
|
+
await t.step("404 when the actor is tombstoned (callback not invoked)", async () => {
|
|
2715
|
+
const federation = createFederation({
|
|
2716
|
+
kv,
|
|
2717
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2718
|
+
});
|
|
2719
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Tombstone({}));
|
|
2720
|
+
let called = false;
|
|
2721
|
+
federation.setMediaUploader("/users/{identifier}/media", () => {
|
|
2722
|
+
called = true;
|
|
2723
|
+
return Promise.resolve(new URL("https://example.com/"));
|
|
2724
|
+
});
|
|
2725
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2726
|
+
method: "POST",
|
|
2727
|
+
body: makeUploadForm()
|
|
2728
|
+
}), { contextData: void 0 })).status, 404);
|
|
2729
|
+
assertEquals(called, false);
|
|
2730
|
+
});
|
|
2731
|
+
await t.step("405 for non-POST methods", async () => {
|
|
2732
|
+
const federation = createFederation({
|
|
2733
|
+
kv,
|
|
2734
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2735
|
+
});
|
|
2736
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2737
|
+
const response = await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2738
|
+
method: "GET",
|
|
2739
|
+
headers: { accept: "application/activity+json" }
|
|
2740
|
+
}), { contextData: void 0 });
|
|
2741
|
+
assertEquals(response.status, 405);
|
|
2742
|
+
assertEquals(response.headers.get("allow"), "POST");
|
|
2743
|
+
});
|
|
2744
|
+
await t.step("warns when the returned id is not a registered object route", async () => {
|
|
2745
|
+
await withLogtapeLock(async () => {
|
|
2746
|
+
const records = [];
|
|
2747
|
+
await reset();
|
|
2748
|
+
try {
|
|
2749
|
+
await configure({
|
|
2750
|
+
sinks: { buffer(record) {
|
|
2751
|
+
records.push(record);
|
|
2752
|
+
} },
|
|
2753
|
+
filters: {},
|
|
2754
|
+
loggers: [{
|
|
2755
|
+
category: [],
|
|
2756
|
+
sinks: ["buffer"]
|
|
2757
|
+
}]
|
|
2758
|
+
});
|
|
2759
|
+
const federation = createFederation({
|
|
2760
|
+
kv,
|
|
2761
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2762
|
+
});
|
|
2763
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2764
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new vocab.Image({ id: new URL("https://example.com/not-registered") })));
|
|
2765
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2766
|
+
method: "POST",
|
|
2767
|
+
body: makeUploadForm()
|
|
2768
|
+
}), { contextData: void 0 })).status, 201);
|
|
2769
|
+
assertEquals(records.some((record) => record.category.join(".") === "fedify.federation.mediaUploader" && record.level === "warning" && record.properties.identifier === "john"), true);
|
|
2770
|
+
} finally {
|
|
2771
|
+
await reset();
|
|
2772
|
+
}
|
|
2773
|
+
});
|
|
2774
|
+
});
|
|
2775
|
+
await t.step("warns when the actor omits endpoints.uploadMedia", async () => {
|
|
2776
|
+
await withLogtapeLock(async () => {
|
|
2777
|
+
const records = [];
|
|
2778
|
+
await reset();
|
|
2779
|
+
try {
|
|
2780
|
+
await configure({
|
|
2781
|
+
sinks: { buffer(record) {
|
|
2782
|
+
records.push(record);
|
|
2783
|
+
} },
|
|
2784
|
+
filters: {},
|
|
2785
|
+
loggers: [{
|
|
2786
|
+
category: [],
|
|
2787
|
+
sinks: ["buffer"]
|
|
2788
|
+
}]
|
|
2789
|
+
});
|
|
2790
|
+
const federation = createFederation({
|
|
2791
|
+
kv,
|
|
2792
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2793
|
+
});
|
|
2794
|
+
federation.setActorDispatcher("/users/{identifier}", (ctx, identifier) => new vocab.Person({ id: ctx.getActorUri(identifier) }));
|
|
2795
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2796
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john", { headers: { accept: "application/activity+json" } }), { contextData: void 0 })).status, 200);
|
|
2797
|
+
assertEquals(records.some((record) => record.rawMessage === "You configured a media uploader, but the actor does not have a endpoints.uploadMedia property. Set the property with Context.getMediaUploaderUri(identifier)."), true);
|
|
2798
|
+
} finally {
|
|
2799
|
+
await reset();
|
|
2800
|
+
}
|
|
2801
|
+
});
|
|
2802
|
+
});
|
|
2803
|
+
await t.step("does not warn when the actor advertises endpoints.uploadMedia", async () => {
|
|
2804
|
+
await withLogtapeLock(async () => {
|
|
2805
|
+
const records = [];
|
|
2806
|
+
await reset();
|
|
2807
|
+
try {
|
|
2808
|
+
await configure({
|
|
2809
|
+
sinks: { buffer(record) {
|
|
2810
|
+
records.push(record);
|
|
2811
|
+
} },
|
|
2812
|
+
filters: {},
|
|
2813
|
+
loggers: [{
|
|
2814
|
+
category: [],
|
|
2815
|
+
sinks: ["buffer"]
|
|
2816
|
+
}]
|
|
2817
|
+
});
|
|
2818
|
+
const federation = createFederation({
|
|
2819
|
+
kv,
|
|
2820
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2821
|
+
});
|
|
2822
|
+
federation.setActorDispatcher("/users/{identifier}", (ctx, identifier) => new vocab.Person({
|
|
2823
|
+
id: ctx.getActorUri(identifier),
|
|
2824
|
+
endpoints: new vocab.Endpoints({ uploadMedia: ctx.getMediaUploaderUri(identifier) })
|
|
2825
|
+
}));
|
|
2826
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2827
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/john", { headers: { accept: "application/activity+json" } }), { contextData: void 0 })).status, 200);
|
|
2828
|
+
assertEquals(records.some((record) => typeof record.rawMessage === "string" && record.rawMessage.includes("endpoints.uploadMedia")), false);
|
|
2829
|
+
} finally {
|
|
2830
|
+
await reset();
|
|
2831
|
+
}
|
|
2832
|
+
});
|
|
2833
|
+
});
|
|
2834
|
+
await t.step("warns once when no authorize hook is configured", async () => {
|
|
2835
|
+
await withLogtapeLock(async () => {
|
|
2836
|
+
const records = [];
|
|
2837
|
+
await reset();
|
|
2838
|
+
try {
|
|
2839
|
+
await configure({
|
|
2840
|
+
sinks: { buffer(record) {
|
|
2841
|
+
records.push(record);
|
|
2842
|
+
} },
|
|
2843
|
+
filters: {},
|
|
2844
|
+
loggers: [{
|
|
2845
|
+
category: [],
|
|
2846
|
+
sinks: ["buffer"]
|
|
2847
|
+
}]
|
|
2848
|
+
});
|
|
2849
|
+
const federation = createFederation({
|
|
2850
|
+
kv,
|
|
2851
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
2852
|
+
});
|
|
2853
|
+
federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
|
|
2854
|
+
federation.setMediaUploader("/users/{identifier}/media", () => Promise.resolve(new URL("https://example.com/")));
|
|
2855
|
+
const send = () => federation.fetch(new Request("https://example.com/users/john/media", {
|
|
2856
|
+
method: "POST",
|
|
2857
|
+
body: makeUploadForm()
|
|
2858
|
+
}), { contextData: void 0 });
|
|
2859
|
+
assertEquals((await send()).status, 202);
|
|
2860
|
+
assertEquals((await send()).status, 202);
|
|
2861
|
+
assertEquals(records.filter((record) => record.category.join(".") === "fedify.federation.mediaUploader" && record.level === "warning" && typeof record.rawMessage === "string" && record.rawMessage.includes("without an authorize() hook")).length, 1);
|
|
2862
|
+
} finally {
|
|
2863
|
+
await reset();
|
|
2864
|
+
}
|
|
2865
|
+
});
|
|
2866
|
+
});
|
|
2867
|
+
});
|
|
2420
2868
|
test("Federation.fetch() preserves original LD-signed payload for InboxContextImpl.activity", async () => {
|
|
2421
2869
|
const remoteContextUrl = "https://remote.example/contexts/ext";
|
|
2422
2870
|
const sourceContextLoader = async (resource) => {
|
package/dist/federation/mod.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
require("../chunk-Czpeue4M.cjs");
|
|
4
|
-
const require_middleware = require("../middleware-
|
|
4
|
+
const require_middleware = require("../middleware-BPHpdYl4.cjs");
|
|
5
5
|
const require_temporal_polyfill = require("../temporal-polyfill-BCdTHexd.cjs");
|
|
6
6
|
let _logtape_logtape = require("@logtape/logtape");
|
|
7
7
|
let _fedify_uri_template = require("@fedify/uri-template");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as CircuitBreakerCreateOptions, A as OutboxListenerSetters, At as UnverifiedActivityHandler, B as TaskEnqueueOptions, C as FederationStartQueueOptions, Ct as ObjectAuthorizePredicate, D as InboxListenerSetters, Dt as OutboxListenerErrorHandler, E as InboxChallengePolicy, Et as OutboxListener, F as createFederation, Ft as PageItems, G as RetryPolicy, H as TaskRegistry, I as Message, It as buildCollectionSynchronizationHeader, J as respondWithObject, K as createExponentialBackoffPolicy, L as createFederationBuilder, Lt as digest, M as FederationKvPrefixes, Mt as WebFingerLinksDispatcher, N as FederationOrigin, Nt as SendActivityError, O as MediaUploaderSetters, Ot as OutboxPermanentFailureHandler, P as FederationQueueOptions, Pt as SenderKeyPair, Q as CircuitBreakerBeforeSendDecision, R as TaskDefinition, S as FederationOptions, St as NodeInfoDispatcher, T as IdempotencyStrategy, Tt as OutboxErrorHandler, U as CreateExponentialBackoffPolicyOptions, V as TaskHandler, W as RetryContext, X as CircuitBreaker, Y as respondWithObjectIfAcceptable, Z as CircuitBreakerActivityDrop, _ as Federatable, _t as CustomCollectionCursor, a as GetSignedKeyOptions, at as NormalizedCircuitBreakerOptions, b as FederationBuilder, bt as InboxListener, c as ParseUriResult, ct as ActorAliasMapper, d as SendActivityOptions, dt as ActorKeyPairsDispatcher, et as CircuitBreakerFailurePolicy, f as SendActivityOptionsForCollection, ft as AuthorizePredicate, g as CustomCollectionCallbackSetters, gt as CustomCollectionCounter, h as ConstructorWithTypeId, ht as CollectionDispatcher, i as GetActorOptions, it as CircuitBreakerStateChange, j as Rfc6570Expression, jt as UnverifiedActivityReason, k as ObjectCallbackSetters, kt as SharedInboxKeyDispatcher, l as RequestContext, lt as ActorDispatcher, m as CollectionCallbackSetters, mt as CollectionCursor, n as Context, nt as CircuitBreakerOptions, o as InboxContext, ot as normalizeCircuitBreakerOptions, p as ActorCallbackSetters, pt as CollectionCounter, q as RespondWithObjectOptions, r as ForwardActivityOptions, rt as CircuitBreakerState, s as OutboxContext, st as parseCircuitBreakerKvState, t as ActorKeyPair, tt as CircuitBreakerKvState, u as RouteActivityOptions, ut as ActorHandleMapper, v as Federation, vt as CustomCollectionDispatcher, w as IdempotencyKeyCallback, wt as ObjectDispatcher, x as FederationFetchOptions, xt as MediaUploaderCallback, y as FederationBenchmarkOptions, yt as InboxErrorHandler, z as TaskDefinitionOptions } from "../context-lxX6I7as.cjs";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-gJ8LYbxX.cjs";
|
|
4
4
|
import { a as MessageQueueDepth, c as ParallelMessageQueue, i as MessageQueue, n as InProcessMessageQueue, o as MessageQueueEnqueueOptions, r as InProcessMessageQueueOptions, s as MessageQueueListenOptions } from "../metrics-CoUJLQhZ.cjs";
|
|
5
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
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, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
|
5
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-gOlPDuT8.cjs";
|
|
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, MediaUploaderCallback, MediaUploaderSetters, 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, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, 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
|
|
2
|
+
import { $ as CircuitBreakerCreateOptions, A as OutboxListenerSetters, At as UnverifiedActivityHandler, B as TaskEnqueueOptions, C as FederationStartQueueOptions, Ct as ObjectAuthorizePredicate, D as InboxListenerSetters, Dt as OutboxListenerErrorHandler, E as InboxChallengePolicy, Et as OutboxListener, F as createFederation, Ft as PageItems, G as RetryPolicy, H as TaskRegistry, I as Message, It as buildCollectionSynchronizationHeader, J as respondWithObject, K as createExponentialBackoffPolicy, L as createFederationBuilder, Lt as digest, M as FederationKvPrefixes, Mt as WebFingerLinksDispatcher, N as FederationOrigin, Nt as SendActivityError, O as MediaUploaderSetters, Ot as OutboxPermanentFailureHandler, P as FederationQueueOptions, Pt as SenderKeyPair, Q as CircuitBreakerBeforeSendDecision, R as TaskDefinition, S as FederationOptions, St as NodeInfoDispatcher, T as IdempotencyStrategy, Tt as OutboxErrorHandler, U as CreateExponentialBackoffPolicyOptions, V as TaskHandler, W as RetryContext, X as CircuitBreaker, Y as respondWithObjectIfAcceptable, Z as CircuitBreakerActivityDrop, _ as Federatable, _t as CustomCollectionCursor, a as GetSignedKeyOptions, at as NormalizedCircuitBreakerOptions, b as FederationBuilder, bt as InboxListener, c as ParseUriResult, ct as ActorAliasMapper, d as SendActivityOptions, dt as ActorKeyPairsDispatcher, et as CircuitBreakerFailurePolicy, f as SendActivityOptionsForCollection, ft as AuthorizePredicate, g as CustomCollectionCallbackSetters, gt as CustomCollectionCounter, h as ConstructorWithTypeId, ht as CollectionDispatcher, i as GetActorOptions, it as CircuitBreakerStateChange, j as Rfc6570Expression, jt as UnverifiedActivityReason, k as ObjectCallbackSetters, kt as SharedInboxKeyDispatcher, l as RequestContext, lt as ActorDispatcher, m as CollectionCallbackSetters, mt as CollectionCursor, n as Context, nt as CircuitBreakerOptions, o as InboxContext, ot as normalizeCircuitBreakerOptions, p as ActorCallbackSetters, pt as CollectionCounter, q as RespondWithObjectOptions, r as ForwardActivityOptions, rt as CircuitBreakerState, s as OutboxContext, st as parseCircuitBreakerKvState, t as ActorKeyPair, tt as CircuitBreakerKvState, u as RouteActivityOptions, ut as ActorHandleMapper, v as Federation, vt as CustomCollectionDispatcher, w as IdempotencyKeyCallback, wt as ObjectDispatcher, x as FederationFetchOptions, xt as MediaUploaderCallback, y as FederationBenchmarkOptions, yt as InboxErrorHandler, z as TaskDefinitionOptions } from "../context-Zii1f5xS.js";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-D6hNiMTK.js";
|
|
4
4
|
import { a as MessageQueueDepth, c as ParallelMessageQueue, i as MessageQueue, n as InProcessMessageQueue, o as MessageQueueEnqueueOptions, r as InProcessMessageQueueOptions, s as MessageQueueListenOptions } from "../metrics-Dc4jR-IC.js";
|
|
5
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
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, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
|
5
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-DLc2Ot6f.js";
|
|
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, MediaUploaderCallback, MediaUploaderSetters, 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, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, 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 "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { a as ParallelMessageQueue, c as respondWithObject, d as digest, f as CircuitBreaker, h as createFederationBuilder, i as InProcessMessageQueue, l as respondWithObjectIfAcceptable, m as parseCircuitBreakerKvState, o as createExponentialBackoffPolicy, p as normalizeCircuitBreakerOptions, r as handleWebFinger, s as SendActivityError, t as createFederation, u as buildCollectionSynchronizationHeader } from "../middleware-
|
|
3
|
+
import { a as ParallelMessageQueue, c as respondWithObject, d as digest, f as CircuitBreaker, h as createFederationBuilder, i as InProcessMessageQueue, l as respondWithObjectIfAcceptable, m as parseCircuitBreakerKvState, o as createExponentialBackoffPolicy, p as normalizeCircuitBreakerOptions, r as handleWebFinger, s as SendActivityError, t as createFederation, u as buildCollectionSynchronizationHeader } from "../middleware-8oyKaRYF.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";
|
|
@@ -8,10 +8,10 @@ import { n as assertGreaterOrEqual, r as assertFalse, t as assertRejects } from
|
|
|
8
8
|
import { t as assertInstanceOf } from "../assert_instance_of-Q9KTBnrf.mjs";
|
|
9
9
|
import { t as assertNotEquals } from "../assert_not_equals-EPJPoxuf.mjs";
|
|
10
10
|
import { t as assert } from "../assert-CJ1KXcvv.mjs";
|
|
11
|
-
import { l as verifyRequest } from "../http-
|
|
11
|
+
import { l as verifyRequest } from "../http-DJEaNMSB.mjs";
|
|
12
12
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-Dbyd7bhl.mjs";
|
|
13
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
14
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-
|
|
13
|
+
import { t as doesActorOwnKey } from "../owner-CB3dPva0.mjs";
|
|
14
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-ClWims8x.mjs";
|
|
15
15
|
import { Activity, Application, Endpoints, Group, Person, Service } from "@fedify/vocab";
|
|
16
16
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
17
17
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
@@ -2,8 +2,8 @@ import { Temporal } from "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as MemoryKvStore } from "../../kv-CXBAok3k.mjs";
|
|
5
|
-
import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../testing-
|
|
6
|
-
import { o as createFederation } from "../../middleware-
|
|
5
|
+
import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../testing-CO7ftO8A.mjs";
|
|
6
|
+
import { o as createFederation } from "../../middleware-CPlgpBML.mjs";
|
|
7
7
|
import { n as ParallelMessageQueue } from "../../mq-llHKivST.mjs";
|
|
8
8
|
import { configure, reset } from "@logtape/logtape";
|
|
9
9
|
import { delay } from "es-toolkit";
|
|
@@ -2,9 +2,9 @@ import { Temporal } from "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as MemoryKvStore } from "../../kv-CXBAok3k.mjs";
|
|
5
|
-
import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../testing-
|
|
6
|
-
import { o as createFederation } from "../../middleware-
|
|
7
|
-
import { r as createFederationBuilder } from "../../builder-
|
|
5
|
+
import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../testing-CO7ftO8A.mjs";
|
|
6
|
+
import { o as createFederation } from "../../middleware-CPlgpBML.mjs";
|
|
7
|
+
import { r as createFederationBuilder } from "../../builder-DYAAegyy.mjs";
|
|
8
8
|
import { t as TaskCodec } from "../../codec-BBga-FWI.mjs";
|
|
9
9
|
import { t as InProcessMessageQueue } from "../../mq-llHKivST.mjs";
|
|
10
10
|
import { W3CTraceContextPropagator } from "@opentelemetry/core";
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import "../std__assert-B2NnY9bq.mjs";
|
|
5
5
|
import { r as assertFalse } from "../assert_rejects-EgstcQy5.mjs";
|
|
6
6
|
import { t as assert } from "../assert-CJ1KXcvv.mjs";
|
|
7
|
-
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-
|
|
7
|
+
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-DyITEDcU.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/federation/temporal.test.ts
|
|
10
10
|
test("hasMalformedKnownTemporalLiteral() detects expanded proof timestamps", async () => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { r as createRequestContext } from "../context-
|
|
4
|
+
import { r as createRequestContext } from "../context-BJXxPElm.mjs";
|
|
5
5
|
import { t as MemoryKvStore } from "../kv-CXBAok3k.mjs";
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-BV7oLMxm.mjs";
|
|
7
7
|
import "../std__assert-B2NnY9bq.mjs";
|
|
8
8
|
import { t as assertNotEquals } from "../assert_not_equals-EPJPoxuf.mjs";
|
|
9
|
-
import { o as createFederation, s as handleWebFinger } from "../middleware-
|
|
9
|
+
import { o as createFederation, s as handleWebFinger } from "../middleware-CPlgpBML.mjs";
|
|
10
10
|
import { Image, Link, Person, Tombstone } from "@fedify/vocab";
|
|
11
11
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
12
12
|
//#region src/federation/webfinger.test.ts
|