@enbox/dwn-sdk-js 0.4.6 → 0.4.7

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 (371) hide show
  1. package/README.md +3 -1
  2. package/dist/browser.mjs +19 -78
  3. package/dist/browser.mjs.map +4 -4
  4. package/dist/esm/generated/precompiled-validators.js +1997 -1517
  5. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  6. package/dist/esm/src/core/constants.js +50 -0
  7. package/dist/esm/src/core/constants.js.map +1 -1
  8. package/dist/esm/src/core/dwn-error.js +28 -11
  9. package/dist/esm/src/core/dwn-error.js.map +1 -1
  10. package/dist/esm/src/core/encryption-control.js +785 -0
  11. package/dist/esm/src/core/encryption-control.js.map +1 -0
  12. package/dist/esm/src/core/message.js +6 -0
  13. package/dist/esm/src/core/message.js.map +1 -1
  14. package/dist/esm/src/core/messages-grant-authorization.js +36 -5
  15. package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
  16. package/dist/esm/src/core/protocol-authorization-action.js +3 -12
  17. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  18. package/dist/esm/src/core/protocol-authorization-validation.js +31 -30
  19. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  20. package/dist/esm/src/core/protocol-authorization.js +6 -0
  21. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  22. package/dist/esm/src/core/recording-validation-state-reader.js +3 -3
  23. package/dist/esm/src/core/recording-validation-state-reader.js.map +1 -1
  24. package/dist/esm/src/core/replication-apply.js +62 -108
  25. package/dist/esm/src/core/replication-apply.js.map +1 -1
  26. package/dist/esm/src/core/validation-state-reader.js +5 -6
  27. package/dist/esm/src/core/validation-state-reader.js.map +1 -1
  28. package/dist/esm/src/dwn.js +1 -2
  29. package/dist/esm/src/dwn.js.map +1 -1
  30. package/dist/esm/src/event-stream/event-emitter-wake-publisher.js +11 -11
  31. package/dist/esm/src/event-stream/event-emitter-wake-publisher.js.map +1 -1
  32. package/dist/esm/src/handlers/messages-query.js +6 -16
  33. package/dist/esm/src/handlers/messages-query.js.map +1 -1
  34. package/dist/esm/src/handlers/messages-read.js +4 -3
  35. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  36. package/dist/esm/src/handlers/messages-subscribe.js +26 -30
  37. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  38. package/dist/esm/src/handlers/protocols-configure.js +6 -4
  39. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  40. package/dist/esm/src/handlers/records-count.js +85 -10
  41. package/dist/esm/src/handlers/records-count.js.map +1 -1
  42. package/dist/esm/src/handlers/records-delete.js +11 -0
  43. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  44. package/dist/esm/src/handlers/records-query.js +140 -18
  45. package/dist/esm/src/handlers/records-query.js.map +1 -1
  46. package/dist/esm/src/handlers/records-read.js +20 -4
  47. package/dist/esm/src/handlers/records-read.js.map +1 -1
  48. package/dist/esm/src/handlers/records-subscribe.js +127 -11
  49. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  50. package/dist/esm/src/handlers/records-write.js +15 -0
  51. package/dist/esm/src/handlers/records-write.js.map +1 -1
  52. package/dist/esm/src/index.js +7 -10
  53. package/dist/esm/src/index.js.map +1 -1
  54. package/dist/esm/src/interfaces/protocols-configure.js +66 -9
  55. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  56. package/dist/esm/src/interfaces/records-write.js +43 -36
  57. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  58. package/dist/esm/src/jose/algorithms/signing/ed25519.js +5 -5
  59. package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
  60. package/dist/esm/src/jose/jws/general/verifier.js +1 -1
  61. package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
  62. package/dist/esm/src/protocols/encryption.js +32 -274
  63. package/dist/esm/src/protocols/encryption.js.map +1 -1
  64. package/dist/esm/src/store/blockstore-level.js +14 -23
  65. package/dist/esm/src/store/blockstore-level.js.map +1 -1
  66. package/dist/esm/src/store/blockstore-mock.js +10 -27
  67. package/dist/esm/src/store/blockstore-mock.js.map +1 -1
  68. package/dist/esm/src/store/blockstore-utils.js +45 -0
  69. package/dist/esm/src/store/blockstore-utils.js.map +1 -0
  70. package/dist/esm/src/store/blockstore.js +2 -0
  71. package/dist/esm/src/store/blockstore.js.map +1 -0
  72. package/dist/esm/src/store/data-store-level.js +4 -12
  73. package/dist/esm/src/store/data-store-level.js.map +1 -1
  74. package/dist/esm/src/store/level.js +7 -0
  75. package/dist/esm/src/store/level.js.map +1 -0
  76. package/dist/esm/src/types/encryption-types.js +4 -1
  77. package/dist/esm/src/types/encryption-types.js.map +1 -1
  78. package/dist/esm/src/utils/data-stream.js +25 -0
  79. package/dist/esm/src/utils/data-stream.js.map +1 -1
  80. package/dist/esm/src/utils/encryption.js +107 -19
  81. package/dist/esm/src/utils/encryption.js.map +1 -1
  82. package/dist/esm/src/utils/grant-key-coverage.js +180 -0
  83. package/dist/esm/src/utils/grant-key-coverage.js.map +1 -0
  84. package/dist/esm/src/utils/hd-key.js +1 -2
  85. package/dist/esm/src/utils/hd-key.js.map +1 -1
  86. package/dist/esm/src/utils/jws.js +7 -1
  87. package/dist/esm/src/utils/jws.js.map +1 -1
  88. package/dist/esm/src/utils/memory-cache.js +29 -8
  89. package/dist/esm/src/utils/memory-cache.js.map +1 -1
  90. package/dist/esm/src/utils/protocols.js +27 -0
  91. package/dist/esm/src/utils/protocols.js.map +1 -1
  92. package/dist/esm/src/utils/record-limit-occupancy.js +23 -3
  93. package/dist/esm/src/utils/record-limit-occupancy.js.map +1 -1
  94. package/dist/esm/src/utils/records.js +29 -0
  95. package/dist/esm/src/utils/records.js.map +1 -1
  96. package/dist/esm/src/utils/secp256k1.js +12 -11
  97. package/dist/esm/src/utils/secp256k1.js.map +1 -1
  98. package/dist/esm/src/utils/secp256r1.js +12 -20
  99. package/dist/esm/src/utils/secp256r1.js.map +1 -1
  100. package/dist/esm/src/utils/time.js +103 -25
  101. package/dist/esm/src/utils/time.js.map +1 -1
  102. package/dist/esm/tests/core/constants.spec.js +35 -0
  103. package/dist/esm/tests/core/constants.spec.js.map +1 -0
  104. package/dist/esm/tests/core/encryption-control.spec.js +100 -0
  105. package/dist/esm/tests/core/encryption-control.spec.js.map +1 -0
  106. package/dist/esm/tests/core/message.spec.js +35 -0
  107. package/dist/esm/tests/core/message.spec.js.map +1 -1
  108. package/dist/esm/tests/core/protocol-authorization.spec.js +1 -1
  109. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  110. package/dist/esm/tests/core/replication-apply.spec.js +157 -74
  111. package/dist/esm/tests/core/replication-apply.spec.js.map +1 -1
  112. package/dist/esm/tests/core/replication-replay-property.spec.js +2 -1
  113. package/dist/esm/tests/core/replication-replay-property.spec.js.map +1 -1
  114. package/dist/esm/tests/core/validation-read-closure.spec.js +14 -28
  115. package/dist/esm/tests/core/validation-read-closure.spec.js.map +1 -1
  116. package/dist/esm/tests/core/validation-state-reader.spec.js +19 -23
  117. package/dist/esm/tests/core/validation-state-reader.spec.js.map +1 -1
  118. package/dist/esm/tests/dwn.spec.js +2 -1
  119. package/dist/esm/tests/dwn.spec.js.map +1 -1
  120. package/dist/esm/tests/event-emitter-wake-publisher.spec.js +51 -0
  121. package/dist/esm/tests/event-emitter-wake-publisher.spec.js.map +1 -0
  122. package/dist/esm/tests/features/protocol-composition.spec.js +1 -1
  123. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  124. package/dist/esm/tests/features/records-record-limit.spec.js +1 -1
  125. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -1
  126. package/dist/esm/tests/fuzz/encryption.fuzz.spec.js +9 -1
  127. package/dist/esm/tests/fuzz/encryption.fuzz.spec.js.map +1 -1
  128. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js +1 -1
  129. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js.map +1 -1
  130. package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js +29 -1
  131. package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js.map +1 -1
  132. package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js +2 -2
  133. package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js.map +1 -1
  134. package/dist/esm/tests/fuzz/time.fuzz.spec.js +7 -1
  135. package/dist/esm/tests/fuzz/time.fuzz.spec.js.map +1 -1
  136. package/dist/esm/tests/handlers/messages-query.spec.js +123 -11
  137. package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -1
  138. package/dist/esm/tests/handlers/messages-read.spec.js +95 -0
  139. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  140. package/dist/esm/tests/handlers/messages-subscribe.spec.js +90 -0
  141. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  142. package/dist/esm/tests/handlers/protocols-configure.spec.js +66 -0
  143. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  144. package/dist/esm/tests/handlers/records-count.spec.js +370 -0
  145. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  146. package/dist/esm/tests/handlers/records-delete.spec.js +70 -1
  147. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  148. package/dist/esm/tests/handlers/records-query.spec.js +562 -1
  149. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  150. package/dist/esm/tests/handlers/records-read.spec.js +140 -2
  151. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  152. package/dist/esm/tests/handlers/records-subscribe.spec.js +241 -1
  153. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  154. package/dist/esm/tests/handlers/records-write.spec.js +1187 -29
  155. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  156. package/dist/esm/tests/interfaces/protocols-configure.spec.js +290 -2
  157. package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
  158. package/dist/esm/tests/interfaces/records-write.spec.js +47 -5
  159. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  160. package/dist/esm/tests/protocols/encryption.spec.js +116 -472
  161. package/dist/esm/tests/protocols/encryption.spec.js.map +1 -1
  162. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +13 -27
  163. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  164. package/dist/esm/tests/store/blockstore-level.spec.js +33 -10
  165. package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
  166. package/dist/esm/tests/store/blockstore-mock.spec.js +31 -7
  167. package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
  168. package/dist/esm/tests/store/blockstore-utils.spec.js +115 -0
  169. package/dist/esm/tests/store/blockstore-utils.spec.js.map +1 -0
  170. package/dist/esm/tests/store/index-level.spec.js +3 -3
  171. package/dist/esm/tests/store/index-level.spec.js.map +1 -1
  172. package/dist/esm/tests/test-stores.js +2 -1
  173. package/dist/esm/tests/test-stores.js.map +1 -1
  174. package/dist/esm/tests/utils/cid.spec.js +15 -0
  175. package/dist/esm/tests/utils/cid.spec.js.map +1 -1
  176. package/dist/esm/tests/utils/data-stream.spec.js +30 -0
  177. package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
  178. package/dist/esm/tests/utils/encryption-control-test-utils.js +111 -0
  179. package/dist/esm/tests/utils/encryption-control-test-utils.js.map +1 -0
  180. package/dist/esm/tests/utils/encryption.spec.js +198 -5
  181. package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
  182. package/dist/esm/tests/utils/grant-key-coverage.spec.js +262 -0
  183. package/dist/esm/tests/utils/grant-key-coverage.spec.js.map +1 -0
  184. package/dist/esm/tests/utils/memory-cache.spec.js +12 -0
  185. package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
  186. package/dist/esm/tests/utils/secp256r1.spec.js +2 -2
  187. package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
  188. package/dist/esm/tests/utils/test-data-generator.js +2 -1
  189. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  190. package/dist/esm/tests/utils/test-validation-state-reader.js +1 -1
  191. package/dist/esm/tests/utils/test-validation-state-reader.js.map +1 -1
  192. package/dist/esm/tests/utils/time.spec.js +26 -0
  193. package/dist/esm/tests/utils/time.spec.js.map +1 -1
  194. package/dist/esm/tests/validation/json-schemas/encryption/audience.spec.js +45 -0
  195. package/dist/esm/tests/validation/json-schemas/encryption/audience.spec.js.map +1 -0
  196. package/dist/esm/tests/validation/json-schemas/encryption/delivery.spec.js +47 -0
  197. package/dist/esm/tests/validation/json-schemas/encryption/delivery.spec.js.map +1 -0
  198. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +152 -0
  199. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
  200. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +46 -1
  201. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  202. package/dist/types/generated/precompiled-validators.d.ts +4 -4
  203. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  204. package/dist/types/src/core/constants.d.ts +39 -0
  205. package/dist/types/src/core/constants.d.ts.map +1 -1
  206. package/dist/types/src/core/dwn-error.d.ts +28 -11
  207. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  208. package/dist/types/src/core/encryption-control.d.ts +128 -0
  209. package/dist/types/src/core/encryption-control.d.ts.map +1 -0
  210. package/dist/types/src/core/message.d.ts +4 -0
  211. package/dist/types/src/core/message.d.ts.map +1 -1
  212. package/dist/types/src/core/messages-grant-authorization.d.ts +11 -0
  213. package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
  214. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  215. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  216. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  217. package/dist/types/src/core/recording-validation-state-reader.d.ts +2 -3
  218. package/dist/types/src/core/recording-validation-state-reader.d.ts.map +1 -1
  219. package/dist/types/src/core/replication-apply.d.ts +10 -1
  220. package/dist/types/src/core/replication-apply.d.ts.map +1 -1
  221. package/dist/types/src/core/validation-state-reader.d.ts +2 -3
  222. package/dist/types/src/core/validation-state-reader.d.ts.map +1 -1
  223. package/dist/types/src/dwn.d.ts.map +1 -1
  224. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts +1 -1
  225. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts.map +1 -1
  226. package/dist/types/src/handlers/messages-query.d.ts.map +1 -1
  227. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  228. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  229. package/dist/types/src/handlers/protocols-configure.d.ts +1 -0
  230. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  231. package/dist/types/src/handlers/records-count.d.ts +2 -0
  232. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  233. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  234. package/dist/types/src/handlers/records-query.d.ts +3 -0
  235. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  236. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  237. package/dist/types/src/handlers/records-subscribe.d.ts +2 -0
  238. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  239. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  240. package/dist/types/src/index.d.ts +10 -17
  241. package/dist/types/src/index.d.ts.map +1 -1
  242. package/dist/types/src/interfaces/protocols-configure.d.ts +13 -1
  243. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  244. package/dist/types/src/interfaces/records-write.d.ts +5 -1
  245. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  246. package/dist/types/src/jose/algorithms/signing/ed25519.d.ts.map +1 -1
  247. package/dist/types/src/protocols/encryption.d.ts +2 -19
  248. package/dist/types/src/protocols/encryption.d.ts.map +1 -1
  249. package/dist/types/src/store/blockstore-level.d.ts +11 -11
  250. package/dist/types/src/store/blockstore-level.d.ts.map +1 -1
  251. package/dist/types/src/store/blockstore-mock.d.ts +12 -12
  252. package/dist/types/src/store/blockstore-mock.d.ts.map +1 -1
  253. package/dist/types/src/store/blockstore-utils.d.ts +23 -0
  254. package/dist/types/src/store/blockstore-utils.d.ts.map +1 -0
  255. package/dist/types/src/store/blockstore.d.ts +3 -0
  256. package/dist/types/src/store/blockstore.d.ts.map +1 -0
  257. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  258. package/dist/types/src/store/level.d.ts +13 -0
  259. package/dist/types/src/store/level.d.ts.map +1 -0
  260. package/dist/types/src/types/cache.d.ts +2 -2
  261. package/dist/types/src/types/cache.d.ts.map +1 -1
  262. package/dist/types/src/types/encryption-types.d.ts +31 -2
  263. package/dist/types/src/types/encryption-types.d.ts.map +1 -1
  264. package/dist/types/src/types/validation-state-reader.d.ts +3 -5
  265. package/dist/types/src/types/validation-state-reader.d.ts.map +1 -1
  266. package/dist/types/src/utils/data-stream.d.ts +5 -0
  267. package/dist/types/src/utils/data-stream.d.ts.map +1 -1
  268. package/dist/types/src/utils/encryption.d.ts +53 -24
  269. package/dist/types/src/utils/encryption.d.ts.map +1 -1
  270. package/dist/types/src/utils/grant-key-coverage.d.ts +36 -0
  271. package/dist/types/src/utils/grant-key-coverage.d.ts.map +1 -0
  272. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  273. package/dist/types/src/utils/jws.d.ts.map +1 -1
  274. package/dist/types/src/utils/memory-cache.d.ts +4 -2
  275. package/dist/types/src/utils/memory-cache.d.ts.map +1 -1
  276. package/dist/types/src/utils/protocols.d.ts +11 -0
  277. package/dist/types/src/utils/protocols.d.ts.map +1 -1
  278. package/dist/types/src/utils/record-limit-occupancy.d.ts +7 -0
  279. package/dist/types/src/utils/record-limit-occupancy.d.ts.map +1 -1
  280. package/dist/types/src/utils/records.d.ts +2 -0
  281. package/dist/types/src/utils/records.d.ts.map +1 -1
  282. package/dist/types/src/utils/secp256k1.d.ts.map +1 -1
  283. package/dist/types/src/utils/secp256r1.d.ts.map +1 -1
  284. package/dist/types/src/utils/time.d.ts +21 -13
  285. package/dist/types/src/utils/time.d.ts.map +1 -1
  286. package/dist/types/tests/core/constants.spec.d.ts +2 -0
  287. package/dist/types/tests/core/constants.spec.d.ts.map +1 -0
  288. package/dist/types/tests/core/encryption-control.spec.d.ts +2 -0
  289. package/dist/types/tests/core/encryption-control.spec.d.ts.map +1 -0
  290. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  291. package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts +2 -0
  292. package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts.map +1 -0
  293. package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -1
  294. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  295. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  296. package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
  297. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  298. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  299. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  300. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  301. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  302. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  303. package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -1
  304. package/dist/types/tests/store/blockstore-utils.spec.d.ts +2 -0
  305. package/dist/types/tests/store/blockstore-utils.spec.d.ts.map +1 -0
  306. package/dist/types/tests/test-stores.d.ts.map +1 -1
  307. package/dist/types/tests/utils/encryption-control-test-utils.d.ts +46 -0
  308. package/dist/types/tests/utils/encryption-control-test-utils.d.ts.map +1 -0
  309. package/dist/types/tests/utils/grant-key-coverage.spec.d.ts +2 -0
  310. package/dist/types/tests/utils/grant-key-coverage.spec.d.ts.map +1 -0
  311. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  312. package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts +2 -0
  313. package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts.map +1 -0
  314. package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts +2 -0
  315. package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts.map +1 -0
  316. package/package.json +47 -28
  317. package/src/core/constants.ts +61 -0
  318. package/src/core/dwn-error.ts +28 -11
  319. package/src/core/encryption-control.ts +1249 -0
  320. package/src/core/message.ts +7 -0
  321. package/src/core/messages-grant-authorization.ts +60 -9
  322. package/src/core/protocol-authorization-action.ts +3 -13
  323. package/src/core/protocol-authorization-validation.ts +66 -46
  324. package/src/core/protocol-authorization.ts +7 -0
  325. package/src/core/recording-validation-state-reader.ts +4 -5
  326. package/src/core/replication-apply.ts +77 -133
  327. package/src/core/validation-state-reader.ts +6 -8
  328. package/src/dwn.ts +1 -2
  329. package/src/event-stream/event-emitter-wake-publisher.ts +10 -14
  330. package/src/handlers/messages-query.ts +6 -22
  331. package/src/handlers/messages-read.ts +4 -3
  332. package/src/handlers/messages-subscribe.ts +34 -30
  333. package/src/handlers/protocols-configure.ts +7 -4
  334. package/src/handlers/records-count.ts +111 -10
  335. package/src/handlers/records-delete.ts +15 -0
  336. package/src/handlers/records-query.ts +176 -20
  337. package/src/handlers/records-read.ts +19 -6
  338. package/src/handlers/records-subscribe.ts +158 -8
  339. package/src/handlers/records-write.ts +19 -0
  340. package/src/index.ts +48 -21
  341. package/src/interfaces/protocols-configure.ts +102 -11
  342. package/src/interfaces/records-write.ts +49 -43
  343. package/src/jose/algorithms/signing/ed25519.ts +7 -6
  344. package/src/jose/jws/general/verifier.ts +3 -3
  345. package/src/protocols/encryption.ts +50 -420
  346. package/src/store/blockstore-level.ts +33 -37
  347. package/src/store/blockstore-mock.ts +24 -38
  348. package/src/store/blockstore-utils.ts +85 -0
  349. package/src/store/blockstore.ts +8 -0
  350. package/src/store/data-store-level.ts +5 -12
  351. package/src/store/level.ts +19 -0
  352. package/src/types/cache.ts +3 -3
  353. package/src/types/encryption-types.ts +39 -2
  354. package/src/types/validation-state-reader.ts +3 -5
  355. package/src/utils/data-stream.ts +29 -1
  356. package/src/utils/encryption.ts +190 -60
  357. package/src/utils/grant-key-coverage.ts +303 -0
  358. package/src/utils/hd-key.ts +1 -2
  359. package/src/utils/jws.ts +8 -2
  360. package/src/utils/memory-cache.ts +42 -11
  361. package/src/utils/protocols.ts +32 -0
  362. package/src/utils/record-limit-occupancy.ts +34 -5
  363. package/src/utils/records.ts +36 -2
  364. package/src/utils/secp256k1.ts +12 -12
  365. package/src/utils/secp256r1.ts +12 -22
  366. package/src/utils/time.ts +145 -27
  367. package/dist/esm/tests/validation/json-schemas/encryption/audience-key.spec.js +0 -40
  368. package/dist/esm/tests/validation/json-schemas/encryption/audience-key.spec.js.map +0 -1
  369. package/dist/types/tests/validation/json-schemas/encryption/audience-key.spec.d.ts +0 -2
  370. package/dist/types/tests/validation/json-schemas/encryption/audience-key.spec.d.ts.map +0 -1
  371. package/src/types/mitt.d.ts +0 -28
