@qwickapps/server 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +238 -0
  2. package/dist/core/control-panel.d.ts +7 -2
  3. package/dist/core/control-panel.d.ts.map +1 -1
  4. package/dist/core/control-panel.js +92 -54
  5. package/dist/core/control-panel.js.map +1 -1
  6. package/dist/core/gateway.d.ts +159 -79
  7. package/dist/core/gateway.d.ts.map +1 -1
  8. package/dist/core/gateway.js +679 -319
  9. package/dist/core/gateway.js.map +1 -1
  10. package/dist/core/index.d.ts +3 -1
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/core/index.js +2 -0
  13. package/dist/core/index.js.map +1 -1
  14. package/dist/core/plugin-registry.d.ts +271 -0
  15. package/dist/core/plugin-registry.d.ts.map +1 -0
  16. package/dist/core/plugin-registry.js +326 -0
  17. package/dist/core/plugin-registry.js.map +1 -0
  18. package/dist/core/types.d.ts +16 -33
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/index.d.ts +8 -5
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +15 -7
  23. package/dist/index.js.map +1 -1
  24. package/dist/plugins/auth/adapters/auth0-adapter.d.ts +14 -0
  25. package/dist/plugins/auth/adapters/auth0-adapter.d.ts.map +1 -0
  26. package/dist/plugins/auth/adapters/auth0-adapter.js +179 -0
  27. package/dist/plugins/auth/adapters/auth0-adapter.js.map +1 -0
  28. package/dist/plugins/auth/adapters/basic-adapter.d.ts +13 -0
  29. package/dist/plugins/auth/adapters/basic-adapter.d.ts.map +1 -0
  30. package/dist/plugins/auth/adapters/basic-adapter.js +51 -0
  31. package/dist/plugins/auth/adapters/basic-adapter.js.map +1 -0
  32. package/dist/plugins/auth/adapters/index.d.ts +9 -0
  33. package/dist/plugins/auth/adapters/index.d.ts.map +1 -0
  34. package/dist/plugins/auth/adapters/index.js +9 -0
  35. package/dist/plugins/auth/adapters/index.js.map +1 -0
  36. package/dist/plugins/auth/adapters/supabase-adapter.d.ts +13 -0
  37. package/dist/plugins/auth/adapters/supabase-adapter.d.ts.map +1 -0
  38. package/dist/plugins/auth/adapters/supabase-adapter.js +109 -0
  39. package/dist/plugins/auth/adapters/supabase-adapter.js.map +1 -0
  40. package/dist/plugins/auth/auth-plugin.d.ts +40 -0
  41. package/dist/plugins/auth/auth-plugin.d.ts.map +1 -0
  42. package/dist/plugins/auth/auth-plugin.js +255 -0
  43. package/dist/plugins/auth/auth-plugin.js.map +1 -0
  44. package/dist/plugins/auth/auth-plugin.test.d.ts +9 -0
  45. package/dist/plugins/auth/auth-plugin.test.d.ts.map +1 -0
  46. package/dist/plugins/auth/auth-plugin.test.js +147 -0
  47. package/dist/plugins/auth/auth-plugin.test.js.map +1 -0
  48. package/dist/plugins/auth/index.d.ts +12 -0
  49. package/dist/plugins/auth/index.d.ts.map +1 -0
  50. package/dist/plugins/auth/index.js +13 -0
  51. package/dist/plugins/auth/index.js.map +1 -0
  52. package/dist/plugins/auth/types.d.ts +148 -0
  53. package/dist/plugins/auth/types.d.ts.map +1 -0
  54. package/dist/plugins/auth/types.js +14 -0
  55. package/dist/plugins/auth/types.js.map +1 -0
  56. package/dist/plugins/bans/bans-plugin.d.ts +59 -0
  57. package/dist/plugins/bans/bans-plugin.d.ts.map +1 -0
  58. package/dist/plugins/bans/bans-plugin.js +428 -0
  59. package/dist/plugins/bans/bans-plugin.js.map +1 -0
  60. package/dist/plugins/bans/index.d.ts +9 -0
  61. package/dist/plugins/bans/index.d.ts.map +1 -0
  62. package/dist/plugins/bans/index.js +10 -0
  63. package/dist/plugins/bans/index.js.map +1 -0
  64. package/dist/plugins/bans/stores/index.d.ts +7 -0
  65. package/dist/plugins/bans/stores/index.d.ts.map +1 -0
  66. package/dist/plugins/bans/stores/index.js +7 -0
  67. package/dist/plugins/bans/stores/index.js.map +1 -0
  68. package/dist/plugins/bans/stores/postgres-store.d.ts +29 -0
  69. package/dist/plugins/bans/stores/postgres-store.d.ts.map +1 -0
  70. package/dist/plugins/bans/stores/postgres-store.js +132 -0
  71. package/dist/plugins/bans/stores/postgres-store.js.map +1 -0
  72. package/dist/plugins/bans/types.d.ts +128 -0
  73. package/dist/plugins/bans/types.d.ts.map +1 -0
  74. package/dist/plugins/bans/types.js +11 -0
  75. package/dist/plugins/bans/types.js.map +1 -0
  76. package/dist/plugins/cache-plugin.d.ts +14 -3
  77. package/dist/plugins/cache-plugin.d.ts.map +1 -1
  78. package/dist/plugins/cache-plugin.js +27 -7
  79. package/dist/plugins/cache-plugin.js.map +1 -1
  80. package/dist/plugins/cache-plugin.test.js +96 -32
  81. package/dist/plugins/cache-plugin.test.js.map +1 -1
  82. package/dist/plugins/config-plugin.d.ts +3 -2
  83. package/dist/plugins/config-plugin.d.ts.map +1 -1
  84. package/dist/plugins/config-plugin.js +17 -10
  85. package/dist/plugins/config-plugin.js.map +1 -1
  86. package/dist/plugins/diagnostics-plugin.d.ts +2 -2
  87. package/dist/plugins/diagnostics-plugin.d.ts.map +1 -1
  88. package/dist/plugins/diagnostics-plugin.js +17 -10
  89. package/dist/plugins/diagnostics-plugin.js.map +1 -1
  90. package/dist/plugins/entitlements/entitlements-plugin.d.ts +95 -0
  91. package/dist/plugins/entitlements/entitlements-plugin.d.ts.map +1 -0
  92. package/dist/plugins/entitlements/entitlements-plugin.js +707 -0
  93. package/dist/plugins/entitlements/entitlements-plugin.js.map +1 -0
  94. package/dist/plugins/entitlements/index.d.ts +12 -0
  95. package/dist/plugins/entitlements/index.d.ts.map +1 -0
  96. package/dist/plugins/entitlements/index.js +16 -0
  97. package/dist/plugins/entitlements/index.js.map +1 -0
  98. package/dist/plugins/entitlements/sources/index.d.ts +9 -0
  99. package/dist/plugins/entitlements/sources/index.d.ts.map +1 -0
  100. package/dist/plugins/entitlements/sources/index.js +9 -0
  101. package/dist/plugins/entitlements/sources/index.js.map +1 -0
  102. package/dist/plugins/entitlements/sources/postgres-source.d.ts +29 -0
  103. package/dist/plugins/entitlements/sources/postgres-source.d.ts.map +1 -0
  104. package/dist/plugins/entitlements/sources/postgres-source.js +169 -0
  105. package/dist/plugins/entitlements/sources/postgres-source.js.map +1 -0
  106. package/dist/plugins/entitlements/types.d.ts +232 -0
  107. package/dist/plugins/entitlements/types.d.ts.map +1 -0
  108. package/dist/plugins/entitlements/types.js +11 -0
  109. package/dist/plugins/entitlements/types.js.map +1 -0
  110. package/dist/plugins/frontend-app-plugin.d.ts +9 -3
  111. package/dist/plugins/frontend-app-plugin.d.ts.map +1 -1
  112. package/dist/plugins/frontend-app-plugin.js +14 -9
  113. package/dist/plugins/frontend-app-plugin.js.map +1 -1
  114. package/dist/plugins/health-plugin.d.ts +5 -2
  115. package/dist/plugins/health-plugin.d.ts.map +1 -1
  116. package/dist/plugins/health-plugin.js +20 -5
  117. package/dist/plugins/health-plugin.js.map +1 -1
  118. package/dist/plugins/index.d.ts +8 -2
  119. package/dist/plugins/index.d.ts.map +1 -1
  120. package/dist/plugins/index.js +8 -2
  121. package/dist/plugins/index.js.map +1 -1
  122. package/dist/plugins/logs-plugin.d.ts +3 -2
  123. package/dist/plugins/logs-plugin.d.ts.map +1 -1
  124. package/dist/plugins/logs-plugin.js +21 -12
  125. package/dist/plugins/logs-plugin.js.map +1 -1
  126. package/dist/plugins/postgres-plugin.d.ts +3 -3
  127. package/dist/plugins/postgres-plugin.d.ts.map +1 -1
  128. package/dist/plugins/postgres-plugin.js +9 -7
  129. package/dist/plugins/postgres-plugin.js.map +1 -1
  130. package/dist/plugins/postgres-plugin.test.js +47 -29
  131. package/dist/plugins/postgres-plugin.test.js.map +1 -1
  132. package/dist/plugins/users/index.d.ts +12 -0
  133. package/dist/plugins/users/index.d.ts.map +1 -0
  134. package/dist/plugins/users/index.js +13 -0
  135. package/dist/plugins/users/index.js.map +1 -0
  136. package/dist/plugins/users/stores/index.d.ts +7 -0
  137. package/dist/plugins/users/stores/index.d.ts.map +1 -0
  138. package/dist/plugins/users/stores/index.js +7 -0
  139. package/dist/plugins/users/stores/index.js.map +1 -0
  140. package/dist/plugins/users/stores/postgres-store.d.ts +28 -0
  141. package/dist/plugins/users/stores/postgres-store.d.ts.map +1 -0
  142. package/dist/plugins/users/stores/postgres-store.js +157 -0
  143. package/dist/plugins/users/stores/postgres-store.js.map +1 -0
  144. package/dist/plugins/users/types.d.ts +189 -0
  145. package/dist/plugins/users/types.d.ts.map +1 -0
  146. package/dist/plugins/users/types.js +12 -0
  147. package/dist/plugins/users/types.js.map +1 -0
  148. package/dist/plugins/users/users-plugin.d.ts +39 -0
  149. package/dist/plugins/users/users-plugin.d.ts.map +1 -0
  150. package/dist/plugins/users/users-plugin.js +242 -0
  151. package/dist/plugins/users/users-plugin.js.map +1 -0
  152. package/dist-ui/assets/index-Bsp2ntcw.js +465 -0
  153. package/dist-ui/assets/index-Bsp2ntcw.js.map +1 -0
  154. package/dist-ui/index.html +1 -1
  155. package/dist-ui-lib/api/controlPanelApi.d.ts +232 -0
  156. package/dist-ui-lib/components/ControlPanelApp.d.ts +61 -0
  157. package/dist-ui-lib/components/index.d.ts +18 -0
  158. package/dist-ui-lib/config/AppConfig.d.ts +7 -0
  159. package/dist-ui-lib/dashboard/DashboardWidgetRegistry.d.ts +62 -0
  160. package/dist-ui-lib/dashboard/DashboardWidgetRenderer.d.ts +8 -0
  161. package/dist-ui-lib/dashboard/PluginWidgetRenderer.d.ts +19 -0
  162. package/dist-ui-lib/dashboard/WidgetComponentRegistry.d.ts +44 -0
  163. package/dist-ui-lib/dashboard/builtInWidgets.d.ts +19 -0
  164. package/dist-ui-lib/dashboard/index.d.ts +13 -0
  165. package/dist-ui-lib/dashboard/widgets/ServiceHealthWidget.d.ts +12 -0
  166. package/dist-ui-lib/dashboard/widgets/index.d.ts +6 -0
  167. package/dist-ui-lib/index.js +6441 -0
  168. package/dist-ui-lib/index.js.map +1 -0
  169. package/dist-ui-lib/pages/ConfigPage.d.ts +1 -0
  170. package/dist-ui-lib/pages/DashboardPage.d.ts +1 -0
  171. package/dist-ui-lib/pages/DiagnosticsPage.d.ts +1 -0
  172. package/dist-ui-lib/pages/EntitlementsPage.d.ts +17 -0
  173. package/dist-ui-lib/pages/LogsPage.d.ts +1 -0
  174. package/dist-ui-lib/pages/NotFoundPage.d.ts +1 -0
  175. package/dist-ui-lib/pages/PluginPage.d.ts +15 -0
  176. package/dist-ui-lib/pages/SystemPage.d.ts +1 -0
  177. package/dist-ui-lib/pages/UsersPage.d.ts +22 -0
  178. package/package.json +18 -6
  179. package/src/core/control-panel.ts +114 -61
  180. package/src/core/gateway.ts +863 -403
  181. package/src/core/index.ts +21 -2
  182. package/src/core/plugin-registry.ts +653 -0
  183. package/src/core/types.ts +31 -37
  184. package/src/index.ts +118 -19
  185. package/src/plugins/auth/adapters/auth0-adapter.ts +214 -0
  186. package/src/plugins/auth/adapters/basic-adapter.ts +61 -0
  187. package/src/plugins/auth/adapters/index.ts +9 -0
  188. package/src/plugins/auth/adapters/supabase-adapter.ts +141 -0
  189. package/src/plugins/auth/auth-plugin.test.ts +176 -0
  190. package/src/plugins/auth/auth-plugin.ts +303 -0
  191. package/src/plugins/auth/index.ts +33 -0
  192. package/src/plugins/auth/types.ts +165 -0
  193. package/src/plugins/bans/bans-plugin.ts +485 -0
  194. package/src/plugins/bans/index.ts +31 -0
  195. package/src/plugins/bans/stores/index.ts +7 -0
  196. package/src/plugins/bans/stores/postgres-store.ts +195 -0
  197. package/src/plugins/bans/types.ts +141 -0
  198. package/src/plugins/cache-plugin.test.ts +105 -32
  199. package/src/plugins/cache-plugin.ts +40 -9
  200. package/src/plugins/config-plugin.ts +23 -12
  201. package/src/plugins/diagnostics-plugin.ts +22 -12
  202. package/src/plugins/entitlements/entitlements-plugin.ts +820 -0
  203. package/src/plugins/entitlements/index.ts +51 -0
  204. package/src/plugins/entitlements/sources/index.ts +9 -0
  205. package/src/plugins/entitlements/sources/postgres-source.ts +253 -0
  206. package/src/plugins/entitlements/types.ts +256 -0
  207. package/src/plugins/frontend-app-plugin.ts +24 -12
  208. package/src/plugins/health-plugin.ts +27 -7
  209. package/src/plugins/index.ts +106 -4
  210. package/src/plugins/logs-plugin.ts +28 -14
  211. package/src/plugins/postgres-plugin.test.ts +49 -29
  212. package/src/plugins/postgres-plugin.ts +11 -9
  213. package/src/plugins/users/index.ts +35 -0
  214. package/src/plugins/users/stores/index.ts +7 -0
  215. package/src/plugins/users/stores/postgres-store.ts +225 -0
  216. package/src/plugins/users/types.ts +209 -0
  217. package/src/plugins/users/users-plugin.ts +281 -0
  218. package/ui/src/App.tsx +185 -31
  219. package/ui/src/api/controlPanelApi.ts +354 -1
  220. package/ui/src/components/ControlPanelApp.tsx +209 -0
  221. package/ui/src/components/index.ts +62 -0
  222. package/ui/src/dashboard/DashboardWidgetRegistry.tsx +129 -0
  223. package/ui/src/dashboard/DashboardWidgetRenderer.tsx +34 -0
  224. package/ui/src/dashboard/PluginWidgetRenderer.tsx +115 -0
  225. package/ui/src/dashboard/WidgetComponentRegistry.tsx +116 -0
  226. package/ui/src/dashboard/builtInWidgets.tsx +29 -0
  227. package/ui/src/dashboard/index.ts +35 -0
  228. package/ui/src/dashboard/widgets/ServiceHealthWidget.tsx +140 -0
  229. package/ui/src/dashboard/widgets/index.ts +7 -0
  230. package/ui/src/pages/DashboardPage.tsx +28 -149
  231. package/ui/src/pages/EntitlementsPage.tsx +557 -0
  232. package/ui/src/pages/LogsPage.tsx +174 -8
  233. package/ui/src/pages/PluginPage.tsx +148 -0
  234. package/ui/src/pages/SystemPage.tsx +445 -0
  235. package/ui/src/pages/UsersPage.tsx +837 -0
  236. package/ui/tsconfig.lib.json +11 -0
  237. package/ui/vite.lib.config.ts +51 -0
  238. package/dist-ui/assets/index-CW1BviRn.js +0 -465
  239. package/dist-ui/assets/index-CW1BviRn.js.map +0 -1
  240. package/ui/src/pages/HealthPage.tsx +0 -204
