@fedify/fedify 2.4.0-dev.2164 → 2.4.0-dev.2169
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-BqRmnx7p.mjs → builder-B2d_Pt0j.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-CxDBdtNz.mjs → compound-proof-D28gMFqP.mjs} +2 -2
- package/dist/{deno-CizGaYeG.mjs → deno-DU8dvnWk.mjs} +1 -1
- package/dist/{docloader-BBFAItNB.mjs → docloader-CghLH7Zi.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 +5 -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 +7 -7
- package/dist/federation/mod.cjs +1 -1
- 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 +4 -4
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- 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-DFCnp94y.cjs → federation-DrNgkLfJ.cjs} +3 -3
- package/dist/{http-R4g1McwE.cjs → http-5CJBdU8n.cjs} +208 -55
- package/dist/{http-Baovr6xq.js → http-BGpexPO7.js} +208 -55
- package/dist/{http-DRH0n8TD.mjs → http-Bd6rZlJX.mjs} +4 -4
- package/dist/{key-D5awqp7u.mjs → key-gIhVZO3p.mjs} +2 -2
- package/dist/{kv-cache-C7RWL7hz.mjs → kv-cache-D0qjSeWY.mjs} +1 -1
- package/dist/{kv-cache-Ct-KWRta.cjs → kv-cache-YRi_g8GB.cjs} +1 -1
- package/dist/{kv-cache-CZiBDLPi.js → kv-cache-iR55fqlk.js} +1 -1
- package/dist/{ld-CyliEU48.mjs → ld-BsTkRrwF.mjs} +3 -3
- package/dist/{metrics-CFBEehTc.mjs → metrics-jUDFfVgi.mjs} +1 -1
- package/dist/{middleware-B99JjvFn.mjs → middleware-Coqgp-K0.mjs} +14 -14
- package/dist/{middleware-CdpTFsa2.js → middleware-DlxMxVp5.js} +3 -3
- package/dist/{middleware-BmqEWsWP.mjs → middleware-Dq-OCmb6.mjs} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-DKdtsrEq.mjs → owner-D3GoetXS.mjs} +3 -3
- package/dist/{portable-collection-uv4CuQXm.js → portable-collection-Bkdh_WpL.js} +1 -1
- package/dist/{portable-collection-Cb5cdPIU.mjs → portable-collection-C60_acmx.mjs} +2 -2
- package/dist/{portable-collection-UajqDrSL.cjs → portable-collection-CnlCamup.cjs} +1 -1
- package/dist/{portable-key-Bv1RdQ0n.mjs → portable-key-DyF5AnZo.mjs} +208 -55
- package/dist/{proof-CRTPWbVh.mjs → proof-CQAYqWdj.mjs} +4 -4
- package/dist/{send-2dULlZc8.mjs → send-DjkQrxt5.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 +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.test.mjs +252 -6
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/{temporal-Dhsk6aUT.mjs → temporal-oRKP803M.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +7 -7
package/dist/sig/ld.test.mjs
CHANGED
|
@@ -8,8 +8,8 @@ import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
|
8
8
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
9
9
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
10
10
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
11
|
-
import { o as generateCryptoKeyPair } from "../key-
|
|
12
|
-
import { a as compactJsonLd, f as isInvalidUrlTypeError, g as verifySignature, h as verifyJsonLd, i as attachSignature, n as UnsafeJsonLdError, o as createSignature, p as signJsonLd, s as detachSignature, u as hasSignatureLike } from "../ld-
|
|
11
|
+
import { o as generateCryptoKeyPair } from "../key-gIhVZO3p.mjs";
|
|
12
|
+
import { a as compactJsonLd, f as isInvalidUrlTypeError, g as verifySignature, h as verifyJsonLd, i as attachSignature, n as UnsafeJsonLdError, o as createSignature, p as signJsonLd, s as detachSignature, u as hasSignatureLike } from "../ld-BsTkRrwF.mjs";
|
|
13
13
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
14
14
|
import { CryptographicKey } from "@fedify/vocab";
|
|
15
15
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
package/dist/sig/mod.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_http = require("../http-
|
|
4
|
-
const require_portable_collection = require("../portable-collection-
|
|
3
|
+
const require_http = require("../http-5CJBdU8n.cjs");
|
|
4
|
+
const require_portable_collection = require("../portable-collection-CnlCamup.cjs");
|
|
5
5
|
exports.attachSignature = require_http.attachSignature;
|
|
6
6
|
exports.createProof = require_http.createProof;
|
|
7
7
|
exports.createSignature = require_http.createSignature;
|
package/dist/sig/mod.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { A as hasSignatureLike, B as fetchKey, D as detachSignature, E as createSignature, F as verifyJsonLd, H as generateCryptoKeyPair, I as verifySignature, N as signJsonLd, R as exportJwk, U as importJwk, V as fetchKeyDetailed, _ as verifyPortableObjectProof, a as signRequest, b as verifyProof, f as createProof, g as verifyObject, gt as validateAcceptSignature, ht as parseAcceptSignature, m as signObject, mt as fulfillAcceptSignature, o as verifyRequest, p as hasProofLike, pt as formatAcceptSignature, s as verifyRequestDetailed, w as attachSignature } from "../http-
|
|
4
|
-
import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "../portable-collection-
|
|
3
|
+
import { A as hasSignatureLike, B as fetchKey, D as detachSignature, E as createSignature, F as verifyJsonLd, H as generateCryptoKeyPair, I as verifySignature, N as signJsonLd, R as exportJwk, U as importJwk, V as fetchKeyDetailed, _ as verifyPortableObjectProof, a as signRequest, b as verifyProof, f as createProof, g as verifyObject, gt as validateAcceptSignature, ht as parseAcceptSignature, m as signObject, mt as fulfillAcceptSignature, o as verifyRequest, p as hasProofLike, pt as formatAcceptSignature, s as verifyRequestDetailed, w as attachSignature } from "../http-BGpexPO7.js";
|
|
4
|
+
import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "../portable-collection-Bkdh_WpL.js";
|
|
5
5
|
export { attachSignature, createProof, createSignature, detachSignature, doesActorOwnKey, exportJwk, fetchKey, fetchKeyDetailed, formatAcceptSignature, fulfillAcceptSignature, generateCryptoKeyPair, getKeyOwner, hasProofLike, hasSignatureLike, importJwk, parseAcceptSignature, signJsonLd, signObject, signRequest, validateAcceptSignature, verifyJsonLd, verifyObject, verifyPortableObject, verifyPortableObjectProof, verifyProof, verifyRequest, verifyRequestDetailed, verifySignature };
|
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-D3GoetXS.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-C60_acmx.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";
|
|
@@ -2,12 +2,13 @@ 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 { 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 {
|
|
5
|
+
import { a as fetchKeyDetailed, i as fetchKey } from "../key-gIhVZO3p.mjs";
|
|
6
|
+
import { h as verifyJsonLd, p as signJsonLd } from "../ld-BsTkRrwF.mjs";
|
|
7
|
+
import { d as verifyProof, r as createProof } from "../proof-CQAYqWdj.mjs";
|
|
8
|
+
import { n as resolvePortableActorKey } from "../portable-key-DyF5AnZo.mjs";
|
|
9
|
+
import { d as verifyRequest, f as verifyRequestDetailed, l as signRequest } from "../http-Bd6rZlJX.mjs";
|
|
9
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";
|
|
10
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-
|
|
11
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-D3GoetXS.mjs";
|
|
11
12
|
import { t as KvKeyCache } from "../keycache-PiOM9pM0.mjs";
|
|
12
13
|
import { Create, CryptographicKey, Multikey, Note, Person } from "@fedify/vocab";
|
|
13
14
|
import { test } from "@fedify/fixture";
|
|
@@ -965,7 +966,21 @@ test("verifyRequest() tries the gateways of ap: key IDs in order", async () => {
|
|
|
965
966
|
documentLoader: many,
|
|
966
967
|
contextLoader
|
|
967
968
|
})).verified);
|
|
968
|
-
deepStrictEqual(many.fetched, gateways.slice(0,
|
|
969
|
+
deepStrictEqual(many.fetched, gateways.slice(0, 3).map((g) => compatibleId(g)));
|
|
970
|
+
for (const [index, expected] of [[2, true], [3, false]]) {
|
|
971
|
+
const documentLoader = createLoader({ [compatibleId(gateways[index])]: signed });
|
|
972
|
+
strictEqual(await verifyRequest(await signedRequest(void 0, hinted(...gateways)), {
|
|
973
|
+
documentLoader,
|
|
974
|
+
contextLoader
|
|
975
|
+
}) != null, expected, `gateway ${index + 1}`);
|
|
976
|
+
deepStrictEqual(documentLoader.fetched, gateways.slice(0, 3).map((g) => compatibleId(g)), `gateway ${index + 1}`);
|
|
977
|
+
}
|
|
978
|
+
const sparse = createLoader({ [compatibleId(gateways[2])]: signed });
|
|
979
|
+
ok(await verifyRequest(await signedRequest(void 0, hinted("not a gateway", gateways[0], gateways[0].toUpperCase(), "https://gw.example/path", gateways[1], gateways[2])), {
|
|
980
|
+
documentLoader: sparse,
|
|
981
|
+
contextLoader
|
|
982
|
+
}) != null);
|
|
983
|
+
deepStrictEqual(sparse.fetched, gateways.slice(0, 3).map((g) => compatibleId(g)));
|
|
969
984
|
});
|
|
970
985
|
function failingLoader(responses) {
|
|
971
986
|
const fetched = [];
|
|
@@ -1189,5 +1204,236 @@ test("verifyRequest() does not cache keys at ap: key IDs it could not process",
|
|
|
1189
1204
|
strictEqual((await verifyRequest(await signedRequest(void 0, hintedKeyId), options))?.ownerId?.href, parseIri(actorId).href);
|
|
1190
1205
|
strictEqual(documentLoader.fetched.length, 2);
|
|
1191
1206
|
});
|
|
1207
|
+
/**
|
|
1208
|
+
* A loader that serves the given responses, and never responds for the URLs
|
|
1209
|
+
* in `hanging`. A hanging response is given up when its signal aborts,
|
|
1210
|
+
* unless `ignoreSignal` is set.
|
|
1211
|
+
*/
|
|
1212
|
+
function controlledLoader(responses, hanging, { ignoreSignal = false, delays = {} } = {}) {
|
|
1213
|
+
const fetched = [];
|
|
1214
|
+
const signals = [];
|
|
1215
|
+
const respond = failingLoader(responses);
|
|
1216
|
+
const loader = async (url, options) => {
|
|
1217
|
+
fetched.push(url);
|
|
1218
|
+
signals.push(options?.signal);
|
|
1219
|
+
const signal = ignoreSignal ? void 0 : options?.signal;
|
|
1220
|
+
const delay = delays[url];
|
|
1221
|
+
if (delay != null) await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1222
|
+
if (hanging.includes(url)) return await new Promise((_, reject) => {
|
|
1223
|
+
signal?.addEventListener("abort", () => reject(signal.reason));
|
|
1224
|
+
});
|
|
1225
|
+
return await respond(url);
|
|
1226
|
+
};
|
|
1227
|
+
return Object.assign(loader, {
|
|
1228
|
+
fetched,
|
|
1229
|
+
signals
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
function isTimeoutError(error) {
|
|
1233
|
+
return error instanceof DOMException && error.name === "TimeoutError";
|
|
1234
|
+
}
|
|
1235
|
+
test("resolvePortableActorKey() gives up gateways that do not respond in time", async () => {
|
|
1236
|
+
const signed = await sign(await apActorJson());
|
|
1237
|
+
for (const ignoreSignal of [false, true]) {
|
|
1238
|
+
const documentLoader = controlledLoader({ [compatibleId(gw2)]: signed }, [compatibleId(gw1)], { ignoreSignal });
|
|
1239
|
+
const resolution = await resolvePortableActorKey(hinted(gw1, gw2), {
|
|
1240
|
+
documentLoader,
|
|
1241
|
+
contextLoader,
|
|
1242
|
+
lookupTimeout: 50
|
|
1243
|
+
});
|
|
1244
|
+
strictEqual(resolution.type, "unavailable", `ignoreSignal: ${ignoreSignal}`);
|
|
1245
|
+
if (resolution.type === "unavailable") strictEqual(resolution.cacheable, false);
|
|
1246
|
+
deepStrictEqual(documentLoader.fetched, [compatibleId(gw1)]);
|
|
1247
|
+
const [signal] = documentLoader.signals;
|
|
1248
|
+
ok(signal?.aborted);
|
|
1249
|
+
ok(isTimeoutError(signal.reason));
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
test("resolvePortableActorKey() caches timeouts only as failures to fetch", async () => {
|
|
1253
|
+
const invalid = await apActorJson();
|
|
1254
|
+
const cases = [
|
|
1255
|
+
{
|
|
1256
|
+
name: "the only gateway times out",
|
|
1257
|
+
responses: {},
|
|
1258
|
+
hanging: [compatibleId(gw1)],
|
|
1259
|
+
hints: [gw1],
|
|
1260
|
+
cacheable: true
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
name: "a gateway responds with 404, and the last one times out",
|
|
1264
|
+
responses: { [compatibleId(gw1)]: 404 },
|
|
1265
|
+
hanging: [compatibleId(gw2)],
|
|
1266
|
+
hints: [gw1, gw2],
|
|
1267
|
+
cacheable: true
|
|
1268
|
+
},
|
|
1269
|
+
{
|
|
1270
|
+
name: "a gateway serves an invalid document, and the last one times out",
|
|
1271
|
+
responses: { [compatibleId(gw1)]: invalid },
|
|
1272
|
+
hanging: [compatibleId(gw2)],
|
|
1273
|
+
hints: [gw1, gw2],
|
|
1274
|
+
cacheable: false
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
name: "the document loader cannot resolve the ap: URI in time",
|
|
1278
|
+
responses: {},
|
|
1279
|
+
hanging: [actorId],
|
|
1280
|
+
hints: [],
|
|
1281
|
+
cacheable: true
|
|
1282
|
+
}
|
|
1283
|
+
];
|
|
1284
|
+
for (const { name, responses, hanging, hints, cacheable } of cases) {
|
|
1285
|
+
const documentLoader = controlledLoader(responses, hanging);
|
|
1286
|
+
const resolution = await resolvePortableActorKey(hinted(...hints), {
|
|
1287
|
+
documentLoader,
|
|
1288
|
+
contextLoader,
|
|
1289
|
+
lookupTimeout: 50
|
|
1290
|
+
});
|
|
1291
|
+
strictEqual(resolution.type, "unavailable", name);
|
|
1292
|
+
if (resolution.type !== "unavailable") continue;
|
|
1293
|
+
strictEqual(resolution.cacheable, cacheable, name);
|
|
1294
|
+
ok(!(resolution.error instanceof FetchError), name);
|
|
1295
|
+
if (hanging.length === 1 && hints.length < 2) ok(isTimeoutError(resolution.error), name);
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
test("resolvePortableActorKey() shares one timeout among all gateways", async () => {
|
|
1299
|
+
const documentLoader = controlledLoader({ [compatibleId(gw1)]: 404 }, [compatibleId(gw2)], { delays: { [compatibleId(gw1)]: 250 } });
|
|
1300
|
+
const started = Date.now();
|
|
1301
|
+
const resolution = await resolvePortableActorKey(hinted(gw1, gw2), {
|
|
1302
|
+
documentLoader,
|
|
1303
|
+
contextLoader,
|
|
1304
|
+
lookupTimeout: 300
|
|
1305
|
+
});
|
|
1306
|
+
const elapsed = Date.now() - started;
|
|
1307
|
+
ok(elapsed < 500, `took ${elapsed} ms`);
|
|
1308
|
+
strictEqual(resolution.type, "unavailable");
|
|
1309
|
+
deepStrictEqual(documentLoader.fetched, [compatibleId(gw1), compatibleId(gw2)]);
|
|
1310
|
+
ok(documentLoader.signals[1]?.aborted);
|
|
1311
|
+
});
|
|
1312
|
+
test("resolvePortableActorKey() bounds loading the contexts of actor documents", async () => {
|
|
1313
|
+
const documentLoader = controlledLoader({ [compatibleId(gw1)]: await sign(await apActorJson()) }, []);
|
|
1314
|
+
const hangingContextLoader = (_url, options) => new Promise((_, reject) => {
|
|
1315
|
+
options?.signal?.addEventListener("abort", () => reject(options.signal.reason));
|
|
1316
|
+
});
|
|
1317
|
+
const resolution = await resolvePortableActorKey(hinted(gw1, gw2), {
|
|
1318
|
+
documentLoader,
|
|
1319
|
+
contextLoader: hangingContextLoader,
|
|
1320
|
+
lookupTimeout: 50
|
|
1321
|
+
});
|
|
1322
|
+
strictEqual(resolution.type, "unavailable");
|
|
1323
|
+
if (resolution.type === "unavailable") strictEqual(resolution.cacheable, false);
|
|
1324
|
+
deepStrictEqual(documentLoader.fetched, [compatibleId(gw1)]);
|
|
1325
|
+
});
|
|
1326
|
+
test("resolvePortableActorKey() ignores what is resolved after the timeout", async () => {
|
|
1327
|
+
let verifiedLate = () => {};
|
|
1328
|
+
const late = new Promise((resolve) => verifiedLate = resolve);
|
|
1329
|
+
let lookupDone = () => {};
|
|
1330
|
+
const done = new Promise((resolve) => lookupDone = resolve);
|
|
1331
|
+
const slowKeyCache = {
|
|
1332
|
+
async get() {
|
|
1333
|
+
await done;
|
|
1334
|
+
},
|
|
1335
|
+
set() {
|
|
1336
|
+
verifiedLate();
|
|
1337
|
+
return Promise.resolve();
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
const documentLoader = controlledLoader({ [compatibleId(gw1)]: await sign(await apActorJson()) }, []);
|
|
1341
|
+
const resolution = await resolvePortableActorKey(hinted(gw1), {
|
|
1342
|
+
documentLoader,
|
|
1343
|
+
contextLoader,
|
|
1344
|
+
keyCache: slowKeyCache,
|
|
1345
|
+
lookupTimeout: 300
|
|
1346
|
+
});
|
|
1347
|
+
lookupDone();
|
|
1348
|
+
strictEqual(resolution.type, "unavailable");
|
|
1349
|
+
if (resolution.type === "unavailable") strictEqual(resolution.cacheable, false);
|
|
1350
|
+
await late;
|
|
1351
|
+
const lateRejection = controlledLoader({}, [], { delays: { [compatibleId(gw1)]: 60 } });
|
|
1352
|
+
strictEqual((await resolvePortableActorKey(hinted(gw1), {
|
|
1353
|
+
documentLoader: lateRejection,
|
|
1354
|
+
contextLoader,
|
|
1355
|
+
lookupTimeout: 20
|
|
1356
|
+
})).type, "unavailable");
|
|
1357
|
+
await new Promise((resolve) => setTimeout(resolve, 80));
|
|
1358
|
+
});
|
|
1359
|
+
test("resolvePortableActorKey() validates the lookup timeout", async () => {
|
|
1360
|
+
const documentLoader = controlledLoader({}, []);
|
|
1361
|
+
for (const lookupTimeout of [
|
|
1362
|
+
-1,
|
|
1363
|
+
NaN,
|
|
1364
|
+
Infinity,
|
|
1365
|
+
2 ** 31
|
|
1366
|
+
]) {
|
|
1367
|
+
let error;
|
|
1368
|
+
try {
|
|
1369
|
+
await resolvePortableActorKey(hinted(gw1), {
|
|
1370
|
+
documentLoader,
|
|
1371
|
+
contextLoader,
|
|
1372
|
+
lookupTimeout
|
|
1373
|
+
});
|
|
1374
|
+
} catch (e) {
|
|
1375
|
+
error = e;
|
|
1376
|
+
}
|
|
1377
|
+
ok(error instanceof RangeError, String(lookupTimeout));
|
|
1378
|
+
}
|
|
1379
|
+
const resolution = await resolvePortableActorKey(hinted(gw1), {
|
|
1380
|
+
documentLoader,
|
|
1381
|
+
contextLoader,
|
|
1382
|
+
lookupTimeout: 0
|
|
1383
|
+
});
|
|
1384
|
+
strictEqual(resolution.type, "unavailable");
|
|
1385
|
+
if (resolution.type === "unavailable") strictEqual(resolution.cacheable, false);
|
|
1386
|
+
deepStrictEqual(documentLoader.fetched, []);
|
|
1387
|
+
});
|
|
1388
|
+
test("fetchKeyDetailed() caches keys at ap: key IDs that time out as fetch failures", async () => {
|
|
1389
|
+
const cases = [{
|
|
1390
|
+
responses: { [compatibleId(gw1)]: 404 },
|
|
1391
|
+
hanging: [compatibleId(gw2)],
|
|
1392
|
+
cached: true
|
|
1393
|
+
}, {
|
|
1394
|
+
responses: {},
|
|
1395
|
+
hanging: [compatibleId(gw1)],
|
|
1396
|
+
cached: false
|
|
1397
|
+
}];
|
|
1398
|
+
for (const { responses, hanging, cached } of cases) {
|
|
1399
|
+
const documentLoader = controlledLoader(responses, hanging);
|
|
1400
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
1401
|
+
const options = {
|
|
1402
|
+
documentLoader,
|
|
1403
|
+
contextLoader,
|
|
1404
|
+
keyCache,
|
|
1405
|
+
portableKeyResolvers: {
|
|
1406
|
+
gatewayKey: () => Promise.resolve({ type: "legacy" }),
|
|
1407
|
+
actorKey: (keyId) => resolvePortableActorKey(keyId, {
|
|
1408
|
+
documentLoader,
|
|
1409
|
+
contextLoader,
|
|
1410
|
+
lookupTimeout: 50
|
|
1411
|
+
})
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
const hintedKeyId = hinted(gw1, gw2);
|
|
1415
|
+
for (let i = 0; i < 2; i++) {
|
|
1416
|
+
const result = await fetchKeyDetailed(hintedKeyId, CryptographicKey, options);
|
|
1417
|
+
strictEqual(result.key, null);
|
|
1418
|
+
strictEqual(result.cached, cached && i > 0, `${cached}, ${i}`);
|
|
1419
|
+
ok(result.fetchError == null || !("status" in result.fetchError), "a timeout has no HTTP status");
|
|
1420
|
+
}
|
|
1421
|
+
strictEqual(documentLoader.fetched.filter((url) => url === compatibleId(gw1)).length, cached ? 1 : 2);
|
|
1422
|
+
}
|
|
1423
|
+
});
|
|
1424
|
+
test("verifyRequestDetailed() reports keys at ap: key IDs that time out as fetch errors", async () => {
|
|
1425
|
+
const timeout = new DOMException("Timed out", "TimeoutError");
|
|
1426
|
+
const documentLoader = () => Promise.reject(timeout);
|
|
1427
|
+
for (const spec of specs) {
|
|
1428
|
+
const result = await verifyRequestDetailed(await signedRequest(spec, hinted(gw1)), {
|
|
1429
|
+
documentLoader,
|
|
1430
|
+
contextLoader,
|
|
1431
|
+
spec
|
|
1432
|
+
});
|
|
1433
|
+
ok(!result.verified, spec);
|
|
1434
|
+
strictEqual(result.reason.type, "keyFetchError", spec);
|
|
1435
|
+
if (result.reason.type === "keyFetchError") ok(!("status" in result.reason.result), spec);
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1192
1438
|
//#endregion
|
|
1193
1439
|
export {};
|
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 { d as verifyRequest } from "../http-
|
|
13
|
+
import { a as signObject, c as verifyPortableObjectProof, d as verifyProof, i as hasProofLike, r as createProof, s as verifyObject } from "../proof-CQAYqWdj.mjs";
|
|
14
|
+
import { d as verifyRequest } from "../http-Bd6rZlJX.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-CghLH7Zi.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-BsTkRrwF.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-Coqgp-K0.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();
|
|
@@ -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 { d as verifyRequest } from "../http-
|
|
8
|
+
import { d as verifyRequest } from "../http-Bd6rZlJX.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-CghLH7Zi.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";
|
|
@@ -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-D0qjSeWY.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-YRi_g8GB.cjs");
|
|
4
4
|
exports.getAuthenticatedDocumentLoader = require_kv_cache.getAuthenticatedDocumentLoader;
|
|
5
5
|
exports.kvCache = require_kv_cache.kvCache;
|
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-iR55fqlk.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.2169+0a45df07",
|
|
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/uri-template": "2.4.0-dev.
|
|
156
|
-
"@fedify/vocab": "2.4.0-dev.
|
|
157
|
-
"@fedify/
|
|
154
|
+
"@fedify/vocab": "2.4.0-dev.2169+0a45df07",
|
|
155
|
+
"@fedify/uri-template": "2.4.0-dev.2169+0a45df07",
|
|
156
|
+
"@fedify/vocab-runtime": "2.4.0-dev.2169+0a45df07",
|
|
157
|
+
"@fedify/webfinger": "2.4.0-dev.2169+0a45df07"
|
|
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/vocab-tools": "^2.4.0-dev.2169+0a45df07",
|
|
170
|
+
"@fedify/fixture": "2.0.0"
|
|
171
171
|
},
|
|
172
172
|
"scripts": {
|
|
173
173
|
"build:self": "tsdown",
|