@@ -1,6 +1,6 @@
1
1
  import { TestDataGenerator } from '../utils/test-data-generator.js';
2
2
  import { describe, expect, it } from 'bun:test';
3
- import { ContentEncryptionAlgorithm, DwnErrorCode, DwnInterfaceName, DwnMethodName, Encoder, Encryption, EncryptionProtocol, Jws, KeyDerivationScheme, RecordsWrite, Time, } from '../../src/index.js';
3
+ import { DwnErrorCode, DwnInterfaceName, DwnMethodName, Encryption, EncryptionProtocol, Jws, KeyAgreementAlgorithm, KeyDerivationScheme, RecordsWrite, Time, } from '../../src/index.js';
4
4
  describe('EncryptionProtocol', () => {
5
5
  it('should expose the encryption protocol uri and definition', () => {
6
6
  const encryptionProtocol = new EncryptionProtocol();
@@ -20,388 +20,148 @@ describe('EncryptionProtocol', () => {
20
20
  const encryptionProtocol = new EncryptionProtocol();
21
21
  await encryptionProtocol.preProcessWrite(alice.did, recordsWrite.message, createValidationStateReader({}));
22
22
  });
23
- it('should accept audienceEpoch records for role paths with key agreement', async () => {
24
- const alice = await TestDataGenerator.generatePersona();
25
- const protocol = 'https://example.com/protocol/chat';
26
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
27
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey);
28
- const message = await createAudienceEpochMessage({
29
- protocol,
30
- role: 'chat/member',
31
- contextId: 'chat1',
32
- epoch: 1,
33
- publicKeyJwk: rolePublicKey,
34
- signer: Jws.createSigner(alice),
35
- });
36
- const encryptionProtocol = new EncryptionProtocol();
37
- await encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({ protocolDefinition }));
38
- });
39
- it('should reject audienceEpoch records that are encrypted', async () => {
40
- const alice = await TestDataGenerator.generatePersona();
41
- const protocol = 'https://example.com/protocol/chat';
42
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
43
- const message = await createAudienceEpochMessage({
44
- protocol,
45
- role: 'chat/member',
46
- contextId: 'chat1',
47
- epoch: 1,
48
- publicKeyJwk: rolePublicKey,
49
- signer: Jws.createSigner(alice),
50
- });
51
- message.encryption = createTestEncryptionProperty();
52
- const encryptionProtocol = new EncryptionProtocol();
53
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({}))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted);
54
- });
55
- it('should reject audienceEpoch records with missing required tags', async () => {
23
+ it('should accept grantKey records covered by an ancestor protocolPath read grant', async () => {
56
24
  const alice = await TestDataGenerator.generatePersona();
57
- const protocol = 'https://example.com/protocol/chat';
58
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
59
- const message = await createAudienceEpochMessage({
25
+ const bob = await TestDataGenerator.generatePersona();
26
+ const protocol = 'https://example.com/protocol';
27
+ const grant = createGrant({
28
+ grantor: alice.did,
29
+ grantee: bob.did,
30
+ id: 'grant1',
60
31
  protocol,
61
- role: 'chat/member',
62
- contextId: 'chat1',
63
- epoch: 1,
64
- publicKeyJwk: rolePublicKey,
65
- signer: Jws.createSigner(alice),
32
+ protocolPath: 'message',
66
33
  });
67
- delete message.descriptor.tags.contextId;
68
- const encryptionProtocol = new EncryptionProtocol();
69
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({}))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag);
70
- });
71
- it('should reject audienceEpoch records with malformed integer tags', async () => {
72
- const alice = await TestDataGenerator.generatePersona();
73
- const protocol = 'https://example.com/protocol/chat';
74
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
75
- const message = await createAudienceEpochMessage({
34
+ const message = await createGrantKeyMessage({
35
+ grant,
76
36
  protocol,
77
- role: 'chat/member',
78
- contextId: 'chat1',
79
- epoch: 1,
80
- publicKeyJwk: rolePublicKey,
37
+ protocolPath: 'message/reply',
38
+ recipient: bob.did,
81
39
  signer: Jws.createSigner(alice),
82
40
  });
83
- message.descriptor.tags.epoch = '1';
84
41
  const encryptionProtocol = new EncryptionProtocol();
85
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({}))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag);
42
+ await encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant }));
86
43
  });
