mindoodb 0.0.23 → 0.0.32

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 (340) hide show
  1. package/README-server.md +9 -1
  2. package/README.md +5 -3
  3. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +1 -1
  4. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
  5. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +24 -5
  6. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
  7. package/dist/appendonlystores/network/HttpTransport.d.ts +14 -2
  8. package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
  9. package/dist/appendonlystores/network/HttpTransport.js +124 -27
  10. package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
  11. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +159 -4
  12. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
  13. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +334 -25
  14. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
  15. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +9 -0
  16. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -1
  17. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +77 -5
  18. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -1
  19. package/dist/browser/index.mjs +103 -0
  20. package/dist/core/BaseMindooDB.d.ts +697 -4
  21. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  22. package/dist/core/BaseMindooDB.js +3273 -180
  23. package/dist/core/BaseMindooDB.js.map +1 -1
  24. package/dist/core/BaseMindooTenant.d.ts +192 -1
  25. package/dist/core/BaseMindooTenant.d.ts.map +1 -1
  26. package/dist/core/BaseMindooTenant.js +633 -88
  27. package/dist/core/BaseMindooTenant.js.map +1 -1
  28. package/dist/core/BaseMindooTenantDirectory.d.ts +770 -10
  29. package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
  30. package/dist/core/BaseMindooTenantDirectory.js +2715 -292
  31. package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
  32. package/dist/core/BaseMindooTenantFactory.d.ts +2 -0
  33. package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
  34. package/dist/core/BaseMindooTenantFactory.js +20 -0
  35. package/dist/core/BaseMindooTenantFactory.js.map +1 -1
  36. package/dist/core/accesscontrol/AccessDeniedError.d.ts +22 -0
  37. package/dist/core/accesscontrol/AccessDeniedError.d.ts.map +1 -0
  38. package/dist/core/accesscontrol/AccessDeniedError.js +28 -0
  39. package/dist/core/accesscontrol/AccessDeniedError.js.map +1 -0
  40. package/dist/core/accesscontrol/DirectoryStateNode.d.ts +220 -0
  41. package/dist/core/accesscontrol/DirectoryStateNode.d.ts.map +1 -0
  42. package/dist/core/accesscontrol/DirectoryStateNode.js +297 -0
  43. package/dist/core/accesscontrol/DirectoryStateNode.js.map +1 -0
  44. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.d.ts +118 -0
  45. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.d.ts.map +1 -0
  46. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.js +173 -0
  47. package/dist/core/accesscontrol/DirectoryTimeTravelIndex.js.map +1 -0
  48. package/dist/core/accesscontrol/directoryProjection.d.ts +26 -0
  49. package/dist/core/accesscontrol/directoryProjection.d.ts.map +1 -0
  50. package/dist/core/accesscontrol/directoryProjection.js +174 -0
  51. package/dist/core/accesscontrol/directoryProjection.js.map +1 -0
  52. package/dist/core/accesscontrol/evaluate.d.ts +77 -0
  53. package/dist/core/accesscontrol/evaluate.d.ts.map +1 -0
  54. package/dist/core/accesscontrol/evaluate.js +206 -0
  55. package/dist/core/accesscontrol/evaluate.js.map +1 -0
  56. package/dist/core/accesscontrol/grantKeys.d.ts +113 -0
  57. package/dist/core/accesscontrol/grantKeys.d.ts.map +1 -0
  58. package/dist/core/accesscontrol/grantKeys.js +302 -0
  59. package/dist/core/accesscontrol/grantKeys.js.map +1 -0
  60. package/dist/core/accesscontrol/keyBagReconciler.d.ts +22 -0
  61. package/dist/core/accesscontrol/keyBagReconciler.d.ts.map +1 -0
  62. package/dist/core/accesscontrol/keyBagReconciler.js +3 -0
  63. package/dist/core/accesscontrol/keyBagReconciler.js.map +1 -0
  64. package/dist/core/accesscontrol/materializationGuard.d.ts +89 -0
  65. package/dist/core/accesscontrol/materializationGuard.d.ts.map +1 -0
  66. package/dist/core/accesscontrol/materializationGuard.js +69 -0
  67. package/dist/core/accesscontrol/materializationGuard.js.map +1 -0
  68. package/dist/core/accesscontrol/quarantine.d.ts +65 -0
  69. package/dist/core/accesscontrol/quarantine.d.ts.map +1 -0
  70. package/dist/core/accesscontrol/quarantine.js +79 -0
  71. package/dist/core/accesscontrol/quarantine.js.map +1 -0
  72. package/dist/core/accesscontrol/receiptValidation.d.ts +113 -0
  73. package/dist/core/accesscontrol/receiptValidation.d.ts.map +1 -0
  74. package/dist/core/accesscontrol/receiptValidation.js +142 -0
  75. package/dist/core/accesscontrol/receiptValidation.js.map +1 -0
  76. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.d.ts +31 -0
  77. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.d.ts.map +1 -0
  78. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.js +66 -0
  79. package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.js.map +1 -0
  80. package/dist/core/accesscontrol/timestamp/TimestampProvider.d.ts +79 -0
  81. package/dist/core/accesscontrol/timestamp/TimestampProvider.d.ts.map +1 -0
  82. package/dist/core/accesscontrol/timestamp/TimestampProvider.js +22 -0
  83. package/dist/core/accesscontrol/timestamp/TimestampProvider.js.map +1 -0
  84. package/dist/core/accesscontrol/types.d.ts +825 -0
  85. package/dist/core/accesscontrol/types.d.ts.map +1 -0
  86. package/dist/core/accesscontrol/types.js +534 -0
  87. package/dist/core/accesscontrol/types.js.map +1 -0
  88. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +9 -0
  89. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
  90. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +54 -0
  91. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
  92. package/dist/core/appendonlystores/network/AuthenticationService.d.ts +38 -2
  93. package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -1
  94. package/dist/core/appendonlystores/network/AuthenticationService.js +199 -26
  95. package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -1
  96. package/dist/core/appendonlystores/network/NetworkTransport.d.ts +17 -3
  97. package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
  98. package/dist/core/appendonlystores/network/types.d.ts +58 -4
  99. package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
  100. package/dist/core/appendonlystores/network/types.js +4 -0
  101. package/dist/core/appendonlystores/network/types.js.map +1 -1
  102. package/dist/core/appendonlystores/scanUtils.d.ts +27 -0
  103. package/dist/core/appendonlystores/scanUtils.d.ts.map +1 -0
  104. package/dist/core/appendonlystores/scanUtils.js +87 -0
  105. package/dist/core/appendonlystores/scanUtils.js.map +1 -0
  106. package/dist/core/appendonlystores/types.d.ts +23 -2
  107. package/dist/core/appendonlystores/types.d.ts.map +1 -1
  108. package/dist/core/cache/CacheManager.d.ts +13 -3
  109. package/dist/core/cache/CacheManager.d.ts.map +1 -1
  110. package/dist/core/cache/CacheManager.js +7 -4
  111. package/dist/core/cache/CacheManager.js.map +1 -1
  112. package/dist/core/crypto/EntrySignature.d.ts +137 -0
  113. package/dist/core/crypto/EntrySignature.d.ts.map +1 -0
  114. package/dist/core/crypto/EntrySignature.js +210 -0
  115. package/dist/core/crypto/EntrySignature.js.map +1 -0
  116. package/dist/core/crypto/MindooDocSigner.d.ts.map +1 -1
  117. package/dist/core/crypto/MindooDocSigner.js +6 -2
  118. package/dist/core/crypto/MindooDocSigner.js.map +1 -1
  119. package/dist/core/crypto/WitnessReceipt.d.ts +137 -0
  120. package/dist/core/crypto/WitnessReceipt.d.ts.map +1 -0
  121. package/dist/core/crypto/WitnessReceipt.js +182 -0
  122. package/dist/core/crypto/WitnessReceipt.js.map +1 -0
  123. package/dist/core/crypto/encryptedFields.d.ts +27 -0
  124. package/dist/core/crypto/encryptedFields.d.ts.map +1 -0
  125. package/dist/core/crypto/encryptedFields.js +58 -0
  126. package/dist/core/crypto/encryptedFields.js.map +1 -0
  127. package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
  128. package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -1
  129. package/dist/core/crypto/pbkdf2Iterations.js +23 -0
  130. package/dist/core/crypto/pbkdf2Iterations.js.map +1 -1
  131. package/dist/core/crypto/privateKeyEncryption.d.ts.map +1 -1
  132. package/dist/core/crypto/privateKeyEncryption.js +3 -1
  133. package/dist/core/crypto/privateKeyEncryption.js.map +1 -1
  134. package/dist/core/databaseIdValidation.d.ts +1 -1
  135. package/dist/core/databaseIdValidation.d.ts.map +1 -1
  136. package/dist/core/databaseIdValidation.js +4 -4
  137. package/dist/core/databaseIdValidation.js.map +1 -1
  138. package/dist/core/errors.d.ts +26 -0
  139. package/dist/core/errors.d.ts.map +1 -1
  140. package/dist/core/errors.js +42 -1
  141. package/dist/core/errors.js.map +1 -1
  142. package/dist/core/expressions/builder.d.ts +102 -0
  143. package/dist/core/expressions/builder.d.ts.map +1 -0
  144. package/dist/core/expressions/builder.js +249 -0
  145. package/dist/core/expressions/builder.js.map +1 -0
  146. package/dist/core/expressions/evaluateExpression.d.ts +78 -0
  147. package/dist/core/expressions/evaluateExpression.d.ts.map +1 -0
  148. package/dist/core/expressions/evaluateExpression.js +386 -0
  149. package/dist/core/expressions/evaluateExpression.js.map +1 -0
  150. package/dist/core/expressions/formulaSource.d.ts +24 -0
  151. package/dist/core/expressions/formulaSource.d.ts.map +1 -0
  152. package/dist/core/expressions/formulaSource.js +765 -0
  153. package/dist/core/expressions/formulaSource.js.map +1 -0
  154. package/dist/core/expressions/index.d.ts +8 -0
  155. package/dist/core/expressions/index.d.ts.map +1 -0
  156. package/dist/core/expressions/index.js +46 -0
  157. package/dist/core/expressions/index.js.map +1 -0
  158. package/dist/core/expressions/metadata.d.ts +23 -0
  159. package/dist/core/expressions/metadata.d.ts.map +1 -0
  160. package/dist/core/expressions/metadata.js +191 -0
  161. package/dist/core/expressions/metadata.js.map +1 -0
  162. package/dist/core/expressions/types.d.ts +164 -0
  163. package/dist/core/expressions/types.d.ts.map +1 -0
  164. package/dist/core/expressions/types.js +3 -0
  165. package/dist/core/expressions/types.js.map +1 -0
  166. package/dist/core/extraction/types.d.ts +47 -0
  167. package/dist/core/extraction/types.d.ts.map +1 -0
  168. package/dist/core/extraction/types.js +42 -0
  169. package/dist/core/extraction/types.js.map +1 -0
  170. package/dist/core/index.d.ts +13 -3
  171. package/dist/core/index.d.ts.map +1 -1
  172. package/dist/core/index.js +113 -4
  173. package/dist/core/index.js.map +1 -1
  174. package/dist/core/indexing/createViewDataProvider.d.ts +84 -0
  175. package/dist/core/indexing/createViewDataProvider.d.ts.map +1 -0
  176. package/dist/core/indexing/createViewDataProvider.js +139 -0
  177. package/dist/core/indexing/createViewDataProvider.js.map +1 -0
  178. package/dist/core/indexing/fulltext/DocumentFullTextIndex.d.ts +180 -0
  179. package/dist/core/indexing/fulltext/DocumentFullTextIndex.d.ts.map +1 -0
  180. package/dist/core/indexing/fulltext/DocumentFullTextIndex.js +548 -0
  181. package/dist/core/indexing/fulltext/DocumentFullTextIndex.js.map +1 -0
  182. package/dist/core/indexing/fulltext/SearchEngineAdapter.d.ts +69 -0
  183. package/dist/core/indexing/fulltext/SearchEngineAdapter.d.ts.map +1 -0
  184. package/dist/core/indexing/fulltext/SearchEngineAdapter.js +183 -0
  185. package/dist/core/indexing/fulltext/SearchEngineAdapter.js.map +1 -0
  186. package/dist/core/indexing/fulltext/extractFulltextText.d.ts +34 -0
  187. package/dist/core/indexing/fulltext/extractFulltextText.d.ts.map +1 -0
  188. package/dist/core/indexing/fulltext/extractFulltextText.js +129 -0
  189. package/dist/core/indexing/fulltext/extractFulltextText.js.map +1 -0
  190. package/dist/core/indexing/fulltext/index.d.ts +5 -0
  191. package/dist/core/indexing/fulltext/index.d.ts.map +1 -0
  192. package/dist/core/indexing/fulltext/index.js +20 -0
  193. package/dist/core/indexing/fulltext/index.js.map +1 -0
  194. package/dist/core/indexing/fulltext/types.d.ts +168 -0
  195. package/dist/core/indexing/fulltext/types.d.ts.map +1 -0
  196. package/dist/core/indexing/fulltext/types.js +89 -0
  197. package/dist/core/indexing/fulltext/types.js.map +1 -0
  198. package/dist/core/indexing/summary/DocumentSummaryStore.d.ts +137 -0
  199. package/dist/core/indexing/summary/DocumentSummaryStore.d.ts.map +1 -0
  200. package/dist/core/indexing/summary/DocumentSummaryStore.js +438 -0
  201. package/dist/core/indexing/summary/DocumentSummaryStore.js.map +1 -0
  202. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts +72 -0
  203. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts.map +1 -0
  204. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js +221 -0
  205. package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js.map +1 -0
  206. package/dist/core/indexing/summary/extractSummaryFields.d.ts +75 -0
  207. package/dist/core/indexing/summary/extractSummaryFields.d.ts.map +1 -0
  208. package/dist/core/indexing/summary/extractSummaryFields.js +266 -0
  209. package/dist/core/indexing/summary/extractSummaryFields.js.map +1 -0
  210. package/dist/core/indexing/summary/index.d.ts +5 -0
  211. package/dist/core/indexing/summary/index.d.ts.map +1 -0
  212. package/dist/core/indexing/summary/index.js +23 -0
  213. package/dist/core/indexing/summary/index.js.map +1 -0
  214. package/dist/core/indexing/summary/types.d.ts +119 -0
  215. package/dist/core/indexing/summary/types.d.ts.map +1 -0
  216. package/dist/core/indexing/summary/types.js +81 -0
  217. package/dist/core/indexing/summary/types.js.map +1 -0
  218. package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts +47 -1
  219. package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts.map +1 -1
  220. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +24 -8
  221. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -1
  222. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +96 -41
  223. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
  224. package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts +2 -0
  225. package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts.map +1 -1
  226. package/dist/core/indexing/virtualviews/ViewEntrySortKey.js +8 -3
  227. package/dist/core/indexing/virtualviews/ViewEntrySortKey.js.map +1 -1
  228. package/dist/core/indexing/virtualviews/VirtualView.d.ts +111 -5
  229. package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -1
  230. package/dist/core/indexing/virtualviews/VirtualView.js +266 -75
  231. package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -1
  232. package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts +12 -0
  233. package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts.map +1 -1
  234. package/dist/core/indexing/virtualviews/VirtualViewColumn.js +1 -0
  235. package/dist/core/indexing/virtualviews/VirtualViewColumn.js.map +1 -1
  236. package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +12 -0
  237. package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -1
  238. package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +66 -5
  239. package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -1
  240. package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts +50 -6
  241. package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts.map +1 -1
  242. package/dist/core/indexing/virtualviews/VirtualViewFactory.js +54 -12
  243. package/dist/core/indexing/virtualviews/VirtualViewFactory.js.map +1 -1
  244. package/dist/core/indexing/virtualviews/index.d.ts +3 -3
  245. package/dist/core/indexing/virtualviews/index.d.ts.map +1 -1
  246. package/dist/core/indexing/virtualviews/index.js.map +1 -1
  247. package/dist/core/indexing/virtualviews/types.d.ts +6 -0
  248. package/dist/core/indexing/virtualviews/types.d.ts.map +1 -1
  249. package/dist/core/indexing/virtualviews/types.js +11 -3
  250. package/dist/core/indexing/virtualviews/types.js.map +1 -1
  251. package/dist/core/keys/KeyBag.d.ts +25 -0
  252. package/dist/core/keys/KeyBag.d.ts.map +1 -1
  253. package/dist/core/keys/KeyBag.js +37 -1
  254. package/dist/core/keys/KeyBag.js.map +1 -1
  255. package/dist/core/query/executeQuery.d.ts +18 -0
  256. package/dist/core/query/executeQuery.d.ts.map +1 -0
  257. package/dist/core/query/executeQuery.js +313 -0
  258. package/dist/core/query/executeQuery.js.map +1 -0
  259. package/dist/core/query/index.d.ts +5 -0
  260. package/dist/core/query/index.d.ts.map +1 -0
  261. package/dist/core/query/index.js +14 -0
  262. package/dist/core/query/index.js.map +1 -0
  263. package/dist/core/query/queryLive.d.ts +27 -0
  264. package/dist/core/query/queryLive.d.ts.map +1 -0
  265. package/dist/core/query/queryLive.js +104 -0
  266. package/dist/core/query/queryLive.js.map +1 -0
  267. package/dist/core/query/queryView.d.ts +156 -0
  268. package/dist/core/query/queryView.d.ts.map +1 -0
  269. package/dist/core/query/queryView.js +266 -0
  270. package/dist/core/query/queryView.js.map +1 -0
  271. package/dist/core/query/types.d.ts +121 -0
  272. package/dist/core/query/types.d.ts.map +1 -0
  273. package/dist/core/query/types.js +18 -0
  274. package/dist/core/query/types.js.map +1 -0
  275. package/dist/core/storeEntryTime.d.ts +57 -0
  276. package/dist/core/storeEntryTime.d.ts.map +1 -0
  277. package/dist/core/storeEntryTime.js +72 -0
  278. package/dist/core/storeEntryTime.js.map +1 -0
  279. package/dist/core/types.d.ts +1509 -39
  280. package/dist/core/types.d.ts.map +1 -1
  281. package/dist/core/types.js +13 -1
  282. package/dist/core/types.js.map +1 -1
  283. package/dist/core/uri/MindooURI.d.ts +53 -1
  284. package/dist/core/uri/MindooURI.d.ts.map +1 -1
  285. package/dist/core/uri/MindooURI.js +135 -0
  286. package/dist/core/uri/MindooURI.js.map +1 -1
  287. package/dist/core/utils/urlSafety.d.ts +46 -0
  288. package/dist/core/utils/urlSafety.d.ts.map +1 -0
  289. package/dist/core/utils/urlSafety.js +144 -0
  290. package/dist/core/utils/urlSafety.js.map +1 -0
  291. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +14 -0
  292. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -1
  293. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +95 -4
  294. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -1
  295. package/dist/node/server/CapabilityMatcher.d.ts +10 -0
  296. package/dist/node/server/CapabilityMatcher.d.ts.map +1 -1
  297. package/dist/node/server/CapabilityMatcher.js +14 -2
  298. package/dist/node/server/CapabilityMatcher.js.map +1 -1
  299. package/dist/node/server/MindooDBServer.d.ts.map +1 -1
  300. package/dist/node/server/MindooDBServer.js +117 -8
  301. package/dist/node/server/MindooDBServer.js.map +1 -1
  302. package/dist/node/server/PurgedDocRegistry.d.ts +32 -0
  303. package/dist/node/server/PurgedDocRegistry.d.ts.map +1 -0
  304. package/dist/node/server/PurgedDocRegistry.js +94 -0
  305. package/dist/node/server/PurgedDocRegistry.js.map +1 -0
  306. package/dist/node/server/ServerSync.d.ts.map +1 -1
  307. package/dist/node/server/ServerSync.js +5 -2
  308. package/dist/node/server/ServerSync.js.map +1 -1
  309. package/dist/node/server/SystemAdminAuth.d.ts +10 -0
  310. package/dist/node/server/SystemAdminAuth.d.ts.map +1 -1
  311. package/dist/node/server/SystemAdminAuth.js +25 -0
  312. package/dist/node/server/SystemAdminAuth.js.map +1 -1
  313. package/dist/node/server/TenantManager.d.ts +95 -1
  314. package/dist/node/server/TenantManager.d.ts.map +1 -1
  315. package/dist/node/server/TenantManager.js +382 -15
  316. package/dist/node/server/TenantManager.js.map +1 -1
  317. package/dist/node/server/config.d.ts.map +1 -1
  318. package/dist/node/server/config.js +5 -1
  319. package/dist/node/server/config.js.map +1 -1
  320. package/dist/node/server/types.d.ts +29 -3
  321. package/dist/node/server/types.d.ts.map +1 -1
  322. package/dist/node/server/types.js +12 -0
  323. package/dist/node/server/types.js.map +1 -1
  324. package/dist/node/server/validation.d.ts +6 -0
  325. package/dist/node/server/validation.d.ts.map +1 -1
  326. package/dist/node/server/validation.js +7 -1
  327. package/dist/node/server/validation.js.map +1 -1
  328. package/package.json +4 -3
  329. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts +0 -8
  330. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts.map +0 -1
  331. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js +0 -16
  332. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js.map +0 -1
  333. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +0 -68
  334. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +0 -1
  335. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +0 -659
  336. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +0 -1
  337. package/dist/node/attachments/writeAttachmentToFile.d.ts +0 -15
  338. package/dist/node/attachments/writeAttachmentToFile.d.ts.map +0 -1
  339. package/dist/node/attachments/writeAttachmentToFile.js +0 -73
  340. package/dist/node/attachments/writeAttachmentToFile.js.map +0 -1
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PSEUDO_TOKEN_AUTHOR = exports.PSEUDO_TOKEN_ADMIN = exports.ALWAYS_PRESENT_PSEUDO_TOKENS = void 0;
4
+ exports.defaultWhenForOp = defaultWhenForOp;
5
+ exports.evaluateAccess = evaluateAccess;
6
+ const types_1 = require("./types");
7
+ Object.defineProperty(exports, "PSEUDO_TOKEN_ADMIN", { enumerable: true, get: function () { return types_1.PSEUDO_TOKEN_ADMIN; } });
8
+ Object.defineProperty(exports, "PSEUDO_TOKEN_AUTHOR", { enumerable: true, get: function () { return types_1.PSEUDO_TOKEN_AUTHOR; } });
9
+ /** The default `when` for a clause, given the operation (§6.3). */
10
+ function defaultWhenForOp(op) {
11
+ return op === "doc_create" ? "after" : "before";
12
+ }
13
+ function allow(reason, tier, matchedRuleId) {
14
+ return { allowed: true, reason, tier, matchedRuleId };
15
+ }
16
+ function deny(reason, tier, matchedRuleId) {
17
+ return { allowed: false, reason, tier, matchedRuleId };
18
+ }
19
+ /**
20
+ * Evaluate access for an operation (§7). The result is fully determined by the
21
+ * inputs; see {@link EvaluateAccessInput}.
22
+ */
23
+ function evaluateAccess(input) {
24
+ const { op, dbid, identity, node, isServer } = input;
25
+ // No policy document has ever existed -> access control was never enabled ->
26
+ // everything is allowed (§6.1, the "no acl_defaultpolicy" state).
27
+ if (node.defaultPolicy === null) {
28
+ return allow("access control not enabled (no default policy)", "tier1");
29
+ }
30
+ const dbPolicy = node.dbPolicies.get(dbid) ?? null;
31
+ const eff = (0, types_1.effectivePolicy)(node.defaultPolicy, dbPolicy);
32
+ // Step 0: master switch short-circuits everything, including standalone deny
33
+ // rules (§7 step 0).
34
+ if (eff.disableAllAccessChecksAndPolicies) {
35
+ return allow("access control disabled by master switch", "tier1");
36
+ }
37
+ // Step 2: baseline from the effective deny<Op> flag.
38
+ const denyField = {
39
+ doc_create: eff.denyDocCreate,
40
+ doc_change: eff.denyDocChange,
41
+ doc_delete: eff.denyDocDelete,
42
+ doc_undelete: eff.denyDocUndelete,
43
+ doc_snapshot: eff.denyDocSnapshot,
44
+ doc_read: eff.denyDocRead,
45
+ }[op];
46
+ const baselineDenied = denyField === true;
47
+ // Step 4: collect rules of this type whose dbid matches and whose users_hashes
48
+ // intersect the identity set.
49
+ const candidateRules = (node.rulesByType.get(op) ?? []).filter((r) => (r.dbid === dbid || r.dbid === "*") && intersects(r.users_hashes, identity.hashes));
50
+ // Partition into Tier 1 (no withfields) and Tier 2 (withfields) rules.
51
+ let denyMatched = null;
52
+ let allowMatched = null;
53
+ // Tracks whether a Tier 2 rule *could* allow (used by the server to defer).
54
+ let tier2AllowDeferred = false;
55
+ let tier2DenyDeferred = false;
56
+ for (const rule of candidateRules) {
57
+ const isTier2 = (rule.withfields?.length ?? 0) > 0;
58
+ if (isTier2 && isServer) {
59
+ // The server cannot evaluate content; remember that a Tier 2 rule of this
60
+ // action exists so it can defer to the client rather than over-deny/allow.
61
+ if (rule.action === "allow")
62
+ tier2AllowDeferred = true;
63
+ else
64
+ tier2DenyDeferred = true;
65
+ continue;
66
+ }
67
+ const matches = isTier2 ? withFieldsPass(rule, input) : true;
68
+ if (!matches)
69
+ continue;
70
+ const tier = isTier2 ? "tier2" : "tier1";
71
+ if (rule.action === "deny" && !denyMatched)
72
+ denyMatched = { rule, tier };
73
+ if (rule.action === "allow" && !allowMatched)
74
+ allowMatched = { rule, tier };
75
+ }
76
+ // Step 5: deny-overrides-allow (set-based, order-independent).
77
+ if (denyMatched) {
78
+ return deny(`denied by rule ${denyMatched.rule.ruleId}`, denyMatched.tier, denyMatched.rule.ruleId);
79
+ }
80
+ if (allowMatched) {
81
+ return allow(`allowed by rule ${allowMatched.rule.ruleId}`, allowMatched.tier, allowMatched.rule.ruleId);
82
+ }
83
+ // No conclusive rule matched. On the server, defer to the client when the
84
+ // only thing that could change the verdict is a Tier 2 rule (§7).
85
+ if (isServer && baselineDenied && tier2AllowDeferred) {
86
+ return allow("baseline deny may be overridden by a Tier 2 allow (deferred to client)", "tier1");
87
+ }
88
+ if (isServer && !baselineDenied && tier2DenyDeferred) {
89
+ // A Tier 2 deny might apply, but only the client can check it.
90
+ return allow("baseline allow; Tier 2 deny deferred to client", "tier1");
91
+ }
92
+ return baselineDenied
93
+ ? deny(`denied by baseline policy for ${op}`, "tier1")
94
+ : allow(`allowed by baseline policy for ${op}`, "tier1");
95
+ }
96
+ /** Returns true if any element of `hashes` is in `set`. */
97
+ function intersects(hashes, set) {
98
+ for (const h of hashes) {
99
+ if (set.has(h))
100
+ return true;
101
+ }
102
+ return false;
103
+ }
104
+ /**
105
+ * Evaluate every `withfields` clause of a Tier 2 rule against the document
106
+ * state selected by each clause's `when` (§6.3). All clauses must pass.
107
+ */
108
+ function withFieldsPass(rule, input) {
109
+ for (const clause of rule.withfields ?? []) {
110
+ const when = clause.when ?? defaultWhenForOp(input.op);
111
+ const doc = when === "after" ? input.afterDoc : input.beforeDoc;
112
+ if (!evaluateClause(clause, doc ?? null, input.identity)) {
113
+ return false;
114
+ }
115
+ }
116
+ return true;
117
+ }
118
+ /** Resolve a clause value, expanding placeholders against the identity set. */
119
+ function resolveValue(value, identity) {
120
+ if ((0, types_1.isPlaceholder)(value)) {
121
+ switch (value) {
122
+ case "${user.username}":
123
+ return { scalar: identity.username, list: [identity.username] };
124
+ case "${user.usernames}":
125
+ return { list: identity.usernames };
126
+ case "${user.groups}":
127
+ return { list: identity.groups };
128
+ }
129
+ }
130
+ if (Array.isArray(value)) {
131
+ return { list: value };
132
+ }
133
+ return { scalar: value };
134
+ }
135
+ /** Read a dot-path from a document object. */
136
+ function readPath(doc, key) {
137
+ if (!doc)
138
+ return undefined;
139
+ const parts = key.split(".");
140
+ let cur = doc;
141
+ for (const part of parts) {
142
+ if (cur === null || cur === undefined || typeof cur !== "object")
143
+ return undefined;
144
+ cur = cur[part];
145
+ }
146
+ return cur;
147
+ }
148
+ /** Evaluate a single clause against a document state. */
149
+ function evaluateClause(clause, doc, identity) {
150
+ const op = clause.op;
151
+ const docValue = readPath(doc, clause.key);
152
+ // Existence operators don't need the value.
153
+ if (op === "exists")
154
+ return docValue !== undefined;
155
+ if (op === "notExists")
156
+ return docValue === undefined;
157
+ const resolved = resolveValue(clause.value, identity);
158
+ switch (op) {
159
+ case "equals":
160
+ return resolved.scalar !== undefined && docValue === resolved.scalar;
161
+ case "notEquals":
162
+ return resolved.scalar === undefined || docValue !== resolved.scalar;
163
+ case "contains": {
164
+ // docValue is an array or string; check it contains the scalar value.
165
+ const needle = resolved.scalar;
166
+ if (needle === undefined)
167
+ return false;
168
+ if (Array.isArray(docValue))
169
+ return docValue.includes(needle);
170
+ if (typeof docValue === "string" && typeof needle === "string")
171
+ return docValue.includes(needle);
172
+ return false;
173
+ }
174
+ case "containsAny": {
175
+ const list = resolved.list ?? (resolved.scalar !== undefined ? [resolved.scalar] : []);
176
+ if (!Array.isArray(docValue))
177
+ return false;
178
+ return list.some((v) => docValue.includes(v));
179
+ }
180
+ case "containsAll": {
181
+ const list = resolved.list ?? (resolved.scalar !== undefined ? [resolved.scalar] : []);
182
+ if (!Array.isArray(docValue))
183
+ return false;
184
+ return list.every((v) => docValue.includes(v));
185
+ }
186
+ case "gt":
187
+ case "gte":
188
+ case "lt":
189
+ case "lte": {
190
+ if (typeof docValue !== "number" || typeof resolved.scalar !== "number")
191
+ return false;
192
+ const a = docValue;
193
+ const b = resolved.scalar;
194
+ return op === "gt" ? a > b : op === "gte" ? a >= b : op === "lt" ? a < b : a <= b;
195
+ }
196
+ default:
197
+ return false;
198
+ }
199
+ }
200
+ /**
201
+ * Convenience: the set of reserved pseudo-tokens an identity always/optionally
202
+ * carries. `$everyone` is always present for registered users; `$admin` and
203
+ * `$author` are added by the caller when applicable.
204
+ */
205
+ exports.ALWAYS_PRESENT_PSEUDO_TOKENS = [types_1.PSEUDO_TOKEN_EVERYONE];
206
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../../src/core/accesscontrol/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Helpers for reading and writing the public-key fields of a `grantaccess`
3
+ * directory document in a way that is forward- and backward-compatible
4
+ * (docs/accesscontrol.md §6.5).
5
+ *
6
+ * Active devices and revoked devices live in TWO SEPARATE lists:
7
+ *
8
+ * - `userKeyPairs`: the ACTIVE device key pairs, an array of
9
+ * `{ signingPublicKey, encryptionPublicKey, label? }` objects. Pairing the
10
+ * keys per device keeps a device's signing and encryption keys together and
11
+ * lets each carry an optional human-readable label. This is the canonical
12
+ * list the server/auth treat as granting access. Because revoked devices are
13
+ * NOT in this list, any reader (old or new) that treats `userKeyPairs` as
14
+ * "the keys that have access" is correct without understanding revocation.
15
+ * - `revokedUserKeyPairs`: the RETAINED revoked device key pairs (§6.5), same
16
+ * shape plus an optional `revokedAt` timestamp. Membership in this list — not
17
+ * a per-entry flag — is what marks a device revoked. Retaining them lets
18
+ * admin UIs list "devices with revoked access" and optionally restore them.
19
+ *
20
+ * For older clients that predate `userKeyPairs`, writers also mirror the ACTIVE
21
+ * keys into the legacy forms, read in this order of authority:
22
+ *
23
+ * 1. `userKeyPairs` (the active list above; authoritative once present).
24
+ * 2. `userSigningPublicKeys` / `userEncryptionPublicKeys`: two parallel string
25
+ * arrays (previous form). Index-aligned by convention; no labels.
26
+ * 3. `userSigningPublicKey` / `userEncryptionPublicKey`: single legacy scalars
27
+ * (oldest form).
28
+ *
29
+ * The most specific present form wins. Critically, a present-but-EMPTY
30
+ * `userKeyPairs` is authoritative (it denotes a grant with no active devices,
31
+ * §6.5): we must NOT fall back to a stale lower form and resurrect access that
32
+ * revocation removed.
33
+ *
34
+ * Writers ({@link applyKeyPairFields}) keep the legacy forms mirrored so older
35
+ * clients (which only understand the array or scalar forms) keep working.
36
+ *
37
+ * These functions are pure (operate on a plain data object) so they can be
38
+ * reused by the directory cache builder, the time-travel node builder, and the
39
+ * server, and unit-tested in isolation.
40
+ */
41
+ import type { GrantKeyPair } from "../types";
42
+ /**
43
+ * All device key pairs on this document — active first, then revoked — in the
44
+ * canonical `{ signingPublicKey, encryptionPublicKey, label?, revoked?,
45
+ * revokedAt? }` shape (§6.5). Used by write paths that need to preserve the
46
+ * full device set (e.g. relabel/merge/revoke) before re-applying.
47
+ *
48
+ * For older documents that predate the canonical lists it reconstructs pairs
49
+ * from the parallel signing/encryption arrays (index-aligned) or the legacy
50
+ * scalars. De-duplicated by signing key.
51
+ */
52
+ export declare function extractKeyPairs(data: Record<string, unknown>): GrantKeyPair[];
53
+ /**
54
+ * The active (non-revoked) device key pairs. This is the set the server/auth
55
+ * treat as granting access; revoked pairs are retained on the document (in
56
+ * `revokedUserKeyPairs`) but excluded here (docs/accesscontrol.md §6.5).
57
+ */
58
+ export declare function extractActiveKeyPairs(data: Record<string, unknown>): GrantKeyPair[];
59
+ /**
60
+ * The revoked device key pairs retained on the grant document (§6.5), each
61
+ * carrying its `revokedAt` timestamp and optional label, so admin UIs can list
62
+ * "devices with revoked access" and optionally restore them.
63
+ */
64
+ export declare function extractRevokedKeyPairs(data: Record<string, unknown>): GrantKeyPair[];
65
+ /**
66
+ * Write the key representations onto `data` from the canonical list of pairs
67
+ * (§6.5). Pairs are partitioned by their `revoked` flag into two lists:
68
+ *
69
+ * - active pairs → `userKeyPairs` (also mirrored to the legacy array/scalar
70
+ * forms so older readers keep working), and
71
+ * - revoked pairs → `revokedUserKeyPairs` (retained with their `revokedAt`
72
+ * timestamp and label, but never mirrored to the legacy forms).
73
+ *
74
+ * Both lists are always written (possibly empty), so the document is
75
+ * authoritative: an empty `userKeyPairs` denotes no active devices and prevents
76
+ * any stale legacy form from resurrecting access. The legacy scalars are left
77
+ * untouched when there is no active pair. This also heals documents written in
78
+ * the older format (revoked pairs embedded in `userKeyPairs`) into the two-list
79
+ * form, since revoked pairs are routed to `revokedUserKeyPairs` here.
80
+ */
81
+ export declare function applyKeyPairFields(data: Record<string, unknown>, pairs: GrantKeyPair[]): void;
82
+ /**
83
+ * Merge `additional` pairs into `existing`, keyed by signing public key. A new
84
+ * entry with the same signing key replaces the existing one (so its encryption
85
+ * key and/or label are updated). Order is preserved: existing pairs first
86
+ * (updated in place), then brand-new pairs in input order.
87
+ */
88
+ export declare function mergeKeyPairs(existing: GrantKeyPair[], additional: GrantKeyPair[]): GrantKeyPair[];
89
+ /**
90
+ * All signing public keys granted by this document. Prefers `userKeyPairs`,
91
+ * then the `userSigningPublicKeys` array, then the legacy scalar. Returns a
92
+ * de-duplicated list (possibly empty, e.g. when all keys were removed to fully
93
+ * revoke the user).
94
+ */
95
+ export declare function extractSigningPublicKeys(data: Record<string, unknown>): string[];
96
+ /**
97
+ * All encryption public keys granted by this document. Prefers `userKeyPairs`,
98
+ * then the `userEncryptionPublicKeys` array, then the legacy scalar.
99
+ */
100
+ export declare function extractEncryptionPublicKeys(data: Record<string, unknown>): string[];
101
+ /**
102
+ * The primary signing/encryption key for legacy consumers that still expect a
103
+ * single value. Returns the first array element, else the scalar, else null.
104
+ */
105
+ export declare function primarySigningPublicKey(data: Record<string, unknown>): string | null;
106
+ export declare function primaryEncryptionPublicKey(data: Record<string, unknown>): string | null;
107
+ /**
108
+ * Signing public keys whose device must wipe the local tenant on next connect
109
+ * (`wipeRequestedForSigningKeys`, §6.5). Self-contained key values, not
110
+ * references into the grant arrays.
111
+ */
112
+ export declare function extractWipeRequestedSigningKeys(data: Record<string, unknown>): string[];
113
+ //# sourceMappingURL=grantKeys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grantKeys.d.ts","sourceRoot":"","sources":["../../../src/core/accesscontrol/grantKeys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAkG7C;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,EAAE,CAK7E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,EAAE,CAKnF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,EAAE,CAEpF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CA6C7F;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAKlG;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAShF;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAanF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAEpF;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAEvF;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAEvF"}
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ /**
3
+ * Helpers for reading and writing the public-key fields of a `grantaccess`
4
+ * directory document in a way that is forward- and backward-compatible
5
+ * (docs/accesscontrol.md §6.5).
6
+ *
7
+ * Active devices and revoked devices live in TWO SEPARATE lists:
8
+ *
9
+ * - `userKeyPairs`: the ACTIVE device key pairs, an array of
10
+ * `{ signingPublicKey, encryptionPublicKey, label? }` objects. Pairing the
11
+ * keys per device keeps a device's signing and encryption keys together and
12
+ * lets each carry an optional human-readable label. This is the canonical
13
+ * list the server/auth treat as granting access. Because revoked devices are
14
+ * NOT in this list, any reader (old or new) that treats `userKeyPairs` as
15
+ * "the keys that have access" is correct without understanding revocation.
16
+ * - `revokedUserKeyPairs`: the RETAINED revoked device key pairs (§6.5), same
17
+ * shape plus an optional `revokedAt` timestamp. Membership in this list — not
18
+ * a per-entry flag — is what marks a device revoked. Retaining them lets
19
+ * admin UIs list "devices with revoked access" and optionally restore them.
20
+ *
21
+ * For older clients that predate `userKeyPairs`, writers also mirror the ACTIVE
22
+ * keys into the legacy forms, read in this order of authority:
23
+ *
24
+ * 1. `userKeyPairs` (the active list above; authoritative once present).
25
+ * 2. `userSigningPublicKeys` / `userEncryptionPublicKeys`: two parallel string
26
+ * arrays (previous form). Index-aligned by convention; no labels.
27
+ * 3. `userSigningPublicKey` / `userEncryptionPublicKey`: single legacy scalars
28
+ * (oldest form).
29
+ *
30
+ * The most specific present form wins. Critically, a present-but-EMPTY
31
+ * `userKeyPairs` is authoritative (it denotes a grant with no active devices,
32
+ * §6.5): we must NOT fall back to a stale lower form and resurrect access that
33
+ * revocation removed.
34
+ *
35
+ * Writers ({@link applyKeyPairFields}) keep the legacy forms mirrored so older
36
+ * clients (which only understand the array or scalar forms) keep working.
37
+ *
38
+ * These functions are pure (operate on a plain data object) so they can be
39
+ * reused by the directory cache builder, the time-travel node builder, and the
40
+ * server, and unit-tested in isolation.
41
+ */
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.extractKeyPairs = extractKeyPairs;
44
+ exports.extractActiveKeyPairs = extractActiveKeyPairs;
45
+ exports.extractRevokedKeyPairs = extractRevokedKeyPairs;
46
+ exports.applyKeyPairFields = applyKeyPairFields;
47
+ exports.mergeKeyPairs = mergeKeyPairs;
48
+ exports.extractSigningPublicKeys = extractSigningPublicKeys;
49
+ exports.extractEncryptionPublicKeys = extractEncryptionPublicKeys;
50
+ exports.primarySigningPublicKey = primarySigningPublicKey;
51
+ exports.primaryEncryptionPublicKey = primaryEncryptionPublicKey;
52
+ exports.extractWipeRequestedSigningKeys = extractWipeRequestedSigningKeys;
53
+ function asStringArray(value) {
54
+ if (!Array.isArray(value))
55
+ return [];
56
+ return value.filter((v) => typeof v === "string" && v.length > 0);
57
+ }
58
+ function asScalarString(value) {
59
+ return typeof value === "string" && value.length > 0 ? value : null;
60
+ }
61
+ function asLabel(value) {
62
+ return typeof value === "string" && value.length > 0 ? value : undefined;
63
+ }
64
+ /**
65
+ * The signing keys from the legacy (pre-`userKeyPairs`) representation: the
66
+ * `userSigningPublicKeys` array if present (authoritative even when empty),
67
+ * else the legacy scalar.
68
+ */
69
+ function legacySigningKeys(data) {
70
+ if (Array.isArray(data.userSigningPublicKeys)) {
71
+ return Array.from(new Set(asStringArray(data.userSigningPublicKeys)));
72
+ }
73
+ const scalar = asScalarString(data.userSigningPublicKey);
74
+ return scalar ? [scalar] : [];
75
+ }
76
+ /** Encryption keys from the legacy representation (array else scalar). */
77
+ function legacyEncryptionKeys(data) {
78
+ if (Array.isArray(data.userEncryptionPublicKeys)) {
79
+ return Array.from(new Set(asStringArray(data.userEncryptionPublicKeys)));
80
+ }
81
+ const scalar = asScalarString(data.userEncryptionPublicKey);
82
+ return scalar ? [scalar] : [];
83
+ }
84
+ /**
85
+ * Parse an array of `{ signingPublicKey, encryptionPublicKey, label? }` entries
86
+ * into {@link GrantKeyPair}s, de-duplicated by signing key. When `markRevoked`
87
+ * is set (parsing `revokedUserKeyPairs`), every parsed pair is marked revoked
88
+ * and carries its `revokedAt` timestamp.
89
+ */
90
+ function parsePairEntries(value, markRevoked) {
91
+ if (!Array.isArray(value))
92
+ return [];
93
+ const seen = new Set();
94
+ const pairs = [];
95
+ for (const entry of value) {
96
+ if (!entry || typeof entry !== "object")
97
+ continue;
98
+ const rec = entry;
99
+ const signingPublicKey = asScalarString(rec.signingPublicKey);
100
+ if (!signingPublicKey || seen.has(signingPublicKey))
101
+ continue;
102
+ seen.add(signingPublicKey);
103
+ const encryptionPublicKey = asScalarString(rec.encryptionPublicKey) ?? "";
104
+ const label = asLabel(rec.label);
105
+ const pair = { signingPublicKey, encryptionPublicKey };
106
+ if (label !== undefined)
107
+ pair.label = label;
108
+ if (markRevoked) {
109
+ pair.revoked = true;
110
+ if (typeof rec.revokedAt === "number")
111
+ pair.revokedAt = rec.revokedAt;
112
+ }
113
+ pairs.push(pair);
114
+ }
115
+ return pairs;
116
+ }
117
+ /** True when the document uses the canonical two-list form (active and/or revoked). */
118
+ function hasCanonicalKeyLists(data) {
119
+ return Array.isArray(data.userKeyPairs) || Array.isArray(data.revokedUserKeyPairs);
120
+ }
121
+ /** The active pairs from the canonical `userKeyPairs` list. */
122
+ function canonicalActivePairs(data) {
123
+ return parsePairEntries(data.userKeyPairs, false);
124
+ }
125
+ /**
126
+ * The revoked pairs from the canonical `revokedUserKeyPairs` list, each marked
127
+ * revoked and carrying its `revokedAt` timestamp.
128
+ */
129
+ function canonicalRevokedPairs(data) {
130
+ return parsePairEntries(data.revokedUserKeyPairs, true);
131
+ }
132
+ /** Reconstruct active pairs from the legacy parallel arrays / scalars by index. */
133
+ function legacyKeyPairs(data) {
134
+ const signing = legacySigningKeys(data);
135
+ const encryption = legacyEncryptionKeys(data);
136
+ const seen = new Set();
137
+ const pairs = [];
138
+ signing.forEach((signingPublicKey, index) => {
139
+ if (seen.has(signingPublicKey))
140
+ return;
141
+ seen.add(signingPublicKey);
142
+ pairs.push({ signingPublicKey, encryptionPublicKey: encryption[index] ?? "" });
143
+ });
144
+ return pairs;
145
+ }
146
+ /**
147
+ * All device key pairs on this document — active first, then revoked — in the
148
+ * canonical `{ signingPublicKey, encryptionPublicKey, label?, revoked?,
149
+ * revokedAt? }` shape (§6.5). Used by write paths that need to preserve the
150
+ * full device set (e.g. relabel/merge/revoke) before re-applying.
151
+ *
152
+ * For older documents that predate the canonical lists it reconstructs pairs
153
+ * from the parallel signing/encryption arrays (index-aligned) or the legacy
154
+ * scalars. De-duplicated by signing key.
155
+ */
156
+ function extractKeyPairs(data) {
157
+ if (hasCanonicalKeyLists(data)) {
158
+ return [...canonicalActivePairs(data), ...canonicalRevokedPairs(data)];
159
+ }
160
+ return legacyKeyPairs(data);
161
+ }
162
+ /**
163
+ * The active (non-revoked) device key pairs. This is the set the server/auth
164
+ * treat as granting access; revoked pairs are retained on the document (in
165
+ * `revokedUserKeyPairs`) but excluded here (docs/accesscontrol.md §6.5).
166
+ */
167
+ function extractActiveKeyPairs(data) {
168
+ if (hasCanonicalKeyLists(data)) {
169
+ return canonicalActivePairs(data);
170
+ }
171
+ return legacyKeyPairs(data);
172
+ }
173
+ /**
174
+ * The revoked device key pairs retained on the grant document (§6.5), each
175
+ * carrying its `revokedAt` timestamp and optional label, so admin UIs can list
176
+ * "devices with revoked access" and optionally restore them.
177
+ */
178
+ function extractRevokedKeyPairs(data) {
179
+ return canonicalRevokedPairs(data);
180
+ }
181
+ /**
182
+ * Write the key representations onto `data` from the canonical list of pairs
183
+ * (§6.5). Pairs are partitioned by their `revoked` flag into two lists:
184
+ *
185
+ * - active pairs → `userKeyPairs` (also mirrored to the legacy array/scalar
186
+ * forms so older readers keep working), and
187
+ * - revoked pairs → `revokedUserKeyPairs` (retained with their `revokedAt`
188
+ * timestamp and label, but never mirrored to the legacy forms).
189
+ *
190
+ * Both lists are always written (possibly empty), so the document is
191
+ * authoritative: an empty `userKeyPairs` denotes no active devices and prevents
192
+ * any stale legacy form from resurrecting access. The legacy scalars are left
193
+ * untouched when there is no active pair. This also heals documents written in
194
+ * the older format (revoked pairs embedded in `userKeyPairs`) into the two-list
195
+ * form, since revoked pairs are routed to `revokedUserKeyPairs` here.
196
+ */
197
+ function applyKeyPairFields(data, pairs) {
198
+ const activePairs = pairs.filter((pair) => !pair.revoked);
199
+ const revokedPairs = pairs.filter((pair) => pair.revoked === true);
200
+ // Active devices: the canonical `userKeyPairs` list. No `revoked` flag is
201
+ // written — membership in this list is what marks a device active.
202
+ data.userKeyPairs = activePairs.map((pair) => {
203
+ const entry = {
204
+ signingPublicKey: pair.signingPublicKey,
205
+ encryptionPublicKey: pair.encryptionPublicKey,
206
+ };
207
+ if (pair.label !== undefined && pair.label.length > 0) {
208
+ entry.label = pair.label;
209
+ }
210
+ return entry;
211
+ });
212
+ // Revoked devices: retained in a SEPARATE list (§6.5). Membership here marks
213
+ // a device revoked; we keep the `revokedAt` timestamp and label for admin UIs.
214
+ data.revokedUserKeyPairs = revokedPairs.map((pair) => {
215
+ const entry = {
216
+ signingPublicKey: pair.signingPublicKey,
217
+ encryptionPublicKey: pair.encryptionPublicKey,
218
+ };
219
+ if (pair.label !== undefined && pair.label.length > 0) {
220
+ entry.label = pair.label;
221
+ }
222
+ if (typeof pair.revokedAt === "number") {
223
+ entry.revokedAt = pair.revokedAt;
224
+ }
225
+ return entry;
226
+ });
227
+ // Mirror the parallel-array form (ACTIVE only) for readers that predate
228
+ // userKeyPairs. A revoked device must never appear here.
229
+ data.userSigningPublicKeys = activePairs.map((pair) => pair.signingPublicKey);
230
+ data.userEncryptionPublicKeys = activePairs
231
+ .map((pair) => pair.encryptionPublicKey)
232
+ .filter((key) => key.length > 0);
233
+ // Keep the legacy scalars pointing at the primary (first) ACTIVE pair for the
234
+ // oldest readers. Only updated when at least one active pair remains.
235
+ if (activePairs.length > 0) {
236
+ data.userSigningPublicKey = activePairs[0].signingPublicKey;
237
+ data.userEncryptionPublicKey = activePairs[0].encryptionPublicKey;
238
+ }
239
+ }
240
+ /**
241
+ * Merge `additional` pairs into `existing`, keyed by signing public key. A new
242
+ * entry with the same signing key replaces the existing one (so its encryption
243
+ * key and/or label are updated). Order is preserved: existing pairs first
244
+ * (updated in place), then brand-new pairs in input order.
245
+ */
246
+ function mergeKeyPairs(existing, additional) {
247
+ const merged = new Map();
248
+ for (const pair of existing)
249
+ merged.set(pair.signingPublicKey, pair);
250
+ for (const pair of additional)
251
+ merged.set(pair.signingPublicKey, pair);
252
+ return Array.from(merged.values());
253
+ }
254
+ /**
255
+ * All signing public keys granted by this document. Prefers `userKeyPairs`,
256
+ * then the `userSigningPublicKeys` array, then the legacy scalar. Returns a
257
+ * de-duplicated list (possibly empty, e.g. when all keys were removed to fully
258
+ * revoke the user).
259
+ */
260
+ function extractSigningPublicKeys(data) {
261
+ // The canonical form is authoritative once present, even when `userKeyPairs`
262
+ // is empty: a grant with no active devices is how a fully-revoked user is
263
+ // represented (§6.5), so we must not fall back to the legacy arrays/scalars
264
+ // in that case. Only ACTIVE (non-revoked) pairs count.
265
+ if (hasCanonicalKeyLists(data)) {
266
+ return Array.from(new Set(extractActiveKeyPairs(data).map((pair) => pair.signingPublicKey)));
267
+ }
268
+ return legacySigningKeys(data);
269
+ }
270
+ /**
271
+ * All encryption public keys granted by this document. Prefers `userKeyPairs`,
272
+ * then the `userEncryptionPublicKeys` array, then the legacy scalar.
273
+ */
274
+ function extractEncryptionPublicKeys(data) {
275
+ // See extractSigningPublicKeys: a present (even empty) canonical form is
276
+ // authoritative, and only ACTIVE (non-revoked) pairs count.
277
+ if (hasCanonicalKeyLists(data)) {
278
+ return Array.from(new Set(extractActiveKeyPairs(data)
279
+ .map((pair) => pair.encryptionPublicKey)
280
+ .filter((key) => key.length > 0)));
281
+ }
282
+ return legacyEncryptionKeys(data);
283
+ }
284
+ /**
285
+ * The primary signing/encryption key for legacy consumers that still expect a
286
+ * single value. Returns the first array element, else the scalar, else null.
287
+ */
288
+ function primarySigningPublicKey(data) {
289
+ return extractSigningPublicKeys(data)[0] ?? null;
290
+ }
291
+ function primaryEncryptionPublicKey(data) {
292
+ return extractEncryptionPublicKeys(data)[0] ?? null;
293
+ }
294
+ /**
295
+ * Signing public keys whose device must wipe the local tenant on next connect
296
+ * (`wipeRequestedForSigningKeys`, §6.5). Self-contained key values, not
297
+ * references into the grant arrays.
298
+ */
299
+ function extractWipeRequestedSigningKeys(data) {
300
+ return Array.from(new Set(asStringArray(data.wipeRequestedForSigningKeys)));
301
+ }
302
+ //# sourceMappingURL=grantKeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grantKeys.js","sourceRoot":"","sources":["../../../src/core/accesscontrol/grantKeys.ts"],"names":[],"mappings":"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"}