mindoodb 0.0.2 → 0.0.4

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 (305) hide show
  1. package/README-server.md +1001 -0
  2. package/README.md +89 -28
  3. package/dist/__mocks__/expo-standard-web-crypto.d.ts +10 -0
  4. package/dist/__mocks__/expo-standard-web-crypto.d.ts.map +1 -0
  5. package/dist/__mocks__/expo-standard-web-crypto.js +22 -0
  6. package/dist/__mocks__/expo-standard-web-crypto.js.map +1 -0
  7. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts +8 -0
  8. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts.map +1 -0
  9. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js +16 -0
  10. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js.map +1 -0
  11. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts +1 -1
  12. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts.map +1 -1
  13. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js +2 -2
  14. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js.map +1 -1
  15. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +30 -1
  16. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
  17. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +152 -5
  18. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
  19. package/dist/appendonlystores/network/HttpTransport.d.ts +17 -2
  20. package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
  21. package/dist/appendonlystores/network/HttpTransport.js +129 -0
  22. package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
  23. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +22 -2
  24. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
  25. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +110 -0
  26. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
  27. package/dist/appendonlystores/network/index.d.ts +1 -1
  28. package/dist/appendonlystores/network/index.d.ts.map +1 -1
  29. package/dist/appendonlystores/network/index.js.map +1 -1
  30. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +65 -0
  31. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -0
  32. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +741 -0
  33. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -0
  34. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts +25 -0
  35. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts.map +1 -0
  36. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js +41 -0
  37. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js.map +1 -0
  38. package/dist/browser/cache/IndexedDBLocalCacheStore.d.ts +21 -0
  39. package/dist/browser/cache/IndexedDBLocalCacheStore.d.ts.map +1 -0
  40. package/dist/browser/cache/IndexedDBLocalCacheStore.js +106 -0
  41. package/dist/browser/cache/IndexedDBLocalCacheStore.js.map +1 -0
  42. package/dist/browser/index.d.ts +8 -0
  43. package/dist/browser/index.d.ts.map +1 -1
  44. package/dist/browser/index.js +21 -1
  45. package/dist/browser/index.js.map +1 -1
  46. package/dist/core/BaseMindooDB.d.ts +115 -13
  47. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  48. package/dist/core/BaseMindooDB.js +1232 -269
  49. package/dist/core/BaseMindooDB.js.map +1 -1
  50. package/dist/core/BaseMindooTenant.d.ts +69 -6
  51. package/dist/core/BaseMindooTenant.d.ts.map +1 -1
  52. package/dist/core/BaseMindooTenant.js +302 -109
  53. package/dist/core/BaseMindooTenant.js.map +1 -1
  54. package/dist/core/BaseMindooTenantDirectory.d.ts +13 -10
  55. package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
  56. package/dist/core/BaseMindooTenantDirectory.js +144 -27
  57. package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
  58. package/dist/core/BaseMindooTenantFactory.d.ts +27 -29
  59. package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
  60. package/dist/core/BaseMindooTenantFactory.js +185 -112
  61. package/dist/core/BaseMindooTenantFactory.js.map +1 -1
  62. package/dist/core/MindooDBServerAdmin.d.ts +238 -0
  63. package/dist/core/MindooDBServerAdmin.d.ts.map +1 -0
  64. package/dist/core/MindooDBServerAdmin.js +345 -0
  65. package/dist/core/MindooDBServerAdmin.js.map +1 -0
  66. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +68 -0
  67. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
  68. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +659 -0
  69. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
  70. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +45 -3
  71. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
  72. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +184 -23
  73. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
  74. package/dist/core/appendonlystores/MaterializationPlanner.d.ts +49 -0
  75. package/dist/core/appendonlystores/MaterializationPlanner.d.ts.map +1 -0
  76. package/dist/core/appendonlystores/MaterializationPlanner.js +325 -0
  77. package/dist/core/appendonlystores/MaterializationPlanner.js.map +1 -0
  78. package/dist/core/appendonlystores/bloom.d.ts +85 -0
  79. package/dist/core/appendonlystores/bloom.d.ts.map +1 -0
  80. package/dist/core/appendonlystores/bloom.js +228 -0
  81. package/dist/core/appendonlystores/bloom.js.map +1 -0
  82. package/dist/core/appendonlystores/network/NetworkTransport.d.ts +37 -2
  83. package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
  84. package/dist/core/appendonlystores/network/types.d.ts +12 -0
  85. package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
  86. package/dist/core/appendonlystores/network/types.js.map +1 -1
  87. package/dist/core/appendonlystores/types.d.ts +206 -0
  88. package/dist/core/appendonlystores/types.d.ts.map +1 -1
  89. package/dist/core/automerge-adapter.d.ts +15 -0
  90. package/dist/core/automerge-adapter.d.ts.map +1 -0
  91. package/dist/core/automerge-adapter.js +73 -0
  92. package/dist/core/automerge-adapter.js.map +1 -0
  93. package/dist/core/cache/CacheManager.d.ts +75 -0
  94. package/dist/core/cache/CacheManager.d.ts.map +1 -0
  95. package/dist/core/cache/CacheManager.js +101 -0
  96. package/dist/core/cache/CacheManager.js.map +1 -0
  97. package/dist/core/cache/EncryptedLocalCacheStore.d.ts +41 -0
  98. package/dist/core/cache/EncryptedLocalCacheStore.d.ts.map +1 -0
  99. package/dist/core/cache/EncryptedLocalCacheStore.js +120 -0
  100. package/dist/core/cache/EncryptedLocalCacheStore.js.map +1 -0
  101. package/dist/core/cache/LocalCacheStore.d.ts +50 -0
  102. package/dist/core/cache/LocalCacheStore.d.ts.map +1 -0
  103. package/dist/core/cache/LocalCacheStore.js +39 -0
  104. package/dist/core/cache/LocalCacheStore.js.map +1 -0
  105. package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
  106. package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -0
  107. package/dist/core/crypto/pbkdf2Iterations.js +55 -0
  108. package/dist/core/crypto/pbkdf2Iterations.js.map +1 -0
  109. package/dist/core/crypto/privateKeyEncryption.d.ts +5 -0
  110. package/dist/core/crypto/privateKeyEncryption.d.ts.map +1 -0
  111. package/dist/core/crypto/privateKeyEncryption.js +87 -0
  112. package/dist/core/crypto/privateKeyEncryption.js.map +1 -0
  113. package/dist/core/index.d.ts +18 -6
  114. package/dist/core/index.d.ts.map +1 -1
  115. package/dist/core/index.js +42 -1
  116. package/dist/core/index.js.map +1 -1
  117. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +4 -1
  118. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -1
  119. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +39 -11
  120. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
  121. package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts +1 -0
  122. package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts.map +1 -1
  123. package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js +3 -0
  124. package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js.map +1 -1
  125. package/dist/core/indexing/virtualviews/VirtualView.d.ts +43 -0
  126. package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -1
  127. package/dist/core/indexing/virtualviews/VirtualView.js +173 -0
  128. package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -1
  129. package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +7 -0
  130. package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -1
  131. package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +28 -0
  132. package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -1
  133. package/dist/core/keys/KeyBag.d.ts +56 -12
  134. package/dist/core/keys/KeyBag.d.ts.map +1 -1
  135. package/dist/core/keys/KeyBag.js +156 -70
  136. package/dist/core/keys/KeyBag.js.map +1 -1
  137. package/dist/core/keys/KeyContext.d.ts +4 -0
  138. package/dist/core/keys/KeyContext.d.ts.map +1 -0
  139. package/dist/core/keys/KeyContext.js +17 -0
  140. package/dist/core/keys/KeyContext.js.map +1 -0
  141. package/dist/core/types.d.ts +512 -60
  142. package/dist/core/types.d.ts.map +1 -1
  143. package/dist/core/types.js +9 -1
  144. package/dist/core/types.js.map +1 -1
  145. package/dist/core/uri/MindooURI.d.ts +58 -0
  146. package/dist/core/uri/MindooURI.d.ts.map +1 -0
  147. package/dist/core/uri/MindooURI.js +169 -0
  148. package/dist/core/uri/MindooURI.js.map +1 -0
  149. package/dist/core/userid/index.d.ts +0 -10
  150. package/dist/core/userid/index.d.ts.map +1 -1
  151. package/dist/core/utils/idGeneration.d.ts.map +1 -1
  152. package/dist/core/utils/idGeneration.js +37 -3
  153. package/dist/core/utils/idGeneration.js.map +1 -1
  154. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +544 -0
  155. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
  156. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +1358 -0
  157. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
  158. package/dist/node/attachments/writeAttachmentToFile.d.ts +15 -0
  159. package/dist/node/attachments/writeAttachmentToFile.d.ts.map +1 -0
  160. package/dist/node/attachments/writeAttachmentToFile.js +73 -0
  161. package/dist/node/attachments/writeAttachmentToFile.js.map +1 -0
  162. package/dist/node/cache/FileSystemLocalCacheStore.d.ts +17 -0
  163. package/dist/node/cache/FileSystemLocalCacheStore.d.ts.map +1 -0
  164. package/dist/node/cache/FileSystemLocalCacheStore.js +128 -0
  165. package/dist/node/cache/FileSystemLocalCacheStore.js.map +1 -0
  166. package/dist/node/cli/change-identity-password.d.ts +7 -0
  167. package/dist/node/cli/change-identity-password.d.ts.map +1 -0
  168. package/dist/node/cli/change-identity-password.js +67 -0
  169. package/dist/node/cli/change-identity-password.js.map +1 -0
  170. package/dist/node/cli/cli-utils.d.ts +16 -0
  171. package/dist/node/cli/cli-utils.d.ts.map +1 -0
  172. package/dist/node/cli/cli-utils.js +113 -0
  173. package/dist/node/cli/cli-utils.js.map +1 -0
  174. package/dist/node/cli/identity-export-public.d.ts +4 -0
  175. package/dist/node/cli/identity-export-public.d.ts.map +1 -0
  176. package/dist/node/cli/identity-export-public.js +55 -0
  177. package/dist/node/cli/identity-export-public.js.map +1 -0
  178. package/dist/node/cli/identity-info.d.ts +4 -0
  179. package/dist/node/cli/identity-info.d.ts.map +1 -0
  180. package/dist/node/cli/identity-info.js +57 -0
  181. package/dist/node/cli/identity-info.js.map +1 -0
  182. package/dist/node/index.d.ts +2 -0
  183. package/dist/node/index.d.ts.map +1 -1
  184. package/dist/node/index.js +8 -1
  185. package/dist/node/index.js.map +1 -1
  186. package/dist/node/server/CapabilityMatcher.d.ts +45 -0
  187. package/dist/node/server/CapabilityMatcher.d.ts.map +1 -0
  188. package/dist/node/server/CapabilityMatcher.js +117 -0
  189. package/dist/node/server/CapabilityMatcher.js.map +1 -0
  190. package/dist/node/server/MindooDBServer.d.ts +87 -0
  191. package/dist/node/server/MindooDBServer.d.ts.map +1 -0
  192. package/dist/node/server/MindooDBServer.js +1040 -0
  193. package/dist/node/server/MindooDBServer.js.map +1 -0
  194. package/dist/node/server/ServerSync.d.ts +41 -0
  195. package/dist/node/server/ServerSync.d.ts.map +1 -0
  196. package/dist/node/server/ServerSync.js +187 -0
  197. package/dist/node/server/ServerSync.js.map +1 -0
  198. package/dist/node/server/StoreFactory.d.ts +45 -0
  199. package/dist/node/server/StoreFactory.d.ts.map +1 -0
  200. package/dist/node/server/StoreFactory.js +89 -0
  201. package/dist/node/server/StoreFactory.js.map +1 -0
  202. package/dist/node/server/SystemAdminAuth.d.ts +65 -0
  203. package/dist/node/server/SystemAdminAuth.d.ts.map +1 -0
  204. package/dist/node/server/SystemAdminAuth.js +200 -0
  205. package/dist/node/server/SystemAdminAuth.js.map +1 -0
  206. package/dist/node/server/SystemIpAllowlist.d.ts +21 -0
  207. package/dist/node/server/SystemIpAllowlist.d.ts.map +1 -0
  208. package/dist/node/server/SystemIpAllowlist.js +210 -0
  209. package/dist/node/server/SystemIpAllowlist.js.map +1 -0
  210. package/dist/node/server/TenantManager.d.ts +85 -0
  211. package/dist/node/server/TenantManager.d.ts.map +1 -0
  212. package/dist/node/server/TenantManager.js +493 -0
  213. package/dist/node/server/TenantManager.js.map +1 -0
  214. package/dist/node/server/add-to-network.d.ts +20 -0
  215. package/dist/node/server/add-to-network.d.ts.map +1 -0
  216. package/dist/node/server/add-to-network.js +275 -0
  217. package/dist/node/server/add-to-network.js.map +1 -0
  218. package/dist/node/server/config.d.ts +51 -0
  219. package/dist/node/server/config.d.ts.map +1 -0
  220. package/dist/node/server/config.js +218 -0
  221. package/dist/node/server/config.js.map +1 -0
  222. package/dist/node/server/resolveServerPassword.d.ts +7 -0
  223. package/dist/node/server/resolveServerPassword.d.ts.map +1 -0
  224. package/dist/node/server/resolveServerPassword.js +25 -0
  225. package/dist/node/server/resolveServerPassword.js.map +1 -0
  226. package/dist/node/server/server.d.ts +22 -0
  227. package/dist/node/server/server.d.ts.map +1 -0
  228. package/dist/node/server/server.js +225 -0
  229. package/dist/node/server/server.js.map +1 -0
  230. package/dist/node/server/serverinit.d.ts +21 -0
  231. package/dist/node/server/serverinit.d.ts.map +1 -0
  232. package/dist/node/server/serverinit.js +317 -0
  233. package/dist/node/server/serverinit.js.map +1 -0
  234. package/dist/node/server/types.d.ts +162 -0
  235. package/dist/node/server/types.d.ts.map +1 -0
  236. package/dist/node/server/types.js +24 -0
  237. package/dist/node/server/types.js.map +1 -0
  238. package/dist/node/server/validation.d.ts +47 -0
  239. package/dist/node/server/validation.d.ts.map +1 -0
  240. package/dist/node/server/validation.js +114 -0
  241. package/dist/node/server/validation.js.map +1 -0
  242. package/dist/reactnative/cache/MMKVLocalCacheStore.d.ts +48 -0
  243. package/dist/reactnative/cache/MMKVLocalCacheStore.d.ts.map +1 -0
  244. package/dist/reactnative/cache/MMKVLocalCacheStore.js +113 -0
  245. package/dist/reactnative/cache/MMKVLocalCacheStore.js.map +1 -0
  246. package/dist/reactnative/crypto/AESAdapter.d.ts +18 -0
  247. package/dist/reactnative/crypto/AESAdapter.d.ts.map +1 -0
  248. package/dist/reactnative/crypto/AESAdapter.js +112 -0
  249. package/dist/reactnative/crypto/AESAdapter.js.map +1 -0
  250. package/dist/reactnative/crypto/Ed25519Adapter.d.ts +34 -0
  251. package/dist/reactnative/crypto/Ed25519Adapter.d.ts.map +1 -0
  252. package/dist/reactnative/crypto/Ed25519Adapter.js +386 -0
  253. package/dist/reactnative/crypto/Ed25519Adapter.js.map +1 -0
  254. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts +23 -0
  255. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts.map +1 -0
  256. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js +51 -0
  257. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js.map +1 -0
  258. package/dist/reactnative/crypto/HMACAdapter.d.ts +13 -0
  259. package/dist/reactnative/crypto/HMACAdapter.d.ts.map +1 -0
  260. package/dist/reactnative/crypto/HMACAdapter.js +50 -0
  261. package/dist/reactnative/crypto/HMACAdapter.js.map +1 -0
  262. package/dist/reactnative/crypto/KeyFormatConverter.d.ts +21 -0
  263. package/dist/reactnative/crypto/KeyFormatConverter.d.ts.map +1 -0
  264. package/dist/reactnative/crypto/KeyFormatConverter.js +72 -0
  265. package/dist/reactnative/crypto/KeyFormatConverter.js.map +1 -0
  266. package/dist/reactnative/crypto/PBKDF2Adapter.d.ts +19 -0
  267. package/dist/reactnative/crypto/PBKDF2Adapter.d.ts.map +1 -0
  268. package/dist/reactnative/crypto/PBKDF2Adapter.js +67 -0
  269. package/dist/reactnative/crypto/PBKDF2Adapter.js.map +1 -0
  270. package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts +37 -0
  271. package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts.map +1 -0
  272. package/dist/reactnative/crypto/QuickCryptoAdapter.js +72 -0
  273. package/dist/reactnative/crypto/QuickCryptoAdapter.js.map +1 -0
  274. package/dist/reactnative/crypto/RSAAdapter.d.ts +38 -0
  275. package/dist/reactnative/crypto/RSAAdapter.d.ts.map +1 -0
  276. package/dist/reactnative/crypto/RSAAdapter.js +184 -0
  277. package/dist/reactnative/crypto/RSAAdapter.js.map +1 -0
  278. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts +33 -0
  279. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts.map +1 -0
  280. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js +61 -0
  281. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js.map +1 -0
  282. package/dist/reactnative/crypto/SHA256Adapter.d.ts +9 -0
  283. package/dist/reactnative/crypto/SHA256Adapter.d.ts.map +1 -0
  284. package/dist/reactnative/crypto/SHA256Adapter.js +29 -0
  285. package/dist/reactnative/crypto/SHA256Adapter.js.map +1 -0
  286. package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts +63 -0
  287. package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts.map +1 -0
  288. package/dist/reactnative/crypto/SubtleCryptoPolyfill.js +350 -0
  289. package/dist/reactnative/crypto/SubtleCryptoPolyfill.js.map +1 -0
  290. package/dist/reactnative/index.d.ts +9 -0
  291. package/dist/reactnative/index.d.ts.map +1 -0
  292. package/dist/reactnative/index.js +41 -0
  293. package/dist/reactnative/index.js.map +1 -0
  294. package/package.json +63 -7
  295. package/patches/PATCHES.md +111 -0
  296. package/patches/react-native+0.76.9.patch +34 -0
  297. package/patches/react-native-quick-crypto+1.0.7.patch +42 -0
  298. package/scripts/cli.js +21 -0
  299. package/scripts/setup-react-native.js +228 -0
  300. package/templates/reactnative/App.js +252 -0
  301. package/templates/reactnative/app.json +29 -0
  302. package/templates/reactnative/babel.config.js +6 -0
  303. package/templates/reactnative/index.js +26 -0
  304. package/templates/reactnative/metro.config.snippet.js +39 -0
  305. package/templates/reactnative/mindoodb-polyfills.js +116 -0
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseMindooTenant = void 0;
4
+ const types_1 = require("./types");
4
5
  const BaseMindooDB_1 = require("./BaseMindooDB");
