@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,439 @@
1
+ /**
2
+ * PostgreSQL Profile Store
3
+ *
4
+ * Profile storage implementation using PostgreSQL.
5
+ * Includes automatic age group calculation.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import type {
11
+ ProfileStore,
12
+ Profile,
13
+ CreateProfileInput,
14
+ UpdateProfileInput,
15
+ ProfileSearchParams,
16
+ ProfileListResponse,
17
+ PostgresProfileStoreConfig,
18
+ AgeGroup,
19
+ AgeThresholds,
20
+ } from '../types.js';
21
+
22
+ // Pool interface (from pg package)
23
+ interface PgPool {
24
+ query(text: string, values?: unknown[]): Promise<{ rows: unknown[]; rowCount: number | null }>;
25
+ }
26
+
27
+ // Default age thresholds
28
+ const DEFAULT_AGE_THRESHOLDS: AgeThresholds = {
29
+ child: 12,
30
+ teen: 17,
31
+ };
32
+
33
+ /**
34
+ * Calculate age group from birth date or age
35
+ */
36
+ function calculateAgeGroup(
37
+ birthDate?: Date | null,
38
+ age?: number | null,
39
+ thresholds: AgeThresholds = DEFAULT_AGE_THRESHOLDS
40
+ ): AgeGroup | null {
41
+ let calculatedAge: number | null = null;
42
+
43
+ if (birthDate) {
44
+ const today = new Date();
45
+ const birth = new Date(birthDate);
46
+ calculatedAge = today.getFullYear() - birth.getFullYear();
47
+ const monthDiff = today.getMonth() - birth.getMonth();
48
+ if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
49
+ calculatedAge--;
50
+ }
51
+ } else if (age !== undefined && age !== null) {
52
+ calculatedAge = age;
53
+ }
54
+
55
+ if (calculatedAge === null) {
56
+ return null;
57
+ }
58
+
59
+ if (calculatedAge <= thresholds.child) {
60
+ return 'child';
61
+ } else if (calculatedAge <= thresholds.teen) {
62
+ return 'teen';
63
+ } else {
64
+ return 'adult';
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Create a PostgreSQL profile store
70
+ *
71
+ * @param config Configuration including a pg Pool instance
72
+ * @param ageThresholds Optional age thresholds for categorization
73
+ * @returns ProfileStore implementation
74
+ */
75
+ export function postgresProfileStore(
76
+ config: PostgresProfileStoreConfig,
77
+ ageThresholds: AgeThresholds = DEFAULT_AGE_THRESHOLDS
78
+ ): ProfileStore {
79
+ const {
80
+ pool: poolOrFn,
81
+ tableName = 'profiles',
82
+ schema = 'public',
83
+ autoCreateTables = true,
84
+ } = config;
85
+
86
+ // Helper to get pool (supports lazy initialization via function)
87
+ const getPool = (): PgPool => {
88
+ const pool = typeof poolOrFn === 'function' ? poolOrFn() : poolOrFn;
89
+ return pool as PgPool;
90
+ };
91
+
92
+ const profilesTableFull = `"${schema}"."${tableName}"`;
93
+
94
+ return {
95
+ name: 'postgres',
96
+
97
+ async initialize(): Promise<void> {
98
+ if (!autoCreateTables) return;
99
+
100
+ // Create profiles table
101
+ await getPool().query(`
102
+ CREATE TABLE IF NOT EXISTS ${profilesTableFull} (
103
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
104
+ org_id UUID,
105
+ user_id UUID NOT NULL,
106
+ name VARCHAR(100) NOT NULL,
107
+ avatar VARCHAR(255),
108
+
109
+ -- Age-based features
110
+ birth_date DATE,
111
+ age INTEGER,
112
+ age_group VARCHAR(20) CHECK (age_group IN ('child', 'teen', 'adult')),
113
+
114
+ -- Content/access control
115
+ content_filter_level VARCHAR(20) DEFAULT 'moderate'
116
+ CHECK (content_filter_level IN ('strict', 'moderate', 'minimal', 'none')),
117
+
118
+ -- Time restrictions
119
+ daily_time_limit_minutes INTEGER,
120
+ allowed_hours_start TIME,
121
+ allowed_hours_end TIME,
122
+
123
+ -- Status
124
+ is_active BOOLEAN DEFAULT true,
125
+ is_default BOOLEAN DEFAULT false,
126
+
127
+ -- Extensibility
128
+ metadata JSONB DEFAULT '{}',
129
+
130
+ created_at TIMESTAMPTZ DEFAULT NOW(),
131
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
132
+ deleted_at TIMESTAMPTZ
133
+ );
134
+
135
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_org ON ${profilesTableFull}(org_id) WHERE deleted_at IS NULL;
136
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_user ON ${profilesTableFull}(user_id) WHERE deleted_at IS NULL;
137
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_age_group ON ${profilesTableFull}(age_group) WHERE age_group IS NOT NULL AND deleted_at IS NULL;
138
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_${tableName}_default ON ${profilesTableFull}(user_id) WHERE is_default = true AND deleted_at IS NULL;
139
+ `);
140
+ },
141
+
142
+ async getById(id: string): Promise<Profile | null> {
143
+ const result = await getPool().query(
144
+ `SELECT * FROM ${profilesTableFull} WHERE id = $1 AND deleted_at IS NULL`,
145
+ [id]
146
+ );
147
+ return (result.rows[0] as Profile) || null;
148
+ },
149
+
150
+ async create(input: CreateProfileInput): Promise<Profile> {
151
+ // Calculate age group
152
+ const ageGroup = calculateAgeGroup(input.birth_date, input.age, ageThresholds);
153
+
154
+ // If this is set as default, unset other defaults first
155
+ if (input.is_default) {
156
+ await getPool().query(
157
+ `UPDATE ${profilesTableFull} SET is_default = false, updated_at = NOW()
158
+ WHERE user_id = $1 AND is_default = true AND deleted_at IS NULL`,
159
+ [input.user_id]
160
+ );
161
+ }
162
+
163
+ const result = await getPool().query(
164
+ `INSERT INTO ${profilesTableFull}
165
+ (org_id, user_id, name, avatar, birth_date, age, age_group,
166
+ content_filter_level, daily_time_limit_minutes,
167
+ allowed_hours_start, allowed_hours_end, is_default, metadata)
168
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
169
+ RETURNING *`,
170
+ [
171
+ input.org_id || null,
172
+ input.user_id,
173
+ input.name,
174
+ input.avatar || null,
175
+ input.birth_date || null,
176
+ input.age || null,
177
+ ageGroup,
178
+ input.content_filter_level || 'moderate',
179
+ input.daily_time_limit_minutes || null,
180
+ input.allowed_hours_start || null,
181
+ input.allowed_hours_end || null,
182
+ input.is_default || false,
183
+ JSON.stringify(input.metadata || {}),
184
+ ]
185
+ );
186
+ return result.rows[0] as Profile;
187
+ },
188
+
189
+ async update(id: string, input: UpdateProfileInput): Promise<Profile | null> {
190
+ // First get the current profile to get user_id
191
+ const current = await this.getById(id);
192
+ if (!current) {
193
+ return null;
194
+ }
195
+
196
+ const updates: string[] = [];
197
+ const values: unknown[] = [];
198
+ let paramIndex = 1;
199
+
200
+ // Handle is_default first (needs to unset others)
201
+ if (input.is_default === true) {
202
+ await getPool().query(
203
+ `UPDATE ${profilesTableFull} SET is_default = false, updated_at = NOW()
204
+ WHERE user_id = $1 AND id != $2 AND is_default = true AND deleted_at IS NULL`,
205
+ [current.user_id, id]
206
+ );
207
+ updates.push(`is_default = $${paramIndex++}`);
208
+ values.push(true);
209
+ } else if (input.is_default === false) {
210
+ updates.push(`is_default = $${paramIndex++}`);
211
+ values.push(false);
212
+ }
213
+
214
+ if (input.name !== undefined) {
215
+ updates.push(`name = $${paramIndex++}`);
216
+ values.push(input.name);
217
+ }
218
+
219
+ if (input.avatar !== undefined) {
220
+ updates.push(`avatar = $${paramIndex++}`);
221
+ values.push(input.avatar);
222
+ }
223
+
224
+ // Handle birth_date (null means clear it)
225
+ if (input.birth_date !== undefined) {
226
+ updates.push(`birth_date = $${paramIndex++}`);
227
+ values.push(input.birth_date);
228
+ }
229
+
230
+ // Handle age (null means clear it)
231
+ if (input.age !== undefined) {
232
+ updates.push(`age = $${paramIndex++}`);
233
+ values.push(input.age);
234
+ }
235
+
236
+ // Recalculate age group if birth_date or age changed
237
+ if (input.birth_date !== undefined || input.age !== undefined) {
238
+ const newBirthDate = input.birth_date !== undefined ? input.birth_date : current.birth_date;
239
+ const newAge = input.age !== undefined ? input.age : current.age;
240
+ const ageGroup = calculateAgeGroup(newBirthDate, newAge, ageThresholds);
241
+ updates.push(`age_group = $${paramIndex++}`);
242
+ values.push(ageGroup);
243
+ }
244
+
245
+ if (input.content_filter_level !== undefined) {
246
+ updates.push(`content_filter_level = $${paramIndex++}`);
247
+ values.push(input.content_filter_level);
248
+ }
249
+
250
+ if (input.daily_time_limit_minutes !== undefined) {
251
+ updates.push(`daily_time_limit_minutes = $${paramIndex++}`);
252
+ values.push(input.daily_time_limit_minutes);
253
+ }
254
+
255
+ if (input.allowed_hours_start !== undefined) {
256
+ updates.push(`allowed_hours_start = $${paramIndex++}`);
257
+ values.push(input.allowed_hours_start);
258
+ }
259
+
260
+ if (input.allowed_hours_end !== undefined) {
261
+ updates.push(`allowed_hours_end = $${paramIndex++}`);
262
+ values.push(input.allowed_hours_end);
263
+ }
264
+
265
+ if (input.is_active !== undefined) {
266
+ updates.push(`is_active = $${paramIndex++}`);
267
+ values.push(input.is_active);
268
+ }
269
+
270
+ if (input.metadata !== undefined) {
271
+ updates.push(`metadata = $${paramIndex++}`);
272
+ values.push(JSON.stringify(input.metadata));
273
+ }
274
+
275
+ if (updates.length === 0) {
276
+ return current;
277
+ }
278
+
279
+ updates.push(`updated_at = NOW()`);
280
+ values.push(id);
281
+
282
+ const result = await getPool().query(
283
+ `UPDATE ${profilesTableFull}
284
+ SET ${updates.join(', ')}
285
+ WHERE id = $${paramIndex} AND deleted_at IS NULL
286
+ RETURNING *`,
287
+ values
288
+ );
289
+ return (result.rows[0] as Profile) || null;
290
+ },
291
+
292
+ async delete(id: string): Promise<boolean> {
293
+ // Soft delete
294
+ const result = await getPool().query(
295
+ `UPDATE ${profilesTableFull}
296
+ SET deleted_at = NOW(), is_active = false, is_default = false, updated_at = NOW()
297
+ WHERE id = $1 AND deleted_at IS NULL`,
298
+ [id]
299
+ );
300
+ return (result.rowCount ?? 0) > 0;
301
+ },
302
+
303
+ async search(params: ProfileSearchParams): Promise<ProfileListResponse> {
304
+ const {
305
+ org_id,
306
+ user_id,
307
+ age_group,
308
+ is_active,
309
+ query,
310
+ page = 1,
311
+ limit = 20,
312
+ sortBy = 'created_at',
313
+ sortOrder = 'desc',
314
+ } = params;
315
+
316
+ const conditions: string[] = ['deleted_at IS NULL'];
317
+ const values: unknown[] = [];
318
+ let paramIndex = 1;
319
+
320
+ if (org_id) {
321
+ conditions.push(`org_id = $${paramIndex++}`);
322
+ values.push(org_id);
323
+ }
324
+
325
+ if (user_id) {
326
+ conditions.push(`user_id = $${paramIndex++}`);
327
+ values.push(user_id);
328
+ }
329
+
330
+ if (age_group) {
331
+ conditions.push(`age_group = $${paramIndex++}`);
332
+ values.push(age_group);
333
+ }
334
+
335
+ if (is_active !== undefined) {
336
+ conditions.push(`is_active = $${paramIndex++}`);
337
+ values.push(is_active);
338
+ }
339
+
340
+ if (query) {
341
+ conditions.push(`LOWER(name) LIKE $${paramIndex++}`);
342
+ values.push(`%${query.toLowerCase()}%`);
343
+ }
344
+
345
+ const whereClause = `WHERE ${conditions.join(' AND ')}`;
346
+
347
+ // Validate sort column to prevent SQL injection
348
+ const validSortColumns = ['name', 'created_at', 'age'];
349
+ const sortColumn = validSortColumns.includes(sortBy) ? sortBy : 'created_at';
350
+ const sortDir = sortOrder === 'asc' ? 'ASC' : 'DESC';
351
+
352
+ const offset = (page - 1) * limit;
353
+
354
+ // Get total count
355
+ const countResult = await getPool().query(
356
+ `SELECT COUNT(*) FROM ${profilesTableFull} ${whereClause}`,
357
+ values
358
+ );
359
+ const total = parseInt((countResult.rows[0] as { count: string }).count, 10);
360
+
361
+ // Get profiles
362
+ const result = await getPool().query(
363
+ `SELECT * FROM ${profilesTableFull} ${whereClause}
364
+ ORDER BY ${sortColumn} ${sortDir}
365
+ LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`,
366
+ [...values, limit, offset]
367
+ );
368
+
369
+ return {
370
+ profiles: result.rows as Profile[],
371
+ total,
372
+ page,
373
+ limit,
374
+ totalPages: Math.ceil(total / limit),
375
+ };
376
+ },
377
+
378
+ async listByUser(userId: string): Promise<Profile[]> {
379
+ const result = await getPool().query(
380
+ `SELECT * FROM ${profilesTableFull}
381
+ WHERE user_id = $1 AND deleted_at IS NULL
382
+ ORDER BY is_default DESC, created_at ASC`,
383
+ [userId]
384
+ );
385
+ return result.rows as Profile[];
386
+ },
387
+
388
+ async getDefaultProfile(userId: string): Promise<Profile | null> {
389
+ const result = await getPool().query(
390
+ `SELECT * FROM ${profilesTableFull}
391
+ WHERE user_id = $1 AND is_default = true AND deleted_at IS NULL`,
392
+ [userId]
393
+ );
394
+ return (result.rows[0] as Profile) || null;
395
+ },
396
+
397
+ async getProfileCount(userId: string): Promise<number> {
398
+ const result = await getPool().query(
399
+ `SELECT COUNT(*) FROM ${profilesTableFull}
400
+ WHERE user_id = $1 AND deleted_at IS NULL`,
401
+ [userId]
402
+ );
403
+ const row = result.rows[0] as { count: string } | undefined;
404
+ return row ? parseInt(row.count, 10) : 0;
405
+ },
406
+
407
+ async getByAgeGroup(userId: string, ageGroup: AgeGroup): Promise<Profile[]> {
408
+ const result = await getPool().query(
409
+ `SELECT * FROM ${profilesTableFull}
410
+ WHERE user_id = $1 AND age_group = $2 AND deleted_at IS NULL
411
+ ORDER BY created_at ASC`,
412
+ [userId, ageGroup]
413
+ );
414
+ return result.rows as Profile[];
415
+ },
416
+
417
+ async setDefaultProfile(profileId: string, userId: string): Promise<boolean> {
418
+ // Unset current default
419
+ await getPool().query(
420
+ `UPDATE ${profilesTableFull} SET is_default = false, updated_at = NOW()
421
+ WHERE user_id = $1 AND is_default = true AND deleted_at IS NULL`,
422
+ [userId]
423
+ );
424
+
425
+ // Set new default
426
+ const result = await getPool().query(
427
+ `UPDATE ${profilesTableFull} SET is_default = true, updated_at = NOW()
428
+ WHERE id = $1 AND user_id = $2 AND deleted_at IS NULL`,
429
+ [profileId, userId]
430
+ );
431
+
432
+ return (result.rowCount ?? 0) > 0;
433
+ },
434
+
435
+ async shutdown(): Promise<void> {
436
+ // Pool is managed externally, nothing to do here
437
+ },
438
+ };
439
+ }