87
- it('should reject audienceEpoch records with inconsistent role context', async () => {
44
+ it('should accept read-grant grantKey records for referenced role paths outside the read subtree', async () => {
88
45
  const alice = await TestDataGenerator.generatePersona();
89
- const protocol = 'https://example.com/protocol/chat';
90
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
91
- const message = await createAudienceEpochMessage({
46
+ const bob = await TestDataGenerator.generatePersona();
47
+ const rolePublicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
48
+ const protocol = 'https://example.com/protocol';
49
+ const protocolDefinition = createGrantKeyCoverageProtocolDefinition(protocol, rolePublicKey);
50
+ const grant = createGrant({
51
+ grantor: alice.did,
52
+ grantee: bob.did,
53
+ id: 'grant1',
92
54
  protocol,
93
- role: 'chat/member',
94
- contextId: '',
95
- epoch: 1,
96
- publicKeyJwk: rolePublicKey,
97
- signer: Jws.createSigner(alice),
55
+ protocolPath: 'chat/message',
98
56
  });
99
- const encryptionProtocol = new EncryptionProtocol();
100
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({}))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateRoleAudienceContextInvalid);
101
- });
102
- it('should accept same-coordinate audienceEpoch records with different keyIds', async () => {
103
- const alice = await TestDataGenerator.generatePersona();
104
- const other = await TestDataGenerator.generatePersona();
105
- const protocol = 'https://example.com/protocol/chat';
106
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
107
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey);
108
- const conflictingEpoch = await createAudienceEpochMessage({
109
- protocol,
110
- role: 'chat/member',
111
- contextId: 'chat1',
112
- epoch: 1,
113
- publicKeyJwk: other.encryptionKeyPair.publicJwk,
114
- signer: Jws.createSigner(other),
115
- });
116
- const message = await createAudienceEpochMessage({
117
- protocol,
118
- role: 'chat/member',
119
- contextId: 'chat1',
120
- epoch: 1,
121
- publicKeyJwk: rolePublicKey,
122
- signer: Jws.createSigner(alice),
123
- });
124
- const encryptionProtocol = new EncryptionProtocol();
125
- await encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({
126
- audienceEpochs: [conflictingEpoch],
127
- protocolDefinition,
128
- }));
129
- });
130
- it('should reject audienceEpoch records authored by DIDs that cannot create the role', async () => {
131
- const alice = await TestDataGenerator.generatePersona();
132
- const protocol = 'https://example.com/protocol/chat';
133
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
134
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey, { memberActions: [] });
135
- const message = await createAudienceEpochMessage({
136
- protocol,
137
- role: 'chat/member',
138
- contextId: 'chat1',
139
- epoch: 1,
140
- publicKeyJwk: rolePublicKey,
141
- signer: Jws.createSigner(alice),
142
- });
143
- const encryptionProtocol = new EncryptionProtocol();
144
- await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceWriterUnauthorized);
145
- });
146
- it('should accept audienceEpoch records authored through an active local role', async () => {
147
- const alice = await TestDataGenerator.generatePersona();
148
- const protocol = 'https://example.com/protocol/chat';
149
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
150
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey, {
151
- memberActions: [{ can: ['create'], role: 'chat/admin' }],
152
- });
153
- const message = await createAudienceEpochMessage({
57
+ const message = await createGrantKeyMessage({
58
+ grant,
154
59
  protocol,
155
- role: 'chat/member',
156
- contextId: 'chat1',
157
- epoch: 1,
158
- publicKeyJwk: rolePublicKey,
60
+ protocolPath: 'chat/member',
61
+ recipient: bob.did,
159
62
  signer: Jws.createSigner(alice),
160
- protocolRole: 'chat/admin',
161
63
  });
162
64
  const encryptionProtocol = new EncryptionProtocol();
163
- await encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({
164
- hasMatchingRoleRecord: (input) => {
165
- return input.protocol === protocol &&
166
- input.protocolPath === 'chat/admin' &&
167
- input.recipient === alice.did &&
168
- input.contextIdPrefix === 'chat1';
169
- },
170
- protocolDefinition,
171
- }));
65
+ await encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant, protocolDefinition }));
172
66
  });