5
6
  const BaseMindooTenantDirectory_1 = require("./BaseMindooTenantDirectory");
6
7
  const MindooDocSigner_1 = require("./crypto/MindooDocSigner");
8
+ const privateKeyEncryption_1 = require("./crypto/privateKeyEncryption");
7
9
  const errors_1 = require("./errors");
8
10
  const logging_1 = require("./logging");
11
+ const MindooURI_1 = require("./uri/MindooURI");
12
+ const EncryptedLocalCacheStore_1 = require("./cache/EncryptedLocalCacheStore");
13
+ const CacheManager_1 = require("./cache/CacheManager");
9
14
  /**
10
15
  * BaseMindooTenant is a platform-agnostic implementation of MindooTenant
11
16
  * that works in both browser and server environments.
@@ -21,19 +26,20 @@ const logging_1 = require("./logging");
21
26
  * - PBKDF2 key derivation (for password-based key derivation)
22
27
  */
23
28
  class BaseMindooTenant {
24
- constructor(factory, tenantId, tenantEncryptionKey, tenantEncryptionKeyPassword, administrationPublicKey, administrationEncryptionPublicKey, currentUser, currentUserPassword, keyBag, storeFactory, cryptoAdapter, logger) {
29
+ constructor(factory, tenantId, administrationPublicKey, administrationEncryptionPublicKey, currentUser, currentUserPassword, keyBag, storeFactory, cryptoAdapter, logger, additionalTrustedKeys, localCacheStore) {
25
30
  this.databaseCache = new Map();
26
31
  this.directoryCache = null;
32
+ // Local cache support
33
+ this.cacheManager = null;
27
34
  this.factory = factory;
28
35
  this.tenantId = tenantId;
29
- this.tenantEncryptionKey = tenantEncryptionKey;
30
- this.tenantEncryptionKeyPassword = tenantEncryptionKeyPassword;
31
36
  this.administrationPublicKey = administrationPublicKey;
32
37
  this.administrationEncryptionPublicKey = administrationEncryptionPublicKey;
33
38
  this.currentUser = currentUser;
34
39
  this.currentUserPassword = currentUserPassword;
35
40
  this.keyBag = keyBag;
36
41
  this.storeFactory = storeFactory;
42
+ this.additionalTrustedKeys = additionalTrustedKeys;
37
43
  // Import createCryptoAdapter dynamically to avoid issues in browser environments
38
44
  if (!cryptoAdapter) {
39
45
  const { createCryptoAdapter } = require("./crypto/CryptoAdapter");
@@ -46,6 +52,11 @@ class BaseMindooTenant {
46
52
  this.logger =
47
53
  logger ||
48
54
  new logging_1.MindooLogger((0, logging_1.getDefaultLogLevel)(), `Tenant:${tenantId}`, true);
55
+ // Set up cache if a local cache store is provided
56
+ if (localCacheStore) {
57
+ const encryptedStore = new EncryptedLocalCacheStore_1.EncryptedLocalCacheStore(localCacheStore, currentUserPassword, this.cryptoAdapter, this.logger.createChild("EncryptedCache"));
58
+ this.cacheManager = new CacheManager_1.CacheManager(encryptedStore, undefined, this.logger.createChild("CacheManager"));
59
+ }
49
60
  }
50
61
  /**
51
62
  * Initialize the tenant.
@@ -56,6 +67,22 @@ class BaseMindooTenant {
56
67
  const keyCount = (await this.keyBag.listKeys()).length;
57
68
  this.logger.info(`Tenant initialized with ${keyCount} keys in KeyBag`);
58
69
  }
70
+ /**
71
+ * Get the CacheManager for this tenant (null if caching is disabled).
72
+ */
73
+ getCacheManager() {
74
+ return this.cacheManager;
75
+ }
76
+ /**
77
+ * Flush and dispose the cache manager.
78
+ * Should be called when the tenant is being closed.
79
+ */
80
+ async disposeCacheManager() {
81
+ if (this.cacheManager) {
82
+ await this.cacheManager.dispose();
83
+ this.cacheManager = null;
84
+ }
85
+ }
59
86
  getCryptoAdapter() {
60
87
  return this.cryptoAdapter;
61
88
  }
@@ -84,9 +111,6 @@ class BaseMindooTenant {
84
111
  getAdministrationEncryptionPublicKey() {
85
112
  return this.administrationEncryptionPublicKey;
86
113
  }
87
- getTenantEncryptionKey() {
88
- return this.tenantEncryptionKey;
89
- }
90
114
  async encryptPayload(payload, decryptionKeyId) {
91
115
  this.logger.debug(`Encrypting payload with key: ${decryptionKeyId}`);
92
116
  this.logger.debug(`Payload size: ${payload.length} bytes`);
@@ -101,18 +125,20 @@ class BaseMindooTenant {
101
125
  this.logger.debug(`Using cached tenant key, length: ${symmetricKey.length} bytes`);
102
126
  }
103
127
  else {
104
- this.logger.debug(`Decrypting tenant encryption key`);
105
- // Decrypt tenant encryption key
106
- const decrypted = await this.decryptPrivateKey(this.tenantEncryptionKey, this.tenantEncryptionKeyPassword, "default");
107
- symmetricKey = new Uint8Array(decrypted);
128
+ this.logger.debug(`Resolving tenant encryption key from KeyBag`);
129
+ const tenantKey = await this.keyBag.get("doc", this.tenantId, types_1.DEFAULT_TENANT_KEY_ID);
130
+ if (!tenantKey) {
131
+ throw new errors_1.SymmetricKeyNotFoundError(`doc:${this.tenantId}:${types_1.DEFAULT_TENANT_KEY_ID}`);
132
+ }
133
+ symmetricKey = tenantKey;
108
134
  this.decryptedTenantKeyCache = symmetricKey;
109
- this.logger.debug(`Decrypted tenant key, length: ${symmetricKey.length} bytes`);
135
+ this.logger.debug(`Loaded tenant key from KeyBag, length: ${symmetricKey.length} bytes`);
110
136
  }
111
137
  }
112
138
  else {
113
139
  this.logger.debug(`Getting named key from KeyBag: ${decryptionKeyId}`);
114
140
  // Get the decrypted key from KeyBag
115
- const decryptedKey = await this.keyBag.get(decryptionKeyId);
141
+ const decryptedKey = await this.keyBag.get("doc", this.tenantId, decryptionKeyId);
116
142
  if (!decryptedKey) {
117
143
  throw new errors_1.SymmetricKeyNotFoundError(decryptionKeyId);
118
144
  }
@@ -210,15 +236,17 @@ class BaseMindooTenant {
210
236
  symmetricKey = this.decryptedTenantKeyCache;
211
237
  }
212
238
  else {
213
- // Decrypt tenant encryption key
214
- const decrypted = await this.decryptPrivateKey(this.tenantEncryptionKey, this.tenantEncryptionKeyPassword, "default");
215
- symmetricKey = new Uint8Array(decrypted);
239
+ const tenantKey = await this.keyBag.get("doc", this.tenantId, types_1.DEFAULT_TENANT_KEY_ID);
240
+ if (!tenantKey) {
241
+ throw new errors_1.SymmetricKeyNotFoundError(`doc:${this.tenantId}:${types_1.DEFAULT_TENANT_KEY_ID}`);
242
+ }
243
+ symmetricKey = tenantKey;
216
244
  this.decryptedTenantKeyCache = symmetricKey;
217
245
  }
218
246
  }
219
247
  else {
220
248
  // Get the decrypted key from KeyBag
221
- const decryptedKey = await this.keyBag.get(decryptionKeyId);
249
+ const decryptedKey = await this.keyBag.get("doc", this.tenantId, decryptionKeyId);
222
250
  if (!decryptedKey) {
223
251
  throw new errors_1.SymmetricKeyNotFoundError(decryptionKeyId);
224
252
  }
@@ -306,11 +334,17 @@ class BaseMindooTenant {
306
334
  // Convert PrivateUserId to PublicUserId
307
335
  return {
308
336
  username: this.currentUser.username,
309
- administrationSignature: this.currentUser.administrationSignature,
310
337
  userSigningPublicKey: this.currentUser.userSigningKeyPair.publicKey,
311
338
  userEncryptionPublicKey: this.currentUser.userEncryptionKeyPair.publicKey,
312
339
  };
313
340
  }
341
+ /**
342
+ * Get the additional trusted signing keys map, if configured.
343
+ * Used by BaseMindooTenantDirectory to check keys before the directory DB.
344
+ */
345
+ getAdditionalTrustedKeys() {
346
+ return this.additionalTrustedKeys;
347
+ }
314
348
  async openDirectory() {
315
349
  if (!this.directoryCache) {
316
350
  const directoryLogger = this.logger.createChild("Directory");
@@ -318,12 +352,31 @@ class BaseMindooTenant {
318
352
  }
319
353
  return this.directoryCache;
320
354
  }
355
+ async assertCurrentUserCanOpenDB(id) {
356
+ if (id === "directory") {
357
+ return;
358
+ }
359
+ const currentUser = await this.getCurrentUserId();
360
+ if (currentUser.userSigningPublicKey === this.getAdministrationPublicKey()) {
361
+ return;
362
+ }
363
+ const directory = await this.openDirectory();
364
+ const registeredUser = await directory.getUserPublicKeys(currentUser.username);
365
+ const hasMatchingGrant = registeredUser?.signingPublicKey === currentUser.userSigningPublicKey &&
366
+ registeredUser?.encryptionPublicKey === currentUser.userEncryptionPublicKey;
367
+ if (hasMatchingGrant) {
368
+ return;
369
+ }
370
+ this.logger.warn(`Denied database open for ungranted user ${currentUser.username} on database ${id}`);
371
+ throw new Error(`User "${currentUser.username}" does not have tenant access yet; the tenant admin must grant access first.`);
372
+ }
321
373
  async openDB(id, options) {
322
374
  // Enforce admin-only mode for directory database - this is a security invariant
323
375
  // The directory database must only accept entries signed by the admin key
324
376
  const effectiveOptions = id === "directory"
325
377
  ? { ...options, adminOnlyDb: true }
326
378
  : options ?? {};
379
+ await this.assertCurrentUserCanOpenDB(id);
327
380
  // Return cached database if it exists
328
381
  const cached = this.databaseCache.get(id);
329
382
  if (cached) {
@@ -334,11 +387,14 @@ class BaseMindooTenant {
334
387
  return cached;
335
388
  }
336
389
  // Extract store options and DB-specific options
337
- const { adminOnlyDb, attachmentConfig, ...storeOptions } = effectiveOptions;
390
+ const { adminOnlyDb, attachmentConfig, documentCacheConfig, snapshotConfig, performanceCallback, ...storeOptions } = effectiveOptions;
338
391
  // Create the database stores using the factory
339
392
  const { docStore, attachmentStore } = this.storeFactory.createStore(id, storeOptions);
340
393
  const dbLogger = this.logger.createChild("BaseMindooDB");
341
- const db = new BaseMindooDB_1.BaseMindooDB(this, docStore, attachmentStore, attachmentConfig, adminOnlyDb ?? false, dbLogger);
394
+ const db = new BaseMindooDB_1.BaseMindooDB(this, docStore, attachmentStore, attachmentConfig, documentCacheConfig, snapshotConfig, adminOnlyDb ?? false, dbLogger, performanceCallback);
395
+ if (this.cacheManager) {
396
+ db.setCacheManager(this.cacheManager);
397
+ }
342
398
  await db.initialize();
343
399
  // Cache the database for future use
344
400
  this.databaseCache.set(id, db);
@@ -349,8 +405,189 @@ class BaseMindooTenant {
349
405
  const signerLogger = this.logger.createChild("MindooDocSigner");
350
406
  return new MindooDocSigner_1.MindooDocSigner(this, signKey, signerLogger);
351
407
  }
408
+ async approveJoinRequest(joinRequest, options) {
409
+ // Parse the join request if it's a URI string
410
+ let request;
411
+ if (typeof joinRequest === "string") {
412
+ if (!(0, MindooURI_1.isMindooURI)(joinRequest)) {
413
+ throw new Error("Invalid join request: expected a JoinRequest object or a mdb://join-request/... URI string");
414
+ }
415
+ const decoded = (0, MindooURI_1.decodeMindooURI)(joinRequest);
416
+ if (decoded.type !== "join-request") {
417
+ throw new Error(`Invalid URI type: expected "join-request", got "${decoded.type}"`);
418
+ }
419
+ request = decoded.payload;
420
+ }
421
+ else {
422
+ request = joinRequest;
423
+ }
424
+ console.log(`[approveJoinRequest] Approving join request for user "${request.username}"`);
425
+ this.logger.info(`Approving join request for user: ${request.username}`);
426
+ // 1. Register the user in the directory
427
+ const directory = await this.openDirectory();
428
+ const publicUserId = {
429
+ username: request.username,
430
+ userSigningPublicKey: request.signingPublicKey,
431
+ userEncryptionPublicKey: request.encryptionPublicKey,
432
+ };
433
+ await directory.registerUser(publicUserId, options.adminSigningKey, options.adminPassword);
434
+ // 2. Export the tenant key encrypted with the share password
435
+ const encryptedTenantKey = await this.keyBag.encryptAndExportKey("doc", this.tenantId, types_1.DEFAULT_TENANT_KEY_ID, options.sharePassword);
436
+ if (!encryptedTenantKey) {
437
+ throw new Error(`Failed to export tenant key for tenant "${this.tenantId}"`);
438
+ }
439
+ // 3. Export the $publicinfos key encrypted with the share password
440
+ const encryptedPublicInfosKey = await this.keyBag.encryptAndExportKey("doc", this.tenantId, types_1.PUBLIC_INFOS_KEY_ID, options.sharePassword);
441
+ if (!encryptedPublicInfosKey) {
442
+ throw new Error(`Failed to export $publicinfos key`);
443
+ }
444
+ // 4. Build the join response
445
+ const joinResponse = {
446
+ v: 1,
447
+ tenantId: this.tenantId,
448
+ adminSigningPublicKey: this.administrationPublicKey,
449
+ adminEncryptionPublicKey: this.administrationEncryptionPublicKey,
450
+ encryptedTenantKey,
451
+ encryptedPublicInfosKey,
452
+ };
453
+ if (options.serverUrl) {
454
+ joinResponse.serverUrl = options.serverUrl;
455
+ }
456
+ console.log(`[approveJoinRequest] ✓ Join request approved for user "${request.username}"`);
457
+ this.logger.info(`Join request approved for user: ${request.username}`);
458
+ // Return as URI string or object depending on format option
459
+ if (options.format === "uri") {
460
+ return (0, MindooURI_1.encodeMindooURI)("join-response", joinResponse);
461
+ }
462
+ return joinResponse;
463
+ }
464
+ /**
465
+ * Publish (register) this tenant on a MindooDB server.
466
+ *
467
+ * When `systemAdminUser` + `systemAdminPassword` are provided the method
468
+ * performs a challenge/response handshake against `/system/auth/*` to
469
+ * obtain a JWT, then calls `POST /system/tenants/:tenantId`.
470
+ */
471
+ async publishToServer(serverUrl, options) {
472
+ console.log(`[publishToServer] Publishing tenant "${this.tenantId}" to server: ${serverUrl}`);
473
+ this.logger.info(`Publishing tenant "${this.tenantId}" to server: ${serverUrl}`);
474
+ const baseUrl = serverUrl.replace(/\/$/, "");
475
+ // Export the $publicinfos key so the server can read the directory DB
476
+ const publicInfosKeyBytes = await this.keyBag.get("doc", this.tenantId, types_1.PUBLIC_INFOS_KEY_ID);
477
+ if (!publicInfosKeyBytes) {
478
+ throw new Error(`Cannot publish to server: $publicinfos key not found in KeyBag`);
479
+ }
480
+ const publicInfosKeyBase64 = this.uint8ArrayToBase64(publicInfosKeyBytes);
481
+ // Build the registration request body
482
+ const requestBody = {
483
+ adminSigningPublicKey: this.administrationPublicKey,
484
+ adminEncryptionPublicKey: this.administrationEncryptionPublicKey,
485
+ publicInfosKey: publicInfosKeyBase64,
486
+ };
487
+ if (options?.adminUsername) {
488
+ requestBody.adminUsername = options.adminUsername;
489
+ }
490
+ // Add users if provided
491
+ if (options?.registerUsers && options.registerUsers.length > 0) {
492
+ requestBody.users = options.registerUsers.map((u) => ({
493
+ username: u.username,
494
+ signingPublicKey: u.userSigningPublicKey,
495
+ encryptionPublicKey: u.userEncryptionPublicKey,
496
+ }));
497
+ }
498
+ // Authenticate as system admin via challenge/response
499
+ const headers = {
500
+ "Content-Type": "application/json",
501
+ };
502
+ if (options?.systemAdminUser && options?.systemAdminPassword) {
503
+ const token = await this.authenticateAsSystemAdmin(baseUrl, options.systemAdminUser, options.systemAdminPassword);
504
+ headers["Authorization"] = `Bearer ${token}`;
505
+ }
506
+ // POST to /system/tenants/:tenantId
507
+ const url = `${baseUrl}/system/tenants/${encodeURIComponent(this.tenantId)}`;
508
+ const response = await fetch(url, {
509
+ method: "POST",
510
+ headers,
511
+ body: JSON.stringify(requestBody),
512
+ });
513
+ if (!response.ok) {
514
+ const errorBody = await response.text();
515
+ throw new Error(`Failed to publish tenant to server (HTTP ${response.status}): ${errorBody}`);
516
+ }
517
+ console.log(`[publishToServer] ✓ Tenant "${this.tenantId}" published to server successfully`);
518
+ this.logger.info(`Tenant "${this.tenantId}" published to server successfully`);
519
+ }
520
+ /**
521
+ * Perform system admin challenge/response auth and return a JWT token.
522
+ */
523
+ async authenticateAsSystemAdmin(baseUrl, adminUser, adminPassword) {
524
+ const subtle = this.cryptoAdapter.getSubtle();
525
+ // Decrypt the admin's signing private key
526
+ const signingKeyBuffer = await this.decryptPrivateKey(adminUser.userSigningKeyPair.privateKey, adminPassword, "signing");
527
+ const signingKey = await subtle.importKey("pkcs8", signingKeyBuffer, { name: "Ed25519" }, false, ["sign"]);
528
+ // Step 1: Request challenge from server
529
+ const challengeRes = await fetch(`${baseUrl}/system/auth/challenge`, {
530
+ method: "POST",
531
+ headers: { "Content-Type": "application/json" },
532
+ body: JSON.stringify({
533
+ username: adminUser.username,
534
+ publicsignkey: adminUser.userSigningKeyPair.publicKey,
535
+ }),
536
+ });
537
+ if (!challengeRes.ok) {
538
+ const errorBody = await challengeRes.text();
539
+ throw new Error(`System admin challenge failed (HTTP ${challengeRes.status}): ${errorBody}`);
540
+ }
541
+ const { challenge } = (await challengeRes.json());
542
+ // Step 2: Sign the challenge
543
+ const messageBytes = new TextEncoder().encode(challenge);
544
+ const signatureBuffer = await subtle.sign({ name: "Ed25519" }, signingKey, messageBytes);
545
+ const signatureBase64 = this.uint8ArrayToBase64(new Uint8Array(signatureBuffer));
546
+ // Step 3: Authenticate
547
+ const authRes = await fetch(`${baseUrl}/system/auth/authenticate`, {
548
+ method: "POST",
549
+ headers: { "Content-Type": "application/json" },
550
+ body: JSON.stringify({ challenge, signature: signatureBase64 }),
551
+ });
552
+ if (!authRes.ok) {
553
+ const errorBody = await authRes.text();
554
+ throw new Error(`System admin authentication failed (HTTP ${authRes.status}): ${errorBody}`);
555
+ }
556
+ const result = (await authRes.json());
557
+ if (!result.success || !result.token) {
558
+ throw new Error(`System admin authentication failed: ${result.error || "unknown error"}`);
559
+ }
560
+ return result.token;
561
+ }
562
+ /**
563
+ * Create a remote store connected to a MindooDB server, ready for sync.
564
+ */
565
+ async connectToServer(serverUrl, dbId) {
566
+ console.log(`[connectToServer] Connecting to server: ${serverUrl}, db: ${dbId}`);
567
+ this.logger.info(`Connecting to server: ${serverUrl}, db: ${dbId}`);
568
+ // Lazy-import network modules to avoid circular dependencies and keep core lightweight
569
+ const { HttpTransport } = await import("../appendonlystores/network/HttpTransport.js");
570
+ const { ClientNetworkContentAddressedStore } = await import("../appendonlystores/network/ClientNetworkContentAddressedStore.js");
571
+ // Create the HTTP transport
572
+ const baseUrl = `${serverUrl.replace(/\/$/, "")}/${this.tenantId}`;
573
+ const transport = new HttpTransport({
574
+ baseUrl,
575
+ tenantId: this.tenantId,
576
+ dbId,
577
+ }, this.logger.createChild("HttpTransport"));
578
+ // Get the current user's decrypted signing key
579
+ const signingKey = await this.getDecryptedSigningKey();
580
+ // Get the current user's decrypted RSA encryption private key (for decrypting entries)
581
+ const decryptedEncryptionKey = await this.getDecryptedEncryptionKey();
582
+ // Create the client network store
583
+ const store = new ClientNetworkContentAddressedStore(dbId, transport, this.cryptoAdapter, this.currentUser.username, signingKey, decryptedEncryptionKey, this.logger.createChild(`ClientNetworkStore:${dbId}`));
584
+ console.log(`[connectToServer] ✓ Connected to server for db "${dbId}"`);
585
+ this.logger.info(`Connected to server for db "${dbId}"`);
586
+ return store;
587
+ }
352
588
  /**
353
589
  * Internal method to get the decrypted signing key for the current user.
590
+ * Protected so that connectToServer() helper and subclasses can access it.
354
591
  */
355
592
  async getDecryptedSigningKey() {
356
593
  // Use cached signing key if available
@@ -368,6 +605,23 @@ class BaseMindooTenant {
368
605
  this.decryptedUserSigningKeyCache = cryptoKey;
369
606
  return cryptoKey;
370
607
  }
608
+ /**
609
+ * Internal method to get the decrypted RSA encryption private key for the current user.
610
+ * Used by connectToServer() to create the network store.
611
+ */
612
+ async getDecryptedEncryptionKey() {
613
+ if (this.decryptedUserEncryptionKeyCache) {
614
+ return this.decryptedUserEncryptionKeyCache;
615
+ }
616
+ const decryptedKeyBuffer = await this.decryptPrivateKey(this.currentUser.userEncryptionKeyPair.privateKey, this.currentUserPassword, "encryption");
617
+ const subtle = this.cryptoAdapter.getSubtle();
618
+ const cryptoKey = await subtle.importKey("pkcs8", decryptedKeyBuffer, {
619
+ name: "RSA-OAEP",
620
+ hash: "SHA-256",
621
+ }, false, ["decrypt"]);
622
+ this.decryptedUserEncryptionKeyCache = cryptoKey;
623
+ return cryptoKey;
624
+ }
371
625
  /**
372
626
  * Internal method to decrypt a private key using password-based key derivation.
373
627
  * Protected so that BaseMindooTenantDirectory can access it.
@@ -382,104 +636,22 @@ class BaseMindooTenant {
382
636
  this.logger.debug(`decryptPrivateKey: Starting decryption with saltString: ${saltString}`);
383
637
  this.logger.debug(`decryptPrivateKey: Password length: ${password.length}`);
384
638
  this.logger.debug(`decryptPrivateKey: EncryptedKey iterations: ${encryptedKey.iterations}`);
385
- const subtle = this.cryptoAdapter.getSubtle();
386
- // Decode base64 strings
387
- this.logger.debug(`decryptPrivateKey: Decoding base64 strings`);
388
- let ciphertext;
389
- let iv;
390
- let tag;
391
- let saltBytes;
639
+ this.logger.debug(`decryptPrivateKey: Delegating PBKDF2 + AES-GCM work to shared helper`);
392
640
  try {
393
- ciphertext = this.base64ToUint8Array(encryptedKey.ciphertext);
394
- iv = this.base64ToUint8Array(encryptedKey.iv);
395
- tag = this.base64ToUint8Array(encryptedKey.tag);
396
- saltBytes = this.base64ToUint8Array(encryptedKey.salt);
397
- this.logger.debug(`decryptPrivateKey: Decoded - ciphertext: ${ciphertext.length} bytes, iv: ${iv.length} bytes, tag: ${tag.length} bytes, salt: ${saltBytes.length} bytes`);
398
- }
399
- catch (error) {
400
- this.logger.error(`decryptPrivateKey: Error decoding base64:`, error);
401
- throw error;
402
- }
403
- // Derive key from password using PBKDF2
404
- // Combine the stored salt bytes with the salt string for additional security
405
- // This ensures different key types (signing, encryption, etc.) use different derived keys
406
- // even if they share the same password
407
- this.logger.debug(`decryptPrivateKey: Combining salt with saltString`);
408
- const saltStringBytes = new TextEncoder().encode(saltString);
409
- const combinedSalt = new Uint8Array(saltBytes.length + saltStringBytes.length);
410
- combinedSalt.set(saltBytes);
411
- combinedSalt.set(saltStringBytes, saltBytes.length);
412
- this.logger.debug(`decryptPrivateKey: Combined salt length: ${combinedSalt.length} bytes`);
413
- this.logger.debug(`decryptPrivateKey: Importing password key for PBKDF2`);
414
- let passwordKey;
415
- try {
416
- passwordKey = await subtle.importKey("raw", new TextEncoder().encode(password), "PBKDF2", false, ["deriveBits", "deriveKey"]);
417
- this.logger.debug(`decryptPrivateKey: Successfully imported password key`);
418
- }
419
- catch (error) {
420
- this.logger.error(`decryptPrivateKey: Error importing password key:`, error);
421
- throw error;
422
- }
423
- this.logger.debug(`decryptPrivateKey: Deriving key with PBKDF2 (iterations: ${encryptedKey.iterations})`);
424
- let derivedKey;
425
- try {
426
- derivedKey = await subtle.deriveKey({
427
- name: "PBKDF2",
428
- salt: combinedSalt,
429
- iterations: encryptedKey.iterations,
430
- hash: "SHA-256",
431
- }, passwordKey, {
432
- name: "AES-GCM",
433
- length: 256,
434
- }, false, ["decrypt"]);
435
- this.logger.debug(`decryptPrivateKey: Successfully derived key`);
436
- }
437
- catch (error) {
438
- this.logger.error(`decryptPrivateKey: Error deriving key:`, error);
439
- throw error;
440
- }
441
- // Combine ciphertext and tag (GCM authentication tag is separate)
442
- // AES-GCM expects the tag to be appended to the ciphertext
443
- this.logger.debug(`decryptPrivateKey: Combining ciphertext and tag`);
444
- const encryptedData = new Uint8Array(ciphertext.length + tag.length);
445
- encryptedData.set(ciphertext);
446
- encryptedData.set(tag, ciphertext.length);
447
- this.logger.debug(`decryptPrivateKey: Combined encrypted data length: ${encryptedData.length} bytes`);
448
- // Decrypt the private key
449
- this.logger.debug(`decryptPrivateKey: Decrypting with AES-GCM`);
450
- this.logger.debug(`decryptPrivateKey: IV length: ${iv.length} bytes (expected: 12 for AES-GCM)`);
451
- this.logger.debug(`decryptPrivateKey: Tag length: ${tag.length} bytes (expected: 16 for 128-bit tag)`);
452
- this.logger.debug(`decryptPrivateKey: Ciphertext length: ${ciphertext.length} bytes`);
453
- let decrypted;
454
- try {
455
- // Create a new ArrayBuffer to ensure we have the correct buffer without any offset issues
456
- const encryptedBuffer = new Uint8Array(encryptedData).buffer;
457
- this.logger.debug(`decryptPrivateKey: Encrypted buffer size: ${encryptedBuffer.byteLength} bytes`);
458
- decrypted = await subtle.decrypt({
459
- name: "AES-GCM",
460
- iv: new Uint8Array(iv), // Create a new Uint8Array to ensure proper buffer
461
- tagLength: 128,
462
- }, derivedKey, encryptedBuffer);
641
+ const decrypted = await (0, privateKeyEncryption_1.decryptPrivateKey)(this.cryptoAdapter, encryptedKey, password, saltString);
463
642
  this.logger.debug(`decryptPrivateKey: Successfully decrypted, result length: ${decrypted.byteLength} bytes`);
643
+ return decrypted;
464
644
  }
465
645
  catch (error) {
466
646
  this.logger.error(`decryptPrivateKey: Error during decryption:`, error);
467
647
  this.logger.error(`decryptPrivateKey: Error details:`, {
468
648
  errorName: error instanceof Error ? error.name : typeof error,
469
649
  errorMessage: error instanceof Error ? error.message : String(error),
470
- ivLength: iv.length,
471
- tagLength: tag.length,
472
- ciphertextLength: ciphertext.length,
473
- encryptedDataLength: encryptedData.length,
474
650
  iterations: encryptedKey.iterations,
475
- saltString: saltString,
476
- encryptedDataByteOffset: encryptedData.byteOffset,
477
- encryptedDataByteLength: encryptedData.byteLength,
478
- encryptedDataBufferLength: encryptedData.buffer.byteLength,
651
+ saltString,
479
652
  });
480
653
  throw error;
481
654
  }
482
- return decrypted;
483
655
  }
484
656
  /**
485
657
  * Helper method to convert base64 string to Uint8Array
@@ -526,6 +698,25 @@ class BaseMindooTenant {
526
698
  }
527
699
  return bytes.buffer;
528
700
  }
701
+ /**
702
+ * Check whether the symmetric key for the given key ID is available in the KeyBag.
703
+ * This is a lightweight probe that does not perform any crypto operations.
704
+ *
705
+ * @param decryptionKeyId The key ID ("default" or a named key ID)
706
+ * @returns true if the key can be resolved, false otherwise
707
+ */
708
+ async hasDecryptionKey(decryptionKeyId) {
709
+ try {
710
+ await this.getSymmetricKey(decryptionKeyId);
711
+ return true;
712
+ }
713
+ catch (error) {
714
+ if (error instanceof errors_1.SymmetricKeyNotFoundError) {
715
+ return false;
716
+ }
717
+ throw error;
718
+ }
719
+ }
529
720
  /**
530
721
  * Get the symmetric key for a given key ID.
531
722
  * This is a protected helper method that can be used by subclasses.
@@ -539,15 +730,17 @@ class BaseMindooTenant {
539
730
  if (this.decryptedTenantKeyCache) {
540
731
  return this.decryptedTenantKeyCache;
541
732
  }
542
- // Decrypt tenant encryption key
543
- const decrypted = await this.decryptPrivateKey(this.tenantEncryptionKey, this.tenantEncryptionKeyPassword, "default");
544
- const symmetricKey = new Uint8Array(decrypted);
733
+ const tenantKey = await this.keyBag.get("doc", this.tenantId, types_1.DEFAULT_TENANT_KEY_ID);
734
+ if (!tenantKey) {
735
+ throw new errors_1.SymmetricKeyNotFoundError(`doc:${this.tenantId}:${types_1.DEFAULT_TENANT_KEY_ID}`);
736
+ }
737
+ const symmetricKey = tenantKey;
545
738
  this.decryptedTenantKeyCache = symmetricKey;
546
739
  return symmetricKey;
547
740
  }
548
741
  else {
549
742
  // Get the decrypted key from KeyBag
550
- const decryptedKey = await this.keyBag.get(decryptionKeyId);
743
+ const decryptedKey = await this.keyBag.get("doc", this.tenantId, decryptionKeyId);
551
744
  if (!decryptedKey) {
552
745
  throw new errors_1.SymmetricKeyNotFoundError(decryptionKeyId);
553
746
  }