@fedify/fedify 2.4.0-dev.2256 → 2.4.0-dev.2260
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-DvSQqk2l.mjs → builder-BK8HfSUm.mjs} +8 -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/{compound-proof-5bg_j_ye.mjs → compound-proof-D--HeIbV.mjs} +41 -4
- package/dist/{context-CtI307_A.d.ts → context-7NyiqIcg.d.ts} +111 -2
- package/dist/{context-B6X-t8gI.d.cts → context-tsYPJ2Ew.d.cts} +111 -2
- package/dist/{deno-AmcRMq5z.mjs → deno-DVP7DGJC.mjs} +1 -1
- package/dist/{docloader-CIP_SG39.mjs → docloader-Dv1JJl37.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 +76 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox-report.test.d.mts +2 -0
- package/dist/federation/inbox-report.test.mjs +475 -0
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +7 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +4 -3
- package/dist/federation/mod.d.ts +4 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +54 -10
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +66 -4
- package/dist/federation/portable-delivery.test.mjs +2 -2
- package/dist/federation/portable-gateway-keys.test.mjs +4 -4
- package/dist/federation/portable-inbox.test.mjs +67 -6
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +3 -3
- 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-BDzIgqOd.cjs → federation-Bo5z395X.cjs} +552 -122
- package/dist/{http-1fZ83jj7.cjs → http-BIhWdDf5.cjs} +447 -110
- package/dist/{http-BGb3QioZ.js → http-DRMu1C2T.js} +430 -111
- package/dist/{http-DkqWu-sm.mjs → http-DvpuyDJB.mjs} +141 -98
- package/dist/{key-CEsu7oaD.mjs → key-B7N8mNoY.mjs} +30 -3
- package/dist/{http-BrwKINQn.d.cts → key-C1nv7_jD.d.ts} +638 -229
- package/dist/{http-DGx0KOws.d.ts → key-DYxuyd-s.d.cts} +638 -229
- package/dist/{kv-cache-CJS4mImS.mjs → kv-cache-D0kA0rml.mjs} +1 -1
- package/dist/{kv-cache-CGhEgt98.js → kv-cache-DZLpqhW9.js} +1 -1
- package/dist/{kv-cache-BEWuZSB4.cjs → kv-cache-mF8Zmjix.cjs} +1 -1
- package/dist/{ld-Cf4CPWN_.mjs → ld-BDMNyM2M.mjs} +40 -5
- package/dist/{metrics-CocsZP0E.mjs → metrics-BbBj-VZN.mjs} +2 -1
- package/dist/{middleware-Cne_jMZo.mjs → middleware-CE1X7-UM.mjs} +1 -1
- package/dist/{middleware-Dxn0E9ES.mjs → middleware-DAA7wDdS.mjs} +520 -131
- package/dist/{middleware-BfYke3YQ.js → middleware-DfUWPAa-.js} +552 -122
- package/dist/{mod-C7_2j7VT.d.cts → mod-BojP2Bw3.d.cts} +1 -1
- package/dist/{mod-BlLwewYe.d.ts → mod-CavhAgLw.d.cts} +5 -255
- package/dist/{mod-VHYh1lTK.d.cts → mod-CtpF2BU5.d.ts} +5 -255
- package/dist/{mod-B8MI1mpi.d.ts → mod-DEZXwV6J.d.ts} +1 -1
- package/dist/{mod-DFL6IxYQ.d.cts → mod-Dw-nPxQh.d.cts} +1 -1
- package/dist/{mod-BhTaDR5H.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +7 -7
- package/dist/mod.d.ts +7 -7
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-DSJ7nFgy.mjs → owner-CzUycuhd.mjs} +3 -3
- package/dist/{portable-collection-BuBV6xTo.js → portable-collection-COcJxZg_.js} +1 -1
- package/dist/{portable-collection-qskqXJrH.mjs → portable-collection-CTcNJiAa.mjs} +2 -2
- package/dist/{portable-collection-r-mHg1PV.cjs → portable-collection-cPMffcHJ.cjs} +1 -1
- package/dist/{portable-key-woGH_1nn.mjs → portable-key-B4QN3OzR.mjs} +1 -1
- package/dist/{proof-8WiH_-Gq.mjs → proof-nce4pf5S.mjs} +133 -16
- package/dist/{send-JKzZBgPU.mjs → send-4Idpe2z0.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 +19 -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/mitra-receive-interop.test.mjs +4 -4
- package/dist/sig/mitra-send-interop.test.mjs +3 -3
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-interop.test.mjs +3 -3
- package/dist/sig/portable-key.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +76 -3
- package/dist/sig/tootik-request-interop.test.mjs +4 -4
- package/dist/sig/tootik-send-interop.test.mjs +3 -3
- package/dist/sig/verification.test.d.mts +2 -0
- package/dist/sig/verification.test.mjs +310 -0
- package/dist/{temporal-CT3fRaMH.mjs → temporal-BbjmPHYn.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +315 -28
- 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.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/dist/verification-C3954hQh.mjs +5 -0
- package/dist/verification-Dpfcw8ml.mjs +105 -0
- package/package.json +7 -7
|
@@ -7,14 +7,14 @@ 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 { n as exportJwk } from "../key-
|
|
11
|
-
import { s as detachSignature } from "../ld-
|
|
12
|
-
import { a as signObject } from "../proof-
|
|
10
|
+
import { n as exportJwk } from "../key-B7N8mNoY.mjs";
|
|
11
|
+
import { s as detachSignature } from "../ld-BDMNyM2M.mjs";
|
|
12
|
+
import { a as signObject } from "../proof-nce4pf5S.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 getEmbeddedFirstGateway, S as getCompactRootId, c as assertPortableActorActivity, n as FederationImpl, o as createFederation, w as warnCompatibleIdsInJson } from "../middleware-
|
|
15
|
-
import {
|
|
14
|
+
import { C as getEmbeddedFirstGateway, S as getCompactRootId, c as assertPortableActorActivity, n as FederationImpl, o as createFederation, w as warnCompatibleIdsInJson } from "../middleware-DAA7wDdS.mjs";
|
|
15
|
+
import { o as verifyCompoundPortableObjectProofs } from "../compound-proof-D--HeIbV.mjs";
|
|
16
16
|
import { configure, reset } from "@logtape/logtape";
|
|
17
|
-
import { Announce, Create, Note, Person } from "@fedify/vocab";
|
|
17
|
+
import { Accept, Announce, Create, Follow, Note, Person } from "@fedify/vocab";
|
|
18
18
|
import { exportDidKey, parseIri } from "@fedify/vocab-runtime";
|
|
19
19
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
20
20
|
//#region src/federation/outgoing-proof.test.ts
|
|
@@ -298,6 +298,42 @@ test("a proof set on an embedded map is not delivered either", async () => {
|
|
|
298
298
|
const { bodies } = await capture(() => assertRejects(() => ctx.sendActivity(rsaKey, recipient, httpCreate(child)), TypeError, "JSON Pointer \"/object/proof\""));
|
|
299
299
|
assertEquals(bodies.length, 0);
|
|
300
300
|
});
|
|
301
|
+
test("a received signed object rebuilt inside a portable activity is not delivered", async () => {
|
|
302
|
+
const followerKey = await didKey();
|
|
303
|
+
const signedFollow = await signObject(new Follow({
|
|
304
|
+
id: new URL("https://example.com/follows/1"),
|
|
305
|
+
actor: new URL("https://example.com/users/bob"),
|
|
306
|
+
object: parseIri("ap+ef61://did:key:z6Mkabc/actor")
|
|
307
|
+
}), followerKey.privateKey, new URL("https://example.com/users/bob#key"), {
|
|
308
|
+
...options,
|
|
309
|
+
created
|
|
310
|
+
});
|
|
311
|
+
const follow = await Follow.fromJsonLd(await signedFollow.toJsonLd({
|
|
312
|
+
format: "compact",
|
|
313
|
+
...options
|
|
314
|
+
}), options);
|
|
315
|
+
const owner = await didKey();
|
|
316
|
+
const accept = (object) => new Accept({
|
|
317
|
+
id: parseIri(`ap+ef61://${owner.did}/accepts/${crypto.randomUUID()}`),
|
|
318
|
+
actor: parseIri(`ap+ef61://${owner.did}/actor`),
|
|
319
|
+
object
|
|
320
|
+
});
|
|
321
|
+
const unsigned = accept(follow);
|
|
322
|
+
const presigned = await signObject(accept(follow), owner.privateKey, owner.keyId, {
|
|
323
|
+
...options,
|
|
324
|
+
created
|
|
325
|
+
});
|
|
326
|
+
const cases = [[unsigned, [rsaKey, sender(owner)]], [presigned, [rsaKey]]];
|
|
327
|
+
for (const [activity, keys] of cases) {
|
|
328
|
+
assertEquals((await capture(() => assertRejects(() => createTestFederation().createContext(new URL("https://example.com/")).sendActivity(keys, recipient, activity), TypeError, "JSON Pointer \"/object\""))).bodies.length, 0);
|
|
329
|
+
const fanout = createQueue();
|
|
330
|
+
await assertRejects(() => createTestFederation(fanout.queue).createContext(new URL("https://example.com/")).sendActivity(keys, recipient, activity, { fanout: "force" }), TypeError, "JSON Pointer \"/object\"");
|
|
331
|
+
assertEquals(fanout.queued.length, 0);
|
|
332
|
+
}
|
|
333
|
+
const { bodies } = await capture(() => createTestFederation().createContext(new URL("https://example.com/")).sendActivity([rsaKey, sender(owner)], recipient, accept(follow.id)));
|
|
334
|
+
assertEquals(bodies.length, 1);
|
|
335
|
+
await assertCompoundVerifies(bodies[0]);
|
|
336
|
+
});
|
|
301
337
|
test("forced fanout selects the DID-matching key before enqueueing", async () => {
|
|
302
338
|
const owner = await didKey();
|
|
303
339
|
const childOwner = await didKey();
|
|
@@ -327,9 +363,9 @@ test("forced fanout selects the DID-matching key before enqueueing", async () =>
|
|
|
327
363
|
});
|
|
328
364
|
test("the fanout worker selects one key for an unsigned portable activity", async () => {
|
|
329
365
|
const owner = await didKey();
|
|
330
|
-
const
|
|
366
|
+
const child = await signedChild(await didKey());
|
|
331
367
|
const federation = createTestFederation();
|
|
332
|
-
const message = {
|
|
368
|
+
const message = async (activity) => ({
|
|
333
369
|
type: "fanout",
|
|
334
370
|
id: crypto.randomUUID(),
|
|
335
371
|
baseUrl: "https://example.com",
|
|
@@ -352,10 +388,18 @@ test("the fanout worker selects one key for an unsigned portable activity", asyn
|
|
|
352
388
|
activityId: activity.id.href,
|
|
353
389
|
activityType: "https://www.w3.org/ns/activitystreams#Create",
|
|
354
390
|
traceContext: {}
|
|
355
|
-
};
|
|
356
|
-
const
|
|
391
|
+
});
|
|
392
|
+
const byId = new Create({
|
|
393
|
+
id: parseIri(`ap+ef61://${owner.did}/activities/${crypto.randomUUID()}`),
|
|
394
|
+
actor: parseIri(`ap+ef61://${owner.did}/actor`),
|
|
395
|
+
object: child.id
|
|
396
|
+
});
|
|
397
|
+
const { bodies } = await capture(async () => federation.processQueuedTask(void 0, await message(byId)));
|
|
357
398
|
assertEquals(bodies.length, 1);
|
|
358
399
|
assertEquals(proofOf(bodies[0]).verificationMethod, owner.keyId.href);
|
|
400
|
+
await assertCompoundVerifies(bodies[0]);
|
|
401
|
+
const embedded = await message(portableCreate(owner, child));
|
|
402
|
+
assertEquals((await capture(() => assertRejects(() => federation.processQueuedTask(void 0, embedded), TypeError, "JSON Pointer \"/object\""))).bodies.length, 0);
|
|
359
403
|
});
|
|
360
404
|
test("actor key pairs follow the compound-proof key selection too", async () => {
|
|
361
405
|
const dispatched = [];
|
|
@@ -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 { a as signObject, c as verifyPortableObjectProof } from "../proof-
|
|
12
|
-
import { f as verifyRequest, l as signRequest } from "../http-
|
|
11
|
+
import { a as signObject, c as verifyPortableObjectProof } from "../proof-nce4pf5S.mjs";
|
|
12
|
+
import { f as verifyRequest, l as signRequest } from "../http-DvpuyDJB.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-DAA7wDdS.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 assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
|
7
7
|
import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
9
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
10
|
-
import { n as exportJwk } from "../key-
|
|
11
|
-
import { c as verifyPortableObjectProof, s as verifyObject } from "../proof-
|
|
10
|
+
import { n as exportJwk } from "../key-B7N8mNoY.mjs";
|
|
11
|
+
import { c as verifyPortableObjectProof, s as verifyObject } from "../proof-nce4pf5S.mjs";
|
|
12
12
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
13
|
-
import { n as FederationImpl } from "../middleware-
|
|
13
|
+
import { n as FederationImpl } from "../middleware-DAA7wDdS.mjs";
|
|
14
14
|
import { Create, DataIntegrityProof, Note, OrderedCollection, Person, traverseCollection } from "@fedify/vocab";
|
|
15
15
|
import { FetchError, encodeMultibase, exportDidKey } from "@fedify/vocab-runtime";
|
|
16
16
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -7,11 +7,11 @@ import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
|
7
7
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
9
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
10
|
-
import { a as signObject } from "../proof-
|
|
10
|
+
import { a as signObject, c as verifyPortableObjectProof } from "../proof-nce4pf5S.mjs";
|
|
11
11
|
import { n as ed25519PrivateKey, r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
12
|
-
import { b as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-
|
|
13
|
-
import { t as verifyPortableObject } from "../portable-collection-
|
|
14
|
-
import {
|
|
12
|
+
import { b as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-DAA7wDdS.mjs";
|
|
13
|
+
import { t as verifyPortableObject } from "../portable-collection-CTcNJiAa.mjs";
|
|
14
|
+
import { c as verifyServedPortableObjects } from "../compound-proof-D--HeIbV.mjs";
|
|
15
15
|
import { n as RouterError } from "../router-u5O5KCQr.mjs";
|
|
16
16
|
import { configure, reset } from "@logtape/logtape";
|
|
17
17
|
import { Create, Note, Object as Object$1, OrderedCollection, PUBLIC_COLLECTION, Person, Tombstone, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
@@ -528,6 +528,68 @@ test("Fedify traverses portable collections that Fedify serves", async () => {
|
|
|
528
528
|
assert(actor2 instanceof Person);
|
|
529
529
|
assertEquals(await actor2.getOutbox(evilOptions), null);
|
|
530
530
|
});
|
|
531
|
+
test("Fedify traverses portable collections through their owners' gateways", async () => {
|
|
532
|
+
const federation = createTestFederation();
|
|
533
|
+
const requests = [];
|
|
534
|
+
const documentLoader = async (url) => {
|
|
535
|
+
requests.push(url);
|
|
536
|
+
if (!/^https?:/.test(url)) throw new Error(`Not found: ${url}`);
|
|
537
|
+
const target = new URL(url);
|
|
538
|
+
const response = await federation.fetch(new Request(new URL(target.pathname + target.search, ORIGIN), { headers: { Accept: ACCEPT } }), { contextData: void 0 });
|
|
539
|
+
if (!response.ok) throw new FetchError(url, `HTTP ${response.status}`, response);
|
|
540
|
+
return {
|
|
541
|
+
contextUrl: null,
|
|
542
|
+
documentUrl: url,
|
|
543
|
+
document: await response.json()
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
const options = {
|
|
547
|
+
documentLoader,
|
|
548
|
+
contextLoader: mockDocumentLoader,
|
|
549
|
+
verifyPortableObject
|
|
550
|
+
};
|
|
551
|
+
const actor = await lookupObject(portableId("/users/alice"), {
|
|
552
|
+
...options,
|
|
553
|
+
gateways: [ORIGIN]
|
|
554
|
+
});
|
|
555
|
+
assert(actor instanceof Person);
|
|
556
|
+
const outbox = await actor.getOutbox(options);
|
|
557
|
+
assert(outbox instanceof OrderedCollection);
|
|
558
|
+
assertEquals((await Array.fromAsync(traverseCollection(outbox, options))).length, PAGES.length * NOTES_PER_PAGE);
|
|
559
|
+
assert(requests.every((url) => url.startsWith(`${ORIGIN}/`)));
|
|
560
|
+
});
|
|
561
|
+
test("Fedify accepts empty portable collections that Fedify serves", async () => {
|
|
562
|
+
const federation = createTestFederation();
|
|
563
|
+
const [response, json] = await fetchJson(federation, gatewayUrl("/users/alice/inbox"));
|
|
564
|
+
assertEquals(response.status, 200);
|
|
565
|
+
assertEquals(json?.totalItems, 0);
|
|
566
|
+
assertEquals(await verifyPortableObjectProof(json, { contextLoader: mockDocumentLoader }), {
|
|
567
|
+
verified: false,
|
|
568
|
+
reason: { type: "unsecuredCollection" }
|
|
569
|
+
});
|
|
570
|
+
const documentLoader = async (url) => {
|
|
571
|
+
const target = new URL(url);
|
|
572
|
+
const response = await federation.fetch(new Request(new URL(target.pathname + target.search, ORIGIN), { headers: { Accept: ACCEPT } }), { contextData: void 0 });
|
|
573
|
+
if (!response.ok) throw new FetchError(url, `HTTP ${response.status}`, response);
|
|
574
|
+
return {
|
|
575
|
+
contextUrl: null,
|
|
576
|
+
documentUrl: url,
|
|
577
|
+
document: await response.json()
|
|
578
|
+
};
|
|
579
|
+
};
|
|
580
|
+
const options = {
|
|
581
|
+
documentLoader,
|
|
582
|
+
contextLoader: mockDocumentLoader,
|
|
583
|
+
gateways: [ORIGIN],
|
|
584
|
+
verifyPortableObject
|
|
585
|
+
};
|
|
586
|
+
const actor = await lookupObject(portableId("/users/alice"), options);
|
|
587
|
+
assert(actor instanceof Person);
|
|
588
|
+
const inbox = await actor.getInbox(options);
|
|
589
|
+
assert(inbox instanceof OrderedCollection);
|
|
590
|
+
assertEquals(inbox.totalItems, 0);
|
|
591
|
+
assertEquals(await Array.fromAsync(traverseCollection(inbox, options)), []);
|
|
592
|
+
});
|
|
531
593
|
test("verifyServedPortableObjects() classifies unsigned maps under their effective contexts", async () => {
|
|
532
594
|
const AS = "https://www.w3.org/ns/activitystreams";
|
|
533
595
|
const collection = (member) => ({
|
|
@@ -4,8 +4,8 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as esm_default } from "../esm-BHXXx4Wx.mjs";
|
|
5
5
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
6
6
|
import { i as rsaPrivateKey2, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
7
|
-
import { n as FederationImpl, r as InboxContextImpl } from "../middleware-
|
|
8
|
-
import { n as extractInboxes, t as SendActivityError } from "../send-
|
|
7
|
+
import { n as FederationImpl, r as InboxContextImpl } from "../middleware-DAA7wDdS.mjs";
|
|
8
|
+
import { n as extractInboxes, t as SendActivityError } from "../send-4Idpe2z0.mjs";
|
|
9
9
|
import { Create, Endpoints, Note, Person } from "@fedify/vocab";
|
|
10
10
|
import { parseIri } from "@fedify/vocab-runtime";
|
|
11
11
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -8,11 +8,11 @@ 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
10
|
import { r as getVerifiedKeyOwnerEvidence } from "../key-owner-evidence-APB6NpSk.mjs";
|
|
11
|
-
import { p as signJsonLd } from "../ld-
|
|
12
|
-
import { f as verifyRequest, l as signRequest, p as verifyRequestDetailed } from "../http-
|
|
11
|
+
import { p as signJsonLd } from "../ld-BDMNyM2M.mjs";
|
|
12
|
+
import { f as verifyRequest, l as signRequest, p as verifyRequestDetailed } from "../http-DvpuyDJB.mjs";
|
|
13
13
|
import { a as rsaPrivateKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
14
|
-
import { f as handleInbox, n as FederationImpl, o as createFederation } from "../middleware-
|
|
15
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-
|
|
14
|
+
import { f as handleInbox, n as FederationImpl, o as createFederation } from "../middleware-DAA7wDdS.mjs";
|
|
15
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-CzUycuhd.mjs";
|
|
16
16
|
import { t as ActivityListenerSet } from "../activity-listener-C-BSbKI7.mjs";
|
|
17
17
|
import { t as KvKeyCache } from "../keycache-Da8A8mZa.mjs";
|
|
18
18
|
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 { a as signObject } from "../proof-
|
|
13
|
-
import { l as signRequest, p as verifyRequestDetailed } from "../http-
|
|
11
|
+
import { p as signJsonLd } from "../ld-BDMNyM2M.mjs";
|
|
12
|
+
import { a as signObject } from "../proof-nce4pf5S.mjs";
|
|
13
|
+
import { l as signRequest, p as verifyRequestDetailed } from "../http-DvpuyDJB.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-DAA7wDdS.mjs";
|
|
16
16
|
import { Create, CryptographicKey, Follow, Note, Person, Tombstone } from "@fedify/vocab";
|
|
17
17
|
import { exportDidKey, formatIri, parseIri } from "@fedify/vocab-runtime";
|
|
18
18
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -86,7 +86,10 @@ function setup({ gateways = [
|
|
|
86
86
|
publicKey: rsaPublicKey2.publicKey
|
|
87
87
|
}] : identifier === "alice" ? aliceKeyPairs : []);
|
|
88
88
|
if (mapPortableActorId != null) actorCallbacks.mapPortableActorId((_ctx, identifier) => mapPortableActorId(identifier));
|
|
89
|
-
const
|
|
89
|
+
const reports = [];
|
|
90
|
+
const inboxListeners = federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").onRequestFinished((_ctx, report) => {
|
|
91
|
+
reports.push(report);
|
|
92
|
+
});
|
|
90
93
|
if (onSharedInboxKey != null) inboxListeners.setSharedKeyDispatcher(() => {
|
|
91
94
|
onSharedInboxKey();
|
|
92
95
|
return null;
|
|
@@ -107,7 +110,8 @@ function setup({ gateways = [
|
|
|
107
110
|
federation,
|
|
108
111
|
received,
|
|
109
112
|
kv,
|
|
110
|
-
queue
|
|
113
|
+
queue,
|
|
114
|
+
reports
|
|
111
115
|
};
|
|
112
116
|
}
|
|
113
117
|
let activityCounter = 0;
|
|
@@ -194,6 +198,31 @@ test("Federation.fetch() refuses portable inbox deliveries it does not accept",
|
|
|
194
198
|
assertEquals(accepting.received.length, 0);
|
|
195
199
|
});
|
|
196
200
|
});
|
|
201
|
+
test("onRequestFinished retains crypto success when a portable activity's DID mismatches", async () => {
|
|
202
|
+
const { federation, reports, received } = setup();
|
|
203
|
+
const signingKeyId = new URL(`${otherDid}#${otherDid.substring(8)}`);
|
|
204
|
+
const activity = await signObject(new Follow({
|
|
205
|
+
id: parseIri(`ap+ef61://${did}/follows/mismatched-report`),
|
|
206
|
+
actor: parseIri(`ap+ef61://${otherDid}/users/bob`),
|
|
207
|
+
object: parseIri(`ap+ef61://${did}/users/alice`)
|
|
208
|
+
}), otherKeyPair.privateKey, signingKeyId, { contextLoader: mockDocumentLoader });
|
|
209
|
+
assertEquals((await federation.fetch(post(inboxUrl(), await activity.toJsonLd({ contextLoader: mockDocumentLoader })), { contextData: void 0 })).status, 401);
|
|
210
|
+
assertEquals(received.length, 0);
|
|
211
|
+
assertEquals(reports.length, 1);
|
|
212
|
+
const report = reports[0];
|
|
213
|
+
assert(report.authentication.status === "rejected");
|
|
214
|
+
assert(report.authentication.reason.type === "proofPolicy");
|
|
215
|
+
assertEquals(report.authentication.reason.policy, "portableActivity");
|
|
216
|
+
assertEquals(report.authentication.reason.detail?.type, "verificationMethodMismatch");
|
|
217
|
+
assert(report.attempts.some((attempt) => attempt.mechanism === "objectIntegrity" && attempt.checks.some((check) => check.status === "verified")));
|
|
218
|
+
assert(report.attempts.some((attempt) => attempt.status === "rejected" && attempt.reason.type === "proofPolicy" && attempt.reason.reason.type === "verificationMethodMismatch"));
|
|
219
|
+
assertEquals(report.outcome, {
|
|
220
|
+
type: "response",
|
|
221
|
+
status: 401,
|
|
222
|
+
disposition: "rejected",
|
|
223
|
+
reason: "authentication"
|
|
224
|
+
});
|
|
225
|
+
});
|
|
197
226
|
test("Federation.fetch() applies the proof policy to portable inbox deliveries", async (t) => {
|
|
198
227
|
const queue = new RecordingQueue();
|
|
199
228
|
const { federation, received } = setup({ queue });
|
|
@@ -1470,5 +1499,37 @@ test("Federation.fetch() keeps ordinary inbox deliveries unchanged", async () =>
|
|
|
1470
1499
|
assertEquals(received.length, 1);
|
|
1471
1500
|
assertEquals(queue.outbox.length, 0);
|
|
1472
1501
|
});
|
|
1502
|
+
test("onRequestFinished covers portable ingress and recipient lookup failures", async () => {
|
|
1503
|
+
const { federation, reports } = setup({ options: { portableInboxForwarding: { maxTargets: 0 } } });
|
|
1504
|
+
assertEquals((await federation.fetch(post(inboxUrl(), await signedFollow()), { contextData: void 0 })).status, 202);
|
|
1505
|
+
assertEquals(reports.length, 1);
|
|
1506
|
+
assertEquals(reports[0].inbox, {
|
|
1507
|
+
kind: "portable",
|
|
1508
|
+
recipient: "alice"
|
|
1509
|
+
});
|
|
1510
|
+
assertEquals(reports[0].authentication.status, "verified");
|
|
1511
|
+
assert(reports[0].attempts.some((attempt) => attempt.subject.pointer === "" && attempt.status === "verified"));
|
|
1512
|
+
const absent = setup({ actor: () => null });
|
|
1513
|
+
assertEquals((await absent.federation.fetch(post(inboxUrl(), {}), { contextData: void 0 })).status, 404);
|
|
1514
|
+
assertEquals(absent.reports[0].payload, { status: "unavailable" });
|
|
1515
|
+
assertEquals(absent.reports[0].authentication, { status: "notDetermined" });
|
|
1516
|
+
const failure = /* @__PURE__ */ new Error("recipient lookup failed");
|
|
1517
|
+
const broken = setup({ actor: () => {
|
|
1518
|
+
throw failure;
|
|
1519
|
+
} });
|
|
1520
|
+
let thrown;
|
|
1521
|
+
try {
|
|
1522
|
+
await broken.federation.fetch(post(inboxUrl(), {}), { contextData: void 0 });
|
|
1523
|
+
} catch (error) {
|
|
1524
|
+
thrown = error;
|
|
1525
|
+
}
|
|
1526
|
+
assertEquals(thrown, failure);
|
|
1527
|
+
assertEquals(broken.reports.length, 1);
|
|
1528
|
+
assertEquals(broken.reports[0].outcome, {
|
|
1529
|
+
type: "exception",
|
|
1530
|
+
stage: "prepare",
|
|
1531
|
+
error: failure
|
|
1532
|
+
});
|
|
1533
|
+
});
|
|
1473
1534
|
//#endregion
|
|
1474
1535
|
export {};
|
|
@@ -7,7 +7,7 @@ import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
8
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
9
9
|
import { r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
10
|
-
import { o as createFederation } from "../middleware-
|
|
10
|
+
import { o as createFederation } from "../middleware-DAA7wDdS.mjs";
|
|
11
11
|
import { Note, Object as Object$1, Person } from "@fedify/vocab";
|
|
12
12
|
import { exportDidKey, parseIri } from "@fedify/vocab-runtime";
|
|
13
13
|
import { test } from "@fedify/fixture";
|
|
@@ -6,9 +6,9 @@ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
|
6
6
|
import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
8
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
9
|
-
import { a as signObject } from "../proof-
|
|
9
|
+
import { a as signObject } from "../proof-nce4pf5S.mjs";
|
|
10
10
|
import { n as ed25519PrivateKey, r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
11
|
-
import { o as createFederation } from "../middleware-
|
|
11
|
+
import { o as createFederation } from "../middleware-DAA7wDdS.mjs";
|
|
12
12
|
import { Create, Note } from "@fedify/vocab";
|
|
13
13
|
import { exportDidKey, formatIri, parseIri, toCompatibleEf61Id } from "@fedify/vocab-runtime";
|
|
14
14
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -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 { a as signObject, c as verifyPortableObjectProof } from "../proof-
|
|
12
|
-
import { l as signRequest } from "../http-
|
|
11
|
+
import { a as signObject, c as verifyPortableObjectProof } from "../proof-nce4pf5S.mjs";
|
|
12
|
+
import { l as signRequest } from "../http-DvpuyDJB.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-DAA7wDdS.mjs";
|
|
15
15
|
import { configure, reset } from "@logtape/logtape";
|
|
16
16
|
import { Collection, Create, Note, Object as Object$1, PUBLIC_COLLECTION, Person, Tombstone, lookupObject } from "@fedify/vocab";
|
|
17
17
|
import { exportDidKey, formatIri, parseIri, toCompatibleEf61Id } from "@fedify/vocab-runtime";
|
|
@@ -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 { f as verifyRequest } from "../http-
|
|
13
|
+
import { f as verifyRequest } from "../http-DvpuyDJB.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-CzUycuhd.mjs";
|
|
16
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-4Idpe2z0.mjs";
|
|
17
17
|
import { Activity, Application, Endpoints, Group, Person, Service } from "@fedify/vocab";
|
|
18
18
|
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
19
19
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -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-IG3pHfvZ.mjs";
|
|
6
6
|
import "../../testing-t8xDeJZ5.mjs";
|
|
7
|
-
import { o as createFederation } from "../../middleware-
|
|
7
|
+
import { o as createFederation } from "../../middleware-DAA7wDdS.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";
|
|
@@ -4,8 +4,8 @@ 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-IG3pHfvZ.mjs";
|
|
6
6
|
import "../../testing-t8xDeJZ5.mjs";
|
|
7
|
-
import { o as createFederation } from "../../middleware-
|
|
8
|
-
import { r as createFederationBuilder } from "../../builder-
|
|
7
|
+
import { o as createFederation } from "../../middleware-DAA7wDdS.mjs";
|
|
8
|
+
import { r as createFederationBuilder } from "../../builder-BK8HfSUm.mjs";
|
|
9
9
|
import { t as TaskCodec } from "../../codec-C6rTrpIp.mjs";
|
|
10
10
|
import { t as InProcessMessageQueue } from "../../mq-Dm1Wmtm-.mjs";
|
|
11
11
|
import { W3CTraceContextPropagator } from "@opentelemetry/core";
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
5
5
|
import "../std__assert-DvMDRPes.mjs";
|
|
6
6
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
7
|
-
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-
|
|
7
|
+
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-BbjmPHYn.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 () => {
|
|
@@ -6,7 +6,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import { t as assertNotEquals } from "../assert_not_equals-CpPK2t89.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
|
-
import { o as createFederation, s as handleWebFinger } from "../middleware-
|
|
9
|
+
import { o as createFederation, s as handleWebFinger } from "../middleware-DAA7wDdS.mjs";
|
|
10
10
|
import { Image, Link, Person, Tombstone } from "@fedify/vocab";
|
|
11
11
|
import { parseIri } from "@fedify/vocab-runtime";
|
|
12
12
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|