@qwickapps/server 1.3.1 → 1.5.0

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 (395) hide show
  1. package/README.md +157 -0
  2. package/dist/core/control-panel.d.ts.map +1 -1
  3. package/dist/core/control-panel.js +114 -0
  4. package/dist/core/control-panel.js.map +1 -1
  5. package/dist/core/types.d.ts +19 -0
  6. package/dist/core/types.d.ts.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +15 -3
  10. package/dist/index.js.map +1 -1
  11. package/dist/plugins/auth/adapter-wrapper.d.ts +47 -0
  12. package/dist/plugins/auth/adapter-wrapper.d.ts.map +1 -0
  13. package/dist/plugins/auth/adapter-wrapper.js +166 -0
  14. package/dist/plugins/auth/adapter-wrapper.js.map +1 -0
  15. package/dist/plugins/auth/adapter-wrapper.test.d.ts +7 -0
  16. package/dist/plugins/auth/adapter-wrapper.test.d.ts.map +1 -0
  17. package/dist/plugins/auth/adapter-wrapper.test.js +303 -0
  18. package/dist/plugins/auth/adapter-wrapper.test.js.map +1 -0
  19. package/dist/plugins/auth/config-store.d.ts +11 -0
  20. package/dist/plugins/auth/config-store.d.ts.map +1 -0
  21. package/dist/plugins/auth/config-store.js +232 -0
  22. package/dist/plugins/auth/config-store.js.map +1 -0
  23. package/dist/plugins/auth/config-store.test.d.ts +7 -0
  24. package/dist/plugins/auth/config-store.test.d.ts.map +1 -0
  25. package/dist/plugins/auth/config-store.test.js +299 -0
  26. package/dist/plugins/auth/config-store.test.js.map +1 -0
  27. package/dist/plugins/auth/env-config.d.ts +51 -1
  28. package/dist/plugins/auth/env-config.d.ts.map +1 -1
  29. package/dist/plugins/auth/env-config.js +640 -7
  30. package/dist/plugins/auth/env-config.js.map +1 -1
  31. package/dist/plugins/auth/index.d.ts +6 -2
  32. package/dist/plugins/auth/index.d.ts.map +1 -1
  33. package/dist/plugins/auth/index.js +5 -1
  34. package/dist/plugins/auth/index.js.map +1 -1
  35. package/dist/plugins/auth/types.d.ts +106 -0
  36. package/dist/plugins/auth/types.d.ts.map +1 -1
  37. package/dist/plugins/bans/bans-plugin.d.ts.map +1 -1
  38. package/dist/plugins/bans/bans-plugin.js +12 -3
  39. package/dist/plugins/bans/bans-plugin.js.map +1 -1
  40. package/dist/plugins/devices/__tests__/devices-plugin.test.d.ts +11 -0
  41. package/dist/plugins/devices/__tests__/devices-plugin.test.d.ts.map +1 -0
  42. package/dist/plugins/devices/__tests__/devices-plugin.test.js +410 -0
  43. package/dist/plugins/devices/__tests__/devices-plugin.test.js.map +1 -0
  44. package/dist/plugins/devices/__tests__/token-utils.test.d.ts +7 -0
  45. package/dist/plugins/devices/__tests__/token-utils.test.d.ts.map +1 -0
  46. package/dist/plugins/devices/__tests__/token-utils.test.js +197 -0
  47. package/dist/plugins/devices/__tests__/token-utils.test.js.map +1 -0
  48. package/dist/plugins/devices/adapters/compute-adapter.d.ts +36 -0
  49. package/dist/plugins/devices/adapters/compute-adapter.d.ts.map +1 -0
  50. package/dist/plugins/devices/adapters/compute-adapter.js +100 -0
  51. package/dist/plugins/devices/adapters/compute-adapter.js.map +1 -0
  52. package/dist/plugins/devices/adapters/index.d.ts +12 -0
  53. package/dist/plugins/devices/adapters/index.d.ts.map +1 -0
  54. package/dist/plugins/devices/adapters/index.js +10 -0
  55. package/dist/plugins/devices/adapters/index.js.map +1 -0
  56. package/dist/plugins/devices/adapters/mobile-adapter.d.ts +41 -0
  57. package/dist/plugins/devices/adapters/mobile-adapter.d.ts.map +1 -0
  58. package/dist/plugins/devices/adapters/mobile-adapter.js +131 -0
  59. package/dist/plugins/devices/adapters/mobile-adapter.js.map +1 -0
  60. package/dist/plugins/devices/devices-plugin.d.ts +70 -0
  61. package/dist/plugins/devices/devices-plugin.d.ts.map +1 -0
  62. package/dist/plugins/devices/devices-plugin.js +453 -0
  63. package/dist/plugins/devices/devices-plugin.js.map +1 -0
  64. package/dist/plugins/devices/index.d.ts +18 -0
  65. package/dist/plugins/devices/index.d.ts.map +1 -0
  66. package/dist/plugins/devices/index.js +18 -0
  67. package/dist/plugins/devices/index.js.map +1 -0
  68. package/dist/plugins/devices/stores/index.d.ts +9 -0
  69. package/dist/plugins/devices/stores/index.d.ts.map +1 -0
  70. package/dist/plugins/devices/stores/index.js +9 -0
  71. package/dist/plugins/devices/stores/index.js.map +1 -0
  72. package/dist/plugins/devices/stores/postgres-store.d.ts +26 -0
  73. package/dist/plugins/devices/stores/postgres-store.d.ts.map +1 -0
  74. package/dist/plugins/devices/stores/postgres-store.js +199 -0
  75. package/dist/plugins/devices/stores/postgres-store.js.map +1 -0
  76. package/dist/plugins/devices/token-utils.d.ts +100 -0
  77. package/dist/plugins/devices/token-utils.d.ts.map +1 -0
  78. package/dist/plugins/devices/token-utils.js +162 -0
  79. package/dist/plugins/devices/token-utils.js.map +1 -0
  80. package/dist/plugins/devices/types.d.ts +307 -0
  81. package/dist/plugins/devices/types.d.ts.map +1 -0
  82. package/dist/plugins/devices/types.js +10 -0
  83. package/dist/plugins/devices/types.js.map +1 -0
  84. package/dist/plugins/index.d.ts +18 -4
  85. package/dist/plugins/index.d.ts.map +1 -1
  86. package/dist/plugins/index.js +16 -2
  87. package/dist/plugins/index.js.map +1 -1
  88. package/dist/plugins/notifications/__tests__/notifications-manager.test.d.ts +5 -0
  89. package/dist/plugins/notifications/__tests__/notifications-manager.test.d.ts.map +1 -0
  90. package/dist/plugins/notifications/__tests__/notifications-manager.test.js +470 -0
  91. package/dist/plugins/notifications/__tests__/notifications-manager.test.js.map +1 -0
  92. package/dist/plugins/notifications/index.d.ts +71 -0
  93. package/dist/plugins/notifications/index.d.ts.map +1 -0
  94. package/dist/plugins/notifications/index.js +72 -0
  95. package/dist/plugins/notifications/index.js.map +1 -0
  96. package/dist/plugins/notifications/notifications-manager.d.ts +182 -0
  97. package/dist/plugins/notifications/notifications-manager.d.ts.map +1 -0
  98. package/dist/plugins/notifications/notifications-manager.js +610 -0
  99. package/dist/plugins/notifications/notifications-manager.js.map +1 -0
  100. package/dist/plugins/notifications/notifications-plugin.d.ts +83 -0
  101. package/dist/plugins/notifications/notifications-plugin.d.ts.map +1 -0
  102. package/dist/plugins/notifications/notifications-plugin.js +337 -0
  103. package/dist/plugins/notifications/notifications-plugin.js.map +1 -0
  104. package/dist/plugins/notifications/types.d.ts +164 -0
  105. package/dist/plugins/notifications/types.d.ts.map +1 -0
  106. package/dist/plugins/notifications/types.js +9 -0
  107. package/dist/plugins/notifications/types.js.map +1 -0
  108. package/dist/plugins/parental/__tests__/parental-plugin.test.d.ts +12 -0
  109. package/dist/plugins/parental/__tests__/parental-plugin.test.d.ts.map +1 -0
  110. package/dist/plugins/parental/__tests__/parental-plugin.test.js +349 -0
  111. package/dist/plugins/parental/__tests__/parental-plugin.test.js.map +1 -0
  112. package/dist/plugins/parental/adapters/index.d.ts +8 -0
  113. package/dist/plugins/parental/adapters/index.d.ts.map +1 -0
  114. package/dist/plugins/parental/adapters/index.js +7 -0
  115. package/dist/plugins/parental/adapters/index.js.map +1 -0
  116. package/dist/plugins/parental/adapters/kids-adapter.d.ts +24 -0
  117. package/dist/plugins/parental/adapters/kids-adapter.d.ts.map +1 -0
  118. package/dist/plugins/parental/adapters/kids-adapter.js +174 -0
  119. package/dist/plugins/parental/adapters/kids-adapter.js.map +1 -0
  120. package/dist/plugins/parental/index.d.ts +14 -0
  121. package/dist/plugins/parental/index.d.ts.map +1 -0
  122. package/dist/plugins/parental/index.js +15 -0
  123. package/dist/plugins/parental/index.js.map +1 -0
  124. package/dist/plugins/parental/parental-plugin.d.ts +88 -0
  125. package/dist/plugins/parental/parental-plugin.d.ts.map +1 -0
  126. package/dist/plugins/parental/parental-plugin.js +666 -0
  127. package/dist/plugins/parental/parental-plugin.js.map +1 -0
  128. package/dist/plugins/parental/stores/index.d.ts +7 -0
  129. package/dist/plugins/parental/stores/index.d.ts.map +1 -0
  130. package/dist/plugins/parental/stores/index.js +7 -0
  131. package/dist/plugins/parental/stores/index.js.map +1 -0
  132. package/dist/plugins/parental/stores/postgres-store.d.ts +10 -0
  133. package/dist/plugins/parental/stores/postgres-store.d.ts.map +1 -0
  134. package/dist/plugins/parental/stores/postgres-store.js +209 -0
  135. package/dist/plugins/parental/stores/postgres-store.js.map +1 -0
  136. package/dist/plugins/parental/types.d.ts +154 -0
  137. package/dist/plugins/parental/types.d.ts.map +1 -0
  138. package/dist/plugins/parental/types.js +10 -0
  139. package/dist/plugins/parental/types.js.map +1 -0
  140. package/dist/plugins/profiles/__tests__/profiles-plugin.test.d.ts +11 -0
  141. package/dist/plugins/profiles/__tests__/profiles-plugin.test.d.ts.map +1 -0
  142. package/dist/plugins/profiles/__tests__/profiles-plugin.test.js +243 -0
  143. package/dist/plugins/profiles/__tests__/profiles-plugin.test.js.map +1 -0
  144. package/dist/plugins/profiles/index.d.ts +12 -0
  145. package/dist/plugins/profiles/index.d.ts.map +1 -0
  146. package/dist/plugins/profiles/index.js +13 -0
  147. package/dist/plugins/profiles/index.js.map +1 -0
  148. package/dist/plugins/profiles/profiles-plugin.d.ts +71 -0
  149. package/dist/plugins/profiles/profiles-plugin.d.ts.map +1 -0
  150. package/dist/plugins/profiles/profiles-plugin.js +481 -0
  151. package/dist/plugins/profiles/profiles-plugin.js.map +1 -0
  152. package/dist/plugins/profiles/stores/index.d.ts +9 -0
  153. package/dist/plugins/profiles/stores/index.d.ts.map +1 -0
  154. package/dist/plugins/profiles/stores/index.js +9 -0
  155. package/dist/plugins/profiles/stores/index.js.map +1 -0
  156. package/dist/plugins/profiles/stores/postgres-store.d.ts +18 -0
  157. package/dist/plugins/profiles/stores/postgres-store.d.ts.map +1 -0
  158. package/dist/plugins/profiles/stores/postgres-store.js +310 -0
  159. package/dist/plugins/profiles/stores/postgres-store.js.map +1 -0
  160. package/dist/plugins/profiles/types.d.ts +289 -0
  161. package/dist/plugins/profiles/types.d.ts.map +1 -0
  162. package/dist/plugins/profiles/types.js +10 -0
  163. package/dist/plugins/profiles/types.js.map +1 -0
  164. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts +7 -0
  165. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts.map +1 -0
  166. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js +220 -0
  167. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js.map +1 -0
  168. package/dist/plugins/rate-limit/cleanup.d.ts +40 -0
  169. package/dist/plugins/rate-limit/cleanup.d.ts.map +1 -0
  170. package/dist/plugins/rate-limit/cleanup.js +72 -0
  171. package/dist/plugins/rate-limit/cleanup.js.map +1 -0
  172. package/dist/plugins/rate-limit/env-config.d.ts +91 -0
  173. package/dist/plugins/rate-limit/env-config.d.ts.map +1 -0
  174. package/dist/plugins/rate-limit/env-config.js +318 -0
  175. package/dist/plugins/rate-limit/env-config.js.map +1 -0
  176. package/dist/plugins/rate-limit/index.d.ts +76 -0
  177. package/dist/plugins/rate-limit/index.d.ts.map +1 -0
  178. package/dist/plugins/rate-limit/index.js +79 -0
  179. package/dist/plugins/rate-limit/index.js.map +1 -0
  180. package/dist/plugins/rate-limit/middleware.d.ts +40 -0
  181. package/dist/plugins/rate-limit/middleware.d.ts.map +1 -0
  182. package/dist/plugins/rate-limit/middleware.js +169 -0
  183. package/dist/plugins/rate-limit/middleware.js.map +1 -0
  184. package/dist/plugins/rate-limit/rate-limit-plugin.d.ts +44 -0
  185. package/dist/plugins/rate-limit/rate-limit-plugin.d.ts.map +1 -0
  186. package/dist/plugins/rate-limit/rate-limit-plugin.js +354 -0
  187. package/dist/plugins/rate-limit/rate-limit-plugin.js.map +1 -0
  188. package/dist/plugins/rate-limit/rate-limit-service.d.ts +110 -0
  189. package/dist/plugins/rate-limit/rate-limit-service.d.ts.map +1 -0
  190. package/dist/plugins/rate-limit/rate-limit-service.js +172 -0
  191. package/dist/plugins/rate-limit/rate-limit-service.js.map +1 -0
  192. package/dist/plugins/rate-limit/stores/cache-store.d.ts +33 -0
  193. package/dist/plugins/rate-limit/stores/cache-store.d.ts.map +1 -0
  194. package/dist/plugins/rate-limit/stores/cache-store.js +225 -0
  195. package/dist/plugins/rate-limit/stores/cache-store.js.map +1 -0
  196. package/dist/plugins/rate-limit/stores/index.d.ts +8 -0
  197. package/dist/plugins/rate-limit/stores/index.d.ts.map +1 -0
  198. package/dist/plugins/rate-limit/stores/index.js +8 -0
  199. package/dist/plugins/rate-limit/stores/index.js.map +1 -0
  200. package/dist/plugins/rate-limit/stores/postgres-store.d.ts +34 -0
  201. package/dist/plugins/rate-limit/stores/postgres-store.d.ts.map +1 -0
  202. package/dist/plugins/rate-limit/stores/postgres-store.js +320 -0
  203. package/dist/plugins/rate-limit/stores/postgres-store.js.map +1 -0
  204. package/dist/plugins/rate-limit/strategies/fixed-window.d.ts +21 -0
  205. package/dist/plugins/rate-limit/strategies/fixed-window.d.ts.map +1 -0
  206. package/dist/plugins/rate-limit/strategies/fixed-window.js +97 -0
  207. package/dist/plugins/rate-limit/strategies/fixed-window.js.map +1 -0
  208. package/dist/plugins/rate-limit/strategies/index.d.ts +14 -0
  209. package/dist/plugins/rate-limit/strategies/index.d.ts.map +1 -0
  210. package/dist/plugins/rate-limit/strategies/index.js +27 -0
  211. package/dist/plugins/rate-limit/strategies/index.js.map +1 -0
  212. package/dist/plugins/rate-limit/strategies/sliding-window.d.ts +22 -0
  213. package/dist/plugins/rate-limit/strategies/sliding-window.d.ts.map +1 -0
  214. package/dist/plugins/rate-limit/strategies/sliding-window.js +122 -0
  215. package/dist/plugins/rate-limit/strategies/sliding-window.js.map +1 -0
  216. package/dist/plugins/rate-limit/strategies/token-bucket.d.ts +28 -0
  217. package/dist/plugins/rate-limit/strategies/token-bucket.d.ts.map +1 -0
  218. package/dist/plugins/rate-limit/strategies/token-bucket.js +121 -0
  219. package/dist/plugins/rate-limit/strategies/token-bucket.js.map +1 -0
  220. package/dist/plugins/rate-limit/types.d.ts +265 -0
  221. package/dist/plugins/rate-limit/types.d.ts.map +1 -0
  222. package/dist/plugins/rate-limit/types.js +9 -0
  223. package/dist/plugins/rate-limit/types.js.map +1 -0
  224. package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.d.ts +11 -0
  225. package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.d.ts.map +1 -0
  226. package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.js +305 -0
  227. package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.js.map +1 -0
  228. package/dist/plugins/subscriptions/index.d.ts +12 -0
  229. package/dist/plugins/subscriptions/index.d.ts.map +1 -0
  230. package/dist/plugins/subscriptions/index.js +13 -0
  231. package/dist/plugins/subscriptions/index.js.map +1 -0
  232. package/dist/plugins/subscriptions/stores/index.d.ts +9 -0
  233. package/dist/plugins/subscriptions/stores/index.d.ts.map +1 -0
  234. package/dist/plugins/subscriptions/stores/index.js +9 -0
  235. package/dist/plugins/subscriptions/stores/index.js.map +1 -0
  236. package/dist/plugins/subscriptions/stores/postgres-store.d.ts +14 -0
  237. package/dist/plugins/subscriptions/stores/postgres-store.d.ts.map +1 -0
  238. package/dist/plugins/subscriptions/stores/postgres-store.js +359 -0
  239. package/dist/plugins/subscriptions/stores/postgres-store.js.map +1 -0
  240. package/dist/plugins/subscriptions/subscriptions-plugin.d.ts +82 -0
  241. package/dist/plugins/subscriptions/subscriptions-plugin.d.ts.map +1 -0
  242. package/dist/plugins/subscriptions/subscriptions-plugin.js +449 -0
  243. package/dist/plugins/subscriptions/subscriptions-plugin.js.map +1 -0
  244. package/dist/plugins/subscriptions/types.d.ts +308 -0
  245. package/dist/plugins/subscriptions/types.d.ts.map +1 -0
  246. package/dist/plugins/subscriptions/types.js +10 -0
  247. package/dist/plugins/subscriptions/types.js.map +1 -0
  248. package/dist/plugins/usage/__tests__/usage-plugin.test.d.ts +11 -0
  249. package/dist/plugins/usage/__tests__/usage-plugin.test.d.ts.map +1 -0
  250. package/dist/plugins/usage/__tests__/usage-plugin.test.js +218 -0
  251. package/dist/plugins/usage/__tests__/usage-plugin.test.js.map +1 -0
  252. package/dist/plugins/usage/index.d.ts +12 -0
  253. package/dist/plugins/usage/index.d.ts.map +1 -0
  254. package/dist/plugins/usage/index.js +13 -0
  255. package/dist/plugins/usage/index.js.map +1 -0
  256. package/dist/plugins/usage/stores/index.d.ts +9 -0
  257. package/dist/plugins/usage/stores/index.d.ts.map +1 -0
  258. package/dist/plugins/usage/stores/index.js +9 -0
  259. package/dist/plugins/usage/stores/index.js.map +1 -0
  260. package/dist/plugins/usage/stores/postgres-store.d.ts +14 -0
  261. package/dist/plugins/usage/stores/postgres-store.d.ts.map +1 -0
  262. package/dist/plugins/usage/stores/postgres-store.js +146 -0
  263. package/dist/plugins/usage/stores/postgres-store.js.map +1 -0
  264. package/dist/plugins/usage/types.d.ts +195 -0
  265. package/dist/plugins/usage/types.d.ts.map +1 -0
  266. package/dist/plugins/usage/types.js +10 -0
  267. package/dist/plugins/usage/types.js.map +1 -0
  268. package/dist/plugins/usage/usage-plugin.d.ts +51 -0
  269. package/dist/plugins/usage/usage-plugin.d.ts.map +1 -0
  270. package/dist/plugins/usage/usage-plugin.js +412 -0
  271. package/dist/plugins/usage/usage-plugin.js.map +1 -0
  272. package/dist/plugins/users/__tests__/postgres-store.test.d.ts +10 -0
  273. package/dist/plugins/users/__tests__/postgres-store.test.d.ts.map +1 -0
  274. package/dist/plugins/users/__tests__/postgres-store.test.js +229 -0
  275. package/dist/plugins/users/__tests__/postgres-store.test.js.map +1 -0
  276. package/dist/plugins/users/__tests__/users-plugin.test.js +3 -0
  277. package/dist/plugins/users/__tests__/users-plugin.test.js.map +1 -1
  278. package/dist/plugins/users/index.d.ts +2 -2
  279. package/dist/plugins/users/index.d.ts.map +1 -1
  280. package/dist/plugins/users/index.js +1 -1
  281. package/dist/plugins/users/index.js.map +1 -1
  282. package/dist/plugins/users/stores/postgres-store.d.ts.map +1 -1
  283. package/dist/plugins/users/stores/postgres-store.js +76 -0
  284. package/dist/plugins/users/stores/postgres-store.js.map +1 -1
  285. package/dist/plugins/users/types.d.ts +74 -6
  286. package/dist/plugins/users/types.d.ts.map +1 -1
  287. package/dist/plugins/users/users-plugin.d.ts +15 -1
  288. package/dist/plugins/users/users-plugin.d.ts.map +1 -1
  289. package/dist/plugins/users/users-plugin.js +29 -0
  290. package/dist/plugins/users/users-plugin.js.map +1 -1
  291. package/dist-ui/assets/index-CynOqPkb.js +469 -0
  292. package/dist-ui/assets/{index-BY8OxNgO.js.map → index-CynOqPkb.js.map} +1 -1
  293. package/dist-ui/index.html +1 -1
  294. package/dist-ui-lib/api/controlPanelApi.d.ts +187 -0
  295. package/dist-ui-lib/components/StatCard.d.ts +16 -0
  296. package/dist-ui-lib/dashboard/widgets/AuthStatusWidget.d.ts +9 -0
  297. package/dist-ui-lib/dashboard/widgets/IntegrationStatusWidget.d.ts +9 -0
  298. package/dist-ui-lib/dashboard/widgets/NotificationsStatsWidget.d.ts +12 -0
  299. package/dist-ui-lib/dashboard/widgets/index.d.ts +3 -0
  300. package/dist-ui-lib/index.js +3579 -2379
  301. package/dist-ui-lib/index.js.map +1 -1
  302. package/dist-ui-lib/pages/IntegrationsPage.d.ts +1 -0
  303. package/dist-ui-lib/pages/NotificationsPage.d.ts +9 -0
  304. package/dist-ui-lib/pages/RateLimitPage.d.ts +1 -0
  305. package/dist-ui-lib/utils/formatters.d.ts +19 -0
  306. package/package.json +1 -1
  307. package/src/core/control-panel.ts +128 -0
  308. package/src/core/types.ts +17 -0
  309. package/src/index.ts +216 -0
  310. package/src/plugins/auth/adapter-wrapper.test.ts +395 -0
  311. package/src/plugins/auth/adapter-wrapper.ts +205 -0
  312. package/src/plugins/auth/config-store.test.ts +417 -0
  313. package/src/plugins/auth/config-store.ts +305 -0
  314. package/src/plugins/auth/env-config.ts +714 -7
  315. package/src/plugins/auth/index.ts +22 -1
  316. package/src/plugins/auth/types.ts +138 -0
  317. package/src/plugins/bans/bans-plugin.ts +15 -3
  318. package/src/plugins/devices/__tests__/devices-plugin.test.ts +551 -0
  319. package/src/plugins/devices/__tests__/token-utils.test.ts +264 -0
  320. package/src/plugins/devices/adapters/compute-adapter.ts +139 -0
  321. package/src/plugins/devices/adapters/index.ts +13 -0
  322. package/src/plugins/devices/adapters/mobile-adapter.ts +179 -0
  323. package/src/plugins/devices/devices-plugin.ts +538 -0
  324. package/src/plugins/devices/index.ts +69 -0
  325. package/src/plugins/devices/stores/index.ts +9 -0
  326. package/src/plugins/devices/stores/postgres-store.ts +304 -0
  327. package/src/plugins/devices/token-utils.ts +213 -0
  328. package/src/plugins/devices/types.ts +351 -0
  329. package/src/plugins/index.ts +267 -0
  330. package/src/plugins/notifications/__tests__/notifications-manager.test.ts +637 -0
  331. package/src/plugins/notifications/index.ts +91 -0
  332. package/src/plugins/notifications/notifications-manager.ts +773 -0
  333. package/src/plugins/notifications/notifications-plugin.ts +398 -0
  334. package/src/plugins/notifications/types.ts +207 -0
  335. package/src/plugins/parental/__tests__/parental-plugin.test.ts +465 -0
  336. package/src/plugins/parental/adapters/index.ts +8 -0
  337. package/src/plugins/parental/adapters/kids-adapter.ts +206 -0
  338. package/src/plugins/parental/index.ts +55 -0
  339. package/src/plugins/parental/parental-plugin.ts +759 -0
  340. package/src/plugins/parental/stores/index.ts +7 -0
  341. package/src/plugins/parental/stores/postgres-store.ts +304 -0
  342. package/src/plugins/parental/types.ts +180 -0
  343. package/src/plugins/profiles/__tests__/profiles-plugin.test.ts +321 -0
  344. package/src/plugins/profiles/index.ts +49 -0
  345. package/src/plugins/profiles/profiles-plugin.ts +546 -0
  346. package/src/plugins/profiles/stores/index.ts +9 -0
  347. package/src/plugins/profiles/stores/postgres-store.ts +439 -0
  348. package/src/plugins/profiles/types.ts +338 -0
  349. package/src/plugins/rate-limit/__tests__/rate-limit-plugin.test.ts +259 -0
  350. package/src/plugins/rate-limit/cleanup.ts +117 -0
  351. package/src/plugins/rate-limit/env-config.ts +400 -0
  352. package/src/plugins/rate-limit/index.ts +128 -0
  353. package/src/plugins/rate-limit/middleware.ts +212 -0
  354. package/src/plugins/rate-limit/rate-limit-plugin.ts +400 -0
  355. package/src/plugins/rate-limit/rate-limit-service.ts +228 -0
  356. package/src/plugins/rate-limit/stores/cache-store.ts +261 -0
  357. package/src/plugins/rate-limit/stores/index.ts +8 -0
  358. package/src/plugins/rate-limit/stores/postgres-store.ts +402 -0
  359. package/src/plugins/rate-limit/strategies/fixed-window.ts +116 -0
  360. package/src/plugins/rate-limit/strategies/index.ts +30 -0
  361. package/src/plugins/rate-limit/strategies/sliding-window.ts +157 -0
  362. package/src/plugins/rate-limit/strategies/token-bucket.ts +154 -0
  363. package/src/plugins/rate-limit/types.ts +338 -0
  364. package/src/plugins/subscriptions/__tests__/subscriptions-plugin.test.ts +404 -0
  365. package/src/plugins/subscriptions/index.ts +51 -0
  366. package/src/plugins/subscriptions/stores/index.ts +9 -0
  367. package/src/plugins/subscriptions/stores/postgres-store.ts +482 -0
  368. package/src/plugins/subscriptions/subscriptions-plugin.ts +530 -0
  369. package/src/plugins/subscriptions/types.ts +355 -0
  370. package/src/plugins/usage/__tests__/usage-plugin.test.ts +288 -0
  371. package/src/plugins/usage/index.ts +39 -0
  372. package/src/plugins/usage/stores/index.ts +9 -0
  373. package/src/plugins/usage/stores/postgres-store.ts +213 -0
  374. package/src/plugins/usage/types.ts +222 -0
  375. package/src/plugins/usage/usage-plugin.ts +484 -0
  376. package/src/plugins/users/__tests__/postgres-store.test.ts +326 -0
  377. package/src/plugins/users/__tests__/users-plugin.test.ts +3 -0
  378. package/src/plugins/users/index.ts +6 -0
  379. package/src/plugins/users/stores/postgres-store.ts +104 -0
  380. package/src/plugins/users/types.ts +82 -6
  381. package/src/plugins/users/users-plugin.ts +37 -0
  382. package/ui/src/App.tsx +36 -14
  383. package/ui/src/api/controlPanelApi.ts +329 -6
  384. package/ui/src/components/StatCard.tsx +58 -0
  385. package/ui/src/dashboard/builtInWidgets.tsx +7 -1
  386. package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +143 -0
  387. package/ui/src/dashboard/widgets/IntegrationStatusWidget.tsx +135 -0
  388. package/ui/src/dashboard/widgets/NotificationsStatsWidget.tsx +167 -0
  389. package/ui/src/dashboard/widgets/index.ts +3 -0
  390. package/ui/src/pages/AuthPage.tsx +986 -142
  391. package/ui/src/pages/IntegrationsPage.tsx +288 -0
  392. package/ui/src/pages/NotificationsPage.tsx +417 -0
  393. package/ui/src/pages/RateLimitPage.tsx +292 -0
  394. package/ui/src/utils/formatters.ts +33 -0
  395. package/dist-ui/assets/index-BY8OxNgO.js +0 -465
