@enbox/dwn-server 0.0.3 → 0.0.5

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 (295) hide show
  1. package/LICENSE +3 -2
  2. package/README.md +112 -212
  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 +122 -3
  36. package/dist/esm/src/config.d.ts.map +1 -1
  37. package/dist/esm/src/config.js +151 -5
  38. package/dist/esm/src/config.js.map +1 -1
  39. package/dist/esm/src/connection/connection-manager.d.ts +24 -1
  40. package/dist/esm/src/connection/connection-manager.d.ts.map +1 -1
  41. package/dist/esm/src/connection/connection-manager.js +33 -2
  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 +39 -4
  48. package/dist/esm/src/connection/socket-connection.d.ts.map +1 -1
  49. package/dist/esm/src/connection/socket-connection.js +80 -9
  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 +8 -0
  60. package/dist/esm/src/dwn-server.d.ts.map +1 -1
  61. package/dist/esm/src/dwn-server.js +198 -12
  62. package/dist/esm/src/dwn-server.js.map +1 -1
  63. package/dist/esm/src/http-api.d.ts +19 -2
  64. package/dist/esm/src/http-api.d.ts.map +1 -1
  65. package/dist/esm/src/http-api.js +219 -19
  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 +106 -4
  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 +22 -4
  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 +13 -1
  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/provider-auth-plugin.d.ts +46 -0
  123. package/dist/esm/src/registration/provider-auth-plugin.d.ts.map +1 -0
  124. package/dist/esm/src/registration/provider-auth-plugin.js +29 -0
  125. package/dist/esm/src/registration/provider-auth-plugin.js.map +1 -0
  126. package/dist/esm/src/registration/registration-manager.d.ts +27 -4
  127. package/dist/esm/src/registration/registration-manager.d.ts.map +1 -1
  128. package/dist/esm/src/registration/registration-manager.js +77 -6
  129. package/dist/esm/src/registration/registration-manager.js.map +1 -1
  130. package/dist/esm/src/registration/registration-store.d.ts +83 -3
  131. package/dist/esm/src/registration/registration-store.d.ts.map +1 -1
  132. package/dist/esm/src/registration/registration-store.js +248 -11
  133. package/dist/esm/src/registration/registration-store.js.map +1 -1
  134. package/dist/esm/src/storage.d.ts +4 -4
  135. package/dist/esm/src/storage.d.ts.map +1 -1
  136. package/dist/esm/src/storage.js +100 -20
  137. package/dist/esm/src/storage.js.map +1 -1
  138. package/dist/esm/src/web5-connect/sql-ttl-cache.d.ts.map +1 -1
  139. package/dist/esm/src/web5-connect/sql-ttl-cache.js +8 -1
  140. package/dist/esm/src/web5-connect/sql-ttl-cache.js.map +1 -1
  141. package/dist/esm/src/ws-api.d.ts +17 -1
  142. package/dist/esm/src/ws-api.d.ts.map +1 -1
  143. package/dist/esm/src/ws-api.js +9 -2
  144. package/dist/esm/src/ws-api.js.map +1 -1
  145. package/package.json +18 -16
  146. package/src/admin/activity-log.ts +100 -0
  147. package/src/admin/admin-api.ts +1308 -0
  148. package/src/admin/admin-auth.ts +56 -0
  149. package/src/admin/admin-store.ts +515 -0
  150. package/src/admin/audit-log.ts +327 -0
  151. package/src/admin/index.ts +34 -0
  152. package/src/admin/types.ts +352 -0
  153. package/src/admin/webhook-manager.ts +245 -0
  154. package/src/config.ts +177 -5
  155. package/src/connection/connection-manager.ts +50 -6
  156. package/src/connection/flow-controller.ts +117 -0
  157. package/src/connection/socket-connection.ts +103 -21
  158. package/src/delivery-service.ts +740 -0
  159. package/src/dwn-error.ts +9 -0
  160. package/src/dwn-server.ts +242 -14
  161. package/src/http-api.ts +271 -30
  162. package/src/index.ts +13 -2
  163. package/src/json-rpc-api.ts +2 -1
  164. package/src/json-rpc-handlers/dwn/process-message.ts +140 -5
  165. package/src/json-rpc-handlers/subscription/ack.ts +63 -0
  166. package/src/json-rpc-handlers/subscription/close.ts +2 -6
  167. package/src/json-rpc-handlers/subscription/index.ts +1 -0
  168. package/src/lib/json-rpc-router.ts +22 -6
  169. package/src/lib/sql-utils.ts +7 -0
  170. package/src/main.ts +0 -8
  171. package/src/message-processed-hook.ts +33 -0
  172. package/src/metrics.ts +50 -1
  173. package/src/plugins/event-log-nats.ts +466 -0
  174. package/src/rate-limiter.ts +143 -0
  175. package/src/registration/jwt-provider-auth-plugin.ts +119 -0
  176. package/src/registration/open-auth-handler.ts +263 -0
  177. package/src/registration/proof-of-work-manager.ts +1 -1
  178. package/src/registration/provider-auth-plugin.ts +84 -0
  179. package/src/registration/registration-manager.ts +108 -12
  180. package/src/registration/registration-store.ts +326 -17
  181. package/src/storage.ts +121 -27
  182. package/src/web5-connect/sql-ttl-cache.ts +7 -1
  183. package/src/ws-api.ts +30 -2
  184. package/dist/esm/src/json-rpc-socket.d.ts +0 -39
  185. package/dist/esm/src/json-rpc-socket.d.ts.map +0 -1
  186. package/dist/esm/src/json-rpc-socket.js +0 -125
  187. package/dist/esm/src/json-rpc-socket.js.map +0 -1
  188. package/dist/esm/src/lib/json-rpc.d.ts +0 -54
  189. package/dist/esm/src/lib/json-rpc.d.ts.map +0 -1
  190. package/dist/esm/src/lib/json-rpc.js +0 -60
  191. package/dist/esm/src/lib/json-rpc.js.map +0 -1
  192. package/dist/esm/src/registration/proof-of-work-types.d.ts +0 -8
  193. package/dist/esm/src/registration/proof-of-work-types.d.ts.map +0 -1
  194. package/dist/esm/src/registration/proof-of-work-types.js +0 -2
  195. package/dist/esm/src/registration/proof-of-work-types.js.map +0 -1
  196. package/dist/esm/src/registration/registration-types.d.ts +0 -18
  197. package/dist/esm/src/registration/registration-types.d.ts.map +0 -1
  198. package/dist/esm/src/registration/registration-types.js +0 -2
  199. package/dist/esm/src/registration/registration-types.js.map +0 -1
  200. package/dist/esm/tests/common-scenario-validator.d.ts +0 -11
  201. package/dist/esm/tests/common-scenario-validator.d.ts.map +0 -1
  202. package/dist/esm/tests/common-scenario-validator.js +0 -113
  203. package/dist/esm/tests/common-scenario-validator.js.map +0 -1
  204. package/dist/esm/tests/connection/connection-manager.spec.d.ts +0 -2
  205. package/dist/esm/tests/connection/connection-manager.spec.d.ts.map +0 -1
  206. package/dist/esm/tests/connection/connection-manager.spec.js +0 -49
  207. package/dist/esm/tests/connection/connection-manager.spec.js.map +0 -1
  208. package/dist/esm/tests/connection/socket-connection.spec.d.ts +0 -2
  209. package/dist/esm/tests/connection/socket-connection.spec.d.ts.map +0 -1
  210. package/dist/esm/tests/connection/socket-connection.spec.js +0 -147
  211. package/dist/esm/tests/connection/socket-connection.spec.js.map +0 -1
  212. package/dist/esm/tests/cors/http-api.browser.d.ts +0 -2
  213. package/dist/esm/tests/cors/http-api.browser.d.ts.map +0 -1
  214. package/dist/esm/tests/cors/http-api.browser.js +0 -60
  215. package/dist/esm/tests/cors/http-api.browser.js.map +0 -1
  216. package/dist/esm/tests/cors/ping.browser.d.ts +0 -2
  217. package/dist/esm/tests/cors/ping.browser.d.ts.map +0 -1
  218. package/dist/esm/tests/cors/ping.browser.js +0 -7
  219. package/dist/esm/tests/cors/ping.browser.js.map +0 -1
  220. package/dist/esm/tests/dwn-process-message.spec.d.ts +0 -2
  221. package/dist/esm/tests/dwn-process-message.spec.d.ts.map +0 -1
  222. package/dist/esm/tests/dwn-process-message.spec.js +0 -172
  223. package/dist/esm/tests/dwn-process-message.spec.js.map +0 -1
  224. package/dist/esm/tests/dwn-server.spec.d.ts +0 -2
  225. package/dist/esm/tests/dwn-server.spec.d.ts.map +0 -1
  226. package/dist/esm/tests/dwn-server.spec.js +0 -48
  227. package/dist/esm/tests/dwn-server.spec.js.map +0 -1
  228. package/dist/esm/tests/http-api.spec.d.ts +0 -2
  229. package/dist/esm/tests/http-api.spec.d.ts.map +0 -1
  230. package/dist/esm/tests/http-api.spec.js +0 -782
  231. package/dist/esm/tests/http-api.spec.js.map +0 -1
  232. package/dist/esm/tests/json-rpc-socket.spec.d.ts +0 -2
  233. package/dist/esm/tests/json-rpc-socket.spec.d.ts.map +0 -1
  234. package/dist/esm/tests/json-rpc-socket.spec.js +0 -227
  235. package/dist/esm/tests/json-rpc-socket.spec.js.map +0 -1
  236. package/dist/esm/tests/plugins/data-store-sqlite.d.ts +0 -17
  237. package/dist/esm/tests/plugins/data-store-sqlite.d.ts.map +0 -1
  238. package/dist/esm/tests/plugins/data-store-sqlite.js +0 -23
  239. package/dist/esm/tests/plugins/data-store-sqlite.js.map +0 -1
  240. package/dist/esm/tests/plugins/event-log-sqlite.d.ts +0 -17
  241. package/dist/esm/tests/plugins/event-log-sqlite.d.ts.map +0 -1
  242. package/dist/esm/tests/plugins/event-log-sqlite.js +0 -23
  243. package/dist/esm/tests/plugins/event-log-sqlite.js.map +0 -1
  244. package/dist/esm/tests/plugins/event-stream-in-memory.d.ts +0 -17
  245. package/dist/esm/tests/plugins/event-stream-in-memory.d.ts.map +0 -1
  246. package/dist/esm/tests/plugins/event-stream-in-memory.js +0 -21
  247. package/dist/esm/tests/plugins/event-stream-in-memory.js.map +0 -1
  248. package/dist/esm/tests/plugins/message-store-sqlite.d.ts +0 -17
  249. package/dist/esm/tests/plugins/message-store-sqlite.d.ts.map +0 -1
  250. package/dist/esm/tests/plugins/message-store-sqlite.js +0 -23
  251. package/dist/esm/tests/plugins/message-store-sqlite.js.map +0 -1
  252. package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts +0 -17
  253. package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts.map +0 -1
  254. package/dist/esm/tests/plugins/resumable-task-store-sqlite.js +0 -23
  255. package/dist/esm/tests/plugins/resumable-task-store-sqlite.js.map +0 -1
  256. package/dist/esm/tests/process-handler.spec.d.ts +0 -2
  257. package/dist/esm/tests/process-handler.spec.d.ts.map +0 -1
  258. package/dist/esm/tests/process-handler.spec.js +0 -60
  259. package/dist/esm/tests/process-handler.spec.js.map +0 -1
  260. package/dist/esm/tests/registration/proof-of-work-manager.spec.d.ts +0 -2
  261. package/dist/esm/tests/registration/proof-of-work-manager.spec.d.ts.map +0 -1
  262. package/dist/esm/tests/registration/proof-of-work-manager.spec.js +0 -156
  263. package/dist/esm/tests/registration/proof-of-work-manager.spec.js.map +0 -1
  264. package/dist/esm/tests/rpc-subscribe-close.spec.d.ts +0 -2
  265. package/dist/esm/tests/rpc-subscribe-close.spec.d.ts.map +0 -1
  266. package/dist/esm/tests/rpc-subscribe-close.spec.js +0 -81
  267. package/dist/esm/tests/rpc-subscribe-close.spec.js.map +0 -1
  268. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.d.ts +0 -2
  269. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.d.ts.map +0 -1
  270. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js +0 -74
  271. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js.map +0 -1
  272. package/dist/esm/tests/scenarios/registration.spec.d.ts +0 -2
  273. package/dist/esm/tests/scenarios/registration.spec.d.ts.map +0 -1
  274. package/dist/esm/tests/scenarios/registration.spec.js +0 -511
  275. package/dist/esm/tests/scenarios/registration.spec.js.map +0 -1
  276. package/dist/esm/tests/scenarios/web5-connect.spec.d.ts +0 -2
  277. package/dist/esm/tests/scenarios/web5-connect.spec.d.ts.map +0 -1
  278. package/dist/esm/tests/scenarios/web5-connect.spec.js +0 -141
  279. package/dist/esm/tests/scenarios/web5-connect.spec.js.map +0 -1
  280. package/dist/esm/tests/test-dwn.d.ts +0 -7
  281. package/dist/esm/tests/test-dwn.d.ts.map +0 -1
  282. package/dist/esm/tests/test-dwn.js +0 -28
  283. package/dist/esm/tests/test-dwn.js.map +0 -1
  284. package/dist/esm/tests/utils.d.ts +0 -43
  285. package/dist/esm/tests/utils.d.ts.map +0 -1
  286. package/dist/esm/tests/utils.js +0 -107
  287. package/dist/esm/tests/utils.js.map +0 -1
  288. package/dist/esm/tests/ws-api.spec.d.ts +0 -2
  289. package/dist/esm/tests/ws-api.spec.d.ts.map +0 -1
  290. package/dist/esm/tests/ws-api.spec.js +0 -332
  291. package/dist/esm/tests/ws-api.spec.js.map +0 -1
  292. package/src/json-rpc-socket.ts +0 -156
  293. package/src/lib/json-rpc.ts +0 -126
  294. package/src/registration/proof-of-work-types.ts +0 -7
  295. package/src/registration/registration-types.ts +0 -18
