@fedify/fedify 2.4.0-pr.936.41 → 2.5.0-dev.2271

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 (244) hide show
  1. package/README.md +50 -39
  2. package/dist/{assert-CJ1KXcvv.mjs → assert-D1Eafmd_.mjs} +1 -1
  3. package/dist/{assert_equals-BV7oLMxm.mjs → assert_equals-Z6IcEbWU.mjs} +2 -28
  4. package/dist/assert_exists-cffSpJ7X.mjs +28 -0
  5. package/dist/assert_false-CPdRnc3E.mjs +23 -0
  6. package/dist/assert_greater_or_equal-BlafOF4-.mjs +31 -0
  7. package/dist/{assert_instance_of-Q9KTBnrf.mjs → assert_instance_of-mrXWWNY-.mjs} +1 -1
  8. package/dist/{assert_not_equals-EPJPoxuf.mjs → assert_not_equals-CpPK2t89.mjs} +2 -1
  9. package/dist/assert_rejects-CTptdYck.mjs +39 -0
  10. package/dist/{assert_strict_equals-Ec20AUwa.mjs → assert_strict_equals-CYvBmkpC.mjs} +2 -1
  11. package/dist/{assert_throws-NiFfqbnH.mjs → assert_throws-BYITOvPO.mjs} +2 -1
  12. package/dist/assertion_error-B-cx0fFA.mjs +31 -0
  13. package/dist/audience-CHQ-FlLD.mjs +95 -0
  14. package/dist/{builder-DonuxRl_.mjs → builder-Bda6LK7A.mjs} +169 -14
  15. package/dist/{circuit-breaker-CBGyz5F7.mjs → circuit-breaker-XJ53md4S.mjs} +224 -17
  16. package/dist/circuit-breaker-test-utils-DW6YC_Pe.mjs +14 -0
  17. package/dist/{client-CjF5IYQS.mjs → client-CEnNz8O7.mjs} +144 -8
  18. package/dist/{codec-BBga-FWI.mjs → codec-C6rTrpIp.mjs} +26 -3
  19. package/dist/{collection-BIhlldqK.mjs → collection-CnnP1UAv.mjs} +1 -1
  20. package/dist/compat/mod.cjs +1 -1
  21. package/dist/compat/mod.d.cts +1 -1
  22. package/dist/compat/mod.d.ts +1 -1
  23. package/dist/compat/mod.js +1 -1
  24. package/dist/compat/outgoing-jsonld.test.mjs +71 -3
  25. package/dist/compat/public-audience.test.mjs +14 -5
  26. package/dist/compat/secured-document.test.d.mts +2 -0
  27. package/dist/compat/secured-document.test.mjs +58 -0
  28. package/dist/compat/transformers.test.mjs +5 -5
  29. package/dist/compound-proof-B-9mXxFW.mjs +989 -0
  30. package/dist/{context-Zii1f5xS.d.ts → context-7NyiqIcg.d.ts} +1600 -25
  31. package/dist/{context-BJXxPElm.mjs → context-8Tu9kea0.mjs} +21 -63
  32. package/dist/{context-lxX6I7as.d.cts → context-tsYPJ2Ew.d.cts} +1600 -25
  33. package/dist/{deno-BHzKn9Ig.mjs → deno-oR5aJKpU.mjs} +1 -1
  34. package/dist/dist-DJQM4u7i.mjs +189 -0
  35. package/dist/docloader-DBoYbvYW.mjs +87 -0
  36. package/dist/{esm-yYQfPhIY.mjs → esm-BHXXx4Wx.mjs} +13 -6
  37. package/dist/federation/audience.test.d.mts +2 -0
  38. package/dist/federation/audience.test.mjs +130 -0
  39. package/dist/federation/builder.test.mjs +54 -5
  40. package/dist/federation/circuit-breaker.test.mjs +838 -7
  41. package/dist/federation/collection.test.mjs +3 -3
  42. package/dist/federation/compound-fanout.test.d.mts +2 -0
  43. package/dist/federation/compound-fanout.test.mjs +228 -0
  44. package/dist/federation/handler-compound-proof.test.d.mts +2 -0
  45. package/dist/federation/handler-compound-proof.test.mjs +384 -0
  46. package/dist/federation/handler.test.mjs +385 -15
  47. package/dist/federation/hashlink-media.test.d.mts +2 -0
  48. package/dist/federation/hashlink-media.test.mjs +422 -0
  49. package/dist/federation/idempotency.test.mjs +6 -6
  50. package/dist/federation/inbox-report.test.d.mts +2 -0
  51. package/dist/federation/inbox-report.test.mjs +475 -0
  52. package/dist/federation/inbox.test.mjs +3 -3
  53. package/dist/federation/keycache.test.mjs +215 -14
  54. package/dist/federation/kv.test.mjs +3 -3
  55. package/dist/federation/metrics.test.mjs +5 -5
  56. package/dist/federation/middleware.test.mjs +967 -35
  57. package/dist/federation/mod.cjs +18 -261
  58. package/dist/federation/mod.d.cts +5 -5
  59. package/dist/federation/mod.d.ts +5 -5
  60. package/dist/federation/mod.js +279 -1
  61. package/dist/federation/mq.test.mjs +123 -47
  62. package/dist/federation/negotiation.test.mjs +4 -4
  63. package/dist/federation/outgoing-proof.test.d.mts +2 -0
  64. package/dist/federation/outgoing-proof.test.mjs +931 -0
  65. package/dist/federation/portable-actor.test.d.mts +2 -0
  66. package/dist/federation/portable-actor.test.mjs +496 -0
  67. package/dist/federation/portable-chain.test.d.mts +2 -0
  68. package/dist/federation/portable-chain.test.mjs +370 -0
  69. package/dist/federation/portable-collection.test.d.mts +2 -0
  70. package/dist/federation/portable-collection.test.mjs +832 -0
  71. package/dist/federation/portable-delivery.test.d.mts +2 -0
  72. package/dist/federation/portable-delivery.test.mjs +746 -0
  73. package/dist/federation/portable-gateway-keys.test.d.mts +2 -0
  74. package/dist/federation/portable-gateway-keys.test.mjs +686 -0
  75. package/dist/federation/portable-inbox.test.d.mts +2 -0
  76. package/dist/federation/portable-inbox.test.mjs +1535 -0
  77. package/dist/federation/portable-parse-uri.test.d.mts +2 -0
  78. package/dist/federation/portable-parse-uri.test.mjs +348 -0
  79. package/dist/federation/portable-route-activity.test.d.mts +2 -0
  80. package/dist/federation/portable-route-activity.test.mjs +259 -0
  81. package/dist/federation/portable.test.d.mts +2 -0
  82. package/dist/federation/portable.test.mjs +1072 -0
  83. package/dist/federation/retry.test.mjs +4 -3
  84. package/dist/federation/router.test.mjs +9 -159
  85. package/dist/federation/send.test.mjs +245 -27
  86. package/dist/federation/tasks/codec.test.mjs +4 -4
  87. package/dist/federation/tasks/enqueue.test.mjs +42 -4
  88. package/dist/federation/tasks/tasks.test.mjs +7 -6
  89. package/dist/federation/temporal.test.mjs +4 -4
  90. package/dist/federation/webfinger.test.mjs +275 -12
  91. package/dist/{middleware-FrSMAYEx.cjs → federation-CkZiAcWY.cjs} +8640 -3722
  92. package/dist/http-B5JT115n.cjs +10630 -0
  93. package/dist/http-DydWCB7R.js +6527 -0
  94. package/dist/{http-CPVMUgsW.mjs → http-siciWkmx.mjs} +397 -168
  95. package/dist/key-BspPiXqn.mjs +951 -0
  96. package/dist/key-C1nv7_jD.d.ts +1125 -0
  97. package/dist/key-DYxuyd-s.d.cts +1125 -0
  98. package/dist/key-owner-evidence-APB6NpSk.mjs +108 -0
  99. package/dist/keycache-Da8A8mZa.mjs +200 -0
  100. package/dist/{kv-D6hNiMTK.d.ts → kv-B2mzK5tl.d.cts} +3 -2
  101. package/dist/{kv-gJ8LYbxX.d.cts → kv-B2mzK5tl.d.ts} +3 -2
  102. package/dist/kv-DBRWVx3Q.mjs +104 -0
  103. package/dist/{kv-cache-KyGqJqSp.mjs → kv-cache-BF1hnW65.mjs} +1 -1
  104. package/dist/{kv-cache-5bnX3-Jq.js → kv-cache-CTQr1tbn.js} +54 -16
  105. package/dist/{kv-cache-DQ29C4XL.cjs → kv-cache-DCac1nEU.cjs} +55 -19
  106. package/dist/{ld-Cj9F_5AP.mjs → ld-CzaP-hJl.mjs} +44 -12
  107. package/dist/map-local-context-conflict-DOYEEJ3u.mjs +204 -0
  108. package/dist/map-local-create-note-B0SeXJms.mjs +214 -0
  109. package/dist/{metrics-DMk-nTxI.mjs → metrics-CYg9yxBL.mjs} +3 -2
  110. package/dist/metrics-DVKYY6K1.d.cts +36 -0
  111. package/dist/metrics-DoRtI0qU.d.ts +36 -0
  112. package/dist/{middleware-Y-kpsp6S.js → middleware-CsDDXKuL.js} +5493 -1103
  113. package/dist/{middleware-CvwTUgnP.mjs → middleware-D7_LO-Vs.mjs} +3157 -272
  114. package/dist/{middleware-CEctxBN6.mjs → middleware-DWjrfpcz.mjs} +1 -1
  115. package/dist/{mod-gOlPDuT8.d.cts → mod-BojP2Bw3.d.cts} +1 -1
  116. package/dist/mod-CavhAgLw.d.cts +320 -0
  117. package/dist/mod-CtpF2BU5.d.ts +320 -0
  118. package/dist/{mod-BtEaIEcD.d.cts → mod-DEZXwV6J.d.ts} +10 -4
  119. package/dist/{mod-UMmveiO0.d.ts → mod-Dw-nPxQh.d.cts} +10 -4
  120. package/dist/{mod-DLc2Ot6f.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
  121. package/dist/mod.cjs +40 -39
  122. package/dist/mod.d.cts +10 -11
  123. package/dist/mod.d.ts +10 -11
  124. package/dist/mod.js +9 -9
  125. package/dist/{mq-llHKivST.mjs → mq-Dm1Wmtm-.mjs} +6 -0
  126. package/dist/nodeinfo/client.test.mjs +139 -4
  127. package/dist/nodeinfo/handler.test.mjs +5 -5
  128. package/dist/nodeinfo/mod.cjs +1 -1
  129. package/dist/nodeinfo/mod.d.cts +1 -1
  130. package/dist/nodeinfo/mod.d.ts +1 -1
  131. package/dist/nodeinfo/mod.js +1 -1
  132. package/dist/nodeinfo/types.test.mjs +4 -4
  133. package/dist/otel/exporter.test.mjs +3 -3
  134. package/dist/otel/mod.cjs +0 -1
  135. package/dist/otel/mod.d.cts +1 -1
  136. package/dist/otel/mod.d.ts +1 -1
  137. package/dist/{outgoing-jsonld-URuqsICz.mjs → outgoing-jsonld-4IJqPYos.mjs} +12 -10
  138. package/dist/{owner-DEvZuyOE.d.cts → owner-BF0L9cMt.d.cts} +11 -0
  139. package/dist/{owner-CnngXDNJ.d.ts → owner-BSzr5-I8.d.ts} +11 -0
  140. package/dist/owner-DYgfTFHy.mjs +267 -0
  141. package/dist/portable-collection-BpsVsRov.js +670 -0
  142. package/dist/portable-collection-C74P1vtC.mjs +418 -0
  143. package/dist/portable-collection-DZd2bm7M.cjs +686 -0
  144. package/dist/portable-key-BIMLrAP4.mjs +549 -0
  145. package/dist/portable-key-id-Ca30-hOa.mjs +248 -0
  146. package/dist/proof-Dxy6ByqI.mjs +1299 -0
  147. package/dist/{public-audience-Cr5MsnMq.mjs → public-audience--klBIOk1.mjs} +15 -10
  148. package/dist/router-u5O5KCQr.mjs +156 -0
  149. package/dist/runtime/mod.cjs +1 -1
  150. package/dist/runtime/mod.js +1 -1
  151. package/dist/secured-document-CxzZZ9nL.mjs +35 -0
  152. package/dist/send-C4dDpAxm.mjs +495 -0
  153. package/dist/sig/accept.test.mjs +1 -1
  154. package/dist/sig/compound-proof-discovery.test.d.mts +2 -0
  155. package/dist/sig/compound-proof-discovery.test.mjs +331 -0
  156. package/dist/sig/compound-proof-producer.test.d.mts +2 -0
  157. package/dist/sig/compound-proof-producer.test.mjs +107 -0
  158. package/dist/sig/compound-proof-verification.test.d.mts +2 -0
  159. package/dist/sig/compound-proof-verification.test.mjs +833 -0
  160. package/dist/sig/compound-proof.test.d.mts +2 -0
  161. package/dist/sig/compound-proof.test.mjs +411 -0
  162. package/dist/sig/http.test.mjs +702 -31
  163. package/dist/sig/key-owner-evidence.test.d.mts +2 -0
  164. package/dist/sig/key-owner-evidence.test.mjs +100 -0
  165. package/dist/sig/key.test.mjs +220 -8
  166. package/dist/sig/ld.test.mjs +65 -7
  167. package/dist/sig/mitra-receive-interop.test.d.mts +2 -0
  168. package/dist/sig/mitra-receive-interop.test.mjs +260 -0
  169. package/dist/sig/mitra-send-interop.test.d.mts +2 -0
  170. package/dist/sig/mitra-send-interop.test.mjs +461 -0
  171. package/dist/sig/mod.cjs +18 -16
  172. package/dist/sig/mod.d.cts +4 -4
  173. package/dist/sig/mod.d.ts +4 -4
  174. package/dist/sig/mod.js +3 -3
  175. package/dist/sig/owner.test.mjs +108 -9
  176. package/dist/sig/portable-collection.test.d.mts +2 -0
  177. package/dist/sig/portable-collection.test.mjs +697 -0
  178. package/dist/sig/portable-interop.test.d.mts +2 -0
  179. package/dist/sig/portable-interop.test.mjs +156 -0
  180. package/dist/sig/portable-key-id.test.d.mts +2 -0
  181. package/dist/sig/portable-key-id.test.mjs +67 -0
  182. package/dist/sig/portable-key.test.d.mts +2 -0
  183. package/dist/sig/portable-key.test.mjs +1439 -0
  184. package/dist/sig/proof.test.mjs +1753 -16
  185. package/dist/sig/tootik-request-interop.test.d.mts +2 -0
  186. package/dist/sig/tootik-request-interop.test.mjs +190 -0
  187. package/dist/sig/tootik-send-interop.test.d.mts +2 -0
  188. package/dist/sig/tootik-send-interop.test.mjs +331 -0
  189. package/dist/sig/verification.test.d.mts +2 -0
  190. package/dist/sig/verification.test.mjs +310 -0
  191. package/dist/std__assert-DvMDRPes.mjs +8 -0
  192. package/dist/{testing-CO7ftO8A.mjs → tasks-IG3pHfvZ.mjs} +2 -2
  193. package/dist/{temporal-fsXO5IvD.mjs → temporal-D0KJI4NF.mjs} +3 -3
  194. package/dist/testing/context.test.d.mts +2 -0
  195. package/dist/testing/context.test.mjs +19 -0
  196. package/dist/testing/kv.test.d.mts +2 -0
  197. package/dist/testing/kv.test.mjs +101 -0
  198. package/dist/testing/mod.d.mts +1617 -48
  199. package/dist/testing/mod.mjs +6 -3
  200. package/dist/testing-t8xDeJZ5.mjs +8 -0
  201. package/dist/{transformers-DGwl-hD1.cjs → transformers-BalCrSsr.cjs} +0 -1
  202. package/dist/{types-DC1pNgJA.js → types-_S2_MeLF.js} +144 -8
  203. package/dist/{types-CPym83zc.cjs → types-poIao40f.cjs} +160 -7
  204. package/dist/utils/docloader.test.mjs +530 -8
  205. package/dist/utils/kv-cache.test.mjs +2 -2
  206. package/dist/utils/mod.cjs +1 -1
  207. package/dist/utils/mod.d.cts +1 -1
  208. package/dist/utils/mod.d.ts +1 -1
  209. package/dist/utils/mod.js +1 -1
  210. package/dist/verification-C3954hQh.mjs +5 -0
  211. package/dist/verification-Dpfcw8ml.mjs +105 -0
  212. package/dist/vocab/cjs.test.mjs +1 -1
  213. package/package.json +8 -8
  214. package/dist/assert_rejects-EgstcQy5.mjs +0 -82
  215. package/dist/docloader-e1khNUKy.mjs +0 -49
  216. package/dist/http-CsmQ-BQ4.js +0 -2483
  217. package/dist/http-VyDTd4G3.d.cts +0 -553
  218. package/dist/http-hlIjmewS.cjs +0 -2694
  219. package/dist/http-lf8Hsd91.d.ts +0 -553
  220. package/dist/key-DfPsX8hv.mjs +0 -453
  221. package/dist/keycache-_DHqz5z_.mjs +0 -97
  222. package/dist/metrics-CoUJLQhZ.d.cts +0 -276
  223. package/dist/metrics-Dc4jR-IC.d.ts +0 -276
  224. package/dist/mod-B0hW12_O.d.cts +0 -307
  225. package/dist/mod-COIAjwRS.d.ts +0 -307
  226. package/dist/owner-Br9YYzn_.mjs +0 -120
  227. package/dist/proof-B4ngoaNQ.mjs +0 -316
  228. package/dist/proof-B6E0XUXJ.js +0 -1415
  229. package/dist/proof-NN4xCQGL.cjs +0 -1562
  230. package/dist/send-CxHKUNzv.mjs +0 -239
  231. package/dist/std__assert-B2NnY9bq.mjs +0 -79
  232. package/dist/temporal-polyfill-BCdTHexd.cjs +0 -3565
  233. /package/dist/{accept-8PiolDP7.mjs → accept-CPVqki78.mjs} +0 -0
  234. /package/dist/{activity-listener-BtTSxZWA.mjs → activity-listener-C-BSbKI7.mjs} +0 -0
  235. /package/dist/{client-CAM_bQXx.d.cts → client-D-XP_Ccb.d.cts} +0 -0
  236. /package/dist/{client-CSddvgWN.d.ts → client-D-XP_Ccb.d.ts} +0 -0
  237. /package/dist/{keys-Dbyd7bhl.mjs → keys-DIJNHW-Y.mjs} +0 -0
  238. /package/dist/{kv-CXBAok3k.mjs → kv-DCHkaJ9-.mjs} +0 -0
  239. /package/dist/{negotiation-RuwrPFqi.mjs → negotiation-CCocWT_N.mjs} +0 -0
  240. /package/dist/{retry-DgFqeS5k.mjs → retry-zX5xw5e0.mjs} +0 -0
  241. /package/dist/{chunk-D5IdezsZ.js → rolldown-runtime-BC-Eo5Mj.js} +0 -0
  242. /package/dist/{chunk-Czpeue4M.cjs → rolldown-runtime-Dmm3t92W.cjs} +0 -0
  243. /package/dist/{transformers-DXze6FUB.js → transformers-DAtXl_Kc.js} +0 -0
  244. /package/dist/{types-CrtdVuDP.mjs → types-DE_LV1JB.mjs} +0 -0
@@ -0,0 +1,2 @@
1
+ import { Temporal } from "temporal-polyfill";
2
+ import { URLPattern } from "urlpattern-polyfill";
@@ -0,0 +1,411 @@
1
+ import { Temporal } from "temporal-polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
5
+ import "../std__assert-DvMDRPes.mjs";
6
+ import { t as assert } from "../assert-D1Eafmd_.mjs";
7
+ import { n as preloadedOnlyDocumentLoader } from "../public-audience--klBIOk1.mjs";
8
+ import { r as normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-4IJqPYos.mjs";
9
+ import { a as signObject, d as verifyProof } from "../proof-Dxy6ByqI.mjs";
10
+ import { n as ed25519PrivateKey, r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
11
+ import { s as verifyCompoundProofDocuments } from "../compound-proof-B-9mXxFW.mjs";
12
+ import { t as map_local_create_note_default } from "../map-local-create-note-B0SeXJms.mjs";
13
+ import { t as map_local_context_conflict_default } from "../map-local-context-conflict-DOYEEJ3u.mjs";
14
+ import { Create, DataIntegrityProof, Note, Question } from "@fedify/vocab";
15
+ import { encodeMultibase, exportDidKey, parseIri } from "@fedify/vocab-runtime";
16
+ import { mockDocumentLoader, test } from "@fedify/fixture";
17
+ import { encodeHex } from "byte-encodings/hex";
18
+ import jsonld from "@fedify/vocab-runtime/jsonld";
19
+ import serialize from "json-canon";
20
+ //#region src/sig/compound-proof.test.ts
21
+ const outerPrivateKey = await crypto.subtle.importKey("jwk", {
22
+ kty: "OKP",
23
+ crv: "Ed25519",
24
+ d: "yW756hDF5BTEcXI6_53nLDX6W3D66X6IMuysfS4rjtY",
25
+ x: "sA2Nk45_dz1RVlqtNqYj9TRPf10ZYPnPPo4SYg6igQ8",
26
+ key_ops: ["sign"],
27
+ ext: true
28
+ }, "Ed25519", true, ["sign"]);
29
+ const outerDid = await exportDidKey(await crypto.subtle.importKey("jwk", {
30
+ kty: "OKP",
31
+ crv: "Ed25519",
32
+ x: "sA2Nk45_dz1RVlqtNqYj9TRPf10ZYPnPPo4SYg6igQ8",
33
+ key_ops: ["verify"],
34
+ ext: true
35
+ }, "Ed25519", true, ["verify"]));
36
+ const innerDid = await exportDidKey(ed25519PublicKey.publicKey);
37
+ const outerMethod = outerDid.substring(8);
38
+ const innerMethod = innerDid.substring(8);
39
+ const outerKeyId = new URL(`${outerDid}#${outerMethod}`);
40
+ const innerKeyId = new URL(`${innerDid}#${innerMethod}`);
41
+ const vectorInnerKeyId = new URL(map_local_create_note_default.keys.inner.verificationMethod);
42
+ const conflictVectorInnerKeyId = new URL(map_local_context_conflict_default.keys.inner.verificationMethod);
43
+ const context = ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"];
44
+ const distinctInnerContext = [...context, { ex: "https://example.com/ns#" }];
45
+ const options = {
46
+ context,
47
+ contextLoader: mockDocumentLoader,
48
+ documentLoader: mockDocumentLoader
49
+ };
50
+ const inboundOptions = {
51
+ contextLoader: preloadedOnlyDocumentLoader,
52
+ documentLoader: preloadedOnlyDocumentLoader
53
+ };
54
+ const compoundLimits = {
55
+ maxDepth: 16,
56
+ maxMaps: 32,
57
+ maxProofs: 8,
58
+ maxBytes: 16384
59
+ };
60
+ async function parseProof(document) {
61
+ const proof = document.proof;
62
+ assert(proof != null && typeof proof === "object" && !Array.isArray(proof));
63
+ return await DataIntegrityProof.fromJsonLd({
64
+ "@context": document["@context"],
65
+ ...proof
66
+ }, options);
67
+ }
68
+ function asRecord(value) {
69
+ assert(value != null && typeof value === "object" && !Array.isArray(value));
70
+ return value;
71
+ }
72
+ function withoutDirectProof(document) {
73
+ const unsecuredDocument = structuredClone(document);
74
+ delete unsecuredDocument.proof;
75
+ return unsecuredDocument;
76
+ }
77
+ function withoutProofValue(proof) {
78
+ const proofConfiguration = structuredClone(proof);
79
+ delete proofConfiguration.proofValue;
80
+ return proofConfiguration;
81
+ }
82
+ async function sha256(value) {
83
+ return new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)));
84
+ }
85
+ async function assertRecordedProof(entry) {
86
+ assertEquals(withoutProofValue(entry.proof), entry.proofConfiguration);
87
+ assertEquals(entry.proof.proofValue, entry.proofValue);
88
+ const documentJcs = serialize(entry.document);
89
+ const proofConfigurationJcs = serialize(entry.proofConfiguration);
90
+ assertEquals(documentJcs, entry.canonicalization.documentJcs);
91
+ assertEquals(proofConfigurationJcs, entry.canonicalization.proofConfigurationJcs);
92
+ const documentDigest = await sha256(documentJcs);
93
+ const proofConfigurationDigest = await sha256(proofConfigurationJcs);
94
+ assertEquals(encodeHex(documentDigest), entry.hashes.documentSha256);
95
+ assertEquals(encodeHex(proofConfigurationDigest), entry.hashes.proofConfigurationSha256);
96
+ const combinedSigningInput = new Uint8Array(proofConfigurationDigest.length + documentDigest.length);
97
+ combinedSigningInput.set(proofConfigurationDigest);
98
+ combinedSigningInput.set(documentDigest, proofConfigurationDigest.length);
99
+ assertEquals(encodeHex(combinedSigningInput), entry.hashes.combinedSigningInput);
100
+ assertEquals(entry.hashes.combinedSigningInput, entry.hashes.proofConfigurationSha256 + entry.hashes.documentSha256);
101
+ const privateJwk = structuredClone(entry.key.testPrivateKeyJwk);
102
+ const publicJwk = structuredClone(entry.key.publicKeyJwk);
103
+ assertEquals(privateJwk.x, publicJwk.x);
104
+ const privateKey = await crypto.subtle.importKey("jwk", privateJwk, "Ed25519", true, ["sign"]);
105
+ const publicKey = await crypto.subtle.importKey("jwk", publicJwk, "Ed25519", true, ["verify"]);
106
+ const controller = await exportDidKey(publicKey);
107
+ assertEquals(controller, entry.key.controller);
108
+ const publicKeyMultibase = controller.replace(/^did:key:/, "");
109
+ assertEquals(publicKeyMultibase, entry.key.publicKeyMultibase);
110
+ assertEquals(entry.key.verificationMethod, `${controller}#${publicKeyMultibase}`);
111
+ assertEquals(entry.proofConfiguration.verificationMethod, entry.key.verificationMethod);
112
+ const signature = new Uint8Array(await crypto.subtle.sign("Ed25519", privateKey, combinedSigningInput));
113
+ assert(await crypto.subtle.verify("Ed25519", publicKey, signature, combinedSigningInput));
114
+ assertEquals(new TextDecoder().decode(encodeMultibase("base58btc", signature)), entry.proofValue);
115
+ }
116
+ test("map-local compound vector records independently reproducible proofs", async () => {
117
+ const securedOuter = asRecord(map_local_create_note_default.documents.finalSecuredCompound);
118
+ const securedInner = asRecord(map_local_create_note_default.documents.securedInner);
119
+ const outerProof = asRecord(securedOuter.proof);
120
+ const innerProof = asRecord(securedInner.proof);
121
+ const replacementInnerProof = asRecord(map_local_create_note_default.documents.replacementInnerProof);
122
+ const replacementInnerProofConfiguration = withoutProofValue(replacementInnerProof);
123
+ assertEquals(withoutDirectProof(securedOuter), map_local_create_note_default.documents.outerUnsecuredDocument);
124
+ assertEquals(withoutDirectProof(securedInner), map_local_create_note_default.documents.innerUnsecuredDocument);
125
+ assertEquals(withoutProofValue(outerProof), map_local_create_note_default.documents.outerProofConfiguration);
126
+ assertEquals(withoutProofValue(innerProof), map_local_create_note_default.documents.innerProofConfiguration);
127
+ const entries = [
128
+ {
129
+ document: map_local_create_note_default.documents.outerUnsecuredDocument,
130
+ proofConfiguration: map_local_create_note_default.documents.outerProofConfiguration,
131
+ proof: outerProof,
132
+ key: map_local_create_note_default.keys.outer,
133
+ canonicalization: map_local_create_note_default.canonicalization.outer,
134
+ hashes: map_local_create_note_default.hashes.outer,
135
+ proofValue: map_local_create_note_default.proofValues.outer
136
+ },
137
+ {
138
+ document: map_local_create_note_default.documents.innerUnsecuredDocument,
139
+ proofConfiguration: map_local_create_note_default.documents.innerProofConfiguration,
140
+ proof: innerProof,
141
+ key: map_local_create_note_default.keys.inner,
142
+ canonicalization: map_local_create_note_default.canonicalization.inner,
143
+ hashes: map_local_create_note_default.hashes.inner,
144
+ proofValue: map_local_create_note_default.proofValues.inner
145
+ },
146
+ {
147
+ document: map_local_create_note_default.documents.innerUnsecuredDocument,
148
+ proofConfiguration: replacementInnerProofConfiguration,
149
+ proof: replacementInnerProof,
150
+ key: map_local_create_note_default.keys.inner,
151
+ canonicalization: map_local_create_note_default.canonicalization.replacementInner,
152
+ hashes: map_local_create_note_default.hashes.replacementInner,
153
+ proofValue: map_local_create_note_default.proofValues.replacementInner
154
+ }
155
+ ];
156
+ for (const entry of entries) await assertRecordedProof(entry);
157
+ });
158
+ test("the context-conflict vector records valid proofs and divergent semantics", async () => {
159
+ const compound = asRecord(map_local_context_conflict_default.documents.finalSecuredCompound);
160
+ const embedded = asRecord(compound.object);
161
+ const securedInner = asRecord(map_local_context_conflict_default.documents.securedInner);
162
+ const outerProof = asRecord(compound.proof);
163
+ const innerProof = asRecord(embedded.proof);
164
+ assertEquals(embedded, securedInner);
165
+ assertEquals(withoutDirectProof(compound), map_local_context_conflict_default.documents.outerUnsecuredDocument);
166
+ assertEquals(withoutDirectProof(embedded), map_local_context_conflict_default.documents.innerUnsecuredDocument);
167
+ await assertRecordedProof({
168
+ document: map_local_context_conflict_default.documents.outerUnsecuredDocument,
169
+ proofConfiguration: map_local_context_conflict_default.documents.outerProofConfiguration,
170
+ proof: outerProof,
171
+ key: map_local_context_conflict_default.keys.outer,
172
+ canonicalization: map_local_context_conflict_default.canonicalization.outer,
173
+ hashes: map_local_context_conflict_default.hashes.outer,
174
+ proofValue: map_local_context_conflict_default.proofValues.outer
175
+ });
176
+ await assertRecordedProof({
177
+ document: map_local_context_conflict_default.documents.innerUnsecuredDocument,
178
+ proofConfiguration: map_local_context_conflict_default.documents.innerProofConfiguration,
179
+ proof: innerProof,
180
+ key: map_local_context_conflict_default.keys.inner,
181
+ canonicalization: map_local_context_conflict_default.canonicalization.inner,
182
+ hashes: map_local_context_conflict_default.hashes.inner,
183
+ proofValue: map_local_context_conflict_default.proofValues.inner
184
+ });
185
+ const verifiedInner = await verifyProof(embedded, await parseProof(embedded), inboundOptions);
186
+ assertEquals(verifiedInner != null, map_local_context_conflict_default.expectedVerification.original.inner);
187
+ assertEquals(verifiedInner?.id, conflictVectorInnerKeyId);
188
+ const verifiedOuter = await verifyProof(compound, await parseProof(compound), inboundOptions);
189
+ assertEquals(verifiedOuter != null, map_local_context_conflict_default.expectedVerification.original.outer);
190
+ assertEquals(verifiedOuter?.id, outerKeyId);
191
+ const standaloneExpansion = await jsonld.expand(embedded, { documentLoader: preloadedOnlyDocumentLoader });
192
+ const compoundExpansion = await jsonld.expand(compound, { documentLoader: preloadedOnlyDocumentLoader });
193
+ const content = "https://www.w3.org/ns/activitystreams#content";
194
+ const object = "https://www.w3.org/ns/activitystreams#object";
195
+ const standaloneContent = asRecord(standaloneExpansion[0])[content];
196
+ const inParentObject = asRecord(asRecord(compoundExpansion[0])[object][0]);
197
+ const inParentContent = inParentObject[content];
198
+ assertEquals(serialize(standaloneExpansion[0]) === serialize(inParentObject), map_local_context_conflict_default.expectedInterpretation.standaloneAndInParentExpansionsEqual);
199
+ assertEquals(standaloneContent, [{ "@value": "A portable note with inherited language" }]);
200
+ assertEquals(inParentContent, [{
201
+ "@value": "A portable note with inherited language",
202
+ "@language": map_local_context_conflict_default.expectedInterpretation.inParentContentLanguage
203
+ }]);
204
+ assertEquals(standaloneContent[0]["@language"] ?? null, map_local_context_conflict_default.expectedInterpretation.standaloneContentLanguage);
205
+ assertEquals(serialize(standaloneContent) !== serialize(inParentContent), !map_local_context_conflict_default.expectedInterpretation.standaloneAndInParentExpansionsEqual);
206
+ });
207
+ test("the raw same-context baseline verifies map-locally", async () => {
208
+ const compound = structuredClone(map_local_create_note_default.documents.finalSecuredCompound);
209
+ const embedded = compound.object;
210
+ const embeddedProof = embedded.proof;
211
+ assertEquals(embedded, map_local_create_note_default.documents.securedInner);
212
+ assertEquals(embeddedProof["@context"], context);
213
+ assertEquals(embedded["@context"], context);
214
+ assert("proof" in embedded);
215
+ const verifiedInnerKey = await verifyProof(embedded, await parseProof(embedded), options);
216
+ assertEquals(verifiedInnerKey != null, map_local_create_note_default.expectedVerification.original.inner);
217
+ assertEquals(verifiedInnerKey != null, map_local_create_note_default.expectedVerification.standaloneInner);
218
+ assertEquals(verifiedInnerKey?.id, vectorInnerKeyId);
219
+ const verifiedOuterKey = await verifyProof(compound, await parseProof(compound), options);
220
+ assertEquals(verifiedOuterKey != null, map_local_create_note_default.expectedVerification.original.outer);
221
+ assertEquals(verifiedOuterKey != null, map_local_create_note_default.expectedVerification.standaloneOuter);
222
+ assertEquals(verifiedOuterKey?.id, outerKeyId);
223
+ const tampered = structuredClone(compound);
224
+ const tamperedInner = tampered.object;
225
+ tamperedInner.content = "A tampered portable note";
226
+ assertEquals(await verifyProof(tamperedInner, await parseProof(tamperedInner), options) != null, map_local_create_note_default.expectedVerification.tamperedInnerContent.inner);
227
+ assertEquals(await verifyProof(tampered, await parseProof(tampered), options) != null, map_local_create_note_default.expectedVerification.tamperedInnerContent.outer);
228
+ const replaced = structuredClone(compound);
229
+ const replacedInner = replaced.object;
230
+ replacedInner.proof = structuredClone(map_local_create_note_default.documents.replacementInnerProof);
231
+ const replacementInnerKey = await verifyProof(replacedInner, await parseProof(replacedInner), options);
232
+ assertEquals(replacementInnerKey != null, map_local_create_note_default.expectedVerification.replacedInnerProof.inner);
233
+ assertEquals(replacementInnerKey?.id, vectorInnerKeyId);
234
+ assertEquals(await verifyProof(replaced, await parseProof(replaced), options) != null, map_local_create_note_default.expectedVerification.replacedInnerProof.outer);
235
+ });
236
+ async function signDistinctContextNote(created, path) {
237
+ return await signObject(new Note({
238
+ id: parseIri(`ap+ef61://${innerDid}/objects/${path}`),
239
+ attribution: parseIri(`ap+ef61://${innerDid}/actor`),
240
+ content: "A portable note with its own context"
241
+ }), ed25519PrivateKey, innerKeyId, {
242
+ ...options,
243
+ context: distinctInnerContext,
244
+ created
245
+ });
246
+ }
247
+ async function serializeOutgoing(object, context) {
248
+ return await normalizeOutgoingActivityJsonLd(await object.toJsonLd({
249
+ format: "compact",
250
+ ...options,
251
+ context: context ?? options.context
252
+ }), mockDocumentLoader, { preserveNestedSecuredDocuments: true });
253
+ }
254
+ async function signOuterCreate(created, path, child) {
255
+ return await signObject(new Create({
256
+ id: parseIri(`ap+ef61://${outerDid}/activities/${path}`),
257
+ actor: parseIri(`ap+ef61://${outerDid}/actor`),
258
+ object: child
259
+ }), outerPrivateKey, outerKeyId, {
260
+ ...options,
261
+ created
262
+ });
263
+ }
264
+ test("typed Create serialization embeds the signed child representation", async () => {
265
+ const created = Temporal.Instant.from("2023-02-24T23:36:38Z");
266
+ const inner = await signDistinctContextNote(created, "distinct-context");
267
+ assert(inner instanceof Note);
268
+ const standaloneInner = await serializeOutgoing(inner, distinctInnerContext);
269
+ const outer = await signOuterCreate(created, "distinct-context", inner);
270
+ assert(outer instanceof Create);
271
+ const compound = await serializeOutgoing(outer);
272
+ const embedded = compound.object;
273
+ const embeddedProof = embedded.proof;
274
+ assertEquals(embedded["@context"], distinctInnerContext);
275
+ assertEquals(embeddedProof["@context"], distinctInnerContext);
276
+ assertEquals(compound["@context"], context);
277
+ assertEquals(serialize(embedded), serialize(standaloneInner));
278
+ assertEquals(embedded.type, "Note");
279
+ assertEquals((await verifyProof(embedded, await parseProof(embedded), options))?.id, innerKeyId);
280
+ assertEquals((await verifyProof(compound, await parseProof(compound), options))?.id, outerKeyId);
281
+ const mapLocal = await verifyCompoundProofDocuments(compound, compoundLimits, inboundOptions);
282
+ assertEquals(mapLocal.status, "ok");
283
+ assert(mapLocal.status === "ok");
284
+ assert(mapLocal.verified);
285
+ assertEquals(mapLocal.documents.map(({ path, verified }) => ({
286
+ path,
287
+ verified
288
+ })), [{
289
+ path: "/object",
290
+ verified: true
291
+ }, {
292
+ path: "",
293
+ verified: true
294
+ }]);
295
+ });
296
+ test("tampering with an embedded signed child invalidates both proofs", async () => {
297
+ const created = Temporal.Instant.from("2023-02-24T23:36:38Z");
298
+ const tampered = await serializeOutgoing(await signOuterCreate(created, "tampered", await signDistinctContextNote(created, "tampered")));
299
+ const tamperedInner = tampered.object;
300
+ tamperedInner.content = "A tampered portable note";
301
+ assertEquals(await verifyProof(tamperedInner, await parseProof(tamperedInner), options), null);
302
+ assertEquals(await verifyProof(tampered, await parseProof(tampered), options), null);
303
+ });
304
+ test("replacing an embedded child proof invalidates only the outer proof", async () => {
305
+ const created = Temporal.Instant.from("2023-02-24T23:36:38Z");
306
+ const replacementCreated = Temporal.Instant.from("2023-02-25T23:36:38Z");
307
+ const inner = await signDistinctContextNote(created, "replaced-proof");
308
+ const replacementProof = (await serializeOutgoing(await signDistinctContextNote(replacementCreated, "replaced-proof"), distinctInnerContext)).proof;
309
+ const compound = await serializeOutgoing(await signOuterCreate(created, "replaced-proof", inner));
310
+ const replacedInner = compound.object;
311
+ replacedInner.proof = replacementProof;
312
+ assertEquals((await verifyProof(replacedInner, await parseProof(replacedInner), options))?.id, innerKeyId);
313
+ assertEquals(await verifyProof(compound, await parseProof(compound), options), null);
314
+ });
315
+ test("cloning or re-signing a signed child drops its retained representation", async () => {
316
+ const created = Temporal.Instant.from("2023-02-24T23:36:38Z");
317
+ const inner = await signDistinctContextNote(created, "cloned");
318
+ const cloned = inner.clone({});
319
+ assert(cloned instanceof Note);
320
+ const clonedEmbedded = (await serializeOutgoing(await signOuterCreate(created, "cloned", cloned))).object;
321
+ assertEquals(clonedEmbedded["@context"], void 0);
322
+ assertEquals(clonedEmbedded.proof["@context"], void 0);
323
+ const reSignedEmbedded = (await serializeOutgoing(await signOuterCreate(created, "re-signed", await signObject(inner, ed25519PrivateKey, innerKeyId, {
324
+ ...options,
325
+ context: distinctInnerContext,
326
+ created
327
+ })))).object;
328
+ assertEquals(reSignedEmbedded["@context"], void 0);
329
+ });
330
+ test("mutating a signed child does not change its embedded representation", async () => {
331
+ const created = Temporal.Instant.from("2023-02-24T23:36:38Z");
332
+ const inner = await signDistinctContextNote(created, "mutated");
333
+ const standaloneInner = await serializeOutgoing(inner, distinctInnerContext);
334
+ const proof = (await Array.fromAsync(inner.getProofs(options)))[0];
335
+ assert(proof.proofValue != null);
336
+ proof.proofValue[0] ^= 255;
337
+ const embedded = (await serializeOutgoing(await signOuterCreate(created, "mutated", inner))).object;
338
+ assertEquals(serialize(embedded), serialize(standaloneInner));
339
+ assertEquals((await verifyProof(embedded, await parseProof(embedded), options))?.id, innerKeyId);
340
+ });
341
+ test("a signed child is embedded through a compactable ancestor too", async () => {
342
+ const inner = await signDistinctContextNote(Temporal.Instant.from("2023-02-24T23:36:38Z"), "compactable-parent");
343
+ const standaloneInner = await serializeOutgoing(inner, distinctInnerContext);
344
+ const wrapper = new Note({
345
+ id: parseIri(`ap+ef61://${innerDid}/objects/wrapper`),
346
+ attachments: [inner]
347
+ });
348
+ const embedded = (await new Question({
349
+ id: parseIri(`ap+ef61://${outerDid}/objects/question`),
350
+ exclusiveOptions: [wrapper]
351
+ }).toJsonLd()).oneOf.attachment;
352
+ assertEquals(serialize(embedded), serialize(standaloneInner));
353
+ assertEquals((await verifyProof(embedded, await parseProof(embedded), options))?.id, innerKeyId);
354
+ });
355
+ test("typed Create serialization bypasses a parsed child's JSON-LD cache", async () => {
356
+ const created = Temporal.Instant.from("2023-02-24T23:36:38Z");
357
+ const standaloneInner = await serializeOutgoing(await signDistinctContextNote(created, "reparsed-context"), distinctInnerContext);
358
+ const standaloneProof = await parseProof(standaloneInner);
359
+ const reparsedInner = await Note.fromJsonLd(standaloneInner, {
360
+ contextLoader: mockDocumentLoader,
361
+ documentLoader: mockDocumentLoader
362
+ });
363
+ assert(reparsedInner instanceof Note);
364
+ assertEquals(await reparsedInner.toJsonLd(), standaloneInner);
365
+ const reparsedCompound = await serializeOutgoing(await signOuterCreate(created, "reparsed-context", reparsedInner));
366
+ const reparsedEmbedded = reparsedCompound.object;
367
+ const reparsedEmbeddedProof = reparsedEmbedded.proof;
368
+ assertEquals(reparsedEmbedded["@context"], void 0);
369
+ assertEquals(reparsedEmbeddedProof["@context"], void 0);
370
+ assertEquals(reparsedEmbeddedProof.proofValue, standaloneInner.proof.proofValue);
371
+ assertEquals(await verifyProof(reparsedEmbedded, standaloneProof, options), null);
372
+ assertEquals((await verifyProof(reparsedCompound, await parseProof(reparsedCompound), options))?.id, outerKeyId);
373
+ });
374
+ test("verifyProof() does not invent a missing child context", async () => {
375
+ const received = structuredClone(map_local_create_note_default.documents.finalSecuredCompound);
376
+ const receivedInner = received.object;
377
+ const receivedInnerProof = receivedInner.proof;
378
+ delete receivedInner["@context"];
379
+ delete receivedInnerProof["@context"];
380
+ const snapshot = structuredClone(received);
381
+ const proof = await DataIntegrityProof.fromJsonLd(received.proof, inboundOptions);
382
+ assertEquals(await verifyProof(received, proof, inboundOptions), null);
383
+ assertEquals(received, snapshot);
384
+ const guessed = structuredClone(received);
385
+ const guessedInner = guessed.object;
386
+ const guessedInnerProof = guessedInner.proof;
387
+ guessedInner["@context"] = structuredClone(guessed["@context"]);
388
+ guessedInnerProof["@context"] = structuredClone(guessed["@context"]);
389
+ assertEquals((await verifyProof(guessed, proof, inboundOptions))?.id, outerKeyId);
390
+ });
391
+ test("signing a document too deep to retain still succeeds", async () => {
392
+ const created = Temporal.Instant.from("2023-02-24T23:36:38Z");
393
+ let deep = new Note({
394
+ id: parseIri(`ap+ef61://${innerDid}/objects/deep-leaf`),
395
+ content: "A portable note nested past the retention bounds"
396
+ });
397
+ for (let i = 0; i < 40; i++) deep = new Note({
398
+ id: parseIri(`ap+ef61://${innerDid}/objects/deep-${i}`),
399
+ attachments: [deep]
400
+ });
401
+ const signed = await signObject(deep, ed25519PrivateKey, innerKeyId, {
402
+ ...options,
403
+ context: distinctInnerContext,
404
+ created
405
+ });
406
+ assertEquals((await Array.fromAsync(signed.getProofs(options))).length, 1);
407
+ const embedded = (await serializeOutgoing(await signOuterCreate(created, "deep", signed))).object;
408
+ assertEquals(embedded["@context"], void 0);
409
+ });
410
+ //#endregion
411
+ export {};