@@ -0,0 +1,395 @@
1
+ /**
2
+ * Auth Adapter Wrapper Tests
3
+ *
4
+ * Unit tests for the hot-reload adapter wrapper.
5
+ */
6
+
7
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
8
+ import type { Request, Response, NextFunction } from 'express';
9
+ import { createAdapterWrapper } from './adapter-wrapper.js';
10
+ import type { AuthAdapter, AuthenticatedUser } from './types.js';
11
+
12
+ // Helper to create a mock adapter
13
+ function createMockAdapter(name: string, overrides: Partial<AuthAdapter> = {}): AuthAdapter {
14
+ return {
15
+ name,
16
+ initialize: vi.fn().mockReturnValue((_req: Request, _res: Response, next: NextFunction) => next()),
17
+ isAuthenticated: vi.fn().mockReturnValue(false),
18
+ getUser: vi.fn().mockReturnValue(null),
19
+ hasRoles: vi.fn().mockReturnValue(false),
20
+ getAccessToken: vi.fn().mockReturnValue(null),
21
+ onUnauthorized: vi.fn(),
22
+ shutdown: vi.fn().mockResolvedValue(undefined),
23
+ ...overrides,
24
+ };
25
+ }
26
+
27
+ // Helper to create mock request/response
28
+ function createMockReq(): Request {
29
+ return {} as Request;
30
+ }
31
+
32
+ function createMockRes(): Response {
33
+ return {
34
+ status: vi.fn().mockReturnThis(),
35
+ json: vi.fn().mockReturnThis(),
36
+ } as unknown as Response;
37
+ }
38
+
39
+ describe('createAdapterWrapper', () => {
40
+ describe('initialization', () => {
41
+ it('should create wrapper with no-op adapter by default', () => {
42
+ const wrapper = createAdapterWrapper();
43
+
44
+ expect(wrapper.name).toBe('none');
45
+ expect(wrapper.hasAdapter()).toBe(false);
46
+ });
47
+
48
+ it('should create wrapper with initial adapter', () => {
49
+ const mockAdapter = createMockAdapter('test');
50
+ const wrapper = createAdapterWrapper(mockAdapter);
51
+
52
+ expect(wrapper.name).toBe('test');
53
+ expect(wrapper.hasAdapter()).toBe(true);
54
+ });
55
+
56
+ it('should return adapter info', () => {
57
+ const mockAdapter = createMockAdapter('test');
58
+ const wrapper = createAdapterWrapper(mockAdapter);
59
+
60
+ const info = wrapper.getAdapterInfo();
61
+
62
+ expect(info.name).toBe('test');
63
+ expect(info.initialized).toBe(false);
64
+ });
65
+ });
66
+
67
+ describe('initialize', () => {
68
+ it('should call underlying adapter initialize', () => {
69
+ const mockAdapter = createMockAdapter('test');
70
+ const wrapper = createAdapterWrapper(mockAdapter);
71
+
72
+ wrapper.initialize();
73
+
74
+ expect(mockAdapter.initialize).toHaveBeenCalled();
75
+ });
76
+
77
+ it('should mark wrapper as initialized', () => {
78
+ const mockAdapter = createMockAdapter('test');
79
+ const wrapper = createAdapterWrapper(mockAdapter);
80
+
81
+ wrapper.initialize();
82
+
83
+ expect(wrapper.getAdapterInfo().initialized).toBe(true);
84
+ });
85
+
86
+ it('should return middleware from underlying adapter', () => {
87
+ const mockMiddleware = vi.fn();
88
+ const mockAdapter = createMockAdapter('test', {
89
+ initialize: vi.fn().mockReturnValue(mockMiddleware),
90
+ });
91
+ const wrapper = createAdapterWrapper(mockAdapter);
92
+
93
+ const result = wrapper.initialize();
94
+
95
+ expect(result).toBe(mockMiddleware);
96
+ });
97
+ });
98
+
99
+ describe('isAuthenticated', () => {
100
+ it('should delegate to current adapter', () => {
101
+ const mockAdapter = createMockAdapter('test', {
102
+ isAuthenticated: vi.fn().mockReturnValue(true),
103
+ });
104
+ const wrapper = createAdapterWrapper(mockAdapter);
105
+ const req = createMockReq();
106
+
107
+ const result = wrapper.isAuthenticated(req);
108
+
109
+ expect(mockAdapter.isAuthenticated).toHaveBeenCalledWith(req);
110
+ expect(result).toBe(true);
111
+ });
112
+
113
+ it('should use new adapter after swap', async () => {
114
+ const oldAdapter = createMockAdapter('old', {
115
+ isAuthenticated: vi.fn().mockReturnValue(false),
116
+ });
117
+ const newAdapter = createMockAdapter('new', {
118
+ isAuthenticated: vi.fn().mockReturnValue(true),
119
+ });
120
+
121
+ const wrapper = createAdapterWrapper(oldAdapter);
122
+ await wrapper.setAdapter(newAdapter);
123
+
124
+ const req = createMockReq();
125
+ const result = wrapper.isAuthenticated(req);
126
+
127
+ expect(result).toBe(true);
128
+ expect(newAdapter.isAuthenticated).toHaveBeenCalledWith(req);
129
+ });
130
+ });
131
+
132
+ describe('getUser', () => {
133
+ it('should delegate to current adapter', () => {
134
+ const mockUser: AuthenticatedUser = {
135
+ id: '123',
136
+ email: 'test@example.com',
137
+ name: 'Test User',
138
+ };
139
+ const mockAdapter = createMockAdapter('test', {
140
+ getUser: vi.fn().mockReturnValue(mockUser),
141
+ });
142
+ const wrapper = createAdapterWrapper(mockAdapter);
143
+ const req = createMockReq();
144
+
145
+ const result = wrapper.getUser(req);
146
+
147
+ expect(mockAdapter.getUser).toHaveBeenCalledWith(req);
148
+ expect(result).toEqual(mockUser);
149
+ });
150
+
151
+ it('should return null for no-op adapter', () => {
152
+ const wrapper = createAdapterWrapper();
153
+ const req = createMockReq();
154
+
155
+ const result = wrapper.getUser(req);
156
+
157
+ expect(result).toBeNull();
158
+ });
159
+ });
160
+
161
+ describe('hasRoles', () => {
162
+ it('should delegate to current adapter if method exists', () => {
163
+ const mockAdapter = createMockAdapter('test', {
164
+ hasRoles: vi.fn().mockReturnValue(true),
165
+ });
166
+ const wrapper = createAdapterWrapper(mockAdapter);
167
+ const req = createMockReq();
168
+
169
+ // Wrapper always implements hasRoles
170
+ const result = wrapper.hasRoles!(req, ['admin']);
171
+
172
+ expect(mockAdapter.hasRoles).toHaveBeenCalledWith(req, ['admin']);
173
+ expect(result).toBe(true);
174
+ });
175
+
176
+ it('should return false if adapter has no hasRoles method', () => {
177
+ const mockAdapter = createMockAdapter('test');
178
+ delete (mockAdapter as Partial<AuthAdapter>).hasRoles;
179
+ const wrapper = createAdapterWrapper(mockAdapter);
180
+ const req = createMockReq();
181
+
182
+ // Wrapper always implements hasRoles, even if underlying adapter doesn't
183
+ const result = wrapper.hasRoles!(req, ['admin']);
184
+
185
+ expect(result).toBe(false);
186
+ });
187
+ });
188
+
189
+ describe('getAccessToken', () => {
190
+ it('should delegate to current adapter if method exists', () => {
191
+ const mockAdapter = createMockAdapter('test', {
192
+ getAccessToken: vi.fn().mockReturnValue('token123'),
193
+ });
194
+ const wrapper = createAdapterWrapper(mockAdapter);
195
+ const req = createMockReq();
196
+
197
+ // Wrapper always implements getAccessToken
198
+ const result = wrapper.getAccessToken!(req);
199
+
200
+ expect(mockAdapter.getAccessToken).toHaveBeenCalledWith(req);
201
+ expect(result).toBe('token123');
202
+ });
203
+
204
+ it('should return null if adapter has no getAccessToken method', () => {
205
+ const mockAdapter = createMockAdapter('test');
206
+ delete (mockAdapter as Partial<AuthAdapter>).getAccessToken;
207
+ const wrapper = createAdapterWrapper(mockAdapter);
208
+ const req = createMockReq();
209
+
210
+ // Wrapper always implements getAccessToken, returns null when adapter doesn't have it
211
+ const result = wrapper.getAccessToken!(req);
212
+
213
+ expect(result).toBeNull();
214
+ });
215
+ });
216
+
217
+ describe('onUnauthorized', () => {
218
+ it('should delegate to current adapter if method exists', () => {
219
+ const mockAdapter = createMockAdapter('test');
220
+ const wrapper = createAdapterWrapper(mockAdapter);
221
+ const req = createMockReq();
222
+ const res = createMockRes();
223
+
224
+ // Wrapper always implements onUnauthorized
225
+ wrapper.onUnauthorized!(req, res);
226
+
227
+ expect(mockAdapter.onUnauthorized).toHaveBeenCalledWith(req, res);
228
+ });
229
+
230
+ it('should return 401 JSON response if adapter has no onUnauthorized', () => {
231
+ const mockAdapter = createMockAdapter('test');
232
+ delete (mockAdapter as Partial<AuthAdapter>).onUnauthorized;
233
+ const wrapper = createAdapterWrapper(mockAdapter);
234
+ const req = createMockReq();
235
+ const res = createMockRes();
236
+
237
+ // Wrapper always implements onUnauthorized with default behavior
238
+ wrapper.onUnauthorized!(req, res);
239
+
240
+ expect(res.status).toHaveBeenCalledWith(401);
241
+ expect(res.json).toHaveBeenCalledWith({
242
+ error: 'Unauthorized',
243
+ message: 'Authentication required',
244
+ });
245
+ });
246
+ });
247
+
248
+ describe('setAdapter (hot-reload)', () => {
249
+ it('should swap adapter successfully', async () => {
250
+ const oldAdapter = createMockAdapter('old');
251
+ const newAdapter = createMockAdapter('new');
252
+ const wrapper = createAdapterWrapper(oldAdapter);
253
+
254
+ await wrapper.setAdapter(newAdapter);
255
+
256
+ expect(wrapper.name).toBe('new');
257
+ });
258
+
259
+ it('should shutdown old adapter before swap', async () => {
260
+ const oldAdapter = createMockAdapter('old');
261
+ const newAdapter = createMockAdapter('new');
262
+ const wrapper = createAdapterWrapper(oldAdapter);
263
+
264
+ await wrapper.setAdapter(newAdapter);
265
+
266
+ expect(oldAdapter.shutdown).toHaveBeenCalled();
267
+ });
268
+
269
+ it('should initialize new adapter if wrapper was initialized', async () => {
270
+ const oldAdapter = createMockAdapter('old');
271
+ const newAdapter = createMockAdapter('new');
272
+ const wrapper = createAdapterWrapper(oldAdapter);
273
+
274
+ // Initialize wrapper
275
+ wrapper.initialize();
276
+
277
+ // Swap adapter
278
+ await wrapper.setAdapter(newAdapter);
279
+
280
+ expect(newAdapter.initialize).toHaveBeenCalled();
281
+ });
282
+
283
+ it('should not initialize new adapter if wrapper was not initialized', async () => {
284
+ const oldAdapter = createMockAdapter('old');
285
+ const newAdapter = createMockAdapter('new');
286
+ const wrapper = createAdapterWrapper(oldAdapter);
287
+
288
+ // Don't initialize wrapper
289
+
290
+ // Swap adapter
291
+ await wrapper.setAdapter(newAdapter);
292
+
293
+ expect(newAdapter.initialize).not.toHaveBeenCalled();
294
+ });
295
+
296
+ it('should prevent concurrent adapter swaps', async () => {
297
+ const oldAdapter = createMockAdapter('old', {
298
+ shutdown: vi.fn().mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100))),
299
+ });
300
+ const newAdapter1 = createMockAdapter('new1');
301
+ const newAdapter2 = createMockAdapter('new2');
302
+ const wrapper = createAdapterWrapper(oldAdapter);
303
+
304
+ // Start first swap
305
+ const swap1 = wrapper.setAdapter(newAdapter1);
306
+
307
+ // Try second swap immediately (should fail)
308
+ await expect(wrapper.setAdapter(newAdapter2)).rejects.toThrow('Adapter swap already in progress');
309
+
310
+ // Wait for first swap to complete
311
+ await swap1;
312
+
313
+ // Now second swap should work
314
+ await wrapper.setAdapter(newAdapter2);
315
+ expect(wrapper.name).toBe('new2');
316
+ });
317
+
318
+ it('should handle shutdown errors gracefully', async () => {
319
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
320
+
321
+ const oldAdapter = createMockAdapter('old', {
322
+ shutdown: vi.fn().mockRejectedValue(new Error('Shutdown failed')),
323
+ });
324
+ const newAdapter = createMockAdapter('new');
325
+ const wrapper = createAdapterWrapper(oldAdapter);
326
+
327
+ // Should not throw
328
+ await wrapper.setAdapter(newAdapter);
329
+
330
+ expect(wrapper.name).toBe('new');
331
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
332
+ '[AdapterWrapper] Error shutting down old adapter:',
333
+ expect.any(Error)
334
+ );
335
+
336
+ consoleErrorSpy.mockRestore();
337
+ });
338
+ });
339
+
340
+ describe('shutdown', () => {
341
+ it('should shutdown current adapter', async () => {
342
+ const mockAdapter = createMockAdapter('test');
343
+ const wrapper = createAdapterWrapper(mockAdapter);
344
+ wrapper.initialize();
345
+
346
+ // Wrapper always implements shutdown
347
+ await wrapper.shutdown!();
348
+
349
+ expect(mockAdapter.shutdown).toHaveBeenCalled();
350
+ expect(wrapper.getAdapterInfo().initialized).toBe(false);
351
+ });
352
+
353
+ it('should handle adapters without shutdown method', async () => {
354
+ const mockAdapter = createMockAdapter('test');
355
+ delete (mockAdapter as Partial<AuthAdapter>).shutdown;
356
+ const wrapper = createAdapterWrapper(mockAdapter);
357
+ wrapper.initialize();
358
+
359
+ // Should not throw - wrapper handles missing shutdown gracefully
360
+ await wrapper.shutdown!();
361
+
362
+ expect(wrapper.getAdapterInfo().initialized).toBe(false);
363
+ });
364
+ });
365
+
366
+ describe('no-op adapter', () => {
367
+ it('should return false for isAuthenticated', () => {
368
+ const wrapper = createAdapterWrapper();
369
+ const req = createMockReq();
370
+
371
+ expect(wrapper.isAuthenticated(req)).toBe(false);
372
+ });
373
+
374
+ it('should return null for getUser', () => {
375
+ const wrapper = createAdapterWrapper();
376
+ const req = createMockReq();
377
+
378
+ expect(wrapper.getUser(req)).toBeNull();
379
+ });
380
+
381
+ it('should return middleware that calls next', () => {
382
+ const wrapper = createAdapterWrapper();
383
+ const middleware = wrapper.initialize();
384
+
385
+ const req = createMockReq();
386
+ const res = createMockRes();
387
+ const next = vi.fn();
388
+
389
+ if (typeof middleware === 'function') {
390
+ middleware(req, res, next);
391
+ expect(next).toHaveBeenCalled();
392
+ }
393
+ });
394
+ });
395
+ });
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Auth Adapter Wrapper
3
+ *
4
+ * Wraps an auth adapter to enable hot-reload without server restart.
5
+ * All method calls are delegated to the underlying adapter, which can
6
+ * be swapped at runtime via setAdapter().
7
+ *
8
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
9
+ */
10
+
11
+ import type { Request, Response, RequestHandler } from 'express';
12
+ import type { AuthAdapter, AuthenticatedUser } from './types.js';
13
+
14
+ /**
15
+ * Extended adapter interface with hot-reload capabilities
16
+ */
17
+ export interface AdapterWrapper extends AuthAdapter {
18
+ /**
19
+ * Replace the underlying adapter (for hot-reload)
20
+ * Calls shutdown() on the old adapter before swapping
21
+ */
22
+ setAdapter(adapter: AuthAdapter): Promise<void>;
23
+
24
+ /**
25
+ * Get information about the current adapter
26
+ */
27
+ getAdapterInfo(): { name: string; initialized: boolean };
28
+
29
+ /**
30
+ * Check if an adapter is currently set
31
+ */
32
+ hasAdapter(): boolean;
33
+ }
34
+
35
+ /**
36
+ * Create a no-op adapter for when auth is disabled
37
+ */
38
+ function createNoopAdapter(): AuthAdapter {
39
+ return {
40
+ name: 'none',
41
+ initialize: () => ((_req, _res, next) => next()) as RequestHandler,
42
+ isAuthenticated: () => false,
43
+ getUser: () => null,
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Create an adapter wrapper for hot-reload support
49
+ *
50
+ * @param initialAdapter Optional initial adapter (defaults to no-op)
51
+ * @returns AdapterWrapper that delegates to the underlying adapter
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * const wrapper = createAdapterWrapper(supertokensAdapter(config));
56
+ *
57
+ * // Later, swap the adapter without restart:
58
+ * await wrapper.setAdapter(auth0Adapter(newConfig));
59
+ * ```
60
+ */
61
+ export function createAdapterWrapper(initialAdapter?: AuthAdapter): AdapterWrapper {
62
+ let currentAdapter: AuthAdapter = initialAdapter || createNoopAdapter();
63
+ let isInitialized = false;
64
+ let isSwapping = false; // Prevent concurrent adapter swaps
65
+
66
+ return {
67
+ // Delegate name to current adapter
68
+ get name(): string {
69
+ return currentAdapter.name;
70
+ },
71
+
72
+ /**
73
+ * Initialize returns the middleware
74
+ * Note: This is called once at startup. The middleware itself
75
+ * will delegate to currentAdapter, which can be swapped.
76
+ */
77
+ initialize(): RequestHandler | RequestHandler[] {
78
+ isInitialized = true;
79
+
80
+ // Get the initial middleware
81
+ const initialMiddleware = currentAdapter.initialize();
82
+
83
+ // Return a wrapper middleware that delegates to current adapter's middleware
84
+ // This allows hot-reload to work - new adapter's middleware will be used
85
+ // Note: For simplicity, we return the initial middleware. Full hot-reload
86
+ // of middleware would require more complex Express route manipulation.
87
+ // The key hot-reload capability is in isAuthenticated/getUser which ARE
88
+ // delegated dynamically.
89
+ return initialMiddleware;
90
+ },
91
+
92
+ /**
93
+ * Delegate isAuthenticated to current adapter
94
+ */
95
+ isAuthenticated(req: Request): boolean {
96
+ return currentAdapter.isAuthenticated(req);
97
+ },
98
+
99
+ /**
100
+ * Delegate getUser to current adapter
101
+ */
102
+ getUser(req: Request): AuthenticatedUser | null | Promise<AuthenticatedUser | null> {
103
+ return currentAdapter.getUser(req);
104
+ },
105
+
106
+ /**
107
+ * Delegate hasRoles to current adapter (if available)
108
+ */
109
+ hasRoles(req: Request, roles: string[]): boolean {
110
+ if (currentAdapter.hasRoles) {
111
+ return currentAdapter.hasRoles(req, roles);
112
+ }
113
+ return false;
114
+ },
115
+
116
+ /**
117
+ * Delegate getAccessToken to current adapter (if available)
118
+ */
119
+ getAccessToken(req: Request): string | null {
120
+ if (currentAdapter.getAccessToken) {
121
+ return currentAdapter.getAccessToken(req);
122
+ }
123
+ return null;
124
+ },
125
+
126
+ /**
127
+ * Delegate onUnauthorized to current adapter (if available)
128
+ */
129
+ onUnauthorized(req: Request, res: Response): void {
130
+ if (currentAdapter.onUnauthorized) {
131
+ currentAdapter.onUnauthorized(req, res);
132
+ } else {
133
+ res.status(401).json({
134
+ error: 'Unauthorized',
135
+ message: 'Authentication required',
136
+ });
137
+ }
138
+ },
139
+
140
+ /**
141
+ * Shutdown the current adapter
142
+ */
143
+ async shutdown(): Promise<void> {
144
+ if (currentAdapter.shutdown) {
145
+ await currentAdapter.shutdown();
146
+ }
147
+ isInitialized = false;
148
+ },
149
+
150
+ /**
151
+ * Hot-reload: Replace the underlying adapter
152
+ * @throws Error if another adapter swap is already in progress
153
+ */
154
+ async setAdapter(adapter: AuthAdapter): Promise<void> {
155
+ // Prevent concurrent adapter swaps
156
+ if (isSwapping) {
157
+ throw new Error('Adapter swap already in progress');
158
+ }
159
+ isSwapping = true;
160
+
161
+ try {
162
+ const oldAdapter = currentAdapter;
163
+
164
+ // Shutdown old adapter
165
+ if (oldAdapter.shutdown) {
166
+ try {
167
+ await oldAdapter.shutdown();
168
+ } catch (err) {
169
+ console.error('[AdapterWrapper] Error shutting down old adapter:', err);
170
+ }
171
+ }
172
+
173
+ // Set new adapter
174
+ currentAdapter = adapter;
175
+
176
+ // Initialize new adapter if we're already running
177
+ if (isInitialized) {
178
+ // Note: We initialize the new adapter but can't easily swap Express middleware
179
+ // The new adapter's isAuthenticated/getUser will be used immediately
180
+ // Full middleware hot-reload would require server restart
181
+ currentAdapter.initialize();
182
+ }
183
+ } finally {
184
+ isSwapping = false;
185
+ }
186
+ },
187
+
188
+ /**
189
+ * Get info about the current adapter
190
+ */
191
+ getAdapterInfo(): { name: string; initialized: boolean } {
192
+ return {
193
+ name: currentAdapter.name,
194
+ initialized: isInitialized,
195
+ };
196
+ },
197
+
198
+ /**
199
+ * Check if a real adapter is set (not the no-op)
200
+ */
201
+ hasAdapter(): boolean {
202
+ return currentAdapter.name !== 'none';
203
+ },
204
+ };
205
+ }