@fedify/fedify 2.2.0-pr.710.26 → 2.2.0-pr.715.27

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.
Files changed (63) hide show
  1. package/dist/{builder-BG2fljmM.mjs → builder-DQtY9nHQ.mjs} +3 -3
  2. package/dist/compat/transformers.test.mjs +2 -2
  3. package/dist/{deno-Bg4eBr2D.mjs → deno-_fgAC2zJ.mjs} +1 -1
  4. package/dist/{docloader-DNzzLpZS.mjs → docloader-vRYuv1jI.mjs} +2 -2
  5. package/dist/federation/builder.test.mjs +2 -2
  6. package/dist/federation/collection.test.mjs +1 -1
  7. package/dist/federation/handler.test.mjs +4 -4
  8. package/dist/federation/idempotency.test.mjs +3 -3
  9. package/dist/federation/inbox.test.mjs +1 -1
  10. package/dist/federation/keycache.test.mjs +2 -2
  11. package/dist/federation/kv.test.mjs +1 -1
  12. package/dist/federation/middleware.test.mjs +7 -17
  13. package/dist/federation/mod.cjs +1 -1
  14. package/dist/federation/mod.js +1 -1
  15. package/dist/federation/negotiation.test.mjs +1 -1
  16. package/dist/federation/retry.test.mjs +1 -1
  17. package/dist/federation/send.test.mjs +3 -3
  18. package/dist/federation/webfinger.test.mjs +2 -2
  19. package/dist/{http-DWkREdt7.mjs → http-C8rif6ld.mjs} +2 -2
  20. package/dist/{http-Dgit35mk.cjs → http-R-epZzZQ.cjs} +1 -1
  21. package/dist/{http-Cbg9qm41.js → http-s3HaFg5o.js} +1 -1
  22. package/dist/{key-DkuUQiqs.mjs → key-Ce0SDXK2.mjs} +1 -1
  23. package/dist/{kv-cache-e9fvIFDA.cjs → kv-cache-Btpmwlb5.cjs} +1 -1
  24. package/dist/{kv-cache-Bl6yhpBL.js → kv-cache-ChSAw77q.js} +1 -1
  25. package/dist/{ld-1klZemqw.mjs → ld-BsDP9tTM.mjs} +2 -2
  26. package/dist/{middleware-DRNKgUtw.js → middleware-C4ymcV-E.js} +3 -4
  27. package/dist/{middleware-DY-mzSrv.cjs → middleware-CXG1M9Om.cjs} +1 -1
  28. package/dist/{middleware-BDpu1OCd.mjs → middleware-DFQeBAbL.mjs} +1 -1
  29. package/dist/{middleware-D1zxydrX.mjs → middleware-DtEWmK1Y.mjs} +15 -17
  30. package/dist/{middleware-G6DmtY5H.cjs → middleware-vUbXbazq.cjs} +4 -5
  31. package/dist/mod.cjs +4 -4
  32. package/dist/mod.js +4 -4
  33. package/dist/nodeinfo/client.test.mjs +1 -1
  34. package/dist/nodeinfo/handler.test.mjs +2 -2
  35. package/dist/nodeinfo/types.test.mjs +1 -1
  36. package/dist/otel/exporter.test.mjs +1 -1
  37. package/dist/{owner-ijaWLw_K.mjs → owner-CTfDotXM.mjs} +2 -2
  38. package/dist/{proof-CP0GRqWY.cjs → proof-3RPJLWOU.cjs} +38 -221
  39. package/dist/{proof-BbfBQytm.mjs → proof-UdlPVu_P.mjs} +31 -36
  40. package/dist/{proof-CQJHVvjQ.js → proof-qQIVjzlw.js} +41 -218
  41. package/dist/{send-CJyp2e8W.mjs → send-kudDOImz.mjs} +2 -2
  42. package/dist/sig/http.test.mjs +2 -2
  43. package/dist/sig/key.test.mjs +1 -1
  44. package/dist/sig/ld.test.mjs +2 -2
  45. package/dist/sig/mod.cjs +2 -2
  46. package/dist/sig/mod.js +2 -2
  47. package/dist/sig/owner.test.mjs +1 -1
  48. package/dist/sig/proof.test.mjs +2 -60
  49. package/dist/utils/docloader.test.mjs +2 -2
  50. package/dist/utils/mod.cjs +1 -1
  51. package/dist/utils/mod.js +1 -1
  52. package/package.json +6 -6
  53. package/dist/compat/public-audience.test.d.mts +0 -2
  54. package/dist/compat/public-audience.test.mjs +0 -178
  55. package/dist/public-audience-eovWqzOF.mjs +0 -181
  56. /package/dist/{activity-listener-CFzUqoCS.mjs → activity-listener-Ck3JZ_hR.mjs} +0 -0
  57. /package/dist/{client-DVu6Fmom.mjs → client-DEpOVgY1.mjs} +0 -0
  58. /package/dist/{collection-BQRKGS7L.mjs → collection-BD6-SZ6O.mjs} +0 -0
  59. /package/dist/{keycache-C2t1kvP5.mjs → keycache-CCSwkQcY.mjs} +0 -0
  60. /package/dist/{kv-C-TG81Sv.mjs → kv-tL2TOE9X.mjs} +0 -0
  61. /package/dist/{negotiation-xb0QR3u_.mjs → negotiation-DnsfFF8I.mjs} +0 -0
  62. /package/dist/{retry-CJL0poaU.mjs → retry-B_E3V_Dx.mjs} +0 -0
  63. /package/dist/{types-CGUnLkU3.mjs → types-DCP0WLdt.mjs} +0 -0
