@fedify/fedify 2.4.0-dev.2169 → 2.4.0-dev.2190
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-B2d_Pt0j.mjs → builder-CFF0YNTp.mjs} +3 -3
- package/dist/{circuit-breaker-C5NqoLBJ.mjs → circuit-breaker-XJ53md4S.mjs} +16 -11
- 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-D28gMFqP.mjs → compound-proof-F2jjkrt0.mjs} +3 -3
- package/dist/{context-BykNUf04.d.ts → context-9T--NSo4.d.ts} +55 -1
- package/dist/{context-L0Fnib9j.d.cts → context-CDcAgm4l.d.cts} +55 -1
- package/dist/{deno-DU8dvnWk.mjs → deno-EopndaNb.mjs} +1 -1
- package/dist/{docloader-CghLH7Zi.mjs → docloader-u6zzOExF.mjs} +25 -17
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/circuit-breaker.test.mjs +50 -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 +5 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/keycache.test.mjs +1 -1
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +137 -13
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +2 -2
- package/dist/federation/mod.d.ts +2 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +5 -5
- 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 +4 -4
- package/dist/federation/portable-gateway-keys.test.mjs +6 -6
- package/dist/federation/portable-inbox.test.mjs +35 -5
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.d.mts +2 -0
- package/dist/federation/portable-route-activity.test.mjs +259 -0
- 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-DrNgkLfJ.cjs → federation-BSS2dUO7.cjs} +38 -21
- package/dist/{http-BGpexPO7.js → http-BqN5kyUf.js} +219 -87
- package/dist/{http-Cok5-vIC.d.ts → http-BrwKINQn.d.cts} +29 -1
- package/dist/{http-5CJBdU8n.cjs → http-CCr2_ipG.cjs} +236 -86
- package/dist/{http-DC1cqAQ2.d.cts → http-DGx0KOws.d.ts} +29 -1
- package/dist/{http-Bd6rZlJX.mjs → http-Y1ObT1A8.mjs} +180 -92
- package/dist/{key-gIhVZO3p.mjs → key-DyXf88bq.mjs} +4 -4
- package/dist/{key-owner-evidence-Bo3yaeL5.mjs → key-owner-evidence-APB6NpSk.mjs} +1 -1
- package/dist/{keycache-PiOM9pM0.mjs → keycache-Da8A8mZa.mjs} +1 -1
- package/dist/{kv-cache-iR55fqlk.js → kv-cache-C02XitwK.js} +24 -16
- package/dist/{kv-cache-D0qjSeWY.mjs → kv-cache-C8YjNAi_.mjs} +1 -1
- package/dist/{kv-cache-YRi_g8GB.cjs → kv-cache-DUXluAc0.cjs} +23 -15
- package/dist/{ld-BsTkRrwF.mjs → ld-oQj6j_hP.mjs} +3 -3
- package/dist/{metrics-jUDFfVgi.mjs → metrics-zMe834ID.mjs} +1 -1
- package/dist/{middleware-Coqgp-K0.mjs → middleware-Bdu2-OPD.mjs} +37 -25
- package/dist/{middleware-DlxMxVp5.js → middleware-CaR2MRWY.js} +39 -22
- package/dist/{middleware-Dq-OCmb6.mjs → middleware-Ck9yghxs.mjs} +1 -1
- package/dist/{mod-DK0y9fd-.d.ts → mod-B3OBLj5g.d.ts} +1 -1
- package/dist/{mod-B5z_q9TH.d.ts → mod-C5Mwx5ty.d.ts} +5 -1
- package/dist/{mod--jv6vyrP.d.ts → mod-Ck9_lSJB.d.ts} +1 -1
- package/dist/{mod-BLOXGs6m.d.cts → mod-D58KCqUg.d.cts} +1 -1
- package/dist/{mod-CPPqkyV_.d.cts → mod-DHTuu3l8.d.cts} +1 -1
- package/dist/{mod-BA_F2x53.d.cts → mod-Dp3Ij7sw.d.cts} +5 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-D3GoetXS.mjs → owner-Dem4fbwc.mjs} +5 -5
- package/dist/{portable-collection-Bkdh_WpL.js → portable-collection-BEqLrMW3.js} +1 -1
- package/dist/{portable-collection-C60_acmx.mjs → portable-collection-BL6aZlQ0.mjs} +2 -2
- package/dist/{portable-collection-CnlCamup.cjs → portable-collection-DJe_bk50.cjs} +1 -1
- package/dist/{portable-key-DyF5AnZo.mjs → portable-key-Duue9Y2Y.mjs} +2 -2
- package/dist/{portable-key-id-Bg259c4Z.mjs → portable-key-id-Ca30-hOa.mjs} +45 -1
- package/dist/{proof-CQAYqWdj.mjs → proof-C9115DX_.mjs} +5 -5
- package/dist/{send-DjkQrxt5.mjs → send-D0hxFFRB.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 +495 -23
- package/dist/sig/key-owner-evidence.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.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-key-id.test.d.mts +2 -0
- package/dist/sig/portable-key-id.test.mjs +67 -0
- package/dist/sig/portable-key.test.mjs +7 -7
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/{temporal-oRKP803M.mjs → temporal-DKchpKyp.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +52 -0
- package/dist/utils/docloader.test.mjs +93 -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/package.json +7 -7
package/dist/sig/owner.test.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
|
6
6
|
import "../std__assert-DvMDRPes.mjs";
|
|
7
7
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
8
8
|
import { o as rsaPublicKey1, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
9
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-
|
|
9
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-Dem4fbwc.mjs";
|
|
10
10
|
import { Create, CryptographicKey, lookupObject } from "@fedify/vocab";
|
|
11
11
|
import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
12
12
|
//#region src/sig/owner.test.ts
|
|
@@ -2,7 +2,7 @@ import "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { n as ed25519PrivateKey, r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
5
|
-
import { t as verifyPortableObject } from "../portable-collection-
|
|
5
|
+
import { t as verifyPortableObject } from "../portable-collection-BL6aZlQ0.mjs";
|
|
6
6
|
import { Collection, CollectionPage, Note, OrderedCollection, Person, traverseCollection } from "@fedify/vocab";
|
|
7
7
|
import { test } from "@fedify/fixture";
|
|
8
8
|
import { FetchError, encodeMultibase, exportDidKey, preloadedContexts } from "@fedify/vocab-runtime";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import "temporal-polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
5
|
+
import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
6
|
+
import "../std__assert-DvMDRPes.mjs";
|
|
7
|
+
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
8
|
+
import { f as isSameObjectId, t as getAuthenticationOrigin } from "../portable-key-id-Ca30-hOa.mjs";
|
|
9
|
+
import { r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
10
|
+
import { test } from "@fedify/fixture";
|
|
11
|
+
import { exportDidKey, parseIri } from "@fedify/vocab-runtime";
|
|
12
|
+
//#region src/sig/portable-key-id.test.ts
|
|
13
|
+
const did = await exportDidKey(ed25519PublicKey.publicKey);
|
|
14
|
+
const otherDid = await exportDidKey((await crypto.subtle.generateKey("Ed25519", true, ["sign", "verify"])).publicKey);
|
|
15
|
+
test("getAuthenticationOrigin()", () => {
|
|
16
|
+
for (const id of [
|
|
17
|
+
parseIri(`ap://${did}/actor`),
|
|
18
|
+
parseIri(`ap+ef61://${did}/actor`),
|
|
19
|
+
parseIri(`ap+ef61://${encodeURIComponent(did)}/actor#main-key`),
|
|
20
|
+
parseIri(`ap://${did}/actor?@gateway=https%3A%2F%2Fgw.example`),
|
|
21
|
+
new URL(`https://gw.example/.well-known/apgateway/${did}/actor`),
|
|
22
|
+
new URL(`https://gw2.example/.well-known/apgateway/${did}/objects/1`),
|
|
23
|
+
new URL(`${did}#${did.slice(8)}`)
|
|
24
|
+
]) assertEquals(getAuthenticationOrigin(id), did, id.href);
|
|
25
|
+
assertEquals(getAuthenticationOrigin(parseIri(`ap+ef61://${otherDid}/actor`)), otherDid);
|
|
26
|
+
assertEquals(getAuthenticationOrigin(new URL("https://example.com:443/users/alice")), "https://example.com");
|
|
27
|
+
assertEquals(getAuthenticationOrigin(new URL("http://example.com:8080/users/alice")), "http://example.com:8080");
|
|
28
|
+
for (const id of [
|
|
29
|
+
new URL(`https://gw.example/.well-known/apgateway/${did}/actor?@gateway=https%3A%2F%2Fgw.example`),
|
|
30
|
+
new URL("https://gw.example/.well-known/apgateway/did:key:invalid!/a"),
|
|
31
|
+
new URL(`https://gw.example/.well-known/apgateway/${did}`),
|
|
32
|
+
new URL(`https://gw.example/.well-known/apgateway/${did}/actor%ZZ`),
|
|
33
|
+
new URL("urn:uuid:3d6f4c1e-2f8b-4d1a-9c6e-7b8a9d0e1f2a"),
|
|
34
|
+
new URL("tag:example.com,2026:actor")
|
|
35
|
+
]) assertEquals(getAuthenticationOrigin(id), null, id.href);
|
|
36
|
+
});
|
|
37
|
+
test("isSameObjectId()", () => {
|
|
38
|
+
const portable = parseIri(`ap+ef61://${did}/activities/1`);
|
|
39
|
+
for (const id of [
|
|
40
|
+
parseIri(`ap://${did}/activities/1`),
|
|
41
|
+
parseIri(`ap+ef61://${encodeURIComponent(did)}/activities/1`),
|
|
42
|
+
parseIri(`ap://${did}/activities/1?@gateway=https%3A%2F%2Fgw.example`),
|
|
43
|
+
new URL(`https://gw.example/.well-known/apgateway/${did}/activities/1`),
|
|
44
|
+
new URL(`https://gw2.example/.well-known/apgateway/${did}/activities/1`)
|
|
45
|
+
]) {
|
|
46
|
+
assert(isSameObjectId(portable, id), id.href);
|
|
47
|
+
assert(isSameObjectId(id, portable), id.href);
|
|
48
|
+
}
|
|
49
|
+
for (const id of [
|
|
50
|
+
parseIri(`ap+ef61://${otherDid}/activities/1`),
|
|
51
|
+
parseIri(`ap+ef61://${did}/activities/2`),
|
|
52
|
+
parseIri(`ap+ef61://${did}/activities/1#fragment`),
|
|
53
|
+
new URL(`https://gw.example/.well-known/apgateway/${did}/activities/1%ZZ`),
|
|
54
|
+
new URL("https://gw.example/activities/1")
|
|
55
|
+
]) {
|
|
56
|
+
assertFalse(isSameObjectId(portable, id), id.href);
|
|
57
|
+
assertFalse(isSameObjectId(id, portable), id.href);
|
|
58
|
+
}
|
|
59
|
+
const malformed = new URL(`https://gw.example/.well-known/apgateway/${did}/activities/1%ZZ`);
|
|
60
|
+
assertFalse(isSameObjectId(malformed, malformed));
|
|
61
|
+
const http = new URL("https://example.com/activities/1");
|
|
62
|
+
assert(isSameObjectId(http, new URL("https://example.com/activities/1")));
|
|
63
|
+
assertFalse(isSameObjectId(http, new URL("https://example.com/activities/1#a")));
|
|
64
|
+
assertFalse(isSameObjectId(http, new URL("https://example.com/activities/1?a")));
|
|
65
|
+
});
|
|
66
|
+
//#endregion
|
|
67
|
+
export {};
|
|
@@ -2,14 +2,14 @@ import { Temporal } from "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
5
|
-
import { a as fetchKeyDetailed, i as fetchKey } from "../key-
|
|
6
|
-
import { h as verifyJsonLd, p as signJsonLd } from "../ld-
|
|
7
|
-
import { d as verifyProof, r as createProof } from "../proof-
|
|
8
|
-
import { n as resolvePortableActorKey } from "../portable-key-
|
|
9
|
-
import {
|
|
5
|
+
import { a as fetchKeyDetailed, i as fetchKey } from "../key-DyXf88bq.mjs";
|
|
6
|
+
import { h as verifyJsonLd, p as signJsonLd } from "../ld-oQj6j_hP.mjs";
|
|
7
|
+
import { d as verifyProof, r as createProof } from "../proof-C9115DX_.mjs";
|
|
8
|
+
import { n as resolvePortableActorKey } from "../portable-key-Duue9Y2Y.mjs";
|
|
9
|
+
import { f as verifyRequest, l as signRequest, p as verifyRequestDetailed } from "../http-Y1ObT1A8.mjs";
|
|
10
10
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
11
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-
|
|
12
|
-
import { t as KvKeyCache } from "../keycache-
|
|
11
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-Dem4fbwc.mjs";
|
|
12
|
+
import { t as KvKeyCache } from "../keycache-Da8A8mZa.mjs";
|
|
13
13
|
import { Create, CryptographicKey, Multikey, Note, Person } from "@fedify/vocab";
|
|
14
14
|
import { test } from "@fedify/fixture";
|
|
15
15
|
import { FetchError, encodeMultibase, exportDidKey, exportSpki, parseIri, preloadedContexts } from "@fedify/vocab-runtime";
|
package/dist/sig/proof.test.mjs
CHANGED
|
@@ -10,10 +10,10 @@ 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 normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-4IJqPYos.mjs";
|
|
13
|
-
import { a as signObject, c as verifyPortableObjectProof, d as verifyProof, i as hasProofLike, r as createProof, s as verifyObject } from "../proof-
|
|
14
|
-
import {
|
|
13
|
+
import { a as signObject, c as verifyPortableObjectProof, d as verifyProof, i as hasProofLike, r as createProof, s as verifyObject } from "../proof-C9115DX_.mjs";
|
|
14
|
+
import { f as verifyRequest } from "../http-Y1ObT1A8.mjs";
|
|
15
15
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
16
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
16
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-u6zzOExF.mjs";
|
|
17
17
|
import { Create, DataIntegrityProof, Document, Multikey, Note, PUBLIC_COLLECTION, Place, Translation } from "@fedify/vocab";
|
|
18
18
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
19
19
|
import { decodeMultibase, encodeMultibase, exportDidKey, exportMultibaseKey, formatIri, importMultibaseKey, parseIri } from "@fedify/vocab-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { c as getNormalizationContextLoader } from "./ld-
|
|
4
|
+
import { c as getNormalizationContextLoader } from "./ld-oQj6j_hP.mjs";
|
|
5
5
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
6
6
|
//#region src/federation/temporal.ts
|
|
7
7
|
function isPlainObject(value) {
|
package/dist/testing/kv.test.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
6
6
|
import { t as ManualClockKvStore } from "../kv-DBRWVx3Q.mjs";
|
|
7
7
|
import { n as baseOptions, o as stringSchema, t as MockQueue } from "../tasks-IG3pHfvZ.mjs";
|
|
8
8
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
+
import { o as createFederation } from "../middleware-Bdu2-OPD.mjs";
|
|
10
10
|
//#region src/testing/kv.test.ts
|
|
11
11
|
test("ManualClockKvStore keeps an entry at its exact expiration instant", async () => {
|
|
12
12
|
const kv = new ManualClockKvStore();
|
package/dist/testing/mod.d.mts
CHANGED
|
@@ -2275,6 +2275,35 @@ interface FederationOptions<TContextData> {
|
|
|
2275
2275
|
* @since 1.3.0
|
|
2276
2276
|
*/
|
|
2277
2277
|
userAgent?: GetUserAgentOptions | string;
|
|
2278
|
+
/**
|
|
2279
|
+
* The timeout for each call of the built-in document loader, context
|
|
2280
|
+
* loader, and authenticated document loader, e.g., when Fedify fetches
|
|
2281
|
+
* a key to verify a signature. The timeout is shared by all the steps of
|
|
2282
|
+
* a call, including every redirect it follows, retries, and reading the
|
|
2283
|
+
* response body. It does not cover the time spent reading from or
|
|
2284
|
+
* writing to the cache.
|
|
2285
|
+
*
|
|
2286
|
+
* A timed-out call throws a `FetchError` without a response, whose
|
|
2287
|
+
* `cause` is a `DOMException` named `"TimeoutError"`, so that, e.g.,
|
|
2288
|
+
* a key fetch that times out is reported as a `keyFetchError` and cached
|
|
2289
|
+
* like other failures to fetch a key.
|
|
2290
|
+
*
|
|
2291
|
+
* It does not affect loaders made by
|
|
2292
|
+
* {@link FederationOptions.documentLoaderFactory},
|
|
2293
|
+
* {@link FederationOptions.contextLoaderFactory}, or
|
|
2294
|
+
* {@link FederationOptions.authenticatedDocumentLoaderFactory}.
|
|
2295
|
+
* Note that if only {@link FederationOptions.documentLoaderFactory} is
|
|
2296
|
+
* set, it also makes context loaders.
|
|
2297
|
+
*
|
|
2298
|
+
* Set it to `null` to turn off the timeout.
|
|
2299
|
+
*
|
|
2300
|
+
* 10 seconds by default.
|
|
2301
|
+
* @throws {RangeError} If the duration is not positive, is longer than
|
|
2302
|
+
* about 24.8 days, or is given in calendar units
|
|
2303
|
+
* such as months.
|
|
2304
|
+
* @since 2.4.0
|
|
2305
|
+
*/
|
|
2306
|
+
documentLoaderTimeout?: Temporal.Duration | Temporal.DurationLike | null;
|
|
2278
2307
|
/**
|
|
2279
2308
|
* A callback that handles errors during outbox processing. Note that this
|
|
2280
2309
|
* callback can be called multiple times for the same activity, because
|
|
@@ -2303,6 +2332,29 @@ interface FederationOptions<TContextData> {
|
|
|
2303
2332
|
* By default, the window is an hour.
|
|
2304
2333
|
*/
|
|
2305
2334
|
signatureTimeWindow?: Temporal.Duration | Temporal.DurationLike | false;
|
|
2335
|
+
/**
|
|
2336
|
+
* The maximum number of [RFC 9421] signatures of an incoming request to
|
|
2337
|
+
* verify, e.g., in the inbox and in
|
|
2338
|
+
* {@link RequestContext.getSignedKey}. A request can carry several
|
|
2339
|
+
* signatures, each of which may make Fedify fetch the key that it names,
|
|
2340
|
+
* so only the first ones in the order of the `Signature-Input` header are
|
|
2341
|
+
* verified, and the rest are ignored as if they were absent. Every
|
|
2342
|
+
* signature among the first ones counts, even if it fails before its key
|
|
2343
|
+
* is fetched. See also the `maxSignatures` option of `verifyRequest()`.
|
|
2344
|
+
*
|
|
2345
|
+
* It has to be a positive integer, or `Infinity` to verify every
|
|
2346
|
+
* signature, which lets a single request make Fedify fetch any number of
|
|
2347
|
+
* keys. Draft-cavage HTTP Signatures carry a single signature, so this
|
|
2348
|
+
* option does not affect them.
|
|
2349
|
+
*
|
|
2350
|
+
* Three by default.
|
|
2351
|
+
*
|
|
2352
|
+
* [RFC 9421]: https://www.rfc-editor.org/rfc/rfc9421
|
|
2353
|
+
* @throws {RangeError} Thrown when the federation is created if the value
|
|
2354
|
+
* is not a positive integer or `Infinity`.
|
|
2355
|
+
* @since 2.4.0
|
|
2356
|
+
*/
|
|
2357
|
+
maxHttpSignatures?: number;
|
|
2306
2358
|
/**
|
|
2307
2359
|
* Whether to skip HTTP Signatures verification for incoming activities.
|
|
2308
2360
|
* This is useful for testing purposes, but should not be used in production.
|
|
@@ -5,9 +5,9 @@ import { t as esm_default } from "../esm-BHXXx4Wx.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
6
|
import "../std__assert-DvMDRPes.mjs";
|
|
7
7
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
8
|
-
import {
|
|
8
|
+
import { f as verifyRequest } from "../http-Y1ObT1A8.mjs";
|
|
9
9
|
import { i as rsaPrivateKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
10
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
10
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-u6zzOExF.mjs";
|
|
11
11
|
import { configure, reset } from "@logtape/logtape";
|
|
12
12
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
13
13
|
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
@@ -534,5 +534,96 @@ test("getAuthenticatedDocumentLoader() rejects cancellation before fetching", as
|
|
|
534
534
|
esm_default.hardReset();
|
|
535
535
|
}
|
|
536
536
|
});
|
|
537
|
+
function assertTimeoutFetchError(error, url) {
|
|
538
|
+
ok(error instanceof FetchError, String(error));
|
|
539
|
+
deepStrictEqual(error.url.href, url);
|
|
540
|
+
deepStrictEqual(error.response, void 0);
|
|
541
|
+
ok(error.cause instanceof DOMException);
|
|
542
|
+
deepStrictEqual(error.cause.name, "TimeoutError");
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
test("getAuthenticatedDocumentLoader() times out", async (t) => {
|
|
546
|
+
const identity = {
|
|
547
|
+
keyId: new URL("https://example.com/key2"),
|
|
548
|
+
privateKey: rsaPrivateKey2
|
|
549
|
+
};
|
|
550
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
551
|
+
await t.step("a request without a response", async () => {
|
|
552
|
+
esm_default.mockGlobal();
|
|
553
|
+
const url = "https://example.com/hang";
|
|
554
|
+
esm_default.get(url, () => new Promise(() => {}));
|
|
555
|
+
try {
|
|
556
|
+
await rejects(getAuthenticatedDocumentLoader(identity, {
|
|
557
|
+
allowPrivateAddress: true,
|
|
558
|
+
timeout: 100
|
|
559
|
+
})(url), (e) => assertTimeoutFetchError(e, url));
|
|
560
|
+
} finally {
|
|
561
|
+
esm_default.hardReset();
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
await t.step("double-knocking shares the timeout", async () => {
|
|
565
|
+
esm_default.mockGlobal();
|
|
566
|
+
const url = "https://example.com/double-knock";
|
|
567
|
+
let requests = 0;
|
|
568
|
+
esm_default.get(url, async () => {
|
|
569
|
+
requests++;
|
|
570
|
+
await delay(80);
|
|
571
|
+
return new Response(null, { status: 401 });
|
|
572
|
+
});
|
|
573
|
+
try {
|
|
574
|
+
await rejects(getAuthenticatedDocumentLoader(identity, {
|
|
575
|
+
allowPrivateAddress: true,
|
|
576
|
+
timeout: 120
|
|
577
|
+
})(url), (e) => assertTimeoutFetchError(e, url));
|
|
578
|
+
deepStrictEqual(requests, 2);
|
|
579
|
+
await delay(100);
|
|
580
|
+
deepStrictEqual(requests, 2);
|
|
581
|
+
} finally {
|
|
582
|
+
esm_default.hardReset();
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
for (const step of ["determineSpec", "rememberSpec"]) await t.step(`a slow ${step}()`, async () => {
|
|
586
|
+
esm_default.mockGlobal();
|
|
587
|
+
const url = `https://example.com/slow-${step}`;
|
|
588
|
+
let requests = 0;
|
|
589
|
+
esm_default.get(url, () => {
|
|
590
|
+
requests++;
|
|
591
|
+
return Response.json({ parsed: true });
|
|
592
|
+
});
|
|
593
|
+
try {
|
|
594
|
+
await rejects(getAuthenticatedDocumentLoader(identity, {
|
|
595
|
+
allowPrivateAddress: true,
|
|
596
|
+
timeout: 50,
|
|
597
|
+
specDeterminer: {
|
|
598
|
+
async determineSpec() {
|
|
599
|
+
if (step === "determineSpec") await delay(150);
|
|
600
|
+
return "rfc9421";
|
|
601
|
+
},
|
|
602
|
+
async rememberSpec() {
|
|
603
|
+
if (step === "rememberSpec") await delay(150);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
})(url), (e) => assertTimeoutFetchError(e, url));
|
|
607
|
+
await delay(200);
|
|
608
|
+
deepStrictEqual(requests, step === "determineSpec" ? 0 : 1);
|
|
609
|
+
} finally {
|
|
610
|
+
esm_default.hardReset();
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
await t.step("the caller's signal still aborts", async () => {
|
|
614
|
+
esm_default.mockGlobal();
|
|
615
|
+
const url = "https://example.com/hang";
|
|
616
|
+
esm_default.get(url, () => new Promise(() => {}));
|
|
617
|
+
try {
|
|
618
|
+
const loader = getAuthenticatedDocumentLoader(identity, { allowPrivateAddress: true });
|
|
619
|
+
const controller = new AbortController();
|
|
620
|
+
const reason = /* @__PURE__ */ new Error("Canceled by the caller");
|
|
621
|
+
setTimeout(() => controller.abort(reason), 50);
|
|
622
|
+
await rejects(loader(url, { signal: controller.signal }), (e) => e === reason);
|
|
623
|
+
} finally {
|
|
624
|
+
esm_default.hardReset();
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
});
|
|
537
628
|
//#endregion
|
|
538
629
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as kvCache, t as MockKvStore } from "../kv-cache-
|
|
4
|
+
import { n as kvCache, t as MockKvStore } from "../kv-cache-C8YjNAi_.mjs";
|
|
5
5
|
import { deepStrictEqual, throws } from "node:assert";
|
|
6
6
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
7
7
|
import { preloadedContexts } from "@fedify/vocab-runtime";
|
package/dist/utils/mod.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_kv_cache = require("../kv-cache-
|
|
3
|
+
const require_kv_cache = require("../kv-cache-DUXluAc0.cjs");
|
|
4
4
|
exports.getAuthenticatedDocumentLoader = require_kv_cache.getAuthenticatedDocumentLoader;
|
|
5
5
|
exports.kvCache = require_kv_cache.kvCache;
|
package/dist/utils/mod.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../mod-
|
|
2
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../mod-Dp3Ij7sw.cjs";
|
|
3
3
|
export { getAuthenticatedDocumentLoader, kvCache };
|
package/dist/utils/mod.d.ts
CHANGED
package/dist/utils/mod.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-
|
|
3
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-C02XitwK.js";
|
|
4
4
|
export { getAuthenticatedDocumentLoader, kvCache };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/fedify",
|
|
3
|
-
"version": "2.4.0-dev.
|
|
3
|
+
"version": "2.4.0-dev.2190+be3a8be0",
|
|
4
4
|
"description": "An ActivityPub server framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ActivityPub",
|
|
@@ -151,10 +151,10 @@
|
|
|
151
151
|
"structured-field-values": "^2.0.4",
|
|
152
152
|
"temporal-polyfill": "^1.0.1",
|
|
153
153
|
"urlpattern-polyfill": "^10.1.0",
|
|
154
|
-
"@fedify/
|
|
155
|
-
"@fedify/
|
|
156
|
-
"@fedify/vocab
|
|
157
|
-
"@fedify/webfinger": "2.4.0-dev.
|
|
154
|
+
"@fedify/uri-template": "2.4.0-dev.2190+be3a8be0",
|
|
155
|
+
"@fedify/vocab-runtime": "2.4.0-dev.2190+be3a8be0",
|
|
156
|
+
"@fedify/vocab": "2.4.0-dev.2190+be3a8be0",
|
|
157
|
+
"@fedify/webfinger": "2.4.0-dev.2190+be3a8be0"
|
|
158
158
|
},
|
|
159
159
|
"devDependencies": {
|
|
160
160
|
"@std/assert": "npm:@jsr/std__assert@^0.226.0",
|
|
@@ -166,8 +166,8 @@
|
|
|
166
166
|
"tsx": "^4.21.0",
|
|
167
167
|
"typescript": "^6.0.0",
|
|
168
168
|
"wrangler": "^4.17.0",
|
|
169
|
-
"@fedify/
|
|
170
|
-
"@fedify/
|
|
169
|
+
"@fedify/fixture": "2.0.0",
|
|
170
|
+
"@fedify/vocab-tools": "^2.4.0-dev.2190+be3a8be0"
|
|
171
171
|
},
|
|
172
172
|
"scripts": {
|
|
173
173
|
"build:self": "tsdown",
|