package/src/dwn-error.ts CHANGED
@@ -33,6 +33,15 @@ export enum DwnServerErrorCode {
33
33
  ProofOfWorkManagerInvalidChallengeNonce = 'ProofOfWorkManagerInvalidChallengeNonce',
34
34
  ProofOfWorkManagerInvalidResponseNonceFormat = 'ProofOfWorkManagerInvalidResponseNonceFormat',
35
35
  ProofOfWorkManagerResponseNonceReused = 'ProofOfWorkManagerResponseNonceReused',
36
+ ProviderAuthNotEnabled = 'ProviderAuthNotEnabled',
37
+ ProviderAuthPluginLoadFailed = 'ProviderAuthPluginLoadFailed',
38
+ ProviderAuthPluginNotConfigured = 'ProviderAuthPluginNotConfigured',
39
+ ProviderAuthTokenInvalid = 'ProviderAuthTokenInvalid',
40
+ RateLimitExceeded = 'RateLimitExceeded',
36
41
  RegistrationManagerInvalidOrOutdatedTermsOfServiceHash = 'RegistrationManagerInvalidOrOutdatedTermsOfServiceHash',
42
+ RegistrationRequestMissingCredentials = 'RegistrationRequestMissingCredentials',
43
+ TenantMessageQuotaExceeded = 'TenantMessageQuotaExceeded',
37
44
  TenantRegistrationOutdatedTermsOfService = 'TenantRegistrationOutdatedTermsOfService',
45
+ TenantStorageQuotaExceeded = 'TenantStorageQuotaExceeded',
46
+ TenantSuspended = 'TenantSuspended',
38
47
  }
