@qwickapps/server 1.7.0 → 1.7.2
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/CHANGELOG.md +66 -0
- package/README.md +13 -116
- package/dist/src/core/control-panel.d.ts.map +1 -1
- package/dist/src/core/control-panel.js +6 -4
- package/dist/src/core/control-panel.js.map +1 -1
- package/dist/src/core/gateway.d.ts.map +1 -1
- package/dist/src/core/gateway.js +24 -2
- package/dist/src/core/gateway.js.map +1 -1
- package/dist/src/core/plugin-registry.d.ts +15 -2
- package/dist/src/core/plugin-registry.d.ts.map +1 -1
- package/dist/src/core/plugin-registry.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/plugins/api-keys/api-keys-plugin.d.ts +5 -2
- package/dist/src/plugins/api-keys/api-keys-plugin.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/api-keys-plugin.js +61 -19
- package/dist/src/plugins/api-keys/api-keys-plugin.js.map +1 -1
- package/dist/src/plugins/api-keys/index.d.ts +0 -4
- package/dist/src/plugins/api-keys/index.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/index.js +2 -3
- package/dist/src/plugins/api-keys/index.js.map +1 -1
- package/dist/src/plugins/api-keys/stores/postgres-store.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/stores/postgres-store.js +29 -0
- package/dist/src/plugins/api-keys/stores/postgres-store.js.map +1 -1
- package/dist/src/plugins/api-keys/types.d.ts +9 -3
- package/dist/src/plugins/api-keys/types.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/types.js.map +1 -1
- package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
- package/dist/src/plugins/auth/auth-plugin.js +4 -2
- package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
- package/dist/src/plugins/auth/env-config.d.ts.map +1 -1
- package/dist/src/plugins/auth/env-config.js +1 -0
- package/dist/src/plugins/auth/env-config.js.map +1 -1
- package/dist/src/plugins/auth/index.d.ts +0 -4
- package/dist/src/plugins/auth/index.d.ts.map +1 -1
- package/dist/src/plugins/auth/index.js +2 -3
- package/dist/src/plugins/auth/index.js.map +1 -1
- package/dist/src/plugins/bans/bans-plugin.d.ts +5 -2
- package/dist/src/plugins/bans/bans-plugin.d.ts.map +1 -1
- package/dist/src/plugins/bans/bans-plugin.js +71 -25
- package/dist/src/plugins/bans/bans-plugin.js.map +1 -1
- package/dist/src/plugins/bans/index.d.ts +1 -5
- package/dist/src/plugins/bans/index.d.ts.map +1 -1
- package/dist/src/plugins/bans/index.js +3 -4
- package/dist/src/plugins/bans/index.js.map +1 -1
- package/dist/src/plugins/bans/stores/in-memory-store.d.ts +34 -0
- package/dist/src/plugins/bans/stores/in-memory-store.d.ts.map +1 -0
- package/dist/src/plugins/bans/stores/in-memory-store.js +97 -0
- package/dist/src/plugins/bans/stores/in-memory-store.js.map +1 -0
- package/dist/src/plugins/bans/stores/index.d.ts +1 -0
- package/dist/src/plugins/bans/stores/index.d.ts.map +1 -1
- package/dist/src/plugins/bans/stores/index.js +1 -0
- package/dist/src/plugins/bans/stores/index.js.map +1 -1
- package/dist/src/plugins/bans/types.d.ts +13 -6
- package/dist/src/plugins/bans/types.d.ts.map +1 -1
- package/dist/src/plugins/cache-plugin.d.ts +35 -16
- package/dist/src/plugins/cache-plugin.d.ts.map +1 -1
- package/dist/src/plugins/cache-plugin.js +299 -20
- package/dist/src/plugins/cache-plugin.js.map +1 -1
- package/dist/src/plugins/cms/cms-plugin.d.ts.map +1 -1
- package/dist/src/plugins/cms/cms-plugin.js +3 -1
- package/dist/src/plugins/cms/cms-plugin.js.map +1 -1
- package/dist/src/plugins/devices/devices-plugin.d.ts +5 -2
- package/dist/src/plugins/devices/devices-plugin.d.ts.map +1 -1
- package/dist/src/plugins/devices/devices-plugin.js +62 -26
- package/dist/src/plugins/devices/devices-plugin.js.map +1 -1
- package/dist/src/plugins/devices/index.d.ts +0 -4
- package/dist/src/plugins/devices/index.d.ts.map +1 -1
- package/dist/src/plugins/devices/index.js +2 -3
- package/dist/src/plugins/devices/index.js.map +1 -1
- package/dist/src/plugins/entitlements/entitlements-plugin.d.ts +5 -2
- package/dist/src/plugins/entitlements/entitlements-plugin.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/entitlements-plugin.js +78 -41
- package/dist/src/plugins/entitlements/entitlements-plugin.js.map +1 -1
- package/dist/src/plugins/entitlements/index.d.ts +1 -5
- package/dist/src/plugins/entitlements/index.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/index.js +3 -4
- package/dist/src/plugins/entitlements/index.js.map +1 -1
- package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts +9 -0
- package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts.map +1 -0
- package/dist/src/plugins/entitlements/sources/in-memory-source.js +65 -0
- package/dist/src/plugins/entitlements/sources/in-memory-source.js.map +1 -0
- package/dist/src/plugins/entitlements/sources/index.d.ts +1 -0
- package/dist/src/plugins/entitlements/sources/index.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/sources/index.js +1 -0
- package/dist/src/plugins/entitlements/sources/index.js.map +1 -1
- package/dist/src/plugins/entitlements/types.d.ts +9 -2
- package/dist/src/plugins/entitlements/types.d.ts.map +1 -1
- package/dist/src/plugins/health-plugin.d.ts.map +1 -1
- package/dist/src/plugins/health-plugin.js +1 -0
- package/dist/src/plugins/health-plugin.js.map +1 -1
- package/dist/src/plugins/index.d.ts +4 -4
- package/dist/src/plugins/index.d.ts.map +1 -1
- package/dist/src/plugins/index.js +4 -4
- package/dist/src/plugins/index.js.map +1 -1
- package/dist/src/plugins/logs-plugin.d.ts.map +1 -1
- package/dist/src/plugins/logs-plugin.js +49 -1
- package/dist/src/plugins/logs-plugin.js.map +1 -1
- package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
- package/dist/src/plugins/maintenance-plugin.js +39 -0
- package/dist/src/plugins/maintenance-plugin.js.map +1 -1
- package/dist/src/plugins/notifications/index.d.ts +0 -4
- package/dist/src/plugins/notifications/index.d.ts.map +1 -1
- package/dist/src/plugins/notifications/index.js +2 -3
- package/dist/src/plugins/notifications/index.js.map +1 -1
- package/dist/src/plugins/notifications/notifications-plugin.d.ts +5 -2
- package/dist/src/plugins/notifications/notifications-plugin.d.ts.map +1 -1
- package/dist/src/plugins/notifications/notifications-plugin.js +46 -13
- package/dist/src/plugins/notifications/notifications-plugin.js.map +1 -1
- package/dist/src/plugins/parental/index.d.ts +0 -4
- package/dist/src/plugins/parental/index.d.ts.map +1 -1
- package/dist/src/plugins/parental/index.js +2 -3
- package/dist/src/plugins/parental/index.js.map +1 -1
- package/dist/src/plugins/parental/parental-plugin.d.ts +5 -2
- package/dist/src/plugins/parental/parental-plugin.d.ts.map +1 -1
- package/dist/src/plugins/parental/parental-plugin.js +60 -24
- package/dist/src/plugins/parental/parental-plugin.js.map +1 -1
- package/dist/src/plugins/postgres-plugin.d.ts +3 -1
- package/dist/src/plugins/postgres-plugin.d.ts.map +1 -1
- package/dist/src/plugins/postgres-plugin.js +18 -8
- package/dist/src/plugins/postgres-plugin.js.map +1 -1
- package/dist/src/plugins/preferences/index.d.ts +0 -4
- package/dist/src/plugins/preferences/index.d.ts.map +1 -1
- package/dist/src/plugins/preferences/index.js +2 -3
- package/dist/src/plugins/preferences/index.js.map +1 -1
- package/dist/src/plugins/preferences/preferences-plugin.d.ts +5 -2
- package/dist/src/plugins/preferences/preferences-plugin.d.ts.map +1 -1
- package/dist/src/plugins/preferences/preferences-plugin.js +63 -19
- package/dist/src/plugins/preferences/preferences-plugin.js.map +1 -1
- package/dist/src/plugins/profiles/index.d.ts +0 -4
- package/dist/src/plugins/profiles/index.d.ts.map +1 -1
- package/dist/src/plugins/profiles/index.js +2 -3
- package/dist/src/plugins/profiles/index.js.map +1 -1
- package/dist/src/plugins/profiles/profiles-plugin.d.ts +5 -2
- package/dist/src/plugins/profiles/profiles-plugin.d.ts.map +1 -1
- package/dist/src/plugins/profiles/profiles-plugin.js +60 -26
- package/dist/src/plugins/profiles/profiles-plugin.js.map +1 -1
- package/dist/src/plugins/profiles/types.d.ts +9 -2
- package/dist/src/plugins/profiles/types.d.ts.map +1 -1
- package/dist/src/plugins/qwickbrain/index.d.ts +0 -4
- package/dist/src/plugins/qwickbrain/index.d.ts.map +1 -1
- package/dist/src/plugins/qwickbrain/index.js +2 -3
- package/dist/src/plugins/qwickbrain/index.js.map +1 -1
- package/dist/src/plugins/qwickbrain/qwickbrain-plugin.d.ts.map +1 -1
- package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js +117 -0
- package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js.map +1 -1
- package/dist/src/plugins/rate-limit/index.d.ts +0 -4
- package/dist/src/plugins/rate-limit/index.d.ts.map +1 -1
- package/dist/src/plugins/rate-limit/index.js +2 -3
- package/dist/src/plugins/rate-limit/index.js.map +1 -1
- package/dist/src/plugins/subscriptions/index.d.ts +0 -4
- package/dist/src/plugins/subscriptions/index.d.ts.map +1 -1
- package/dist/src/plugins/subscriptions/index.js +2 -3
- package/dist/src/plugins/subscriptions/index.js.map +1 -1
- package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts +5 -2
- package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts.map +1 -1
- package/dist/src/plugins/subscriptions/subscriptions-plugin.js +63 -29
- package/dist/src/plugins/subscriptions/subscriptions-plugin.js.map +1 -1
- package/dist/src/plugins/subscriptions/types.d.ts +8 -2
- package/dist/src/plugins/subscriptions/types.d.ts.map +1 -1
- package/dist/src/plugins/tenants/index.d.ts +1 -1
- package/dist/src/plugins/tenants/index.d.ts.map +1 -1
- package/dist/src/plugins/tenants/index.js +1 -1
- package/dist/src/plugins/tenants/index.js.map +1 -1
- package/dist/src/plugins/tenants/stores/in-memory-store.d.ts +59 -0
- package/dist/src/plugins/tenants/stores/in-memory-store.d.ts.map +1 -0
- package/dist/src/plugins/tenants/stores/in-memory-store.js +257 -0
- package/dist/src/plugins/tenants/stores/in-memory-store.js.map +1 -0
- package/dist/src/plugins/tenants/stores/index.d.ts +8 -0
- package/dist/src/plugins/tenants/stores/index.d.ts.map +1 -0
- package/dist/src/plugins/tenants/stores/index.js +8 -0
- package/dist/src/plugins/tenants/stores/index.js.map +1 -0
- package/dist/src/plugins/tenants/tenants-plugin.d.ts +5 -2
- package/dist/src/plugins/tenants/tenants-plugin.d.ts.map +1 -1
- package/dist/src/plugins/tenants/tenants-plugin.js +93 -60
- package/dist/src/plugins/tenants/tenants-plugin.js.map +1 -1
- package/dist/src/plugins/tenants/types.d.ts +8 -2
- package/dist/src/plugins/tenants/types.d.ts.map +1 -1
- package/dist/src/plugins/usage/index.d.ts +0 -4
- package/dist/src/plugins/usage/index.d.ts.map +1 -1
- package/dist/src/plugins/usage/index.js +2 -3
- package/dist/src/plugins/usage/index.js.map +1 -1
- package/dist/src/plugins/usage/usage-plugin.d.ts +5 -2
- package/dist/src/plugins/usage/usage-plugin.d.ts.map +1 -1
- package/dist/src/plugins/usage/usage-plugin.js +57 -23
- package/dist/src/plugins/usage/usage-plugin.js.map +1 -1
- package/dist/src/plugins/users/index.d.ts +1 -1
- package/dist/src/plugins/users/index.d.ts.map +1 -1
- package/dist/src/plugins/users/index.js +1 -1
- package/dist/src/plugins/users/index.js.map +1 -1
- package/dist/src/plugins/users/stores/in-memory-store.d.ts +36 -0
- package/dist/src/plugins/users/stores/in-memory-store.d.ts.map +1 -0
- package/dist/src/plugins/users/stores/in-memory-store.js +122 -0
- package/dist/src/plugins/users/stores/in-memory-store.js.map +1 -0
- package/dist/src/plugins/users/stores/index.d.ts +1 -0
- package/dist/src/plugins/users/stores/index.d.ts.map +1 -1
- package/dist/src/plugins/users/stores/index.js +1 -0
- package/dist/src/plugins/users/stores/index.js.map +1 -1
- package/dist/src/plugins/users/types.d.ts +7 -2
- package/dist/src/plugins/users/types.d.ts.map +1 -1
- package/dist/src/plugins/users/users-plugin.d.ts +5 -2
- package/dist/src/plugins/users/users-plugin.d.ts.map +1 -1
- package/dist/src/plugins/users/users-plugin.js +56 -23
- package/dist/src/plugins/users/users-plugin.js.map +1 -1
- package/dist/ui/src/api/controlPanelApi.d.ts +10 -1
- package/dist/ui/src/api/controlPanelApi.d.ts.map +1 -1
- package/dist/ui/src/api/controlPanelApi.js.map +1 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts.map +1 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.js +5 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.js.map +1 -1
- package/dist/ui/src/dashboard/builtInWidgets.d.ts.map +1 -1
- package/dist/ui/src/dashboard/builtInWidgets.js +13 -1
- package/dist/ui/src/dashboard/builtInWidgets.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +11 -0
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js +77 -0
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js +14 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js +14 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +11 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js +96 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js +55 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js +14 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/index.d.ts +6 -0
- package/dist/ui/src/dashboard/widgets/index.d.ts.map +1 -1
- package/dist/ui/src/dashboard/widgets/index.js +6 -0
- package/dist/ui/src/dashboard/widgets/index.js.map +1 -1
- package/dist/ui/src/pages/DashboardPage.js +1 -1
- package/dist/ui/src/pages/DashboardPage.js.map +1 -1
- package/dist-ui/assets/index-0gzisPdy.js +528 -0
- package/dist-ui/assets/{index-lm1yX6UD.js.map → index-0gzisPdy.js.map} +1 -1
- package/dist-ui/index.html +1 -1
- package/dist-ui-lib/index.js +3109 -2774
- package/dist-ui-lib/index.js.map +1 -1
- package/dist-ui-lib/src/api/controlPanelApi.d.ts +10 -1
- package/dist-ui-lib/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
- package/dist-ui-lib/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +10 -0
- package/dist-ui-lib/src/dashboard/widgets/DatabaseOpsWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +10 -0
- package/dist-ui-lib/src/dashboard/widgets/SeedManagementWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/ServiceControlWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/index.d.ts +6 -0
- package/package.json +12 -6
- package/src/core/control-panel.ts +6 -4
- package/src/core/gateway.ts +25 -2
- package/src/core/plugin-registry.ts +15 -2
- package/src/index.ts +53 -0
- package/src/plugins/api-keys/api-keys-plugin.ts +64 -20
- package/src/plugins/api-keys/index.ts +2 -5
- package/src/plugins/api-keys/stores/postgres-store.ts +30 -0
- package/src/plugins/api-keys/types.ts +9 -3
- package/src/plugins/auth/auth-plugin.ts +4 -2
- package/src/plugins/auth/env-config.ts +1 -0
- package/src/plugins/auth/index.ts +3 -5
- package/src/plugins/bans/bans-plugin.ts +71 -26
- package/src/plugins/bans/index.ts +4 -6
- package/src/plugins/bans/stores/in-memory-store.ts +106 -0
- package/src/plugins/bans/stores/index.ts +1 -0
- package/src/plugins/bans/types.ts +13 -6
- package/src/plugins/cache-plugin.test.ts +2 -2
- package/src/plugins/cache-plugin.ts +331 -30
- package/src/plugins/cms/cms-plugin.ts +3 -1
- package/src/plugins/devices/devices-plugin.ts +62 -27
- package/src/plugins/devices/index.ts +3 -5
- package/src/plugins/entitlements/entitlements-plugin.ts +81 -43
- package/src/plugins/entitlements/index.ts +4 -6
- package/src/plugins/entitlements/sources/in-memory-source.ts +76 -0
- package/src/plugins/entitlements/sources/index.ts +1 -0
- package/src/plugins/entitlements/types.ts +9 -2
- package/src/plugins/health-plugin.ts +1 -0
- package/src/plugins/index.ts +4 -1
- package/src/plugins/logs-plugin.ts +55 -1
- package/src/plugins/maintenance-plugin.ts +43 -0
- package/src/plugins/notifications/index.ts +3 -5
- package/src/plugins/notifications/notifications-plugin.ts +49 -19
- package/src/plugins/parental/index.ts +3 -5
- package/src/plugins/parental/parental-plugin.ts +63 -25
- package/src/plugins/postgres-plugin.test.ts +2 -2
- package/src/plugins/postgres-plugin.ts +20 -9
- package/src/plugins/preferences/index.ts +3 -5
- package/src/plugins/preferences/preferences-plugin.ts +66 -20
- package/src/plugins/profiles/index.ts +3 -5
- package/src/plugins/profiles/profiles-plugin.ts +60 -27
- package/src/plugins/profiles/types.ts +9 -2
- package/src/plugins/qwickbrain/index.ts +3 -5
- package/src/plugins/qwickbrain/qwickbrain-plugin.ts +135 -0
- package/src/plugins/rate-limit/index.ts +3 -5
- package/src/plugins/subscriptions/index.ts +3 -5
- package/src/plugins/subscriptions/subscriptions-plugin.ts +63 -30
- package/src/plugins/subscriptions/types.ts +8 -2
- package/src/plugins/tenants/index.ts +1 -1
- package/src/plugins/tenants/stores/in-memory-store.ts +335 -0
- package/src/plugins/tenants/stores/index.ts +13 -0
- package/src/plugins/tenants/tenants-plugin.ts +97 -62
- package/src/plugins/tenants/types.ts +8 -2
- package/src/plugins/usage/index.ts +3 -5
- package/src/plugins/usage/usage-plugin.ts +60 -26
- package/src/plugins/users/index.ts +1 -1
- package/src/plugins/users/stores/in-memory-store.ts +140 -0
- package/src/plugins/users/stores/index.ts +1 -0
- package/src/plugins/users/types.ts +7 -2
- package/src/plugins/users/users-plugin.ts +56 -24
- package/src/testing/index.ts +1 -0
- package/src/testing/pg-mem-pool.ts +33 -0
- package/ui/src/api/controlPanelApi.ts +10 -1
- package/ui/src/dashboard/PluginWidgetRenderer.tsx +8 -0
- package/ui/src/dashboard/builtInWidgets.tsx +19 -1
- package/ui/src/dashboard/widgets/CacheMaintenanceWidget.tsx +195 -0
- package/ui/src/dashboard/widgets/DatabaseOpsWidget.tsx +29 -0
- package/ui/src/dashboard/widgets/EnvironmentConfigWidget.tsx +29 -0
- package/ui/src/dashboard/widgets/LogsMaintenanceWidget.tsx +247 -0
- package/ui/src/dashboard/widgets/SeedManagementWidget.tsx +128 -0
- package/ui/src/dashboard/widgets/ServiceControlWidget.tsx +29 -0
- package/ui/src/dashboard/widgets/index.ts +6 -0
- package/ui/src/pages/DashboardPage.tsx +2 -2
- package/ui/src/pages/MaintenancePage.tsx +1 -1
- package/dist-ui/assets/index-lm1yX6UD.js +0 -528
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory Tenant Store for Demo/Testing
|
|
3
|
+
*
|
|
4
|
+
* Implements the TenantStore interface with in-memory storage.
|
|
5
|
+
* Pre-populated with demo tenants and memberships.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Default demo user ID used for pre-populated tenants.
|
|
9
|
+
* Matches the user ID assigned by basic auth guard.
|
|
10
|
+
*/
|
|
11
|
+
export const DEMO_USER_ID = 'basic-auth-user';
|
|
12
|
+
/**
|
|
13
|
+
* Creates an in-memory tenant store for demo/testing purposes.
|
|
14
|
+
* Pre-populated with 4 demo tenants (organization, group, department, user).
|
|
15
|
+
*
|
|
16
|
+
* This store is NOT suitable for production use - data is lost on restart.
|
|
17
|
+
* Use postgresTenantsStore for production deployments.
|
|
18
|
+
*
|
|
19
|
+
* @param options - Configuration options for the store
|
|
20
|
+
* @returns TenantStore implementation with in-memory storage
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { createInMemoryTenantStore } from '@qwickapps/server';
|
|
25
|
+
*
|
|
26
|
+
* const store = createInMemoryTenantStore({
|
|
27
|
+
* demoUserId: 'test-user-123',
|
|
28
|
+
* logger: console,
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* await store.initialize();
|
|
32
|
+
* const tenants = await store.getTenantsForUser('test-user-123');
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function createInMemoryTenantStore(options = {}) {
|
|
36
|
+
const demoUserId = options.demoUserId || DEMO_USER_ID;
|
|
37
|
+
const logger = options.logger || {
|
|
38
|
+
info: (msg) => console.log(msg),
|
|
39
|
+
debug: (msg) => console.log(msg),
|
|
40
|
+
};
|
|
41
|
+
const tenants = new Map();
|
|
42
|
+
const memberships = new Map();
|
|
43
|
+
let tenantIdCounter = 1;
|
|
44
|
+
let membershipIdCounter = 1;
|
|
45
|
+
// Pre-populate demo tenants
|
|
46
|
+
const demoTenants = [
|
|
47
|
+
{ name: 'Acme Corporation', type: 'organization', owner_id: demoUserId },
|
|
48
|
+
{ name: 'Engineering Team', type: 'group', owner_id: demoUserId },
|
|
49
|
+
{ name: 'Finance Department', type: 'department', owner_id: demoUserId },
|
|
50
|
+
{ name: 'Demo User Workspace', type: 'user', owner_id: demoUserId },
|
|
51
|
+
];
|
|
52
|
+
demoTenants.forEach((t) => {
|
|
53
|
+
const id = `tenant-${tenantIdCounter++}`;
|
|
54
|
+
const tenant = {
|
|
55
|
+
id,
|
|
56
|
+
name: t.name,
|
|
57
|
+
type: t.type,
|
|
58
|
+
owner_id: t.owner_id,
|
|
59
|
+
metadata: {},
|
|
60
|
+
created_at: new Date(),
|
|
61
|
+
updated_at: new Date(),
|
|
62
|
+
};
|
|
63
|
+
tenants.set(id, tenant);
|
|
64
|
+
// Auto-create membership for owner
|
|
65
|
+
const membershipId = `membership-${membershipIdCounter++}`;
|
|
66
|
+
const membership = {
|
|
67
|
+
id: membershipId,
|
|
68
|
+
tenant_id: id,
|
|
69
|
+
user_id: t.owner_id,
|
|
70
|
+
role: 'owner',
|
|
71
|
+
joined_at: new Date(),
|
|
72
|
+
};
|
|
73
|
+
memberships.set(membershipId, membership);
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
name: 'in-memory',
|
|
77
|
+
async initialize() {
|
|
78
|
+
logger.info('[InMemoryTenantStore] Initialized with demo tenants');
|
|
79
|
+
},
|
|
80
|
+
async getById(id) {
|
|
81
|
+
return tenants.get(id) || null;
|
|
82
|
+
},
|
|
83
|
+
async getByIds(ids) {
|
|
84
|
+
return ids.map((id) => tenants.get(id)).filter((t) => t !== undefined);
|
|
85
|
+
},
|
|
86
|
+
async getByName(name) {
|
|
87
|
+
for (const tenant of tenants.values()) {
|
|
88
|
+
if (tenant.name.toLowerCase() === name.toLowerCase()) {
|
|
89
|
+
return tenant;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
},
|
|
94
|
+
async create(input) {
|
|
95
|
+
const id = `tenant-${tenantIdCounter++}`;
|
|
96
|
+
const tenant = {
|
|
97
|
+
id,
|
|
98
|
+
name: input.name,
|
|
99
|
+
type: input.type,
|
|
100
|
+
owner_id: input.owner_id,
|
|
101
|
+
metadata: input.metadata || {},
|
|
102
|
+
created_at: new Date(),
|
|
103
|
+
updated_at: new Date(),
|
|
104
|
+
};
|
|
105
|
+
tenants.set(id, tenant);
|
|
106
|
+
// Auto-create membership for owner
|
|
107
|
+
const membershipId = `membership-${membershipIdCounter++}`;
|
|
108
|
+
const membership = {
|
|
109
|
+
id: membershipId,
|
|
110
|
+
tenant_id: id,
|
|
111
|
+
user_id: input.owner_id,
|
|
112
|
+
role: 'owner',
|
|
113
|
+
joined_at: new Date(),
|
|
114
|
+
};
|
|
115
|
+
memberships.set(membershipId, membership);
|
|
116
|
+
return tenant;
|
|
117
|
+
},
|
|
118
|
+
async update(id, input) {
|
|
119
|
+
const tenant = tenants.get(id);
|
|
120
|
+
if (!tenant)
|
|
121
|
+
return null;
|
|
122
|
+
const updated = {
|
|
123
|
+
...tenant,
|
|
124
|
+
...input,
|
|
125
|
+
id: tenant.id, // Preserve ID
|
|
126
|
+
created_at: tenant.created_at, // Preserve created_at
|
|
127
|
+
updated_at: new Date(),
|
|
128
|
+
};
|
|
129
|
+
tenants.set(id, updated);
|
|
130
|
+
return updated;
|
|
131
|
+
},
|
|
132
|
+
async delete(id) {
|
|
133
|
+
// Delete all memberships for this tenant
|
|
134
|
+
for (const [key, membership] of memberships.entries()) {
|
|
135
|
+
if (membership.tenant_id === id) {
|
|
136
|
+
memberships.delete(key);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return tenants.delete(id);
|
|
140
|
+
},
|
|
141
|
+
async search(params = {}) {
|
|
142
|
+
let result = Array.from(tenants.values());
|
|
143
|
+
if (params.query) {
|
|
144
|
+
const query = params.query.toLowerCase();
|
|
145
|
+
result = result.filter((t) => t.name.toLowerCase().includes(query));
|
|
146
|
+
}
|
|
147
|
+
if (params.type) {
|
|
148
|
+
result = result.filter((t) => t.type === params.type);
|
|
149
|
+
}
|
|
150
|
+
if (params.owner_id) {
|
|
151
|
+
result = result.filter((t) => t.owner_id === params.owner_id);
|
|
152
|
+
}
|
|
153
|
+
const sortBy = params.sortBy || 'created_at';
|
|
154
|
+
const sortOrder = params.sortOrder || 'desc';
|
|
155
|
+
result.sort((a, b) => {
|
|
156
|
+
const aVal = a[sortBy];
|
|
157
|
+
const bVal = b[sortBy];
|
|
158
|
+
if (aVal == null || bVal == null)
|
|
159
|
+
return 0;
|
|
160
|
+
if (aVal < bVal)
|
|
161
|
+
return sortOrder === 'asc' ? -1 : 1;
|
|
162
|
+
if (aVal > bVal)
|
|
163
|
+
return sortOrder === 'asc' ? 1 : -1;
|
|
164
|
+
return 0;
|
|
165
|
+
});
|
|
166
|
+
const total = result.length;
|
|
167
|
+
const page = params.page || 1;
|
|
168
|
+
const limit = params.limit || 20;
|
|
169
|
+
const offset = (page - 1) * limit;
|
|
170
|
+
result = result.slice(offset, offset + limit);
|
|
171
|
+
return {
|
|
172
|
+
tenants: result,
|
|
173
|
+
total,
|
|
174
|
+
page,
|
|
175
|
+
limit,
|
|
176
|
+
totalPages: Math.ceil(total / limit),
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
async getTenantsForUser(userId) {
|
|
180
|
+
const userMemberships = Array.from(memberships.values()).filter((m) => m.user_id === userId);
|
|
181
|
+
const results = [];
|
|
182
|
+
for (const membership of userMemberships) {
|
|
183
|
+
const tenant = tenants.get(membership.tenant_id);
|
|
184
|
+
if (tenant) {
|
|
185
|
+
results.push({
|
|
186
|
+
...tenant,
|
|
187
|
+
user_role: membership.role,
|
|
188
|
+
membership,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return results;
|
|
193
|
+
},
|
|
194
|
+
async getTenantForUser(tenantId, userId) {
|
|
195
|
+
const membership = await this.getMembership(tenantId, userId);
|
|
196
|
+
if (!membership)
|
|
197
|
+
return null;
|
|
198
|
+
const tenant = tenants.get(tenantId);
|
|
199
|
+
if (!tenant)
|
|
200
|
+
return null;
|
|
201
|
+
return {
|
|
202
|
+
...tenant,
|
|
203
|
+
user_role: membership.role,
|
|
204
|
+
membership,
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
async getMembers(tenantId) {
|
|
208
|
+
return Array.from(memberships.values()).filter((m) => m.tenant_id === tenantId);
|
|
209
|
+
},
|
|
210
|
+
async getMembership(tenantId, userId) {
|
|
211
|
+
for (const membership of memberships.values()) {
|
|
212
|
+
if (membership.tenant_id === tenantId && membership.user_id === userId) {
|
|
213
|
+
return membership;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
},
|
|
218
|
+
async addMember(input) {
|
|
219
|
+
const id = `membership-${membershipIdCounter++}`;
|
|
220
|
+
const membership = {
|
|
221
|
+
id,
|
|
222
|
+
tenant_id: input.tenant_id,
|
|
223
|
+
user_id: input.user_id,
|
|
224
|
+
role: input.role,
|
|
225
|
+
joined_at: new Date(),
|
|
226
|
+
};
|
|
227
|
+
memberships.set(id, membership);
|
|
228
|
+
return membership;
|
|
229
|
+
},
|
|
230
|
+
async updateMember(tenantId, userId, input) {
|
|
231
|
+
for (const membership of memberships.values()) {
|
|
232
|
+
if (membership.tenant_id === tenantId && membership.user_id === userId) {
|
|
233
|
+
const updated = {
|
|
234
|
+
...membership,
|
|
235
|
+
...input,
|
|
236
|
+
};
|
|
237
|
+
memberships.set(membership.id, updated);
|
|
238
|
+
return updated;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
},
|
|
243
|
+
async removeMember(tenantId, userId) {
|
|
244
|
+
for (const [key, membership] of memberships.entries()) {
|
|
245
|
+
if (membership.tenant_id === tenantId && membership.user_id === userId) {
|
|
246
|
+
memberships.delete(key);
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return false;
|
|
251
|
+
},
|
|
252
|
+
async shutdown() {
|
|
253
|
+
logger.info('[InMemoryTenantStore] Shutdown');
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=in-memory-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../../../../../src/plugins/tenants/stores/in-memory-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tenant Stores Index
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
export { postgresTenantStore } from './postgres-store.js';
|
|
7
|
+
export { createInMemoryTenantStore as inMemoryTenantStore, DEMO_USER_ID, type InMemoryStoreLogger, type InMemoryTenantStoreOptions, } from './in-memory-store.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/tenants/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,yBAAyB,IAAI,mBAAmB,EAChD,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,GAChC,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tenant Stores Index
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
5
|
+
*/
|
|
6
|
+
export { postgresTenantStore } from './postgres-store.js';
|
|
7
|
+
export { createInMemoryTenantStore as inMemoryTenantStore, DEMO_USER_ID, } from './in-memory-store.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/plugins/tenants/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,yBAAyB,IAAI,mBAAmB,EAChD,YAAY,GAGb,MAAM,sBAAsB,CAAC"}
|
|
@@ -12,9 +12,12 @@
|
|
|
12
12
|
import type { Plugin } from '../../core/plugin-registry.js';
|
|
13
13
|
import type { TenantsPluginConfig, TenantStore } from './types.js';
|
|
14
14
|
/**
|
|
15
|
-
* Create the Tenants plugin
|
|
15
|
+
* Create the Tenants plugin with smart defaults
|
|
16
|
+
*
|
|
17
|
+
* Config is optional - plugin will use defaults and get dependencies from registry.
|
|
18
|
+
* Gracefully handles missing dependencies with clear log messages.
|
|
16
19
|
*/
|
|
17
|
-
export declare function createTenantsPlugin(config
|
|
20
|
+
export declare function createTenantsPlugin(config?: Partial<TenantsPluginConfig>): Plugin;
|
|
18
21
|
/**
|
|
19
22
|
* Helper function to get the tenant store
|
|
20
23
|
* Used by other plugins to access tenant data
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenants-plugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tenants/tenants-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EAMZ,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"tenants-plugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tenants/tenants-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EAMZ,MAAM,YAAY,CAAC;AAUpB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAAG,MAAM,CAqoBrF;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqC3E"}
|
|
@@ -11,55 +11,25 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { getUserById } from '../users/users-plugin.js';
|
|
13
13
|
import { getAuthenticatedUser, isAuthenticated } from '../auth/index.js';
|
|
14
|
+
import { hasPostgres, getPostgres } from '../postgres-plugin.js';
|
|
15
|
+
import { postgresTenantStore } from './stores/index.js';
|
|
14
16
|
// Store instance and registry for helper access
|
|
15
17
|
let currentStore = null;
|
|
16
18
|
let currentRegistry = null;
|
|
17
19
|
/**
|
|
18
|
-
* Create the Tenants plugin
|
|
20
|
+
* Create the Tenants plugin with smart defaults
|
|
21
|
+
*
|
|
22
|
+
* Config is optional - plugin will use defaults and get dependencies from registry.
|
|
23
|
+
* Gracefully handles missing dependencies with clear log messages.
|
|
19
24
|
*/
|
|
20
|
-
export function createTenantsPlugin(config) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (debug) {
|
|
26
|
-
console.log(`[TenantsPlugin] ${message}`, data || '');
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Helper to check if user has access to a tenant
|
|
31
|
-
*/
|
|
32
|
-
async function canAccessTenant(userId, tenantId) {
|
|
33
|
-
try {
|
|
34
|
-
const membership = await config.store.getTenantForUser(tenantId, userId);
|
|
35
|
-
return membership !== null;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return false;
|
|
25
|
+
export function createTenantsPlugin(config = {}) {
|
|
26
|
+
function log(message, data, isError = false) {
|
|
27
|
+
const prefix = '[TenantsPlugin]';
|
|
28
|
+
if (isError) {
|
|
29
|
+
console.error(`${prefix} ${message}`, data || '');
|
|
39
30
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* Helper to check if user has admin/owner role in a tenant
|
|
43
|
-
*/
|
|
44
|
-
async function canManageTenant(userId, tenantId) {
|
|
45
|
-
try {
|
|
46
|
-
const membership = await config.store.getTenantForUser(tenantId, userId);
|
|
47
|
-
return membership !== null && ['owner', 'admin'].includes(membership.user_role);
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Helper to check if user is owner of a tenant
|
|
55
|
-
*/
|
|
56
|
-
async function isOwnerOfTenant(userId, tenantId) {
|
|
57
|
-
try {
|
|
58
|
-
const membership = await config.store.getTenantForUser(tenantId, userId);
|
|
59
|
-
return membership !== null && membership.user_role === 'owner';
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
return false;
|
|
31
|
+
else if (config.debug) {
|
|
32
|
+
console.log(`${prefix} ${message}`, data || '');
|
|
63
33
|
}
|
|
64
34
|
}
|
|
65
35
|
return {
|
|
@@ -67,12 +37,37 @@ export function createTenantsPlugin(config) {
|
|
|
67
37
|
name: 'Tenants',
|
|
68
38
|
version: '1.0.0',
|
|
69
39
|
async onStart(_pluginConfig, registry) {
|
|
40
|
+
const logger = registry.getLogger('tenants');
|
|
41
|
+
// Check for postgres in registry
|
|
42
|
+
if (!hasPostgres()) {
|
|
43
|
+
logger.warn('No Database! Tenants plugin disabled.');
|
|
44
|
+
registry.registerHealthCheck({
|
|
45
|
+
name: 'tenants-store',
|
|
46
|
+
type: 'custom',
|
|
47
|
+
check: async () => ({
|
|
48
|
+
healthy: false,
|
|
49
|
+
details: {
|
|
50
|
+
error: 'PostgreSQL not available',
|
|
51
|
+
state: 'disabled',
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Smart defaults - get dependencies from registry
|
|
58
|
+
const store = config.store ?? postgresTenantStore({
|
|
59
|
+
pool: () => getPostgres().getPool(),
|
|
60
|
+
autoCreateTables: true,
|
|
61
|
+
});
|
|
62
|
+
const debug = config.debug ?? false;
|
|
63
|
+
const apiPrefix = config.apiPrefix ?? '/tenants';
|
|
64
|
+
const apiEnabled = config.apiEnabled ?? true;
|
|
70
65
|
log('Starting tenants plugin');
|
|
71
66
|
// Initialize the store (creates tables if needed)
|
|
72
|
-
await
|
|
67
|
+
await store.initialize();
|
|
73
68
|
log('Tenants plugin migrations complete');
|
|
74
69
|
// Store references for helper access
|
|
75
|
-
currentStore =
|
|
70
|
+
currentStore = store;
|
|
76
71
|
currentRegistry = registry;
|
|
77
72
|
// Register health check
|
|
78
73
|
registry.registerHealthCheck({
|
|
@@ -81,7 +76,7 @@ export function createTenantsPlugin(config) {
|
|
|
81
76
|
check: async () => {
|
|
82
77
|
try {
|
|
83
78
|
// Simple health check - try to search with limit 1
|
|
84
|
-
await
|
|
79
|
+
await store.search({ limit: 1 });
|
|
85
80
|
return { healthy: true };
|
|
86
81
|
}
|
|
87
82
|
catch {
|
|
@@ -89,6 +84,42 @@ export function createTenantsPlugin(config) {
|
|
|
89
84
|
}
|
|
90
85
|
},
|
|
91
86
|
});
|
|
87
|
+
/**
|
|
88
|
+
* Helper to check if user has access to a tenant
|
|
89
|
+
*/
|
|
90
|
+
async function canAccessTenant(userId, tenantId) {
|
|
91
|
+
try {
|
|
92
|
+
const membership = await store.getTenantForUser(tenantId, userId);
|
|
93
|
+
return membership !== null;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Helper to check if user has admin/owner role in a tenant
|
|
101
|
+
*/
|
|
102
|
+
async function canManageTenant(userId, tenantId) {
|
|
103
|
+
try {
|
|
104
|
+
const membership = await store.getTenantForUser(tenantId, userId);
|
|
105
|
+
return membership !== null && ['owner', 'admin'].includes(membership.user_role);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Helper to check if user is owner of a tenant
|
|
113
|
+
*/
|
|
114
|
+
async function isOwnerOfTenant(userId, tenantId) {
|
|
115
|
+
try {
|
|
116
|
+
const membership = await store.getTenantForUser(tenantId, userId);
|
|
117
|
+
return membership !== null && membership.user_role === 'owner';
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
92
123
|
if (!apiEnabled)
|
|
93
124
|
return;
|
|
94
125
|
// ========================================================================
|
|
@@ -97,7 +128,7 @@ export function createTenantsPlugin(config) {
|
|
|
97
128
|
// List/Search tenants
|
|
98
129
|
registry.addRoute({
|
|
99
130
|
method: 'get',
|
|
100
|
-
path: apiPrefix,
|
|
131
|
+
path: apiPrefix || '/',
|
|
101
132
|
pluginId: 'tenants',
|
|
102
133
|
handler: async (req, res) => {
|
|
103
134
|
try {
|
|
@@ -117,7 +148,7 @@ export function createTenantsPlugin(config) {
|
|
|
117
148
|
}
|
|
118
149
|
// Users can only search their own tenants
|
|
119
150
|
// Get all tenants user belongs to
|
|
120
|
-
const userTenants = await
|
|
151
|
+
const userTenants = await store.getTenantsForUser(user.id);
|
|
121
152
|
res.json({
|
|
122
153
|
tenants: userTenants,
|
|
123
154
|
total: userTenants.length,
|
|
@@ -160,7 +191,7 @@ export function createTenantsPlugin(config) {
|
|
|
160
191
|
message: 'You do not have access to this tenant',
|
|
161
192
|
});
|
|
162
193
|
}
|
|
163
|
-
const tenant = await
|
|
194
|
+
const tenant = await store.getById(req.params.id);
|
|
164
195
|
if (!tenant) {
|
|
165
196
|
return res.status(404).json({ error: 'Tenant not found' });
|
|
166
197
|
}
|
|
@@ -175,7 +206,7 @@ export function createTenantsPlugin(config) {
|
|
|
175
206
|
// Create tenant
|
|
176
207
|
registry.addRoute({
|
|
177
208
|
method: 'post',
|
|
178
|
-
path: apiPrefix,
|
|
209
|
+
path: apiPrefix || '/',
|
|
179
210
|
pluginId: 'tenants',
|
|
180
211
|
handler: async (req, res) => {
|
|
181
212
|
try {
|
|
@@ -219,9 +250,9 @@ export function createTenantsPlugin(config) {
|
|
|
219
250
|
message: 'You can only create tenants for yourself',
|
|
220
251
|
});
|
|
221
252
|
}
|
|
222
|
-
const tenant = await
|
|
253
|
+
const tenant = await store.create(input);
|
|
223
254
|
// Automatically add creator as owner
|
|
224
|
-
await
|
|
255
|
+
await store.addMember({
|
|
225
256
|
tenant_id: tenant.id,
|
|
226
257
|
user_id: user.id,
|
|
227
258
|
role: 'owner',
|
|
@@ -267,7 +298,7 @@ export function createTenantsPlugin(config) {
|
|
|
267
298
|
name: req.body.name,
|
|
268
299
|
metadata: req.body.metadata,
|
|
269
300
|
};
|
|
270
|
-
const tenant = await
|
|
301
|
+
const tenant = await store.update(req.params.id, input);
|
|
271
302
|
if (!tenant) {
|
|
272
303
|
return res.status(404).json({ error: 'Tenant not found' });
|
|
273
304
|
}
|
|
@@ -308,7 +339,7 @@ export function createTenantsPlugin(config) {
|
|
|
308
339
|
message: 'Only owners can delete tenants',
|
|
309
340
|
});
|
|
310
341
|
}
|
|
311
|
-
const deleted = await
|
|
342
|
+
const deleted = await store.delete(req.params.id);
|
|
312
343
|
if (!deleted) {
|
|
313
344
|
return res.status(404).json({ error: 'Tenant not found' });
|
|
314
345
|
}
|
|
@@ -352,7 +383,7 @@ export function createTenantsPlugin(config) {
|
|
|
352
383
|
message: 'You can only view your own tenants',
|
|
353
384
|
});
|
|
354
385
|
}
|
|
355
|
-
const tenants = await
|
|
386
|
+
const tenants = await store.getTenantsForUser(req.params.userId);
|
|
356
387
|
res.json({ tenants, total: tenants.length });
|
|
357
388
|
}
|
|
358
389
|
catch (error) {
|
|
@@ -392,7 +423,7 @@ export function createTenantsPlugin(config) {
|
|
|
392
423
|
message: 'You do not have access to this tenant',
|
|
393
424
|
});
|
|
394
425
|
}
|
|
395
|
-
const members = await
|
|
426
|
+
const members = await store.getMembers(req.params.tenantId);
|
|
396
427
|
res.json({ members, total: members.length });
|
|
397
428
|
}
|
|
398
429
|
catch (error) {
|
|
@@ -447,7 +478,7 @@ export function createTenantsPlugin(config) {
|
|
|
447
478
|
error: `Invalid role. Must be one of: ${validRoles.join(', ')}`,
|
|
448
479
|
});
|
|
449
480
|
}
|
|
450
|
-
const membership = await
|
|
481
|
+
const membership = await store.addMember(input);
|
|
451
482
|
log('Member added to tenant', {
|
|
452
483
|
tenantId: input.tenant_id,
|
|
453
484
|
userId: input.user_id,
|
|
@@ -503,7 +534,7 @@ export function createTenantsPlugin(config) {
|
|
|
503
534
|
error: `Invalid role. Must be one of: ${validRoles.join(', ')}`,
|
|
504
535
|
});
|
|
505
536
|
}
|
|
506
|
-
const membership = await
|
|
537
|
+
const membership = await store.updateMember(req.params.tenantId, req.params.userId, input);
|
|
507
538
|
if (!membership) {
|
|
508
539
|
return res.status(404).json({ error: 'Membership not found' });
|
|
509
540
|
}
|
|
@@ -549,7 +580,7 @@ export function createTenantsPlugin(config) {
|
|
|
549
580
|
message: 'Only admins and owners can remove members',
|
|
550
581
|
});
|
|
551
582
|
}
|
|
552
|
-
const deleted = await
|
|
583
|
+
const deleted = await store.removeMember(req.params.tenantId, req.params.userId);
|
|
553
584
|
if (!deleted) {
|
|
554
585
|
return res.status(404).json({ error: 'Membership not found' });
|
|
555
586
|
}
|
|
@@ -570,7 +601,9 @@ export function createTenantsPlugin(config) {
|
|
|
570
601
|
},
|
|
571
602
|
async onStop() {
|
|
572
603
|
log('Stopping tenants plugin');
|
|
573
|
-
|
|
604
|
+
if (currentStore) {
|
|
605
|
+
await currentStore.shutdown();
|
|
606
|
+
}
|
|
574
607
|
currentStore = null;
|
|
575
608
|
currentRegistry = null;
|
|
576
609
|
},
|