@@ -1,16 +1,16 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
- import { _ as version, d as validateCryptoKey, g as name, s as fetchKey } from "./http-Cbg9qm41.js";
3
+ import { _ as version, d as validateCryptoKey, g as name, s as fetchKey } from "./http-s3HaFg5o.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
- import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, PUBLIC_COLLECTION, getTypeId, isActor } from "@fedify/vocab";
5
+ import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, getTypeId, isActor } from "@fedify/vocab";
6
6
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
7
7
  import { encodeHex } from "byte-encodings/hex";
8
- import { getDocumentLoader, preloadedContexts } from "@fedify/vocab-runtime";
8
+ import { getDocumentLoader } from "@fedify/vocab-runtime";
9
9
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
10
10
  import jsonld from "@fedify/vocab-runtime/jsonld";
11
11
  import serialize from "json-canon";
12
12
  //#region src/sig/ld.ts
13
- const logger$2 = getLogger([
13
+ const logger$1 = getLogger([
14
14
  "fedify",
15
15
  "sig",
16
16
  "ld"
@@ -158,7 +158,7 @@ async function verifySignature(jsonLd, options = {}) {
158
158
  try {
159
159
  signature = decodeBase64(sig.signatureValue);
160
160
  } catch (error) {
161
- logger$2.debug("Failed to verify; invalid base64 signatureValue: {signatureValue}", {
161
+ logger$1.debug("Failed to verify; invalid base64 signatureValue: {signatureValue}", {
162
162
  ...sig,
163
163
  error
164
164
  });
@@ -177,7 +177,7 @@ async function verifySignature(jsonLd, options = {}) {
177
177
  try {
178
178
  sigOptsHash = await hashJsonLd(sigOpts, options.contextLoader);
179
179
  } catch (error) {
180
- logger$2.warn("Failed to verify; failed to hash the signature options: {signatureOptions}\n{error}", {
180
+ logger$1.warn("Failed to verify; failed to hash the signature options: {signatureOptions}\n{error}", {
181
181
  signatureOptions: sigOpts,
182
182
  error
183
183
  });
@@ -189,7 +189,7 @@ async function verifySignature(jsonLd, options = {}) {
189
189
  try {
190
190
  docHash = await hashJsonLd(document, options.contextLoader);
191
191
  } catch (error) {
192
- logger$2.warn("Failed to verify; failed to hash the document: {document}\n{error}", {
192
+ logger$1.warn("Failed to verify; failed to hash the document: {document}\n{error}", {
193
193
  document,
194
194
  error
195
195
  });
@@ -200,7 +200,7 @@ async function verifySignature(jsonLd, options = {}) {
200
200
  const messageBytes = encoder.encode(message);
201
201
  if (await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes)) return key;
202
202
  if (cached) {
203
- logger$2.debug("Failed to verify with the cached key {keyId}; signature {signatureValue} is invalid. Retrying with the freshly fetched key...", {
203
+ logger$1.debug("Failed to verify with the cached key {keyId}; signature {signatureValue} is invalid. Retrying with the freshly fetched key...", {
204
204
  keyId: sig.creator,
205
205
  ...sig
206
206
  });
@@ -214,7 +214,7 @@ async function verifySignature(jsonLd, options = {}) {
214
214
  if (key == null) return null;
215
215
  return await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes) ? key : null;
216
216
  }
217
- logger$2.debug("Failed to verify with the fetched key {keyId}; signature {signatureValue} is invalid. Check if the key is correct or if the signed message is correct. The message to sign is:\n{message}", {
217
+ logger$1.debug("Failed to verify with the fetched key {keyId}; signature {signatureValue} is invalid. Check if the key is correct or if the signed message is correct. The message to sign is:\n{message}", {
218
218
  keyId: sig.creator,
219
219
  ...sig,
220
220
  message
@@ -246,12 +246,12 @@ async function verifyJsonLd(jsonLd, options = {}) {
246
246
  const key = await verifySignature(jsonLd, options);
247
247
  if (key == null) return false;
248
248
  if (key.ownerId == null) {
249
- logger$2.debug("Key {keyId} has no owner.", { keyId: key.id?.href });
249
+ logger$1.debug("Key {keyId} has no owner.", { keyId: key.id?.href });
250
250
  return false;
251
251
  }
252
252
  attributions.delete(key.ownerId.href);
253
253
  if (attributions.size > 0) {
254
- logger$2.debug("Some attributions are not authenticated by the Linked Data Signatures: {attributions}.", { attributions: [...attributions] });
254
+ logger$1.debug("Some attributions are not authenticated by the Linked Data Signatures: {attributions}.", { attributions: [...attributions] });
255
255
  return false;
256
256
  }
257
257
  return true;
@@ -386,179 +386,6 @@ async function getKeyOwner(keyId, options) {
386
386
  return null;
387
387
  }
388
388
  //#endregion
389
- //#region src/compat/public-audience.ts
390
- const logger$1 = getLogger([
391
- "fedify",
392
- "compat",
393
- "public-audience"
394
- ]);
395
- const PUBLIC_ADDRESSING_FIELDS = new Set([
396
- "to",
397
- "cc",
398
- "bto",
399
- "bcc",
400
- "audience"
401
- ]);
402
- const preloadedOnlyDocumentLoader = (url) => {
403
- if (Object.hasOwn(preloadedContexts, url)) return Promise.resolve({
404
- contextUrl: null,
405
- documentUrl: url,
406
- document: preloadedContexts[url]
407
- });
408
- return Promise.reject(/* @__PURE__ */ new Error("Refusing to fetch a non-preloaded JSON-LD context: " + url));
409
- };
410
- const AS_CONTEXT_URL = "https://www.w3.org/ns/activitystreams";
411
- const MAX_TRAVERSAL_DEPTH = 64;
412
- const KNOWN_SAFE_CONTEXT_URLS = new Set(Object.keys(preloadedContexts));
413
- function hasPublicCurieInAddressing(value, parentKey, depth = 0) {
414
- if (typeof value === "string") return parentKey != null && PUBLIC_ADDRESSING_FIELDS.has(parentKey) && (value === "as:Public" || value === "Public");
415
- if (depth >= MAX_TRAVERSAL_DEPTH) return false;
416
- if (Array.isArray(value)) return value.some((item) => hasPublicCurieInAddressing(item, parentKey, depth + 1));
417
- if (typeof value !== "object" || value == null) return false;
418
- const record = value;
419
- for (const key of Object.keys(record)) {
420
- if (key === "@context") continue;
421
- if (hasPublicCurieInAddressing(record[key], key, depth + 1)) return true;
422
- }
423
- return false;
424
- }
425
- function rewritePublicAudience(value, parentKey, depth = 0) {
426
- if (typeof value === "string" && parentKey != null && PUBLIC_ADDRESSING_FIELDS.has(parentKey) && (value === "as:Public" || value === "Public")) return PUBLIC_COLLECTION.href;
427
- if (depth >= MAX_TRAVERSAL_DEPTH) return value;
428
- if (Array.isArray(value)) {
429
- let changed = false;
430
- const mapped = value.map((item) => {
431
- const rewritten = rewritePublicAudience(item, parentKey, depth + 1);
432
- if (rewritten !== item) changed = true;
433
- return rewritten;
434
- });
435
- return changed ? mapped : value;
436
- }
437
- if (typeof value !== "object" || value == null) return value;
438
- const record = value;
439
- let changed = false;
440
- const normalized = Object.create(null);
441
- for (const key of Object.keys(record)) {
442
- const rewritten = key === "@context" ? record[key] : rewritePublicAudience(record[key], key, depth + 1);
443
- if (rewritten !== record[key]) changed = true;
444
- normalized[key] = rewritten;
445
- }
446
- return changed ? normalized : value;
447
- }
448
- /**
449
- * Reports whether `value` carries an `@context` property anywhere inside
450
- * its subtree (not counting the value itself). A nested `@context` can
451
- * introduce a local term-definition scope that redefines `as:` or `Public`
452
- * even when the top-level `@context` is safe, so the fast path must defer
453
- * to the URDNA2015 equivalence check whenever one is present.
454
- */
455
- function hasNestedContext(value, depth = 0) {
456
- if (depth >= MAX_TRAVERSAL_DEPTH) return true;
457
- if (Array.isArray(value)) return value.some((item) => hasNestedContext(item, depth + 1));
458
- if (typeof value !== "object" || value == null) return false;
459
- const record = value;
460
- for (const key of Object.keys(record)) {
461
- if (key === "@context") return true;
462
- if (hasNestedContext(record[key], depth + 1)) return true;
463
- }
464
- return false;
465
- }
466
- /**
467
- * Checks whether the `@context` of a JSON-LD document is guaranteed not
468
- * to redefine the `as:` prefix or the bare `Public` term. Only documents
469
- * whose `@context` is a string, or an array of strings, drawn from Fedify's
470
- * preloaded context set AND including the ActivityStreams URL qualify,
471
- * AND no nested subtree carries its own `@context` that might redefine
472
- * those terms within a local scope. When all of that holds the rewrite
473
- * is provably semantics-preserving and the URDNA2015 equivalence check
474
- * can be skipped. Any other shape (unknown external URLs, inline
475
- * objects at the top level, nested `@context` blocks) is treated as
476
- * potentially unsafe.
477
- */
478
- function hasKnownSafeContext(jsonLd) {
479
- if (typeof jsonLd !== "object" || jsonLd == null) return false;
480
- const record = jsonLd;
481
- if (!Object.hasOwn(record, "@context")) return false;
482
- const ctx = record["@context"];
483
- const entries = typeof ctx === "string" ? [ctx] : Array.isArray(ctx) ? ctx : null;
484
- if (entries == null || entries.length === 0) return false;
485
- let hasAs = false;
486
- for (const entry of entries) {
487
- if (typeof entry !== "string") return false;
488
- if (!KNOWN_SAFE_CONTEXT_URLS.has(entry)) return false;
489
- if (entry === AS_CONTEXT_URL) hasAs = true;
490
- }
491
- if (!hasAs) return false;
492
- for (const key of Object.keys(record)) {
493
- if (key === "@context") continue;
494
- if (hasNestedContext(record[key])) return false;
495
- }
496
- return true;
497
- }
498
- /**
499
- * Rewrites the compact `as:Public` / `Public` CURIE appearing in activity
500
- * addressing fields (`to`, `cc`, `bto`, `bcc`, `audience`) to the fully
501
- * expanded `https://www.w3.org/ns/activitystreams#Public` URI.
502
- *
503
- * Several ActivityPub implementations, Lemmy among them, match these
504
- * fields as plain URLs without running JSON-LD expansion, and silently
505
- * drop activities whose public addressing appears in CURIE form. This
506
- * helper works around that gap.
507
- *
508
- * For documents whose `@context` is drawn entirely from Fedify's
509
- * preloaded context set and includes the ActivityStreams URL, the
510
- * rewrite is applied directly: the content of every preloaded non-AS
511
- * context is known not to redefine the `as:` prefix or the bare `Public`
512
- * term, so the semantics are preserved by construction. Any other
513
- * shape (an inline object, an unknown external URL, and so on) is
514
- * treated as potentially unsafe and gated on a JSON-LD equivalence
515
- * check; both forms are canonicalized with URDNA2015 and the resulting
516
- * N-Quads are compared. When they differ, the original document is
517
- * returned unchanged. Canonicalization failures also fall back to the
518
- * original document.
519
- *
520
- * When no `contextLoader` is supplied the helper falls back to an
521
- * internal loader that resolves only the URLs in Fedify's
522
- * preloaded-contexts set and rejects every other URL without issuing a
523
- * network request. That behaviour is deliberately narrower than
524
- * `@fedify/vocab-runtime`'s `getDocumentLoader()`, which after its
525
- * `validatePublicUrl` check will happily fetch non-preloaded URLs: the
526
- * helper is reached from verification paths (`verifyProof()` /
527
- * `verifyObject()`) that operate on inbound, potentially adversarial
528
- * JSON-LD, and a default loader that fetches attacker-supplied
529
- * `@context` URLs on the caller's behalf would be an SSRF vector.
530
- * Canonicalization failures against the restricted loader fall back to
531
- * the original document, same as any other canonicalization error.
532
- * Callers that genuinely need the remote-fetch loader (for example
533
- * applications that sign local JSON-LD against a custom vocabulary)
534
- * should pass a `contextLoader` explicitly.
535
- *
536
- * Must be called before any signing step that canonicalizes the
537
- * compact form byte-for-byte (for example, Object Integrity Proofs
538
- * using the `eddsa-jcs-2022` cryptosuite), so the signed payload
539
- * matches what is sent on the wire.
540
- */
541
- async function normalizePublicAudience(jsonLd, contextLoader) {
542
- if (!hasPublicCurieInAddressing(jsonLd)) return jsonLd;
543
- const normalized = rewritePublicAudience(jsonLd);
544
- if (hasKnownSafeContext(jsonLd)) return normalized;
545
- const loader = contextLoader ?? preloadedOnlyDocumentLoader;
546
- try {
547
- const [before, after] = await Promise.all([jsonld.canonize(jsonLd, {
548
- format: "application/n-quads",
549
- documentLoader: loader
550
- }), jsonld.canonize(normalized, {
551
- format: "application/n-quads",
552
- documentLoader: loader
553
- })]);
554
- if (before === after) return normalized;
555
- logger$1.warn("Expanding the public audience CURIE to its full URI would change the canonical form of the activity; sending the activity as is. This usually means the active JSON-LD context redefines the `as:` prefix or the bare `Public` term.");
556
- } catch (error) {
557
- logger$1.debug("Failed to verify public audience normalization equivalence via JSON-LD canonicalization; sending the activity as is.\n{error}", { error });
558
- }
559
- return jsonLd;
560
- }
561
- //#endregion
562
389
  //#region src/sig/proof.ts
563
390
  const logger = getLogger([
564
391
  "fedify",
@@ -607,12 +434,11 @@ function hasProofLike(jsonLd) {
607
434
  async function createProof(object, privateKey, keyId, { contextLoader, context, created } = {}) {
608
435
  validateCryptoKey(privateKey, "private");
609
436
  if (privateKey.algorithm.name !== "Ed25519") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
610
- let compactMsg = await object.clone({ proofs: [] }).toJsonLd({
437
+ const compactMsg = await object.clone({ proofs: [] }).toJsonLd({
611
438
  format: "compact",
612
439
  contextLoader,
613
440
  context
614
441
  });
615
- compactMsg = await normalizePublicAudience(compactMsg, contextLoader);
616
442
  const msgCanon = serialize(compactMsg);
617
443
  const encoder = new TextEncoder();
618
444
  const msgBytes = encoder.encode(msgCanon);
@@ -707,25 +533,27 @@ async function verifyProof(jsonLd, proof, options = {}) {
707
533
  });
708
534
  }
709
535
  async function verifyProofInternal(jsonLd, proof, options) {
710
- if (typeof jsonLd !== "object" || jsonLd == null || Array.isArray(jsonLd) || proof.cryptosuite !== "eddsa-jcs-2022" || proof.verificationMethodId == null || proof.proofPurpose !== "assertionMethod" || proof.proofValue == null || proof.created == null) return null;
536
+ if (typeof jsonLd !== "object" || proof.cryptosuite !== "eddsa-jcs-2022" || proof.verificationMethodId == null || proof.proofPurpose !== "assertionMethod" || proof.proofValue == null || proof.created == null) return null;
711
537
  const publicKeyPromise = fetchKey(proof.verificationMethodId, Multikey, options);
712
- const proofConfig = {
538
+ const proofCanon = serialize({
713
539
  "@context": jsonLd["@context"],
714
540
  type: "DataIntegrityProof",
715
541
  cryptosuite: proof.cryptosuite,
716
542
  verificationMethod: proof.verificationMethodId.href,
717
543
  proofPurpose: proof.proofPurpose,
718
544
  created: proof.created.toString()
719
- };
545
+ });
720
546
  const encoder = new TextEncoder();
721
- const proofBytes = encoder.encode(serialize(proofConfig));
547
+ const proofBytes = encoder.encode(proofCanon);
722
548
  const proofDigest = await crypto.subtle.digest("SHA-256", proofBytes);
723
549
  const msg = { ...jsonLd };
724
550
  if ("proof" in msg) delete msg.proof;
725
- if ("https://w3id.org/security#proof" in msg) delete msg["https://w3id.org/security#proof"];
726
- const candidates = [msg];
727
- const normalized = await normalizePublicAudience(msg, options.contextLoader);
728
- if (normalized !== msg) candidates.push(normalized);
551
+ const msgCanon = serialize(msg);
552
+ const msgBytes = encoder.encode(msgCanon);
553
+ const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
554
+ const digest = new Uint8Array(proofDigest.byteLength + msgDigest.byteLength);
555
+ digest.set(new Uint8Array(proofDigest), 0);
556
+ digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
729
557
  let fetchedKey;
730
558
  try {
731
559
  fetchedKey = await publicKeyPromise;
@@ -754,7 +582,7 @@ async function verifyProofInternal(jsonLd, proof, options) {
754
582
  return await verifyProof(jsonLd, proof, {
755
583
  ...options,
756
584
  keyCache: {
757
- get: () => Promise.resolve(void 0),
585
+ get: () => Promise.resolve(null),
758
586
  set: async (keyId, key) => await options.keyCache?.set(keyId, key)
759
587
  }
760
588
  });
@@ -765,32 +593,27 @@ async function verifyProofInternal(jsonLd, proof, options) {
765
593
  });
766
594
  return null;
767
595
  }
768
- const digest = new Uint8Array(proofDigest.byteLength + 32);
769
- digest.set(new Uint8Array(proofDigest), 0);
770
- for (const candidate of candidates) {
771
- const msgBytes = encoder.encode(serialize(candidate));
772
- const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
773
- digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
774
- if (await crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest)) return publicKey;
775
- }
776
- if (fetchedKey.cached) {
777
- logger.debug("Failed to verify the proof with the cached key {keyId}; retrying with the freshly fetched key...", {
596
+ if (!await crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest)) {
597
+ if (fetchedKey.cached) {
598
+ logger.debug("Failed to verify the proof with the cached key {keyId}; retrying with the freshly fetched key...", {
599
+ keyId: proof.verificationMethodId.href,
600
+ proof
601
+ });
602
+ return await verifyProof(jsonLd, proof, {
603
+ ...options,
604
+ keyCache: {
605
+ get: () => Promise.resolve(void 0),
606
+ set: async (keyId, key) => await options.keyCache?.set(keyId, key)
607
+ }
608
+ });
609
+ }
610
+ logger.debug("Failed to verify the proof with the fetched key {keyId}:\n{proof}", {
778
611
  keyId: proof.verificationMethodId.href,
779
612
  proof
780
613
  });
781
- return await verifyProof(jsonLd, proof, {
782
- ...options,
783
- keyCache: {
784
- get: () => Promise.resolve(void 0),
785
- set: async (keyId, key) => await options.keyCache?.set(keyId, key)
786
- }
787
- });
614
+ return null;
788
615
  }
789
- logger.debug("Failed to verify the proof with the fetched key {keyId}:\n{proof}", {
790
- keyId: proof.verificationMethodId.href,
791
- proof
792
- });
793
- return null;
616
+ return publicKey;
794
617
  }
795
618
  /**
796
619
  * Verifies the given object. It will verify all the proofs in the object,
@@ -831,4 +654,4 @@ async function verifyObject(cls, jsonLd, options = {}) {
831
654
  return object;
832
655
  }
833
656
  //#endregion
834
- export { verifyProof as a, getKeyOwner as c, detachSignature as d, hasSignatureLike as f, verifySignature as h, verifyObject as i, attachSignature as l, verifyJsonLd as m, hasProofLike as n, normalizePublicAudience as o, signJsonLd as p, signObject as r, doesActorOwnKey as s, createProof as t, createSignature as u };
657
+ export { verifyProof as a, attachSignature as c, hasSignatureLike as d, signJsonLd as f, verifyObject as i, createSignature as l, verifySignature as m, hasProofLike as n, doesActorOwnKey as o, verifyJsonLd as p, signObject as r, getKeyOwner as s, createProof as t, detachSignature as u };
@@ -1,8 +1,8 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Bg4eBr2D.mjs";
5
- import { n as doubleKnock } from "./http-DWkREdt7.mjs";
4
+ import { n as version, t as name } from "./deno-_fgAC2zJ.mjs";
5
+ import { n as doubleKnock } from "./http-C8rif6ld.mjs";
6
6
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  //#region src/federation/send.ts
@@ -7,8 +7,8 @@ import { a as assertExists, t as assertStringIncludes } from "../std__assert-Dui
7
7
  import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
8
8
  import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
9
9
  import { t as assert } from "../assert-ddO5KLpe.mjs";
10
- import { t as exportJwk } from "../key-DkuUQiqs.mjs";
11
- import { a as parseRfc9421Signature, c as timingSafeEqual, i as formatRfc9421SignatureParameters, l as verifyRequest, n as doubleKnock, o as parseRfc9421SignatureInput, r as formatRfc9421Signature, s as signRequest, t as createRfc9421SignatureBase, u as verifyRequestDetailed } from "../http-DWkREdt7.mjs";
10
+ import { t as exportJwk } from "../key-Ce0SDXK2.mjs";
11
+ import { a as parseRfc9421Signature, c as timingSafeEqual, i as formatRfc9421SignatureParameters, l as verifyRequest, n as doubleKnock, o as parseRfc9421SignatureInput, r as formatRfc9421Signature, s as signRequest, t as createRfc9421SignatureBase, u as verifyRequestDetailed } from "../http-C8rif6ld.mjs";
12
12
  import { i as rsaPrivateKey2, l as rsaPublicKey5, o as rsaPublicKey1, s as rsaPublicKey2 } from "../keys-BAK-tUlf.mjs";
13
13
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
14
14
  import { FetchError, exportSpki } from "@fedify/vocab-runtime";
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
5
  import "../std__assert-Duiq_YC9.mjs";
6
6
  import { t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
7
7
  import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
8
- import { a as importJwk, i as generateCryptoKeyPair, n as fetchKey, o as validateCryptoKey, r as fetchKeyDetailed, t as exportJwk } from "../key-DkuUQiqs.mjs";
8
+ import { a as importJwk, i as generateCryptoKeyPair, n as fetchKey, o as validateCryptoKey, r as fetchKeyDetailed, t as exportJwk } from "../key-Ce0SDXK2.mjs";
9
9
  import { c as rsaPublicKey3, i as rsaPrivateKey2, o as rsaPublicKey1, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-BAK-tUlf.mjs";
10
10
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
11
11
  import { CryptographicKey, Multikey } from "@fedify/vocab";
@@ -5,9 +5,9 @@ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
5
  import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
6
6
  import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
7
7
  import { t as assert } from "../assert-ddO5KLpe.mjs";
8
- import { i as generateCryptoKeyPair } from "../key-DkuUQiqs.mjs";
8
+ import { i as generateCryptoKeyPair } from "../key-Ce0SDXK2.mjs";
9
9
  import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-BAK-tUlf.mjs";
10
- import { a as signJsonLd, i as hasSignatureLike, n as createSignature, o as verifyJsonLd, r as detachSignature, s as verifySignature, t as attachSignature } from "../ld-1klZemqw.mjs";
10
+ import { a as signJsonLd, i as hasSignatureLike, n as createSignature, o as verifyJsonLd, r as detachSignature, s as verifySignature, t as attachSignature } from "../ld-BsDP9tTM.mjs";
11
11
  import { mockDocumentLoader, test } from "@fedify/fixture";
12
12
  import { CryptographicKey } from "@fedify/vocab";
13
13
  import { encodeBase64 } from "byte-encodings/base64";
package/dist/sig/mod.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- const require_http = require("../http-Dgit35mk.cjs");
5
- const require_proof = require("../proof-CP0GRqWY.cjs");
4
+ const require_http = require("../http-R-epZzZQ.cjs");
5
+ const require_proof = require("../proof-3RPJLWOU.cjs");
6
6
  exports.attachSignature = require_proof.attachSignature;
7
7
  exports.createProof = require_proof.createProof;
8
8
  exports.createSignature = require_proof.createSignature;
package/dist/sig/mod.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
- import { a as verifyRequestDetailed, c as fetchKeyDetailed, f as formatAcceptSignature, h as validateAcceptSignature, i as verifyRequest, l as generateCryptoKeyPair, m as parseAcceptSignature, o as exportJwk, p as fulfillAcceptSignature, r as signRequest, s as fetchKey, u as importJwk } from "../http-Cbg9qm41.js";
4
- import { a as verifyProof, c as getKeyOwner, d as detachSignature, f as hasSignatureLike, h as verifySignature, i as verifyObject, l as attachSignature, m as verifyJsonLd, n as hasProofLike, p as signJsonLd, r as signObject, s as doesActorOwnKey, t as createProof, u as createSignature } from "../proof-CQJHVvjQ.js";
3
+ import { a as verifyRequestDetailed, c as fetchKeyDetailed, f as formatAcceptSignature, h as validateAcceptSignature, i as verifyRequest, l as generateCryptoKeyPair, m as parseAcceptSignature, o as exportJwk, p as fulfillAcceptSignature, r as signRequest, s as fetchKey, u as importJwk } from "../http-s3HaFg5o.js";
4
+ import { a as verifyProof, c as attachSignature, d as hasSignatureLike, f as signJsonLd, i as verifyObject, l as createSignature, m as verifySignature, n as hasProofLike, o as doesActorOwnKey, p as verifyJsonLd, r as signObject, s as getKeyOwner, t as createProof, u as detachSignature } from "../proof-qQIVjzlw.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, verifyProof, verifyRequest, verifyRequestDetailed, verifySignature };
@@ -6,7 +6,7 @@ import "../std__assert-Duiq_YC9.mjs";
6
6
  import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
7
7
  import { t as assert } from "../assert-ddO5KLpe.mjs";
8
8
  import { o as rsaPublicKey1, s as rsaPublicKey2 } from "../keys-BAK-tUlf.mjs";
9
- import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-ijaWLw_K.mjs";
9
+ import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-CTfDotXM.mjs";
10
10
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
11
11
  import { Create, CryptographicKey, lookupObject } from "@fedify/vocab";
12
12
  //#region src/sig/owner.test.ts
@@ -7,10 +7,9 @@ import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z
7
7
  import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
8
8
  import { t as assert } from "../assert-ddO5KLpe.mjs";
9
9
  import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-BAK-tUlf.mjs";
10
- import { t as normalizePublicAudience } from "../public-audience-eovWqzOF.mjs";
11
- import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-BbfBQytm.mjs";
10
+ import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-UdlPVu_P.mjs";
12
11
  import { mockDocumentLoader, test } from "@fedify/fixture";
13
- import { Create, DataIntegrityProof, Multikey, Note, PUBLIC_COLLECTION, Place } from "@fedify/vocab";
12
+ import { Create, DataIntegrityProof, Multikey, Note, Place } from "@fedify/vocab";
14
13
  import { decodeMultibase, importMultibaseKey } from "@fedify/vocab-runtime";
15
14
  import { decodeHex } from "byte-encodings/hex";
16
15
  //#region src/sig/proof.test.ts
@@ -152,39 +151,6 @@ test("signObject()", async () => {
152
151
  created,
153
152
  contextLoader: mockDocumentLoader
154
153
  }), TypeError, "Unsupported algorithm");
155
- const signed = await signObject(new Create({
156
- id: new URL("https://server.example/activities/2"),
157
- actor: new URL("https://server.example/users/alice"),
158
- object: new Note({
159
- id: new URL("https://server.example/objects/2"),
160
- attribution: new URL("https://server.example/users/alice"),
161
- content: "Hello public"
162
- }),
163
- tos: [PUBLIC_COLLECTION]
164
- }), fep8b32TestVectorPrivateKey, fep8b32TestVectorKeyId, {
165
- ...options,
166
- created
167
- });
168
- const [proof] = await Array.fromAsync(signed.getProofs(options));
169
- assertInstanceOf(proof, DataIntegrityProof);
170
- const signedJson = await normalizePublicAudience(await signed.toJsonLd(options), mockDocumentLoader);
171
- assertEquals(signedJson.to, PUBLIC_COLLECTION.href);
172
- const verifyCache = {};
173
- const verifyOptions = {
174
- contextLoader: mockDocumentLoader,
175
- documentLoader: mockDocumentLoader,
176
- keyCache: {
177
- get: (keyId) => Promise.resolve(verifyCache[keyId.href]),
178
- set: (keyId, key) => {
179
- verifyCache[keyId.href] = key;
180
- return Promise.resolve();
181
- }
182
- }
183
- };
184
- assertInstanceOf(await verifyProof(signedJson, proof, verifyOptions), Multikey);
185
- const signedJsonWithCurie = await signed.toJsonLd(options);
186
- assertEquals(signedJsonWithCurie.to, "as:Public");
187
- assertInstanceOf(await verifyProof(signedJsonWithCurie, proof, verifyOptions), Multikey);
188
154
  });
189
155
  test("hasProofLike()", () => {
190
156
  assert(hasProofLike({ proof: {
@@ -286,30 +252,6 @@ test("verifyProof()", async () => {
286
252
  }
287
253
  }, proof, options), null);
288
254
  assertEquals(await verifyProof(jsonLd, proof.clone({ created: Temporal.Now.instant() }), options), null);
289
- assertEquals(await verifyProof({
290
- ...jsonLd,
291
- "https://w3id.org/security#proof": {
292
- "@type": ["https://w3id.org/security#DataIntegrityProof"],
293
- "https://w3id.org/security#proofValue": [{ "@value": "stale" }]
294
- }
295
- }, proof, options), expectedKey);
296
- assertEquals(await verifyProof([jsonLd], proof, options), null);
297
- assertEquals(await verifyProof({
298
- "@context": ["https://www.w3.org/ns/activitystreams", "https://attacker.example/ctx"],
299
- id: "https://server.example/activities/attacker",
300
- type: "Create",
301
- actor: "https://server.example/users/alice",
302
- object: {
303
- id: "https://server.example/objects/attacker",
304
- type: "Note",
305
- attributedTo: "https://server.example/users/alice",
306
- content: "n/a",
307
- to: "as:Public"
308
- }
309
- }, proof, {
310
- documentLoader: mockDocumentLoader,
311
- keyCache: options.keyCache
312
- }), null);
313
255
  });
314
256
  test("verifyObject()", async () => {
315
257
  const options = {
@@ -5,9 +5,9 @@ import { t as esm_default } from "../esm-DVILvP5e.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
6
6
  import "../std__assert-Duiq_YC9.mjs";
7
7
  import { t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
8
- import { l as verifyRequest } from "../http-DWkREdt7.mjs";
8
+ import { l as verifyRequest } from "../http-C8rif6ld.mjs";
9
9
  import { i as rsaPrivateKey2 } from "../keys-BAK-tUlf.mjs";
10
- import { t as getAuthenticatedDocumentLoader } from "../docloader-DNzzLpZS.mjs";
10
+ import { t as getAuthenticatedDocumentLoader } from "../docloader-vRYuv1jI.mjs";
11
11
  import { mockDocumentLoader, test } from "@fedify/fixture";
12
12
  import { UrlError } from "@fedify/vocab-runtime";
13
13
  //#region src/utils/docloader.test.ts
@@ -1,6 +1,6 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- const require_kv_cache = require("../kv-cache-e9fvIFDA.cjs");
4
+ const require_kv_cache = require("../kv-cache-Btpmwlb5.cjs");
5
5
  exports.getAuthenticatedDocumentLoader = require_kv_cache.getAuthenticatedDocumentLoader;
6
6
  exports.kvCache = require_kv_cache.kvCache;
package/dist/utils/mod.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-Bl6yhpBL.js";
3
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-ChSAw77q.js";
4
4
  export { getAuthenticatedDocumentLoader, kvCache };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/fedify",
3
- "version": "2.2.0-pr.710.26+a95be522",
3
+ "version": "2.2.0-pr.715.27+c922f396",
4
4
  "description": "An ActivityPub server framework",
5
5
  "keywords": [
6
6
  "ActivityPub",
@@ -153,9 +153,9 @@
153
153
  "uri-template-router": "^1.0.0",
154
154
  "url-template": "^3.1.1",
155
155
  "urlpattern-polyfill": "^10.1.0",
156
- "@fedify/vocab-runtime": "2.2.0-pr.710.26+a95be522",
157
- "@fedify/webfinger": "2.2.0-pr.710.26+a95be522",
158
- "@fedify/vocab": "2.2.0-pr.710.26+a95be522"
156
+ "@fedify/vocab": "2.2.0-pr.715.27+c922f396",
157
+ "@fedify/vocab-runtime": "2.2.0-pr.715.27+c922f396",
158
+ "@fedify/webfinger": "2.2.0-pr.715.27+c922f396"
159
159
  },
160
160
  "devDependencies": {
161
161
  "@std/assert": "npm:@jsr/std__assert@^0.226.0",
@@ -167,8 +167,8 @@
167
167
  "tsx": "^4.19.4",
168
168
  "typescript": "^5.9.2",
169
169
  "wrangler": "^4.17.0",
170
- "@fedify/vocab-tools": "^2.2.0-pr.710.26+a95be522",
171
- "@fedify/fixture": "2.0.0"
170
+ "@fedify/fixture": "2.0.0",
171
+ "@fedify/vocab-tools": "^2.2.0-pr.715.27+c922f396"
172
172
  },
173
173
  "scripts": {
174
174
  "build:self": "tsdown",
@@ -1,2 +0,0 @@
1
- import { Temporal } from "@js-temporal/polyfill";
2
- import { URLPattern } from "urlpattern-polyfill";