@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
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limit Plugin Environment Configuration
|
|
3
|
+
*
|
|
4
|
+
* Factory function for configuring rate limiting via environment variables.
|
|
5
|
+
*
|
|
6
|
+
* Environment Variables:
|
|
7
|
+
* - RATE_LIMIT_ENABLED: Enable rate limiting (default: true)
|
|
8
|
+
* - RATE_LIMIT_STRATEGY: Strategy to use: sliding-window, fixed-window, token-bucket (default: sliding-window)
|
|
9
|
+
* - RATE_LIMIT_WINDOW_MS: Window size in milliseconds (default: 60000 = 1 minute)
|
|
10
|
+
* - RATE_LIMIT_MAX_REQUESTS: Maximum requests per window (default: 100)
|
|
11
|
+
* - RATE_LIMIT_CACHE_TYPE: Cache type: redis, memory, auto (default: auto)
|
|
12
|
+
* - RATE_LIMIT_CLEANUP_ENABLED: Enable cleanup job (default: true)
|
|
13
|
+
* - RATE_LIMIT_CLEANUP_INTERVAL_MS: Cleanup interval in ms (default: 300000 = 5 minutes)
|
|
14
|
+
* - RATE_LIMIT_API_ENABLED: Enable status API endpoints (default: true)
|
|
15
|
+
* - RATE_LIMIT_API_PREFIX: API route prefix (default: /rate-limit)
|
|
16
|
+
* - RATE_LIMIT_DEBUG: Enable debug logging (default: false)
|
|
17
|
+
*
|
|
18
|
+
* PostgreSQL Store (via postgres-plugin):
|
|
19
|
+
* - RATE_LIMIT_TABLE_NAME: Table name (default: rate_limits)
|
|
20
|
+
* - RATE_LIMIT_ENABLE_RLS: Enable Row-Level Security (default: true)
|
|
21
|
+
* - RATE_LIMIT_AUTO_CREATE_TABLES: Auto-create tables (default: true)
|
|
22
|
+
*
|
|
23
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import type { Request, Response } from 'express';
|
|
27
|
+
import type { Plugin, PluginConfig, PluginRegistry } from '../../core/plugin-registry.js';
|
|
28
|
+
import type { RateLimitPluginConfig, RateLimitStrategy, RateLimitCacheConfig } from './types.js';
|
|
29
|
+
import { createRateLimitPlugin } from './rate-limit-plugin.js';
|
|
30
|
+
import { postgresRateLimitStore } from './stores/postgres-store.js';
|
|
31
|
+
import { getPostgres, hasPostgres } from '../postgres-plugin.js';
|
|
32
|
+
|
|
33
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
34
|
+
// Module State
|
|
35
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
36
|
+
|
|
37
|
+
interface RateLimitConfigStatus {
|
|
38
|
+
state: 'disabled' | 'enabled' | 'error';
|
|
39
|
+
strategy: RateLimitStrategy | null;
|
|
40
|
+
error?: string;
|
|
41
|
+
config?: Record<string, string | number | boolean>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let currentStatus: RateLimitConfigStatus = {
|
|
45
|
+
state: 'disabled',
|
|
46
|
+
strategy: null,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
50
|
+
// Environment Variable Helpers
|
|
51
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get an environment variable, treating empty strings as undefined
|
|
55
|
+
*/
|
|
56
|
+
function getEnv(key: string): string | undefined {
|
|
57
|
+
const value = process.env[key];
|
|
58
|
+
if (value === undefined || value === null || value.trim() === '') {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
return value.trim();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Parse a boolean environment variable
|
|
66
|
+
*/
|
|
67
|
+
function getEnvBool(key: string, defaultValue: boolean): boolean {
|
|
68
|
+
const value = getEnv(key);
|
|
69
|
+
if (value === undefined) {
|
|
70
|
+
return defaultValue;
|
|
71
|
+
}
|
|
72
|
+
const lower = value.toLowerCase();
|
|
73
|
+
if (['true', '1', 'yes'].includes(lower)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
if (['false', '0', 'no'].includes(lower)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return defaultValue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Parse an integer environment variable
|
|
84
|
+
*/
|
|
85
|
+
function getEnvInt(key: string, defaultValue: number): number {
|
|
86
|
+
const value = getEnv(key);
|
|
87
|
+
if (value === undefined) {
|
|
88
|
+
return defaultValue;
|
|
89
|
+
}
|
|
90
|
+
const parsed = parseInt(value, 10);
|
|
91
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
95
|
+
// Factory Options
|
|
96
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
97
|
+
|
|
98
|
+
export interface RateLimitEnvPluginOptions {
|
|
99
|
+
/**
|
|
100
|
+
* Override the default store. If not provided, uses postgres-plugin.
|
|
101
|
+
*/
|
|
102
|
+
store?: RateLimitPluginConfig['store'];
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Debug mode override
|
|
106
|
+
*/
|
|
107
|
+
debug?: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
111
|
+
// Factory Function
|
|
112
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
113
|
+
|
|
114
|
+
const VALID_STRATEGIES: RateLimitStrategy[] = ['sliding-window', 'fixed-window', 'token-bucket'];
|
|
115
|
+
const VALID_CACHE_TYPES: RateLimitCacheConfig['type'][] = ['redis', 'memory', 'auto'];
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Create a rate limit plugin configured from environment variables.
|
|
119
|
+
*
|
|
120
|
+
* The plugin state depends on environment configuration:
|
|
121
|
+
* - **disabled**: RATE_LIMIT_ENABLED=false - no rate limiting is applied
|
|
122
|
+
* - **enabled**: Valid configuration - rate limiting is active
|
|
123
|
+
* - **error**: Invalid configuration or missing postgres - plugin is disabled with error details
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* // Zero-config setup - reads everything from env vars
|
|
128
|
+
* // Requires postgres-plugin to be registered first
|
|
129
|
+
* const rateLimitPlugin = createRateLimitPluginFromEnv();
|
|
130
|
+
*
|
|
131
|
+
* // With custom store
|
|
132
|
+
* const rateLimitPlugin = createRateLimitPluginFromEnv({
|
|
133
|
+
* store: myCustomStore,
|
|
134
|
+
* });
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @param options - Optional overrides
|
|
138
|
+
* @returns A Plugin instance
|
|
139
|
+
*/
|
|
140
|
+
export function createRateLimitPluginFromEnv(options?: RateLimitEnvPluginOptions): Plugin {
|
|
141
|
+
const enabled = getEnvBool('RATE_LIMIT_ENABLED', true);
|
|
142
|
+
|
|
143
|
+
// Check if disabled
|
|
144
|
+
if (!enabled) {
|
|
145
|
+
currentStatus = {
|
|
146
|
+
state: 'disabled',
|
|
147
|
+
strategy: null,
|
|
148
|
+
};
|
|
149
|
+
return createDisabledPlugin();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Parse strategy
|
|
153
|
+
const strategyName = getEnv('RATE_LIMIT_STRATEGY')?.toLowerCase() || 'sliding-window';
|
|
154
|
+
if (!VALID_STRATEGIES.includes(strategyName as RateLimitStrategy)) {
|
|
155
|
+
const error = `Invalid RATE_LIMIT_STRATEGY: "${strategyName}". Valid options: ${VALID_STRATEGIES.join(', ')}`;
|
|
156
|
+
currentStatus = {
|
|
157
|
+
state: 'error',
|
|
158
|
+
strategy: null,
|
|
159
|
+
error,
|
|
160
|
+
};
|
|
161
|
+
return createErrorPlugin(error);
|
|
162
|
+
}
|
|
163
|
+
const strategy = strategyName as RateLimitStrategy;
|
|
164
|
+
|
|
165
|
+
// Parse cache type
|
|
166
|
+
const cacheTypeName = getEnv('RATE_LIMIT_CACHE_TYPE')?.toLowerCase() || 'auto';
|
|
167
|
+
if (!VALID_CACHE_TYPES.includes(cacheTypeName as RateLimitCacheConfig['type'])) {
|
|
168
|
+
const error = `Invalid RATE_LIMIT_CACHE_TYPE: "${cacheTypeName}". Valid options: ${VALID_CACHE_TYPES.join(', ')}`;
|
|
169
|
+
currentStatus = {
|
|
170
|
+
state: 'error',
|
|
171
|
+
strategy: null,
|
|
172
|
+
error,
|
|
173
|
+
};
|
|
174
|
+
return createErrorPlugin(error);
|
|
175
|
+
}
|
|
176
|
+
const cacheType = cacheTypeName as RateLimitCacheConfig['type'];
|
|
177
|
+
|
|
178
|
+
// Parse other config
|
|
179
|
+
const windowMs = getEnvInt('RATE_LIMIT_WINDOW_MS', 60000);
|
|
180
|
+
const maxRequests = getEnvInt('RATE_LIMIT_MAX_REQUESTS', 100);
|
|
181
|
+
const cleanupEnabled = getEnvBool('RATE_LIMIT_CLEANUP_ENABLED', true);
|
|
182
|
+
const cleanupIntervalMs = getEnvInt('RATE_LIMIT_CLEANUP_INTERVAL_MS', 300000);
|
|
183
|
+
const apiEnabled = getEnvBool('RATE_LIMIT_API_ENABLED', true);
|
|
184
|
+
const apiPrefix = getEnv('RATE_LIMIT_API_PREFIX') || '/rate-limit';
|
|
185
|
+
const debug = options?.debug ?? getEnvBool('RATE_LIMIT_DEBUG', false);
|
|
186
|
+
|
|
187
|
+
// PostgreSQL store config
|
|
188
|
+
const tableName = getEnv('RATE_LIMIT_TABLE_NAME') || 'rate_limits';
|
|
189
|
+
const enableRLS = getEnvBool('RATE_LIMIT_ENABLE_RLS', true);
|
|
190
|
+
const autoCreateTables = getEnvBool('RATE_LIMIT_AUTO_CREATE_TABLES', true);
|
|
191
|
+
|
|
192
|
+
// Build config
|
|
193
|
+
const config: Omit<RateLimitPluginConfig, 'store'> = {
|
|
194
|
+
defaults: {
|
|
195
|
+
windowMs,
|
|
196
|
+
maxRequests,
|
|
197
|
+
strategy,
|
|
198
|
+
},
|
|
199
|
+
cache: {
|
|
200
|
+
type: cacheType,
|
|
201
|
+
},
|
|
202
|
+
cleanup: {
|
|
203
|
+
enabled: cleanupEnabled,
|
|
204
|
+
intervalMs: cleanupIntervalMs,
|
|
205
|
+
},
|
|
206
|
+
api: {
|
|
207
|
+
enabled: apiEnabled,
|
|
208
|
+
prefix: apiPrefix,
|
|
209
|
+
},
|
|
210
|
+
debug,
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// Update status
|
|
214
|
+
currentStatus = {
|
|
215
|
+
state: 'enabled',
|
|
216
|
+
strategy,
|
|
217
|
+
config: {
|
|
218
|
+
strategy,
|
|
219
|
+
windowMs,
|
|
220
|
+
maxRequests,
|
|
221
|
+
cacheType: cacheType as string,
|
|
222
|
+
cleanupEnabled,
|
|
223
|
+
cleanupIntervalMs,
|
|
224
|
+
apiEnabled,
|
|
225
|
+
apiPrefix,
|
|
226
|
+
tableName,
|
|
227
|
+
enableRLS,
|
|
228
|
+
autoCreateTables,
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// Return a plugin that will initialize store on start
|
|
233
|
+
return createDeferredPlugin(config, options?.store, {
|
|
234
|
+
tableName,
|
|
235
|
+
enableRLS,
|
|
236
|
+
autoCreateTables,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
241
|
+
// Status API
|
|
242
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Get current rate limit plugin status
|
|
246
|
+
*/
|
|
247
|
+
export function getRateLimitConfigStatus(): RateLimitConfigStatus {
|
|
248
|
+
return { ...currentStatus };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Register config API routes
|
|
253
|
+
*/
|
|
254
|
+
function registerConfigRoutes(registry: PluginRegistry): void {
|
|
255
|
+
// GET /rate-limit/config/status - Get current rate limit status
|
|
256
|
+
registry.addRoute({
|
|
257
|
+
method: 'get',
|
|
258
|
+
path: '/rate-limit/config/status',
|
|
259
|
+
pluginId: 'rate-limit',
|
|
260
|
+
handler: (_req: Request, res: Response) => {
|
|
261
|
+
res.json(getRateLimitConfigStatus());
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
267
|
+
// Plugin Factories
|
|
268
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
269
|
+
|
|
270
|
+
interface PostgresStoreOptions {
|
|
271
|
+
tableName: string;
|
|
272
|
+
enableRLS: boolean;
|
|
273
|
+
autoCreateTables: boolean;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Create a deferred plugin that initializes the store on start
|
|
278
|
+
* This allows the postgres-plugin to be initialized first
|
|
279
|
+
*/
|
|
280
|
+
function createDeferredPlugin(
|
|
281
|
+
config: Omit<RateLimitPluginConfig, 'store'>,
|
|
282
|
+
customStore: RateLimitPluginConfig['store'] | undefined,
|
|
283
|
+
pgOptions: PostgresStoreOptions
|
|
284
|
+
): Plugin {
|
|
285
|
+
return {
|
|
286
|
+
id: 'rate-limit',
|
|
287
|
+
name: 'Rate Limit Plugin',
|
|
288
|
+
version: '1.0.0',
|
|
289
|
+
|
|
290
|
+
async onStart(pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
291
|
+
const logger = registry.getLogger('rate-limit');
|
|
292
|
+
|
|
293
|
+
// Get or create store
|
|
294
|
+
let store = customStore;
|
|
295
|
+
if (!store) {
|
|
296
|
+
// Check if postgres plugin is available
|
|
297
|
+
if (!hasPostgres()) {
|
|
298
|
+
const error = 'Rate limit plugin requires postgres-plugin to be registered and started first';
|
|
299
|
+
logger.error(error);
|
|
300
|
+
currentStatus = {
|
|
301
|
+
state: 'error',
|
|
302
|
+
strategy: null,
|
|
303
|
+
error,
|
|
304
|
+
};
|
|
305
|
+
// Register config routes so admin can see the error
|
|
306
|
+
registerConfigRoutes(registry);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Create postgres store
|
|
311
|
+
store = postgresRateLimitStore({
|
|
312
|
+
pool: () => getPostgres().getPool(),
|
|
313
|
+
tableName: pgOptions.tableName,
|
|
314
|
+
enableRLS: pgOptions.enableRLS,
|
|
315
|
+
autoCreateTables: pgOptions.autoCreateTables,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Create the actual plugin and delegate
|
|
320
|
+
const actualPlugin = createRateLimitPlugin({
|
|
321
|
+
...config,
|
|
322
|
+
store,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// Call its onStart
|
|
326
|
+
await actualPlugin.onStart?.(pluginConfig, registry);
|
|
327
|
+
|
|
328
|
+
// Register config routes
|
|
329
|
+
registerConfigRoutes(registry);
|
|
330
|
+
|
|
331
|
+
logger.info('Rate limit plugin started from env config', {
|
|
332
|
+
strategy: config.defaults!.strategy,
|
|
333
|
+
windowMs: config.defaults!.windowMs,
|
|
334
|
+
maxRequests: config.defaults!.maxRequests,
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
async onStop(): Promise<void> {
|
|
339
|
+
// The actual plugin handles cleanup
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Create a disabled plugin (no rate limiting)
|
|
346
|
+
*/
|
|
347
|
+
function createDisabledPlugin(): Plugin {
|
|
348
|
+
return {
|
|
349
|
+
id: 'rate-limit',
|
|
350
|
+
name: 'Rate Limit Plugin (Disabled)',
|
|
351
|
+
version: '1.0.0',
|
|
352
|
+
|
|
353
|
+
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
354
|
+
const logger = registry.getLogger('rate-limit');
|
|
355
|
+
logger.info('Rate limit plugin disabled - RATE_LIMIT_ENABLED=false');
|
|
356
|
+
|
|
357
|
+
// Register status routes even when disabled
|
|
358
|
+
registerConfigRoutes(registry);
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
async onStop(): Promise<void> {
|
|
362
|
+
// Nothing to cleanup
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Create an error plugin (rate limiting disabled due to configuration error)
|
|
369
|
+
*/
|
|
370
|
+
function createErrorPlugin(error: string): Plugin {
|
|
371
|
+
return {
|
|
372
|
+
id: 'rate-limit',
|
|
373
|
+
name: 'Rate Limit Plugin (Error)',
|
|
374
|
+
version: '1.0.0',
|
|
375
|
+
|
|
376
|
+
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
377
|
+
const logger = registry.getLogger('rate-limit');
|
|
378
|
+
logger.error(`Rate limit plugin error: ${error}`);
|
|
379
|
+
|
|
380
|
+
// Register status routes so admin can see the error
|
|
381
|
+
registerConfigRoutes(registry);
|
|
382
|
+
},
|
|
383
|
+
|
|
384
|
+
async onStop(): Promise<void> {
|
|
385
|
+
// Nothing to cleanup
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
391
|
+
// Exports for Testing
|
|
392
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
393
|
+
|
|
394
|
+
export const __testing = {
|
|
395
|
+
getEnv,
|
|
396
|
+
getEnvBool,
|
|
397
|
+
getEnvInt,
|
|
398
|
+
VALID_STRATEGIES,
|
|
399
|
+
VALID_CACHE_TYPES,
|
|
400
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limit Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides rate limiting capabilities for @qwickapps/server.
|
|
5
|
+
*
|
|
6
|
+
* ## Features
|
|
7
|
+
* - Multiple strategies: sliding window, fixed window, token bucket
|
|
8
|
+
* - PostgreSQL persistence with RLS for multi-tenant isolation
|
|
9
|
+
* - Redis caching with in-memory fallback
|
|
10
|
+
* - Express middleware for automatic enforcement
|
|
11
|
+
* - Programmatic API for custom rate limiting
|
|
12
|
+
* - Auto-cleanup of expired limits
|
|
13
|
+
*
|
|
14
|
+
* ## Usage
|
|
15
|
+
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import {
|
|
18
|
+
* createGateway,
|
|
19
|
+
* createRateLimitPlugin,
|
|
20
|
+
* postgresRateLimitStore,
|
|
21
|
+
* rateLimitMiddleware,
|
|
22
|
+
* isLimited,
|
|
23
|
+
* clearLimit,
|
|
24
|
+
* getPostgres,
|
|
25
|
+
* } from '@qwickapps/server';
|
|
26
|
+
*
|
|
27
|
+
* // Create the gateway with rate limit plugin
|
|
28
|
+
* const gateway = createGateway({
|
|
29
|
+
* plugins: [
|
|
30
|
+
* createRateLimitPlugin({
|
|
31
|
+
* store: postgresRateLimitStore({
|
|
32
|
+
* pool: () => getPostgres().getPool(),
|
|
33
|
+
* }),
|
|
34
|
+
* defaults: {
|
|
35
|
+
* windowMs: 60000, // 1 minute
|
|
36
|
+
* maxRequests: 100, // 100 requests per window
|
|
37
|
+
* strategy: 'sliding-window',
|
|
38
|
+
* },
|
|
39
|
+
* }),
|
|
40
|
+
* ],
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* // Use middleware
|
|
44
|
+
* app.use('/api', rateLimitMiddleware());
|
|
45
|
+
*
|
|
46
|
+
* // Per-route configuration
|
|
47
|
+
* app.post('/api/chat', rateLimitMiddleware({
|
|
48
|
+
* windowMs: 60000,
|
|
49
|
+
* max: 50,
|
|
50
|
+
* keyGenerator: (req) => `chat:${req.user.id}`,
|
|
51
|
+
* }));
|
|
52
|
+
*
|
|
53
|
+
* // Programmatic API
|
|
54
|
+
* const limited = await isLimited('user:123:api');
|
|
55
|
+
* if (limited) {
|
|
56
|
+
* // Handle rate limit
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* // Clear limit (e.g., after CAPTCHA)
|
|
60
|
+
* await clearLimit('user:123:api');
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
// Plugin
|
|
67
|
+
export { createRateLimitPlugin } from './rate-limit-plugin.js';
|
|
68
|
+
export { createRateLimitPluginFromEnv, getRateLimitConfigStatus } from './env-config.js';
|
|
69
|
+
export type { RateLimitEnvPluginOptions } from './env-config.js';
|
|
70
|
+
|
|
71
|
+
// Stores
|
|
72
|
+
export { postgresRateLimitStore } from './stores/postgres-store.js';
|
|
73
|
+
export { createRateLimitCache, createNoOpCache } from './stores/cache-store.js';
|
|
74
|
+
|
|
75
|
+
// Strategies
|
|
76
|
+
export {
|
|
77
|
+
createSlidingWindowStrategy,
|
|
78
|
+
createFixedWindowStrategy,
|
|
79
|
+
createTokenBucketStrategy,
|
|
80
|
+
getStrategy,
|
|
81
|
+
} from './strategies/index.js';
|
|
82
|
+
|
|
83
|
+
// Middleware
|
|
84
|
+
export { rateLimitMiddleware, rateLimitStatusMiddleware } from './middleware.js';
|
|
85
|
+
|
|
86
|
+
// Service and programmatic API
|
|
87
|
+
export {
|
|
88
|
+
RateLimitService,
|
|
89
|
+
getRateLimitService,
|
|
90
|
+
isLimited,
|
|
91
|
+
checkLimit,
|
|
92
|
+
incrementLimit,
|
|
93
|
+
getRemainingRequests,
|
|
94
|
+
getLimitStatus,
|
|
95
|
+
clearLimit,
|
|
96
|
+
} from './rate-limit-service.js';
|
|
97
|
+
|
|
98
|
+
// Cleanup
|
|
99
|
+
export { createCleanupJob } from './cleanup.js';
|
|
100
|
+
export type { CleanupJob, CleanupJobConfig } from './cleanup.js';
|
|
101
|
+
|
|
102
|
+
// Types
|
|
103
|
+
export type {
|
|
104
|
+
// Strategy types
|
|
105
|
+
RateLimitStrategy,
|
|
106
|
+
LimitStatus,
|
|
107
|
+
Strategy,
|
|
108
|
+
StrategyOptions,
|
|
109
|
+
StrategyContext,
|
|
110
|
+
|
|
111
|
+
// Store types
|
|
112
|
+
StoredLimit,
|
|
113
|
+
IncrementOptions,
|
|
114
|
+
RateLimitStore,
|
|
115
|
+
PostgresRateLimitStoreConfig,
|
|
116
|
+
|
|
117
|
+
// Cache types
|
|
118
|
+
CachedLimit,
|
|
119
|
+
RateLimitCache,
|
|
120
|
+
RateLimitCacheConfig,
|
|
121
|
+
|
|
122
|
+
// Middleware types
|
|
123
|
+
RateLimitMiddlewareOptions,
|
|
124
|
+
|
|
125
|
+
// Plugin types
|
|
126
|
+
RateLimitPluginConfig,
|
|
127
|
+
CheckLimitOptions,
|
|
128
|
+
} from './types.js';
|