package/src/dwn-server.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { DidResolver } from '@enbox/dids';
2
2
  import type { DwnServerConfig } from './config.js';
3
- import type { EventStream } from '@enbox/dwn-sdk-js';
3
+ import type { EventLog } from '@enbox/dwn-sdk-js';
4
+ import type { MessageProcessedHook } from './message-processed-hook.js';
4
5
  import type { ProcessHandlers } from './process-handlers.js';
5
6
  import type { Server } from 'bun';
6
7
 
@@ -8,14 +9,27 @@ import type { WsData } from './http-api.js';
8
9
 
9
10
  import log from 'loglevel';
10
11
  import prefix from 'loglevel-plugin-prefix';
11
- import { Dwn, EventEmitterStream } from '@enbox/dwn-sdk-js';
12
+ import { DidDht, DidJwk, DidKey, DidWeb, UniversalResolver } from '@enbox/dids';
13
+ import { Dwn, EventEmitterEventLog } from '@enbox/dwn-sdk-js';
12
14
 
15
+ import type { ProviderAuthPlugin } from './registration/provider-auth-plugin.js';
16
+
17
+ import { ActivityLog } from './admin/activity-log.js';
18
+ import { AdminApi } from './admin/admin-api.js';
19
+ import { AdminStore } from './admin/admin-store.js';
20
+ import { AuditLog } from './admin/audit-log.js';
13
21
  import { config as defaultConfig } from './config.js';