package/src/core/types.ts CHANGED
@@ -116,6 +116,16 @@ export interface ControlPanelConfig {
116
116
  /** Product name displayed in the control panel */
117
117
  productName: string;
118
118
 
119
+ /** Optional: Logo name for ProductLogo component (defaults to productName) */
120
+ logoName?: string;
121
+
122
+ /**
123
+ * Optional: URL path to the product logo icon (SVG, PNG, etc.).
124
+ * Used by the React UI to display a custom logo instead of the default QwickIcon.
125
+ * Example: '/cpanel/logo.svg'
126
+ */
127
+ logoIconUrl?: string;
128
+
119
129
  /** Port to run the control panel on */
120
130
  port: number;
121
131
 
@@ -124,7 +134,6 @@ export interface ControlPanelConfig {
124
134
 
125
135
  /** Optional: Branding configuration */
126
136
  branding?: {
127
- logo?: string;
128
137
  primaryColor?: string;
129
138
  favicon?: string;
130
139
  };
@@ -168,40 +177,20 @@ export interface ControlPanelConfig {
168
177
  customUiPath?: string;
169
178
  }
170
179
 
171
- /**
172
- * Plugin Context - passed to plugins during initialization
173
- */
174
- export interface PluginContext {
175
- config: ControlPanelConfig;
176
- app: Application;
177
- router: Router;
178
- logger: Logger;
179
- registerHealthCheck: (check: HealthCheck) => void;
180
- }
181
-
182
- /**
183
- * Control Panel Plugin interface
184
- */
185
- export interface ControlPanelPlugin {
186
- /** Unique plugin name */
187
- name: string;
188
-
189
- /** Order for tab display (lower = first) */
190
- order?: number;
191
-
192
- /** API routes provided by this plugin */
193
- routes?: Array<{
194
- method: 'get' | 'post' | 'put' | 'delete';
195
- path: string;
196
- handler: RequestHandler;
197
- }>;
198
-
199
- /** Lifecycle: Initialize plugin */
200
- onInit?: (context: PluginContext) => Promise<void>;
201
-
202
- /** Lifecycle: Shutdown plugin */
203
- onShutdown?: () => Promise<void>;
204
- }
180
+ // Plugin types are now in plugin-registry.ts
181
+ // Re-export for convenience
182
+ export type {
183
+ Plugin,
184
+ PluginConfig,
185
+ PluginInfo,
186
+ PluginEvent,
187
+ PluginEventHandler,
188
+ PluginRegistry,
189
+ MenuContribution,
190
+ PageContribution,
191
+ WidgetContribution,
192
+ RouteDefinition,
193
+ } from './plugin-registry.js';
205
194
 
206
195
  /**
207
196
  * Health Check types
@@ -283,14 +272,17 @@ export interface ControlPanelInstance {
283
272
  /** Stop the control panel server */
284
273
  stop: () => Promise<void>;
285
274
 
286
- /** Register a plugin */
287
- registerPlugin: (plugin: ControlPanelPlugin) => Promise<void>;
275
+ /** Start a plugin with optional configuration */
276
+ startPlugin: (plugin: import('./plugin-registry.js').Plugin, config?: import('./plugin-registry.js').PluginConfig) => Promise<boolean>;
288
277
 
289
278
  /** Get health check results */
290
279
  getHealthStatus: () => Record<string, HealthCheckResult>;
291
280
 
292
281
  /** Get diagnostics for AI agents */
293
282
  getDiagnostics: () => DiagnosticsReport;
283
+
284
+ /** Get the plugin registry for direct access */
285
+ getPluginRegistry: () => import('./plugin-registry.js').PluginRegistry;
294
286
  }
295
287
 
296
288
  /**
@@ -300,6 +292,8 @@ export interface DiagnosticsReport {
300
292
  timestamp: string;
301
293
  product: string;
302
294
  version?: string;
295
+ /** @qwickapps/server framework version */
296
+ frameworkVersion?: string;
303
297
  uptime: number;
304
298
  health: Record<string, HealthCheckResult>;
305
299
  system: {
package/src/index.ts CHANGED
@@ -9,15 +9,33 @@
9
9
 
10
10
  // Core exports
11
11
  export { createControlPanel } from './core/control-panel.js';
12
+ export type { CreateControlPanelOptions } from './core/control-panel.js';
12
13
  export { createGateway } from './core/gateway.js';
13
14
  export { HealthManager } from './core/health-manager.js';
14
15
 
15
- // Guards exports
16
+ // Plugin Registry exports (event-driven architecture v2.0)
16
17
  export {
17
- createRouteGuard,
18
- isAuthenticated,
19
- getAuthenticatedUser,
20
- } from './core/guards.js';
18
+ createPluginRegistry,
19
+ getPluginRegistry,
20
+ hasPluginRegistry,
21
+ resetPluginRegistry,
22
+ PluginRegistryImpl,
23
+ } from './core/plugin-registry.js';
24
+ export type {
25
+ Plugin,
26
+ PluginConfig,
27
+ PluginEvent,
28
+ PluginEventHandler,
29
+ PluginRegistry,
30
+ PluginInfo,
31
+ MenuContribution,
32
+ PageContribution,
33
+ WidgetContribution,
34
+ RouteDefinition,
35
+ } from './core/plugin-registry.js';
36
+
37
+ // Route guards (for control panel protection)
38
+ export { createRouteGuard } from './core/guards.js';
21
39
 
22
40
  // Logging exports
23
41
  export {
@@ -29,9 +47,7 @@ export type { LoggingConfig } from './core/logging.js';
29
47
 
30
48
  export type {
31
49
  ControlPanelConfig,
32
- ControlPanelPlugin,
33
50
  ControlPanelInstance,
34
- PluginContext,
35
51
  HealthCheck,
36
52
  HealthCheckType,
37
53
  HealthCheckResult,
@@ -40,7 +56,7 @@ export type {
40
56
  ConfigDisplayOptions,
41
57
  Logger,
42
58
  DiagnosticsReport,
43
- // New mount path and guard types
59
+ // Route guard types
44
60
  RouteGuardType,
45
61
  RouteGuardConfig,
46
62
  BasicAuthGuardConfig,
@@ -53,7 +69,7 @@ export type {
53
69
  export type {
54
70
  GatewayConfig,
55
71
  GatewayInstance,
56
- ServiceFactory,
72
+ MountedAppConfig,
57
73
  } from './core/gateway.js';
58
74
 
59
75
  // Built-in plugins
@@ -63,18 +79,64 @@ export {
63
79
  createConfigPlugin,
64
80
  createDiagnosticsPlugin,
65
81
  createFrontendAppPlugin,
66
- // Database plugins
82
+ // Postgres plugin
67
83
  createPostgresPlugin,
68
84
  getPostgres,
69
85
  hasPostgres,
70
- // Backward compatibility aliases (deprecated)
71
- createPostgresPlugin as createDatabasePlugin,
72
- getPostgres as getDatabase,
73
- hasPostgres as hasDatabase,
74
- // Cache plugins
86
+ // Cache plugin
75
87
  createCachePlugin,
76
88
  getCache,
77
89
  hasCache,
90
+ // Auth plugin
91
+ createAuthPlugin,
92
+ isAuthenticated,
93
+ getAuthenticatedUser,
94
+ getAccessToken,
95
+ requireAuth,
96
+ requireRoles,
97
+ requireAnyRole,
98
+ auth0Adapter,
99
+ basicAdapter,
100
+ supabaseAdapter,
101
+ isAuthenticatedRequest,
102
+ // Users plugin
103
+ createUsersPlugin,
104
+ getUserStore,
105
+ getUserById,
106
+ getUserByEmail,
107
+ findOrCreateUser,
108
+ postgresUserStore,
109
+ // Bans plugin (separate from Users, depends on Users)
110
+ createBansPlugin,
111
+ getBanStore,
112
+ isUserBanned,
113
+ isEmailBanned,
114
+ getActiveBan,
115
+ banUser,
116
+ unbanUser,
117
+ listActiveBans,
118
+ postgresBanStore,
119
+ // Entitlements plugin
120
+ createEntitlementsPlugin,
121
+ getEntitlementSource,
122
+ isSourceReadonly,
123
+ getEntitlements,
124
+ refreshEntitlements,
125
+ hasEntitlement,
126
+ hasAnyEntitlement,
127
+ hasAllEntitlements,
128
+ grantEntitlement,
129
+ revokeEntitlement,
130
+ setEntitlements,
131
+ getAvailableEntitlements,
132
+ getEntitlementStats,
133
+ invalidateEntitlementCache,
134
+ storeExternalIdMapping,
135
+ invalidateByExternalId,
136
+ requireEntitlement,
137
+ requireAnyEntitlement,
138
+ requireAllEntitlements,
139
+ postgresEntitlementSource,
78
140
  } from './plugins/index.js';
79
141
  export type {
80
142
  HealthPluginConfig,
@@ -82,14 +144,51 @@ export type {
82
144
  ConfigPluginConfig,
83
145
  DiagnosticsPluginConfig,
84
146
  FrontendAppPluginConfig,
85
- // Database plugin types
147
+ // Postgres plugin types
86
148
  PostgresPluginConfig,
87
149
  PostgresInstance,
88
150
  TransactionCallback,
89
- // Backward compatibility aliases (deprecated)
90
- PostgresPluginConfig as DatabasePluginConfig,
91
- PostgresInstance as DatabaseInstance,
92
151
  // Cache plugin types
93
152
  CachePluginConfig,
94
153
  CacheInstance,
154
+ // Auth plugin types
155
+ AuthPluginConfig,
156
+ AuthAdapter,
157
+ AuthenticatedUser,
158
+ AuthenticatedRequest,
159
+ Auth0AdapterConfig,
160
+ SupabaseAdapterConfig,
161
+ BasicAdapterConfig,
162
+ // Users plugin types
163
+ UsersPluginConfig,
164
+ UserStore,
165
+ User,
166
+ CreateUserInput,
167
+ UpdateUserInput,
168
+ UserSearchParams,
169
+ UserListResponse,
170
+ PostgresUserStoreConfig,
171
+ UserSyncConfig,
172
+ UsersApiConfig,
173
+ UsersUiConfig,
174
+ // Bans plugin types
175
+ BansPluginConfig,
176
+ BanStore,
177
+ Ban,
178
+ CreateBanInput,
179
+ RemoveBanInput,
180
+ BanCallbacks,
181
+ PostgresBanStoreConfig,
182
+ // Entitlements plugin types
183
+ EntitlementsPluginConfig,
184
+ EntitlementSource,
185
+ EntitlementResult,
186
+ EntitlementDefinition,
187
+ EntitlementCallbacks,
188
+ EntitlementsCacheConfig,
189
+ EntitlementsApiConfig,
190
+ PostgresEntitlementSourceConfig,
191
+ UserEntitlement,
192
+ CachedEntitlements,
193
+ EntitlementStats,
95
194
  } from './plugins/index.js';
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Auth0 Adapter
3
+ *
4
+ * Provides Auth0 authentication using express-openid-connect.
5
+ * Enhanced with RBAC support, domain whitelisting, and token exposure.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import type { Request, Response, RequestHandler } from 'express';
11
+ import type { AuthAdapter, AuthenticatedUser, Auth0AdapterConfig } from '../types.js';
12
+
13
+ /**
14
+ * Extract user roles from Auth0 claims
15
+ */
16
+ function extractUserRoles(req: Request, domain: string): string[] {
17
+ const oidc = (req as any).oidc;
18
+ const user = oidc?.user;
19
+
20
+ if (!user) return [];
21
+
22
+ // Check various common locations for roles
23
+ const roles: string[] = [];
24
+
25
+ // Standard RBAC claim
26
+ if (Array.isArray(user['https://roles'])) {
27
+ roles.push(...user['https://roles']);
28
+ }
29
+
30
+ // Namespaced roles (common pattern)
31
+ const namespace = domain ? `https://${domain}/` : '';
32
+ if (namespace && Array.isArray(user[`${namespace}roles`])) {
33
+ roles.push(...user[`${namespace}roles`]);
34
+ }
35
+
36
+ // Auth0 authorization extension
37
+ if (Array.isArray(user.roles)) {
38
+ roles.push(...user.roles);
39
+ }
40
+
41
+ // Custom claims
42
+ if (Array.isArray(user['custom:roles'])) {
43
+ roles.push(...user['custom:roles']);
44
+ }
45
+
46
+ return [...new Set(roles)]; // Deduplicate
47
+ }
48
+
49
+ /**
50
+ * Create an Auth0 authentication adapter
51
+ */
52
+ export function auth0Adapter(config: Auth0AdapterConfig): AuthAdapter {
53
+ let authMiddleware: RequestHandler | null = null;
54
+ let initializationError: Error | null = null;
55
+
56
+ const adapter: AuthAdapter = {
57
+ name: 'auth0',
58
+
59
+ initialize(): RequestHandler {
60
+ // Return a middleware that lazily initializes Auth0
61
+ return async (req: Request, res: Response, next) => {
62
+ // Skip if already initialized with error
63
+ if (initializationError) {
64
+ return res.status(500).json({
65
+ error: 'Auth Configuration Error',
66
+ message: 'Auth0 is not properly configured.',
67
+ });
68
+ }
69
+
70
+ // Lazy initialize the Auth0 middleware
71
+ if (!authMiddleware) {
72
+ try {
73
+ const { auth } = await import('express-openid-connect');
74
+
75
+ const authConfig: Record<string, unknown> = {
76
+ authRequired: false, // We handle auth requirement ourselves
77
+ auth0Logout: true,
78
+ secret: config.secret,
79
+ baseURL: config.baseUrl,
80
+ clientID: config.clientId,
81
+ issuerBaseURL: `https://${config.domain}`,
82
+ clientSecret: config.clientSecret,
83
+ idpLogout: true,
84
+ routes: {
85
+ login: config.routes?.login || '/login',
86
+ logout: config.routes?.logout || '/logout',
87
+ callback: config.routes?.callback || '/callback',
88
+ },
89
+ };
90
+
91
+ // Add audience if specified (for API access tokens)
92
+ if (config.audience) {
93
+ authConfig.authorizationParams = {
94
+ audience: config.audience,
95
+ scope: (config.scopes || ['openid', 'profile', 'email']).join(' '),
96
+ };
97
+ }
98
+
99
+ // Enable access token fetching if needed
100
+ if (config.exposeAccessToken && config.audience) {
101
+ authConfig.afterCallback = (
102
+ _req: Request,
103
+ _res: Response,
104
+ session: Record<string, unknown>
105
+ ) => {
106
+ // Access token is automatically stored in session
107
+ return session;
108
+ };
109
+ }
110
+
111
+ authMiddleware = auth(authConfig);
112
+ } catch (error) {
113
+ initializationError =
114
+ error instanceof Error ? error : new Error('Failed to initialize Auth0');
115
+ console.error('[Auth0Adapter] Initialization error:', error);
116
+ return res.status(500).json({
117
+ error: 'Auth Configuration Error',
118
+ message:
119
+ 'Auth0 is not properly configured. Install express-openid-connect package.',
120
+ });
121
+ }
122
+ }
123
+
124
+ // Apply the Auth0 middleware
125
+ authMiddleware!(req, res, next);
126
+ };
127
+ },
128
+
129
+ isAuthenticated(req: Request): boolean {
130
+ const oidc = (req as any).oidc;
131
+ if (!oidc?.isAuthenticated()) {
132
+ return false;
133
+ }
134
+
135
+ // Check domain whitelist if configured
136
+ if (config.allowedDomains && config.allowedDomains.length > 0) {
137
+ const email = oidc.user?.email;
138
+ if (!email) return false;
139
+
140
+ const domain = email.split('@')[1];
141
+ if (!config.allowedDomains.includes(domain) && !config.allowedDomains.includes(`@${domain}`)) {
142
+ return false;
143
+ }
144
+ }
145
+
146
+ // Check role whitelist if configured
147
+ if (config.allowedRoles && config.allowedRoles.length > 0) {
148
+ const userRoles = extractUserRoles(req, config.domain);
149
+ const hasRole = config.allowedRoles.some((role) => userRoles.includes(role));
150
+ if (!hasRole) {
151
+ return false;
152
+ }
153
+ }
154
+
155
+ return true;
156
+ },
157
+
158
+ getUser(req: Request): AuthenticatedUser | null {
159
+ const oidc = (req as any).oidc;
160
+
161
+ if (!adapter.isAuthenticated(req)) {
162
+ return null;
163
+ }
164
+
165
+ const user = oidc.user;
166
+ if (!user) return null;
167
+
168
+ return {
169
+ id: user.sub,
170
+ email: user.email,
171
+ name: user.name || user.nickname,
172
+ picture: user.picture,
173
+ emailVerified: user.email_verified,
174
+ roles: extractUserRoles(req, config.domain),
175
+ raw: user,
176
+ };
177
+ },
178
+
179
+ hasRoles(req: Request, roles: string[]): boolean {
180
+ const userRoles = extractUserRoles(req, config.domain);
181
+ return roles.every((role) => userRoles.includes(role));
182
+ },
183
+
184
+ getAccessToken(req: Request): string | null {
185
+ if (!config.exposeAccessToken) {
186
+ return null;
187
+ }
188
+
189
+ const oidc = (req as any).oidc;
190
+ return oidc?.accessToken?.access_token || null;
191
+ },
192
+
193
+ onUnauthorized(req: Request, res: Response): void {
194
+ // Check if it's an API request
195
+ const isApiRequest =
196
+ req.headers.accept?.includes('application/json') || req.path.startsWith('/api/');
197
+
198
+ if (isApiRequest) {
199
+ res.status(401).json({
200
+ error: 'Unauthorized',
201
+ message: 'Authentication required',
202
+ loginUrl: config.routes?.login || '/login',
203
+ });
204
+ } else {
205
+ // Redirect to login for browser requests
206
+ const loginPath = config.routes?.login || '/login';
207
+ const returnTo = encodeURIComponent(req.originalUrl);
208
+ res.redirect(`${loginPath}?returnTo=${returnTo}`);
209
+ }
210
+ },
211
+ };
212
+
213
+ return adapter;
214
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Basic Auth Adapter
3
+ *
4
+ * Provides HTTP Basic authentication for simple use cases.
5
+ *
6
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
7
+ */
8
+
9
+ import type { Request, Response, RequestHandler } from 'express';
10
+ import type { AuthAdapter, AuthenticatedUser, BasicAdapterConfig } from '../types.js';
11
+
12
+ /**
13
+ * Create a Basic authentication adapter
14
+ */
15
+ export function basicAdapter(config: BasicAdapterConfig): AuthAdapter {
16
+ const expectedAuth = `Basic ${Buffer.from(`${config.username}:${config.password}`).toString('base64')}`;
17
+ const realm = config.realm || 'Protected';
18
+
19
+ // Create a static user for basic auth
20
+ const staticUser: AuthenticatedUser = {
21
+ id: 'basic-auth-user',
22
+ email: `${config.username}@localhost`,
23
+ name: config.username,
24
+ roles: ['admin'], // Basic auth users typically have full access
25
+ };
26
+
27
+ return {
28
+ name: 'basic',
29
+
30
+ initialize(): RequestHandler {
31
+ // Basic auth doesn't need initialization middleware
32
+ // Just return a pass-through middleware
33
+ return (_req, _res, next) => next();
34
+ },
35
+
36
+ isAuthenticated(req: Request): boolean {
37
+ const authHeader = req.headers.authorization;
38
+ return authHeader === expectedAuth;
39
+ },
40
+
41
+ getUser(req: Request): AuthenticatedUser | null {
42
+ if (!this.isAuthenticated(req)) {
43
+ return null;
44
+ }
45
+ return staticUser;
46
+ },
47
+
48
+ hasRoles(_req: Request, roles: string[]): boolean {
49
+ // Basic auth user has 'admin' role
50
+ return roles.every((role) => staticUser.roles?.includes(role));
51
+ },
52
+
53
+ onUnauthorized(_req: Request, res: Response): void {
54
+ res.setHeader('WWW-Authenticate', `Basic realm="${realm}"`);
55
+ res.status(401).json({
56
+ error: 'Unauthorized',
57
+ message: 'Authentication required.',
58
+ });
59
+ },
60
+ };
61
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Auth Adapters Index
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+
7
+ export { auth0Adapter } from './auth0-adapter.js';
8
+ export { basicAdapter } from './basic-adapter.js';
9
+ export { supabaseAdapter } from './supabase-adapter.js';