@enbox/dwn-sdk-js 0.4.6 → 0.4.8

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 (375) 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 +2324 -1525
  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 +29 -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 +8 -11
  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 +60 -270
  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 +187 -452
  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/encryption/wrapped-grant-key-envelope.spec.js +43 -0
  199. package/dist/esm/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.js.map +1 -0
  200. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +152 -0
  201. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
  202. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +46 -1
  203. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  204. package/dist/types/generated/precompiled-validators.d.ts +20 -4
  205. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  206. package/dist/types/src/core/constants.d.ts +39 -0
  207. package/dist/types/src/core/constants.d.ts.map +1 -1
  208. package/dist/types/src/core/dwn-error.d.ts +29 -11
  209. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  210. package/dist/types/src/core/encryption-control.d.ts +128 -0
  211. package/dist/types/src/core/encryption-control.d.ts.map +1 -0
  212. package/dist/types/src/core/message.d.ts +4 -0
  213. package/dist/types/src/core/message.d.ts.map +1 -1
  214. package/dist/types/src/core/messages-grant-authorization.d.ts +11 -0
  215. package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
  216. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  217. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  218. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  219. package/dist/types/src/core/recording-validation-state-reader.d.ts +2 -3
  220. package/dist/types/src/core/recording-validation-state-reader.d.ts.map +1 -1
  221. package/dist/types/src/core/replication-apply.d.ts +10 -1
  222. package/dist/types/src/core/replication-apply.d.ts.map +1 -1
  223. package/dist/types/src/core/validation-state-reader.d.ts +2 -3
  224. package/dist/types/src/core/validation-state-reader.d.ts.map +1 -1
  225. package/dist/types/src/dwn.d.ts.map +1 -1
  226. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts +1 -1
  227. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts.map +1 -1
  228. package/dist/types/src/handlers/messages-query.d.ts.map +1 -1
  229. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  230. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  231. package/dist/types/src/handlers/protocols-configure.d.ts +1 -0
  232. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  233. package/dist/types/src/handlers/records-count.d.ts +2 -0
  234. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  235. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  236. package/dist/types/src/handlers/records-query.d.ts +3 -0
  237. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  238. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  239. package/dist/types/src/handlers/records-subscribe.d.ts +2 -0
  240. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  241. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  242. package/dist/types/src/index.d.ts +12 -18
  243. package/dist/types/src/index.d.ts.map +1 -1
  244. package/dist/types/src/interfaces/protocols-configure.d.ts +13 -1
  245. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  246. package/dist/types/src/interfaces/records-write.d.ts +5 -1
  247. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  248. package/dist/types/src/jose/algorithms/signing/ed25519.d.ts.map +1 -1
  249. package/dist/types/src/protocols/encryption.d.ts +15 -19
  250. package/dist/types/src/protocols/encryption.d.ts.map +1 -1
  251. package/dist/types/src/store/blockstore-level.d.ts +11 -11
  252. package/dist/types/src/store/blockstore-level.d.ts.map +1 -1
  253. package/dist/types/src/store/blockstore-mock.d.ts +12 -12
  254. package/dist/types/src/store/blockstore-mock.d.ts.map +1 -1
  255. package/dist/types/src/store/blockstore-utils.d.ts +23 -0
  256. package/dist/types/src/store/blockstore-utils.d.ts.map +1 -0
  257. package/dist/types/src/store/blockstore.d.ts +3 -0
  258. package/dist/types/src/store/blockstore.d.ts.map +1 -0
  259. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  260. package/dist/types/src/store/level.d.ts +13 -0
  261. package/dist/types/src/store/level.d.ts.map +1 -0
  262. package/dist/types/src/types/cache.d.ts +2 -2
  263. package/dist/types/src/types/cache.d.ts.map +1 -1
  264. package/dist/types/src/types/encryption-types.d.ts +31 -2
  265. package/dist/types/src/types/encryption-types.d.ts.map +1 -1
  266. package/dist/types/src/types/validation-state-reader.d.ts +3 -5
  267. package/dist/types/src/types/validation-state-reader.d.ts.map +1 -1
  268. package/dist/types/src/utils/data-stream.d.ts +5 -0
  269. package/dist/types/src/utils/data-stream.d.ts.map +1 -1
  270. package/dist/types/src/utils/encryption.d.ts +53 -24
  271. package/dist/types/src/utils/encryption.d.ts.map +1 -1
  272. package/dist/types/src/utils/grant-key-coverage.d.ts +36 -0
  273. package/dist/types/src/utils/grant-key-coverage.d.ts.map +1 -0
  274. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  275. package/dist/types/src/utils/jws.d.ts.map +1 -1
  276. package/dist/types/src/utils/memory-cache.d.ts +4 -2
  277. package/dist/types/src/utils/memory-cache.d.ts.map +1 -1
  278. package/dist/types/src/utils/protocols.d.ts +11 -0
  279. package/dist/types/src/utils/protocols.d.ts.map +1 -1
  280. package/dist/types/src/utils/record-limit-occupancy.d.ts +7 -0
  281. package/dist/types/src/utils/record-limit-occupancy.d.ts.map +1 -1
  282. package/dist/types/src/utils/records.d.ts +2 -0
  283. package/dist/types/src/utils/records.d.ts.map +1 -1
  284. package/dist/types/src/utils/secp256k1.d.ts.map +1 -1
  285. package/dist/types/src/utils/secp256r1.d.ts.map +1 -1
  286. package/dist/types/src/utils/time.d.ts +21 -13
  287. package/dist/types/src/utils/time.d.ts.map +1 -1
  288. package/dist/types/tests/core/constants.spec.d.ts +2 -0
  289. package/dist/types/tests/core/constants.spec.d.ts.map +1 -0
  290. package/dist/types/tests/core/encryption-control.spec.d.ts +2 -0
  291. package/dist/types/tests/core/encryption-control.spec.d.ts.map +1 -0
  292. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  293. package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts +2 -0
  294. package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts.map +1 -0
  295. package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -1
  296. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  297. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  298. package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
  299. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  300. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  301. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  302. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  303. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  304. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  305. package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -1
  306. package/dist/types/tests/store/blockstore-utils.spec.d.ts +2 -0
  307. package/dist/types/tests/store/blockstore-utils.spec.d.ts.map +1 -0
  308. package/dist/types/tests/test-stores.d.ts.map +1 -1
  309. package/dist/types/tests/utils/encryption-control-test-utils.d.ts +46 -0
  310. package/dist/types/tests/utils/encryption-control-test-utils.d.ts.map +1 -0
  311. package/dist/types/tests/utils/grant-key-coverage.spec.d.ts +2 -0
  312. package/dist/types/tests/utils/grant-key-coverage.spec.d.ts.map +1 -0
  313. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  314. package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts +2 -0
  315. package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts.map +1 -0
  316. package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts +2 -0
  317. package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts.map +1 -0
  318. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts +2 -0
  319. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts.map +1 -0
  320. package/package.json +47 -28
  321. package/src/core/constants.ts +61 -0
  322. package/src/core/dwn-error.ts +29 -11
  323. package/src/core/encryption-control.ts +1249 -0
  324. package/src/core/message.ts +7 -0
  325. package/src/core/messages-grant-authorization.ts +60 -9
  326. package/src/core/protocol-authorization-action.ts +3 -13
  327. package/src/core/protocol-authorization-validation.ts +66 -46
  328. package/src/core/protocol-authorization.ts +7 -0
  329. package/src/core/recording-validation-state-reader.ts +4 -5
  330. package/src/core/replication-apply.ts +77 -133
  331. package/src/core/validation-state-reader.ts +6 -8
  332. package/src/dwn.ts +1 -2
  333. package/src/event-stream/event-emitter-wake-publisher.ts +10 -14
  334. package/src/handlers/messages-query.ts +6 -22
  335. package/src/handlers/messages-read.ts +4 -3
  336. package/src/handlers/messages-subscribe.ts +34 -30
  337. package/src/handlers/protocols-configure.ts +7 -4
  338. package/src/handlers/records-count.ts +111 -10
  339. package/src/handlers/records-delete.ts +15 -0
  340. package/src/handlers/records-query.ts +176 -20
  341. package/src/handlers/records-read.ts +19 -6
  342. package/src/handlers/records-subscribe.ts +158 -8
  343. package/src/handlers/records-write.ts +19 -0
  344. package/src/index.ts +50 -22
  345. package/src/interfaces/protocols-configure.ts +102 -11
  346. package/src/interfaces/records-write.ts +49 -43
  347. package/src/jose/algorithms/signing/ed25519.ts +7 -6
  348. package/src/jose/jws/general/verifier.ts +3 -3
  349. package/src/protocols/encryption.ts +94 -411
  350. package/src/store/blockstore-level.ts +33 -37
  351. package/src/store/blockstore-mock.ts +24 -38
  352. package/src/store/blockstore-utils.ts +85 -0
  353. package/src/store/blockstore.ts +8 -0
  354. package/src/store/data-store-level.ts +5 -12
  355. package/src/store/level.ts +19 -0
  356. package/src/types/cache.ts +3 -3
  357. package/src/types/encryption-types.ts +39 -2
  358. package/src/types/validation-state-reader.ts +3 -5
  359. package/src/utils/data-stream.ts +29 -1
  360. package/src/utils/encryption.ts +190 -60
  361. package/src/utils/grant-key-coverage.ts +303 -0
  362. package/src/utils/hd-key.ts +1 -2
  363. package/src/utils/jws.ts +8 -2
  364. package/src/utils/memory-cache.ts +42 -11
  365. package/src/utils/protocols.ts +32 -0
  366. package/src/utils/record-limit-occupancy.ts +34 -5
  367. package/src/utils/records.ts +36 -2
  368. package/src/utils/secp256k1.ts +12 -12
  369. package/src/utils/secp256r1.ts +12 -22
  370. package/src/utils/time.ts +145 -27
  371. package/dist/esm/tests/validation/json-schemas/encryption/audience-key.spec.js +0 -40
  372. package/dist/esm/tests/validation/json-schemas/encryption/audience-key.spec.js.map +0 -1
  373. package/dist/types/tests/validation/json-schemas/encryption/audience-key.spec.d.ts +0 -2
  374. package/dist/types/tests/validation/json-schemas/encryption/audience-key.spec.d.ts.map +0 -1
  375. package/src/types/mitt.d.ts +0 -28