173
- it('should reject audienceEpoch records when the invoked role does not match the create rule', async () => {
67
+ it('should reject read-grant grantKey records for unreferenced role paths outside the read subtree', async () => {
174
68
  const alice = await TestDataGenerator.generatePersona();
175
- const protocol = 'https://example.com/protocol/chat';
176
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
177
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey, {
178
- memberActions: [{ can: ['create'], role: 'chat/admin' }],
179
- });
180
- const message = await createAudienceEpochMessage({
69
+ const bob = await TestDataGenerator.generatePersona();
70
+ const rolePublicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
71
+ const protocol = 'https://example.com/protocol';
72
+ const protocolDefinition = createGrantKeyCoverageProtocolDefinition(protocol, rolePublicKey);
73
+ const grant = createGrant({
74
+ grantor: alice.did,
75
+ grantee: bob.did,
76
+ id: 'grant1',
181
77
  protocol,
182
- role: 'chat/member',
183
- contextId: 'chat1',
184
- epoch: 1,
185
- publicKeyJwk: rolePublicKey,
186
- signer: Jws.createSigner(alice),
187
- protocolRole: 'chat/moderator',
188
- });
189
- const encryptionProtocol = new EncryptionProtocol();
190
- await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceWriterUnauthorized);
191
- });
192
- it('should accept audienceEpoch records authored through an active cross-protocol role', async () => {
193
- const alice = await TestDataGenerator.generatePersona();
194
- const protocol = 'https://example.com/protocol/chat';
195
- const roleProtocol = 'https://example.com/protocol/roles';
196
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
197
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey, {
198
- memberActions: [{ can: ['create'], role: 'roles:admin' }],
199
- uses: { roles: roleProtocol },
200
- });
201
- const message = await createAudienceEpochMessage({
202
- protocol,
203
- role: 'chat/member',
204
- contextId: 'chat1',
205
- epoch: 1,
206
- publicKeyJwk: rolePublicKey,
207
- signer: Jws.createSigner(alice),
208
- protocolRole: 'roles:admin',
209
- });
210
- const encryptionProtocol = new EncryptionProtocol();
211
- await encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({
212
- hasMatchingRoleRecord: (input) => {
213
- return input.protocol === roleProtocol &&
214
- input.protocolPath === 'admin' &&
215
- input.recipient === alice.did &&
216
- input.contextIdPrefix === undefined;
217
- },
218
- protocolDefinition,
219
- }));
220
- });
221
- it('should reject audienceEpoch records that invoke a cross-protocol role with an unknown alias', async () => {
222
- const alice = await TestDataGenerator.generatePersona();
223
- const protocol = 'https://example.com/protocol/chat';
224
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
225
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey, {
226
- memberActions: [{ can: ['create'], role: 'roles:admin' }],
78
+ protocolPath: 'chat/message',
227
79
  });
228
- const message = await createAudienceEpochMessage({
80
+ const message = await createGrantKeyMessage({
81
+ grant,
229
82
  protocol,
230
- role: 'chat/member',
231
- contextId: 'chat1',
232
- epoch: 1,
233
- publicKeyJwk: rolePublicKey,
234
- signer: Jws.createSigner(alice),
235
- protocolRole: 'roles:admin',
236
- });
237
- const encryptionProtocol = new EncryptionProtocol();
238
- await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceWriterUnauthorized);
239
- });
240
- it('should reject audienceKey records without a matching audienceEpoch', async () => {
241
- const alice = await TestDataGenerator.generatePersona();
242
- const bob = await TestDataGenerator.generatePersona();
243
- const protocol = 'https://example.com/protocol/chat';
244
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
245
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey);
246
- const message = await createAudienceKeyMessage({
247
- protocol,
248
- role: 'chat/member',
249
- contextId: 'chat1',
250
- epoch: 1,
251
- publicKeyJwk: rolePublicKey,
83
+ protocolPath: 'chat/admin',
252
84
  recipient: bob.did,
253
85
  signer: Jws.createSigner(alice),
254
86
  });
255
87
  const encryptionProtocol = new EncryptionProtocol();
256
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({
257
- audienceEpochs: [],
258
- hasMatchingRole: true,
259
- protocolDefinition,
260
- }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceEpochMissing);
88
+ await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant, protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
261
89
  });
