@fedify/fedify 2.4.0-dev.2103 → 2.4.0-dev.2115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{builder-CHht75pX.mjs → builder-CZcBWrBd.mjs} +29 -5
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-DKKH_Nr1.mjs → compound-proof-CDuP9MIX.mjs} +3 -3
- package/dist/{context-mDTxTw-S.d.cts → context-SMNOiiY6.d.cts} +93 -11
- package/dist/{context-CfJE_oQu.d.ts → context-tOiJfBoD.d.ts} +93 -11
- package/dist/{deno-CkjiYK_Z.mjs → deno-CCABdw7r.mjs} +1 -1
- package/dist/{docloader-C1hAJnWc.mjs → docloader-Bby5g2iu.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +118 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/keycache.test.mjs +67 -1
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +184 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +3 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +5 -5
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-gateway-keys.test.mjs +24 -7
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable.test.mjs +31 -4
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-C1dL6SiT.cjs → federation-DYr384xz.cjs} +116 -15
- package/dist/{http-Cala2Grs.cjs → http-B4mQvNcv.cjs} +140 -55
- package/dist/{http-BU-8fUrz.mjs → http-BcLnr2do.mjs} +6 -12
- package/dist/{http-xlG-jRdB.d.cts → http-BrQgkJay.d.ts} +12 -7
- package/dist/{http-tTlTeFa0.js → http-Ce6_Lf7k.js} +140 -55
- package/dist/{http-n2v6DPxu.d.ts → http-D76Py0M4.d.cts} +12 -7
- package/dist/{key-I8gLBkcf.mjs → key-CkNxztNV.mjs} +107 -16
- package/dist/{keycache-BUDHB5rY.mjs → keycache-BInaECGj.mjs} +68 -0
- package/dist/{kv-cache-Bl5EBFrU.cjs → kv-cache-Dqp_E-1g.cjs} +1 -1
- package/dist/{kv-cache-CxQu_cd4.js → kv-cache-DwzXzchj.js} +1 -1
- package/dist/{kv-cache-DJFoGRWQ.mjs → kv-cache-iFaRIcIL.mjs} +1 -1
- package/dist/{ld-wiJbqJHa.mjs → ld-CnT0f1nU.mjs} +4 -7
- package/dist/{metrics-BCAa5-kE.mjs → metrics-em_7lwhG.mjs} +1 -1
- package/dist/{middleware-FnITXhtz.mjs → middleware-BpwKvOpU.mjs} +26 -17
- package/dist/{middleware-B6IVTVL0.js → middleware-DhIBngkj.js} +108 -7
- package/dist/{middleware-6p2dYEVA.mjs → middleware-U9IuzvDO.mjs} +1 -1
- package/dist/{mod-BYvPz_T0.d.ts → mod-COWgSo2v.d.ts} +1 -1
- package/dist/{mod-Coacostr.d.ts → mod-CTh7ijx5.d.ts} +1 -1
- package/dist/{mod-xGFCHqq_.d.cts → mod-Cr79cQlc.d.cts} +1 -1
- package/dist/{mod-CVZrXSdm.d.ts → mod-Cwdt_CWU.d.ts} +1 -1
- package/dist/{mod-C8LieBzF.d.cts → mod-DMdGFMEl.d.cts} +1 -1
- package/dist/{mod-B3OzOobN.d.cts → mod-DnElMslb.d.cts} +1 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +7 -7
- package/dist/mod.d.ts +7 -7
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-BJp47LxN.mjs → owner-9LiHmOv1.mjs} +4 -4
- package/dist/{owner-DCt8W_Cv.cjs → owner-BtoMCv6Z.cjs} +1 -1
- package/dist/{owner-j5yrbXS1.js → owner-Cb3ytrlq.js} +1 -1
- package/dist/{portable-key-B5oKE_wZ.mjs → portable-key-9ck61lI0.mjs} +5 -4
- package/dist/{portable-key-id-Bva5iT3W.mjs → portable-key-id-T7lecIbt.mjs} +3 -2
- package/dist/{proof-BE4T5zF6.mjs → proof-xdPYGPaA.mjs} +32 -31
- package/dist/{send-BFITuKHw.mjs → send-Bf8rSWch.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +3 -3
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +2 -2
- package/dist/sig/portable-key.test.mjs +301 -23
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/{sig-CRTRoouH.cjs → sig-Bj3fHnv0.cjs} +2 -2
- package/dist/{sig-CJHdGk9w.js → sig-DN9pOglI.js} +2 -2
- package/dist/{temporal-CyDDbE4i.mjs → temporal-tAtwv6vX.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +91 -9
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +7 -7
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import "temporal-polyfill";
|
|
1
|
+
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { n as
|
|
8
|
-
import {
|
|
4
|
+
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
5
|
+
import { i as fetchKey } from "../key-CkNxztNV.mjs";
|
|
6
|
+
import { h as verifyJsonLd, p as signJsonLd } from "../ld-CnT0f1nU.mjs";
|
|
7
|
+
import { n as createProof, u as verifyProof } from "../proof-xdPYGPaA.mjs";
|
|
8
|
+
import { d as verifyRequest, f as verifyRequestDetailed, l as signRequest } from "../http-BcLnr2do.mjs";
|
|
9
|
+
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-9LiHmOv1.mjs";
|
|
11
|
+
import { t as KvKeyCache } from "../keycache-BInaECGj.mjs";
|
|
12
|
+
import { Create, CryptographicKey, Multikey, Note, Person } from "@fedify/vocab";
|
|
9
13
|
import { test } from "@fedify/fixture";
|
|
10
14
|
import { FetchError, encodeMultibase, exportDidKey, exportSpki, parseIri, preloadedContexts } from "@fedify/vocab-runtime";
|
|
11
15
|
import serialize from "json-canon";
|
|
@@ -46,14 +50,15 @@ function createLoader(responses) {
|
|
|
46
50
|
};
|
|
47
51
|
return Object.assign(loader, { fetched });
|
|
48
52
|
}
|
|
49
|
-
async function sign(document, privateKey = ed25519PrivateKey, verificationMethod = didKeyId) {
|
|
53
|
+
async function sign(document, privateKey = ed25519PrivateKey, verificationMethod = didKeyId, proofOptions = {}) {
|
|
50
54
|
const proofConfig = {
|
|
51
55
|
"@context": document["@context"],
|
|
52
56
|
type: "DataIntegrityProof",
|
|
53
57
|
cryptosuite: "eddsa-jcs-2022",
|
|
54
58
|
verificationMethod,
|
|
55
59
|
proofPurpose: "assertionMethod",
|
|
56
|
-
created: "2023-02-24T23:36:38Z"
|
|
60
|
+
created: "2023-02-24T23:36:38Z",
|
|
61
|
+
...proofOptions
|
|
57
62
|
};
|
|
58
63
|
const encoder = new TextEncoder();
|
|
59
64
|
const proofDigest = await crypto.subtle.digest("SHA-256", encoder.encode(serialize(proofConfig)));
|
|
@@ -333,32 +338,305 @@ test("keys at ordinary URLs cannot belong to portable actors", async () => {
|
|
|
333
338
|
keyCache
|
|
334
339
|
})).key, null);
|
|
335
340
|
});
|
|
336
|
-
|
|
341
|
+
const specs = ["draft-cavage-http-signatures-12", "rfc9421"];
|
|
342
|
+
function fetchKeyOf(cls, options) {
|
|
343
|
+
return cls === CryptographicKey ? fetchKey(keyId, CryptographicKey, options) : fetchKey(keyId, Multikey, options);
|
|
344
|
+
}
|
|
345
|
+
function fetchCount(loader, url = keyId) {
|
|
346
|
+
const document = url.href.replace(/#.*$/, "");
|
|
347
|
+
return loader.fetched.filter((u) => u.replace(/#.*$/, "") === document).length;
|
|
348
|
+
}
|
|
349
|
+
test("verifyRequest() caches failures to fetch compatible key IDs", async () => {
|
|
350
|
+
const unreachable = {
|
|
351
|
+
"404 Not Found": createLoader({}),
|
|
352
|
+
"a network error": (url) => Promise.reject(/* @__PURE__ */ new TypeError(`${url}`))
|
|
353
|
+
};
|
|
354
|
+
for (const spec of specs) for (const [name, inner] of Object.entries(unreachable)) {
|
|
355
|
+
const fetched = [];
|
|
356
|
+
const documentLoader = Object.assign((url) => {
|
|
357
|
+
fetched.push(url);
|
|
358
|
+
return inner(url);
|
|
359
|
+
}, { fetched });
|
|
360
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
361
|
+
const options = {
|
|
362
|
+
documentLoader,
|
|
363
|
+
contextLoader,
|
|
364
|
+
keyCache,
|
|
365
|
+
spec
|
|
366
|
+
};
|
|
367
|
+
for (let i = 0; i < 3; i++) {
|
|
368
|
+
const result = await verifyRequestDetailed(await signedRequest(spec), options);
|
|
369
|
+
ok(!result.verified, `${spec}, ${name}`);
|
|
370
|
+
strictEqual(result.reason.type, "keyFetchError", `${spec}, ${name}`);
|
|
371
|
+
}
|
|
372
|
+
strictEqual(fetchCount(documentLoader), 1, `${spec}, ${name}`);
|
|
373
|
+
for (const cls of [CryptographicKey, Multikey]) {
|
|
374
|
+
const result = await fetchKeyOf(cls, options);
|
|
375
|
+
strictEqual(result.key, null);
|
|
376
|
+
ok(result.cached, `${spec}, ${name}, ${cls.name}`);
|
|
377
|
+
}
|
|
378
|
+
strictEqual(fetchCount(documentLoader), 1, `${spec}, ${name}`);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
test("verifyRequest() caches gateway keys only for HTTP Signatures", async () => {
|
|
382
|
+
for (const spec of specs) {
|
|
383
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await sign(await actorJson()) });
|
|
384
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
385
|
+
const options = {
|
|
386
|
+
documentLoader,
|
|
387
|
+
contextLoader,
|
|
388
|
+
keyCache,
|
|
389
|
+
spec
|
|
390
|
+
};
|
|
391
|
+
for (let i = 0; i < 3; i++) strictEqual((await verifyRequest(await signedRequest(spec), options))?.ownerId?.href, parseIri(actorId).href, spec);
|
|
392
|
+
strictEqual(fetchCount(documentLoader), 1, spec);
|
|
393
|
+
const document = {
|
|
394
|
+
"@context": "https://www.w3.org/ns/activitystreams",
|
|
395
|
+
type: "Create",
|
|
396
|
+
id: "https://gw1.example/activities/1",
|
|
397
|
+
actor: compatibleId(gw1)
|
|
398
|
+
};
|
|
399
|
+
const { signature } = await signJsonLd(document, rsaPrivateKey2, keyId, { contextLoader });
|
|
400
|
+
ok(!await verifyJsonLd({
|
|
401
|
+
...document,
|
|
402
|
+
signature
|
|
403
|
+
}, options), spec);
|
|
404
|
+
const note = new Note({
|
|
405
|
+
id: new URL("https://gw1.example/notes/1"),
|
|
406
|
+
attribution: new URL(compatibleId(gw1)),
|
|
407
|
+
content: "Hello"
|
|
408
|
+
});
|
|
409
|
+
const proof = await createProof(note, ed25519PrivateKey, keyId, { contextLoader });
|
|
410
|
+
strictEqual(await verifyProof(await note.toJsonLd({
|
|
411
|
+
format: "compact",
|
|
412
|
+
contextLoader
|
|
413
|
+
}), proof, options), null, spec);
|
|
414
|
+
for (const cls of [CryptographicKey, Multikey]) strictEqual((await fetchKeyOf(cls, options)).key, null, spec);
|
|
415
|
+
const fetched = fetchCount(documentLoader);
|
|
416
|
+
ok(await verifyRequest(await signedRequest(spec), options) != null, spec);
|
|
417
|
+
strictEqual(fetchCount(documentLoader), fetched, spec);
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
test("verifyRequest() is not rejected by other purposes' negative entries", async () => {
|
|
421
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await sign(await actorJson()) });
|
|
422
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
423
|
+
const options = {
|
|
424
|
+
documentLoader,
|
|
425
|
+
contextLoader,
|
|
426
|
+
keyCache
|
|
427
|
+
};
|
|
428
|
+
for (const cls of [CryptographicKey, Multikey]) strictEqual((await fetchKeyOf(cls, options)).key, null);
|
|
429
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
430
|
+
const fetched = fetchCount(documentLoader);
|
|
431
|
+
for (const cls of [CryptographicKey, Multikey]) {
|
|
432
|
+
const result = await fetchKeyOf(cls, options);
|
|
433
|
+
strictEqual(result.key, null);
|
|
434
|
+
ok(result.cached);
|
|
435
|
+
}
|
|
436
|
+
strictEqual(fetchCount(documentLoader), fetched);
|
|
437
|
+
});
|
|
438
|
+
test("fetchKey() does not share negative entries of compatible key IDs across key classes", async () => {
|
|
439
|
+
const ownerId = new URL("https://gw1.example/users/bob");
|
|
440
|
+
const multikey = new Multikey({
|
|
441
|
+
id: keyId,
|
|
442
|
+
controller: ownerId,
|
|
443
|
+
publicKey: ed25519PublicKey.publicKey
|
|
444
|
+
});
|
|
445
|
+
const documentLoader = createLoader({
|
|
446
|
+
[compatibleId(gw1)]: await multikey.toJsonLd({ contextLoader }),
|
|
447
|
+
[ownerId.href]: await new Person({
|
|
448
|
+
id: ownerId,
|
|
449
|
+
assertionMethods: [multikey]
|
|
450
|
+
}).toJsonLd({ contextLoader })
|
|
451
|
+
});
|
|
452
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
453
|
+
const options = {
|
|
454
|
+
documentLoader,
|
|
455
|
+
contextLoader,
|
|
456
|
+
keyCache
|
|
457
|
+
};
|
|
458
|
+
strictEqual((await fetchKey(keyId, CryptographicKey, options)).key, null);
|
|
459
|
+
strictEqual(await verifyRequest(await signedRequest(), options), null);
|
|
460
|
+
const result = await fetchKey(keyId, Multikey, options);
|
|
461
|
+
strictEqual(result.key?.id?.href, keyId.href);
|
|
462
|
+
ok(!result.cached);
|
|
463
|
+
const cached = await fetchKey(keyId, Multikey, options);
|
|
464
|
+
strictEqual(cached.key?.id?.href, keyId.href);
|
|
465
|
+
ok(cached.cached);
|
|
466
|
+
const other = await fetchKey(keyId, CryptographicKey, options);
|
|
467
|
+
strictEqual(other.key, null);
|
|
468
|
+
ok(other.cached);
|
|
469
|
+
});
|
|
470
|
+
test("verifyRequest() caches rejected portable actor documents", async () => {
|
|
471
|
+
for (const spec of specs) {
|
|
472
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await actorJson() });
|
|
473
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
474
|
+
const options = {
|
|
475
|
+
documentLoader,
|
|
476
|
+
contextLoader,
|
|
477
|
+
keyCache,
|
|
478
|
+
spec
|
|
479
|
+
};
|
|
480
|
+
for (let i = 0; i < 3; i++) {
|
|
481
|
+
const result = await verifyRequestDetailed(await signedRequest(spec), options);
|
|
482
|
+
ok(!result.verified, spec);
|
|
483
|
+
strictEqual(result.reason.type, "invalidSignature", spec);
|
|
484
|
+
}
|
|
485
|
+
strictEqual(fetchCount(documentLoader), 1, spec);
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
test("verifyRequest() refetches a cached gateway key that fails to verify", async () => {
|
|
489
|
+
for (const spec of specs) {
|
|
490
|
+
const responses = { [compatibleId(gw1)]: await sign(await actorJson()) };
|
|
491
|
+
const documentLoader = createLoader(responses);
|
|
492
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
493
|
+
const options = {
|
|
494
|
+
documentLoader,
|
|
495
|
+
contextLoader,
|
|
496
|
+
keyCache,
|
|
497
|
+
spec
|
|
498
|
+
};
|
|
499
|
+
ok(await verifyRequest(await signedRequest(spec), options) != null);
|
|
500
|
+
responses[compatibleId(gw1)] = await sign(await actorJson({
|
|
501
|
+
publicKey: rsaPublicKey3.publicKey,
|
|
502
|
+
assertionMethod: false
|
|
503
|
+
}));
|
|
504
|
+
const rotated = async () => await signRequest(new Request("https://recipient.example/inbox", {
|
|
505
|
+
method: "POST",
|
|
506
|
+
body: "{}",
|
|
507
|
+
headers: { "Content-Type": "application/activity+json" }
|
|
508
|
+
}), rsaPrivateKey3, keyId, { spec });
|
|
509
|
+
ok(await verifyRequest(await rotated(), options) != null, spec);
|
|
510
|
+
strictEqual(fetchCount(documentLoader), 2, spec);
|
|
511
|
+
ok(await verifyRequest(await rotated(), options) != null, spec);
|
|
512
|
+
strictEqual(fetchCount(documentLoader), 2, spec);
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
test("verifyRequest() drops a cached gateway key when its refetch fails", async () => {
|
|
516
|
+
for (const spec of specs) {
|
|
517
|
+
const responses = { [compatibleId(gw1)]: await sign(await actorJson()) };
|
|
518
|
+
const documentLoader = createLoader(responses);
|
|
519
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
520
|
+
const options = {
|
|
521
|
+
documentLoader,
|
|
522
|
+
contextLoader,
|
|
523
|
+
keyCache,
|
|
524
|
+
spec
|
|
525
|
+
};
|
|
526
|
+
ok(await verifyRequest(await signedRequest(spec), options) != null);
|
|
527
|
+
delete responses[compatibleId(gw1)];
|
|
528
|
+
const result = await verifyRequestDetailed(await signRequest(new Request("https://recipient.example/inbox", {
|
|
529
|
+
method: "POST",
|
|
530
|
+
body: "{}",
|
|
531
|
+
headers: { "Content-Type": "application/activity+json" }
|
|
532
|
+
}), rsaPrivateKey3, keyId, { spec }), options);
|
|
533
|
+
ok(!result.verified, spec);
|
|
534
|
+
strictEqual(result.reason.type, "keyFetchError", spec);
|
|
535
|
+
strictEqual(fetchCount(documentLoader), 2, spec);
|
|
536
|
+
const next = await verifyRequestDetailed(await signedRequest(spec), options);
|
|
537
|
+
ok(!next.verified, spec);
|
|
538
|
+
strictEqual(next.reason.type, "keyFetchError", spec);
|
|
539
|
+
strictEqual(fetchCount(documentLoader), 2, spec);
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
test("verifyRequest() does not trust a cached gateway key for longer than its proof", async () => {
|
|
543
|
+
let now = Temporal.Now.instant();
|
|
544
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"], { now: () => now });
|
|
545
|
+
const expires = now.add({ minutes: 30 });
|
|
546
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await sign(await actorJson(), ed25519PrivateKey, didKeyId, { expires: expires.toString() }) });
|
|
547
|
+
const options = {
|
|
548
|
+
documentLoader,
|
|
549
|
+
contextLoader,
|
|
550
|
+
keyCache
|
|
551
|
+
};
|
|
552
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
553
|
+
now = expires.subtract({ seconds: 1 });
|
|
554
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
555
|
+
strictEqual(fetchCount(documentLoader), 1);
|
|
556
|
+
now = expires;
|
|
557
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
558
|
+
strictEqual(fetchCount(documentLoader), 2);
|
|
559
|
+
});
|
|
560
|
+
test("verifyRequest() looks up a cached gateway key again after an hour", async () => {
|
|
561
|
+
let now = Temporal.Now.instant();
|
|
562
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"], { now: () => now });
|
|
563
|
+
const responses = { [compatibleId(gw1)]: await sign(await actorJson()) };
|
|
564
|
+
const documentLoader = createLoader(responses);
|
|
565
|
+
const options = {
|
|
566
|
+
documentLoader,
|
|
567
|
+
contextLoader,
|
|
568
|
+
keyCache
|
|
569
|
+
};
|
|
570
|
+
const start = now;
|
|
571
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
572
|
+
now = start.add({ minutes: 59 });
|
|
573
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
574
|
+
strictEqual(fetchCount(documentLoader), 1);
|
|
575
|
+
responses[compatibleId(gw1)] = await sign(await actorJson({ gateways: [gw2] }));
|
|
576
|
+
now = start.add({ hours: 1 });
|
|
577
|
+
strictEqual(await verifyRequest(await signedRequest(), options), null);
|
|
578
|
+
strictEqual(fetchCount(documentLoader), 2);
|
|
579
|
+
});
|
|
580
|
+
test("verifyRequest() rejects and caches gateway keys of expired documents", async () => {
|
|
581
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await sign(await actorJson(), ed25519PrivateKey, didKeyId, { expires: "2000-01-01T00:00:00Z" }) });
|
|
582
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
583
|
+
const options = {
|
|
584
|
+
documentLoader,
|
|
585
|
+
contextLoader,
|
|
586
|
+
keyCache
|
|
587
|
+
};
|
|
588
|
+
strictEqual(await verifyRequest(await signedRequest(), options), null);
|
|
589
|
+
strictEqual(await verifyRequest(await signedRequest(), options), null);
|
|
590
|
+
strictEqual(fetchCount(documentLoader), 1);
|
|
591
|
+
});
|
|
592
|
+
test("verifyRequest() takes the expiration of a proof whatever its context", async () => {
|
|
593
|
+
let now = Temporal.Now.instant();
|
|
594
|
+
const keyCache = new KvKeyCache(new MemoryKvStore(), ["pk"], { now: () => now });
|
|
595
|
+
const expires = now.add({ minutes: 30 });
|
|
596
|
+
const actor = await actorJson();
|
|
597
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await sign({
|
|
598
|
+
...actor,
|
|
599
|
+
"@context": [...actor["@context"], { expires: "https://example.com/ns#notExpiration" }]
|
|
600
|
+
}, ed25519PrivateKey, didKeyId, { expires: expires.toString() }) });
|
|
601
|
+
const options = {
|
|
602
|
+
documentLoader,
|
|
603
|
+
contextLoader,
|
|
604
|
+
keyCache
|
|
605
|
+
};
|
|
606
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
607
|
+
now = expires.subtract({ seconds: 1 });
|
|
608
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
609
|
+
strictEqual(fetchCount(documentLoader), 1);
|
|
610
|
+
now = expires;
|
|
611
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
612
|
+
strictEqual(fetchCount(documentLoader), 2);
|
|
613
|
+
});
|
|
614
|
+
test("a key cache without namespaces caches only fetch failures of compatible key IDs", async () => {
|
|
337
615
|
const calls = [];
|
|
616
|
+
const entries = /* @__PURE__ */ new Map();
|
|
338
617
|
const keyCache = {
|
|
339
618
|
get(id) {
|
|
340
619
|
calls.push(`get ${id.href}`);
|
|
341
|
-
return Promise.resolve(
|
|
620
|
+
return Promise.resolve(entries.get(id.href));
|
|
342
621
|
},
|
|
343
|
-
set(id) {
|
|
344
|
-
calls.push(`set ${id.href}`);
|
|
622
|
+
set(id, key) {
|
|
623
|
+
calls.push(`set ${id.href} ${key == null ? "null" : "key"}`);
|
|
624
|
+
entries.set(id.href, key);
|
|
345
625
|
return Promise.resolve();
|
|
346
626
|
}
|
|
347
627
|
};
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
documentLoader,
|
|
351
|
-
contextLoader,
|
|
352
|
-
keyCache
|
|
353
|
-
}) != null);
|
|
354
|
-
const fetchOptions = {
|
|
355
|
-
documentLoader,
|
|
628
|
+
const options = {
|
|
629
|
+
documentLoader: createLoader({ [compatibleId(gw1)]: await sign(await actorJson()) }),
|
|
356
630
|
contextLoader,
|
|
357
631
|
keyCache
|
|
358
632
|
};
|
|
359
|
-
|
|
360
|
-
strictEqual((await
|
|
361
|
-
|
|
633
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
634
|
+
for (const cls of [CryptographicKey, Multikey]) strictEqual((await fetchKeyOf(cls, options)).key, null);
|
|
635
|
+
ok(await verifyRequest(await signedRequest(), options) != null);
|
|
636
|
+
deepStrictEqual(calls.filter((c) => c.startsWith("set ") && c.includes(keyId.origin)), []);
|
|
637
|
+
const unreachable = new URL(`${compatibleId(gw2)}#main-key`);
|
|
638
|
+
strictEqual((await fetchKey(unreachable, CryptographicKey, options)).key, null);
|
|
639
|
+
deepStrictEqual(calls.filter((c) => c.startsWith("set ") && c.includes(gw2)), [`set ${unreachable.href} null`]);
|
|
362
640
|
});
|
|
363
641
|
test("doesActorOwnKey() and getKeyOwner() resolve gateway keys to portable actors", async () => {
|
|
364
642
|
const options = {
|
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 { i as signObject, n as createProof, o as verifyObject, r as hasProofLike, s as verifyPortableObjectProof, u as verifyProof } from "../proof-
|
|
14
|
-
import { d as verifyRequest } from "../http-
|
|
13
|
+
import { i as signObject, n as createProof, o as verifyObject, r as hasProofLike, s as verifyPortableObjectProof, u as verifyProof } from "../proof-xdPYGPaA.mjs";
|
|
14
|
+
import { d as verifyRequest } from "../http-BcLnr2do.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-Bby5g2iu.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,6 +1,6 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
|
-
const require_http = require("./http-
|
|
3
|
-
require("./owner-
|
|
2
|
+
const require_http = require("./http-B4mQvNcv.cjs");
|
|
3
|
+
require("./owner-BtoMCv6Z.cjs");
|
|
4
4
|
let _logtape_logtape = require("@logtape/logtape");
|
|
5
5
|
let _fedify_vocab = require("@fedify/vocab");
|
|
6
6
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { _ as verifyPortableObjectProofWithRoot, bt as name, h as verifyPortableObjectProof, xt as version } from "./http-
|
|
4
|
-
import "./owner-
|
|
3
|
+
import { _ as verifyPortableObjectProofWithRoot, bt as name, h as verifyPortableObjectProof, xt as version } from "./http-Ce6_Lf7k.js";
|
|
4
|
+
import "./owner-Cb3ytrlq.js";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
import { CollectionPage, Object as Object$1, isActor } from "@fedify/vocab";
|
|
7
7
|
import { trace } from "@opentelemetry/api";
|
|
@@ -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-CnT0f1nU.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-dbCShlCb.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-BpwKvOpU.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
|
@@ -387,14 +387,18 @@ type ActorAliasMapper<TContextData> = (context: RequestContext<TContextData>, re
|
|
|
387
387
|
username: string;
|
|
388
388
|
} | null>;
|
|
389
389
|
/**
|
|
390
|
-
* A callback that dispatches an object.
|
|
390
|
+
* A callback that dispatches an object or a {@link Tombstone}.
|
|
391
|
+
*
|
|
392
|
+
* Return a {@link Tombstone} if the object has been deleted; Fedify then
|
|
393
|
+
* responds with `410 Gone` and the serialized tombstone. Return `null` if
|
|
394
|
+
* the object is not found.
|
|
391
395
|
*
|
|
392
396
|
* @template TContextData The context data to pass to the {@link Context}.
|
|
393
397
|
* @template TObject The type of object to dispatch.
|
|
394
398
|
* @template TParam The parameter names of the requested URL.
|
|
395
399
|
* @since 0.7.0
|
|
396
400
|
*/
|
|
397
|
-
type ObjectDispatcher<TContextData, TObject extends Object$1, TParam extends string> = (context: RequestContext<TContextData>, values: Record<TParam, string>) => TObject | null | Promise<TObject | null>;
|
|
401
|
+
type ObjectDispatcher<TContextData, TObject extends Object$1, TParam extends string> = (context: RequestContext<TContextData>, values: Record<TParam, string>) => TObject | Tombstone | null | Promise<TObject | Tombstone | null>;
|
|
398
402
|
/**
|
|
399
403
|
* A callback that dispatches a collection.
|
|
400
404
|
*
|
|
@@ -1525,7 +1529,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
|
1525
1529
|
* based on URI Template
|
|
1526
1530
|
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
|
|
1527
1531
|
* must have one or more variables.
|
|
1528
|
-
* @param dispatcher An object dispatcher callback to register.
|
|
1532
|
+
* @param dispatcher An object dispatcher callback to register. It may
|
|
1533
|
+
* return an object, a `Tombstone` if the object has been
|
|
1534
|
+
* deleted, or `null` if the object is not found.
|
|
1529
1535
|
*/
|
|
1530
1536
|
setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
|
|
1531
1537
|
/**
|
|
@@ -1539,7 +1545,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
|
1539
1545
|
* based on URI Template
|
|
1540
1546
|
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
|
|
1541
1547
|
* must have one or more variables.
|
|
1542
|
-
* @param dispatcher An object dispatcher callback to register.
|
|
1548
|
+
* @param dispatcher An object dispatcher callback to register. It may
|
|
1549
|
+
* return an object, a `Tombstone` if the object has been
|
|
1550
|
+
* deleted, or `null` if the object is not found.
|
|
1543
1551
|
*/
|
|
1544
1552
|
setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
|
|
1545
1553
|
/**
|
|
@@ -1553,7 +1561,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
|
1553
1561
|
* based on URI Template
|
|
1554
1562
|
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
|
|
1555
1563
|
* must have one or more variables.
|
|
1556
|
-
* @param dispatcher An object dispatcher callback to register.
|
|
1564
|
+
* @param dispatcher An object dispatcher callback to register. It may
|
|
1565
|
+
* return an object, a `Tombstone` if the object has been
|
|
1566
|
+
* deleted, or `null` if the object is not found.
|
|
1557
1567
|
*/
|
|
1558
1568
|
setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
|
|
1559
1569
|
/**
|
|
@@ -1567,7 +1577,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
|
1567
1577
|
* based on URI Template
|
|
1568
1578
|
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
|
|
1569
1579
|
* must have one or more variables.
|
|
1570
|
-
* @param dispatcher An object dispatcher callback to register.
|
|
1580
|
+
* @param dispatcher An object dispatcher callback to register. It may
|
|
1581
|
+
* return an object, a `Tombstone` if the object has been
|
|
1582
|
+
* deleted, or `null` if the object is not found.
|
|
1571
1583
|
*/
|
|
1572
1584
|
setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}${Rfc6570Expression<TParam>}${string}${Rfc6570Expression<TParam>}${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
|
|
1573
1585
|
/**
|
|
@@ -1581,7 +1593,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
|
1581
1593
|
* based on URI Template
|
|
1582
1594
|
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
|
|
1583
1595
|
* must have one or more variables.
|
|
1584
|
-
* @param dispatcher An object dispatcher callback to register.
|
|
1596
|
+
* @param dispatcher An object dispatcher callback to register. It may
|
|
1597
|
+
* return an object, a `Tombstone` if the object has been
|
|
1598
|
+
* deleted, or `null` if the object is not found.
|
|
1585
1599
|
*/
|
|
1586
1600
|
setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}${Rfc6570Expression<TParam>}${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
|
|
1587
1601
|
/**
|
|
@@ -1595,7 +1609,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
|
1595
1609
|
* based on URI Template
|
|
1596
1610
|
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
|
|
1597
1611
|
* must have one or more variables.
|
|
1598
|
-
* @param dispatcher An object dispatcher callback to register.
|
|
1612
|
+
* @param dispatcher An object dispatcher callback to register. It may
|
|
1613
|
+
* return an object, a `Tombstone` if the object has been
|
|
1614
|
+
* deleted, or `null` if the object is not found.
|
|
1599
1615
|
*/
|
|
1600
1616
|
setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
|
|
1601
1617
|
/**
|
|
@@ -3357,6 +3373,23 @@ interface GetActorOptions {
|
|
|
3357
3373
|
*/
|
|
3358
3374
|
readonly tombstone?: "suppress" | "passthrough";
|
|
3359
3375
|
}
|
|
3376
|
+
/**
|
|
3377
|
+
* Options for {@link RequestContext.getObject}.
|
|
3378
|
+
* @since 2.4.0
|
|
3379
|
+
*/
|
|
3380
|
+
interface GetObjectOptions {
|
|
3381
|
+
/**
|
|
3382
|
+
* Controls how tombstoned objects are returned.
|
|
3383
|
+
*
|
|
3384
|
+
* By default, or if set to `"suppress"`, a {@link Tombstone} is returned as
|
|
3385
|
+
* `null`, unless it is an instance of the requested class, e.g., when
|
|
3386
|
+
* the requested class is `Object` or `Tombstone` itself. In that case,
|
|
3387
|
+
* the tombstone is returned as is, as it is an object of the requested
|
|
3388
|
+
* class. Set this to `"passthrough"` to always receive a {@link Tombstone}
|
|
3389
|
+
* result instead of `null`.
|
|
3390
|
+
*/
|
|
3391
|
+
readonly tombstone?: "suppress" | "passthrough";
|
|
3392
|
+
}
|
|
3360
3393
|
/**
|
|
3361
3394
|
* A context for a request.
|
|
3362
3395
|
*/
|
|
@@ -3522,12 +3555,61 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
3522
3555
|
* @param cls The class to instantiate.
|
|
3523
3556
|
* @param values The values to pass to the object dispatcher.
|
|
3524
3557
|
* @returns The object of the given class with the given values, or `null`
|
|
3525
|
-
* if the object is not found.
|
|
3558
|
+
* if the object is not found. Tombstoned objects are suppressed
|
|
3559
|
+
* unless the tombstone is an instance of `cls`.
|
|
3526
3560
|
* @throws {Error} If no object dispatcher is available for the class.
|
|
3527
3561
|
* @throws {TypeError} If values are invalid.
|
|
3528
3562
|
* @since 0.7.0
|
|
3529
3563
|
*/
|
|
3530
3564
|
getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>): Promise<TObject | null>;
|
|
3565
|
+
/**
|
|
3566
|
+
* Gets an object of the given class, or a {@link Tombstone}, with the given
|
|
3567
|
+
* values.
|
|
3568
|
+
* @param cls The class to instantiate.
|
|
3569
|
+
* @param values The values to pass to the object dispatcher.
|
|
3570
|
+
* @param options Options for getting the object. Set `options.tombstone`
|
|
3571
|
+
* to `"passthrough"` to receive tombstoned objects instead
|
|
3572
|
+
* of `null`.
|
|
3573
|
+
* @returns The object of the given class with the given values,
|
|
3574
|
+
* a tombstone, or `null` if the object is not found.
|
|
3575
|
+
* @throws {Error} If no object dispatcher is available for the class.
|
|
3576
|
+
* @throws {TypeError} If values are invalid.
|
|
3577
|
+
* @since 2.4.0
|
|
3578
|
+
*/
|
|
3579
|
+
getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, options: GetObjectOptions & {
|
|
3580
|
+
readonly tombstone: "passthrough";
|
|
3581
|
+
}): Promise<TObject | Tombstone | null>;
|
|
3582
|
+
/**
|
|
3583
|
+
* Gets an object of the given class with the given values.
|
|
3584
|
+
* @param cls The class to instantiate.
|
|
3585
|
+
* @param values The values to pass to the object dispatcher.
|
|
3586
|
+
* @param options Options for getting the object.
|
|
3587
|
+
* @returns The object of the given class with the given values, or `null`
|
|
3588
|
+
* if the object is not found. Tombstoned objects are suppressed
|
|
3589
|
+
* unless `options.tombstone` is `"passthrough"` or the tombstone
|
|
3590
|
+
* is an instance of `cls`.
|
|
3591
|
+
* @throws {Error} If no object dispatcher is available for the class.
|
|
3592
|
+
* @throws {TypeError} If values are invalid.
|
|
3593
|
+
* @since 2.4.0
|
|
3594
|
+
*/
|
|
3595
|
+
getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, options: GetObjectOptions & {
|
|
3596
|
+
readonly tombstone?: "suppress" | undefined;
|
|
3597
|
+
}): Promise<TObject | null>;
|
|
3598
|
+
/**
|
|
3599
|
+
* Gets an object of the given class, or a {@link Tombstone}, with the given
|
|
3600
|
+
* values.
|
|
3601
|
+
* @param cls The class to instantiate.
|
|
3602
|
+
* @param values The values to pass to the object dispatcher.
|
|
3603
|
+
* @param options Options for getting the object.
|
|
3604
|
+
* @returns The object of the given class with the given values,
|
|
3605
|
+
* a tombstone, or `null` if the object is not found. This broad
|
|
3606
|
+
* overload is used when the caller passes an options value whose
|
|
3607
|
+
* `tombstone` mode is not known statically.
|
|
3608
|
+
* @throws {Error} If no object dispatcher is available for the class.
|
|
3609
|
+
* @throws {TypeError} If values are invalid.
|
|
3610
|
+
* @since 2.4.0
|
|
3611
|
+
*/
|
|
3612
|
+
getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, options: GetObjectOptions): Promise<TObject | Tombstone | null>;
|
|
3531
3613
|
/**
|
|
3532
3614
|
* Gets the public key of the sender, if any exists and it is verified.
|
|
3533
3615
|
* Otherwise, `null` is returned.
|
|
@@ -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-BcLnr2do.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-Bby5g2iu.mjs";
|
|
11
11
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
12
12
|
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
13
13
|
//#region src/utils/docloader.test.ts
|
|
@@ -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-iFaRIcIL.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-Dqp_E-1g.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-Cr79cQlc.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-DwzXzchj.js";
|
|
4
4
|
export { getAuthenticatedDocumentLoader, kvCache };
|