@@ -1,95 +1,61 @@
1
1
  import type { CoreProtocol } from '../core/core-protocol.js';
2
2
  import type { Filter } from '../types/query-types.js';
3
- import type { GenericSignaturePayload } from '../types/message-types.js';
4
3
  import type { MessagesFilter } from '../types/messages-types.js';
5
4
  import type { PermissionGrant } from './permission-grant.js';
6
5
  import type { PermissionScope } from '../types/permission-types.js';
7
- import type { PublicKeyJwk } from '../types/jose-types.js';
6
+ import type { ProtocolDefinition } from '../types/protocols-types.js';
8
7
  import type { RecordsWriteMessage } from '../types/records-types.js';
9
8
  import type { ValidationStateReader } from '../types/validation-state-reader.js';
10
- import type { ProtocolActionRule, ProtocolDefinition, ProtocolRuleSet } from '../types/protocols-types.js';
9
+ import type { ContentEncryptionAlgorithm, X25519KeyEncryptionBase } from '../utils/encryption.js';
11
10
 
12
- import { checkActor } from '../core/protocol-authorization-action.js';
11
+ import { DwnConstant } from '../core/dwn-constant.js';
13
12
  import { Encoder } from '../utils/encoder.js';
14
- import { Encryption } from '../utils/encryption.js';
15
13
  import { ENCRYPTION_PROTOCOL_URI } from '../core/constants.js';
