@fedify/fedify 2.4.0-dev.2010 → 2.4.0-dev.2030

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 (100) hide show
  1. package/dist/{assert-CebeUf0C.mjs → assert-D1Eafmd_.mjs} +1 -1
  2. package/dist/{assert_equals-CBlRfA-_.mjs → assert_equals-Z6IcEbWU.mjs} +2 -28
  3. package/dist/{assert_exists-DtzkXC47.mjs → assert_exists-cffSpJ7X.mjs} +1 -1
  4. package/dist/{assert_false-3pLLLsO4.mjs → assert_false-CPdRnc3E.mjs} +1 -1
  5. package/dist/{assert_greater_or_equal-BApOTh1h.mjs → assert_greater_or_equal-BlafOF4-.mjs} +2 -1
  6. package/dist/{assert_instance_of-g3WcyYNR.mjs → assert_instance_of-mrXWWNY-.mjs} +1 -1
  7. package/dist/{assert_not_equals-BN7yDMWe.mjs → assert_not_equals-CpPK2t89.mjs} +2 -1
  8. package/dist/{assert_rejects-wFbSPn1O.mjs → assert_rejects-CTptdYck.mjs} +2 -2
  9. package/dist/{assert_strict_equals-Bpjl4Psw.mjs → assert_strict_equals-CYvBmkpC.mjs} +2 -1
  10. package/dist/{assert_throws-BJ5wuvR2.mjs → assert_throws-BYITOvPO.mjs} +2 -1
  11. package/dist/assertion_error-B-cx0fFA.mjs +31 -0
  12. package/dist/{builder-asm96yV1.mjs → builder-BYJ5otJa.mjs} +2 -2
  13. package/dist/compat/outgoing-jsonld.test.mjs +71 -3
  14. package/dist/compat/public-audience.test.mjs +3 -3
  15. package/dist/compat/secured-document.test.d.mts +2 -0
  16. package/dist/compat/secured-document.test.mjs +58 -0
  17. package/dist/compat/transformers.test.mjs +4 -4
  18. package/dist/{compound-proof-7UIAueLV.mjs → compound-proof-BIvUoJxm.mjs} +74 -2
  19. package/dist/{deno-Ckq9TwCv.mjs → deno-Vj_9wePq.mjs} +1 -1
  20. package/dist/{docloader-DUKEPG-O.mjs → docloader-qUudHZVH.mjs} +2 -2
  21. package/dist/federation/builder.test.mjs +5 -5
  22. package/dist/federation/circuit-breaker.test.mjs +3 -3
  23. package/dist/federation/collection.test.mjs +2 -2
  24. package/dist/federation/compound-fanout.test.d.mts +2 -0
  25. package/dist/federation/compound-fanout.test.mjs +228 -0
  26. package/dist/federation/handler-compound-proof.test.mjs +5 -5
  27. package/dist/federation/handler.test.mjs +11 -11
  28. package/dist/federation/idempotency.test.mjs +4 -4
  29. package/dist/federation/inbox.test.mjs +2 -2
  30. package/dist/federation/keycache.test.mjs +3 -3
  31. package/dist/federation/kv.test.mjs +2 -2
  32. package/dist/federation/metrics.test.mjs +4 -4
  33. package/dist/federation/middleware.test.mjs +17 -17
  34. package/dist/federation/mod.cjs +1 -1
  35. package/dist/federation/mod.js +1 -1
  36. package/dist/federation/mq.test.mjs +7 -6
  37. package/dist/federation/negotiation.test.mjs +3 -3
  38. package/dist/federation/outgoing-proof.test.d.mts +2 -0
  39. package/dist/federation/outgoing-proof.test.mjs +396 -0
  40. package/dist/federation/retry.test.mjs +3 -2
  41. package/dist/federation/router.test.mjs +5 -5
  42. package/dist/federation/send.test.mjs +11 -11
  43. package/dist/federation/tasks/enqueue.test.mjs +1 -1
  44. package/dist/federation/tasks/tasks.test.mjs +2 -2
  45. package/dist/federation/temporal.test.mjs +4 -4
  46. package/dist/federation/webfinger.test.mjs +4 -4
  47. package/dist/{federation-CgbvMauV.cjs → federation-CTnaljmy.cjs} +203 -37
  48. package/dist/{http-DQBfmkrS.cjs → http-B5F1JMh0.cjs} +1 -1
  49. package/dist/{http-DQA2JOEJ.js → http-By8tnmEr.js} +1 -1
  50. package/dist/{http-DZaAutqg.mjs → http-D4WPcJUe.mjs} +3 -3
  51. package/dist/{key-zxzx01Ec.mjs → key-B_Zc5Jbd.mjs} +2 -2
  52. package/dist/{kv-cache-sy8OMNT8.cjs → kv-cache-8K70pjtX.cjs} +1 -1
  53. package/dist/{kv-cache-CbrUX90H.mjs → kv-cache-BXdT7pJQ.mjs} +1 -1
  54. package/dist/{kv-cache-BBoePTOJ.js → kv-cache-BswMKQjC.js} +1 -1
  55. package/dist/{ld-CD_TN0e8.mjs → ld-B16KUSIQ.mjs} +3 -3
  56. package/dist/{metrics-B47Cm5gK.mjs → metrics-DpQqUAmh.mjs} +1 -1
  57. package/dist/{middleware-U_Gannqi.mjs → middleware-BL5HFFVU.mjs} +1 -1
  58. package/dist/{middleware-pHwDTAnq.mjs → middleware-C7_hqDnl.mjs} +143 -49
  59. package/dist/{middleware-U0OIuqwD.js → middleware-Cxto6Bq2.js} +204 -38
  60. package/dist/{mod-UDwMjuHM.d.ts → mod-CNRAxXEb.d.ts} +1 -5
  61. package/dist/{mod-CbKDOnCt.d.cts → mod-CVQFWefn.d.cts} +1 -5
  62. package/dist/mod.cjs +4 -4
  63. package/dist/mod.d.cts +1 -1
  64. package/dist/mod.d.ts +1 -1
  65. package/dist/mod.js +4 -4
  66. package/dist/nodeinfo/client.test.mjs +2 -2
  67. package/dist/nodeinfo/handler.test.mjs +3 -3
  68. package/dist/nodeinfo/types.test.mjs +3 -3
  69. package/dist/otel/exporter.test.mjs +2 -2
  70. package/dist/{outgoing-jsonld-B5Ne7JoL.mjs → outgoing-jsonld-4IJqPYos.mjs} +11 -9
  71. package/dist/{owner-u3IJRhVx.mjs → owner-BIOIhZoM.mjs} +2 -2
  72. package/dist/{owner-BNKC3s6G.js → owner-D-E0bT2O.js} +127 -35
  73. package/dist/{owner--mNatWct.cjs → owner-WUYke16i.cjs} +126 -34
  74. package/dist/{proof-D3te0SP-.mjs → proof-BVxJu5vv.mjs} +80 -23
  75. package/dist/{public-audience-Cc2YJ3ip.mjs → public-audience--klBIOk1.mjs} +13 -9
  76. package/dist/secured-document-CxzZZ9nL.mjs +35 -0
  77. package/dist/{send-CDr0Zivk.mjs → send-Cr5FJ7iu.mjs} +3 -3
  78. package/dist/sig/compound-proof-discovery.test.mjs +3 -3
  79. package/dist/sig/compound-proof-producer.test.d.mts +2 -0
  80. package/dist/sig/compound-proof-producer.test.mjs +107 -0
  81. package/dist/sig/compound-proof-verification.test.mjs +5 -5
  82. package/dist/sig/compound-proof.test.mjs +145 -58
  83. package/dist/sig/http.test.mjs +11 -10
  84. package/dist/sig/key.test.mjs +6 -6
  85. package/dist/sig/ld.test.mjs +9 -9
  86. package/dist/sig/mod.cjs +2 -2
  87. package/dist/sig/mod.d.cts +1 -1
  88. package/dist/sig/mod.d.ts +1 -1
  89. package/dist/sig/mod.js +2 -2
  90. package/dist/sig/owner.test.mjs +5 -5
  91. package/dist/sig/proof.test.mjs +9 -9
  92. package/dist/std__assert-DvMDRPes.mjs +8 -0
  93. package/dist/{temporal-DKhVF_Uk.mjs → temporal-CCf0lZV3.mjs} +1 -1
  94. package/dist/testing/kv.test.mjs +2 -2
  95. package/dist/utils/docloader.test.mjs +5 -5
  96. package/dist/utils/kv-cache.test.mjs +1 -1
  97. package/dist/utils/mod.cjs +1 -1
  98. package/dist/utils/mod.js +1 -1
  99. package/package.json +6 -6
  100. package/dist/std__assert-CxFT0MNt.mjs +0 -8
