@enbox/dwn-server 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 (309) hide show
  1. package/LICENSE +3 -2
  2. package/README.md +115 -215
  3. package/dist/esm/src/admin/activity-log.d.ts +44 -0
  4. package/dist/esm/src/admin/activity-log.d.ts.map +1 -0
  5. package/dist/esm/src/admin/activity-log.js +85 -0
  6. package/dist/esm/src/admin/activity-log.js.map +1 -0
  7. package/dist/esm/src/admin/admin-api.d.ts +61 -0
  8. package/dist/esm/src/admin/admin-api.d.ts.map +1 -0
  9. package/dist/esm/src/admin/admin-api.js +1047 -0
  10. package/dist/esm/src/admin/admin-api.js.map +1 -0
  11. package/dist/esm/src/admin/admin-auth.d.ts +9 -0
  12. package/dist/esm/src/admin/admin-auth.d.ts.map +1 -0
  13. package/dist/esm/src/admin/admin-auth.js +45 -0
  14. package/dist/esm/src/admin/admin-auth.js.map +1 -0
  15. package/dist/esm/src/admin/admin-store.d.ts +111 -0
  16. package/dist/esm/src/admin/admin-store.d.ts.map +1 -0
  17. package/dist/esm/src/admin/admin-store.js +376 -0
  18. package/dist/esm/src/admin/admin-store.js.map +1 -0
  19. package/dist/esm/src/admin/audit-log.d.ts +94 -0
  20. package/dist/esm/src/admin/audit-log.d.ts.map +1 -0
  21. package/dist/esm/src/admin/audit-log.js +220 -0
  22. package/dist/esm/src/admin/audit-log.js.map +1 -0
  23. package/dist/esm/src/admin/index.d.ts +10 -0
  24. package/dist/esm/src/admin/index.d.ts.map +1 -0
  25. package/dist/esm/src/admin/index.js +7 -0
  26. package/dist/esm/src/admin/index.js.map +1 -0
  27. package/dist/esm/src/admin/types.d.ts +306 -0
  28. package/dist/esm/src/admin/types.d.ts.map +1 -0
  29. package/dist/esm/src/admin/types.js +2 -0
  30. package/dist/esm/src/admin/types.js.map +1 -0
  31. package/dist/esm/src/admin/webhook-manager.d.ts +55 -0
  32. package/dist/esm/src/admin/webhook-manager.d.ts.map +1 -0
  33. package/dist/esm/src/admin/webhook-manager.js +184 -0
  34. package/dist/esm/src/admin/webhook-manager.js.map +1 -0
  35. package/dist/esm/src/config.d.ts +124 -9
  36. package/dist/esm/src/config.d.ts.map +1 -1
  37. package/dist/esm/src/config.js +155 -13
  38. package/dist/esm/src/config.js.map +1 -1
  39. package/dist/esm/src/connection/connection-manager.d.ts +32 -9
  40. package/dist/esm/src/connection/connection-manager.d.ts.map +1 -1
  41. package/dist/esm/src/connection/connection-manager.js +38 -5
  42. package/dist/esm/src/connection/connection-manager.js.map +1 -1
  43. package/dist/esm/src/connection/flow-controller.d.ts +53 -0
  44. package/dist/esm/src/connection/flow-controller.d.ts.map +1 -0
  45. package/dist/esm/src/connection/flow-controller.js +101 -0
  46. package/dist/esm/src/connection/flow-controller.js.map +1 -0
  47. package/dist/esm/src/connection/socket-connection.d.ts +54 -18
  48. package/dist/esm/src/connection/socket-connection.d.ts.map +1 -1
  49. package/dist/esm/src/connection/socket-connection.js +102 -40
  50. package/dist/esm/src/connection/socket-connection.js.map +1 -1
  51. package/dist/esm/src/delivery-service.d.ts +43 -0
  52. package/dist/esm/src/delivery-service.d.ts.map +1 -0
  53. package/dist/esm/src/delivery-service.js +574 -0
  54. package/dist/esm/src/delivery-service.js.map +1 -0
  55. package/dist/esm/src/dwn-error.d.ts +10 -1
  56. package/dist/esm/src/dwn-error.d.ts.map +1 -1
  57. package/dist/esm/src/dwn-error.js +9 -0
  58. package/dist/esm/src/dwn-error.js.map +1 -1
  59. package/dist/esm/src/dwn-server.d.ts +13 -6
  60. package/dist/esm/src/dwn-server.d.ts.map +1 -1
  61. package/dist/esm/src/dwn-server.js +199 -24
  62. package/dist/esm/src/dwn-server.js.map +1 -1
  63. package/dist/esm/src/http-api.d.ts +28 -13
  64. package/dist/esm/src/http-api.d.ts.map +1 -1
  65. package/dist/esm/src/http-api.js +649 -374
  66. package/dist/esm/src/http-api.js.map +1 -1
  67. package/dist/esm/src/index.d.ts +6 -2
  68. package/dist/esm/src/index.d.ts.map +1 -1
  69. package/dist/esm/src/index.js +4 -1
  70. package/dist/esm/src/index.js.map +1 -1
  71. package/dist/esm/src/json-rpc-api.js +2 -1
  72. package/dist/esm/src/json-rpc-api.js.map +1 -1
  73. package/dist/esm/src/json-rpc-handlers/dwn/process-message.d.ts.map +1 -1
  74. package/dist/esm/src/json-rpc-handlers/dwn/process-message.js +109 -7
  75. package/dist/esm/src/json-rpc-handlers/dwn/process-message.js.map +1 -1
  76. package/dist/esm/src/json-rpc-handlers/subscription/ack.d.ts +20 -0
  77. package/dist/esm/src/json-rpc-handlers/subscription/ack.d.ts.map +1 -0
  78. package/dist/esm/src/json-rpc-handlers/subscription/ack.js +41 -0
  79. package/dist/esm/src/json-rpc-handlers/subscription/ack.js.map +1 -0
  80. package/dist/esm/src/json-rpc-handlers/subscription/close.d.ts.map +1 -1
  81. package/dist/esm/src/json-rpc-handlers/subscription/close.js +1 -1
  82. package/dist/esm/src/json-rpc-handlers/subscription/close.js.map +1 -1
  83. package/dist/esm/src/json-rpc-handlers/subscription/index.d.ts +1 -0
  84. package/dist/esm/src/json-rpc-handlers/subscription/index.d.ts.map +1 -1
  85. package/dist/esm/src/json-rpc-handlers/subscription/index.js +1 -0
  86. package/dist/esm/src/json-rpc-handlers/subscription/index.js.map +1 -1
  87. package/dist/esm/src/lib/json-rpc-router.d.ts +25 -8
  88. package/dist/esm/src/lib/json-rpc-router.d.ts.map +1 -1
  89. package/dist/esm/src/lib/json-rpc-router.js.map +1 -1
  90. package/dist/esm/src/lib/sql-utils.d.ts +6 -0
  91. package/dist/esm/src/lib/sql-utils.d.ts.map +1 -0
  92. package/dist/esm/src/lib/sql-utils.js +8 -0
  93. package/dist/esm/src/lib/sql-utils.js.map +1 -0
  94. package/dist/esm/src/main.js +0 -6
  95. package/dist/esm/src/main.js.map +1 -1
  96. package/dist/esm/src/message-processed-hook.d.ts +35 -0
  97. package/dist/esm/src/message-processed-hook.d.ts.map +1 -0
  98. package/dist/esm/src/message-processed-hook.js +2 -0
  99. package/dist/esm/src/message-processed-hook.js.map +1 -0
  100. package/dist/esm/src/metrics.d.ts +14 -2
  101. package/dist/esm/src/metrics.d.ts.map +1 -1
  102. package/dist/esm/src/metrics.js +41 -1
  103. package/dist/esm/src/metrics.js.map +1 -1
  104. package/dist/esm/src/plugins/event-log-nats.d.ts +25 -0
  105. package/dist/esm/src/plugins/event-log-nats.d.ts.map +1 -0
  106. package/dist/esm/src/plugins/event-log-nats.js +379 -0
  107. package/dist/esm/src/plugins/event-log-nats.js.map +1 -0
  108. package/dist/esm/src/rate-limiter.d.ts +60 -0
  109. package/dist/esm/src/rate-limiter.d.ts.map +1 -0
  110. package/dist/esm/src/rate-limiter.js +116 -0
  111. package/dist/esm/src/rate-limiter.js.map +1 -0
  112. package/dist/esm/src/registration/jwt-provider-auth-plugin.d.ts +53 -0
  113. package/dist/esm/src/registration/jwt-provider-auth-plugin.d.ts.map +1 -0
  114. package/dist/esm/src/registration/jwt-provider-auth-plugin.js +90 -0
  115. package/dist/esm/src/registration/jwt-provider-auth-plugin.js.map +1 -0
  116. package/dist/esm/src/registration/open-auth-handler.d.ts +37 -0
  117. package/dist/esm/src/registration/open-auth-handler.d.ts.map +1 -0
  118. package/dist/esm/src/registration/open-auth-handler.js +214 -0
  119. package/dist/esm/src/registration/open-auth-handler.js.map +1 -0
  120. package/dist/esm/src/registration/proof-of-work-manager.d.ts +1 -1
  121. package/dist/esm/src/registration/proof-of-work-manager.d.ts.map +1 -1
  122. package/dist/esm/src/registration/proof-of-work-manager.js +3 -3
  123. package/dist/esm/src/registration/proof-of-work-manager.js.map +1 -1
  124. package/dist/esm/src/registration/provider-auth-plugin.d.ts +46 -0
  125. package/dist/esm/src/registration/provider-auth-plugin.d.ts.map +1 -0
  126. package/dist/esm/src/registration/provider-auth-plugin.js +29 -0
  127. package/dist/esm/src/registration/provider-auth-plugin.js.map +1 -0
  128. package/dist/esm/src/registration/registration-manager.d.ts +28 -5
  129. package/dist/esm/src/registration/registration-manager.d.ts.map +1 -1
  130. package/dist/esm/src/registration/registration-manager.js +83 -12
  131. package/dist/esm/src/registration/registration-manager.js.map +1 -1
  132. package/dist/esm/src/registration/registration-store.d.ts +83 -3
  133. package/dist/esm/src/registration/registration-store.d.ts.map +1 -1
  134. package/dist/esm/src/registration/registration-store.js +248 -11
  135. package/dist/esm/src/registration/registration-store.js.map +1 -1
  136. package/dist/esm/src/storage.d.ts +5 -5
  137. package/dist/esm/src/storage.d.ts.map +1 -1
  138. package/dist/esm/src/storage.js +105 -24
  139. package/dist/esm/src/storage.js.map +1 -1
  140. package/dist/esm/src/web5-connect/sql-ttl-cache.d.ts.map +1 -1
  141. package/dist/esm/src/web5-connect/sql-ttl-cache.js +11 -3
  142. package/dist/esm/src/web5-connect/sql-ttl-cache.js.map +1 -1
  143. package/dist/esm/src/web5-connect/web5-connect-server.d.ts.map +1 -1
  144. package/dist/esm/src/web5-connect/web5-connect-server.js +2 -2
  145. package/dist/esm/src/web5-connect/web5-connect-server.js.map +1 -1
  146. package/dist/esm/src/ws-api.d.ts +18 -4
  147. package/dist/esm/src/ws-api.d.ts.map +1 -1
  148. package/dist/esm/src/ws-api.js +12 -16
  149. package/dist/esm/src/ws-api.js.map +1 -1
  150. package/package.json +34 -53
  151. package/src/admin/activity-log.ts +100 -0
  152. package/src/admin/admin-api.ts +1308 -0
  153. package/src/admin/admin-auth.ts +56 -0
  154. package/src/admin/admin-store.ts +515 -0
  155. package/src/admin/audit-log.ts +327 -0
  156. package/src/admin/index.ts +34 -0
  157. package/src/admin/types.ts +352 -0
  158. package/src/admin/webhook-manager.ts +245 -0
  159. package/src/config.ts +190 -22
  160. package/src/connection/connection-manager.ts +67 -17
  161. package/src/connection/flow-controller.ts +117 -0
  162. package/src/connection/socket-connection.ts +144 -67
  163. package/src/delivery-service.ts +740 -0
  164. package/src/dwn-error.ts +11 -2
  165. package/src/dwn-server.ts +254 -39
  166. package/src/http-api.ts +736 -392
  167. package/src/index.ts +13 -2
  168. package/src/json-rpc-api.ts +2 -1
  169. package/src/json-rpc-handlers/dwn/process-message.ts +149 -15
  170. package/src/json-rpc-handlers/subscription/ack.ts +63 -0
  171. package/src/json-rpc-handlers/subscription/close.ts +5 -9
  172. package/src/json-rpc-handlers/subscription/index.ts +1 -0
  173. package/src/lib/json-rpc-router.ts +26 -11
  174. package/src/lib/sql-utils.ts +7 -0
  175. package/src/main.ts +0 -8
  176. package/src/message-processed-hook.ts +33 -0
  177. package/src/metrics.ts +57 -8
  178. package/src/plugins/event-log-nats.ts +466 -0
  179. package/src/process-handlers.ts +5 -5
  180. package/src/rate-limiter.ts +143 -0
  181. package/src/registration/jwt-provider-auth-plugin.ts +119 -0
  182. package/src/registration/open-auth-handler.ts +263 -0
  183. package/src/registration/proof-of-work-manager.ts +11 -10
  184. package/src/registration/provider-auth-plugin.ts +84 -0
  185. package/src/registration/registration-manager.ts +129 -31
  186. package/src/registration/registration-store.ts +332 -22
  187. package/src/storage.ts +136 -40
  188. package/src/web5-connect/sql-ttl-cache.ts +12 -5
  189. package/src/web5-connect/web5-connect-server.ts +9 -8
  190. package/src/ws-api.ts +39 -26
  191. package/dist/cjs/index.js +0 -6811
  192. package/dist/cjs/package.json +0 -1
  193. package/dist/esm/src/json-rpc-socket.d.ts +0 -39
  194. package/dist/esm/src/json-rpc-socket.d.ts.map +0 -1
  195. package/dist/esm/src/json-rpc-socket.js +0 -125
  196. package/dist/esm/src/json-rpc-socket.js.map +0 -1
  197. package/dist/esm/src/lib/http-server-shutdown-handler.d.ts +0 -10
  198. package/dist/esm/src/lib/http-server-shutdown-handler.d.ts.map +0 -1
  199. package/dist/esm/src/lib/http-server-shutdown-handler.js +0 -65
  200. package/dist/esm/src/lib/http-server-shutdown-handler.js.map +0 -1
  201. package/dist/esm/src/lib/json-rpc.d.ts +0 -54
  202. package/dist/esm/src/lib/json-rpc.d.ts.map +0 -1
  203. package/dist/esm/src/lib/json-rpc.js +0 -60
  204. package/dist/esm/src/lib/json-rpc.js.map +0 -1
  205. package/dist/esm/src/registration/proof-of-work-types.d.ts +0 -8
  206. package/dist/esm/src/registration/proof-of-work-types.d.ts.map +0 -1
  207. package/dist/esm/src/registration/proof-of-work-types.js +0 -2
  208. package/dist/esm/src/registration/proof-of-work-types.js.map +0 -1
  209. package/dist/esm/src/registration/registration-types.d.ts +0 -18
  210. package/dist/esm/src/registration/registration-types.d.ts.map +0 -1
  211. package/dist/esm/src/registration/registration-types.js +0 -2
  212. package/dist/esm/src/registration/registration-types.js.map +0 -1
  213. package/dist/esm/tests/common-scenario-validator.d.ts +0 -11
  214. package/dist/esm/tests/common-scenario-validator.d.ts.map +0 -1
  215. package/dist/esm/tests/common-scenario-validator.js +0 -114
  216. package/dist/esm/tests/common-scenario-validator.js.map +0 -1
  217. package/dist/esm/tests/connection/connection-manager.spec.d.ts +0 -2
  218. package/dist/esm/tests/connection/connection-manager.spec.d.ts.map +0 -1
  219. package/dist/esm/tests/connection/connection-manager.spec.js +0 -47
  220. package/dist/esm/tests/connection/connection-manager.spec.js.map +0 -1
  221. package/dist/esm/tests/connection/socket-connection.spec.d.ts +0 -2
  222. package/dist/esm/tests/connection/socket-connection.spec.d.ts.map +0 -1
  223. package/dist/esm/tests/connection/socket-connection.spec.js +0 -125
  224. package/dist/esm/tests/connection/socket-connection.spec.js.map +0 -1
  225. package/dist/esm/tests/cors/http-api.browser.d.ts +0 -2
  226. package/dist/esm/tests/cors/http-api.browser.d.ts.map +0 -1
  227. package/dist/esm/tests/cors/http-api.browser.js +0 -60
  228. package/dist/esm/tests/cors/http-api.browser.js.map +0 -1
  229. package/dist/esm/tests/cors/ping.browser.d.ts +0 -2
  230. package/dist/esm/tests/cors/ping.browser.d.ts.map +0 -1
  231. package/dist/esm/tests/cors/ping.browser.js +0 -7
  232. package/dist/esm/tests/cors/ping.browser.js.map +0 -1
  233. package/dist/esm/tests/dwn-process-message.spec.d.ts +0 -2
  234. package/dist/esm/tests/dwn-process-message.spec.d.ts.map +0 -1
  235. package/dist/esm/tests/dwn-process-message.spec.js +0 -172
  236. package/dist/esm/tests/dwn-process-message.spec.js.map +0 -1
  237. package/dist/esm/tests/dwn-server.spec.d.ts +0 -2
  238. package/dist/esm/tests/dwn-server.spec.d.ts.map +0 -1
  239. package/dist/esm/tests/dwn-server.spec.js +0 -49
  240. package/dist/esm/tests/dwn-server.spec.js.map +0 -1
  241. package/dist/esm/tests/http-api.spec.d.ts +0 -2
  242. package/dist/esm/tests/http-api.spec.d.ts.map +0 -1
  243. package/dist/esm/tests/http-api.spec.js +0 -775
  244. package/dist/esm/tests/http-api.spec.js.map +0 -1
  245. package/dist/esm/tests/json-rpc-socket.spec.d.ts +0 -2
  246. package/dist/esm/tests/json-rpc-socket.spec.d.ts.map +0 -1
  247. package/dist/esm/tests/json-rpc-socket.spec.js +0 -225
  248. package/dist/esm/tests/json-rpc-socket.spec.js.map +0 -1
  249. package/dist/esm/tests/plugins/data-store-sqlite.d.ts +0 -17
  250. package/dist/esm/tests/plugins/data-store-sqlite.d.ts.map +0 -1
  251. package/dist/esm/tests/plugins/data-store-sqlite.js +0 -23
  252. package/dist/esm/tests/plugins/data-store-sqlite.js.map +0 -1
  253. package/dist/esm/tests/plugins/event-log-sqlite.d.ts +0 -17
  254. package/dist/esm/tests/plugins/event-log-sqlite.d.ts.map +0 -1
  255. package/dist/esm/tests/plugins/event-log-sqlite.js +0 -23
  256. package/dist/esm/tests/plugins/event-log-sqlite.js.map +0 -1
  257. package/dist/esm/tests/plugins/event-stream-in-memory.d.ts +0 -17
  258. package/dist/esm/tests/plugins/event-stream-in-memory.d.ts.map +0 -1
  259. package/dist/esm/tests/plugins/event-stream-in-memory.js +0 -21
  260. package/dist/esm/tests/plugins/event-stream-in-memory.js.map +0 -1
  261. package/dist/esm/tests/plugins/message-store-sqlite.d.ts +0 -17
  262. package/dist/esm/tests/plugins/message-store-sqlite.d.ts.map +0 -1
  263. package/dist/esm/tests/plugins/message-store-sqlite.js +0 -23
  264. package/dist/esm/tests/plugins/message-store-sqlite.js.map +0 -1
  265. package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts +0 -17
  266. package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts.map +0 -1
  267. package/dist/esm/tests/plugins/resumable-task-store-sqlite.js +0 -23
  268. package/dist/esm/tests/plugins/resumable-task-store-sqlite.js.map +0 -1
  269. package/dist/esm/tests/process-handler.spec.d.ts +0 -2
  270. package/dist/esm/tests/process-handler.spec.d.ts.map +0 -1
  271. package/dist/esm/tests/process-handler.spec.js +0 -60
  272. package/dist/esm/tests/process-handler.spec.js.map +0 -1
  273. package/dist/esm/tests/registration/proof-of-work-manager.spec.d.ts +0 -2
  274. package/dist/esm/tests/registration/proof-of-work-manager.spec.d.ts.map +0 -1
  275. package/dist/esm/tests/registration/proof-of-work-manager.spec.js +0 -157
  276. package/dist/esm/tests/registration/proof-of-work-manager.spec.js.map +0 -1
  277. package/dist/esm/tests/rpc-subscribe-close.spec.d.ts +0 -2
  278. package/dist/esm/tests/rpc-subscribe-close.spec.d.ts.map +0 -1
  279. package/dist/esm/tests/rpc-subscribe-close.spec.js +0 -81
  280. package/dist/esm/tests/rpc-subscribe-close.spec.js.map +0 -1
  281. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.d.ts +0 -2
  282. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.d.ts.map +0 -1
  283. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js +0 -73
  284. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js.map +0 -1
  285. package/dist/esm/tests/scenarios/registration.spec.d.ts +0 -2
  286. package/dist/esm/tests/scenarios/registration.spec.d.ts.map +0 -1
  287. package/dist/esm/tests/scenarios/registration.spec.js +0 -507
  288. package/dist/esm/tests/scenarios/registration.spec.js.map +0 -1
  289. package/dist/esm/tests/scenarios/web5-connect.spec.d.ts +0 -2
  290. package/dist/esm/tests/scenarios/web5-connect.spec.d.ts.map +0 -1
  291. package/dist/esm/tests/scenarios/web5-connect.spec.js +0 -137
  292. package/dist/esm/tests/scenarios/web5-connect.spec.js.map +0 -1
  293. package/dist/esm/tests/test-dwn.d.ts +0 -7
  294. package/dist/esm/tests/test-dwn.d.ts.map +0 -1
  295. package/dist/esm/tests/test-dwn.js +0 -34
  296. package/dist/esm/tests/test-dwn.js.map +0 -1
  297. package/dist/esm/tests/utils.d.ts +0 -46
  298. package/dist/esm/tests/utils.d.ts.map +0 -1
  299. package/dist/esm/tests/utils.js +0 -116
  300. package/dist/esm/tests/utils.js.map +0 -1
  301. package/dist/esm/tests/ws-api.spec.d.ts +0 -2
  302. package/dist/esm/tests/ws-api.spec.d.ts.map +0 -1
  303. package/dist/esm/tests/ws-api.spec.js +0 -327
  304. package/dist/esm/tests/ws-api.spec.js.map +0 -1
  305. package/src/json-rpc-socket.ts +0 -155
  306. package/src/lib/http-server-shutdown-handler.ts +0 -79
  307. package/src/lib/json-rpc.ts +0 -126
  308. package/src/registration/proof-of-work-types.ts +0 -7
  309. package/src/registration/registration-types.ts +0 -18
