@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.
- package/README.md +157 -0
- package/dist/core/control-panel.d.ts.map +1 -1
- package/dist/core/control-panel.js +114 -0
- package/dist/core/control-panel.js.map +1 -1
- package/dist/core/types.d.ts +19 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/plugins/auth/adapter-wrapper.d.ts +47 -0
- package/dist/plugins/auth/adapter-wrapper.d.ts.map +1 -0
- package/dist/plugins/auth/adapter-wrapper.js +166 -0
- package/dist/plugins/auth/adapter-wrapper.js.map +1 -0
- package/dist/plugins/auth/adapter-wrapper.test.d.ts +7 -0
- package/dist/plugins/auth/adapter-wrapper.test.d.ts.map +1 -0
- package/dist/plugins/auth/adapter-wrapper.test.js +303 -0
- package/dist/plugins/auth/adapter-wrapper.test.js.map +1 -0
- package/dist/plugins/auth/config-store.d.ts +11 -0
- package/dist/plugins/auth/config-store.d.ts.map +1 -0
- package/dist/plugins/auth/config-store.js +232 -0
- package/dist/plugins/auth/config-store.js.map +1 -0
- package/dist/plugins/auth/config-store.test.d.ts +7 -0
- package/dist/plugins/auth/config-store.test.d.ts.map +1 -0
- package/dist/plugins/auth/config-store.test.js +299 -0
- package/dist/plugins/auth/config-store.test.js.map +1 -0
- package/dist/plugins/auth/env-config.d.ts +51 -1
- package/dist/plugins/auth/env-config.d.ts.map +1 -1
- package/dist/plugins/auth/env-config.js +640 -7
- package/dist/plugins/auth/env-config.js.map +1 -1
- package/dist/plugins/auth/index.d.ts +6 -2
- package/dist/plugins/auth/index.d.ts.map +1 -1
- package/dist/plugins/auth/index.js +5 -1
- package/dist/plugins/auth/index.js.map +1 -1
- package/dist/plugins/auth/types.d.ts +106 -0
- package/dist/plugins/auth/types.d.ts.map +1 -1
- package/dist/plugins/bans/bans-plugin.d.ts.map +1 -1
- package/dist/plugins/bans/bans-plugin.js +12 -3
- package/dist/plugins/bans/bans-plugin.js.map +1 -1
- package/dist/plugins/devices/__tests__/devices-plugin.test.d.ts +11 -0
- package/dist/plugins/devices/__tests__/devices-plugin.test.d.ts.map +1 -0
- package/dist/plugins/devices/__tests__/devices-plugin.test.js +410 -0
- package/dist/plugins/devices/__tests__/devices-plugin.test.js.map +1 -0
- package/dist/plugins/devices/__tests__/token-utils.test.d.ts +7 -0
- package/dist/plugins/devices/__tests__/token-utils.test.d.ts.map +1 -0
- package/dist/plugins/devices/__tests__/token-utils.test.js +197 -0
- package/dist/plugins/devices/__tests__/token-utils.test.js.map +1 -0
- package/dist/plugins/devices/adapters/compute-adapter.d.ts +36 -0
- package/dist/plugins/devices/adapters/compute-adapter.d.ts.map +1 -0
- package/dist/plugins/devices/adapters/compute-adapter.js +100 -0
- package/dist/plugins/devices/adapters/compute-adapter.js.map +1 -0
- package/dist/plugins/devices/adapters/index.d.ts +12 -0
- package/dist/plugins/devices/adapters/index.d.ts.map +1 -0
- package/dist/plugins/devices/adapters/index.js +10 -0
- package/dist/plugins/devices/adapters/index.js.map +1 -0
- package/dist/plugins/devices/adapters/mobile-adapter.d.ts +41 -0
- package/dist/plugins/devices/adapters/mobile-adapter.d.ts.map +1 -0
- package/dist/plugins/devices/adapters/mobile-adapter.js +131 -0
- package/dist/plugins/devices/adapters/mobile-adapter.js.map +1 -0
- package/dist/plugins/devices/devices-plugin.d.ts +70 -0
- package/dist/plugins/devices/devices-plugin.d.ts.map +1 -0
- package/dist/plugins/devices/devices-plugin.js +453 -0
- package/dist/plugins/devices/devices-plugin.js.map +1 -0
- package/dist/plugins/devices/index.d.ts +18 -0
- package/dist/plugins/devices/index.d.ts.map +1 -0
- package/dist/plugins/devices/index.js +18 -0
- package/dist/plugins/devices/index.js.map +1 -0
- package/dist/plugins/devices/stores/index.d.ts +9 -0
- package/dist/plugins/devices/stores/index.d.ts.map +1 -0
- package/dist/plugins/devices/stores/index.js +9 -0
- package/dist/plugins/devices/stores/index.js.map +1 -0
- package/dist/plugins/devices/stores/postgres-store.d.ts +26 -0
- package/dist/plugins/devices/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/devices/stores/postgres-store.js +199 -0
- package/dist/plugins/devices/stores/postgres-store.js.map +1 -0
- package/dist/plugins/devices/token-utils.d.ts +100 -0
- package/dist/plugins/devices/token-utils.d.ts.map +1 -0
- package/dist/plugins/devices/token-utils.js +162 -0
- package/dist/plugins/devices/token-utils.js.map +1 -0
- package/dist/plugins/devices/types.d.ts +307 -0
- package/dist/plugins/devices/types.d.ts.map +1 -0
- package/dist/plugins/devices/types.js +10 -0
- package/dist/plugins/devices/types.js.map +1 -0
- package/dist/plugins/index.d.ts +18 -4
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +16 -2
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/notifications/__tests__/notifications-manager.test.d.ts +5 -0
- package/dist/plugins/notifications/__tests__/notifications-manager.test.d.ts.map +1 -0
- package/dist/plugins/notifications/__tests__/notifications-manager.test.js +470 -0
- package/dist/plugins/notifications/__tests__/notifications-manager.test.js.map +1 -0
- package/dist/plugins/notifications/index.d.ts +71 -0
- package/dist/plugins/notifications/index.d.ts.map +1 -0
- package/dist/plugins/notifications/index.js +72 -0
- package/dist/plugins/notifications/index.js.map +1 -0
- package/dist/plugins/notifications/notifications-manager.d.ts +182 -0
- package/dist/plugins/notifications/notifications-manager.d.ts.map +1 -0
- package/dist/plugins/notifications/notifications-manager.js +610 -0
- package/dist/plugins/notifications/notifications-manager.js.map +1 -0
- package/dist/plugins/notifications/notifications-plugin.d.ts +83 -0
- package/dist/plugins/notifications/notifications-plugin.d.ts.map +1 -0
- package/dist/plugins/notifications/notifications-plugin.js +337 -0
- package/dist/plugins/notifications/notifications-plugin.js.map +1 -0
- package/dist/plugins/notifications/types.d.ts +164 -0
- package/dist/plugins/notifications/types.d.ts.map +1 -0
- package/dist/plugins/notifications/types.js +9 -0
- package/dist/plugins/notifications/types.js.map +1 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.d.ts +12 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.d.ts.map +1 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.js +349 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.js.map +1 -0
- package/dist/plugins/parental/adapters/index.d.ts +8 -0
- package/dist/plugins/parental/adapters/index.d.ts.map +1 -0
- package/dist/plugins/parental/adapters/index.js +7 -0
- package/dist/plugins/parental/adapters/index.js.map +1 -0
- package/dist/plugins/parental/adapters/kids-adapter.d.ts +24 -0
- package/dist/plugins/parental/adapters/kids-adapter.d.ts.map +1 -0
- package/dist/plugins/parental/adapters/kids-adapter.js +174 -0
- package/dist/plugins/parental/adapters/kids-adapter.js.map +1 -0
- package/dist/plugins/parental/index.d.ts +14 -0
- package/dist/plugins/parental/index.d.ts.map +1 -0
- package/dist/plugins/parental/index.js +15 -0
- package/dist/plugins/parental/index.js.map +1 -0
- package/dist/plugins/parental/parental-plugin.d.ts +88 -0
- package/dist/plugins/parental/parental-plugin.d.ts.map +1 -0
- package/dist/plugins/parental/parental-plugin.js +666 -0
- package/dist/plugins/parental/parental-plugin.js.map +1 -0
- package/dist/plugins/parental/stores/index.d.ts +7 -0
- package/dist/plugins/parental/stores/index.d.ts.map +1 -0
- package/dist/plugins/parental/stores/index.js +7 -0
- package/dist/plugins/parental/stores/index.js.map +1 -0
- package/dist/plugins/parental/stores/postgres-store.d.ts +10 -0
- package/dist/plugins/parental/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/parental/stores/postgres-store.js +209 -0
- package/dist/plugins/parental/stores/postgres-store.js.map +1 -0
- package/dist/plugins/parental/types.d.ts +154 -0
- package/dist/plugins/parental/types.d.ts.map +1 -0
- package/dist/plugins/parental/types.js +10 -0
- package/dist/plugins/parental/types.js.map +1 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.d.ts +11 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.d.ts.map +1 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.js +243 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.js.map +1 -0
- package/dist/plugins/profiles/index.d.ts +12 -0
- package/dist/plugins/profiles/index.d.ts.map +1 -0
- package/dist/plugins/profiles/index.js +13 -0
- package/dist/plugins/profiles/index.js.map +1 -0
- package/dist/plugins/profiles/profiles-plugin.d.ts +71 -0
- package/dist/plugins/profiles/profiles-plugin.d.ts.map +1 -0
- package/dist/plugins/profiles/profiles-plugin.js +481 -0
- package/dist/plugins/profiles/profiles-plugin.js.map +1 -0
- package/dist/plugins/profiles/stores/index.d.ts +9 -0
- package/dist/plugins/profiles/stores/index.d.ts.map +1 -0
- package/dist/plugins/profiles/stores/index.js +9 -0
- package/dist/plugins/profiles/stores/index.js.map +1 -0
- package/dist/plugins/profiles/stores/postgres-store.d.ts +18 -0
- package/dist/plugins/profiles/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/profiles/stores/postgres-store.js +310 -0
- package/dist/plugins/profiles/stores/postgres-store.js.map +1 -0
- package/dist/plugins/profiles/types.d.ts +289 -0
- package/dist/plugins/profiles/types.d.ts.map +1 -0
- package/dist/plugins/profiles/types.js +10 -0
- package/dist/plugins/profiles/types.js.map +1 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts +7 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts.map +1 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js +220 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js.map +1 -0
- package/dist/plugins/rate-limit/cleanup.d.ts +40 -0
- package/dist/plugins/rate-limit/cleanup.d.ts.map +1 -0
- package/dist/plugins/rate-limit/cleanup.js +72 -0
- package/dist/plugins/rate-limit/cleanup.js.map +1 -0
- package/dist/plugins/rate-limit/env-config.d.ts +91 -0
- package/dist/plugins/rate-limit/env-config.d.ts.map +1 -0
- package/dist/plugins/rate-limit/env-config.js +318 -0
- package/dist/plugins/rate-limit/env-config.js.map +1 -0
- package/dist/plugins/rate-limit/index.d.ts +76 -0
- package/dist/plugins/rate-limit/index.d.ts.map +1 -0
- package/dist/plugins/rate-limit/index.js +79 -0
- package/dist/plugins/rate-limit/index.js.map +1 -0
- package/dist/plugins/rate-limit/middleware.d.ts +40 -0
- package/dist/plugins/rate-limit/middleware.d.ts.map +1 -0
- package/dist/plugins/rate-limit/middleware.js +169 -0
- package/dist/plugins/rate-limit/middleware.js.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.d.ts +44 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.d.ts.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.js +354 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.js.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-service.d.ts +110 -0
- package/dist/plugins/rate-limit/rate-limit-service.d.ts.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-service.js +172 -0
- package/dist/plugins/rate-limit/rate-limit-service.js.map +1 -0
- package/dist/plugins/rate-limit/stores/cache-store.d.ts +33 -0
- package/dist/plugins/rate-limit/stores/cache-store.d.ts.map +1 -0
- package/dist/plugins/rate-limit/stores/cache-store.js +225 -0
- package/dist/plugins/rate-limit/stores/cache-store.js.map +1 -0
- package/dist/plugins/rate-limit/stores/index.d.ts +8 -0
- package/dist/plugins/rate-limit/stores/index.d.ts.map +1 -0
- package/dist/plugins/rate-limit/stores/index.js +8 -0
- package/dist/plugins/rate-limit/stores/index.js.map +1 -0
- package/dist/plugins/rate-limit/stores/postgres-store.d.ts +34 -0
- package/dist/plugins/rate-limit/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/rate-limit/stores/postgres-store.js +320 -0
- package/dist/plugins/rate-limit/stores/postgres-store.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.d.ts +21 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.js +97 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/index.d.ts +14 -0
- package/dist/plugins/rate-limit/strategies/index.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/index.js +27 -0
- package/dist/plugins/rate-limit/strategies/index.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.d.ts +22 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.js +122 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.d.ts +28 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.js +121 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.js.map +1 -0
- package/dist/plugins/rate-limit/types.d.ts +265 -0
- package/dist/plugins/rate-limit/types.d.ts.map +1 -0
- package/dist/plugins/rate-limit/types.js +9 -0
- package/dist/plugins/rate-limit/types.js.map +1 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.d.ts +11 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.d.ts.map +1 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.js +305 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.js.map +1 -0
- package/dist/plugins/subscriptions/index.d.ts +12 -0
- package/dist/plugins/subscriptions/index.d.ts.map +1 -0
- package/dist/plugins/subscriptions/index.js +13 -0
- package/dist/plugins/subscriptions/index.js.map +1 -0
- package/dist/plugins/subscriptions/stores/index.d.ts +9 -0
- package/dist/plugins/subscriptions/stores/index.d.ts.map +1 -0
- package/dist/plugins/subscriptions/stores/index.js +9 -0
- package/dist/plugins/subscriptions/stores/index.js.map +1 -0
- package/dist/plugins/subscriptions/stores/postgres-store.d.ts +14 -0
- package/dist/plugins/subscriptions/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/subscriptions/stores/postgres-store.js +359 -0
- package/dist/plugins/subscriptions/stores/postgres-store.js.map +1 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.d.ts +82 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.d.ts.map +1 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.js +449 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.js.map +1 -0
- package/dist/plugins/subscriptions/types.d.ts +308 -0
- package/dist/plugins/subscriptions/types.d.ts.map +1 -0
- package/dist/plugins/subscriptions/types.js +10 -0
- package/dist/plugins/subscriptions/types.js.map +1 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.d.ts +11 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.d.ts.map +1 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.js +218 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.js.map +1 -0
- package/dist/plugins/usage/index.d.ts +12 -0
- package/dist/plugins/usage/index.d.ts.map +1 -0
- package/dist/plugins/usage/index.js +13 -0
- package/dist/plugins/usage/index.js.map +1 -0
- package/dist/plugins/usage/stores/index.d.ts +9 -0
- package/dist/plugins/usage/stores/index.d.ts.map +1 -0
- package/dist/plugins/usage/stores/index.js +9 -0
- package/dist/plugins/usage/stores/index.js.map +1 -0
- package/dist/plugins/usage/stores/postgres-store.d.ts +14 -0
- package/dist/plugins/usage/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/usage/stores/postgres-store.js +146 -0
- package/dist/plugins/usage/stores/postgres-store.js.map +1 -0
- package/dist/plugins/usage/types.d.ts +195 -0
- package/dist/plugins/usage/types.d.ts.map +1 -0
- package/dist/plugins/usage/types.js +10 -0
- package/dist/plugins/usage/types.js.map +1 -0
- package/dist/plugins/usage/usage-plugin.d.ts +51 -0
- package/dist/plugins/usage/usage-plugin.d.ts.map +1 -0
- package/dist/plugins/usage/usage-plugin.js +412 -0
- package/dist/plugins/usage/usage-plugin.js.map +1 -0
- package/dist/plugins/users/__tests__/postgres-store.test.d.ts +10 -0
- package/dist/plugins/users/__tests__/postgres-store.test.d.ts.map +1 -0
- package/dist/plugins/users/__tests__/postgres-store.test.js +229 -0
- package/dist/plugins/users/__tests__/postgres-store.test.js.map +1 -0
- package/dist/plugins/users/__tests__/users-plugin.test.js +3 -0
- package/dist/plugins/users/__tests__/users-plugin.test.js.map +1 -1
- package/dist/plugins/users/index.d.ts +2 -2
- package/dist/plugins/users/index.d.ts.map +1 -1
- package/dist/plugins/users/index.js +1 -1
- package/dist/plugins/users/index.js.map +1 -1
- package/dist/plugins/users/stores/postgres-store.d.ts.map +1 -1
- package/dist/plugins/users/stores/postgres-store.js +76 -0
- package/dist/plugins/users/stores/postgres-store.js.map +1 -1
- package/dist/plugins/users/types.d.ts +74 -6
- package/dist/plugins/users/types.d.ts.map +1 -1
- package/dist/plugins/users/users-plugin.d.ts +15 -1
- package/dist/plugins/users/users-plugin.d.ts.map +1 -1
- package/dist/plugins/users/users-plugin.js +29 -0
- package/dist/plugins/users/users-plugin.js.map +1 -1
- package/dist-ui/assets/index-CynOqPkb.js +469 -0
- package/dist-ui/assets/{index-BY8OxNgO.js.map → index-CynOqPkb.js.map} +1 -1
- package/dist-ui/index.html +1 -1
- package/dist-ui-lib/api/controlPanelApi.d.ts +187 -0
- package/dist-ui-lib/components/StatCard.d.ts +16 -0
- package/dist-ui-lib/dashboard/widgets/AuthStatusWidget.d.ts +9 -0
- package/dist-ui-lib/dashboard/widgets/IntegrationStatusWidget.d.ts +9 -0
- package/dist-ui-lib/dashboard/widgets/NotificationsStatsWidget.d.ts +12 -0
- package/dist-ui-lib/dashboard/widgets/index.d.ts +3 -0
- package/dist-ui-lib/index.js +3579 -2379
- package/dist-ui-lib/index.js.map +1 -1
- package/dist-ui-lib/pages/IntegrationsPage.d.ts +1 -0
- package/dist-ui-lib/pages/NotificationsPage.d.ts +9 -0
- package/dist-ui-lib/pages/RateLimitPage.d.ts +1 -0
- package/dist-ui-lib/utils/formatters.d.ts +19 -0
- package/package.json +1 -1
- package/src/core/control-panel.ts +128 -0
- package/src/core/types.ts +17 -0
- package/src/index.ts +216 -0
- package/src/plugins/auth/adapter-wrapper.test.ts +395 -0
- package/src/plugins/auth/adapter-wrapper.ts +205 -0
- package/src/plugins/auth/config-store.test.ts +417 -0
- package/src/plugins/auth/config-store.ts +305 -0
- package/src/plugins/auth/env-config.ts +714 -7
- package/src/plugins/auth/index.ts +22 -1
- package/src/plugins/auth/types.ts +138 -0
- package/src/plugins/bans/bans-plugin.ts +15 -3
- package/src/plugins/devices/__tests__/devices-plugin.test.ts +551 -0
- package/src/plugins/devices/__tests__/token-utils.test.ts +264 -0
- package/src/plugins/devices/adapters/compute-adapter.ts +139 -0
- package/src/plugins/devices/adapters/index.ts +13 -0
- package/src/plugins/devices/adapters/mobile-adapter.ts +179 -0
- package/src/plugins/devices/devices-plugin.ts +538 -0
- package/src/plugins/devices/index.ts +69 -0
- package/src/plugins/devices/stores/index.ts +9 -0
- package/src/plugins/devices/stores/postgres-store.ts +304 -0
- package/src/plugins/devices/token-utils.ts +213 -0
- package/src/plugins/devices/types.ts +351 -0
- package/src/plugins/index.ts +267 -0
- package/src/plugins/notifications/__tests__/notifications-manager.test.ts +637 -0
- package/src/plugins/notifications/index.ts +91 -0
- package/src/plugins/notifications/notifications-manager.ts +773 -0
- package/src/plugins/notifications/notifications-plugin.ts +398 -0
- package/src/plugins/notifications/types.ts +207 -0
- package/src/plugins/parental/__tests__/parental-plugin.test.ts +465 -0
- package/src/plugins/parental/adapters/index.ts +8 -0
- package/src/plugins/parental/adapters/kids-adapter.ts +206 -0
- package/src/plugins/parental/index.ts +55 -0
- package/src/plugins/parental/parental-plugin.ts +759 -0
- package/src/plugins/parental/stores/index.ts +7 -0
- package/src/plugins/parental/stores/postgres-store.ts +304 -0
- package/src/plugins/parental/types.ts +180 -0
- package/src/plugins/profiles/__tests__/profiles-plugin.test.ts +321 -0
- package/src/plugins/profiles/index.ts +49 -0
- package/src/plugins/profiles/profiles-plugin.ts +546 -0
- package/src/plugins/profiles/stores/index.ts +9 -0
- package/src/plugins/profiles/stores/postgres-store.ts +439 -0
- package/src/plugins/profiles/types.ts +338 -0
- package/src/plugins/rate-limit/__tests__/rate-limit-plugin.test.ts +259 -0
- package/src/plugins/rate-limit/cleanup.ts +117 -0
- package/src/plugins/rate-limit/env-config.ts +400 -0
- package/src/plugins/rate-limit/index.ts +128 -0
- package/src/plugins/rate-limit/middleware.ts +212 -0
- package/src/plugins/rate-limit/rate-limit-plugin.ts +400 -0
- package/src/plugins/rate-limit/rate-limit-service.ts +228 -0
- package/src/plugins/rate-limit/stores/cache-store.ts +261 -0
- package/src/plugins/rate-limit/stores/index.ts +8 -0
- package/src/plugins/rate-limit/stores/postgres-store.ts +402 -0
- package/src/plugins/rate-limit/strategies/fixed-window.ts +116 -0
- package/src/plugins/rate-limit/strategies/index.ts +30 -0
- package/src/plugins/rate-limit/strategies/sliding-window.ts +157 -0
- package/src/plugins/rate-limit/strategies/token-bucket.ts +154 -0
- package/src/plugins/rate-limit/types.ts +338 -0
- package/src/plugins/subscriptions/__tests__/subscriptions-plugin.test.ts +404 -0
- package/src/plugins/subscriptions/index.ts +51 -0
- package/src/plugins/subscriptions/stores/index.ts +9 -0
- package/src/plugins/subscriptions/stores/postgres-store.ts +482 -0
- package/src/plugins/subscriptions/subscriptions-plugin.ts +530 -0
- package/src/plugins/subscriptions/types.ts +355 -0
- package/src/plugins/usage/__tests__/usage-plugin.test.ts +288 -0
- package/src/plugins/usage/index.ts +39 -0
- package/src/plugins/usage/stores/index.ts +9 -0
- package/src/plugins/usage/stores/postgres-store.ts +213 -0
- package/src/plugins/usage/types.ts +222 -0
- package/src/plugins/usage/usage-plugin.ts +484 -0
- package/src/plugins/users/__tests__/postgres-store.test.ts +326 -0
- package/src/plugins/users/__tests__/users-plugin.test.ts +3 -0
- package/src/plugins/users/index.ts +6 -0
- package/src/plugins/users/stores/postgres-store.ts +104 -0
- package/src/plugins/users/types.ts +82 -6
- package/src/plugins/users/users-plugin.ts +37 -0
- package/ui/src/App.tsx +36 -14
- package/ui/src/api/controlPanelApi.ts +329 -6
- package/ui/src/components/StatCard.tsx +58 -0
- package/ui/src/dashboard/builtInWidgets.tsx +7 -1
- package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +143 -0
- package/ui/src/dashboard/widgets/IntegrationStatusWidget.tsx +135 -0
- package/ui/src/dashboard/widgets/NotificationsStatsWidget.tsx +167 -0
- package/ui/src/dashboard/widgets/index.ts +3 -0
- package/ui/src/pages/AuthPage.tsx +986 -142
- package/ui/src/pages/IntegrationsPage.tsx +288 -0
- package/ui/src/pages/NotificationsPage.tsx +417 -0
- package/ui/src/pages/RateLimitPage.tsx +292 -0
- package/ui/src/utils/formatters.ts +33 -0
- package/dist-ui/assets/index-BY8OxNgO.js +0 -465
package/ui/src/App.tsx
CHANGED
|
@@ -3,13 +3,21 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
|
3
3
|
import { QwickApp, ProductLogo, Text } from '@qwickapps/react-framework';
|
|
4
4
|
import { Link, Box } from '@mui/material';
|
|
5
5
|
import { defaultConfig } from './config/AppConfig';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
DashboardWidgetProvider,
|
|
8
|
+
WidgetComponentRegistryProvider,
|
|
9
|
+
getBuiltInWidgetComponents,
|
|
10
|
+
} from './dashboard';
|
|
7
11
|
import { DashboardPage } from './pages/DashboardPage';
|
|
8
12
|
import { LogsPage } from './pages/LogsPage';
|
|
9
13
|
import { SystemPage } from './pages/SystemPage';
|
|
10
14
|
import { PluginsPage } from './pages/PluginsPage';
|
|
11
15
|
import { UsersPage } from './pages/UsersPage';
|
|
12
16
|
import { EntitlementsPage } from './pages/EntitlementsPage';
|
|
17
|
+
import { AuthPage } from './pages/AuthPage';
|
|
18
|
+
import { RateLimitPage } from './pages/RateLimitPage';
|
|
19
|
+
import { NotificationsPage } from './pages/NotificationsPage';
|
|
20
|
+
import { IntegrationsPage } from './pages/IntegrationsPage';
|
|
13
21
|
import { PluginPage } from './pages/PluginPage';
|
|
14
22
|
import { NotFoundPage } from './pages/NotFoundPage';
|
|
15
23
|
import { api, type MenuContribution } from './api/controlPanelApi';
|
|
@@ -36,7 +44,7 @@ const builtInPluginNavItems: Record<string, NavigationItem> = {
|
|
|
36
44
|
};
|
|
37
45
|
|
|
38
46
|
// Routes that have dedicated page components
|
|
39
|
-
const dedicatedRoutes = new Set(['/', '/plugins', '/logs', '/system', '/users', '/entitlements']);
|
|
47
|
+
const dedicatedRoutes = new Set(['/', '/plugins', '/logs', '/system', '/users', '/entitlements', '/auth', '/rate-limits', '/notifications', '/integrations']);
|
|
40
48
|
|
|
41
49
|
// Package version - injected at build time or fallback
|
|
42
50
|
const SERVER_VERSION = '1.0.0';
|
|
@@ -177,16 +185,17 @@ export function App() {
|
|
|
177
185
|
|
|
178
186
|
return (
|
|
179
187
|
<BrowserRouter basename={basePath || undefined}>
|
|
180
|
-
<
|
|
181
|
-
<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
<WidgetComponentRegistryProvider initialComponents={getBuiltInWidgetComponents()}>
|
|
189
|
+
<DashboardWidgetProvider>
|
|
190
|
+
<QwickApp
|
|
191
|
+
config={defaultConfig}
|
|
192
|
+
logo={logo}
|
|
193
|
+
footerContent={footerContent}
|
|
194
|
+
enableScaffolding={true}
|
|
195
|
+
navigationItems={navigationItems}
|
|
196
|
+
showThemeSwitcher={true}
|
|
197
|
+
showPaletteSwitcher={true}
|
|
198
|
+
>
|
|
190
199
|
<Routes>
|
|
191
200
|
{/* Core routes */}
|
|
192
201
|
<Route path="/" element={<DashboardPage />} />
|
|
@@ -201,6 +210,18 @@ export function App() {
|
|
|
201
210
|
{registeredPlugins.has('entitlements') && (
|
|
202
211
|
<Route path="/entitlements" element={<EntitlementsPage />} />
|
|
203
212
|
)}
|
|
213
|
+
{registeredPlugins.has('auth') && (
|
|
214
|
+
<Route path="/auth" element={<AuthPage />} />
|
|
215
|
+
)}
|
|
216
|
+
{registeredPlugins.has('rate-limit') && (
|
|
217
|
+
<Route path="/rate-limits" element={<RateLimitPage />} />
|
|
218
|
+
)}
|
|
219
|
+
{registeredPlugins.has('notifications') && (
|
|
220
|
+
<Route path="/notifications" element={<NotificationsPage />} />
|
|
221
|
+
)}
|
|
222
|
+
{registeredPlugins.has('ai-proxy') && (
|
|
223
|
+
<Route path="/integrations" element={<IntegrationsPage />} />
|
|
224
|
+
)}
|
|
204
225
|
|
|
205
226
|
{/* Dynamic plugin routes - render generic PluginPage for non-dedicated routes */}
|
|
206
227
|
{pluginMenuItems
|
|
@@ -215,8 +236,9 @@ export function App() {
|
|
|
215
236
|
|
|
216
237
|
<Route path="*" element={<NotFoundPage />} />
|
|
217
238
|
</Routes>
|
|
218
|
-
|
|
219
|
-
|
|
239
|
+
</QwickApp>
|
|
240
|
+
</DashboardWidgetProvider>
|
|
241
|
+
</WidgetComponentRegistryProvider>
|
|
220
242
|
</BrowserRouter>
|
|
221
243
|
);
|
|
222
244
|
}
|
|
@@ -255,6 +255,7 @@ export interface PluginDetailResponse {
|
|
|
255
255
|
// ==================
|
|
256
256
|
|
|
257
257
|
export type AuthPluginState = 'disabled' | 'enabled' | 'error';
|
|
258
|
+
export type AuthAdapterType = 'auth0' | 'supabase' | 'supertokens' | 'basic';
|
|
258
259
|
|
|
259
260
|
export interface AuthConfigStatus {
|
|
260
261
|
state: AuthPluginState;
|
|
@@ -262,6 +263,163 @@ export interface AuthConfigStatus {
|
|
|
262
263
|
error?: string;
|
|
263
264
|
missingVars?: string[];
|
|
264
265
|
config?: Record<string, string>;
|
|
266
|
+
/** Runtime config from database (if available) */
|
|
267
|
+
runtimeConfig?: RuntimeAuthConfig;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface RuntimeAuthConfig {
|
|
271
|
+
adapter: AuthAdapterType | null;
|
|
272
|
+
config: {
|
|
273
|
+
auth0?: Auth0AdapterConfig;
|
|
274
|
+
supabase?: SupabaseAdapterConfig;
|
|
275
|
+
supertokens?: SupertokensAdapterConfig;
|
|
276
|
+
basic?: BasicAdapterConfig;
|
|
277
|
+
};
|
|
278
|
+
settings: {
|
|
279
|
+
authRequired?: boolean;
|
|
280
|
+
excludePaths?: string[];
|
|
281
|
+
debug?: boolean;
|
|
282
|
+
};
|
|
283
|
+
updatedAt: string;
|
|
284
|
+
updatedBy?: string;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export interface Auth0AdapterConfig {
|
|
288
|
+
domain: string;
|
|
289
|
+
clientId: string;
|
|
290
|
+
clientSecret: string;
|
|
291
|
+
baseUrl: string;
|
|
292
|
+
secret: string;
|
|
293
|
+
audience?: string;
|
|
294
|
+
scopes?: string[];
|
|
295
|
+
allowedRoles?: string[];
|
|
296
|
+
allowedDomains?: string[];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface SupabaseAdapterConfig {
|
|
300
|
+
url: string;
|
|
301
|
+
anonKey: string;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export interface BasicAdapterConfig {
|
|
305
|
+
username: string;
|
|
306
|
+
password: string;
|
|
307
|
+
realm?: string;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export interface SupertokensAdapterConfig {
|
|
311
|
+
connectionUri: string;
|
|
312
|
+
apiKey?: string;
|
|
313
|
+
appName: string;
|
|
314
|
+
apiDomain: string;
|
|
315
|
+
websiteDomain: string;
|
|
316
|
+
apiBasePath?: string;
|
|
317
|
+
websiteBasePath?: string;
|
|
318
|
+
enableEmailPassword?: boolean;
|
|
319
|
+
socialProviders?: {
|
|
320
|
+
google?: { clientId: string; clientSecret: string };
|
|
321
|
+
apple?: { clientId: string; clientSecret: string; keyId: string; teamId: string };
|
|
322
|
+
github?: { clientId: string; clientSecret: string };
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface UpdateAuthConfigRequest {
|
|
327
|
+
adapter: AuthAdapterType;
|
|
328
|
+
config: Record<string, unknown>;
|
|
329
|
+
settings?: {
|
|
330
|
+
authRequired?: boolean;
|
|
331
|
+
excludePaths?: string[];
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export interface TestProviderRequest {
|
|
336
|
+
adapter: AuthAdapterType;
|
|
337
|
+
config: Record<string, unknown>;
|
|
338
|
+
provider?: 'google' | 'github' | 'apple';
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export interface TestProviderResponse {
|
|
342
|
+
success: boolean;
|
|
343
|
+
message: string;
|
|
344
|
+
details?: {
|
|
345
|
+
latency?: number;
|
|
346
|
+
version?: string;
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ==================
|
|
351
|
+
// Notifications API Types
|
|
352
|
+
// ==================
|
|
353
|
+
|
|
354
|
+
export interface NotificationsConnectionHealth {
|
|
355
|
+
isConnected: boolean;
|
|
356
|
+
isHealthy: boolean;
|
|
357
|
+
lastEventAt: string | null;
|
|
358
|
+
timeSinceLastEvent: number;
|
|
359
|
+
channelCount: number;
|
|
360
|
+
isReconnecting: boolean;
|
|
361
|
+
reconnectAttempts: number;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export interface NotificationsStatsResponse {
|
|
365
|
+
totalConnections: number;
|
|
366
|
+
currentConnections: number;
|
|
367
|
+
eventsProcessed: number;
|
|
368
|
+
eventsRouted: number;
|
|
369
|
+
eventsParseFailed: number;
|
|
370
|
+
eventsDroppedNoClients: number;
|
|
371
|
+
reconnectionAttempts: number;
|
|
372
|
+
lastReconnectionAt?: string;
|
|
373
|
+
clientsByType: {
|
|
374
|
+
device: number;
|
|
375
|
+
user: number;
|
|
376
|
+
};
|
|
377
|
+
connectionHealth: NotificationsConnectionHealth;
|
|
378
|
+
channels: string[];
|
|
379
|
+
lastEventAt?: string;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export interface NotificationsClient {
|
|
383
|
+
id: string;
|
|
384
|
+
deviceId?: string;
|
|
385
|
+
userId?: string;
|
|
386
|
+
connectedAt: string;
|
|
387
|
+
durationMs: number;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export interface NotificationsClientsResponse {
|
|
391
|
+
clients: NotificationsClient[];
|
|
392
|
+
total: number;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ==================
|
|
396
|
+
// Rate Limit Config Types
|
|
397
|
+
// ==================
|
|
398
|
+
|
|
399
|
+
export type RateLimitStrategy = 'sliding-window' | 'fixed-window' | 'token-bucket';
|
|
400
|
+
|
|
401
|
+
export interface RateLimitConfig {
|
|
402
|
+
windowMs: number;
|
|
403
|
+
maxRequests: number;
|
|
404
|
+
strategy: RateLimitStrategy;
|
|
405
|
+
cleanupEnabled: boolean;
|
|
406
|
+
cleanupIntervalMs: number;
|
|
407
|
+
store: string;
|
|
408
|
+
cache: string;
|
|
409
|
+
cacheAvailable: boolean;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
export interface RateLimitConfigUpdateRequest {
|
|
413
|
+
windowMs?: number;
|
|
414
|
+
maxRequests?: number;
|
|
415
|
+
strategy?: RateLimitStrategy;
|
|
416
|
+
cleanupEnabled?: boolean;
|
|
417
|
+
cleanupIntervalMs?: number;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export interface RateLimitConfigUpdateResponse {
|
|
421
|
+
success: boolean;
|
|
422
|
+
config: RateLimitConfig;
|
|
265
423
|
}
|
|
266
424
|
|
|
267
425
|
class ControlPanelApi {
|
|
@@ -279,6 +437,33 @@ class ControlPanelApi {
|
|
|
279
437
|
this.baseUrl = baseUrl;
|
|
280
438
|
}
|
|
281
439
|
|
|
440
|
+
/**
|
|
441
|
+
* Get the base URL for API requests.
|
|
442
|
+
*/
|
|
443
|
+
getBaseUrl(): string {
|
|
444
|
+
return this.baseUrl;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Generic fetch method for API requests.
|
|
449
|
+
* Automatically prepends the base URL and /api prefix.
|
|
450
|
+
*/
|
|
451
|
+
async fetch<T = unknown>(path: string, options?: RequestInit): Promise<T> {
|
|
452
|
+
const url = `${this.baseUrl}/api${path.startsWith('/') ? path : `/${path}`}`;
|
|
453
|
+
const response = await fetch(url, {
|
|
454
|
+
...options,
|
|
455
|
+
headers: {
|
|
456
|
+
'Content-Type': 'application/json',
|
|
457
|
+
...options?.headers,
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
if (!response.ok) {
|
|
461
|
+
const error = await response.json().catch(() => ({}));
|
|
462
|
+
throw new Error(error.error || error.message || `Request failed: ${response.statusText}`);
|
|
463
|
+
}
|
|
464
|
+
return response.json();
|
|
465
|
+
}
|
|
466
|
+
|
|
282
467
|
// ==================
|
|
283
468
|
// Plugin Feature Detection
|
|
284
469
|
// ==================
|
|
@@ -330,7 +515,7 @@ class ControlPanelApi {
|
|
|
330
515
|
const params = new URLSearchParams();
|
|
331
516
|
if (options.limit) params.set('limit', options.limit.toString());
|
|
332
517
|
if (options.page) params.set('page', options.page.toString());
|
|
333
|
-
if (options.search) params.set('
|
|
518
|
+
if (options.search) params.set('q', options.search);
|
|
334
519
|
|
|
335
520
|
const response = await fetch(`${this.baseUrl}/api/users?${params}`);
|
|
336
521
|
if (!response.ok) {
|
|
@@ -360,10 +545,18 @@ class ControlPanelApi {
|
|
|
360
545
|
}
|
|
361
546
|
|
|
362
547
|
async banUser(email: string, reason: string, expiresAt?: string): Promise<void> {
|
|
363
|
-
|
|
548
|
+
// Convert expiresAt datetime to duration in seconds
|
|
549
|
+
let duration: number | undefined;
|
|
550
|
+
if (expiresAt) {
|
|
551
|
+
const expiresDate = new Date(expiresAt);
|
|
552
|
+
const now = new Date();
|
|
553
|
+
duration = Math.max(0, Math.floor((expiresDate.getTime() - now.getTime()) / 1000));
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const response = await fetch(`${this.baseUrl}/api/bans/email/${encodeURIComponent(email)}`, {
|
|
364
557
|
method: 'POST',
|
|
365
558
|
headers: { 'Content-Type': 'application/json' },
|
|
366
|
-
body: JSON.stringify({
|
|
559
|
+
body: JSON.stringify({ reason, duration }),
|
|
367
560
|
});
|
|
368
561
|
if (!response.ok) {
|
|
369
562
|
const error = await response.json().catch(() => ({}));
|
|
@@ -372,7 +565,7 @@ class ControlPanelApi {
|
|
|
372
565
|
}
|
|
373
566
|
|
|
374
567
|
async unbanUser(email: string): Promise<void> {
|
|
375
|
-
const response = await fetch(`${this.baseUrl}/api/bans/${encodeURIComponent(email)}`, {
|
|
568
|
+
const response = await fetch(`${this.baseUrl}/api/bans/email/${encodeURIComponent(email)}`, {
|
|
376
569
|
method: 'DELETE',
|
|
377
570
|
});
|
|
378
571
|
if (!response.ok) {
|
|
@@ -381,11 +574,13 @@ class ControlPanelApi {
|
|
|
381
574
|
}
|
|
382
575
|
|
|
383
576
|
async checkBan(email: string): Promise<{ banned: boolean; ban?: Ban }> {
|
|
384
|
-
const response = await fetch(`${this.baseUrl}/api/bans/
|
|
577
|
+
const response = await fetch(`${this.baseUrl}/api/bans/email/${encodeURIComponent(email)}`);
|
|
385
578
|
if (!response.ok) {
|
|
386
579
|
throw new Error(`Ban check failed: ${response.statusText}`);
|
|
387
580
|
}
|
|
388
|
-
|
|
581
|
+
const data = await response.json();
|
|
582
|
+
// Backend returns { email, isBanned }, transform to expected shape
|
|
583
|
+
return { banned: data.isBanned };
|
|
389
584
|
}
|
|
390
585
|
|
|
391
586
|
// ==================
|
|
@@ -595,6 +790,134 @@ class ControlPanelApi {
|
|
|
595
790
|
}
|
|
596
791
|
return response.json();
|
|
597
792
|
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Update auth configuration (save to database for hot-reload)
|
|
796
|
+
*/
|
|
797
|
+
async updateAuthConfig(request: UpdateAuthConfigRequest): Promise<{ success: boolean; message: string }> {
|
|
798
|
+
const response = await fetch(`${this.baseUrl}/api/auth/config`, {
|
|
799
|
+
method: 'PUT',
|
|
800
|
+
headers: { 'Content-Type': 'application/json' },
|
|
801
|
+
body: JSON.stringify(request),
|
|
802
|
+
});
|
|
803
|
+
if (!response.ok) {
|
|
804
|
+
const error = await response.json().catch(() => ({}));
|
|
805
|
+
throw new Error(error.error || `Auth config update failed: ${response.statusText}`);
|
|
806
|
+
}
|
|
807
|
+
return response.json();
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Delete auth configuration (revert to environment variables)
|
|
812
|
+
*/
|
|
813
|
+
async deleteAuthConfig(): Promise<{ success: boolean; message: string }> {
|
|
814
|
+
const response = await fetch(`${this.baseUrl}/api/auth/config`, {
|
|
815
|
+
method: 'DELETE',
|
|
816
|
+
});
|
|
817
|
+
if (!response.ok) {
|
|
818
|
+
const error = await response.json().catch(() => ({}));
|
|
819
|
+
throw new Error(error.error || `Auth config delete failed: ${response.statusText}`);
|
|
820
|
+
}
|
|
821
|
+
return response.json();
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* Test auth provider connection without saving
|
|
826
|
+
*/
|
|
827
|
+
async testAuthProvider(request: TestProviderRequest): Promise<TestProviderResponse> {
|
|
828
|
+
const response = await fetch(`${this.baseUrl}/api/auth/test-provider`, {
|
|
829
|
+
method: 'POST',
|
|
830
|
+
headers: { 'Content-Type': 'application/json' },
|
|
831
|
+
body: JSON.stringify(request),
|
|
832
|
+
});
|
|
833
|
+
if (!response.ok) {
|
|
834
|
+
const error = await response.json().catch(() => ({}));
|
|
835
|
+
throw new Error(error.error || `Provider test failed: ${response.statusText}`);
|
|
836
|
+
}
|
|
837
|
+
return response.json();
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Test current auth provider connection (uses existing env/runtime config)
|
|
842
|
+
*/
|
|
843
|
+
async testCurrentAuthProvider(): Promise<TestProviderResponse> {
|
|
844
|
+
const response = await fetch(`${this.baseUrl}/api/auth/test-current`, {
|
|
845
|
+
method: 'POST',
|
|
846
|
+
headers: { 'Content-Type': 'application/json' },
|
|
847
|
+
});
|
|
848
|
+
if (!response.ok) {
|
|
849
|
+
const error = await response.json().catch(() => ({}));
|
|
850
|
+
throw new Error(error.error || `Provider test failed: ${response.statusText}`);
|
|
851
|
+
}
|
|
852
|
+
return response.json();
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// ==================
|
|
856
|
+
// Rate Limit Config API
|
|
857
|
+
// ==================
|
|
858
|
+
|
|
859
|
+
async getRateLimitConfig(): Promise<RateLimitConfig> {
|
|
860
|
+
const response = await fetch(`${this.baseUrl}/api/rate-limit/config`);
|
|
861
|
+
if (!response.ok) {
|
|
862
|
+
throw new Error(`Rate limit config request failed: ${response.statusText}`);
|
|
863
|
+
}
|
|
864
|
+
return response.json();
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
async updateRateLimitConfig(updates: RateLimitConfigUpdateRequest): Promise<RateLimitConfigUpdateResponse> {
|
|
868
|
+
const response = await fetch(`${this.baseUrl}/api/rate-limit/config`, {
|
|
869
|
+
method: 'PUT',
|
|
870
|
+
headers: { 'Content-Type': 'application/json' },
|
|
871
|
+
body: JSON.stringify(updates),
|
|
872
|
+
});
|
|
873
|
+
if (!response.ok) {
|
|
874
|
+
const error = await response.json().catch(() => ({}));
|
|
875
|
+
throw new Error(error.error || `Rate limit config update failed: ${response.statusText}`);
|
|
876
|
+
}
|
|
877
|
+
return response.json();
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// ==================
|
|
881
|
+
// Notifications API
|
|
882
|
+
// ==================
|
|
883
|
+
|
|
884
|
+
async getNotificationsStats(): Promise<NotificationsStatsResponse> {
|
|
885
|
+
const response = await fetch(`${this.baseUrl}/api/notifications/stats`);
|
|
886
|
+
if (!response.ok) {
|
|
887
|
+
throw new Error(`Notifications stats request failed: ${response.statusText}`);
|
|
888
|
+
}
|
|
889
|
+
return response.json();
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
async getNotificationsClients(): Promise<NotificationsClientsResponse> {
|
|
893
|
+
const response = await fetch(`${this.baseUrl}/api/notifications/clients`);
|
|
894
|
+
if (!response.ok) {
|
|
895
|
+
throw new Error(`Notifications clients request failed: ${response.statusText}`);
|
|
896
|
+
}
|
|
897
|
+
return response.json();
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
async disconnectNotificationsClient(clientId: string): Promise<{ success: boolean }> {
|
|
901
|
+
const response = await fetch(`${this.baseUrl}/api/notifications/clients/${encodeURIComponent(clientId)}`, {
|
|
902
|
+
method: 'DELETE',
|
|
903
|
+
});
|
|
904
|
+
if (!response.ok) {
|
|
905
|
+
const error = await response.json().catch(() => ({}));
|
|
906
|
+
throw new Error(error.error || `Disconnect client failed: ${response.statusText}`);
|
|
907
|
+
}
|
|
908
|
+
return response.json();
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
async forceNotificationsReconnect(): Promise<{ success: boolean; message: string }> {
|
|
912
|
+
const response = await fetch(`${this.baseUrl}/api/notifications/reconnect`, {
|
|
913
|
+
method: 'POST',
|
|
914
|
+
});
|
|
915
|
+
if (!response.ok) {
|
|
916
|
+
const error = await response.json().catch(() => ({}));
|
|
917
|
+
throw new Error(error.error || `Force reconnect failed: ${response.statusText}`);
|
|
918
|
+
}
|
|
919
|
+
return response.json();
|
|
920
|
+
}
|
|
598
921
|
}
|
|
599
922
|
|
|
600
923
|
export const api = new ControlPanelApi();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StatCard Component
|
|
3
|
+
*
|
|
4
|
+
* A reusable card component for displaying statistics with an icon,
|
|
5
|
+
* value, label, and optional sub-value.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Box, Card, CardContent } from '@mui/material';
|
|
11
|
+
import { Text } from '@qwickapps/react-framework';
|
|
12
|
+
|
|
13
|
+
export interface StatCardProps {
|
|
14
|
+
icon: React.ReactNode;
|
|
15
|
+
label: string;
|
|
16
|
+
value: string | number;
|
|
17
|
+
subValue?: string;
|
|
18
|
+
color?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function StatCard({
|
|
22
|
+
icon,
|
|
23
|
+
label,
|
|
24
|
+
value,
|
|
25
|
+
subValue,
|
|
26
|
+
color = 'var(--theme-primary)',
|
|
27
|
+
}: StatCardProps) {
|
|
28
|
+
return (
|
|
29
|
+
<Card sx={{ bgcolor: 'var(--theme-surface)', height: '100%' }}>
|
|
30
|
+
<CardContent sx={{ py: 1.5, '&:last-child': { pb: 1.5 } }}>
|
|
31
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
|
|
32
|
+
<Box sx={{ color }}>{icon}</Box>
|
|
33
|
+
<Box sx={{ flex: 1, minWidth: 0 }}>
|
|
34
|
+
<Text
|
|
35
|
+
variant="h4"
|
|
36
|
+
content={String(value)}
|
|
37
|
+
customColor="var(--theme-text-primary)"
|
|
38
|
+
fontWeight="600"
|
|
39
|
+
/>
|
|
40
|
+
<Text
|
|
41
|
+
variant="caption"
|
|
42
|
+
content={label}
|
|
43
|
+
customColor="var(--theme-text-secondary)"
|
|
44
|
+
/>
|
|
45
|
+
{subValue && (
|
|
46
|
+
<Text
|
|
47
|
+
variant="caption"
|
|
48
|
+
content={subValue}
|
|
49
|
+
customColor="var(--theme-text-secondary)"
|
|
50
|
+
sx={{ display: 'block', mt: 0.25 }}
|
|
51
|
+
/>
|
|
52
|
+
)}
|
|
53
|
+
</Box>
|
|
54
|
+
</Box>
|
|
55
|
+
</CardContent>
|
|
56
|
+
</Card>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { ServiceHealthWidget } from './widgets';
|
|
13
|
+
import { ServiceHealthWidget, IntegrationStatusWidget, AuthStatusWidget, NotificationsStatsWidget } from './widgets';
|
|
14
14
|
import type { WidgetComponent } from './WidgetComponentRegistry';
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -19,6 +19,9 @@ import type { WidgetComponent } from './WidgetComponentRegistry';
|
|
|
19
19
|
*/
|
|
20
20
|
export const builtInWidgetComponents: Record<string, React.ComponentType> = {
|
|
21
21
|
ServiceHealthWidget: ServiceHealthWidget,
|
|
22
|
+
IntegrationStatusWidget: IntegrationStatusWidget,
|
|
23
|
+
AuthStatusWidget: AuthStatusWidget,
|
|
24
|
+
NotificationsStatsWidget: NotificationsStatsWidget,
|
|
22
25
|
};
|
|
23
26
|
|
|
24
27
|
/**
|
|
@@ -31,5 +34,8 @@ export const builtInWidgetComponents: Record<string, React.ComponentType> = {
|
|
|
31
34
|
export function getBuiltInWidgetComponents(): WidgetComponent[] {
|
|
32
35
|
return [
|
|
33
36
|
{ name: 'ServiceHealthWidget', component: ServiceHealthWidget },
|
|
37
|
+
{ name: 'IntegrationStatusWidget', component: IntegrationStatusWidget },
|
|
38
|
+
{ name: 'AuthStatusWidget', component: AuthStatusWidget },
|
|
39
|
+
{ name: 'NotificationsStatsWidget', component: NotificationsStatsWidget },
|
|
34
40
|
];
|
|
35
41
|
}
|