@fedify/fedify 2.4.0-dev.2103 → 2.4.0-dev.2108
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-CHht75pX.mjs → builder-BRlYEsrV.mjs} +28 -4
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-DKKH_Nr1.mjs → compound-proof-CHGINiJg.mjs} +2 -2
- package/dist/{context-CfJE_oQu.d.ts → context-B4F4kGJq.d.ts} +92 -10
- package/dist/{context-mDTxTw-S.d.cts → context-Cqx9M_zO.d.cts} +92 -10
- package/dist/{deno-CkjiYK_Z.mjs → deno-CC4RKEEp.mjs} +1 -1
- package/dist/{docloader-C1hAJnWc.mjs → docloader-D3_m98fe.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +118 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +184 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +3 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +5 -5
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-gateway-keys.test.mjs +3 -3
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable.test.mjs +31 -4
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-C1dL6SiT.cjs → federation-dqo6ZzgT.cjs} +48 -15
- package/dist/{http-Cala2Grs.cjs → http-B7wEqv49.cjs} +1 -1
- package/dist/{http-BU-8fUrz.mjs → http-CHEYA5fH.mjs} +4 -4
- package/dist/{http-tTlTeFa0.js → http-CaUBCHYJ.js} +1 -1
- package/dist/{key-I8gLBkcf.mjs → key-B8u1vdvF.mjs} +2 -2
- package/dist/{kv-cache-Bl5EBFrU.cjs → kv-cache-0pYMPrkL.cjs} +1 -1
- package/dist/{kv-cache-DJFoGRWQ.mjs → kv-cache-CTdvf_Iq.mjs} +1 -1
- package/dist/{kv-cache-CxQu_cd4.js → kv-cache-ibncHN1D.js} +1 -1
- package/dist/{ld-wiJbqJHa.mjs → ld-BTMJHEGV.mjs} +3 -3
- package/dist/{metrics-BCAa5-kE.mjs → metrics-CF1TEvdS.mjs} +1 -1
- package/dist/{middleware-FnITXhtz.mjs → middleware-B-rZ7oE-.mjs} +24 -15
- package/dist/{middleware-6p2dYEVA.mjs → middleware-DCMTJT3_.mjs} +1 -1
- package/dist/{middleware-B6IVTVL0.js → middleware-Dl-Y_ZlC.js} +40 -7
- package/dist/{mod-BYvPz_T0.d.ts → mod-4s_XgF17.d.ts} +1 -1
- package/dist/{mod-B3OzOobN.d.cts → mod-BuFmStNT.d.cts} +1 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +4 -4
- package/dist/mod.d.ts +4 -4
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-DCt8W_Cv.cjs → owner-CGnHPl4k.cjs} +1 -1
- package/dist/{owner-BJp47LxN.mjs → owner-CY--JSqO.mjs} +3 -3
- package/dist/{owner-j5yrbXS1.js → owner-M8dOKEl6.js} +1 -1
- package/dist/{portable-key-B5oKE_wZ.mjs → portable-key-C0-ghkgM.mjs} +1 -1
- package/dist/{proof-BE4T5zF6.mjs → proof-DDw0i9b1.mjs} +4 -4
- package/dist/{send-BFITuKHw.mjs → send-CU3sHGPt.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +3 -3
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +2 -2
- package/dist/sig/portable-key.test.mjs +3 -3
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/{sig-CRTRoouH.cjs → sig-C2CORtvg.cjs} +2 -2
- package/dist/{sig-CJHdGk9w.js → sig-fycq7sOr.js} +2 -2
- package/dist/{temporal-CyDDbE4i.mjs → temporal-NHiSpGcW.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +91 -9
- 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
|
@@ -10,12 +10,12 @@ import "../std__assert-DvMDRPes.mjs";
|
|
|
10
10
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
11
11
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
12
12
|
import { r as parseAcceptSignature } from "../accept-CPVqki78.mjs";
|
|
13
|
-
import { a as generateCryptoKeyPair } from "../key-
|
|
14
|
-
import { a as compactJsonLd, p as signJsonLd } from "../ld-
|
|
15
|
-
import { i as signObject } from "../proof-
|
|
16
|
-
import { l as signRequest } from "../http-
|
|
13
|
+
import { a as generateCryptoKeyPair } from "../key-B8u1vdvF.mjs";
|
|
14
|
+
import { a as compactJsonLd, p as signJsonLd } from "../ld-BTMJHEGV.mjs";
|
|
15
|
+
import { i as signObject } from "../proof-DDw0i9b1.mjs";
|
|
16
|
+
import { l as signRequest } from "../http-CHEYA5fH.mjs";
|
|
17
17
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
18
|
-
import { d as handleCustomCollection, f as handleInbox, g as respondWithObjectIfAcceptable, h as respondWithObject, l as handleActor, m as handleOutbox, o as createFederation, p as handleObject, u as handleCollection } from "../middleware-
|
|
18
|
+
import { d as handleCustomCollection, f as handleInbox, g as respondWithObjectIfAcceptable, h as respondWithObject, l as handleActor, m as handleOutbox, o as createFederation, p as handleObject, u as handleCollection } from "../middleware-B-rZ7oE-.mjs";
|
|
19
19
|
import { t as ActivityListenerSet } from "../activity-listener-C-BSbKI7.mjs";
|
|
20
20
|
import { Activity, Create, CryptographicKey, Multikey, Note, Person, Tombstone } from "@fedify/vocab";
|
|
21
21
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -500,6 +500,119 @@ test("handleObject()", async () => {
|
|
|
500
500
|
assertEquals(onNotFoundCalled, null);
|
|
501
501
|
assertEquals(onUnauthorizedCalled, null);
|
|
502
502
|
});
|
|
503
|
+
test("handleObject() with a tombstone", async () => {
|
|
504
|
+
const federation = createFederation({ kv: new MemoryKvStore() });
|
|
505
|
+
const url = new URL("https://example.com/users/someone/notes/123");
|
|
506
|
+
let context = createRequestContext({
|
|
507
|
+
federation,
|
|
508
|
+
data: void 0,
|
|
509
|
+
url,
|
|
510
|
+
request: new Request(url, { headers: { Accept: "application/activity+json" } })
|
|
511
|
+
});
|
|
512
|
+
const objectDispatcher = (_ctx, values) => {
|
|
513
|
+
if (values.id !== "123") return null;
|
|
514
|
+
return new Tombstone({
|
|
515
|
+
id: new URL(`https://example.com/users/${values.identifier}/notes/${values.id}`),
|
|
516
|
+
formerType: Note,
|
|
517
|
+
deleted: Temporal.Instant.from("2024-01-15T00:00:00Z")
|
|
518
|
+
});
|
|
519
|
+
};
|
|
520
|
+
let onNotFoundCalled = null;
|
|
521
|
+
const onNotFound = (request) => {
|
|
522
|
+
onNotFoundCalled = request;
|
|
523
|
+
return new Response("Not found", { status: 404 });
|
|
524
|
+
};
|
|
525
|
+
let onUnauthorizedCalled = null;
|
|
526
|
+
const onUnauthorized = (request) => {
|
|
527
|
+
onUnauthorizedCalled = request;
|
|
528
|
+
return new Response("Unauthorized", { status: 401 });
|
|
529
|
+
};
|
|
530
|
+
let response = await handleObject(context.request, {
|
|
531
|
+
context,
|
|
532
|
+
values: {
|
|
533
|
+
identifier: "someone",
|
|
534
|
+
id: "123"
|
|
535
|
+
},
|
|
536
|
+
objectDispatcher,
|
|
537
|
+
onNotFound,
|
|
538
|
+
onUnauthorized
|
|
539
|
+
});
|
|
540
|
+
assertEquals(response.status, 410);
|
|
541
|
+
assertEquals(response.headers.get("Content-Type"), "application/activity+json");
|
|
542
|
+
assertEquals(response.headers.get("Vary"), "Accept");
|
|
543
|
+
const body = await response.json();
|
|
544
|
+
assertEquals(body.id, "https://example.com/users/someone/notes/123");
|
|
545
|
+
assertEquals(body.type, "Tombstone");
|
|
546
|
+
assertEquals(body.formerType, "as:Note");
|
|
547
|
+
assertEquals(body.deleted, "2024-01-15T00:00:00Z");
|
|
548
|
+
assertEquals(onNotFoundCalled, null);
|
|
549
|
+
assertEquals(onUnauthorizedCalled, null);
|
|
550
|
+
response = await handleObject(context.request, {
|
|
551
|
+
context,
|
|
552
|
+
values: {
|
|
553
|
+
identifier: "someone",
|
|
554
|
+
id: "456"
|
|
555
|
+
},
|
|
556
|
+
objectDispatcher,
|
|
557
|
+
onNotFound,
|
|
558
|
+
onUnauthorized
|
|
559
|
+
});
|
|
560
|
+
assertEquals(response.status, 404);
|
|
561
|
+
assertEquals(onNotFoundCalled, context.request);
|
|
562
|
+
assertEquals(onUnauthorizedCalled, null);
|
|
563
|
+
onNotFoundCalled = null;
|
|
564
|
+
let authorized = false;
|
|
565
|
+
const authorizePredicate = () => authorized;
|
|
566
|
+
response = await handleObject(context.request, {
|
|
567
|
+
context,
|
|
568
|
+
values: {
|
|
569
|
+
identifier: "someone",
|
|
570
|
+
id: "123"
|
|
571
|
+
},
|
|
572
|
+
objectDispatcher,
|
|
573
|
+
authorizePredicate,
|
|
574
|
+
onNotFound,
|
|
575
|
+
onUnauthorized
|
|
576
|
+
});
|
|
577
|
+
assertEquals(response.status, 401);
|
|
578
|
+
assertEquals(onNotFoundCalled, null);
|
|
579
|
+
assertEquals(onUnauthorizedCalled, context.request);
|
|
580
|
+
onUnauthorizedCalled = null;
|
|
581
|
+
authorized = true;
|
|
582
|
+
response = await handleObject(context.request, {
|
|
583
|
+
context,
|
|
584
|
+
values: {
|
|
585
|
+
identifier: "someone",
|
|
586
|
+
id: "123"
|
|
587
|
+
},
|
|
588
|
+
objectDispatcher,
|
|
589
|
+
authorizePredicate,
|
|
590
|
+
onNotFound,
|
|
591
|
+
onUnauthorized
|
|
592
|
+
});
|
|
593
|
+
assertEquals(response.status, 410);
|
|
594
|
+
assertEquals(onUnauthorizedCalled, null);
|
|
595
|
+
context = createRequestContext({
|
|
596
|
+
...context,
|
|
597
|
+
request: new Request(url, {
|
|
598
|
+
method: "HEAD",
|
|
599
|
+
headers: { Accept: "application/activity+json" }
|
|
600
|
+
})
|
|
601
|
+
});
|
|
602
|
+
response = await handleObject(context.request, {
|
|
603
|
+
context,
|
|
604
|
+
values: {
|
|
605
|
+
identifier: "someone",
|
|
606
|
+
id: "123"
|
|
607
|
+
},
|
|
608
|
+
objectDispatcher,
|
|
609
|
+
onNotFound,
|
|
610
|
+
onUnauthorized
|
|
611
|
+
});
|
|
612
|
+
assertEquals(response.status, 410);
|
|
613
|
+
assertEquals(response.headers.get("Content-Type"), "application/activity+json");
|
|
614
|
+
assertEquals(response.body, null);
|
|
615
|
+
});
|
|
503
616
|
test("handleCollection()", async () => {
|
|
504
617
|
let context = createRequestContext({
|
|
505
618
|
federation: createFederation({ kv: new MemoryKvStore() }),
|
|
@@ -10,8 +10,8 @@ import "../std__assert-DvMDRPes.mjs";
|
|
|
10
10
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
11
11
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
12
12
|
import { r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
13
|
-
import { o as createFederation, x as parseHashlinkGatewayRequest } from "../middleware-
|
|
14
|
-
import { r as createFederationBuilder } from "../builder-
|
|
13
|
+
import { o as createFederation, x as parseHashlinkGatewayRequest } from "../middleware-B-rZ7oE-.mjs";
|
|
14
|
+
import { r as createFederationBuilder } from "../builder-BRlYEsrV.mjs";
|
|
15
15
|
import { n as RouterError } from "../router-u5O5KCQr.mjs";
|
|
16
16
|
import { Note } from "@fedify/vocab";
|
|
17
17
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -4,9 +4,9 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
6
|
import "../std__assert-DvMDRPes.mjs";
|
|
7
|
-
import { i as signObject } from "../proof-
|
|
7
|
+
import { i as signObject } from "../proof-DDw0i9b1.mjs";
|
|
8
8
|
import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
+
import { o as createFederation } from "../middleware-B-rZ7oE-.mjs";
|
|
10
10
|
import { Create, Follow, Person } from "@fedify/vocab";
|
|
11
11
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
12
12
|
//#region src/federation/idempotency.test.ts
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
5
5
|
import "../std__assert-DvMDRPes.mjs";
|
|
6
6
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
7
|
-
import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-
|
|
7
|
+
import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-CF1TEvdS.mjs";
|
|
8
8
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
9
9
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
10
10
|
import { DataPointType, MeterProvider, MetricReader } from "@opentelemetry/sdk-metrics";
|
|
@@ -16,14 +16,14 @@ import "../std__assert-DvMDRPes.mjs";
|
|
|
16
16
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
17
17
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
18
18
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
19
|
-
import { g as recordInboxActivity } from "../metrics-
|
|
20
|
-
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-
|
|
21
|
-
import { i as signObject, o as verifyObject } from "../proof-
|
|
22
|
-
import { d as verifyRequest, l as signRequest } from "../http-
|
|
19
|
+
import { g as recordInboxActivity } from "../metrics-CF1TEvdS.mjs";
|
|
20
|
+
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-BTMJHEGV.mjs";
|
|
21
|
+
import { i as signObject, o as verifyObject } from "../proof-DDw0i9b1.mjs";
|
|
22
|
+
import { d as verifyRequest, l as signRequest } from "../http-CHEYA5fH.mjs";
|
|
23
23
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
24
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
25
|
-
import { S as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-
|
|
26
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
24
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-D3_m98fe.mjs";
|
|
25
|
+
import { S as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-B-rZ7oE-.mjs";
|
|
26
|
+
import { t as doesActorOwnKey } from "../owner-CY--JSqO.mjs";
|
|
27
27
|
import { t as CircuitBreaker } from "../circuit-breaker-C5NqoLBJ.mjs";
|
|
28
28
|
import { t as TaskCodec } from "../codec-C6rTrpIp.mjs";
|
|
29
29
|
import { t as markCircuitBreakerLegacySweepDone } from "../circuit-breaker-test-utils-DW6YC_Pe.mjs";
|
|
@@ -7882,5 +7882,182 @@ test("Federation.fetch() bounds inbox bodies before dispatch", async () => {
|
|
|
7882
7882
|
}), { contextData: void 0 })).status, 202);
|
|
7883
7883
|
assert(dispatched);
|
|
7884
7884
|
});
|
|
7885
|
+
function getRawMessage(record) {
|
|
7886
|
+
return typeof record.rawMessage === "string" ? record.rawMessage : record.rawMessage.join("");
|
|
7887
|
+
}
|
|
7888
|
+
test("Federation.fetch() serves tombstones of objects", async (t) => {
|
|
7889
|
+
const deleted = Temporal.Instant.from("2024-01-15T00:00:00Z");
|
|
7890
|
+
const federation = createFederation({
|
|
7891
|
+
kv: new MemoryKvStore(),
|
|
7892
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
7893
|
+
contextLoaderFactory: () => mockDocumentLoader
|
|
7894
|
+
});
|
|
7895
|
+
federation.setObjectDispatcher(vocab.Note, "/users/{identifier}/notes/{id}", (ctx, values) => {
|
|
7896
|
+
if (values.id === "missing") return null;
|
|
7897
|
+
if (values.id === "deleted") return new vocab.Tombstone({
|
|
7898
|
+
id: ctx.getObjectUri(vocab.Note, values),
|
|
7899
|
+
formerType: vocab.Note,
|
|
7900
|
+
deleted
|
|
7901
|
+
});
|
|
7902
|
+
return new vocab.Note({
|
|
7903
|
+
id: ctx.getObjectUri(vocab.Note, values),
|
|
7904
|
+
content: "Hello"
|
|
7905
|
+
});
|
|
7906
|
+
});
|
|
7907
|
+
federation.setObjectDispatcher(vocab.Tombstone, "/tombstones/{id}", (ctx, values) => new vocab.Tombstone({ id: ctx.getObjectUri(vocab.Tombstone, values) }));
|
|
7908
|
+
federation.setObjectDispatcher(vocab.Object, "/objects/{id}", (ctx, values) => values.id === "deleted" ? new vocab.Tombstone({ id: ctx.getObjectUri(vocab.Object, values) }) : new vocab.Note({ id: ctx.getObjectUri(vocab.Object, values) }));
|
|
7909
|
+
function fetch(path, method = "GET") {
|
|
7910
|
+
return federation.fetch(new Request(`https://example.com${path}`, {
|
|
7911
|
+
method,
|
|
7912
|
+
headers: { Accept: "application/activity+json" }
|
|
7913
|
+
}), { contextData: void 0 });
|
|
7914
|
+
}
|
|
7915
|
+
await t.step("GET responds with 410 Gone and the tombstone", async () => {
|
|
7916
|
+
const response = await fetch("/users/john/notes/deleted");
|
|
7917
|
+
assertEquals(response.status, 410);
|
|
7918
|
+
assertEquals(response.headers.get("Content-Type"), "application/activity+json");
|
|
7919
|
+
const body = await response.json();
|
|
7920
|
+
assertEquals(body.id, "https://example.com/users/john/notes/deleted");
|
|
7921
|
+
assertEquals(body.type, "Tombstone");
|
|
7922
|
+
assertEquals(body.formerType, "as:Note");
|
|
7923
|
+
assertEquals(body.deleted, "2024-01-15T00:00:00Z");
|
|
7924
|
+
});
|
|
7925
|
+
await t.step("HEAD responds with 410 Gone without a body", async () => {
|
|
7926
|
+
const response = await fetch("/users/john/notes/deleted", "HEAD");
|
|
7927
|
+
assertEquals(response.status, 410);
|
|
7928
|
+
assertEquals(response.body, null);
|
|
7929
|
+
});
|
|
7930
|
+
await t.step("objects and null are served as before", async () => {
|
|
7931
|
+
const response = await fetch("/users/john/notes/123");
|
|
7932
|
+
assertEquals(response.status, 200);
|
|
7933
|
+
assertEquals((await response.json()).type, "Note");
|
|
7934
|
+
assertEquals((await fetch("/users/john/notes/missing")).status, 404);
|
|
7935
|
+
});
|
|
7936
|
+
await t.step("Tombstone and Object dispatchers respond with 410", async () => {
|
|
7937
|
+
assertEquals((await fetch("/tombstones/1")).status, 410);
|
|
7938
|
+
assertEquals((await fetch("/objects/deleted")).status, 410);
|
|
7939
|
+
assertEquals((await fetch("/objects/live")).status, 200);
|
|
7940
|
+
});
|
|
7941
|
+
await t.step("RequestContext.getObject()", async () => {
|
|
7942
|
+
const ctx = federation.createContext(new Request("https://example.com/"), void 0);
|
|
7943
|
+
const values = {
|
|
7944
|
+
identifier: "john",
|
|
7945
|
+
id: "deleted"
|
|
7946
|
+
};
|
|
7947
|
+
assertEquals(await ctx.getObject(vocab.Note, values), null);
|
|
7948
|
+
assertEquals(await ctx.getObject(vocab.Note, values, { tombstone: "suppress" }), null);
|
|
7949
|
+
assertEquals(await ctx.getObject(vocab.Note, values, {}), null);
|
|
7950
|
+
const tombstone = await ctx.getObject(vocab.Note, values, { tombstone: "passthrough" });
|
|
7951
|
+
assertInstanceOf(tombstone, vocab.Tombstone);
|
|
7952
|
+
assertEquals(tombstone.id, new URL("https://example.com/users/john/notes/deleted"));
|
|
7953
|
+
assertEquals(tombstone.deleted, deleted);
|
|
7954
|
+
assertInstanceOf(await ctx.getObject(vocab.Note, values, { tombstone: "passthrough" }), vocab.Tombstone);
|
|
7955
|
+
assertInstanceOf(await ctx.getObject(vocab.Note, {
|
|
7956
|
+
identifier: "john",
|
|
7957
|
+
id: "123"
|
|
7958
|
+
}), vocab.Note);
|
|
7959
|
+
assertEquals(await ctx.getObject(vocab.Note, {
|
|
7960
|
+
identifier: "john",
|
|
7961
|
+
id: "missing"
|
|
7962
|
+
}, { tombstone: "passthrough" }), null);
|
|
7963
|
+
assertInstanceOf(await ctx.getObject(vocab.Tombstone, { id: "1" }), vocab.Tombstone);
|
|
7964
|
+
assertInstanceOf(await ctx.getObject(vocab.Object, { id: "deleted" }, { tombstone: "suppress" }), vocab.Tombstone);
|
|
7965
|
+
});
|
|
7966
|
+
await t.step("authorization predicates can get the tombstone", async () => {
|
|
7967
|
+
await withLogtapeLock(async () => {
|
|
7968
|
+
const records = [];
|
|
7969
|
+
await reset();
|
|
7970
|
+
try {
|
|
7971
|
+
await configure({
|
|
7972
|
+
sinks: { buffer(record) {
|
|
7973
|
+
records.push(record);
|
|
7974
|
+
} },
|
|
7975
|
+
filters: {},
|
|
7976
|
+
loggers: [{
|
|
7977
|
+
category: ["fedify", "federation"],
|
|
7978
|
+
sinks: ["buffer"]
|
|
7979
|
+
}, {
|
|
7980
|
+
category: ["logtape", "meta"],
|
|
7981
|
+
sinks: []
|
|
7982
|
+
}]
|
|
7983
|
+
});
|
|
7984
|
+
const federation = createFederation({
|
|
7985
|
+
kv: new MemoryKvStore(),
|
|
7986
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
7987
|
+
contextLoaderFactory: () => mockDocumentLoader
|
|
7988
|
+
});
|
|
7989
|
+
let dispatched = 0;
|
|
7990
|
+
federation.setObjectDispatcher(vocab.Note, "/notes/{id}", (ctx, values) => {
|
|
7991
|
+
dispatched++;
|
|
7992
|
+
return new vocab.Tombstone({ id: ctx.getObjectUri(vocab.Note, values) });
|
|
7993
|
+
}).authorize(async (ctx, values) => {
|
|
7994
|
+
return await ctx.getObject(vocab.Note, values, { tombstone: "passthrough" }) instanceof vocab.Tombstone;
|
|
7995
|
+
});
|
|
7996
|
+
assertEquals((await federation.fetch(new Request("https://example.com/notes/1", { headers: { Accept: "application/activity+json" } }), { contextData: void 0 })).status, 410);
|
|
7997
|
+
assertEquals(dispatched, 2);
|
|
7998
|
+
assert(records.some((record) => getRawMessage(record).startsWith("RequestContext.getObject(") && getRawMessage(record).includes("may cause an infinite loop")));
|
|
7999
|
+
} finally {
|
|
8000
|
+
await reset();
|
|
8001
|
+
}
|
|
8002
|
+
});
|
|
8003
|
+
});
|
|
8004
|
+
await t.step("warns about the id of a tombstone", async () => {
|
|
8005
|
+
await withLogtapeLock(async () => {
|
|
8006
|
+
const records = [];
|
|
8007
|
+
await reset();
|
|
8008
|
+
try {
|
|
8009
|
+
await configure({
|
|
8010
|
+
sinks: { buffer(record) {
|
|
8011
|
+
records.push(record);
|
|
8012
|
+
} },
|
|
8013
|
+
filters: {},
|
|
8014
|
+
loggers: [{
|
|
8015
|
+
category: [
|
|
8016
|
+
"fedify",
|
|
8017
|
+
"federation",
|
|
8018
|
+
"object"
|
|
8019
|
+
],
|
|
8020
|
+
sinks: ["buffer"]
|
|
8021
|
+
}, {
|
|
8022
|
+
category: ["logtape", "meta"],
|
|
8023
|
+
sinks: []
|
|
8024
|
+
}]
|
|
8025
|
+
});
|
|
8026
|
+
const federation = createFederation({
|
|
8027
|
+
kv: new MemoryKvStore(),
|
|
8028
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
8029
|
+
contextLoaderFactory: () => mockDocumentLoader
|
|
8030
|
+
});
|
|
8031
|
+
const ids = {
|
|
8032
|
+
"matching": new URL("https://example.com/notes/matching"),
|
|
8033
|
+
"missing": null,
|
|
8034
|
+
"mismatched": new URL("https://example.com/other/mismatched"),
|
|
8035
|
+
"ap": new URL("ap://did%3Akey%3Az6MkTest/notes/ap"),
|
|
8036
|
+
"ap-ef61": new URL("ap+ef61://did%3Akey%3Az6MkTest/notes/ap-ef61")
|
|
8037
|
+
};
|
|
8038
|
+
federation.setObjectDispatcher(vocab.Note, "/notes/{id}", (_ctx, { id }) => id === "live" ? new vocab.Note({ id: new URL("https://example.com/other/live") }) : new vocab.Tombstone({ id: ids[id] }));
|
|
8039
|
+
const warnings = async (id) => {
|
|
8040
|
+
records.length = 0;
|
|
8041
|
+
assertEquals((await federation.fetch(new Request(`https://example.com/notes/${id}`, { headers: { Accept: "application/activity+json" } }), { contextData: void 0 })).status, id === "live" ? 200 : 410);
|
|
8042
|
+
return records.filter((r) => r.level === "warning");
|
|
8043
|
+
};
|
|
8044
|
+
assertEquals(await warnings("matching"), []);
|
|
8045
|
+
const missing = await warnings("missing");
|
|
8046
|
+
assertEquals(missing.length, 1);
|
|
8047
|
+
assert(getRawMessage(missing[0]).includes("without an id property"));
|
|
8048
|
+
const mismatched = await warnings("mismatched");
|
|
8049
|
+
assertEquals(mismatched.length, 1);
|
|
8050
|
+
assert(getRawMessage(mismatched[0]).includes("does not match"));
|
|
8051
|
+
assertEquals(mismatched[0].properties.tombstoneId, "https://example.com/other/mismatched");
|
|
8052
|
+
assertEquals(mismatched[0].properties.objectUri, "https://example.com/notes/mismatched");
|
|
8053
|
+
assertEquals(await warnings("ap"), []);
|
|
8054
|
+
assertEquals(await warnings("ap-ef61"), []);
|
|
8055
|
+
assertEquals(await warnings("live"), []);
|
|
8056
|
+
} finally {
|
|
8057
|
+
await reset();
|
|
8058
|
+
}
|
|
8059
|
+
});
|
|
8060
|
+
});
|
|
8061
|
+
});
|
|
7885
8062
|
//#endregion
|
|
7886
8063
|
export {};
|
package/dist/federation/mod.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_federation = require("../federation-
|
|
3
|
+
const require_federation = require("../federation-dqo6ZzgT.cjs");
|
|
4
4
|
exports.CircuitBreaker = require_federation.CircuitBreaker;
|
|
5
5
|
exports.InProcessMessageQueue = require_federation.InProcessMessageQueue;
|
|
6
6
|
exports.MemoryKvStore = require_federation.MemoryKvStore;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as InProcessMessageQueue, A as MediaUploaderSetters, At as HashlinkMediaRequest, B as createFederationBuilder, Bt as OutboxPermanentFailureHandler, C as FederationFetchOptions, Ct as CollectionCounter, D as IdempotencyStrategy, Dt as CustomCollectionCursor, E as IdempotencyKeyCallback, Et as CustomCollectionCounter, F as FederationKvPrefixes, Ft as ObjectAuthorizePredicate, G as TaskRegistry, Gt as WebFingerLinksDispatcher, H as TaskDefinitionOptions, Ht as SharedInboxKeyDispatcher, I as FederationOrigin, It as ObjectDispatcher, J as RetryPolicy, Jt as PageItems, K as CreateExponentialBackoffPolicyOptions, Kt as SendActivityError, L as FederationQueueOptions, Lt as OutboxErrorHandler, M as OutboxListenerSetters, Mt as InboxListener, N as PortableInboxForwardingOptions, Nt as MediaUploaderCallback, O as InboxChallengePolicy, Ot as CustomCollectionDispatcher, P as Rfc6570Expression, Pt as NodeInfoDispatcher, Q as respondWithObjectIfAcceptable, R as createFederation, Rt as OutboxListener, S as FederationBuilder, St as AuthorizePredicate, T as FederationStartQueueOptions, Tt as CollectionDispatcher, U as TaskEnqueueOptions, Ut as UnverifiedActivityHandler, V as TaskDefinition, Vt as PortableActorIdMapper, W as TaskHandler, Wt as UnverifiedActivityReason, X as RespondWithObjectOptions, Xt as digest, Y as createExponentialBackoffPolicy, Yt as buildCollectionSynchronizationHeader, Z as respondWithObject, _ as ConstructorWithTypeId, _t as parseCircuitBreakerKvState, a as GetObjectOptions, at as ParallelMessageQueue, b as Federation, bt as ActorHandleMapper, c as OutboxContext, ct as CircuitBreakerBeforeSendDecision, d as RequestContext, dt as CircuitBreakerKvState, et as InProcessMessageQueueOptions, f as RouteActivityOptions, ft as CircuitBreakerOptions, g as CollectionCallbackSetters, gt as normalizeCircuitBreakerOptions, h as ActorCallbackSetters, ht as NormalizedCircuitBreakerOptions, i as GetActorOptions, it as MessageQueueListenOptions, j as ObjectCallbackSetters, jt as InboxErrorHandler, k as InboxListenerSetters, kt as HashlinkMediaDispatcher, l as ParseUriResult, lt as CircuitBreakerCreateOptions, m as SendActivityOptionsForCollection, mt as CircuitBreakerStateChange, n as Context, nt as MessageQueueDepth, o as GetSignedKeyOptions, ot as CircuitBreaker, p as SendActivityOptions, pt as CircuitBreakerState, q as RetryContext, qt as SenderKeyPair, r as ForwardActivityOptions, rt as MessageQueueEnqueueOptions, s as InboxContext, st as CircuitBreakerActivityDrop, t as ActorKeyPair, tt as MessageQueue, u as PortableRequest, ut as CircuitBreakerFailurePolicy, v as CustomCollectionCallbackSetters, vt as ActorAliasMapper, w as FederationOptions, wt as CollectionCursor, x as FederationBenchmarkOptions, xt as ActorKeyPairsDispatcher, y as Federatable, yt as ActorDispatcher, z as Message, zt as OutboxListenerErrorHandler } from "../context-Cqx9M_zO.cjs";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-BhNbN8Ed.cjs";
|
|
4
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
5
|
-
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, HashlinkMediaDispatcher, HashlinkMediaRequest, 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, PortableActorIdMapper, PortableInboxForwardingOptions, PortableRequest, 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 };
|
|
4
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-BuFmStNT.cjs";
|
|
5
|
+
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, GetObjectOptions, GetSignedKeyOptions, HashlinkMediaDispatcher, HashlinkMediaRequest, 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, PortableActorIdMapper, PortableInboxForwardingOptions, PortableRequest, 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,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as InProcessMessageQueue, A as MediaUploaderSetters, At as HashlinkMediaRequest, B as createFederationBuilder, Bt as OutboxPermanentFailureHandler, C as FederationFetchOptions, Ct as CollectionCounter, D as IdempotencyStrategy, Dt as CustomCollectionCursor, E as IdempotencyKeyCallback, Et as CustomCollectionCounter, F as FederationKvPrefixes, Ft as ObjectAuthorizePredicate, G as TaskRegistry, Gt as WebFingerLinksDispatcher, H as TaskDefinitionOptions, Ht as SharedInboxKeyDispatcher, I as FederationOrigin, It as ObjectDispatcher, J as RetryPolicy, Jt as PageItems, K as CreateExponentialBackoffPolicyOptions, Kt as SendActivityError, L as FederationQueueOptions, Lt as OutboxErrorHandler, M as OutboxListenerSetters, Mt as InboxListener, N as PortableInboxForwardingOptions, Nt as MediaUploaderCallback, O as InboxChallengePolicy, Ot as CustomCollectionDispatcher, P as Rfc6570Expression, Pt as NodeInfoDispatcher, Q as respondWithObjectIfAcceptable, R as createFederation, Rt as OutboxListener, S as FederationBuilder, St as AuthorizePredicate, T as FederationStartQueueOptions, Tt as CollectionDispatcher, U as TaskEnqueueOptions, Ut as UnverifiedActivityHandler, V as TaskDefinition, Vt as PortableActorIdMapper, W as TaskHandler, Wt as UnverifiedActivityReason, X as RespondWithObjectOptions, Xt as digest, Y as createExponentialBackoffPolicy, Yt as buildCollectionSynchronizationHeader, Z as respondWithObject, _ as ConstructorWithTypeId, _t as parseCircuitBreakerKvState, a as GetObjectOptions, at as ParallelMessageQueue, b as Federation, bt as ActorHandleMapper, c as OutboxContext, ct as CircuitBreakerBeforeSendDecision, d as RequestContext, dt as CircuitBreakerKvState, et as InProcessMessageQueueOptions, f as RouteActivityOptions, ft as CircuitBreakerOptions, g as CollectionCallbackSetters, gt as normalizeCircuitBreakerOptions, h as ActorCallbackSetters, ht as NormalizedCircuitBreakerOptions, i as GetActorOptions, it as MessageQueueListenOptions, j as ObjectCallbackSetters, jt as InboxErrorHandler, k as InboxListenerSetters, kt as HashlinkMediaDispatcher, l as ParseUriResult, lt as CircuitBreakerCreateOptions, m as SendActivityOptionsForCollection, mt as CircuitBreakerStateChange, n as Context, nt as MessageQueueDepth, o as GetSignedKeyOptions, ot as CircuitBreaker, p as SendActivityOptions, pt as CircuitBreakerState, q as RetryContext, qt as SenderKeyPair, r as ForwardActivityOptions, rt as MessageQueueEnqueueOptions, s as InboxContext, st as CircuitBreakerActivityDrop, t as ActorKeyPair, tt as MessageQueue, u as PortableRequest, ut as CircuitBreakerFailurePolicy, v as CustomCollectionCallbackSetters, vt as ActorAliasMapper, w as FederationOptions, wt as CollectionCursor, x as FederationBenchmarkOptions, xt as ActorKeyPairsDispatcher, y as Federatable, yt as ActorDispatcher, z as Message, zt as OutboxListenerErrorHandler } from "../context-B4F4kGJq.js";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-BhNbN8Ed.js";
|
|
4
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
5
|
-
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, HashlinkMediaDispatcher, HashlinkMediaRequest, 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, PortableActorIdMapper, PortableInboxForwardingOptions, PortableRequest, 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 };
|
|
4
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-4s_XgF17.js";
|
|
5
|
+
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, GetObjectOptions, GetSignedKeyOptions, HashlinkMediaDispatcher, HashlinkMediaRequest, 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, PortableActorIdMapper, PortableInboxForwardingOptions, PortableRequest, 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 respondWithObjectIfAcceptable, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as respondWithObject, l as CircuitBreaker, n as handleWebFinger, o as SendActivityError, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "../middleware-
|
|
3
|
+
import { a as respondWithObjectIfAcceptable, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as respondWithObject, l as CircuitBreaker, n as handleWebFinger, o as SendActivityError, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "../middleware-Dl-Y_ZlC.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";
|
|
@@ -7,12 +7,12 @@ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
8
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
9
9
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
10
|
-
import { t as exportJwk } from "../key-
|
|
11
|
-
import { s as detachSignature } from "../ld-
|
|
12
|
-
import { i as signObject } from "../proof-
|
|
10
|
+
import { t as exportJwk } from "../key-B8u1vdvF.mjs";
|
|
11
|
+
import { s as detachSignature } from "../ld-BTMJHEGV.mjs";
|
|
12
|
+
import { i as signObject } from "../proof-DDw0i9b1.mjs";
|
|
13
13
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
14
|
-
import { c as assertPortableActorActivity, n as FederationImpl, o as createFederation } from "../middleware-
|
|
15
|
-
import { a as verifyCompoundPortableObjectProofs } from "../compound-proof-
|
|
14
|
+
import { c as assertPortableActorActivity, n as FederationImpl, o as createFederation } from "../middleware-B-rZ7oE-.mjs";
|
|
15
|
+
import { a as verifyCompoundPortableObjectProofs } from "../compound-proof-CHGINiJg.mjs";
|
|
16
16
|
import { configure, reset } from "@logtape/logtape";
|
|
17
17
|
import { Create, Note, Person } from "@fedify/vocab";
|
|
18
18
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -8,10 +8,10 @@ import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
|
8
8
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
9
9
|
import "../std__assert-DvMDRPes.mjs";
|
|
10
10
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
11
|
-
import { i as signObject, s as verifyPortableObjectProof } from "../proof-
|
|
12
|
-
import { d as verifyRequest, l as signRequest } from "../http-
|
|
11
|
+
import { i as signObject, s as verifyPortableObjectProof } from "../proof-DDw0i9b1.mjs";
|
|
12
|
+
import { d as verifyRequest, l as signRequest } from "../http-CHEYA5fH.mjs";
|
|
13
13
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
14
|
-
import { b as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-
|
|
14
|
+
import { b as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-B-rZ7oE-.mjs";
|
|
15
15
|
import { n as RouterError } from "../router-u5O5KCQr.mjs";
|
|
16
16
|
import { configure, reset } from "@logtape/logtape";
|
|
17
17
|
import { Note, Person, Tombstone, lookupObject } from "@fedify/vocab";
|
|
@@ -7,10 +7,10 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
7
7
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
9
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
10
|
-
import { p as signJsonLd } from "../ld-
|
|
11
|
-
import { l as signRequest } from "../http-
|
|
10
|
+
import { p as signJsonLd } from "../ld-BTMJHEGV.mjs";
|
|
11
|
+
import { l as signRequest } from "../http-CHEYA5fH.mjs";
|
|
12
12
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
13
|
-
import { f as handleInbox, n as FederationImpl, o as createFederation } from "../middleware-
|
|
13
|
+
import { f as handleInbox, n as FederationImpl, o as createFederation } from "../middleware-B-rZ7oE-.mjs";
|
|
14
14
|
import { t as ActivityListenerSet } from "../activity-listener-C-BSbKI7.mjs";
|
|
15
15
|
import { t as KvKeyCache } from "../keycache-BUDHB5rY.mjs";
|
|
16
16
|
import { Create, CryptographicKey, Person } from "@fedify/vocab";
|
|
@@ -8,11 +8,11 @@ import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
|
8
8
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
9
9
|
import "../std__assert-DvMDRPes.mjs";
|
|
10
10
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
11
|
-
import { p as signJsonLd } from "../ld-
|
|
12
|
-
import { i as signObject } from "../proof-
|
|
13
|
-
import { f as verifyRequestDetailed, l as signRequest } from "../http-
|
|
11
|
+
import { p as signJsonLd } from "../ld-BTMJHEGV.mjs";
|
|
12
|
+
import { i as signObject } from "../proof-DDw0i9b1.mjs";
|
|
13
|
+
import { f as verifyRequestDetailed, l as signRequest } from "../http-CHEYA5fH.mjs";
|
|
14
14
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
15
|
-
import { _ as coversDelivery, o as createFederation, v as forwardPortableInboxActivity, y as resolvePortableInboxForwardingOptions } from "../middleware-
|
|
15
|
+
import { _ as coversDelivery, o as createFederation, v as forwardPortableInboxActivity, y as resolvePortableInboxForwardingOptions } from "../middleware-B-rZ7oE-.mjs";
|
|
16
16
|
import { Create, CryptographicKey, Follow, Note, Person, Tombstone } from "@fedify/vocab";
|
|
17
17
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
18
18
|
import { exportDidKey, formatIri, parseIri } from "@fedify/vocab-runtime";
|
|
@@ -8,10 +8,10 @@ import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
9
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
10
10
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
11
|
-
import { i as signObject, s as verifyPortableObjectProof } from "../proof-
|
|
12
|
-
import { l as signRequest } from "../http-
|
|
11
|
+
import { i as signObject, s as verifyPortableObjectProof } from "../proof-DDw0i9b1.mjs";
|
|
12
|
+
import { l as signRequest } from "../http-CHEYA5fH.mjs";
|
|
13
13
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
14
|
-
import { b as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-
|
|
14
|
+
import { b as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-B-rZ7oE-.mjs";
|
|
15
15
|
import { configure, reset } from "@logtape/logtape";
|
|
16
16
|
import { Collection, Create, Note, Object as Object$1, Person, Tombstone, lookupObject } from "@fedify/vocab";
|
|
17
17
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -220,6 +220,18 @@ test("Federation.fetch() applies the FEP-ef61 proof policy to portable objects",
|
|
|
220
220
|
inbox: parseIri(`ap+ef61://${did}/objects/unsigned-actor/inbox`),
|
|
221
221
|
outbox: parseIri(`ap+ef61://${did}/objects/unsigned-actor/outbox`),
|
|
222
222
|
gateways: [new URL("https://example.com/")]
|
|
223
|
+
})),
|
|
224
|
+
"tombstone": () => sign(new Tombstone({
|
|
225
|
+
id: parseIri(`ap+ef61://${did}/objects/tombstone`),
|
|
226
|
+
formerType: Note
|
|
227
|
+
})),
|
|
228
|
+
"unsigned-tombstone": () => Promise.resolve(new Tombstone({
|
|
229
|
+
id: parseIri(`ap+ef61://${did}/objects/unsigned-tombstone`),
|
|
230
|
+
formerType: Note
|
|
231
|
+
})),
|
|
232
|
+
"mismatched-tombstone": () => sign(new Tombstone({
|
|
233
|
+
id: parseIri(`ap+ef61://${did}/objects/other`),
|
|
234
|
+
formerType: Note
|
|
223
235
|
}))
|
|
224
236
|
};
|
|
225
237
|
federation.setObjectDispatcher(Object$1, "/objects/{id}", (_ctx, { id }) => objects[id]?.() ?? null);
|
|
@@ -234,7 +246,10 @@ test("Federation.fetch() applies the FEP-ef61 proof policy to portable objects",
|
|
|
234
246
|
"activity": 200,
|
|
235
247
|
"actor": 200,
|
|
236
248
|
"mutated-id": 404,
|
|
237
|
-
"unsigned-actor": 500
|
|
249
|
+
"unsigned-actor": 500,
|
|
250
|
+
"tombstone": 200,
|
|
251
|
+
"unsigned-tombstone": 500,
|
|
252
|
+
"mismatched-tombstone": 404
|
|
238
253
|
})) await t.step(`${id} → ${status}`, async () => {
|
|
239
254
|
const response = await federation.fetch(gatewayRequest(`/objects/${id}`), { contextData: void 0 });
|
|
240
255
|
assertEquals(response.status, status);
|
|
@@ -245,6 +260,18 @@ test("Federation.fetch() applies the FEP-ef61 proof policy to portable objects",
|
|
|
245
260
|
assertEquals(response.status, 500);
|
|
246
261
|
assertEquals(response.body, null);
|
|
247
262
|
});
|
|
263
|
+
await t.step("serves a signed tombstone with its body", async () => {
|
|
264
|
+
const response = await federation.fetch(gatewayRequest("/objects/tombstone"), { contextData: void 0 });
|
|
265
|
+
assertEquals(response.status, 200);
|
|
266
|
+
const body = await response.json();
|
|
267
|
+
assertEquals(body.type, "Tombstone");
|
|
268
|
+
assertEquals(body.id, `ap+ef61://${did}/objects/tombstone`);
|
|
269
|
+
});
|
|
270
|
+
await t.step("responds to HEAD for a tombstone without a body", async () => {
|
|
271
|
+
const response = await federation.fetch(gatewayRequest("/objects/tombstone", { method: "HEAD" }), { contextData: void 0 });
|
|
272
|
+
assertEquals(response.status, 200);
|
|
273
|
+
assertEquals(response.body, null);
|
|
274
|
+
});
|
|
248
275
|
});
|
|
249
276
|
test("Federation.fetch() authorizes portable object requests", async (t) => {
|
|
250
277
|
const federation = createTestFederation();
|
|
@@ -10,10 +10,10 @@ import { t as assertNotEquals } from "../assert_not_equals-CpPK2t89.mjs";
|
|
|
10
10
|
import "../std__assert-DvMDRPes.mjs";
|
|
11
11
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
12
12
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
13
|
-
import { d as verifyRequest } from "../http-
|
|
13
|
+
import { d as verifyRequest } from "../http-CHEYA5fH.mjs";
|
|
14
14
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
15
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
16
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-
|
|
15
|
+
import { t as doesActorOwnKey } from "../owner-CY--JSqO.mjs";
|
|
16
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-CU3sHGPt.mjs";
|
|
17
17
|
import { Activity, Application, Endpoints, Group, Person, Service } from "@fedify/vocab";
|
|
18
18
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
19
19
|
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as MemoryKvStore } from "../../kv-DCHkaJ9-.mjs";
|
|
5
5
|
import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../tasks-dbCShlCb.mjs";
|
|
6
6
|
import "../../testing-BWq1dCzx.mjs";
|
|
7
|
-
import { o as createFederation } from "../../middleware-
|
|
7
|
+
import { o as createFederation } from "../../middleware-B-rZ7oE-.mjs";
|
|
8
8
|
import { n as ParallelMessageQueue } from "../../mq-Dm1Wmtm-.mjs";
|
|
9
9
|
import { configure, reset } from "@logtape/logtape";
|
|
10
10
|
import { delay } from "es-toolkit";
|