14
- import { getDwnConfig } from './storage.js';
22
+ import { DeliveryService } from './delivery-service.js';
15
23
  import { HttpApi } from './http-api.js';
24
+ import { JwtProviderAuthPlugin } from './registration/jwt-provider-auth-plugin.js';
25
+ import { loadProviderAuthPlugin } from './registration/provider-auth-plugin.js';
26
+ import { OpenAuthHandler } from './registration/open-auth-handler.js';
16
27
  import { PluginLoader } from './plugin-loader.js';
28
+ import { RateLimiter } from './rate-limiter.js';
17
29
  import { RegistrationManager } from './registration/registration-manager.js';
30
+ import { WebhookManager } from './admin/webhook-manager.js';
18
31
  import { WsApi } from './ws-api.js';
32
+ import { getDialectFromUrl, getDwnConfig } from './storage.js';
19
33
  import { removeProcessHandlers, setProcessHandlers } from './process-handlers.js';
20
34
 
21
35
  /**
@@ -31,6 +45,13 @@ export type DwnServerOptions = {
31
45
  didResolver?: DidResolver;
32
46
  dwn?: Dwn;
33
47
  config?: DwnServerConfig;
48
+ /**
49
+ * Hooks invoked after every `dwn.processMessage()` call.
50
+ * The built-in DeliveryService hook is always prepended automatically
51
+ * when forwarding or delivery is enabled. Additional hooks provided here
52
+ * are appended after the DeliveryService hook.
53
+ */
54
+ messageProcessedHooks?: MessageProcessedHook[];
34
55
  };
