@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,417 @@
1
+ /**
2
+ * Notifications Page
3
+ *
4
+ * Full management page for the Notifications Plugin.
5
+ * Shows connection stats, connected clients table, and management actions.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import { useState, useEffect, useRef, useCallback } from 'react';
11
+ import {
12
+ Box,
13
+ Card,
14
+ CardContent,
15
+ Typography,
16
+ Table,
17
+ TableBody,
18
+ TableCell,
19
+ TableContainer,
20
+ TableHead,
21
+ TableRow,
22
+ Paper,
23
+ Button,
24
+ IconButton,
25
+ Tooltip,
26
+ Chip,
27
+ Dialog,
28
+ DialogTitle,
29
+ DialogContent,
30
+ DialogContentText,
31
+ DialogActions,
32
+ CircularProgress,
33
+ Alert,
34
+ } from '@mui/material';
35
+ import RefreshIcon from '@mui/icons-material/Refresh';
36
+ import WifiIcon from '@mui/icons-material/Wifi';
37
+ import WifiOffIcon from '@mui/icons-material/WifiOff';
38
+ import DevicesIcon from '@mui/icons-material/Devices';
39
+ import PersonIcon from '@mui/icons-material/Person';
40
+ import SendIcon from '@mui/icons-material/Send';
41
+ import ErrorIcon from '@mui/icons-material/Error';
42
+ import NotificationsIcon from '@mui/icons-material/Notifications';
43
+ import DisconnectIcon from '@mui/icons-material/LinkOff';
44
+ import RestartAltIcon from '@mui/icons-material/RestartAlt';
45
+ import { GridLayout } from '@qwickapps/react-framework';
46
+ import {
47
+ api,
48
+ type NotificationsStatsResponse,
49
+ type NotificationsClient,
50
+ } from '../api/controlPanelApi';
51
+ import { StatCard } from '../components/StatCard';
52
+ import { formatDuration, formatNumber, truncateId } from '../utils/formatters';
53
+
54
+ export function NotificationsPage() {
55
+ const [stats, setStats] = useState<NotificationsStatsResponse | null>(null);
56
+ const [clients, setClients] = useState<NotificationsClient[]>([]);
57
+ const [loading, setLoading] = useState(true);
58
+ const [error, setError] = useState<string | null>(null);
59
+ const [success, setSuccess] = useState<string | null>(null);
60
+ const [disconnectingId, setDisconnectingId] = useState<string | null>(null);
61
+ const [reconnecting, setReconnecting] = useState(false);
62
+ const [confirmDisconnect, setConfirmDisconnect] = useState<NotificationsClient | null>(null);
63
+
64
+ // Track mounted state to prevent state updates after unmount
65
+ const isMountedRef = useRef(true);
66
+
67
+ const fetchData = useCallback(async () => {
68
+ try {
69
+ const [statsData, clientsData] = await Promise.all([
70
+ api.getNotificationsStats(),
71
+ api.getNotificationsClients(),
72
+ ]);
73
+ // Only update state if component is still mounted
74
+ if (isMountedRef.current) {
75
+ setStats(statsData);
76
+ setClients(clientsData.clients);
77
+ setError(null);
78
+ }
79
+ } catch (err) {
80
+ if (isMountedRef.current) {
81
+ if (err instanceof Error && err.message.includes('404')) {
82
+ setError('Notifications plugin not enabled');
83
+ } else {
84
+ setError(err instanceof Error ? err.message : 'Failed to fetch data');
85
+ }
86
+ }
87
+ } finally {
88
+ if (isMountedRef.current) {
89
+ setLoading(false);
90
+ }
91
+ }
92
+ }, []);
93
+
94
+ useEffect(() => {
95
+ isMountedRef.current = true;
96
+ fetchData();
97
+ const interval = setInterval(fetchData, 5000);
98
+ return () => {
99
+ isMountedRef.current = false;
100
+ clearInterval(interval);
101
+ };
102
+ }, [fetchData]);
103
+
104
+ const handleDisconnect = async (client: NotificationsClient) => {
105
+ setDisconnectingId(client.id);
106
+ setConfirmDisconnect(null);
107
+ try {
108
+ await api.disconnectNotificationsClient(client.id);
109
+ if (isMountedRef.current) {
110
+ setSuccess(`Client ${truncateId(client.id)} disconnected`);
111
+ setTimeout(() => {
112
+ if (isMountedRef.current) setSuccess(null);
113
+ }, 3000);
114
+ await fetchData();
115
+ }
116
+ } catch (err) {
117
+ if (isMountedRef.current) {
118
+ setError(err instanceof Error ? err.message : 'Failed to disconnect client');
119
+ }
120
+ } finally {
121
+ if (isMountedRef.current) {
122
+ setDisconnectingId(null);
123
+ }
124
+ }
125
+ };
126
+
127
+ const handleForceReconnect = async () => {
128
+ setReconnecting(true);
129
+ try {
130
+ const result = await api.forceNotificationsReconnect();
131
+ if (isMountedRef.current) {
132
+ setSuccess(result.message);
133
+ setTimeout(() => {
134
+ if (isMountedRef.current) setSuccess(null);
135
+ }, 3000);
136
+ await fetchData();
137
+ }
138
+ } catch (err) {
139
+ if (isMountedRef.current) {
140
+ setError(err instanceof Error ? err.message : 'Failed to force reconnect');
141
+ }
142
+ } finally {
143
+ if (isMountedRef.current) {
144
+ setReconnecting(false);
145
+ }
146
+ }
147
+ };
148
+
149
+ if (loading) {
150
+ return (
151
+ <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '50vh' }}>
152
+ <CircularProgress />
153
+ </Box>
154
+ );
155
+ }
156
+
157
+ if (error && !stats) {
158
+ return (
159
+ <Card sx={{ bgcolor: 'var(--theme-surface)', border: '1px solid var(--theme-border)' }}>
160
+ <CardContent>
161
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
162
+ <WifiOffIcon sx={{ color: 'var(--theme-text-secondary)' }} />
163
+ <Typography sx={{ color: 'var(--theme-text-secondary)' }}>{error}</Typography>
164
+ </Box>
165
+ </CardContent>
166
+ </Card>
167
+ );
168
+ }
169
+
170
+ const isHealthy = stats?.connectionHealth.isHealthy ?? false;
171
+ const healthColor = isHealthy ? 'var(--theme-success)' : 'var(--theme-warning)';
172
+
173
+ return (
174
+ <Box>
175
+ {/* Page Header */}
176
+ <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
177
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
178
+ <NotificationsIcon sx={{ color: 'var(--theme-primary)', fontSize: 32 }} />
179
+ <Typography variant="h4" sx={{ color: 'var(--theme-text-primary)' }}>
180
+ Notifications
181
+ </Typography>
182
+ </Box>
183
+ <Box sx={{ display: 'flex', gap: 1 }}>
184
+ <Tooltip title="Refresh">
185
+ <IconButton onClick={fetchData} sx={{ color: 'var(--theme-text-secondary)' }}>
186
+ <RefreshIcon />
187
+ </IconButton>
188
+ </Tooltip>
189
+ <Button
190
+ variant="outlined"
191
+ startIcon={reconnecting ? <CircularProgress size={16} /> : <RestartAltIcon />}
192
+ onClick={handleForceReconnect}
193
+ disabled={reconnecting}
194
+ sx={{ borderColor: 'var(--theme-border)' }}
195
+ >
196
+ {reconnecting ? 'Reconnecting...' : 'Force Reconnect'}
197
+ </Button>
198
+ </Box>
199
+ </Box>
200
+ <Typography variant="body2" sx={{ mb: 4, color: 'var(--theme-text-secondary)' }}>
201
+ Manage realtime notification connections and SSE clients
202
+ </Typography>
203
+
204
+ {/* Success/Error messages */}
205
+ {success && <Alert severity="success" sx={{ mb: 3 }}>{success}</Alert>}
206
+ {error && stats && <Alert severity="error" sx={{ mb: 3 }}>{error}</Alert>}
207
+
208
+ {/* Connection Status Bar */}
209
+ <Card sx={{ bgcolor: 'var(--theme-surface)', mb: 3 }}>
210
+ <CardContent sx={{ py: 1.5, '&:last-child': { pb: 1.5 } }}>
211
+ <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
212
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
213
+ {isHealthy ? (
214
+ <WifiIcon sx={{ color: healthColor, fontSize: 20 }} />
215
+ ) : (
216
+ <WifiOffIcon sx={{ color: healthColor, fontSize: 20 }} />
217
+ )}
218
+ <Typography sx={{ color: healthColor, fontWeight: 500 }}>
219
+ {isHealthy ? 'Connected' : 'Reconnecting...'}
220
+ </Typography>
221
+ {stats?.connectionHealth.isReconnecting && (
222
+ <Chip
223
+ label={`Attempt ${stats.connectionHealth.reconnectAttempts}`}
224
+ size="small"
225
+ sx={{
226
+ bgcolor: 'var(--theme-warning)20',
227
+ color: 'var(--theme-warning)',
228
+ fontSize: '0.7rem',
229
+ height: 18,
230
+ }}
231
+ />
232
+ )}
233
+ </Box>
234
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
235
+ <Typography variant="caption" sx={{ color: 'var(--theme-text-secondary)' }}>
236
+ {stats?.channels.length} channel{stats?.channels.length !== 1 ? 's' : ''}
237
+ </Typography>
238
+ {stats?.lastEventAt && (
239
+ <Typography variant="caption" sx={{ color: 'var(--theme-text-secondary)' }}>
240
+ Last event: {formatDuration(stats.connectionHealth.timeSinceLastEvent)} ago
241
+ </Typography>
242
+ )}
243
+ </Box>
244
+ </Box>
245
+ </CardContent>
246
+ </Card>
247
+
248
+ {/* Stats Grid */}
249
+ <GridLayout columns={4} spacing="small" equalHeight>
250
+ <StatCard
251
+ icon={<DevicesIcon sx={{ fontSize: 28 }} />}
252
+ label="Active Clients"
253
+ value={stats?.currentConnections ?? 0}
254
+ subValue={`${stats?.totalConnections ?? 0} total`}
255
+ color="var(--theme-primary)"
256
+ />
257
+ <StatCard
258
+ icon={<PersonIcon sx={{ fontSize: 28 }} />}
259
+ label="By Device"
260
+ value={stats?.clientsByType.device ?? 0}
261
+ subValue={`${stats?.clientsByType.user ?? 0} by user`}
262
+ color="var(--theme-info)"
263
+ />
264
+ <StatCard
265
+ icon={<SendIcon sx={{ fontSize: 28 }} />}
266
+ label="Events Routed"
267
+ value={formatNumber(stats?.eventsRouted ?? 0)}
268
+ subValue={`${formatNumber(stats?.eventsProcessed ?? 0)} processed`}
269
+ color="var(--theme-success)"
270
+ />
271
+ <StatCard
272
+ icon={<ErrorIcon sx={{ fontSize: 28 }} />}
273
+ label="Dropped"
274
+ value={formatNumber(stats?.eventsDroppedNoClients ?? 0)}
275
+ subValue={`${stats?.eventsParseFailed ?? 0} parse errors`}
276
+ color={(stats?.eventsDroppedNoClients ?? 0) > 0 ? 'var(--theme-warning)' : 'var(--theme-text-secondary)'}
277
+ />
278
+ </GridLayout>
279
+
280
+ {/* Clients Table */}
281
+ <Card sx={{ bgcolor: 'var(--theme-surface)', mt: 3 }}>
282
+ <CardContent>
283
+ <Typography variant="h6" sx={{ color: 'var(--theme-text-primary)', mb: 2 }}>
284
+ Connected Clients
285
+ </Typography>
286
+
287
+ {clients.length === 0 ? (
288
+ <Typography sx={{ color: 'var(--theme-text-secondary)', py: 4, textAlign: 'center' }}>
289
+ No clients currently connected
290
+ </Typography>
291
+ ) : (
292
+ <TableContainer component={Paper} sx={{ bgcolor: 'transparent', boxShadow: 'none' }}>
293
+ <Table size="small">
294
+ <TableHead>
295
+ <TableRow>
296
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }}>
297
+ Client ID
298
+ </TableCell>
299
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }}>
300
+ Device ID
301
+ </TableCell>
302
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }}>
303
+ User ID
304
+ </TableCell>
305
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }}>
306
+ Connected
307
+ </TableCell>
308
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }}>
309
+ Duration
310
+ </TableCell>
311
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }} align="right">
312
+ Actions
313
+ </TableCell>
314
+ </TableRow>
315
+ </TableHead>
316
+ <TableBody>
317
+ {clients.map((client) => (
318
+ <TableRow key={client.id} hover>
319
+ <TableCell sx={{ color: 'var(--theme-text-primary)', borderColor: 'var(--theme-border)' }}>
320
+ <Tooltip title={client.id}>
321
+ <code style={{ fontSize: '0.85em' }}>{truncateId(client.id)}</code>
322
+ </Tooltip>
323
+ </TableCell>
324
+ <TableCell sx={{ color: 'var(--theme-text-primary)', borderColor: 'var(--theme-border)' }}>
325
+ {client.deviceId ? (
326
+ <Tooltip title={client.deviceId}>
327
+ <Chip
328
+ size="small"
329
+ icon={<DevicesIcon sx={{ fontSize: 14 }} />}
330
+ label={truncateId(client.deviceId)}
331
+ sx={{ bgcolor: 'var(--theme-primary)20', color: 'var(--theme-primary)' }}
332
+ />
333
+ </Tooltip>
334
+ ) : (
335
+ <Typography variant="caption" sx={{ color: 'var(--theme-text-secondary)' }}>—</Typography>
336
+ )}
337
+ </TableCell>
338
+ <TableCell sx={{ color: 'var(--theme-text-primary)', borderColor: 'var(--theme-border)' }}>
339
+ {client.userId ? (
340
+ <Tooltip title={client.userId}>
341
+ <Chip
342
+ size="small"
343
+ icon={<PersonIcon sx={{ fontSize: 14 }} />}
344
+ label={truncateId(client.userId)}
345
+ sx={{ bgcolor: 'var(--theme-info)20', color: 'var(--theme-info)' }}
346
+ />
347
+ </Tooltip>
348
+ ) : (
349
+ <Typography variant="caption" sx={{ color: 'var(--theme-text-secondary)' }}>—</Typography>
350
+ )}
351
+ </TableCell>
352
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }}>
353
+ {new Date(client.connectedAt).toLocaleTimeString()}
354
+ </TableCell>
355
+ <TableCell sx={{ color: 'var(--theme-text-secondary)', borderColor: 'var(--theme-border)' }}>
356
+ {formatDuration(client.durationMs)}
357
+ </TableCell>
358
+ <TableCell sx={{ borderColor: 'var(--theme-border)' }} align="right">
359
+ <Tooltip title="Disconnect client">
360
+ <IconButton
361
+ size="small"
362
+ onClick={() => setConfirmDisconnect(client)}
363
+ disabled={disconnectingId === client.id}
364
+ sx={{ color: 'var(--theme-error)' }}
365
+ >
366
+ {disconnectingId === client.id ? (
367
+ <CircularProgress size={18} />
368
+ ) : (
369
+ <DisconnectIcon fontSize="small" />
370
+ )}
371
+ </IconButton>
372
+ </Tooltip>
373
+ </TableCell>
374
+ </TableRow>
375
+ ))}
376
+ </TableBody>
377
+ </Table>
378
+ </TableContainer>
379
+ )}
380
+ </CardContent>
381
+ </Card>
382
+
383
+ {/* Confirmation Dialog */}
384
+ <Dialog
385
+ open={!!confirmDisconnect}
386
+ onClose={() => setConfirmDisconnect(null)}
387
+ aria-labelledby="disconnect-dialog-title"
388
+ >
389
+ <DialogTitle id="disconnect-dialog-title">Disconnect Client?</DialogTitle>
390
+ <DialogContent>
391
+ <DialogContentText>
392
+ Are you sure you want to disconnect this client?
393
+ {confirmDisconnect?.deviceId && (
394
+ <><br /><strong>Device:</strong> {truncateId(confirmDisconnect.deviceId)}</>
395
+ )}
396
+ {confirmDisconnect?.userId && (
397
+ <><br /><strong>User:</strong> {truncateId(confirmDisconnect.userId)}</>
398
+ )}
399
+ <br /><br />
400
+ The client will receive a disconnect event and the connection will be closed.
401
+ The client may automatically reconnect.
402
+ </DialogContentText>
403
+ </DialogContent>
404
+ <DialogActions>
405
+ <Button onClick={() => setConfirmDisconnect(null)}>Cancel</Button>
406
+ <Button
407
+ onClick={() => confirmDisconnect && handleDisconnect(confirmDisconnect)}
408
+ color="error"
409
+ autoFocus
410
+ >
411
+ Disconnect
412
+ </Button>
413
+ </DialogActions>
414
+ </Dialog>
415
+ </Box>
416
+ );
417
+ }