mindoodb 0.0.84 → 0.0.86

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 (264) hide show
  1. package/README-server.md +1 -0
  2. package/README.md +6 -4
  3. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +15 -0
  4. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
  5. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +75 -1
  6. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
  7. package/dist/appendonlystores/network/HttpTransport.d.ts +9 -1
  8. package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
  9. package/dist/appendonlystores/network/HttpTransport.js +38 -10
  10. package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
  11. package/dist/cloudflare/DurableObjectSql.d.ts +56 -0
  12. package/dist/cloudflare/DurableObjectSql.d.ts.map +1 -0
  13. package/dist/cloudflare/DurableObjectSql.js +180 -0
  14. package/dist/cloudflare/DurableObjectSql.js.map +1 -0
  15. package/dist/cloudflare/MindooDatabaseObject.d.ts +86 -0
  16. package/dist/cloudflare/MindooDatabaseObject.d.ts.map +1 -0
  17. package/dist/cloudflare/MindooDatabaseObject.js +614 -0
  18. package/dist/cloudflare/MindooDatabaseObject.js.map +1 -0
  19. package/dist/cloudflare/MindooServerObject.d.ts +63 -0
  20. package/dist/cloudflare/MindooServerObject.d.ts.map +1 -0
  21. package/dist/cloudflare/MindooServerObject.js +521 -0
  22. package/dist/cloudflare/MindooServerObject.js.map +1 -0
  23. package/dist/cloudflare/WorkersCryptoAdapter.d.ts +7 -0
  24. package/dist/cloudflare/WorkersCryptoAdapter.d.ts.map +1 -0
  25. package/dist/cloudflare/WorkersCryptoAdapter.js +14 -0
  26. package/dist/cloudflare/WorkersCryptoAdapter.js.map +1 -0
  27. package/dist/cloudflare/host.d.ts +49 -0
  28. package/dist/cloudflare/host.d.ts.map +1 -0
  29. package/dist/cloudflare/host.js +104 -0
  30. package/dist/cloudflare/host.js.map +1 -0
  31. package/dist/cloudflare/http.d.ts +91 -0
  32. package/dist/cloudflare/http.d.ts.map +1 -0
  33. package/dist/cloudflare/http.js +266 -0
  34. package/dist/cloudflare/http.js.map +1 -0
  35. package/dist/cloudflare/index.d.ts +12 -0
  36. package/dist/cloudflare/index.d.ts.map +1 -0
  37. package/dist/cloudflare/index.js +20 -0
  38. package/dist/cloudflare/index.js.map +1 -0
  39. package/dist/cloudflare/storeRpc.d.ts +22 -0
  40. package/dist/cloudflare/storeRpc.d.ts.map +1 -0
  41. package/dist/cloudflare/storeRpc.js +85 -0
  42. package/dist/cloudflare/storeRpc.js.map +1 -0
  43. package/dist/cloudflare/types.d.ts +101 -0
  44. package/dist/cloudflare/types.d.ts.map +1 -0
  45. package/dist/cloudflare/types.js +10 -0
  46. package/dist/cloudflare/types.js.map +1 -0
  47. package/dist/cloudflare/worker.d.ts +25 -0
  48. package/dist/cloudflare/worker.d.ts.map +1 -0
  49. package/dist/cloudflare/worker.js +170 -0
  50. package/dist/cloudflare/worker.js.map +1 -0
  51. package/dist/core/BaseMindooDB.d.ts +43 -1
  52. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  53. package/dist/core/BaseMindooDB.js +209 -87
  54. package/dist/core/BaseMindooDB.js.map +1 -1
  55. package/dist/core/BaseMindooTenant.d.ts +14 -0
  56. package/dist/core/BaseMindooTenant.d.ts.map +1 -1
  57. package/dist/core/BaseMindooTenant.js +46 -0
  58. package/dist/core/BaseMindooTenant.js.map +1 -1
  59. package/dist/core/BaseMindooTenantDirectory.d.ts +10 -0
  60. package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
  61. package/dist/core/BaseMindooTenantDirectory.js +79 -8
  62. package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
  63. package/dist/core/ChangeDocDraft.d.ts +133 -0
  64. package/dist/core/ChangeDocDraft.d.ts.map +1 -0
  65. package/dist/core/ChangeDocDraft.js +492 -0
  66. package/dist/core/ChangeDocDraft.js.map +1 -0
  67. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
  68. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +1 -0
  69. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
  70. package/dist/core/appendonlystores/network/AuthenticationService.d.ts +8 -0
  71. package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -1
  72. package/dist/core/appendonlystores/network/AuthenticationService.js +19 -0
  73. package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -1
  74. package/dist/core/appendonlystores/network/IrohStreamIO.d.ts.map +1 -1
  75. package/dist/core/appendonlystores/network/IrohStreamIO.js +3 -23
  76. package/dist/core/appendonlystores/network/IrohStreamIO.js.map +1 -1
  77. package/dist/core/appendonlystores/network/NetworkTransport.d.ts +7 -1
  78. package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
  79. package/dist/core/appendonlystores/network/types.d.ts +23 -0
  80. package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
  81. package/dist/core/appendonlystores/network/types.js.map +1 -1
  82. package/dist/core/appendonlystores/rpc/storeRpcCodec.d.ts.map +1 -1
  83. package/dist/core/appendonlystores/rpc/storeRpcCodec.js +3 -23
  84. package/dist/core/appendonlystores/rpc/storeRpcCodec.js.map +1 -1
  85. package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.d.ts.map +1 -1
  86. package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.js +21 -30
  87. package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.js.map +1 -1
  88. package/dist/core/appendonlystores/sqlite/SqliteDriver.d.ts +37 -1
  89. package/dist/core/appendonlystores/sqlite/SqliteDriver.d.ts.map +1 -1
  90. package/dist/core/appendonlystores/sqlite/SqliteDriver.js +99 -40
  91. package/dist/core/appendonlystores/sqlite/SqliteDriver.js.map +1 -1
  92. package/dist/core/appendonlystores/syncStores.d.ts.map +1 -1
  93. package/dist/core/appendonlystores/syncStores.js +253 -168
  94. package/dist/core/appendonlystores/syncStores.js.map +1 -1
  95. package/dist/core/appendonlystores/types.d.ts +8 -0
  96. package/dist/core/appendonlystores/types.d.ts.map +1 -1
  97. package/dist/core/appendonlystores/types.js.map +1 -1
  98. package/dist/core/expressions/evaluateExpression.d.ts +8 -0
  99. package/dist/core/expressions/evaluateExpression.d.ts.map +1 -1
  100. package/dist/core/expressions/evaluateExpression.js +29 -4
  101. package/dist/core/expressions/evaluateExpression.js.map +1 -1
  102. package/dist/core/expressions/metadata.js +4 -4
  103. package/dist/core/expressions/metadata.js.map +1 -1
  104. package/dist/core/types.d.ts +61 -2
  105. package/dist/core/types.d.ts.map +1 -1
  106. package/dist/core/types.js.map +1 -1
  107. package/dist/core/uri/MindooURI.d.ts.map +1 -1
  108. package/dist/core/uri/MindooURI.js +3 -24
  109. package/dist/core/uri/MindooURI.js.map +1 -1
  110. package/dist/core/utils/base64.d.ts +17 -0
  111. package/dist/core/utils/base64.d.ts.map +1 -0
  112. package/dist/core/utils/base64.js +54 -0
  113. package/dist/core/utils/base64.js.map +1 -0
  114. package/dist/core/utils/idGeneration.d.ts.map +1 -1
  115. package/dist/core/utils/idGeneration.js +14 -3
  116. package/dist/core/utils/idGeneration.js.map +1 -1
  117. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -1
  118. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +1 -0
  119. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -1
  120. package/dist/node/server/FsServerDataStore.d.ts +23 -0
  121. package/dist/node/server/FsServerDataStore.d.ts.map +1 -0
  122. package/dist/node/server/FsServerDataStore.js +59 -0
  123. package/dist/node/server/FsServerDataStore.js.map +1 -0
  124. package/dist/node/server/IrohServerEndpoint.d.ts +1 -1
  125. package/dist/node/server/IrohServerEndpoint.d.ts.map +1 -1
  126. package/dist/node/server/IrohServerRpc.d.ts +5 -5
  127. package/dist/node/server/IrohServerRpc.d.ts.map +1 -1
  128. package/dist/node/server/IrohServerRpc.js +1 -1
  129. package/dist/node/server/IrohServerRpc.js.map +1 -1
  130. package/dist/node/server/MindooDBServer.d.ts +29 -150
  131. package/dist/node/server/MindooDBServer.d.ts.map +1 -1
  132. package/dist/node/server/MindooDBServer.js +160 -1568
  133. package/dist/node/server/MindooDBServer.js.map +1 -1
  134. package/dist/node/server/PurgedDocRegistry.d.ts +4 -27
  135. package/dist/node/server/PurgedDocRegistry.d.ts.map +1 -1
  136. package/dist/node/server/PurgedDocRegistry.js +6 -83
  137. package/dist/node/server/PurgedDocRegistry.js.map +1 -1
  138. package/dist/node/server/StoreFactory.d.ts +1 -1
  139. package/dist/node/server/StoreFactory.d.ts.map +1 -1
  140. package/dist/node/server/TenantManager.d.ts +16 -284
  141. package/dist/node/server/TenantManager.d.ts.map +1 -1
  142. package/dist/node/server/TenantManager.js +35 -1168
  143. package/dist/node/server/TenantManager.js.map +1 -1
  144. package/dist/node/server/add-to-network.js +1 -1
  145. package/dist/node/server/add-to-network.js.map +1 -1
  146. package/dist/node/server/compressionMiddleware.d.ts +14 -0
  147. package/dist/node/server/compressionMiddleware.d.ts.map +1 -1
  148. package/dist/node/server/compressionMiddleware.js +46 -3
  149. package/dist/node/server/compressionMiddleware.js.map +1 -1
  150. package/dist/node/server/config.d.ts +11 -15
  151. package/dist/node/server/config.d.ts.map +1 -1
  152. package/dist/node/server/config.js +30 -245
  153. package/dist/node/server/config.js.map +1 -1
  154. package/dist/node/server/expressAdapter.d.ts +23 -0
  155. package/dist/node/server/expressAdapter.d.ts.map +1 -0
  156. package/dist/node/server/expressAdapter.js +108 -0
  157. package/dist/node/server/expressAdapter.js.map +1 -0
  158. package/dist/node/server/nativeIrohStreamIO.d.ts +1 -1
  159. package/dist/node/server/nativeIrohStreamIO.d.ts.map +1 -1
  160. package/dist/node/server/peer/FileClusterAuditStorage.d.ts +16 -0
  161. package/dist/node/server/peer/FileClusterAuditStorage.d.ts.map +1 -0
  162. package/dist/node/server/peer/FileClusterAuditStorage.js +39 -0
  163. package/dist/node/server/peer/FileClusterAuditStorage.js.map +1 -0
  164. package/dist/node/server/peer/IrohPeerLink.d.ts +1 -1
  165. package/dist/node/server/peer/IrohPeerLink.d.ts.map +1 -1
  166. package/dist/node/server/peer/routes.d.ts +10 -44
  167. package/dist/node/server/peer/routes.d.ts.map +1 -1
  168. package/dist/node/server/peer/routes.js +33 -275
  169. package/dist/node/server/peer/routes.js.map +1 -1
  170. package/dist/node/server/resolveServerPassword.js +1 -1
  171. package/dist/node/server/resolveServerPassword.js.map +1 -1
  172. package/dist/node/server/server.js +1 -1
  173. package/dist/node/server/server.js.map +1 -1
  174. package/dist/node/server/serverinit.js +1 -1
  175. package/dist/node/server/serverinit.js.map +1 -1
  176. package/dist/server/CapabilityMatcher.d.ts +60 -0
  177. package/dist/server/CapabilityMatcher.d.ts.map +1 -0
  178. package/dist/server/CapabilityMatcher.js +138 -0
  179. package/dist/server/CapabilityMatcher.js.map +1 -0
  180. package/dist/server/DeviceDiscoveryService.d.ts +36 -0
  181. package/dist/server/DeviceDiscoveryService.d.ts.map +1 -0
  182. package/dist/server/DeviceDiscoveryService.js +165 -0
  183. package/dist/server/DeviceDiscoveryService.js.map +1 -0
  184. package/dist/server/PurgedDocRegistry.d.ts +35 -0
  185. package/dist/server/PurgedDocRegistry.d.ts.map +1 -0
  186. package/dist/server/PurgedDocRegistry.js +90 -0
  187. package/dist/server/PurgedDocRegistry.js.map +1 -0
  188. package/dist/server/ServerDataStore.d.ts +67 -0
  189. package/dist/server/ServerDataStore.d.ts.map +1 -0
  190. package/dist/server/ServerDataStore.js +88 -0
  191. package/dist/server/ServerDataStore.js.map +1 -0
  192. package/dist/server/SyncEventBus.d.ts +39 -0
  193. package/dist/server/SyncEventBus.d.ts.map +1 -0
  194. package/dist/server/SyncEventBus.js +41 -0
  195. package/dist/server/SyncEventBus.js.map +1 -0
  196. package/dist/server/SystemAdminAuth.d.ts +82 -0
  197. package/dist/server/SystemAdminAuth.d.ts.map +1 -0
  198. package/dist/server/SystemAdminAuth.js +228 -0
  199. package/dist/server/SystemAdminAuth.js.map +1 -0
  200. package/dist/server/TenantManager.d.ts +330 -0
  201. package/dist/server/TenantManager.d.ts.map +1 -0
  202. package/dist/server/TenantManager.js +1186 -0
  203. package/dist/server/TenantManager.js.map +1 -0
  204. package/dist/server/http/MindooDBServerCore.d.ts +313 -0
  205. package/dist/server/http/MindooDBServerCore.d.ts.map +1 -0
  206. package/dist/server/http/MindooDBServerCore.js +1403 -0
  207. package/dist/server/http/MindooDBServerCore.js.map +1 -0
  208. package/dist/server/http/types.d.ts +89 -0
  209. package/dist/server/http/types.d.ts.map +1 -0
  210. package/dist/server/http/types.js +29 -0
  211. package/dist/server/http/types.js.map +1 -0
  212. package/dist/server/index.d.ts +32 -0
  213. package/dist/server/index.d.ts.map +1 -0
  214. package/dist/server/index.js +76 -0
  215. package/dist/server/index.js.map +1 -0
  216. package/dist/server/peer/ClusterAuditLog.d.ts +71 -0
  217. package/dist/server/peer/ClusterAuditLog.d.ts.map +1 -0
  218. package/dist/server/peer/ClusterAuditLog.js +81 -0
  219. package/dist/server/peer/ClusterAuditLog.js.map +1 -0
  220. package/dist/server/peer/ClusterJobRunner.d.ts +43 -0
  221. package/dist/server/peer/ClusterJobRunner.d.ts.map +1 -0
  222. package/dist/server/peer/ClusterJobRunner.js +119 -0
  223. package/dist/server/peer/ClusterJobRunner.js.map +1 -0
  224. package/dist/server/peer/ClusterManager.d.ts +149 -0
  225. package/dist/server/peer/ClusterManager.d.ts.map +1 -0
  226. package/dist/server/peer/ClusterManager.js +292 -0
  227. package/dist/server/peer/ClusterManager.js.map +1 -0
  228. package/dist/server/peer/PeerAuthService.d.ts +69 -0
  229. package/dist/server/peer/PeerAuthService.d.ts.map +1 -0
  230. package/dist/server/peer/PeerAuthService.js +208 -0
  231. package/dist/server/peer/PeerAuthService.js.map +1 -0
  232. package/dist/server/peer/PeerReplicator.d.ts +303 -0
  233. package/dist/server/peer/PeerReplicator.d.ts.map +1 -0
  234. package/dist/server/peer/PeerReplicator.js +1071 -0
  235. package/dist/server/peer/PeerReplicator.js.map +1 -0
  236. package/dist/server/peer/clusterHttp.d.ts +113 -0
  237. package/dist/server/peer/clusterHttp.d.ts.map +1 -0
  238. package/dist/server/peer/clusterHttp.js +290 -0
  239. package/dist/server/peer/clusterHttp.js.map +1 -0
  240. package/dist/server/peer/types.d.ts +244 -0
  241. package/dist/server/peer/types.d.ts.map +1 -0
  242. package/dist/server/peer/types.js +189 -0
  243. package/dist/server/peer/types.js.map +1 -0
  244. package/dist/server/rateLimits.d.ts +119 -0
  245. package/dist/server/rateLimits.d.ts.map +1 -0
  246. package/dist/server/rateLimits.js +159 -0
  247. package/dist/server/rateLimits.js.map +1 -0
  248. package/dist/server/serverConfig.d.ts +37 -0
  249. package/dist/server/serverConfig.d.ts.map +1 -0
  250. package/dist/server/serverConfig.js +251 -0
  251. package/dist/server/serverConfig.js.map +1 -0
  252. package/dist/server/timestampProxy.d.ts +129 -0
  253. package/dist/server/timestampProxy.d.ts.map +1 -0
  254. package/dist/server/timestampProxy.js +361 -0
  255. package/dist/server/timestampProxy.js.map +1 -0
  256. package/dist/server/types.d.ts +267 -0
  257. package/dist/server/types.d.ts.map +1 -0
  258. package/dist/server/types.js +56 -0
  259. package/dist/server/types.js.map +1 -0
  260. package/dist/server/validation.d.ts +43 -0
  261. package/dist/server/validation.d.ts.map +1 -0
  262. package/dist/server/validation.js +104 -0
  263. package/dist/server/validation.js.map +1 -0
  264. package/package.json +9 -1
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ /**
3
+ * RFC 3161 timestamp proxy.
4
+ *
5
+ * Sealing a document (see the TeamSketchbook seal feature) needs a third-party
6
+ * attested time: the client hashes its own signature and asks a Time-Stamping
7
+ * Authority to sign that hash together with the TSA's clock reading.
8
+ *
9
+ * Most public TSAs cannot be called from a browser — they are http-only or send
10
+ * no CORS headers — so the server offers an authenticated proxy. It forwards
11
+ * opaque DER bytes and never parses them; the *client* verifies the returned
12
+ * token (messageImprint equality and chain to a trusted root), which is what
13
+ * makes a hostile or buggy proxy a denial-of-service risk rather than a forgery
14
+ * risk.
15
+ *
16
+ * SSRF is the hazard a forwarding endpoint always carries, so target URLs come
17
+ * only from server-side env config. A client may name a provider `id`; it can
18
+ * never supply a URL.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.TimestampProxyError = exports.BUILT_IN_TSA_PROVIDERS = exports.DEFAULT_TIMESTAMP_TIMEOUT_MS = exports.MAX_TIMESTAMP_RESPONSE_BYTES = exports.MAX_TIMESTAMP_REQUEST_BYTES = exports.TIMESTAMP_REPLY_CONTENT_TYPE = exports.TIMESTAMP_QUERY_CONTENT_TYPE = void 0;
22
+ exports.parseTsaProviders = parseTsaProviders;
23
+ exports.toPublicTsaProviders = toPublicTsaProviders;
24
+ exports.requestTimestampToken = requestTimestampToken;
25
+ const urlSafety_js_1 = require("../core/utils/urlSafety.js");
26
+ /** Content type mandated by RFC 3161 §3.4 for a request. */
27
+ exports.TIMESTAMP_QUERY_CONTENT_TYPE = "application/timestamp-query";
28
+ /** Content type mandated by RFC 3161 §3.4 for a response. */
29
+ exports.TIMESTAMP_REPLY_CONTENT_TYPE = "application/timestamp-reply";
30
+ /**
31
+ * A TimeStampReq is a hash plus a little ASN.1 framing — a few hundred bytes at
32
+ * most. Anything larger is either a bug or an attempt to use us as an upload
33
+ * relay.
34
+ */
35
+ exports.MAX_TIMESTAMP_REQUEST_BYTES = 8 * 1024;
36
+ /**
37
+ * A TimeStampResp carries the token and the TSA certificate chain. Real tokens
38
+ * run 2–8 KB; the cap bounds memory when an upstream misbehaves.
39
+ */
40
+ exports.MAX_TIMESTAMP_RESPONSE_BYTES = 128 * 1024;
41
+ /** Per-provider timeout. Failover to the next provider is preferable to waiting. */
42
+ exports.DEFAULT_TIMESTAMP_TIMEOUT_MS = 10000;
43
+ /**
44
+ * Providers a client can name by id without the operator writing a URL.
45
+ *
46
+ * Terms of use differ and are the operator's call, which is why nothing here is
47
+ * enabled by default:
48
+ * - `aimoda` and `opentsa` state that general production use is fine;
49
+ * - `freetsa` is a community service with no usage restriction;
50
+ * - the DigiCert/Sectigo endpoints are provided for their own certificate
51
+ * customers' code signing, so using them as general infrastructure is not
52
+ * clearly permitted — they are listed for completeness, not recommended.
53
+ */
54
+ exports.BUILT_IN_TSA_PROVIDERS = Object.freeze({
55
+ aimoda: {
56
+ id: "aimoda",
57
+ name: "ai.moda RFC 3161 proxy",
58
+ url: "https://rfc3161.ai.moda",
59
+ qualified: false,
60
+ rootInPublicTrustStores: true,
61
+ },
62
+ opentsa: {
63
+ id: "opentsa",
64
+ name: "Open TSA (open-tsa.eu)",
65
+ url: "https://tsr.open-tsa.eu",
66
+ qualified: false,
67
+ rootInPublicTrustStores: false,
68
+ },
69
+ freetsa: {
70
+ id: "freetsa",
71
+ name: "FreeTSA",
72
+ url: "https://freetsa.org/tsr",
73
+ qualified: false,
74
+ rootInPublicTrustStores: false,
75
+ },
76
+ digicert: {
77
+ id: "digicert",
78
+ name: "DigiCert",
79
+ url: "http://timestamp.digicert.com",
80
+ qualified: false,
81
+ rootInPublicTrustStores: true,
82
+ },
83
+ sectigo: {
84
+ id: "sectigo",
85
+ name: "Sectigo",
86
+ url: "http://timestamp.sectigo.com",
87
+ qualified: false,
88
+ rootInPublicTrustStores: true,
89
+ },
90
+ "sectigo-qualified": {
91
+ id: "sectigo-qualified",
92
+ name: "Sectigo Qualified",
93
+ url: "http://timestamp.sectigo.com/qualified",
94
+ qualified: true,
95
+ rootInPublicTrustStores: true,
96
+ },
97
+ });
98
+ /** Provider ids are used in URLs, filenames and manifests — keep them boring. */
99
+ const PROVIDER_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,31}$/;
100
+ /**
101
+ * Parse `MINDOODB_TSA_PROVIDERS`.
102
+ *
103
+ * Comma-separated entries, each either a built-in id (`aimoda`) or a custom
104
+ * `id=url` pair (`inhouse=https://tsa.corp.example/tsr`). A trailing `!` on an
105
+ * entry marks it qualified, and `+` marks its root as publicly trusted:
106
+ *
107
+ * MINDOODB_TSA_PROVIDERS="aimoda,opentsa,belgium=http://tsa.belgium.be/connect!+"
108
+ *
109
+ * Unset or empty disables the proxy entirely. That is the safe default: a
110
+ * forwarding endpoint is outbound network access the operator should opt into,
111
+ * and Haven can still reach the browser-callable TSA directly without it.
112
+ */
113
+ function parseTsaProviders(raw, options = {}) {
114
+ const warn = options.warn ?? ((message) => console.warn(message));
115
+ const allowInsecure = options.allowInsecureUrls ?? false;
116
+ const entries = (raw ?? "")
117
+ .split(",")
118
+ .map((entry) => entry.trim())
119
+ .filter((entry) => entry.length > 0);
120
+ const providers = [];
121
+ const seen = new Set();
122
+ for (const entry of entries) {
123
+ let spec = entry;
124
+ let qualified = false;
125
+ let publiclyTrusted;
126
+ // Flags are suffixes so a URL containing them is still parsed correctly.
127
+ while (spec.endsWith("!") || spec.endsWith("+")) {
128
+ if (spec.endsWith("!"))
129
+ qualified = true;
130
+ else
131
+ publiclyTrusted = true;
132
+ spec = spec.slice(0, -1);
133
+ }
134
+ const eq = spec.indexOf("=");
135
+ const id = (eq === -1 ? spec : spec.slice(0, eq)).trim().toLowerCase();
136
+ const url = eq === -1 ? undefined : spec.slice(eq + 1).trim();
137
+ if (!PROVIDER_ID_PATTERN.test(id)) {
138
+ warn(`[timestampProxy] Ignoring TSA provider "${entry}": invalid id "${id}"`);
139
+ continue;
140
+ }
141
+ if (seen.has(id)) {
142
+ warn(`[timestampProxy] Ignoring duplicate TSA provider id "${id}"`);
143
+ continue;
144
+ }
145
+ let resolved;
146
+ if (url === undefined) {
147
+ const builtIn = exports.BUILT_IN_TSA_PROVIDERS[id];
148
+ if (!builtIn) {
149
+ warn(`[timestampProxy] Ignoring TSA provider "${id}": not a built-in id and no URL given (use "${id}=https://...")`);
150
+ continue;
151
+ }
152
+ resolved = { ...builtIn };
153
+ if (qualified)
154
+ resolved.qualified = true;
155
+ if (publiclyTrusted !== undefined)
156
+ resolved.rootInPublicTrustStores = publiclyTrusted;
157
+ }
158
+ else {
159
+ resolved = {
160
+ id,
161
+ name: id,
162
+ url,
163
+ qualified,
164
+ rootInPublicTrustStores: publiclyTrusted ?? false,
165
+ };
166
+ }
167
+ try {
168
+ // http is deliberately allowed: every eIDAS-qualified TSA we can use is
169
+ // http-only. The token is signed, so transport confidentiality only hides
170
+ // an opaque hash. Internal hosts stay blocked — that is the SSRF guard.
171
+ (0, urlSafety_js_1.assertSafeSyncUrl)(resolved.url, {
172
+ requireHttps: false,
173
+ allowPrivate: allowInsecure,
174
+ });
175
+ }
176
+ catch (error) {
177
+ const reason = error instanceof urlSafety_js_1.UnsafeUrlError ? error.message : String(error);
178
+ warn(`[timestampProxy] Ignoring TSA provider "${id}": ${reason}`);
179
+ continue;
180
+ }
181
+ seen.add(id);
182
+ providers.push(resolved);
183
+ }
184
+ return providers;
185
+ }
186
+ /** Drop the URL before a provider list is handed to a client. */
187
+ function toPublicTsaProviders(providers) {
188
+ return providers.map(({ url: _url, ...rest }) => ({ ...rest }));
189
+ }
190
+ class TimestampProxyError extends Error {
191
+ constructor(message, status,
192
+ /** Per-provider failures, for logging and for a client that wants to retry elsewhere. */
193
+ attempts = []) {
194
+ super(message);
195
+ this.status = status;
196
+ this.attempts = attempts;
197
+ this.name = "TimestampProxyError";
198
+ }
199
+ }
200
+ exports.TimestampProxyError = TimestampProxyError;
201
+ /**
202
+ * Read a response body with a hard byte cap.
203
+ *
204
+ * `response.arrayBuffer()` would buffer whatever the upstream sends; a TSA that
205
+ * answers with a gigabyte (hostile, or simply broken) must not be able to take
206
+ * the process down with it.
207
+ */
208
+ async function readCappedBody(response, maxBytes) {
209
+ const declared = response.headers.get("content-length");
210
+ if (declared) {
211
+ const declaredBytes = Number(declared);
212
+ if (Number.isFinite(declaredBytes) && declaredBytes > maxBytes) {
213
+ throw new Error(`response too large (${declaredBytes} bytes, max ${maxBytes})`);
214
+ }
215
+ }
216
+ const body = response.body;
217
+ if (!body) {
218
+ const buffer = new Uint8Array(await response.arrayBuffer());
219
+ if (buffer.byteLength > maxBytes) {
220
+ throw new Error(`response too large (${buffer.byteLength} bytes, max ${maxBytes})`);
221
+ }
222
+ return buffer;
223
+ }
224
+ const reader = body.getReader();
225
+ const chunks = [];
226
+ let total = 0;
227
+ try {
228
+ for (;;) {
229
+ const { done, value } = await reader.read();
230
+ if (done)
231
+ break;
232
+ if (!value)
233
+ continue;
234
+ total += value.byteLength;
235
+ if (total > maxBytes) {
236
+ throw new Error(`response too large (over ${maxBytes} bytes)`);
237
+ }
238
+ chunks.push(value);
239
+ }
240
+ }
241
+ finally {
242
+ reader.releaseLock();
243
+ // Abandoning a partially-read body leaks the socket otherwise.
244
+ void body.cancel().catch(() => undefined);
245
+ }
246
+ const out = new Uint8Array(total);
247
+ let offset = 0;
248
+ for (const chunk of chunks) {
249
+ out.set(chunk, offset);
250
+ offset += chunk.byteLength;
251
+ }
252
+ return out;
253
+ }
254
+ /** Reject an answer that is obviously not DER before it reaches the client. */
255
+ function assertLooksLikeTimestampResponse(bytes, contentType) {
256
+ if (bytes.byteLength < 2) {
257
+ throw new Error("empty response");
258
+ }
259
+ // Every TimeStampResp is a DER SEQUENCE.
260
+ if (bytes[0] !== 0x30) {
261
+ const hint = contentType ? ` (content-type "${contentType}")` : "";
262
+ throw new Error(`response is not DER${hint}`);
263
+ }
264
+ if (contentType) {
265
+ const normalized = contentType.split(";")[0].trim().toLowerCase();
266
+ // Some deployments answer `application/octet-stream`; only reject types that
267
+ // are certainly wrong, such as an HTML error page from a captive proxy.
268
+ if (normalized.startsWith("text/") || normalized === "application/json") {
269
+ throw new Error(`unexpected content-type "${normalized}"`);
270
+ }
271
+ }
272
+ }
273
+ /**
274
+ * POST the request to each provider in turn, returning the first DER answer.
275
+ *
276
+ * Failover is per-provider and the reason for each failure is preserved: an
277
+ * operator debugging "sealing stopped working" needs to see that provider A
278
+ * timed out and provider B answered 403, not a single opaque 502.
279
+ */
280
+ async function requestTimestampToken(options) {
281
+ const { providers, request, preferredProviderId, timeoutMs = exports.DEFAULT_TIMESTAMP_TIMEOUT_MS, maxResponseBytes = exports.MAX_TIMESTAMP_RESPONSE_BYTES, fetchImpl = fetch, } = options;
282
+ if (providers.length === 0) {
283
+ throw new TimestampProxyError("Timestamping is not enabled on this server", 503);
284
+ }
285
+ if (request.byteLength === 0) {
286
+ throw new TimestampProxyError("Empty timestamp request", 400);
287
+ }
288
+ if (request.byteLength > exports.MAX_TIMESTAMP_REQUEST_BYTES) {
289
+ throw new TimestampProxyError(`Timestamp request too large (${request.byteLength} bytes, max ${exports.MAX_TIMESTAMP_REQUEST_BYTES})`, 413);
290
+ }
291
+ if (request[0] !== 0x30) {
292
+ throw new TimestampProxyError("Timestamp request is not DER-encoded", 400);
293
+ }
294
+ let ordered = providers;
295
+ if (preferredProviderId) {
296
+ const preferred = providers.find((provider) => provider.id === preferredProviderId);
297
+ if (!preferred) {
298
+ throw new TimestampProxyError(`Unknown timestamp provider "${preferredProviderId}"`, 400);
299
+ }
300
+ ordered = [preferred, ...providers.filter((provider) => provider.id !== preferred.id)];
301
+ }
302
+ const attempts = [];
303
+ for (const provider of ordered) {
304
+ const startedAt = Date.now();
305
+ const controller = new AbortController();
306
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
307
+ try {
308
+ const response = await fetchImpl(provider.url, {
309
+ method: "POST",
310
+ headers: {
311
+ "content-type": exports.TIMESTAMP_QUERY_CONTENT_TYPE,
312
+ accept: exports.TIMESTAMP_REPLY_CONTENT_TYPE,
313
+ },
314
+ // A copy, because `fetch` may retain the buffer past this call.
315
+ body: request.slice().buffer,
316
+ // Following a redirect would let an upstream re-point us at an internal
317
+ // host, defeating the URL allowlist.
318
+ redirect: "error",
319
+ signal: controller.signal,
320
+ });
321
+ if (!response.ok) {
322
+ attempts.push({
323
+ providerId: provider.id,
324
+ ok: false,
325
+ httpStatus: response.status,
326
+ error: `HTTP ${response.status}`,
327
+ durationMs: Date.now() - startedAt,
328
+ });
329
+ continue;
330
+ }
331
+ const bytes = await readCappedBody(response, maxResponseBytes);
332
+ assertLooksLikeTimestampResponse(bytes, response.headers.get("content-type"));
333
+ attempts.push({
334
+ providerId: provider.id,
335
+ ok: true,
336
+ httpStatus: response.status,
337
+ durationMs: Date.now() - startedAt,
338
+ });
339
+ return {
340
+ providerId: provider.id,
341
+ providerName: provider.name,
342
+ response: bytes,
343
+ attempts,
344
+ };
345
+ }
346
+ catch (error) {
347
+ const aborted = error instanceof Error && error.name === "AbortError";
348
+ attempts.push({
349
+ providerId: provider.id,
350
+ ok: false,
351
+ error: aborted ? `timed out after ${timeoutMs}ms` : String(error instanceof Error ? error.message : error),
352
+ durationMs: Date.now() - startedAt,
353
+ });
354
+ }
355
+ finally {
356
+ clearTimeout(timer);
357
+ }
358
+ }
359
+ throw new TimestampProxyError("No timestamp provider could be reached", 502, attempts);
360
+ }
361
+ //# sourceMappingURL=timestampProxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timestampProxy.js","sourceRoot":"","sources":["../../src/server/timestampProxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,267 @@
1
+ import type { MindooDBServerInfo } from "../core/types";
2
+ import type { PeerSyncDirection, PeerRole, PeerAttachmentMode } from "./peer/types";
3
+ /**
4
+ * Types for the MindooDB Example Server
5
+ */
6
+ /**
7
+ * Store type for content-addressed stores.
8
+ */
9
+ export type StoreType = "inmemory" | "file";
10
+ /**
11
+ * Configuration for a user registered in the tenant.
12
+ * Users can be human clients or other servers (for server-to-server sync).
13
+ *
14
+ * The canonical identity of an entry is its `signingPublicKey`: the server
15
+ * matches and authorizes by key, never by name. `username` is optional and
16
+ * documentation-only (a human-readable label); it is ignored for matching.
17
+ * Arbitrary extra fields (e.g. `comment`) are allowed and ignored by the server.
18
+ */
19
+ export interface UserConfig {
20
+ /**
21
+ * Optional, documentation-only label for this key (e.g. "alice" or
22
+ * "server-eu-west"). Ignored for identity matching — the server identifies
23
+ * users by `signingPublicKey`. Kept for backward compatibility with
24
+ * config-based username authentication.
25
+ */
26
+ username?: string;
27
+ /** Ed25519 public key in PEM format for signature verification (the identity). */
28
+ signingPublicKey: string;
29
+ /** RSA-OAEP public key in PEM format for encryption */
30
+ encryptionPublicKey: string;
31
+ /** Optional free-form note describing this entry (ignored by the server). */
32
+ comment?: string;
33
+ /** Arbitrary extra documentation fields are tolerated and ignored. */
34
+ [key: string]: unknown;
35
+ }
36
+ /**
37
+ * A remote server trusted for server-to-server sync.
38
+ * Stored globally in <dataDir>/trusted-servers.json.
39
+ *
40
+ * Trust and reachability are one entry: the keys authenticate the peer in both
41
+ * directions, and `url` says where to reach it. An entry without `url` stays
42
+ * auth-only — the peer may call us, we never dial it.
43
+ */
44
+ export interface TrustedServer extends MindooDBServerInfo {
45
+ /**
46
+ * Where to reach the peer: an HTTPS origin without a tenant path
47
+ * (`https://eu-west.example.com`) or an Iroh locator (`iroh:<ticket>` /
48
+ * raw `endpoint…` ticket). HTTP appends `/{tenantId}`; Iroh uses the
49
+ * same peer RPC over QUIC. An endpoint-id-only locator (`iroh:<64-hex>`)
50
+ * is a stable label but cannot be dialled — store a full ticket to pair.
51
+ */
52
+ url?: string;
53
+ /** Which way entries flow. Defaults to `"bidirectional"`. */
54
+ direction?: PeerSyncDirection;
55
+ /** Mesh shape. Defaults to `"peer"`. */
56
+ role?: PeerRole;
57
+ /** How eagerly attachment blobs follow. Defaults to `"eager"`. */
58
+ attachments?: PeerAttachmentMode;
59
+ }
60
+ /**
61
+ * Per-database store configuration.
62
+ */
63
+ export interface DatabaseStoreConfig {
64
+ storeType: StoreType;
65
+ }
66
+ /**
67
+ * Tenant configuration stored in <dataDir>/<tenantId>/config.json
68
+ *
69
+ * The tenantId is NOT stored here - it's derived from the directory name.
70
+ */
71
+ export interface TenantConfig {
72
+ /** Admin username used for bootstrap authentication (e.g., "cn=admin/o=acme") */
73
+ adminUsername?: string;
74
+ /** Ed25519 public key in PEM format for verifying admin signatures */
75
+ adminSigningPublicKey: string;
76
+ /** RSA-OAEP public key in PEM format for encrypting admin-only data */
77
+ adminEncryptionPublicKey: string;
78
+ /** Default store type for new databases (default: "file") */
79
+ defaultStoreType?: StoreType;
80
+ /** Per-database store configuration overrides */
81
+ databaseStores?: Record<string, DatabaseStoreConfig>;
82
+ /** Registered users (clients and other servers) kept for bootstrap metadata only */
83
+ users?: UserConfig[];
84
+ }
85
+ /**
86
+ * Request body for POST /admin/register-tenant
87
+ */
88
+ export interface RegisterTenantRequest {
89
+ /** Tenant identifier (lowercase, becomes directory name) */
90
+ tenantId: string;
91
+ /** Admin username used for bootstrap authentication */
92
+ adminUsername?: string;
93
+ /** Ed25519 public key in PEM format */
94
+ adminSigningPublicKey: string;
95
+ /** RSA-OAEP public key in PEM format */
96
+ adminEncryptionPublicKey: string;
97
+ /** Legacy fallback: base64-encoded raw $publicinfos AES-256 key */
98
+ publicInfosKey?: string;
99
+ /** Preferred transport: base64-encoded RSA-encrypted $publicinfos AES-256 key */
100
+ encryptedPublicInfosKey?: string;
101
+ /** Default store type (default: "file") */
102
+ defaultStoreType?: StoreType;
103
+ /** Initial users to register (for testing/bootstrapping only, ignored when publicInfosKey is present) */
104
+ users?: UserConfig[];
105
+ }
106
+ /**
107
+ * Response body for POST /admin/register-tenant
108
+ */
109
+ export interface RegisterTenantResponse {
110
+ success: boolean;
111
+ tenantId: string;
112
+ created?: boolean;
113
+ message?: string;
114
+ }
115
+ export interface TenantPublicInfosFingerprintsResponse {
116
+ tenantId: string;
117
+ fingerprints: string[];
118
+ }
119
+ /**
120
+ * Response body for GET /admin/tenants
121
+ */
122
+ export interface ListTenantsResponse {
123
+ tenants: string[];
124
+ }
125
+ /**
126
+ * Loaded tenant context used internally by the server.
127
+ */
128
+ export interface TenantContext {
129
+ /** Tenant identifier (lowercase) */
130
+ tenantId: string;
131
+ /** Loaded tenant configuration */
132
+ config: TenantConfig;
133
+ }
134
+ /**
135
+ * A principal entry in a capability rule.
136
+ * Identifies a system admin by both username and public signing key.
137
+ *
138
+ * The special wildcard principal `{ username: "*", publicsignkey: "*" }`
139
+ * is reserved for demo tenant-creation rules and is rejected for all other
140
+ * system endpoints.
141
+ */
142
+ export interface SystemAdminPrincipal {
143
+ username: string;
144
+ publicsignkey: string;
145
+ }
146
+ export interface RateLimitConfig {
147
+ windowMs?: number;
148
+ max?: number;
149
+ }
150
+ /**
151
+ * Timestamp proxying additionally carries a daily cap, because the constrained
152
+ * resource is a third party's allowance rather than this server's CPU.
153
+ */
154
+ export interface TimestampRateLimitConfig extends RateLimitConfig {
155
+ dailyMax?: number;
156
+ }
157
+ export interface ServerRateLimitsConfig {
158
+ auth?: RateLimitConfig;
159
+ sync?: RateLimitConfig;
160
+ timestamps?: TimestampRateLimitConfig;
161
+ /**
162
+ * Per-IP limit for `/system/*`. Defaults to 30/min, which suits occasional
163
+ * CRUD but is tight for a cluster console: `GET /system/cluster/status`
164
+ * polled every few seconds across several nodes will hit it. Raise it on
165
+ * nodes that a monitoring dashboard watches.
166
+ *
167
+ * Does not cover `/system/peer/*`, which is server-to-server traffic with its
168
+ * own, much higher limit.
169
+ */
170
+ system?: RateLimitConfig;
171
+ /**
172
+ * Coarse per-IP net applied to every route ahead of the tier limiters.
173
+ * Defaults to the combined sync and auth budgets plus headroom; setting it
174
+ * below what a tier allows makes it, not the tier, the effective limit.
175
+ */
176
+ global?: RateLimitConfig;
177
+ }
178
+ /**
179
+ * Server-level configuration loaded from config.json.
180
+ *
181
+ * The `capabilities` map controls which system admins can call which
182
+ * endpoints. Keys are `METHOD:PATHPATTERN` rules (e.g. `ALL:/system/*`,
183
+ * `POST:/system/tenants/company-*`). Values are arrays of principals
184
+ * allowed to call matching routes.
185
+ */
186
+ export interface ServerConfig {
187
+ capabilities: Record<string, SystemAdminPrincipal[]>;
188
+ rateLimits?: ServerRateLimitsConfig;
189
+ cluster?: ServerClusterConfig;
190
+ /**
191
+ * Join the Iroh network and accept MindooDB sync on ALPN `mindoodb/sync-v5`.
192
+ * Off when omitted. HTTP listen stays unchanged.
193
+ */
194
+ iroh?: ServerIrohConfig;
195
+ }
196
+ /** Optional Iroh listen settings in config.json. Default is disabled. */
197
+ export interface ServerIrohConfig {
198
+ enabled: boolean;
199
+ /**
200
+ * Path to the 32-byte secret key (hex). Relative paths are resolved against
201
+ * the server data directory. Created on first start when missing.
202
+ */
203
+ secretKeyPath?: string;
204
+ }
205
+ /** Written into new `config.json` files. `--update` does not rewrite existing files. */
206
+ export declare const DEFAULT_SERVER_IROH_CONFIG: ServerIrohConfig;
207
+ /** Node-level cluster settings; per-peer settings live in `trusted-servers.json`. */
208
+ export interface ServerClusterConfig {
209
+ /**
210
+ * Start peer replication on boot. Equivalent to the `--auto-sync` CLI flag,
211
+ * which is the more common way to set it.
212
+ */
213
+ autoSync?: boolean;
214
+ /**
215
+ * This node's mesh role. `spoke` means it does not dial other spokes (the hub
216
+ * carries that traffic); `hub` and the default `peer` dial everyone.
217
+ */
218
+ role?: PeerRole;
219
+ }
220
+ /**
221
+ * Environment variables used by the server.
222
+ */
223
+ export declare const ENV_VARS: {
224
+ /** Password to decrypt server identity private keys and per-tenant keybags */
225
+ readonly SERVER_PASSWORD: "MINDOODB_SERVER_PASSWORD";
226
+ /**
227
+ * Path to a file whose contents are the server password (trimmed). If set, used
228
+ * instead of {@link ENV_VARS.SERVER_PASSWORD}. Prefer in Docker so the secret is
229
+ * not stored in the container environment block.
230
+ */
231
+ readonly SERVER_PASSWORD_FILE: "MINDOODB_SERVER_PASSWORD_FILE";
232
+ /**
233
+ * Optional comma-separated allowlist for /system/* (system admin HTTP surface).
234
+ * If unset or `*`, any client IP may call /system/* (JWT + capabilities still required).
235
+ * Supports exact IPv4/IPv6 addresses plus IPv4/IPv6 CIDRs.
236
+ * Example: `127.0.0.1,::1,10.0.0.0/8,2001:db8::/32`
237
+ */
238
+ readonly ADMIN_ALLOWED_IPS: "MINDOODB_ADMIN_ALLOWED_IPS";
239
+ /**
240
+ * Express `trust proxy` setting: a hop count (`1` behind Cloudflare, `2` when
241
+ * nginx also fronts the origin), a comma-separated list of trusted
242
+ * addresses/CIDRs, `loopback`, or `true`. Unset means no proxy is trusted.
243
+ *
244
+ * Every rate limiter keys on `req.ip`; behind a proxy without this, all
245
+ * clients share the proxy's address and therefore one budget.
246
+ */
247
+ readonly TRUST_PROXY: "MINDOODB_TRUST_PROXY";
248
+ /**
249
+ * When `true`/`1`, peer URLs may use plaintext http and target
250
+ * loopback/private/link-local hosts. Off by default so the server cannot be
251
+ * pointed at internal services (SSRF). Enable only for local development.
252
+ */
253
+ readonly ALLOW_INSECURE_SYNC_URLS: "MINDOODB_ALLOW_INSECURE_SYNC_URLS";
254
+ /**
255
+ * Comma-separated RFC 3161 Time-Stamping Authorities the proxy at
256
+ * `POST /:tenantId/timestamps/rfc3161` may contact. Each entry is a built-in
257
+ * id (`aimoda`, `opentsa`, `freetsa`, ...) or a custom `id=url` pair; suffix
258
+ * `!` marks the provider qualified and `+` marks its root publicly trusted.
259
+ *
260
+ * Example: `aimoda,opentsa,belgium=http://tsa.belgium.be/connect!+`
261
+ *
262
+ * Unset disables the proxy. Clients name a provider by id only — a URL from a
263
+ * client would turn the endpoint into an SSRF gadget.
264
+ */
265
+ readonly TSA_PROVIDERS: "MINDOODB_TSA_PROVIDERS";
266
+ };
267
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}