35
56
 
36
57
  /**
@@ -54,6 +75,11 @@ export class DwnServer {
54
75
  config: DwnServerConfig;
55
76
  #httpApi: HttpApi;
56
77
  #wsApi: WsApi;
78
+ #adminApi: AdminApi | undefined;
79
+ #ipRateLimiter: RateLimiter | undefined;
80
+ #tenantRateLimiter: RateLimiter | undefined;
81
+ #auditLog: AuditLog | undefined;
82
+ #externalHooks: MessageProcessedHook[];
57
83
 
58
84
  /**
59
85
  * @param options.dwn - Dwn instance to use as an override. Registration endpoint will not be enabled if this is provided.
@@ -63,6 +89,7 @@ export class DwnServer {
63
89
 
64
90
  this.didResolver = options.didResolver;
65
91
  this.dwn = options.dwn;
92
+ this.#externalHooks = options.messageProcessedHooks ?? [];
66
93
 
67
94
  log.setLevel(this.config.logLevel as log.LogLevelDesc);
68
95
 
@@ -91,42 +118,226 @@ export class DwnServer {
91
118
 
92
119
  let registrationManager: RegistrationManager;
93
120
  if (!this.dwn) {
121
+ // Load provider auth plugin if configured.
122
+ let providerAuthPlugin: ProviderAuthPlugin | undefined;
123
+ if (this.config.providerAuthEnabled) {
124
+ if (this.config.providerAuthPluginPath) {
125
+ // Custom external plugin.
126
+ providerAuthPlugin = await loadProviderAuthPlugin(this.config.providerAuthPluginPath);
127
+ log.info('Provider auth plugin loaded from path');
128
+ } else if (this.config.providerAuthJwtSecret || this.config.providerAuthJwtJwksUrl) {
129
+ // Built-in JWT plugin.
130
+ providerAuthPlugin = await JwtProviderAuthPlugin.create({
131
+ secret : this.config.providerAuthJwtSecret,
132
+ jwksUrl : this.config.providerAuthJwtJwksUrl,
133
+ issuer : this.config.baseUrl,
134
+ audience : this.config.baseUrl,
135
+ });
136
+ log.info('Built-in JWT provider auth plugin created');
137
+ }
138
+ }
139
+
94
140
  // undefined registrationStoreUrl is used as a signal that there is no need for tenant registration, DWN is open for all.
95
141
  registrationManager = await RegistrationManager.create({
96
142
  registrationStoreUrl : this.config.registrationStoreUrl,
97
143
  termsOfServiceFilePath : this.config.termsOfServiceFilePath,
98
144
  proofOfWorkChallengeNonceSeed : this.config.registrationProofOfWorkSeed,
99
145
  proofOfWorkInitialMaximumAllowedHash : this.config.registrationProofOfWorkInitialMaxHash,
146
+ providerAuthPlugin,
100
147
  });
101
148
 
102
- let eventStream: EventStream | undefined;
149
+ // Warn if the tenant gate is active but no registration method is enabled.
150
+ // This is almost certainly a misconfiguration — new tenants will be rejected
151
+ // with 401 and have no way to register.
152
+ if (this.config.registrationStoreUrl
153
+ && !this.config.registrationProofOfWorkEnabled
154
+ && !providerAuthPlugin) {
155
+ log.warn(
156
+ '*** WARNING: DWN_REGISTRATION_STORE_URL is set (tenant gate active) but neither ' +
157
+ 'proof-of-work (DWN_REGISTRATION_PROOF_OF_WORK_ENABLED) nor provider auth ' +
158
+ '(DWN_PROVIDER_AUTH_ENABLED + secret/plugin) is configured. ' +
159
+ 'New tenants will be unable to register. ***',
160
+ );
161
+ }
162
+
163
+ let eventLog: EventLog | undefined;
103
164
  if (this.config.webSocketSupport) {
104
- // If Even Stream plugin is not specified, use `EventEmitterStream` implementation as default.
105
- if (this.config.eventStreamPluginPath === undefined || this.config.eventStreamPluginPath === '') {
106
- eventStream = new EventEmitterStream();
165
+ // If EventLog plugin is not specified, use `EventEmitterEventLog` implementation as default.
166
+ if (this.config.eventLogPluginPath === undefined || this.config.eventLogPluginPath === '') {
167
+ eventLog = new EventEmitterEventLog();
107
168
  } else {
108
- eventStream = await PluginLoader.loadPlugin<EventStream>(this.config.eventStreamPluginPath);
169
+ eventLog = await PluginLoader.loadPlugin<EventLog>(this.config.eventLogPluginPath);
109
170
  }
110
171
 
111
172
  }
112
173
 
174
+ // Create a DID resolver explicitly without LevelDB cache. The default
175
+ // Dwn.create() uses DidResolverCacheLevel which requires exclusive file
176
+ // locks and is not managed by the DWN's open()/close() lifecycle. In
177
+ // containerized deployments this causes "Database is not open" errors
178
+ // when the LevelDB lock file persists across restarts or when concurrent
179
+ // async operations (e.g. DeliveryService) race with the deferred open.
180
+ // UniversalResolver defaults to DidResolverCacheNoop when no cache is provided.
181
+ const didResolver = this.didResolver ?? new UniversalResolver({
182
+ didResolvers: [DidDht, DidJwk, DidKey, DidWeb],
183
+ });
184
+
113
185
  const dwnConfig = await getDwnConfig(this.config, {
114
- didResolver : this.didResolver,
115
- tenantGate : registrationManager,
116
- eventStream,
186
+ didResolver,
187
+ tenantGate: registrationManager,
188
+ eventLog,
117
189
  });
118
190
  this.dwn = await Dwn.create(dwnConfig);
119
191
  }
120
192
 
121
- this.#httpApi = await HttpApi.create(this.config, this.dwn, registrationManager);
193
+ // Assemble message-processed hooks.
194
+ const messageProcessedHooks: MessageProcessedHook[] = [];
195
+
196
+ // Add the built-in DeliveryService hook when forwarding or delivery is enabled.
197
+ if (this.config.forwardingEnabled || this.config.deliveryEnabled) {
198
+ const deliveryResolver = this.didResolver ?? new UniversalResolver({
199
+ didResolvers: [DidDht, DidJwk, DidKey, DidWeb],
200
+ });
201
+ const deliveryService = DeliveryService.create(this.dwn, deliveryResolver, this.config);
202
+ messageProcessedHooks.push(deliveryService);
203
+ log.info(`Delivery service enabled (forwarding: ${this.config.forwardingEnabled}, delivery: ${this.config.deliveryEnabled})`);
204
+ }
205
+
206
+ // Append externally provided hooks.
207
+ messageProcessedHooks.push(...this.#externalHooks);
208
+
209
+ // Create rate limiters when configured.
210
+ let ipRateLimiter: RateLimiter | undefined;
211
+ let tenantRateLimiter: RateLimiter | undefined;
212
+
213
+ if (this.config.rateLimitRequestsPerSecond > 0) {
214
+ ipRateLimiter = new RateLimiter({
215
+ refillRate : this.config.rateLimitRequestsPerSecond,
216
+ maxTokens : this.config.rateLimitBurst,
217
+ });
218
+ log.info(`Per-IP rate limiting enabled: ${this.config.rateLimitRequestsPerSecond} req/s, burst ${this.config.rateLimitBurst}`);
219
+ }
220
+
221
+ if (this.config.rateLimitTenantRequestsPerSecond > 0) {
222
+ tenantRateLimiter = new RateLimiter({
223
+ refillRate : this.config.rateLimitTenantRequestsPerSecond,
224
+ maxTokens : this.config.rateLimitTenantBurst,
225
+ });
226
+ log.info(`Per-tenant rate limiting enabled: ${this.config.rateLimitTenantRequestsPerSecond} req/s, burst ${this.config.rateLimitTenantBurst}`);
227
+ }
228
+
229
+ const registrationStore = registrationManager?.getRegistrationStore();
230
+
231
+ // Initialize admin API if an admin token is configured.
232
+ let adminApi: AdminApi | undefined;
233
+ let activityLog: ActivityLog | undefined;
234
+ let adminStore: AdminStore | undefined;
235
+ let auditLog: AuditLog | undefined;
236
+ let webhookManager: WebhookManager | undefined;
237
+
238
+ if (this.config.adminToken) {
239
+ const storageUrl = this.config.messageStore;
240
+ adminStore = AdminStore.create(storageUrl);
241
+ activityLog = new ActivityLog(this.config.adminActivityLogCapacity);
242
+
243
+ // Create the persistent audit log using the registration store's dialect
244
+ // (same DB) or the message store URL as fallback.
245
+ if (this.config.registrationStoreUrl) {
246
+ try {
247
+ const auditDialect = getDialectFromUrl(new URL(this.config.registrationStoreUrl));
248
+ auditLog = await AuditLog.create(auditDialect, {
249
+ maxAgeDays : this.config.auditLogMaxAgeDays,
250
+ maxRows : this.config.auditLogMaxRows,
251
+ });
252
+ } catch (err) {
253
+ log.warn('Failed to create audit log:', err);
254
+ }
255
+ }
256
+
257
+ // Create webhook manager using the same dialect as the audit log.
258
+ if (this.config.registrationStoreUrl) {
259
+ try {
260
+ const webhookDialect = getDialectFromUrl(new URL(this.config.registrationStoreUrl));
261
+ webhookManager = await WebhookManager.create(webhookDialect);
262
+ } catch (err) {
263
+ log.warn('Failed to create webhook manager:', err);
264
+ }
265
+ }
266
+
267
+ adminApi = AdminApi.create({
268
+ config : this.config,
269
+ dwn : this.dwn,
270
+ adminStore,
271
+ registrationManager,
272
+ registrationStore,
273
+ activityLog,
274
+ auditLog,
275
+ ipRateLimiter,
276
+ tenantRateLimiter,
277
+ webhookManager,
278
+ });
279
+
280
+ // Record server start event in audit log.
281
+ if (auditLog) {
282
+ await auditLog.record({ actor: 'system', action: 'server.start' });
283
+ }
284
+
285
+ log.info('Admin API enabled');
286
+ }
287
+
288
+ // Store references for cleanup in stop().
289
+ this.#adminApi = adminApi;
290
+ this.#ipRateLimiter = ipRateLimiter;
291
+ this.#tenantRateLimiter = tenantRateLimiter;
292
+ this.#auditLog = auditLog;
293
+
294
+ // Create open-auth handler if provider auth is enabled with a JWT secret
295
+ // and authorize/token URLs point to this server (or are not set — defaulting to built-in).
296
+ let openAuthHandler: OpenAuthHandler | undefined;
297
+ if (this.config.providerAuthEnabled && this.config.providerAuthJwtSecret && !this.config.providerAuthPluginPath) {
298
+ openAuthHandler = OpenAuthHandler.create(
299
+ this.config.providerAuthJwtSecret,
300
+ this.config.baseUrl,
301
+ );
302
+ log.info('Built-in open-auth endpoints enabled');
303
+
304
+ // Auto-configure authorize/token/refresh URLs if not explicitly set.
305
+ if (!this.config.providerAuthAuthorizeUrl) {
306
+ this.config.providerAuthAuthorizeUrl = `${this.config.baseUrl}/provider-auth/authorize`;
307
+ }
308
+ if (!this.config.providerAuthTokenUrl) {
309
+ this.config.providerAuthTokenUrl = `${this.config.baseUrl}/provider-auth/token`;
310
+ }
311
+ if (!this.config.providerAuthRefreshUrl) {
312
+ this.config.providerAuthRefreshUrl = `${this.config.baseUrl}/provider-auth/refresh`;
313
+ }
314
+ }
315
+
316
+ this.#httpApi = await HttpApi.create(
317
+ this.config, this.dwn, registrationManager, adminApi, activityLog,
318
+ { adminStore, registrationStore, ipRateLimiter, tenantRateLimiter, messageProcessedHooks, openAuthHandler },
319
+ );
122
320
 
123
321
  await this.#httpApi.start(this.config.port);
124
322
  log.info(`HttpServer listening on port ${this.config.port}`);
125
323
 
126
324
  if (this.config.webSocketSupport) {
127
- this.#wsApi = new WsApi(this.#httpApi, this.dwn);
325
+ this.#wsApi = new WsApi(
326
+ this.#httpApi, this.dwn, undefined, this.config.maxInFlight, activityLog,
327
+ { adminStore, registrationStore, config: this.config, tenantRateLimiter, messageProcessedHooks },
328
+ );
128
329
  this.#wsApi.start();
129
330
  log.info('WebSocketServer ready...');
331
+
332
+ // Wire connection manager to admin API for connection counting.
333
+ if (adminApi) {
334
+ adminApi.setConnectionManager(this.#wsApi.connectionManager);
335
+ }
336
+ }
337
+
338
+ // Start periodic Prometheus gauge updates.
339
+ if (adminApi) {
340
+ adminApi.startMetricsUpdater();
130
341
  }
131
342
  }
132
343
 
@@ -138,9 +349,26 @@ export class DwnServer {
138
349
  return;
139
350
  }
140
351
 
352
+ // Stop admin metrics updater and record shutdown audit event.
353
+ if (this.#adminApi) {
354
+ this.#adminApi.stopMetricsUpdater();
355
+ }
356
+ if (this.#auditLog) {
357
+ await this.#auditLog.record({ actor: 'system', action: 'server.stop' });
358
+ await this.#auditLog.close();
359
+ }
360
+
361
+ // Clean up rate limiters (stops their interval timers).
362
+ if (this.#ipRateLimiter) {
363
+ this.#ipRateLimiter.destroy();
364
+ }
365
+ if (this.#tenantRateLimiter) {
366
+ this.#tenantRateLimiter.destroy();
367
+ }
368
+
141
369
  await this.dwn.close();
142
370
 
143
- // close WebSocket server if it was initialized
371
+ // Close WebSocket server if it was initialized.
144
372
  if (this.#wsApi !== undefined) {
145
373
  await this.#wsApi.close();
146
374
  }