@@ -1,10 +1,10 @@
1
1
  const { URLPattern } = require("urlpattern-polyfill");
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-Dmm3t92W.cjs");
3
3
  const require_transformers = require("./transformers-BalCrSsr.cjs");
4
- const require_http = require("./http-DQBfmkrS.cjs");
4
+ const require_http = require("./http-B5F1JMh0.cjs");
5
5
  const require_types = require("./types-Be2zbyeG.cjs");
6
- const require_owner = require("./owner--mNatWct.cjs");
7
- const require_kv_cache = require("./kv-cache-sy8OMNT8.cjs");
6
+ const require_owner = require("./owner-WUYke16i.cjs");
7
+ const require_kv_cache = require("./kv-cache-8K70pjtX.cjs");
8
8
  let _logtape_logtape = require("@logtape/logtape");
9
9
  let _fedify_uri_template = require("@fedify/uri-template");
10
10
  let _fedify_vocab = require("@fedify/vocab");
@@ -1644,6 +1644,78 @@ function inspectCompoundPortableObjectApplicability(json, limits) {
1644
1644
  return "absent";
1645
1645
  }
1646
1646
  /**
1647
+ * Walks every JSON map in a finite, already-materialized JSON tree, depth
1648
+ * first in insertion order, skipping the values of `proof` and `@context`
1649
+ * members. A map reached a second time through a repeated reference is not
1650
+ * visited again, so a cyclic input terminates. The walk stops as soon as
1651
+ * the visitor returns a value other than `undefined`.
1652
+ */
1653
+ function findInJsonMaps(json, visit) {
1654
+ const seen = /* @__PURE__ */ new Set();
1655
+ const pending = [{
1656
+ value: json,
1657
+ path: ""
1658
+ }];
1659
+ while (pending.length > 0) {
1660
+ const { value, path } = pending.pop();
1661
+ if (typeof value !== "object" || value == null || seen.has(value)) continue;
1662
+ seen.add(value);
1663
+ if (Array.isArray(value)) {
1664
+ for (let index = value.length - 1; index >= 0; index--) pending.push({
1665
+ value: value[index],
1666
+ path: childPath(path, String(index))
1667
+ });
1668
+ continue;
1669
+ }
1670
+ const map = value;
1671
+ const result = visit(map, path);
1672
+ if (result !== void 0) return result;
1673
+ const keys = Object.keys(map);
1674
+ for (let index = keys.length - 1; index >= 0; index--) {
1675
+ const key = keys[index];
1676
+ if (key === "proof" || key === "@context") continue;
1677
+ pending.push({
1678
+ value: map[key],
1679
+ path: childPath(path, key)
1680
+ });
1681
+ }
1682
+ }
1683
+ }
1684
+ /**
1685
+ * Determines whether an outgoing JSON tree contains portable content that
1686
+ * requires producer-side proof-shape checks: a map, outside proof and context
1687
+ * values, whose direct `id` or `@id` is a portable ActivityPub URI.
1688
+ *
1689
+ * This deliberately differs from
1690
+ * {@link inspectCompoundPortableObjectApplicability}: it applies no resource
1691
+ * limits, so a portable map or an unsupported proof beyond the inbox limits
1692
+ * is still found, and a large document without portable maps stays outside
1693
+ * the compound-proof profile. The input must be a finite JSON tree that has
1694
+ * already been materialized, such as a compact JSON-LD document about to be
1695
+ * sent.
1696
+ *
1697
+ * @internal
1698
+ */
1699
+ function containsCompoundPortableObject(json) {
1700
+ return findInJsonMaps(json, (map) => [map.id, map["@id"]].some((id) => typeof id === "string" && PORTABLE_OBJECT_ID_PATTERN.test(id)) ? true : void 0) ?? false;
1701
+ }
1702
+ /**
1703
+ * Finds the first direct `proof` member whose value the map-local
1704
+ * compound-proof profile does not accept, i.e., anything other than a single
1705
+ * JSON map: a proof set, `null`, or a scalar. Like the inbox discovery, it
1706
+ * does not look inside proof or context values.
1707
+ *
1708
+ * The input must be a finite, already-materialized JSON tree; see
1709
+ * {@link containsCompoundPortableObject}.
1710
+ *
1711
+ * @returns The RFC 6901 JSON Pointer to the unsupported `proof` member, or
1712
+ * `null` if every direct proof is a single JSON map.
1713
+ * @internal
1714
+ */
1715
+ function findUnsupportedCompoundProofShape(json) {
1716
+ return findInJsonMaps(json, (map, path) => Object.hasOwn(map, "proof") && !isJsonMap(map.proof) ? childPath(path, "proof") : void 0) ?? null;
1717
+ }
1718
+ /**
1647
1719
  * Discovers direct literal proof-bearing maps in an immutable JSON snapshot.
1648
1720
  *
1649
1721
  * Discovery is bounded and atomic. Unsupported proof shapes, non-JSON input,
@@ -4628,6 +4700,102 @@ function serializeDataPointType(dataPointType) {
4628
4700
  }
4629
4701
  }
4630
4702
  //#endregion
4703
+ //#region src/federation/outgoing-proof.ts
4704
+ function isPortableUrl(url) {
4705
+ return url.protocol === "ap:" || url.protocol === "ap+ef61:";
4706
+ }
4707
+ function formatKeyIds(candidates) {
4708
+ return candidates.map((c) => c.verificationMethod.href).join(", ");
4709
+ }
4710
+ /**
4711
+ * Creates the Object Integrity Proofs Fedify attaches to an outgoing activity.
4712
+ *
4713
+ * Outside the map-local compound-proof profile, i.e., when the activity
4714
+ * embeds no portable object, every Ed25519 key signs the activity, as it
4715
+ * always has. Inside the profile, which accepts exactly one direct proof per
4716
+ * map, Fedify creates at most one proof:
4717
+ *
4718
+ * - An activity that already carries a proof is kept as is.
4719
+ * - A single Ed25519 key signs the activity.
4720
+ * - With several Ed25519 keys, a portable activity is signed by the one key
4721
+ * whose verification method is a DID URL for the activity's DID, the only
4722
+ * proof the FEP-ef61 policy can accept. If no key or more than one key
4723
+ * qualifies, or the activity is not portable itself, the choice is
4724
+ * ambiguous and this function throws.
4725
+ *
4726
+ * @throws {TypeError} If a single proof key cannot be chosen.
4727
+ * @internal
4728
+ */
4729
+ async function signOutgoingActivity(activity, candidates, options) {
4730
+ const { contextLoader, tracerProvider } = options;
4731
+ let hasProof = false;
4732
+ for await (const _ of activity.getProofs({ contextLoader })) {
4733
+ hasProof = true;
4734
+ break;
4735
+ }
4736
+ const keys = candidates.filter((c) => c.privateKey.algorithm.name === "Ed25519");
4737
+ if (keys.length < 1 || hasProof && !options.appendToExistingProofs) return {
4738
+ activity,
4739
+ hasProof,
4740
+ proofCreated: false
4741
+ };
4742
+ const sign = async (selected) => {
4743
+ for (const { verificationMethod, privateKey } of selected) activity = await require_owner.signObject(activity, privateKey, verificationMethod, {
4744
+ contextLoader,
4745
+ tracerProvider
4746
+ });
4747
+ return {
4748
+ activity,
4749
+ hasProof: true,
4750
+ proofCreated: true
4751
+ };
4752
+ };
4753
+ if (keys.length < 2 && !hasProof) return await sign(keys);
4754
+ if (!containsCompoundPortableObject(await activity.toJsonLd({
4755
+ format: "compact",
4756
+ contextLoader
4757
+ }))) return await sign(keys);
4758
+ const logger = (0, _logtape_logtape.getLogger)([
4759
+ "fedify",
4760
+ "federation",
4761
+ "outbox"
4762
+ ]);
4763
+ const activityId = activity.id?.href;
4764
+ if (hasProof) {
4765
+ logger.debug("The activity {activityId} embeds portable objects and already carries a proof, so no further proof is added; the map-local compound-proof profile accepts exactly one direct proof per map.", { activityId });
4766
+ return {
4767
+ activity,
4768
+ hasProof,
4769
+ proofCreated: false
4770
+ };
4771
+ }
4772
+ if (activity.id == null || !isPortableUrl(activity.id)) throw new TypeError(`Cannot choose an Object Integrity Proof key for the activity ${activityId}: it embeds portable objects, so it falls under the map-local compound-proof profile, which accepts exactly one direct proof per map, but ${keys.length} Ed25519 keys were supplied (${formatKeyIds(keys)}). Send it with explicit sender keys that contain exactly one Ed25519 key (RSA keys for HTTP Signatures may stay), or sign it with signObject() before sending it.`);
4773
+ const activityDid = (0, _fedify_vocab_runtime.getFe34Origin)(activity.id);
4774
+ const eligible = keys.filter((c) => c.verificationMethod.protocol === "did:" && (0, _fedify_vocab_runtime.haveSameFe34Origin)(activity.id, c.verificationMethod));
4775
+ if (eligible.length !== 1) throw new TypeError(`Cannot choose an Object Integrity Proof key for the portable activity ${activityId}: ` + (eligible.length < 1 ? `none of its ${keys.length} Ed25519 keys (${formatKeyIds(keys)}) ` : `${eligible.length} of its Ed25519 keys (${formatKeyIds(eligible)}) `) + `${eligible.length < 1 ? "is" : "are"} a DID URL verification method for ${activityDid}. The map-local compound-proof profile accepts exactly one direct proof per map, and FEP-ef61 requires that proof's verification method to be a DID URL for the activity's DID. Supply exactly one Ed25519 key whose key ID is a DID URL for ${activityDid}, or sign the activity with signObject() before sending it.`);
4776
+ logger.debug("The portable activity {activityId} is signed only by {keyId}, the one Ed25519 key whose verification method matches its DID; the map-local compound-proof profile accepts exactly one direct proof per map.", {
4777
+ activityId,
4778
+ keyId: eligible[0].verificationMethod.href
4779
+ });
4780
+ return await sign(eligible);
4781
+ }
4782
+ /**
4783
+ * Rejects an outgoing activity whose proofs Fedify's own inbox would reject
4784
+ * as unsupported: a document with portable objects in which some map carries
4785
+ * a proof set or another value that is not a single proof map.
4786
+ *
4787
+ * @param jsonLd The compact JSON-LD document about to be delivered.
4788
+ * @param activityId The activity ID, for the error message.
4789
+ * @throws {TypeError} If the document has an unsupported proof shape.
4790
+ * @internal
4791
+ */
4792
+ function assertSupportedCompoundProofShape(jsonLd, activityId) {
4793
+ if (!containsCompoundPortableObject(jsonLd)) return;
4794
+ const path = findUnsupportedCompoundProofShape(jsonLd);
4795
+ if (path == null) return;
4796
+ throw new TypeError(`Cannot send the activity ${activityId}: it embeds portable objects, but its proof at the JSON Pointer ${JSON.stringify(path)} is not a single proof map. The map-local compound-proof profile accepts exactly one direct proof per map, so Fedify inboxes would reject the activity. Sign each object with exactly one key.`);
4797
+ }
4798
+ //#endregion
4631
4799
  //#region src/federation/retry.ts