@@ -1,12 +1,14 @@
1
- import { ProofOfWorkManager } from "./proof-of-work-manager.js";
2
- import { ProofOfWork } from "./proof-of-work.js";
3
- import { RegistrationStore } from "./registration-store.js";
4
- import type { RegistrationData, RegistrationRequest } from "./registration-types.js";
5
- import type { ProofOfWorkChallengeModel } from "./proof-of-work-types.js";
6
- import { DwnServerError, DwnServerErrorCode } from "../dwn-error.js";
7
- import type { ActiveTenantCheckResult, TenantGate } from "@enbox/dwn-sdk-js";
8
- import { getDialectFromUrl } from "../storage.js";
9
- import { readFileSync } from "fs";
1
+ import type { ProviderAuthPlugin } from './provider-auth-plugin.js';
2
+ import type { ActiveTenantCheckResult, TenantGate } from '@enbox/dwn-sdk-js';
3
+ import type { ProofOfWorkChallengeModel, RegistrationRequest } from '@enbox/dwn-clients';
4
+
5
+ import { readFileSync } from 'fs';
6
+
7
+ import { getDialectFromUrl } from '../storage.js';
8
+ import { ProofOfWork } from './proof-of-work.js';
9
+ import { ProofOfWorkManager } from './proof-of-work-manager.js';
10
+ import { RegistrationStore } from './registration-store.js';
11
+ import { DwnServerError, DwnServerErrorCode } from '../dwn-error.js';
10
12
 
