@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,7 +1,7 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  const require_chunk = require("./chunk-DDcVe30Y.cjs");
4
- const require_http = require("./http-Dgit35mk.cjs");
4
+ const require_http = require("./http-R-epZzZQ.cjs");
5
5
  let _logtape_logtape = require("@logtape/logtape");
6
6
  let _fedify_vocab = require("@fedify/vocab");
7
7
  let _opentelemetry_api = require("@opentelemetry/api");
@@ -13,7 +13,7 @@ _fedify_vocab_runtime_jsonld = require_chunk.__toESM(_fedify_vocab_runtime_jsonl
13
13
  let json_canon = require("json-canon");
14
14
  json_canon = require_chunk.__toESM(json_canon);
15
15
  //#region src/sig/ld.ts
16
- const logger$2 = (0, _logtape_logtape.getLogger)([
16
+ const logger$1 = (0, _logtape_logtape.getLogger)([
17
17
  "fedify",
18
18
  "sig",
19
19
  "ld"
@@ -161,7 +161,7 @@ async function verifySignature(jsonLd, options = {}) {
161
161
  try {
162
162
  signature = (0, byte_encodings_base64.decodeBase64)(sig.signatureValue);
163
163
  } catch (error) {
164
- logger$2.debug("Failed to verify; invalid base64 signatureValue: {signatureValue}", {
164
+ logger$1.debug("Failed to verify; invalid base64 signatureValue: {signatureValue}", {
165
165
  ...sig,
166
166
  error
167
167
  });
@@ -180,7 +180,7 @@ async function verifySignature(jsonLd, options = {}) {
180
180
  try {
181
181
  sigOptsHash = await hashJsonLd(sigOpts, options.contextLoader);
182
182
  } catch (error) {
183
- logger$2.warn("Failed to verify; failed to hash the signature options: {signatureOptions}\n{error}", {
183
+ logger$1.warn("Failed to verify; failed to hash the signature options: {signatureOptions}\n{error}", {
184
184
  signatureOptions: sigOpts,
185
185
  error
186
186
  });
@@ -192,7 +192,7 @@ async function verifySignature(jsonLd, options = {}) {
192
192
  try {
193
193
  docHash = await hashJsonLd(document, options.contextLoader);
194
194
  } catch (error) {
195
- logger$2.warn("Failed to verify; failed to hash the document: {document}\n{error}", {
195
+ logger$1.warn("Failed to verify; failed to hash the document: {document}\n{error}", {
196
196
  document,
197
197
  error
198
198
  });
@@ -203,7 +203,7 @@ async function verifySignature(jsonLd, options = {}) {
203
203
  const messageBytes = encoder.encode(message);
204
204
  if (await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes)) return key;
205
205
  if (cached) {
206
- logger$2.debug("Failed to verify with the cached key {keyId}; signature {signatureValue} is invalid. Retrying with the freshly fetched key...", {
206
+ logger$1.debug("Failed to verify with the cached key {keyId}; signature {signatureValue} is invalid. Retrying with the freshly fetched key...", {
207
207
  keyId: sig.creator,
208
208
  ...sig
209
209
  });
@@ -217,7 +217,7 @@ async function verifySignature(jsonLd, options = {}) {
217
217
  if (key == null) return null;
218
218
  return await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes) ? key : null;
219
219
  }
220
- 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}", {
220
+ 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}", {
221
221
  keyId: sig.creator,
222
222
  ...sig,
223
223
  message
@@ -249,12 +249,12 @@ async function verifyJsonLd(jsonLd, options = {}) {
249
249
  const key = await verifySignature(jsonLd, options);
250
250
  if (key == null) return false;
251
251
  if (key.ownerId == null) {
252
- logger$2.debug("Key {keyId} has no owner.", { keyId: key.id?.href });
252
+ logger$1.debug("Key {keyId} has no owner.", { keyId: key.id?.href });
253
253
  return false;
254
254
  }
255
255
  attributions.delete(key.ownerId.href);
256
256
  if (attributions.size > 0) {
257
- logger$2.debug("Some attributions are not authenticated by the Linked Data Signatures: {attributions}.", { attributions: [...attributions] });
257
+ logger$1.debug("Some attributions are not authenticated by the Linked Data Signatures: {attributions}.", { attributions: [...attributions] });
258
258
  return false;
259
259
  }
260
260
  return true;
@@ -389,179 +389,6 @@ async function getKeyOwner(keyId, options) {
389
389
  return null;
390
390
  }
391
391
  //#endregion
392
- //#region src/compat/public-audience.ts
393
- const logger$1 = (0, _logtape_logtape.getLogger)([
394
- "fedify",
395
- "compat",
396
- "public-audience"
397
- ]);
398
- const PUBLIC_ADDRESSING_FIELDS = new Set([
399
- "to",
400
- "cc",
401
- "bto",
402
- "bcc",
403
- "audience"
404
- ]);
405
- const preloadedOnlyDocumentLoader = (url) => {
406
- if (Object.hasOwn(_fedify_vocab_runtime.preloadedContexts, url)) return Promise.resolve({
407
- contextUrl: null,
408
- documentUrl: url,
409
- document: _fedify_vocab_runtime.preloadedContexts[url]
410
- });
411
- return Promise.reject(/* @__PURE__ */ new Error("Refusing to fetch a non-preloaded JSON-LD context: " + url));
412
- };
413
- const AS_CONTEXT_URL = "https://www.w3.org/ns/activitystreams";
414
- const MAX_TRAVERSAL_DEPTH = 64;
415
- const KNOWN_SAFE_CONTEXT_URLS = new Set(Object.keys(_fedify_vocab_runtime.preloadedContexts));
416
- function hasPublicCurieInAddressing(value, parentKey, depth = 0) {
417
- if (typeof value === "string") return parentKey != null && PUBLIC_ADDRESSING_FIELDS.has(parentKey) && (value === "as:Public" || value === "Public");
418
- if (depth >= MAX_TRAVERSAL_DEPTH) return false;
419
- if (Array.isArray(value)) return value.some((item) => hasPublicCurieInAddressing(item, parentKey, depth + 1));
420
- if (typeof value !== "object" || value == null) return false;
421
- const record = value;
422
- for (const key of Object.keys(record)) {
423
- if (key === "@context") continue;
424
- if (hasPublicCurieInAddressing(record[key], key, depth + 1)) return true;
425
- }
426
- return false;
427
- }
428
- function rewritePublicAudience(value, parentKey, depth = 0) {
429
- if (typeof value === "string" && parentKey != null && PUBLIC_ADDRESSING_FIELDS.has(parentKey) && (value === "as:Public" || value === "Public")) return _fedify_vocab.PUBLIC_COLLECTION.href;
430
- if (depth >= MAX_TRAVERSAL_DEPTH) return value;
431
- if (Array.isArray(value)) {
432
- let changed = false;
433
- const mapped = value.map((item) => {
434
- const rewritten = rewritePublicAudience(item, parentKey, depth + 1);
435
- if (rewritten !== item) changed = true;
436
- return rewritten;
437
- });
438
- return changed ? mapped : value;
439
- }
440
- if (typeof value !== "object" || value == null) return value;
441
- const record = value;
442
- let changed = false;
443
- const normalized = Object.create(null);
444
- for (const key of Object.keys(record)) {
445
- const rewritten = key === "@context" ? record[key] : rewritePublicAudience(record[key], key, depth + 1);
446
- if (rewritten !== record[key]) changed = true;
447
- normalized[key] = rewritten;
448
- }
449
- return changed ? normalized : value;
450
- }
451
- /**
452
- * Reports whether `value` carries an `@context` property anywhere inside
453
- * its subtree (not counting the value itself). A nested `@context` can
454
- * introduce a local term-definition scope that redefines `as:` or `Public`
455
- * even when the top-level `@context` is safe, so the fast path must defer
456
- * to the URDNA2015 equivalence check whenever one is present.
457
- */
458
- function hasNestedContext(value, depth = 0) {
459
- if (depth >= MAX_TRAVERSAL_DEPTH) return true;
460
- if (Array.isArray(value)) return value.some((item) => hasNestedContext(item, depth + 1));
461
- if (typeof value !== "object" || value == null) return false;
462
- const record = value;
463
- for (const key of Object.keys(record)) {
464
- if (key === "@context") return true;
465
- if (hasNestedContext(record[key], depth + 1)) return true;
466
- }
467
- return false;
468
- }
469
- /**
470
- * Checks whether the `@context` of a JSON-LD document is guaranteed not
471
- * to redefine the `as:` prefix or the bare `Public` term. Only documents
472
- * whose `@context` is a string, or an array of strings, drawn from Fedify's
473
- * preloaded context set AND including the ActivityStreams URL qualify,
474
- * AND no nested subtree carries its own `@context` that might redefine
475
- * those terms within a local scope. When all of that holds the rewrite
476
- * is provably semantics-preserving and the URDNA2015 equivalence check
477
- * can be skipped. Any other shape (unknown external URLs, inline
478
- * objects at the top level, nested `@context` blocks) is treated as
479
- * potentially unsafe.
480
- */
481
- function hasKnownSafeContext(jsonLd) {
482
- if (typeof jsonLd !== "object" || jsonLd == null) return false;
483
- const record = jsonLd;
484
- if (!Object.hasOwn(record, "@context")) return false;
485
- const ctx = record["@context"];
486
- const entries = typeof ctx === "string" ? [ctx] : Array.isArray(ctx) ? ctx : null;
487
- if (entries == null || entries.length === 0) return false;
488
- let hasAs = false;
489
- for (const entry of entries) {
490
- if (typeof entry !== "string") return false;
491
- if (!KNOWN_SAFE_CONTEXT_URLS.has(entry)) return false;
492
- if (entry === AS_CONTEXT_URL) hasAs = true;
493
- }
494
- if (!hasAs) return false;
495
- for (const key of Object.keys(record)) {
496
- if (key === "@context") continue;
497
- if (hasNestedContext(record[key])) return false;
498
- }
499
- return true;
500
- }
501
- /**
502
- * Rewrites the compact `as:Public` / `Public` CURIE appearing in activity
503
- * addressing fields (`to`, `cc`, `bto`, `bcc`, `audience`) to the fully
504
- * expanded `https://www.w3.org/ns/activitystreams#Public` URI.
505
- *
506
- * Several ActivityPub implementations, Lemmy among them, match these
507
- * fields as plain URLs without running JSON-LD expansion, and silently
508
- * drop activities whose public addressing appears in CURIE form. This
509
- * helper works around that gap.
510
- *
511
- * For documents whose `@context` is drawn entirely from Fedify's
512
- * preloaded context set and includes the ActivityStreams URL, the
513
- * rewrite is applied directly: the content of every preloaded non-AS
514
- * context is known not to redefine the `as:` prefix or the bare `Public`
515
- * term, so the semantics are preserved by construction. Any other
516
- * shape (an inline object, an unknown external URL, and so on) is
517
- * treated as potentially unsafe and gated on a JSON-LD equivalence
518
- * check; both forms are canonicalized with URDNA2015 and the resulting
519
- * N-Quads are compared. When they differ, the original document is
520
- * returned unchanged. Canonicalization failures also fall back to the
521
- * original document.
522
- *
523
- * When no `contextLoader` is supplied the helper falls back to an
524
- * internal loader that resolves only the URLs in Fedify's
525
- * preloaded-contexts set and rejects every other URL without issuing a
526
- * network request. That behaviour is deliberately narrower than
527
- * `@fedify/vocab-runtime`'s `getDocumentLoader()`, which after its
528
- * `validatePublicUrl` check will happily fetch non-preloaded URLs: the
529
- * helper is reached from verification paths (`verifyProof()` /
530
- * `verifyObject()`) that operate on inbound, potentially adversarial
531
- * JSON-LD, and a default loader that fetches attacker-supplied
532
- * `@context` URLs on the caller's behalf would be an SSRF vector.
533
- * Canonicalization failures against the restricted loader fall back to
534
- * the original document, same as any other canonicalization error.
535
- * Callers that genuinely need the remote-fetch loader (for example
536
- * applications that sign local JSON-LD against a custom vocabulary)
537
- * should pass a `contextLoader` explicitly.
538
- *
539
- * Must be called before any signing step that canonicalizes the
540
- * compact form byte-for-byte (for example, Object Integrity Proofs
541
- * using the `eddsa-jcs-2022` cryptosuite), so the signed payload
542
- * matches what is sent on the wire.
543
- */
544
- async function normalizePublicAudience(jsonLd, contextLoader) {
545
- if (!hasPublicCurieInAddressing(jsonLd)) return jsonLd;
546
- const normalized = rewritePublicAudience(jsonLd);
547
- if (hasKnownSafeContext(jsonLd)) return normalized;
548
- const loader = contextLoader ?? preloadedOnlyDocumentLoader;
549
- try {
550
- const [before, after] = await Promise.all([_fedify_vocab_runtime_jsonld.default.canonize(jsonLd, {
551
- format: "application/n-quads",
552
- documentLoader: loader
553
- }), _fedify_vocab_runtime_jsonld.default.canonize(normalized, {
554
- format: "application/n-quads",
555
- documentLoader: loader
556
- })]);
557
- if (before === after) return normalized;
558
- 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.");
559
- } catch (error) {
560
- logger$1.debug("Failed to verify public audience normalization equivalence via JSON-LD canonicalization; sending the activity as is.\n{error}", { error });
561
- }
562
- return jsonLd;
563
- }
564
- //#endregion
565
392
  //#region src/sig/proof.ts
566
393
  const logger = (0, _logtape_logtape.getLogger)([
567
394
  "fedify",
@@ -610,12 +437,11 @@ function hasProofLike(jsonLd) {
610
437
  async function createProof(object, privateKey, keyId, { contextLoader, context, created } = {}) {
611
438
  require_http.validateCryptoKey(privateKey, "private");
612
439
  if (privateKey.algorithm.name !== "Ed25519") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
613
- let compactMsg = await object.clone({ proofs: [] }).toJsonLd({
440
+ const compactMsg = await object.clone({ proofs: [] }).toJsonLd({
614
441
  format: "compact",
615
442
  contextLoader,
616
443
  context
617
444
  });
618
- compactMsg = await normalizePublicAudience(compactMsg, contextLoader);
619
445
  const msgCanon = (0, json_canon.default)(compactMsg);
620
446
  const encoder = new TextEncoder();
621
447
  const msgBytes = encoder.encode(msgCanon);
@@ -710,25 +536,27 @@ async function verifyProof(jsonLd, proof, options = {}) {
710
536
  });
711
537
  }
712
538
  async function verifyProofInternal(jsonLd, proof, options) {
713
- 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;
539
+ if (typeof jsonLd !== "object" || proof.cryptosuite !== "eddsa-jcs-2022" || proof.verificationMethodId == null || proof.proofPurpose !== "assertionMethod" || proof.proofValue == null || proof.created == null) return null;
714
540
  const publicKeyPromise = require_http.fetchKey(proof.verificationMethodId, _fedify_vocab.Multikey, options);
715
- const proofConfig = {
541
+ const proofCanon = (0, json_canon.default)({
716
542
  "@context": jsonLd["@context"],
717
543
  type: "DataIntegrityProof",
718
544
  cryptosuite: proof.cryptosuite,
719
545
  verificationMethod: proof.verificationMethodId.href,
720
546
  proofPurpose: proof.proofPurpose,
721
547
  created: proof.created.toString()
722
- };
548
+ });
723
549
  const encoder = new TextEncoder();
724
- const proofBytes = encoder.encode((0, json_canon.default)(proofConfig));
550
+ const proofBytes = encoder.encode(proofCanon);
725
551
  const proofDigest = await crypto.subtle.digest("SHA-256", proofBytes);
726
552
  const msg = { ...jsonLd };
727
553
  if ("proof" in msg) delete msg.proof;
728
- if ("https://w3id.org/security#proof" in msg) delete msg["https://w3id.org/security#proof"];
729
- const candidates = [msg];
730
- const normalized = await normalizePublicAudience(msg, options.contextLoader);
731
- if (normalized !== msg) candidates.push(normalized);
554
+ const msgCanon = (0, json_canon.default)(msg);
555
+ const msgBytes = encoder.encode(msgCanon);
556
+ const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
557
+ const digest = new Uint8Array(proofDigest.byteLength + msgDigest.byteLength);
558
+ digest.set(new Uint8Array(proofDigest), 0);
559
+ digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
732
560
  let fetchedKey;
733
561
  try {
734
562
  fetchedKey = await publicKeyPromise;
@@ -757,7 +585,7 @@ async function verifyProofInternal(jsonLd, proof, options) {
757
585
  return await verifyProof(jsonLd, proof, {
758
586
  ...options,
759
587
  keyCache: {
760
- get: () => Promise.resolve(void 0),
588
+ get: () => Promise.resolve(null),
761
589
  set: async (keyId, key) => await options.keyCache?.set(keyId, key)
762
590
  }
763
591
  });
@@ -768,32 +596,27 @@ async function verifyProofInternal(jsonLd, proof, options) {
768
596
  });
769
597
  return null;
770
598
  }
771
- const digest = new Uint8Array(proofDigest.byteLength + 32);
772
- digest.set(new Uint8Array(proofDigest), 0);
773
- for (const candidate of candidates) {
774
- const msgBytes = encoder.encode((0, json_canon.default)(candidate));
775
- const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
776
- digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
777
- if (await crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest)) return publicKey;
778
- }
779
- if (fetchedKey.cached) {
780
- logger.debug("Failed to verify the proof with the cached key {keyId}; retrying with the freshly fetched key...", {
599
+ if (!await crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest)) {
600
+ if (fetchedKey.cached) {
601
+ logger.debug("Failed to verify the proof with the cached key {keyId}; retrying with the freshly fetched key...", {
602
+ keyId: proof.verificationMethodId.href,
603
+ proof
604
+ });
605
+ return await verifyProof(jsonLd, proof, {
606
+ ...options,
607
+ keyCache: {
608
+ get: () => Promise.resolve(void 0),
609
+ set: async (keyId, key) => await options.keyCache?.set(keyId, key)
610
+ }
611
+ });
612
+ }
613
+ logger.debug("Failed to verify the proof with the fetched key {keyId}:\n{proof}", {
781
614
  keyId: proof.verificationMethodId.href,
782
615
  proof
783
616
  });
784
- return await verifyProof(jsonLd, proof, {
785
- ...options,
786
- keyCache: {
787
- get: () => Promise.resolve(void 0),
788
- set: async (keyId, key) => await options.keyCache?.set(keyId, key)
789
- }
790
- });
617
+ return null;
791
618
  }
792
- logger.debug("Failed to verify the proof with the fetched key {keyId}:\n{proof}", {
793
- keyId: proof.verificationMethodId.href,
794
- proof
795
- });
796
- return null;
619
+ return publicKey;
797
620
  }
798
621
  /**
799
622
  * Verifies the given object. It will verify all the proofs in the object,
@@ -882,12 +705,6 @@ Object.defineProperty(exports, "hasSignatureLike", {
882
705
  return hasSignatureLike;
883
706
  }
884
707
  });
885
- Object.defineProperty(exports, "normalizePublicAudience", {
886
- enumerable: true,
887
- get: function() {
888
- return normalizePublicAudience;
889
- }
890
- });
891
708
  Object.defineProperty(exports, "signJsonLd", {
892
709
  enumerable: true,
893
710
  get: function() {
@@ -1,9 +1,8 @@
1
1
  import { Temporal } from "@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 fetchKey, o as validateCryptoKey } from "./key-DkuUQiqs.mjs";
6
- import { t as normalizePublicAudience } from "./public-audience-eovWqzOF.mjs";
4
+ import { n as version, t as name } from "./deno-_fgAC2zJ.mjs";
5
+ import { n as fetchKey, o as validateCryptoKey } from "./key-Ce0SDXK2.mjs";
7
6
  import { Activity, DataIntegrityProof, Multikey, getTypeId } from "@fedify/vocab";
8
7
  import { SpanStatusCode, trace } from "@opentelemetry/api";
9
8
  import { getLogger } from "@logtape/logtape";
@@ -57,12 +56,11 @@ function hasProofLike(jsonLd) {
57
56
  async function createProof(object, privateKey, keyId, { contextLoader, context, created } = {}) {
58
57
  validateCryptoKey(privateKey, "private");
59
58
  if (privateKey.algorithm.name !== "Ed25519") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
60
- let compactMsg = await object.clone({ proofs: [] }).toJsonLd({
59
+ const compactMsg = await object.clone({ proofs: [] }).toJsonLd({
61
60
  format: "compact",
62
61
  contextLoader,
63
62
  context
64
63
  });
65
- compactMsg = await normalizePublicAudience(compactMsg, contextLoader);
66
64
  const msgCanon = serialize(compactMsg);
67
65
  const encoder = new TextEncoder();
68
66
  const msgBytes = encoder.encode(msgCanon);
@@ -157,25 +155,27 @@ async function verifyProof(jsonLd, proof, options = {}) {
157
155
  });
158
156
  }
159
157
  async function verifyProofInternal(jsonLd, proof, options) {
160
- 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;
158
+ if (typeof jsonLd !== "object" || proof.cryptosuite !== "eddsa-jcs-2022" || proof.verificationMethodId == null || proof.proofPurpose !== "assertionMethod" || proof.proofValue == null || proof.created == null) return null;
161
159
  const publicKeyPromise = fetchKey(proof.verificationMethodId, Multikey, options);
162
- const proofConfig = {
160
+ const proofCanon = serialize({
163
161
  "@context": jsonLd["@context"],
164
162
  type: "DataIntegrityProof",
165
163
  cryptosuite: proof.cryptosuite,
166
164
  verificationMethod: proof.verificationMethodId.href,
167
165
  proofPurpose: proof.proofPurpose,
168
166
  created: proof.created.toString()
169
- };
167
+ });
170
168
  const encoder = new TextEncoder();
171
- const proofBytes = encoder.encode(serialize(proofConfig));
169
+ const proofBytes = encoder.encode(proofCanon);
172
170
  const proofDigest = await crypto.subtle.digest("SHA-256", proofBytes);
173
171
  const msg = { ...jsonLd };
174
172
  if ("proof" in msg) delete msg.proof;
175
- if ("https://w3id.org/security#proof" in msg) delete msg["https://w3id.org/security#proof"];
176
- const candidates = [msg];
177
- const normalized = await normalizePublicAudience(msg, options.contextLoader);
178
- if (normalized !== msg) candidates.push(normalized);
173
+ const msgCanon = serialize(msg);
174
+ const msgBytes = encoder.encode(msgCanon);
175
+ const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
176
+ const digest = new Uint8Array(proofDigest.byteLength + msgDigest.byteLength);
177
+ digest.set(new Uint8Array(proofDigest), 0);
178
+ digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
179
179
  let fetchedKey;
180
180
  try {
181
181
  fetchedKey = await publicKeyPromise;
@@ -204,7 +204,7 @@ async function verifyProofInternal(jsonLd, proof, options) {
204
204
  return await verifyProof(jsonLd, proof, {
205
205
  ...options,
206
206
  keyCache: {
207
- get: () => Promise.resolve(void 0),
207
+ get: () => Promise.resolve(null),
208
208
  set: async (keyId, key) => await options.keyCache?.set(keyId, key)
209
209
  }
210
210
  });
@@ -215,32 +215,27 @@ async function verifyProofInternal(jsonLd, proof, options) {
215
215
  });
216
216
  return null;
217
217
  }
218
- const digest = new Uint8Array(proofDigest.byteLength + 32);
219
- digest.set(new Uint8Array(proofDigest), 0);
220
- for (const candidate of candidates) {
221
- const msgBytes = encoder.encode(serialize(candidate));
222
- const msgDigest = await crypto.subtle.digest("SHA-256", msgBytes);
223
- digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
224
- if (await crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest)) return publicKey;
225
- }
226
- if (fetchedKey.cached) {
227
- logger.debug("Failed to verify the proof with the cached key {keyId}; retrying with the freshly fetched key...", {
218
+ if (!await crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest)) {
219
+ if (fetchedKey.cached) {
220
+ logger.debug("Failed to verify the proof with the cached key {keyId}; retrying with the freshly fetched key...", {
221
+ keyId: proof.verificationMethodId.href,
222
+ proof
223
+ });
224
+ return await verifyProof(jsonLd, proof, {
225
+ ...options,
226
+ keyCache: {
227
+ get: () => Promise.resolve(void 0),
228
+ set: async (keyId, key) => await options.keyCache?.set(keyId, key)
229
+ }
230
+ });
231
+ }
232
+ logger.debug("Failed to verify the proof with the fetched key {keyId}:\n{proof}", {
228
233
  keyId: proof.verificationMethodId.href,
229
234
  proof
230
235
  });
231
- return await verifyProof(jsonLd, proof, {
232
- ...options,
233
- keyCache: {
234
- get: () => Promise.resolve(void 0),
235
- set: async (keyId, key) => await options.keyCache?.set(keyId, key)
236
- }
237
- });
236
+ return null;
238
237
  }
239
- logger.debug("Failed to verify the proof with the fetched key {keyId}:\n{proof}", {
240
- keyId: proof.verificationMethodId.href,
241
- proof
242
- });
243
- return null;
238
+ return publicKey;
244
239
  }
245
240
  /**
246
241
  * Verifies the given object. It will verify all the proofs in the object,