4632
4800
  const Temporal$4 = require_http.Temporal;
4633
4801
  /**
@@ -5756,6 +5924,7 @@ var FederationImpl = class extends FederationBuilderImpl {
5756
5924
  collectionSync: message.collectionSync,
5757
5925
  orderingKey: message.orderingKey,
5758
5926
  normalizeExistingProofs: message.normalizeExistingProofs,
5927
+ activityJsonLd: message.activity,
5759
5928
  context
5760
5929
  });
5761
5930
  }
@@ -6437,8 +6606,6 @@ var FederationImpl = class extends FederationBuilderImpl {
6437
6606
  else if (keys.length < 1) throw new TypeError("The keys must not be empty.");
6438
6607
  const contextLoader = this.contextLoaderFactory(this.#getLoaderOptions(ctx.origin));
6439
6608
  const activityId = activity.id.href;
6440
- let hasProof = false;
6441
- let proofCreated = false;
6442
6609
  let rsaKey = null;
6443
6610
  for (const { keyId, privateKey } of keys) {
6444
6611
  require_http.validateCryptoKey(privateKey, "private");
@@ -6447,25 +6614,22 @@ var FederationImpl = class extends FederationBuilderImpl {
6447
6614
  privateKey
6448
6615
  };
6449
6616
  }
6450
- for await (const _ of activity.getProofs({ contextLoader })) {
6451
- hasProof = true;
6452
- break;
6453
- }
6454
- if (!hasProof) {
6455
- for (const { keyId, privateKey } of keys) if (privateKey.algorithm.name === "Ed25519") {
6456
- activity = await require_owner.signObject(activity, privateKey, keyId, {
6457
- contextLoader,
6458
- tracerProvider: this.tracerProvider
6459
- });
6460
- hasProof = true;
6461
- proofCreated = true;
6462
- }
6463
- }
6464
- let jsonLd = await activity.toJsonLd({
6617
+ const signed = await signOutgoingActivity(activity, keys.map(({ keyId, privateKey }) => ({
6618
+ verificationMethod: keyId,
6619
+ privateKey
6620
+ })), {
6621
+ contextLoader,
6622
+ tracerProvider: this.tracerProvider,
6623
+ appendToExistingProofs: false
6624
+ });
6625
+ activity = signed.activity;
6626
+ const { hasProof, proofCreated } = signed;
6627
+ let jsonLd = !proofCreated && options.activityJsonLd != null ? options.activityJsonLd : await activity.toJsonLd({
6465
6628
  format: "compact",
6466
6629
  contextLoader
6467
6630
  });
6468
- if (proofCreated || !hasProof || options.normalizeExistingProofs) jsonLd = await require_owner.normalizeOutgoingActivityJsonLd(jsonLd, contextLoader);
6631
+ if (proofCreated || !hasProof || options.normalizeExistingProofs) jsonLd = await require_owner.normalizeOutgoingActivityJsonLd(jsonLd, contextLoader, { preserveNestedSecuredDocuments: true });
6632
+ assertSupportedCompoundProofShape(jsonLd, activityId);
6469
6633
  if (rsaKey == null) logger.warn("No supported key found to create a Linked Data signature for the activity {activityId}. The activity will be sent without a Linked Data signature. In order to create a Linked Data signature, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
6470
6634
  activityId,
6471
6635
  keys: keys.map((pair) => ({
@@ -7437,18 +7601,18 @@ var ContextImpl = class ContextImpl {
7437
7601
  });
7438
7602
  throw new TypeError("The activity to send must have at least one actor property.");
7439
7603
  }
7440
- let proofCreated = false;
7441
- if (actorKeyPairs != null) {
7442
- const contextLoader = this.contextLoader;
7443
- for (const kp of actorKeyPairs) {
7444
- if (kp.privateKey.algorithm.name !== "Ed25519" || kp.multikey.id == null) continue;
7445
- activity = await require_owner.signObject(activity, kp.privateKey, kp.multikey.id, {
7446
- contextLoader,
7447
- tracerProvider: this.tracerProvider
7448
- });
7449
- proofCreated = true;
7450
- }
7451
- }
7604
+ const { activity: signedActivity, proofCreated } = await signOutgoingActivity(activity, actorKeyPairs == null ? keys.map(({ keyId, privateKey }) => ({
7605
+ verificationMethod: keyId,
7606
+ privateKey
7607
+ })) : actorKeyPairs.flatMap((kp) => kp.multikey.id == null ? [] : [{
7608
+ verificationMethod: kp.multikey.id,
7609
+ privateKey: kp.privateKey
7610
+ }]), {
7611
+ contextLoader: this.contextLoader,
7612
+ tracerProvider: this.tracerProvider,
7613
+ appendToExistingProofs: actorKeyPairs != null
7614
+ });
7615
+ activity = signedActivity;
7452
7616
  const inboxes = extractInboxes({
7453
7617
  recipients: expandedRecipients,
7454
7618
  preferSharedInbox: options.preferSharedInbox,
@@ -7473,6 +7637,11 @@ var ContextImpl = class ContextImpl {
7473
7637
  });
7474
7638
  return true;
7475
7639
  }
7640
+ const activityJsonLd = await activity.toJsonLd({
7641
+ format: "compact",
7642
+ contextLoader: this.contextLoader
7643
+ });
7644
+ assertSupportedCompoundProofShape(activityJsonLd, activity.id?.href);
7476
7645
  const keyJwkPairs = await Promise.all(keys.map(async ({ keyId, privateKey }) => ({
7477
7646
  keyId: keyId.href,
7478
7647
  privateKey: await require_http.exportJwk(privateKey)
@@ -7488,10 +7657,7 @@ var ContextImpl = class ContextImpl {
7488
7657
  actorIds: [...actorIds],
7489
7658
  sharedInbox
7490
7659
  }])),
7491
- activity: await activity.toJsonLd({
7492
- format: "compact",
7493
- contextLoader: this.contextLoader
7494
- }),
7660
+ activity: activityJsonLd,
7495
7661
  activityId: activity.id?.href,
7496
7662
  activityType: (0, _fedify_vocab.getTypeId)(activity).href,
7497
7663
  collectionSync: opts.collectionSync,
@@ -9,7 +9,7 @@ let byte_encodings_base64 = require("byte-encodings/base64");
9
9
  let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
10
10
  //#region deno.json
11
11
  var name = "@fedify/fedify";
12
- var version = "2.4.0-dev.2010+498229f4";
12
+ var version = "2.4.0-dev.2030+e6b3de3d";
13
13
  //#endregion
14
14
  //#region ../../node_modules/.pnpm/temporal-polyfill@1.0.1/node_modules/temporal-polyfill/chunks/root.js
15
15
  const NativeTemporal = globalThis.Temporal;
@@ -10,7 +10,7 @@ import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
10
10
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
11
11
  //#region deno.json
12
12
  var name = "@fedify/fedify";
13
- var version = "2.4.0-dev.2010+498229f4";
13
+ var version = "2.4.0-dev.2030+e6b3de3d";
14
14
  //#endregion
15
15
  //#region src/sig/accept.ts
16
16
  /**
@@ -1,10 +1,10 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Ckq9TwCv.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-B47Cm5gK.mjs";
4
+ import { n as version, t as name } from "./deno-Vj_9wePq.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-DpQqUAmh.mjs";
6
6
  import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPVqki78.mjs";
7
- import { i as fetchKeyDetailed, s as validateCryptoKey } from "./key-zxzx01Ec.mjs";
7
+ import { i as fetchKeyDetailed, s as validateCryptoKey } from "./key-B_Zc5Jbd.mjs";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { CryptographicKey } from "@fedify/vocab";
10
10
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,8 +1,8 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Ckq9TwCv.mjs";
5
- import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-B47Cm5gK.mjs";
4
+ import { n as version, t as name } from "./deno-Vj_9wePq.mjs";
5
+ import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-DpQqUAmh.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
8
8
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,5 +1,5 @@
1
1
  const { URLPattern } = require("urlpattern-polyfill");
2
- const require_http = require("./http-DQBfmkrS.cjs");
2
+ const require_http = require("./http-B5F1JMh0.cjs");
3
3
  let _logtape_logtape = require("@logtape/logtape");
4
4
  let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
5
5
  let es_toolkit = require("es-toolkit");
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { p as recordDocumentCache } from "./metrics-B47Cm5gK.mjs";
4
+ import { p as recordDocumentCache } from "./metrics-DpQqUAmh.mjs";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { preloadedContexts } from "@fedify/vocab-runtime";
7
7
  //#region src/utils/kv-cache.ts
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { T as recordDocumentCache, f as validateCryptoKey, t as doubleKnock } from "./http-DQA2JOEJ.js";
3
+ import { T as recordDocumentCache, f as validateCryptoKey, t as doubleKnock } from "./http-By8tnmEr.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
6
6
  import { curry } from "es-toolkit";
@@ -1,9 +1,9 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Ckq9TwCv.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-B47Cm5gK.mjs";
6
- import { r as fetchKey, s as validateCryptoKey } from "./key-zxzx01Ec.mjs";
4
+ import { n as version, t as name } from "./deno-Vj_9wePq.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-DpQqUAmh.mjs";
6
+ import { r as fetchKey, s as validateCryptoKey } from "./key-B_Zc5Jbd.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,7 +1,7 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Ckq9TwCv.mjs";
4
+ import { n as version, t as name } from "./deno-Vj_9wePq.mjs";
5
5
  import { metrics } from "@opentelemetry/api";
6
6
  import { FetchError } from "@fedify/vocab-runtime";
7
7
  //#region src/federation/metrics.ts
@@ -1,5 +1,5 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as FederationImpl } from "./middleware-pHwDTAnq.mjs";
4
+ import { n as FederationImpl } from "./middleware-C7_hqDnl.mjs";
5
5
  export { FederationImpl };