262
- it('should reject audienceEpoch records for role paths without key agreement', async () => {
263
- const alice = await TestDataGenerator.generatePersona();
264
- const protocol = 'https://example.com/protocol/chat';
265
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
266
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey, { keyAgreement: false });
267
- const message = await createAudienceEpochMessage({
268
- protocol,
269
- role: 'chat/member',
270
- contextId: 'chat1',
271
- epoch: 1,
272
- publicKeyJwk: rolePublicKey,
273
- signer: Jws.createSigner(alice),
274
- });
275
- const encryptionProtocol = new EncryptionProtocol();
276
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({ protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateRoleAudienceInvalid);
277
- });
278
- it('should accept audienceKey records for active role holders', async () => {
90
+ it('should reject read-grant grantKey records for cross-protocol role references', async () => {
279
91
  const alice = await TestDataGenerator.generatePersona();
280
92
  const bob = await TestDataGenerator.generatePersona();
281
- const protocol = 'https://example.com/protocol/chat';
282
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
283
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey);
284
- const audienceEpoch = await createAudienceEpochMessage({
285
- protocol,
286
- role: 'chat/member',
287
- contextId: 'chat1',
288
- epoch: 1,
289
- publicKeyJwk: rolePublicKey,
290
- signer: Jws.createSigner(alice),
93
+ const rolePublicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
94
+ const protocol = 'https://example.com/protocol';
95
+ const protocolDefinition = createGrantKeyCoverageProtocolDefinition(protocol, rolePublicKey, {
96
+ messageRole: 'contacts:member',
97
+ uses: { contacts: 'https://example.com/contacts' },
291
98
  });
292
- const message = await createAudienceKeyMessage({
99
+ const grant = createGrant({
100
+ grantor: alice.did,
101
+ grantee: bob.did,
102
+ id: 'grant1',
293
103
  protocol,
294
- role: 'chat/member',
295
- contextId: 'chat1',
296
- epoch: 1,
297
- publicKeyJwk: rolePublicKey,
298
- recipient: bob.did,
299
- signer: Jws.createSigner(alice),
104
+ protocolPath: 'chat/message',
300
105
  });
301
- const encryptionProtocol = new EncryptionProtocol();
302
- await encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({
303
- audienceEpochs: [audienceEpoch],
304
- hasMatchingRole: true,
305
- protocolDefinition,
306
- }));
307
- });
308
- it('should reject audienceKey records that are not encrypted', async () => {
309
- const alice = await TestDataGenerator.generatePersona();
310
- const bob = await TestDataGenerator.generatePersona();
311
- const protocol = 'https://example.com/protocol/chat';
312
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
313
- const message = await createAudienceKeyMessage({
106
+ const message = await createGrantKeyMessage({
107
+ grant,
314
108
  protocol,
315
- role: 'chat/member',
316
- contextId: 'chat1',
317
- epoch: 1,
318
- publicKeyJwk: rolePublicKey,
109
+ protocolPath: 'chat/member',
319
110
  recipient: bob.did,
320
111
  signer: Jws.createSigner(alice),
321
- encrypted: false,
322
- });
323
- const encryptionProtocol = new EncryptionProtocol();
324
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({}))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateEncryptedDeliveryMissingEncryption);
325
- });
326
- it('should reject audienceKey records without a recipient', async () => {
327
- const alice = await TestDataGenerator.generatePersona();
328
- const protocol = 'https://example.com/protocol/chat';
329
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
330
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey);
331
- const audienceEpoch = await createAudienceEpochMessage({
332
- protocol,
333
- role: 'chat/member',
334
- contextId: 'chat1',
335
- epoch: 1,
336
- publicKeyJwk: rolePublicKey,
337
- signer: Jws.createSigner(alice),
338
- });
339
- const message = await createAudienceKeyMessage({
340
- protocol,
341
- role: 'chat/member',
342
- contextId: 'chat1',
343
- epoch: 1,
344
- publicKeyJwk: rolePublicKey,
345
- signer: Jws.createSigner(alice),
346
112
  });
347
113
  const encryptionProtocol = new EncryptionProtocol();
348
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({
349
- audienceEpochs: [audienceEpoch],
350
- protocolDefinition,
351
- }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceKeyRecipientMissing);
114
+ await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant, protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
352
115
  });
353
- it('should reject audienceKey records for recipients without the referenced role', async () => {
116
+ it('should accept write-grant grantKey records for covered role paths', async () => {
354
117
  const alice = await TestDataGenerator.generatePersona();
355
118
  const bob = await TestDataGenerator.generatePersona();
356
- const protocol = 'https://example.com/protocol/chat';
357
- const rolePublicKey = alice.encryptionKeyPair.publicJwk;
358
- const protocolDefinition = createRoleProtocolDefinition(protocol, rolePublicKey);
359
- const audienceEpoch = await createAudienceEpochMessage({
360
- protocol,
361
- role: 'chat/member',
362
- contextId: 'chat1',
363
- epoch: 1,
364
- publicKeyJwk: rolePublicKey,
365
- signer: Jws.createSigner(alice),
119
+ const rolePublicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
120
+ const protocol = 'https://example.com/protocol';
121
+ const protocolDefinition = createGrantKeyCoverageProtocolDefinition(protocol, rolePublicKey);
122
+ const grant = createGrant({
123
+ grantor: alice.did,
124
+ grantee: bob.did,
125
+ id: 'grant1',
126
+ method: DwnMethodName.Write,
127
+ protocol,
128
+ protocolPath: 'chat',
366
129
  });
367
- const message = await createAudienceKeyMessage({
130
+ const message = await createGrantKeyMessage({
131
+ grant,
368
132
  protocol,
369
- role: 'chat/member',
370
- contextId: 'chat1',
371
- epoch: 1,
372
- publicKeyJwk: rolePublicKey,
133
+ protocolPath: 'chat/member',
373
134
  recipient: bob.did,
374
135
  signer: Jws.createSigner(alice),
375
136
  });
376
137
  const encryptionProtocol = new EncryptionProtocol();
377
- await expect(encryptionProtocol.preProcessWrite(alice.did, message, createValidationStateReader({
378
- audienceEpochs: [audienceEpoch],
379
- hasMatchingRole: false,
380
- protocolDefinition,
381
- }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceKeyRoleRecordMissing);
138
+ await encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant, protocolDefinition }));
382
139
  });
383
- it('should accept grantKey records covered by an ancestor protocolPath read grant', async () => {
140
+ it('should reject write-grant grantKey records for covered non-role paths', async () => {
384
141
  const alice = await TestDataGenerator.generatePersona();
385
142
  const bob = await TestDataGenerator.generatePersona();
143
+ const rolePublicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
386
144
  const protocol = 'https://example.com/protocol';
145
+ const protocolDefinition = createGrantKeyCoverageProtocolDefinition(protocol, rolePublicKey);
387
146
  const grant = createGrant({
388
147
  grantor: alice.did,
389
148
  grantee: bob.did,
390
149
  id: 'grant1',
150
+ method: DwnMethodName.Write,
391
151
  protocol,
392
- protocolPath: 'message',
152
+ protocolPath: 'chat',
393
153
  });
394
154
  const message = await createGrantKeyMessage({
395
155
  grant,
396
156
  protocol,
397
- protocolPath: 'message/reply',
157
+ protocolPath: 'chat/message',
398
158
  recipient: bob.did,
399
159
  signer: Jws.createSigner(alice),
400
160
  });
401
161
  const encryptionProtocol = new EncryptionProtocol();
402
- await encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant }));
162
+ await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant, protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
403
163
  });
404
- it('should accept grantKey records covered by a Messages read grant', async () => {
164
+ it('should reject grantKey records covered only by a Messages read grant', async () => {
405
165
  const alice = await TestDataGenerator.generatePersona();
406
166
  const bob = await TestDataGenerator.generatePersona();
407
167
  const protocol = 'https://example.com/protocol';
@@ -419,12 +179,14 @@ describe('EncryptionProtocol', () => {
419
179
  signer: Jws.createSigner(alice),
420
180
  });
421
181
  const encryptionProtocol = new EncryptionProtocol();
422
- await encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant }));
182
+ await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
423
183
  });
424
184
  it('should reject protocol-scoped grantKey records for protocolPath-scoped read grants', async () => {
425
185
  const alice = await TestDataGenerator.generatePersona();
426
186
  const bob = await TestDataGenerator.generatePersona();
187
+ const rolePublicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
427
188
  const protocol = 'https://example.com/protocol';
189
+ const protocolDefinition = createGrantKeyCoverageProtocolDefinition(protocol, rolePublicKey);
428
190
  const grant = createGrant({
429
191
  grantor: alice.did,
430
192
  grantee: bob.did,
@@ -439,7 +201,7 @@ describe('EncryptionProtocol', () => {
439
201
  signer: Jws.createSigner(alice),
440
202
  });
441
203
  const encryptionProtocol = new EncryptionProtocol();
442
- await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
204
+ await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant, protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
443
205
  });
444
206
  it('should reject grantKey records outside the grant protocol', async () => {
445
207
  const alice = await TestDataGenerator.generatePersona();
@@ -462,7 +224,9 @@ describe('EncryptionProtocol', () => {
462
224
  it('should reject grantKey records outside the grant protocolPath subtree', async () => {
463
225
  const alice = await TestDataGenerator.generatePersona();
464
226
  const bob = await TestDataGenerator.generatePersona();
227
+ const rolePublicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
465
228
  const protocol = 'https://example.com/protocol';
229
+ const protocolDefinition = createGrantKeyCoverageProtocolDefinition(protocol, rolePublicKey);
466
230
  const grant = createGrant({
467
231
  grantor: alice.did,
468
232
  grantee: bob.did,
@@ -478,7 +242,7 @@ describe('EncryptionProtocol', () => {
478
242
  signer: Jws.createSigner(alice),
479
243
  });
480
244
  const encryptionProtocol = new EncryptionProtocol();
481
- await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
245
+ await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant, protocolDefinition }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch);
482
246
  });
483
247
  it('should reject grantKey records whose recipient is not the grant grantee', async () => {
484
248
  const alice = await TestDataGenerator.generatePersona();
@@ -626,15 +390,15 @@ describe('EncryptionProtocol', () => {
626
390
  const encryptionProtocol = new EncryptionProtocol();
627
391
  await expect(encryptionProtocol.preProcessWrite('did:example:tenant', message, createValidationStateReader({ grant }))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateEncryptedDeliveryMissingEncryption);
628
392
  });
629
- it('should reject grantKey records for non-read permission grants', async () => {
393
+ it('should reject grantKey records for context-scoped permission grants', async () => {
630
394
  const alice = await TestDataGenerator.generatePersona();
631
395
  const bob = await TestDataGenerator.generatePersona();
632
396
  const protocol = 'https://example.com/protocol';
633
397
  const grant = createGrant({
398
+ contextId: 'context1',
634
399
  grantor: alice.did,
635
400
  grantee: bob.did,
636
401
  id: 'grant1',
637
- method: DwnMethodName.Write,
638
402
  protocol,
639
403
  });
640
404
  const message = await createGrantKeyMessage({
@@ -660,74 +424,22 @@ describe('EncryptionProtocol', () => {
660
424
  const encryptionProtocol = new EncryptionProtocol();
661
425
  await expect(encryptionProtocol.validateRecord(recordsWrite.message, TestDataGenerator.randomBytes(32))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateSchemaUnexpectedRecord);
662
426
  });
663
- it('should reject audienceEpoch records whose keyId does not match the public key', async () => {
664
- const alice = await TestDataGenerator.generatePersona();
665
- const other = await TestDataGenerator.generatePersona();
666
- const protocol = 'https://example.com/protocol/chat';
667
- const message = await createAudienceEpochMessage({
668
- protocol,
669
- role: 'chat/member',
670
- contextId: 'chat1',
671
- epoch: 1,
672
- publicKeyJwk: alice.encryptionKeyPair.publicJwk,
673
- keyId: await Encryption.getKeyId(other.encryptionKeyPair.publicJwk),
674
- signer: Jws.createSigner(alice),
675
- });
676
- const encryptionProtocol = new EncryptionProtocol();
677
- await expect(encryptionProtocol.validateRecord(message, Encoder.base64UrlToBytes(message.encodedData))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceEpochKeyIdMismatch);
678
- });
679
- it('should reject audienceEpoch records whose payload does not match tags', async () => {
680
- const alice = await TestDataGenerator.generatePersona();
681
- const protocol = 'https://example.com/protocol/chat';
682
- const keyId = await Encryption.getKeyId(alice.encryptionKeyPair.publicJwk);
683
- const message = await createAudienceEpochMessage({
684
- protocol,
685
- role: 'chat/member',
686
- contextId: 'chat1',
687
- epoch: 1,
688
- publicKeyJwk: alice.encryptionKeyPair.publicJwk,
689
- keyId,
690
- signer: Jws.createSigner(alice),
691
- });
692
- const mismatchingPayload = Encoder.objectToBytes({
693
- protocol,
694
- contextId: 'chat2',
695
- role: 'chat/member',
696
- epoch: 1,
697
- keyId,
698
- publicKeyJwk: alice.encryptionKeyPair.publicJwk,
699
- });
700
- const encryptionProtocol = new EncryptionProtocol();
701
- await expect(encryptionProtocol.validateRecord(message, mismatchingPayload)).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceTagsMismatch);
702
- });
703
- it('should reject encrypted audienceEpoch records', async () => {
427
+ it('should reject unencrypted grantKey records', async () => {
704
428
  const alice = await TestDataGenerator.generatePersona();
429
+ const bob = await TestDataGenerator.generatePersona();
705
430
  const protocol = 'https://example.com/protocol/chat';
706
- const message = await createAudienceEpochMessage({
431
+ const grant = createGrant({
432
+ grantor: alice.did,
433
+ grantee: bob.did,
434
+ id: 'grant1',
707
435
  protocol,
708
- role: 'chat/member',
709
- contextId: 'chat1',
710
- epoch: 1,
711
- publicKeyJwk: alice.encryptionKeyPair.publicJwk,
712
- signer: Jws.createSigner(alice),
713
436
  });
714
- message.encryption = createTestEncryptionProperty();
715
- const encryptionProtocol = new EncryptionProtocol();
716
- await expect(encryptionProtocol.validateRecord(message, Encoder.base64UrlToBytes(message.encodedData))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted);
717
- });
718
- it('should reject unencrypted delivery records', async () => {
719
- const alice = await TestDataGenerator.generatePersona();
720
- const bob = await TestDataGenerator.generatePersona();
721
- const protocol = 'https://example.com/protocol/chat';
722
- const message = await createAudienceKeyMessage({
437
+ const message = await createGrantKeyMessage({
438
+ encrypted: false,
439
+ grant,
723
440
  protocol,
724
- role: 'chat/member',
725
- contextId: 'chat1',
726
- epoch: 1,
727
- publicKeyJwk: alice.encryptionKeyPair.publicJwk,
728
441
  recipient: bob.did,
729
442
  signer: Jws.createSigner(alice),
730
- encrypted: false,
731
443
  });
732
444
  const encryptionProtocol = new EncryptionProtocol();
733
445
  await expect(encryptionProtocol.validateRecord(message, TestDataGenerator.randomBytes(32))).rejects.toThrow(DwnErrorCode.EncryptionProtocolValidateEncryptedDeliveryMissingEncryption);
@@ -736,7 +448,7 @@ describe('EncryptionProtocol', () => {
736
448
  describe('mapErrorToStatusCode()', () => {
737
449
  it('should map encryption validation errors to bad request', () => {
738
450
  const encryptionProtocol = new EncryptionProtocol();
739
- expect(encryptionProtocol.mapErrorToStatusCode(DwnErrorCode.EncryptionProtocolValidateAudienceEpochMissing)).toBe(400);
451
+ expect(encryptionProtocol.mapErrorToStatusCode(DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch)).toBe(400);
740
452
  expect(encryptionProtocol.mapErrorToStatusCode(DwnErrorCode.GrantAuthorizationGrantExpired)).toBeUndefined();
741
453
  });
742
454
  });
@@ -770,6 +482,7 @@ function createGrant(input) {
770
482
  interface: input.interface ?? DwnInterfaceName.Records,
771
483
  method: input.method ?? DwnMethodName.Read,
772
484
  protocol: input.protocol,
485
+ contextId: input.contextId,
773
486
  protocolPath: input.protocolPath,
774
487
  },
775
488
  };
@@ -780,25 +493,9 @@ function createValidationStateReader(input) {
780
493
  fetchGrant: async () => input.grant,
781
494
  fetchOldestGrantRevocation: async () => input.revocation,
782
495
  fetchProtocolDefinition: async () => input.protocolDefinition,
783
- hasMatchingRoleRecord: async (roleInput) => {
784
- return input.hasMatchingRoleRecord?.(roleInput) ?? input.hasMatchingRole ?? true;
785
- },
786
- queryAudienceEpochs: async () => input.audienceEpochs ?? [],
787
496
  };
788
497
  }
789
- function createRoleProtocolDefinition(protocol, publicKeyJwk, options = {}) {
790
- const adminRuleSet = {
791
- $actions: [{ can: ['create'], who: 'anyone' }],
792
- $role: true,
793
- };
794
- const memberRuleSet = {
795
- $actions: options.memberActions ?? [{ can: ['create'], who: 'anyone' }],
796
- $role: true,
797
- };
798
- if (options.keyAgreement !== false) {
799
- adminRuleSet.$keyAgreement = { publicKeyJwk };
800
- memberRuleSet.$keyAgreement = { publicKeyJwk };
801
- }
498
+ function createGrantKeyCoverageProtocolDefinition(protocol, publicKeyJwk, options = {}) {
802
499
  return {
803
500
  published: true,
804
501
  protocol,
@@ -807,73 +504,26 @@ function createRoleProtocolDefinition(protocol, publicKeyJwk, options = {}) {
807
504
  admin: { dataFormats: ['application/json'] },
808
505
  chat: { dataFormats: ['application/json'] },
809
506
  member: { dataFormats: ['application/json'] },
507
+ message: { dataFormats: ['application/json'], encryptionRequired: true },
810
508
  },
811
509
  structure: {
812
510
  chat: {
813
- admin: adminRuleSet,
814
- member: memberRuleSet,
511
+ admin: {
512
+ $keyAgreement: { publicKeyJwk },
513
+ $role: true,
514
+ },
515
+ member: {
516
+ $keyAgreement: { publicKeyJwk },
517
+ $role: true,
518
+ },
519
+ message: {
520
+ $actions: [{ can: ['read'], role: options.messageRole ?? 'chat/member' }],
521
+ $keyAgreement: { publicKeyJwk },
522
+ },
815
523
  },
816
524
  },
817
525
  };
818
526
  }
819
- async function createAudienceEpochMessage(input) {
820
- const keyId = input.keyId ?? await Encryption.getKeyId(input.publicKeyJwk);
821
- const data = Encoder.objectToBytes({
822
- protocol: input.protocol,
823
- contextId: input.contextId,
824
- role: input.role,
825
- epoch: input.epoch,
826
- keyId,
827
- publicKeyJwk: input.publicKeyJwk,
828
- });
829
- const recordsWrite = await RecordsWrite.create({
830
- data,
831
- dataFormat: 'application/json',
832
- protocol: EncryptionProtocol.uri,
833
- protocolPath: EncryptionProtocol.audienceEpochPath,
834
- protocolRole: input.protocolRole,
835
- signer: input.signer,
836
- tags: {
837
- protocol: input.protocol,
838
- contextId: input.contextId,
839
- role: input.role,
840
- epoch: input.epoch,
841
- keyId,
842
- },
843
- });
844
- return {
845
- ...recordsWrite.message,
846
- encodedData: Encoder.bytesToBase64Url(data),
847
- };
848
- }
849
- async function createAudienceKeyMessage(input) {
850
- const keyId = await Encryption.getKeyId(input.publicKeyJwk);
851
- const recordsWrite = await RecordsWrite.create({
852
- data: TestDataGenerator.randomBytes(32),
853
- dataFormat: 'application/json',
854
- encryptionInput: input.encrypted === false ? undefined : {
855
- initializationVector: TestDataGenerator.randomBytes(16),
856
- key: TestDataGenerator.randomBytes(32),
857
- keyEncryptionInputs: [{
858
- derivationScheme: KeyDerivationScheme.ProtocolPath,
859
- keyId,
860
- publicKey: input.publicKeyJwk,
861
- }],
862
- },
863
- protocol: EncryptionProtocol.uri,
864
- protocolPath: EncryptionProtocol.audienceKeyPath,
865
- recipient: input.recipient,
866
- signer: input.signer,
867
- tags: {
868
- protocol: input.protocol,
869
- contextId: input.contextId,
870
- role: input.role,
871
- epoch: input.epoch,
872
- keyId,
873
- },
874
- });
875
- return recordsWrite.message;
876
- }
877
527
  async function createGrantKeyMessage(input) {
878
528
  const publicKey = (await TestDataGenerator.generatePersona()).encryptionKeyPair.publicJwk;
879
529
  const tags = {
@@ -891,6 +541,7 @@ async function createGrantKeyMessage(input) {
891
541
  initializationVector: TestDataGenerator.randomBytes(16),
892
542
  key: TestDataGenerator.randomBytes(32),
893
543
  keyEncryptionInputs: [{
544
+ algorithm: KeyAgreementAlgorithm.X25519HkdfSha256A256Kw,
894
545
  derivationScheme: KeyDerivationScheme.ProtocolPath,
895
546
  keyId: await Encryption.getKeyId(publicKey),
896
547
  publicKey,
@@ -904,11 +555,4 @@ async function createGrantKeyMessage(input) {
904
555
  });
905
556
  return recordsWrite.message;
906
557
  }
907
- function createTestEncryptionProperty() {
908
- return {
909
- algorithm: ContentEncryptionAlgorithm.A256CTR,
910
- initializationVector: Encoder.bytesToBase64Url(TestDataGenerator.randomBytes(16)),
911
- keyEncryption: [],
912
- };
913
- }
914
558
  //# sourceMappingURL=encryption.spec.js.map