16
14
  import { FilterUtility } from '../utils/filter.js';
17
- import { Jws } from '../utils/jws.js';
18
15
  import { Message } from '../core/message.js';
19
16
  import { Records } from '../utils/records.js';
20
17
  import { validateJsonSchema } from '../schema-validator.js';
21
18
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
22
- import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
23
- import { getRuleSetAtPath, isCrossProtocolRef, parseCrossProtocolRef } from '../utils/protocols.js';
24
- import { ProtocolAction, ProtocolActor } from '../types/protocols-types.js';
25
-
26
- type AudienceTags = {
27
- protocol: string;
28
- contextId: string;
29
- role: string;
30
- epoch: number;
31
- keyId: string;
32
- };
19
+ import { grantKeyScopeCoversDeliveredScope, isGrantKeyEligibleRecordsScope, isGrantKeyRecordsScope } from '../utils/grant-key-coverage.js';
20
+
21
+ export const WRAPPED_GRANT_KEY_FORMAT = 'enbox/wrapped-grant-key@1';
33
22
 
34
- type AudienceEpochData = AudienceTags & {
35
- publicKeyJwk: PublicKeyJwk;
23
+ export type WrappedGrantKeyEnvelope = {
24
+ format: typeof WRAPPED_GRANT_KEY_FORMAT;
25
+ keyEncryption: X25519KeyEncryptionBase;
26
+ contentEncryption: {
27
+ algorithm: typeof ContentEncryptionAlgorithm.A256CTR;
28
+ initializationVector: string;
29
+ };
30
+ ciphertext: string;
36
31
  };
37
32
 
33
+ export function assertWrappedGrantKeyEnvelope(envelope: unknown): asserts envelope is WrappedGrantKeyEnvelope {
34
+ try {
35
+ validateJsonSchema('WrappedGrantKeyEnvelope', envelope);
36
+ } catch (error) {
37
+ const detail = error instanceof Error ? error.message : String(error);
38
+ throw new DwnError(
39
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyWrappedDeliveryInvalid,
40
+ `wrapped grantKey envelope is invalid: ${detail}`
41
+ );
42
+ }
43
+ }
44
+
38
45
  export class EncryptionProtocol implements CoreProtocol {
39
46
  public static readonly uri = ENCRYPTION_PROTOCOL_URI;
40
- public static readonly audienceEpochPath = 'audienceEpoch';
41
- public static readonly audienceKeyPath = 'audienceKey';
42
47
  public static readonly grantKeyPath = 'grantKey';
43
48
 
44
49
  public static readonly definition: ProtocolDefinition = {
45
50
  published : true,
46
51
  protocol : EncryptionProtocol.uri,
47
52
  types : {
48
- audienceEpoch: {
49
- dataFormats : ['application/json'],
50
- schema : 'https://identity.foundation/dwn/json-schemas/encryption/audience-epoch.json',
51
- },
52
- audienceKey: {
53
- dataFormats : ['application/json'],
54
- schema : 'https://identity.foundation/dwn/json-schemas/encryption/audience-key.json',
55
- },
56
53
  grantKey: {
57
54
  dataFormats : ['application/json'],
58
55
  schema : 'https://identity.foundation/dwn/json-schemas/encryption/grant-key.json',
59
56
  },
60
57
  },
61
58
  structure: {
62
- audienceEpoch: {
63
- $actions: [
64
- { can: ['create', 'read'], who: 'anyone' },
65
- ],
66
- $immutable : true,
67
- $tags : {
68
- $allowUndefinedTags : false,
69
- $requiredTags : ['protocol', 'contextId', 'role', 'epoch', 'keyId'],
70
- contextId : { type: 'string' },
71
- epoch : { minimum: 1, type: 'integer' },
72
- keyId : { pattern: '^[A-Za-z0-9_-]{43}$', type: 'string' },
73
- protocol : { type: 'string' },
74
- role : { type: 'string' },
75
- },
76
- },
77
- audienceKey: {
78
- $actions: [
79
- { can: ['create'], who: 'anyone' },
80
- { can: ['read'], of: 'audienceKey', who: 'recipient' },
81
- ],
82
- $immutable : true,
83
- $tags : {
84
- $allowUndefinedTags : false,
85
- $requiredTags : ['protocol', 'contextId', 'role', 'epoch', 'keyId'],
86
- contextId : { type: 'string' },
87
- epoch : { minimum: 1, type: 'integer' },
88
- keyId : { pattern: '^[A-Za-z0-9_-]{43}$', type: 'string' },
89
- protocol : { type: 'string' },
90
- role : { type: 'string' },
91
- },
92
- },
93
59
  grantKey: {
94
60
  $actions: [
95
61
  { can: ['create'], who: 'anyone' },
@@ -121,119 +87,21 @@ export class EncryptionProtocol implements CoreProtocol {
121
87
  message: RecordsWriteMessage,
122
88
  validationStateReader: ValidationStateReader,
123
89
  ): Promise<void> {
124
- switch (message.descriptor.protocolPath) {
125
- case EncryptionProtocol.audienceEpochPath:
126
- await EncryptionProtocol.preProcessAudienceEpoch(tenant, message, validationStateReader);
127
- return;
128
- case EncryptionProtocol.audienceKeyPath:
129
- await EncryptionProtocol.preProcessAudienceKey(tenant, message, validationStateReader);
130
- return;
131
- case EncryptionProtocol.grantKeyPath:
90
+ if (message.descriptor.protocolPath === EncryptionProtocol.grantKeyPath) {
132
91
  await EncryptionProtocol.preProcessGrantKey(tenant, message, validationStateReader);
133
- return;
134
- default:
135
- return;
136
92
  }
137
93
  }
138
94
 
139
95
  public async validateRecord(message: RecordsWriteMessage, dataBytes: Uint8Array): Promise<void> {
140
- switch (message.descriptor.protocolPath) {
141
- case EncryptionProtocol.audienceEpochPath:
142
- await EncryptionProtocol.validateAudienceEpoch(message, dataBytes);
143
- return;
144
- case EncryptionProtocol.audienceKeyPath:
145
- case EncryptionProtocol.grantKeyPath:
146
- EncryptionProtocol.verifyEncryptedDelivery(message);
96
+ if (message.descriptor.protocolPath === EncryptionProtocol.grantKeyPath) {
97
+ EncryptionProtocol.verifyGrantKeyDelivery(message, dataBytes);
147
98
  return;
148
- default:
149
- throw new DwnError(
150
- DwnErrorCode.EncryptionProtocolValidateSchemaUnexpectedRecord,
151
- `Unexpected encryption record: ${message.descriptor.protocolPath}`
152
- );
153
99
  }
154
- }
155
100
 
156
- private static async preProcessAudienceEpoch(
157
- tenant: string,
158
- message: RecordsWriteMessage,
159
- validationStateReader: ValidationStateReader,
160
- ): Promise<void> {
161
- if (message.encryption !== undefined) {
162
- throw new DwnError(
163
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted,
164
- 'audienceEpoch records must be plaintext.'
165
- );
166
- }
167
-
168
- const tags = EncryptionProtocol.getAudienceTags(message, 'audienceEpoch');
169
- const { ruleSet, protocolDefinition } = await EncryptionProtocol.verifyRoleAudienceDefinition(tenant, tags, message, validationStateReader);
170
- await EncryptionProtocol.verifyWriterCanCreateRole({
171
- tenant,
172
- message,
173
- tags,
174
- ruleSet,
175
- protocolDefinition,
176
- validationStateReader,
177
- });
178
-
179
- }
180
-
181
- private static async preProcessAudienceKey(
182
- tenant: string,
183
- message: RecordsWriteMessage,
184
- validationStateReader: ValidationStateReader,
185
- ): Promise<void> {
186
- EncryptionProtocol.verifyEncryptedDelivery(message);
187
-
188
- const recipient = message.descriptor.recipient;
189
- if (recipient === undefined) {
190
- throw new DwnError(
191
- DwnErrorCode.EncryptionProtocolValidateAudienceKeyRecipientMissing,
192
- 'audienceKey records must have a recipient.'
193
- );
194
- }
195
-
196
- const tags = EncryptionProtocol.getAudienceTags(message, 'audienceKey');
197
- const { ruleSet, protocolDefinition } = await EncryptionProtocol.verifyRoleAudienceDefinition(tenant, tags, message, validationStateReader);
198
- await EncryptionProtocol.verifyWriterCanCreateRole({
199
- tenant,
200
- message,
201
- tags,
202
- ruleSet,
203
- protocolDefinition,
204
- validationStateReader,
205
- });
206
-
207
- const matchingEpochs = await validationStateReader.queryAudienceEpochs({
208
- tenant,
209
- protocol : tags.protocol,
210
- contextId : tags.contextId,
211
- role : tags.role,
212
- epoch : tags.epoch,
213
- keyId : tags.keyId,
214
- });
215
-
216
- if (matchingEpochs.length === 0) {
217
- throw new DwnError(
218
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochMissing,
219
- 'audienceKey references a missing audienceEpoch.'
220
- );
221
- }
222
-
223
- const hasRoleRecord = await validationStateReader.hasMatchingRoleRecord({
224
- tenant,
225
- protocol : tags.protocol,
226
- protocolPath : tags.role,
227
- recipient,
228
- contextIdPrefix : tags.contextId === '' ? undefined : tags.contextId,
229
- });
230
-
231
- if (!hasRoleRecord) {
232
- throw new DwnError(
233
- DwnErrorCode.EncryptionProtocolValidateAudienceKeyRoleRecordMissing,
234
- 'audienceKey recipient is not an active holder of the referenced role.'
235
- );
236
- }
101
+ throw new DwnError(
102
+ DwnErrorCode.EncryptionProtocolValidateSchemaUnexpectedRecord,
103
+ `Unexpected encryption record: ${message.descriptor.protocolPath}`
104
+ );
237
105
  }
238
106
 
239
107
  private static async preProcessGrantKey(
@@ -241,7 +109,7 @@ export class EncryptionProtocol implements CoreProtocol {
241
109
  message: RecordsWriteMessage,
242
110
  validationStateReader: ValidationStateReader,
243
111
  ): Promise<void> {
244
- EncryptionProtocol.verifyEncryptedDelivery(message);
112
+ EncryptionProtocol.verifyInlineWrappedGrantKeyDelivery(message);
245
113
 
246
114
  const grantId = EncryptionProtocol.getRequiredStringTag(message, 'grantId');
247
115
  const protocol = EncryptionProtocol.getRequiredStringTag(message, 'protocol');
@@ -252,91 +120,62 @@ export class EncryptionProtocol implements CoreProtocol {
252
120
  await EncryptionProtocol.verifyGrantActive(tenant, message, grant, validationStateReader);
253
121
  EncryptionProtocol.verifyGrantKeyAuthor(message, grant);
254
122
  EncryptionProtocol.verifyGrantKeyRecipient(message, grant);
255
- EncryptionProtocol.verifyGrantKeyScope(grant.scope, protocol, protocolPath);
123
+ await EncryptionProtocol.verifyGrantKeyScope({
124
+ tenant,
125
+ message,
126
+ grantScope: grant.scope,
127
+ protocol,
128
+ protocolPath,
129
+ validationStateReader,
130
+ });
256
131
  }
257
132
 
258
- private static verifyEncryptedDelivery(message: RecordsWriteMessage): void {
259
- if (message.encryption === undefined) {
133
+ private static verifyInlineWrappedGrantKeyDelivery(message: RecordsWriteMessage): void {
134
+ if (message.encryption !== undefined) {
135
+ return;
136
+ }
137
+
138
+ if (message.descriptor.dataSize > DwnConstant.maxDataSizeAllowedToBeEncoded) {
260
139
  throw new DwnError(
261
140
  DwnErrorCode.EncryptionProtocolValidateEncryptedDeliveryMissingEncryption,
262
- `${message.descriptor.protocolPath} records must be encrypted.`
141
+ 'plaintext grantKey records must carry an inline wrapped grantKey envelope.'
263
142
  );
264
143
  }
265
144
  }
266
145
 
267
- private static async validateAudienceEpoch(message: RecordsWriteMessage, dataBytes: Uint8Array): Promise<void> {
146
+ private static verifyGrantKeyDelivery(message: RecordsWriteMessage, dataBytes: Uint8Array): void {
268
147
  if (message.encryption !== undefined) {
269
- throw new DwnError(
270
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted,
271
- 'audienceEpoch records must be plaintext.'
272
- );
148
+ return;
273
149
  }
274
150
 
275
- const dataObject = JSON.parse(Encoder.bytesToString(dataBytes)) as AudienceEpochData;
276
- validateJsonSchema('AudienceEpoch', dataObject);
277
-
278
- const tags = EncryptionProtocol.getAudienceTags(message, 'audienceEpoch');
279
- EncryptionProtocol.verifyAudiencePayloadMatchesTags(dataObject, tags);
280
-
281
- const keyId = await Encryption.getKeyId(dataObject.publicKeyJwk);
282
- if (keyId !== dataObject.keyId) {
283
- throw new DwnError(
284
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochKeyIdMismatch,
285
- 'audienceEpoch keyId must match publicKeyJwk thumbprint.'
286
- );
287
- }
288
- }
151
+ try {
152
+ const envelope = Encoder.bytesToObject(dataBytes);
153
+ assertWrappedGrantKeyEnvelope(envelope);
154
+ } catch (error) {
155
+ if (error instanceof DwnError) {
156
+ throw error;
157
+ }
289
158
 
290
- private static verifyAudiencePayloadMatchesTags(payload: AudienceTags, tags: AudienceTags): void {
291
- if (payload.protocol !== tags.protocol ||
292
- payload.contextId !== tags.contextId ||
293
- payload.role !== tags.role ||
294
- payload.epoch !== tags.epoch ||
295
- payload.keyId !== tags.keyId) {
159
+ const detail = error instanceof Error ? error.message : String(error);
296
160
  throw new DwnError(
297
- DwnErrorCode.EncryptionProtocolValidateAudienceTagsMismatch,
298
- 'audienceEpoch tags must match payload fields.'
161
+ DwnErrorCode.EncryptionProtocolValidateEncryptedDeliveryMissingEncryption,
162
+ `${message.descriptor.protocolPath} records must be encrypted or carry a valid wrapped grantKey envelope: ${detail}`
299
163
  );
300
164
  }
301
165
  }
302
166
 
303
- private static getRequiredStringTag(message: RecordsWriteMessage, tag: string, recordType = 'grantKey'): string {
167
+ private static getRequiredStringTag(message: RecordsWriteMessage, tag: string): string {
304
168
  const value = message.descriptor.tags?.[tag];
305
169
  if (typeof value !== 'string') {
306
- const errorCode = recordType === 'grantKey'
307
- ? DwnErrorCode.EncryptionProtocolValidateGrantKeyMissingRequiredTag
308
- : DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag;
309
170
  throw new DwnError(
310
- errorCode,
311
- `${recordType} records must include string tag '${tag}'.`
171
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyMissingRequiredTag,
172
+ `grantKey records must include string tag '${tag}'.`
312
173
  );
313
174
  }
314
175
 
315
176
  return value;
316
177
  }
317
178
 
318
- private static getRequiredIntegerTag(message: RecordsWriteMessage, tag: string, recordType: string): number {
319
- const value = message.descriptor.tags?.[tag];
320
- if (!Number.isInteger(value)) {
321
- throw new DwnError(
322
- DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag,
323
- `${recordType} records must include integer tag '${tag}'.`
324
- );
325
- }
326
-
327
- return value as number;
328
- }
329
-
330
- private static getAudienceTags(message: RecordsWriteMessage, recordType: string): AudienceTags {
331
- return {
332
- protocol : EncryptionProtocol.getRequiredStringTag(message, 'protocol', recordType),
333
- contextId : EncryptionProtocol.getRequiredStringTag(message, 'contextId', recordType),
334
- role : EncryptionProtocol.getRequiredStringTag(message, 'role', recordType),
335
- epoch : EncryptionProtocol.getRequiredIntegerTag(message, 'epoch', recordType),
336
- keyId : EncryptionProtocol.getRequiredStringTag(message, 'keyId', recordType),
337
- };
338
- }
339
-
340
179
  private static getOptionalStringTag(message: RecordsWriteMessage, tag: string): string | undefined {
341
180
  const value = message.descriptor.tags?.[tag];
342
181
  if (value === undefined) {
@@ -405,220 +244,64 @@ export class EncryptionProtocol implements CoreProtocol {
405
244
  );
406
245
  }
407
246
 
408
- private static verifyGrantKeyScope(grantScope: PermissionScope, protocol: string, protocolPath: string | undefined): void {
409
- if (!EncryptionProtocol.isReadScope(grantScope)) {
410
- throw new DwnError(
411
- DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
412
- 'grantKey must reference a read permission grant.'
413
- );
414
- }
247
+ private static async verifyGrantKeyScope(params: {
248
+ tenant: string;
249
+ message: RecordsWriteMessage;
250
+ grantScope: PermissionScope;
251
+ protocol: string;
252
+ protocolPath: string | undefined;
253
+ validationStateReader: ValidationStateReader;
254
+ }): Promise<void> {
255
+ const { grantScope, protocol, protocolPath } = params;
415
256
 
416
- if ('protocol' in grantScope && grantScope.protocol !== undefined && grantScope.protocol !== protocol) {
257
+ if (!isGrantKeyRecordsScope(grantScope)) {
417
258
  throw new DwnError(
418
259
  DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
419
- `grantKey protocol ${protocol} is outside the permission grant scope.`
260
+ 'grantKey must reference a Records.Read or Records.Write permission grant.'
420
261
  );
421
262
  }
422
263
 
423
- if (!('protocolPath' in grantScope) || grantScope.protocolPath === undefined) {
424
- return;
425
- }
426
-
427
- if (protocolPath === undefined || !EncryptionProtocol.isBoundaryAwareSubtree(grantScope.protocolPath, protocolPath)) {
264
+ if (!isGrantKeyEligibleRecordsScope(grantScope)) {
428
265
  throw new DwnError(
429
266
  DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
430
- `grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
267
+ 'grantKey must not reference a context-scoped permission grant.'
431
268
  );
432
269
  }
433
- }
434
-
435
- private static isReadScope(scope: PermissionScope): boolean {
436
- return (scope.interface === DwnInterfaceName.Records || scope.interface === DwnInterfaceName.Messages) &&
437
- scope.method === DwnMethodName.Read;
438
- }
439
-
440
- private static isBoundaryAwareSubtree(scopePath: string, candidatePath: string): boolean {
441
- return candidatePath === scopePath || candidatePath.startsWith(scopePath + '/');
442
- }
443
-
444
- private static async verifyRoleAudienceDefinition(
445
- tenant: string,
446
- tags: AudienceTags,
447
- message: RecordsWriteMessage,
448
- validationStateReader: ValidationStateReader,
449
- ): Promise<{ protocolDefinition: ProtocolDefinition; ruleSet: ProtocolRuleSet }> {
450
- EncryptionProtocol.verifyRoleAudienceContext(tags.role, tags.contextId);
451
-
452
- const protocolDefinition = await validationStateReader.fetchProtocolDefinition(
453
- tenant,
454
- tags.protocol,
455
- message.descriptor.messageTimestamp,
456
- );
457
- const ruleSet = getRuleSetAtPath(tags.role, protocolDefinition.structure);
458
270
 
459
- if (ruleSet?.$role !== true || ruleSet.$keyAgreement === undefined) {
271
+ if (grantScope.protocol !== protocol) {
460
272
  throw new DwnError(
461
- DwnErrorCode.EncryptionProtocolValidateRoleAudienceInvalid,
462
- `role audience path '${tags.role}' must be a role path with $keyAgreement.`
463
- );
464
- }
465
-
466
- return { protocolDefinition, ruleSet };
467
- }
468
-
469
- private static verifyRoleAudienceContext(rolePath: string, contextId: string): void {
470
- const parentDepth = rolePath.split('/').length - 1;
471
- if ((parentDepth === 0 && contextId !== '') || (parentDepth > 0 && contextId === '')) {
472
- throw new DwnError(
473
- DwnErrorCode.EncryptionProtocolValidateRoleAudienceContextInvalid,
474
- 'role audience contextId is inconsistent with role path depth.'
273
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
274
+ `grantKey protocol ${protocol} is outside the permission grant scope.`
475
275
  );
476
276
  }
477
- }
478
277
 
479
- private static async verifyWriterCanCreateRole(input: {
480
- tenant: string;
481
- message: RecordsWriteMessage;
482
- tags: AudienceTags;
483
- ruleSet: ProtocolRuleSet;
484
- protocolDefinition: ProtocolDefinition;
485
- validationStateReader: ValidationStateReader;
486
- }): Promise<void> {
487
- const author = Message.getAuthor(input.message);
488
- if (author === input.tenant) {
278
+ const deliveredScope = { protocol, protocolPath };
279
+ if (grantKeyScopeCoversDeliveredScope({ grantScope, deliveredScope })) {
489
280
  return;
490
281
  }
491
282
 
492
- if (author === undefined) {
283
+ if (protocolPath === undefined) {
493
284
  throw new DwnError(
494
- DwnErrorCode.EncryptionProtocolValidateAudienceWriterUnauthorized,
495
- 'audience key records must be authored by a DID authorized to create role records.'
285
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
286
+ `grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
496
287
  );
497
288
  }
498
289
 
499
- const actionRules = input.ruleSet.$actions ?? [];
500
- const recordChain = await EncryptionProtocol.constructRoleParentChain(input.tenant, input.tags, input.validationStateReader);
501
- const signaturePayload = Jws.decodePlainObjectPayload(input.message.authorization.signature) as GenericSignaturePayload;
502
-
503
- for (const actionRule of actionRules) {
504
- if (!actionRule.can.includes(ProtocolAction.Create)) {
505
- continue;
506
- }
507
-
508
- if (actionRule.who === ProtocolActor.Anyone) {
509
- return;
510
- }
511
-
512
- if (await EncryptionProtocol.roleRuleAllowsAuthor(
513
- input.tenant,
514
- author,
515
- actionRule,
516
- input.tags,
517
- input.protocolDefinition,
518
- input.validationStateReader,
519
- signaturePayload.protocolRole,
520
- )) {
521
- return;
522
- }
523
-
524
- if (await checkActor(author, actionRule, recordChain, input.protocolDefinition)) {
525
- return;
526
- }
290
+ const protocolDefinition = await params.validationStateReader.fetchProtocolDefinition(
291
+ params.tenant,
292
+ params.protocol,
293
+ params.message.descriptor.messageTimestamp,
294
+ );
295
+ if (grantKeyScopeCoversDeliveredScope({ grantScope, deliveredScope, protocolDefinition })) {
296
+ return;
527
297
  }
528
298
 
529
299
  throw new DwnError(
530
- DwnErrorCode.EncryptionProtocolValidateAudienceWriterUnauthorized,
531
- 'audience key records must be authored by a DID authorized to create role records.'
300
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
301
+ `grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
532
302
  );
533
303
  }
534
304
 
535
- private static async constructRoleParentChain(
536
- tenant: string,
537
- tags: AudienceTags,
538
- validationStateReader: ValidationStateReader,
539
- ): Promise<RecordsWriteMessage[]> {
540
- if (tags.contextId === '') {
541
- return [];
542
- }
543
-
544
- const parentRecordId = tags.contextId.split('/').pop();
545
- if (parentRecordId === undefined || parentRecordId === '') {
546
- return [];
547
- }
548
-
549
- return validationStateReader.constructRecordChain(tenant, parentRecordId);
550
- }
551
-
552
- private static async roleRuleAllowsAuthor(
553
- tenant: string,
554
- author: string,
555
- actionRule: ProtocolActionRule,
556
- tags: AudienceTags,
557
- protocolDefinition: ProtocolDefinition,
558
- validationStateReader: ValidationStateReader,
559
- invokedRole: string | undefined,
560
- ): Promise<boolean> {
561
- if (actionRule.role === undefined || invokedRole !== actionRule.role) {
562
- return false;
563
- }
564
-
565
- const roleRef = actionRule.role;
566
- return EncryptionProtocol.hasInvokedRole(tenant, author, roleRef, tags, protocolDefinition, validationStateReader);
567
- }
568
-
569
- private static async hasInvokedRole(
570
- tenant: string,
571
- author: string,
572
- roleRef: string,
573
- tags: AudienceTags,
574
- protocolDefinition: ProtocolDefinition,
575
- validationStateReader: ValidationStateReader,
576
- ): Promise<boolean> {
577
- const resolved = EncryptionProtocol.resolveRoleReference(roleRef, tags.protocol, protocolDefinition);
578
- if (resolved === undefined) {
579
- return false;
580
- }
581
-
582
- const ancestorDepth = resolved.protocolPath.split('/').length - 1;
583
- let contextIdPrefix: string | undefined;
584
- if (ancestorDepth > 0) {
585
- contextIdPrefix = tags.contextId.split('/').slice(0, ancestorDepth).join('/');
586
- if (contextIdPrefix === '') {
587
- return false;
588
- }
589
- }
590
-
591
- return validationStateReader.hasMatchingRoleRecord({
592
- tenant,
593
- protocol : resolved.protocol,
594
- protocolPath : resolved.protocolPath,
595
- recipient : author,
596
- contextIdPrefix,
597
- });
598
- }
599
-
600
- private static resolveRoleReference(
601
- roleRef: string,
602
- currentProtocol: string,
603
- protocolDefinition: ProtocolDefinition,
604
- ): { protocol: string; protocolPath: string } | undefined {
605
- if (!isCrossProtocolRef(roleRef)) {
606
- return { protocol: currentProtocol, protocolPath: roleRef };
607
- }
608
-
609
- const parsed = parseCrossProtocolRef(roleRef);
610
- if (parsed === undefined) {
611
- return undefined;
612
- }
613
-
614
- const protocol = protocolDefinition.uses?.[parsed.alias];
615
- if (protocol === undefined) {
616
- return undefined;
617
- }
618
-
619
- return { protocol, protocolPath: parsed.protocolPath };
620
- }
621
-
622
305
  public mapErrorToStatusCode(errorCode: string): number | undefined {
623
306
  if (errorCode.startsWith('EncryptionProtocolValidate')) {
624
307
  return 400;