11
13
  /**
12
14
  * The RegistrationManager is responsible for managing the registration of tenants.
@@ -14,6 +16,7 @@ import { readFileSync } from "fs";
14
16
  */
15
17
  export class RegistrationManager implements TenantGate {
16
18
  private proofOfWorkManager: ProofOfWorkManager;
19
+ private providerAuthPlugin?: ProviderAuthPlugin;
17
20
  private registrationStore: RegistrationStore;
18
21
 
19
22
  private termsOfServiceHash?: string;
@@ -27,7 +30,7 @@ export class RegistrationManager implements TenantGate {
27
30
  }
28
31
 
29
32
  /**
30
- * The terms-of-service hash.
33
+ * The terms-of-service hash.
31
34
  */
32
35
  public getTermsOfServiceHash(): string | undefined {
33
36
  return this.termsOfServiceHash;
@@ -45,13 +48,14 @@ export class RegistrationManager implements TenantGate {
45
48
  * Creates a new RegistrationManager instance.
46
49
  * @param input.registrationStoreUrl - The URL of the registration store.
47
50
  * Set to `undefined` or empty string if tenant registration is not required (ie. DWN is open for all).
48
- *
51
+ *
49
52
  */
50
53
  public static async create(input: {
51
54
  registrationStoreUrl?: string,
52
- termsOfServiceFilePath?: string
55
+ termsOfServiceFilePath?: string,
53
56
  proofOfWorkChallengeNonceSeed?: string,
54
57
  proofOfWorkInitialMaximumAllowedHash?: string,
58
+ providerAuthPlugin?: ProviderAuthPlugin,
55
59
  }): Promise<RegistrationManager> {
56
60
  const { termsOfServiceFilePath, registrationStoreUrl } = input;
57
61
 
@@ -70,17 +74,22 @@ export class RegistrationManager implements TenantGate {
70
74
 
71
75
  // Initialize and start ProofOfWorkManager.
72
76
  registrationManager.proofOfWorkManager = await ProofOfWorkManager.create({
73
- autoStart: true,
74
- desiredSolveCountPerMinute: 10,
75
- initialMaximumAllowedHashValue: input.proofOfWorkInitialMaximumAllowedHash,
76
- challengeSeed: input.proofOfWorkChallengeNonceSeed,
77
+ autoStart : true,
78
+ desiredSolveCountPerMinute : 10,
79
+ initialMaximumAllowedHashValue : input.proofOfWorkInitialMaximumAllowedHash,
80
+ challengeSeed : input.proofOfWorkChallengeNonceSeed,
77
81
  });
78
82
 
79
83
  // Initialize RegistrationStore.
80
84
  const sqlDialect = getDialectFromUrl(new URL(registrationStoreUrl));
81
85
  const registrationStore = await RegistrationStore.create(sqlDialect);
82
86
  registrationManager.registrationStore = registrationStore;
83
-
87
+
88
+ // Store optional provider auth plugin.
89
+ if (input.providerAuthPlugin !== undefined) {
90
+ registrationManager.providerAuthPlugin = input.providerAuthPlugin;
91
+ }
92
+
84
93
  return registrationManager;
85
94
  }
86
95
 
@@ -93,17 +102,79 @@ export class RegistrationManager implements TenantGate {
93
102
  }
94
103
 
95
104
  /**
96
- * Handles a registration request.
105
+ * Handles a registration request by dispatching to the appropriate handler
106
+ * based on the credentials provided.
97
107
  */
98
108
  public async handleRegistrationRequest(registrationRequest: RegistrationRequest): Promise<void> {
99
- // Ensure the supplied terms of service hash matches the one we require.
100
- if (registrationRequest.registrationData.termsOfServiceHash !== this.termsOfServiceHash) {
101
- throw new DwnServerError(DwnServerErrorCode.RegistrationManagerInvalidOrOutdatedTermsOfServiceHash,
102
- `Expecting terms-of-service hash ${this.termsOfServiceHash}, but got ${registrationRequest.registrationData.termsOfServiceHash}.`
109
+ if (registrationRequest.providerAuth?.registrationToken !== undefined) {
110
+ await this.handleProviderAuthRegistration(registrationRequest);
111
+ } else if (registrationRequest.proofOfWork !== undefined) {
112
+ await this.handleProofOfWorkRegistration(registrationRequest);
113
+ } else {
114
+ throw new DwnServerError(
115
+ DwnServerErrorCode.RegistrationRequestMissingCredentials,
116
+ 'Registration request must include either providerAuth or proofOfWork credentials.',
103
117
  );
104
118
  }
119
+ }
105
120
 
106
- const { challengeNonce, responseNonce } = registrationRequest.proofOfWork;
121
+ /**
122
+ * Handles a provider-auth registration request.
123
+ */
124
+ private async handleProviderAuthRegistration(registrationRequest: RegistrationRequest): Promise<void> {
125
+ if (this.providerAuthPlugin === undefined) {
126
+ throw new DwnServerError(
127
+ DwnServerErrorCode.ProviderAuthNotEnabled,
128
+ 'Provider auth registration is not enabled on this server.',
129
+ );
130
+ }
131
+
132
+ const token = registrationRequest.providerAuth!.registrationToken;
133
+ const validationResult = await this.providerAuthPlugin.validateRegistrationToken(token);
134
+
135
+ if (!validationResult.isValid) {
136
+ throw new DwnServerError(
137
+ DwnServerErrorCode.ProviderAuthTokenInvalid,
138
+ validationResult.detail ?? 'Provider auth registration token is invalid.',
139
+ );
140
+ }
141
+
142
+ // Validate ToS only when the server has ToS configured AND the request includes a hash.
143
+ if (this.termsOfServiceHash !== undefined && registrationRequest.registrationData.termsOfServiceHash !== undefined) {
144
+ if (registrationRequest.registrationData.termsOfServiceHash !== this.termsOfServiceHash) {
145
+ throw new DwnServerError(DwnServerErrorCode.RegistrationManagerInvalidOrOutdatedTermsOfServiceHash,
146
+ `Expecting terms-of-service hash ${this.termsOfServiceHash}, ` +
147
+ `but got ${registrationRequest.registrationData.termsOfServiceHash}.`,
148
+ );
149
+ }
150
+ }
151
+
152
+ await this.registrationStore.insertOrUpdateTenantRegistration({
153
+ did : registrationRequest.registrationData.did,
154
+ termsOfServiceHash : registrationRequest.registrationData.termsOfServiceHash,
155
+ accountId : validationResult.accountId,
156
+ registrationType : 'provider-auth',
157
+ metadata : validationResult.metadata !== undefined
158
+ ? JSON.stringify(validationResult.metadata)
159
+ : undefined,
160
+ });
161
+ }
162
+
163
+ /**
164
+ * Handles a proof-of-work registration request.
165
+ */
166
+ private async handleProofOfWorkRegistration(registrationRequest: RegistrationRequest): Promise<void> {
167
+ // Validate ToS only when the server has ToS configured.
168
+ if (this.termsOfServiceHash !== undefined) {
169
+ if (registrationRequest.registrationData.termsOfServiceHash !== this.termsOfServiceHash) {
170
+ throw new DwnServerError(DwnServerErrorCode.RegistrationManagerInvalidOrOutdatedTermsOfServiceHash,
171
+ `Expecting terms-of-service hash ${this.termsOfServiceHash}, ` +
172
+ `but got ${registrationRequest.registrationData.termsOfServiceHash}.`,
173
+ );
174
+ }
175
+ }
176
+
177
+ const { challengeNonce, responseNonce } = registrationRequest.proofOfWork!;
107
178
 
108
179
  await this.proofOfWorkManager.verifyProofOfWork({
109
180
  challengeNonce,
@@ -112,14 +183,24 @@ export class RegistrationManager implements TenantGate {
112
183
  });
113
184
 
114
185
  // Store tenant registration data in database.
115
- await this.recordTenantRegistration(registrationRequest.registrationData);
186
+ await this.recordTenantRegistration({
187
+ did : registrationRequest.registrationData.did,
188
+ termsOfServiceHash : registrationRequest.registrationData.termsOfServiceHash,
189
+ registrationType : 'proof-of-work',
190
+ });
116
191
  }
117
192
 
118
193
  /**
119
194
  * Records the given registration data in the database.
120
195
  * Exposed as a public method for testing purposes.
121
196
  */
122
- public async recordTenantRegistration(registrationData: RegistrationData): Promise<void> {
197
+ public async recordTenantRegistration(registrationData: {
198
+ did: string;
199
+ termsOfServiceHash?: string;
200
+ accountId?: string;
201
+ registrationType?: string;
202
+ metadata?: string;
203
+ }): Promise<void> {
123
204
  await this.registrationStore.insertOrUpdateTenantRegistration(registrationData);
124
205
  }
125
206
 
@@ -136,18 +217,35 @@ export class RegistrationManager implements TenantGate {
136
217
 
137
218
  if (tenantRegistration === undefined) {
138
219
  return {
139
- isActiveTenant: false,
140
- detail: 'Not a registered tenant.'
220
+ isActiveTenant : false,
221
+ detail : 'Not a registered tenant.'
141
222
  };
142
223
  }
143
224
 
144
- if (tenantRegistration.termsOfServiceHash !== this.termsOfServiceHash) {
225
+ if (tenantRegistration.suspended) {
145
226
  return {
146
- isActiveTenant: false,
147
- detail: 'Agreed terms-of-service is outdated.'
227
+ isActiveTenant : false,
228
+ detail : 'Tenant is suspended.'
148
229
  };
149
230
  }
150
231
 
151
- return { isActiveTenant: true }
232
+ // Only enforce ToS hash check when the server has a ToS configured.
233
+ if (this.termsOfServiceHash !== undefined &&
234
+ tenantRegistration.termsOfServiceHash !== this.termsOfServiceHash) {
235
+ return {
236
+ isActiveTenant : false,
237
+ detail : 'Agreed terms-of-service is outdated.'
238
+ };
239
+ }
240
+
241
+ return { isActiveTenant: true };
242
+ }
243
+
244
+ /**
245
+ * Returns the underlying RegistrationStore, if initialized.
246
+ * Used by the admin API to access tenant data.
247
+ */
248
+ public getRegistrationStore(): RegistrationStore | undefined {
249
+ return this.registrationStore;
152
250
  }
153
251
  }
@@ -1,12 +1,16 @@
1
- import { Kysely } from 'kysely';
2
- import type { RegistrationData } from './registration-types.js';
3
1
  import type { Dialect } from '@enbox/dwn-sql-store';
2
+ import type { TenantQuota } from '../admin/types.js';
3
+
4
+ import { Kysely, sql } from 'kysely';
5
+
6
+ import { escapeLikeWildcards } from '../lib/sql-utils.js';
4
7
 
5
8
  /**
6
9
  * The RegistrationStore is responsible for storing and retrieving tenant registration information.
7
10
  */
8
11
  export class RegistrationStore {
9
12
  private static readonly registeredTenantTableName = 'registeredTenants';
13
+ private static readonly tenantQuotasTableName = 'tenantQuotas';
10
14
 
11
15
  private db: Kysely<RegistrationDatabase>;
12
16
 
@@ -18,46 +22,114 @@ export class RegistrationStore {
18
22
  * Creates a new RegistrationStore instance.
19
23
  */
20
24
  public static async create(sqlDialect: Dialect): Promise<RegistrationStore> {
21
- const proofOfWorkManager = new RegistrationStore(sqlDialect);
25
+ const store = new RegistrationStore(sqlDialect);
22
26
 
23
- await proofOfWorkManager.initialize();
27
+ await store.initialize();
24
28
 
25
- return proofOfWorkManager;
29
+ return store;
26
30
  }
27
31
 
28
32
  private async initialize(): Promise<void> {
29
33
  await this.db.schema
30
- .createTable(RegistrationStore.registeredTenantTableName)
31
- .ifNotExists()
32
- .addColumn('did', 'text', (column) => column.primaryKey())
33
- .addColumn('termsOfServiceHash', 'text')
34
- .execute();
34
+ .createTable(RegistrationStore.registeredTenantTableName)
35
+ .ifNotExists()
36
+ .addColumn('did', 'text', (column) => column.primaryKey())
37
+ .addColumn('termsOfServiceHash', 'text')
38
+ .addColumn('suspended', 'integer', (column) => column.defaultTo(0))
39
+ .execute();
40
+
41
+ // Add the `suspended` column to existing tables that don't have it yet.
42
+ // Kysely doesn't support `ADD COLUMN IF NOT EXISTS` across all dialects, so we
43
+ // catch and ignore the "column already exists" error.
44
+ try {
45
+ await this.db.schema
46
+ .alterTable(RegistrationStore.registeredTenantTableName)
47
+ .addColumn('suspended', 'integer', (column) => column.defaultTo(0))
48
+ .execute();
49
+ } catch {
50
+ // Column already exists — expected for new installations.
51
+ }
52
+
53
+ // Add provider-auth columns (idempotent migration). https://github.com/enboxorg/enbox/issues/404
54
+ for (const col of ['accountId', 'registrationType', 'registeredAt', 'metadata']) {
55
+ try {
56
+ await this.db.schema
57
+ .alterTable(RegistrationStore.registeredTenantTableName)
58
+ .addColumn(col, 'text')
59
+ .execute();
60
+ } catch {
61
+ // Column already exists — expected.
62
+ }
63
+ }
64
+
65
+ // Per-tenant storage quotas table.
66
+ await this.db.schema
67
+ .createTable(RegistrationStore.tenantQuotasTableName)
68
+ .ifNotExists()
69
+ .addColumn('did', 'text', (column) => column.primaryKey())
70
+ .addColumn('maxMessages', 'integer', (column) => column.defaultTo(0))
71
+ .addColumn('maxStorageBytes', 'bigint', (column) => column.defaultTo(0))
72
+ .execute();
35
73
  }
36
74
 
37
75
  /**
38
76
  * Inserts or updates the tenant registration information.
39
77
  */
40
- public async insertOrUpdateTenantRegistration(registrationData: RegistrationData): Promise<void> {
78
+ public async insertOrUpdateTenantRegistration(registrationData: {
79
+ did: string;
80
+ termsOfServiceHash?: string;
81
+ accountId?: string;
82
+ registrationType?: string;
83
+ metadata?: string;
84
+ }): Promise<void> {
85
+ const insertValues: Record<string, unknown> = {
86
+ did : registrationData.did,
87
+ termsOfServiceHash : registrationData.termsOfServiceHash ?? '',
88
+ suspended : 0,
89
+ registeredAt : new Date().toISOString(),
90
+ };
91
+
92
+ if (registrationData.accountId !== undefined) {
93
+ insertValues.accountId = registrationData.accountId;
94
+ }
95
+ if (registrationData.registrationType !== undefined) {
96
+ insertValues.registrationType = registrationData.registrationType;
97
+ }
98
+ if (registrationData.metadata !== undefined) {
99
+ insertValues.metadata = registrationData.metadata;
100
+ }
101
+
41
102
  await this.db
42
103
  .insertInto(RegistrationStore.registeredTenantTableName)
43
- .values(registrationData)
104
+ .values(insertValues as any)
44
105
  .onConflict((oc) =>
45
- oc.column('did').doUpdateSet((eb) => ({
46
- termsOfServiceHash: eb.ref('excluded.termsOfServiceHash'),
47
- })),
106
+ oc.column('did').doUpdateSet((eb) => {
107
+ const updateSet: Record<string, any> = {
108
+ termsOfServiceHash: eb.ref('excluded.termsOfServiceHash'),
109
+ };
110
+ // Do NOT overwrite registeredAt on update.
111
+ if (registrationData.accountId !== undefined) {
112
+ updateSet.accountId = registrationData.accountId;
113
+ }
114
+ if (registrationData.registrationType !== undefined) {
115
+ updateSet.registrationType = registrationData.registrationType;
116
+ }
117
+ if (registrationData.metadata !== undefined) {
118
+ updateSet.metadata = registrationData.metadata;
119
+ }
120
+ return updateSet;
121
+ }),
48
122
  )
49
- // Executes the query. No error is thrown if the query doesn’t affect any rows (ie. if the insert or update didn’t change anything).
50
123
  .executeTakeFirst();
51
124
  }
52
125
 
53
126
  /**
54
127
  * Retrieves the tenant registration information.
55
128
  */
56
- public async getTenantRegistration(tenantDid: string): Promise<RegistrationData | undefined> {
129
+ public async getTenantRegistration(tenantDid: string): Promise<RegisteredTenantRow | undefined> {
57
130
  const result = await this.db
58
131
  .selectFrom(RegistrationStore.registeredTenantTableName)
59
- .select('did')
60
- .select('termsOfServiceHash')
132
+ .select(['did', 'termsOfServiceHash', 'suspended', 'accountId', 'registrationType', 'registeredAt', 'metadata'])
61
133
  .where('did', '=', tenantDid)
62
134
  .execute();
63
135
 
@@ -67,13 +139,251 @@ export class RegistrationStore {
67
139
 
68
140
  return result[0];
69
141
  }
142
+
143
+ // ---------------------------------------------------------------------------
144
+ // Admin operations
145
+ // ---------------------------------------------------------------------------
146
+
147
+ /**
148
+ * Returns a paginated list of registered tenants with optional search and status filtering.
149
+ *
150
+ * @see https://github.com/enboxorg/enbox/issues/390
151
+ */
152
+ public async listTenants(options?: {
153
+ cursor? : string;
154
+ limit? : number;
155
+ search? : string;
156
+ status? : 'active' | 'suspended';
157
+ }): Promise<{ tenants: RegisteredTenantRow[]; cursor?: string }> {
158
+ const limit = options?.limit ?? 20;
159
+
160
+ let query = this.db
161
+ .selectFrom(RegistrationStore.registeredTenantTableName)
162
+ .select(['did', 'termsOfServiceHash', 'suspended', 'accountId', 'registrationType', 'registeredAt', 'metadata'])
163
+ .orderBy('did', 'asc')
164
+ .limit(limit + 1); // fetch one extra to detect next page
165
+
166
+ if (options?.cursor) {
167
+ query = query.where('did', '>', options.cursor);
168
+ }
169
+
170
+ if (options?.search) {
171
+ query = query.where('did', 'like', `%${escapeLikeWildcards(options.search)}%`);
172
+ }
173
+
174
+ if (options?.status === 'suspended') {
175
+ query = query.where('suspended', '=', 1);
176
+ } else if (options?.status === 'active') {
177
+ query = query.where('suspended', '=', 0);
178
+ }
179
+
180
+ const results = await query.execute();
181
+
182
+ let cursor: string | undefined;
183
+ if (results.length > limit) {
184
+ results.pop();
185
+ cursor = results[results.length - 1].did;
186
+ }
187
+
188
+ return { tenants: results, cursor };
189
+ }
190
+
191
+ /**
192
+ * Returns the total count of registered tenants matching optional filters.
193
+ */
194
+ public async getTenantCount(options?: {
195
+ search? : string;
196
+ status? : 'active' | 'suspended';
197
+ }): Promise<number> {
198
+ let query = this.db
199
+ .selectFrom(RegistrationStore.registeredTenantTableName)
200
+ .select(sql<number>`count(*)`.as('count'));
201
+
202
+ if (options?.search) {
203
+ query = query.where('did', 'like', `%${escapeLikeWildcards(options.search)}%`);
204
+ }
205
+
206
+ if (options?.status === 'suspended') {
207
+ query = query.where('suspended', '=', 1);
208
+ } else if (options?.status === 'active') {
209
+ query = query.where('suspended', '=', 0);
210
+ }
211
+
212
+ const result = await query.executeTakeFirstOrThrow();
213
+ return Number(result.count);
214
+ }
215
+
216
+ /**
217
+ * Inserts a new tenant registration. Returns `false` if the tenant already exists.
218
+ *
219
+ * @see https://github.com/enboxorg/enbox/issues/393
220
+ */
221
+ public async createTenant(did: string): Promise<boolean> {
222
+ try {
223
+ await this.db
224
+ .insertInto(RegistrationStore.registeredTenantTableName)
225
+ .values({ did, termsOfServiceHash: '', suspended: 0 })
226
+ .execute();
227
+ return true;
228
+ } catch {
229
+ // Unique constraint violation — tenant already exists.
230
+ return false;
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Suspends a tenant. Returns `true` if the tenant was found and suspended.
236
+ */
237
+ public async suspendTenant(did: string): Promise<boolean> {
238
+ const result = await this.db
239
+ .updateTable(RegistrationStore.registeredTenantTableName)
240
+ .set({ suspended: 1 })
241
+ .where('did', '=', did)
242
+ .executeTakeFirst();
243
+
244
+ return Number(result.numUpdatedRows) > 0;
245
+ }
246
+
247
+ /**
248
+ * Unsuspends a tenant. Returns `true` if the tenant was found and unsuspended.
249
+ */
250
+ public async unsuspendTenant(did: string): Promise<boolean> {
251
+ const result = await this.db
252
+ .updateTable(RegistrationStore.registeredTenantTableName)
253
+ .set({ suspended: 0 })
254
+ .where('did', '=', did)
255
+ .executeTakeFirst();
256
+
257
+ return Number(result.numUpdatedRows) > 0;
258
+ }
259
+
260
+ /**
261
+ * Deletes a tenant registration. Returns `true` if the tenant was found and deleted.
262
+ */
263
+ public async deleteTenant(did: string): Promise<boolean> {
264
+ const result = await this.db
265
+ .deleteFrom(RegistrationStore.registeredTenantTableName)
266
+ .where('did', '=', did)
267
+ .executeTakeFirst();
268
+
269
+ return Number(result.numDeletedRows) > 0;
270
+ }
271
+
272
+ /**
273
+ * Returns all tenant registrations associated with the given account ID.
274
+ *
275
+ * @see https://github.com/enboxorg/enbox/issues/404
276
+ */
277
+ public async getTenantsForAccount(accountId: string): Promise<RegisteredTenantRow[]> {
278
+ return this.db
279
+ .selectFrom(RegistrationStore.registeredTenantTableName)
280
+ .select(['did', 'termsOfServiceHash', 'suspended', 'accountId', 'registrationType', 'registeredAt', 'metadata'])
281
+ .where('accountId', '=', accountId)
282
+ .orderBy('did', 'asc')
283
+ .execute();
284
+ }
285
+
286
+ /**
287
+ * Returns the count of suspended tenants.
288
+ */
289
+ public async getSuspendedCount(): Promise<number> {
290
+ const result = await this.db
291
+ .selectFrom(RegistrationStore.registeredTenantTableName)
292
+ .select(sql<number>`count(*)`.as('count'))
293
+ .where('suspended', '=', 1)
294
+ .executeTakeFirstOrThrow();
295
+
296
+ return Number(result.count);
297
+ }
298
+
299
+ // ---------------------------------------------------------------------------
300
+ // Tenant quota operations
301
+ // ---------------------------------------------------------------------------
302
+
303
+ /**
304
+ * Returns the quota for a tenant, or `undefined` if no per-tenant quota is set.
305
+ */
306
+ public async getQuota(did: string): Promise<TenantQuota | undefined> {
307
+ const result = await this.db
308
+ .selectFrom(RegistrationStore.tenantQuotasTableName)
309
+ .select(['did', 'maxMessages', 'maxStorageBytes'])
310
+ .where('did', '=', did)
311
+ .executeTakeFirst();
312
+
313
+ if (result === undefined) {
314
+ return undefined;
315
+ }
316
+
317
+ return {
318
+ did : result.did,
319
+ maxMessages : Number(result.maxMessages),
320
+ maxStorageBytes : Number(result.maxStorageBytes),
321
+ };
322
+ }
323
+
324
+ /**
325
+ * Sets (inserts or updates) the quota for a tenant.
326
+ */
327
+ public async setQuota(quota: TenantQuota): Promise<void> {
328
+ await this.db
329
+ .insertInto(RegistrationStore.tenantQuotasTableName)
330
+ .values({
331
+ did : quota.did,
332
+ maxMessages : quota.maxMessages,
333
+ maxStorageBytes : quota.maxStorageBytes,
334
+ })
335
+ .onConflict((oc) =>
336
+ oc.column('did').doUpdateSet({
337
+ maxMessages : quota.maxMessages,
338
+ maxStorageBytes : quota.maxStorageBytes,
339
+ }),
340
+ )
341
+ .executeTakeFirst();
342
+ }
343
+
344
+ /**
345
+ * Deletes the per-tenant quota. Returns `true` if a quota existed and was deleted.
346
+ */
347
+ public async deleteQuota(did: string): Promise<boolean> {
348
+ const result = await this.db
349
+ .deleteFrom(RegistrationStore.tenantQuotasTableName)
350
+ .where('did', '=', did)
351
+ .executeTakeFirst();
352
+
353
+ return Number(result.numDeletedRows) > 0;
354
+ }
355
+ }
356
+
357
+ /**
358
+ * A row in the `registeredTenants` table.
359
+ */
360
+ export interface RegisteredTenantRow {
361
+ did : string;
362
+ termsOfServiceHash : string;
363
+ suspended? : number;
364
+ accountId? : string;
365
+ registrationType? : string;
366
+ registeredAt? : string;
367
+ metadata? : string;
70
368
  }
71
369
 
72
370
  interface RegisteredTenants {
73
- did: string;
74
- termsOfServiceHash: string;
371
+ did : string;
372
+ termsOfServiceHash : string;
373
+ suspended : number;
374
+ accountId? : string;
375
+ registrationType? : string;
376
+ registeredAt? : string;
377
+ metadata? : string;
378
+ }
379
+
380
+ interface TenantQuotasRow {
381
+ did : string;
382
+ maxMessages : number;
383
+ maxStorageBytes : number;
75
384
  }
76
385
 
77
386
  interface RegistrationDatabase {
78
- registeredTenants: RegisteredTenants;
387
+ registeredTenants : RegisteredTenants;
388
+ tenantQuotas : TenantQuotasRow;
79
389
  }