@qwickapps/server 1.2.0 → 1.3.1
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 +392 -0
- package/dist/core/control-panel.d.ts +7 -2
- package/dist/core/control-panel.d.ts.map +1 -1
- package/dist/core/control-panel.js +120 -54
- package/dist/core/control-panel.js.map +1 -1
- package/dist/core/gateway.d.ts +159 -79
- package/dist/core/gateway.d.ts.map +1 -1
- package/dist/core/gateway.js +679 -319
- package/dist/core/gateway.js.map +1 -1
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/plugin-registry.d.ts +307 -0
- package/dist/core/plugin-registry.d.ts.map +1 -0
- package/dist/core/plugin-registry.js +352 -0
- package/dist/core/plugin-registry.js.map +1 -0
- package/dist/core/types.d.ts +16 -33
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -7
- package/dist/index.js.map +1 -1
- package/dist/plugins/auth/adapters/auth0-adapter.d.ts +14 -0
- package/dist/plugins/auth/adapters/auth0-adapter.d.ts.map +1 -0
- package/dist/plugins/auth/adapters/auth0-adapter.js +179 -0
- package/dist/plugins/auth/adapters/auth0-adapter.js.map +1 -0
- package/dist/plugins/auth/adapters/basic-adapter.d.ts +13 -0
- package/dist/plugins/auth/adapters/basic-adapter.d.ts.map +1 -0
- package/dist/plugins/auth/adapters/basic-adapter.js +51 -0
- package/dist/plugins/auth/adapters/basic-adapter.js.map +1 -0
- package/dist/plugins/auth/adapters/index.d.ts +10 -0
- package/dist/plugins/auth/adapters/index.d.ts.map +1 -0
- package/dist/plugins/auth/adapters/index.js +10 -0
- package/dist/plugins/auth/adapters/index.js.map +1 -0
- package/dist/plugins/auth/adapters/supabase-adapter.d.ts +13 -0
- package/dist/plugins/auth/adapters/supabase-adapter.d.ts.map +1 -0
- package/dist/plugins/auth/adapters/supabase-adapter.js +109 -0
- package/dist/plugins/auth/adapters/supabase-adapter.js.map +1 -0
- package/dist/plugins/auth/adapters/supertokens-adapter.d.ts +18 -0
- package/dist/plugins/auth/adapters/supertokens-adapter.d.ts.map +1 -0
- package/dist/plugins/auth/adapters/supertokens-adapter.js +267 -0
- package/dist/plugins/auth/adapters/supertokens-adapter.js.map +1 -0
- package/dist/plugins/auth/auth-plugin.d.ts +40 -0
- package/dist/plugins/auth/auth-plugin.d.ts.map +1 -0
- package/dist/plugins/auth/auth-plugin.js +255 -0
- package/dist/plugins/auth/auth-plugin.js.map +1 -0
- package/dist/plugins/auth/auth-plugin.test.d.ts +9 -0
- package/dist/plugins/auth/auth-plugin.test.d.ts.map +1 -0
- package/dist/plugins/auth/auth-plugin.test.js +147 -0
- package/dist/plugins/auth/auth-plugin.test.js.map +1 -0
- package/dist/plugins/auth/env-config.d.ts +88 -0
- package/dist/plugins/auth/env-config.d.ts.map +1 -0
- package/dist/plugins/auth/env-config.js +489 -0
- package/dist/plugins/auth/env-config.js.map +1 -0
- package/dist/plugins/auth/index.d.ts +14 -0
- package/dist/plugins/auth/index.d.ts.map +1 -0
- package/dist/plugins/auth/index.js +16 -0
- package/dist/plugins/auth/index.js.map +1 -0
- package/dist/plugins/auth/supertokens-adapter.test.d.ts +10 -0
- package/dist/plugins/auth/supertokens-adapter.test.d.ts.map +1 -0
- package/dist/plugins/auth/supertokens-adapter.test.js +486 -0
- package/dist/plugins/auth/supertokens-adapter.test.js.map +1 -0
- package/dist/plugins/auth/types.d.ts +218 -0
- package/dist/plugins/auth/types.d.ts.map +1 -0
- package/dist/plugins/auth/types.js +14 -0
- package/dist/plugins/auth/types.js.map +1 -0
- package/dist/plugins/bans/bans-plugin.d.ts +59 -0
- package/dist/plugins/bans/bans-plugin.d.ts.map +1 -0
- package/dist/plugins/bans/bans-plugin.js +428 -0
- package/dist/plugins/bans/bans-plugin.js.map +1 -0
- package/dist/plugins/bans/index.d.ts +9 -0
- package/dist/plugins/bans/index.d.ts.map +1 -0
- package/dist/plugins/bans/index.js +10 -0
- package/dist/plugins/bans/index.js.map +1 -0
- package/dist/plugins/bans/stores/index.d.ts +7 -0
- package/dist/plugins/bans/stores/index.d.ts.map +1 -0
- package/dist/plugins/bans/stores/index.js +7 -0
- package/dist/plugins/bans/stores/index.js.map +1 -0
- package/dist/plugins/bans/stores/postgres-store.d.ts +29 -0
- package/dist/plugins/bans/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/bans/stores/postgres-store.js +132 -0
- package/dist/plugins/bans/stores/postgres-store.js.map +1 -0
- package/dist/plugins/bans/types.d.ts +128 -0
- package/dist/plugins/bans/types.d.ts.map +1 -0
- package/dist/plugins/bans/types.js +11 -0
- package/dist/plugins/bans/types.js.map +1 -0
- package/dist/plugins/cache-plugin.d.ts +14 -3
- package/dist/plugins/cache-plugin.d.ts.map +1 -1
- package/dist/plugins/cache-plugin.js +27 -7
- package/dist/plugins/cache-plugin.js.map +1 -1
- package/dist/plugins/cache-plugin.test.js +99 -32
- package/dist/plugins/cache-plugin.test.js.map +1 -1
- package/dist/plugins/config-plugin.d.ts +3 -2
- package/dist/plugins/config-plugin.d.ts.map +1 -1
- package/dist/plugins/config-plugin.js +17 -10
- package/dist/plugins/config-plugin.js.map +1 -1
- package/dist/plugins/diagnostics-plugin.d.ts +2 -2
- package/dist/plugins/diagnostics-plugin.d.ts.map +1 -1
- package/dist/plugins/diagnostics-plugin.js +17 -10
- package/dist/plugins/diagnostics-plugin.js.map +1 -1
- package/dist/plugins/entitlements/entitlements-plugin.d.ts +95 -0
- package/dist/plugins/entitlements/entitlements-plugin.d.ts.map +1 -0
- package/dist/plugins/entitlements/entitlements-plugin.js +707 -0
- package/dist/plugins/entitlements/entitlements-plugin.js.map +1 -0
- package/dist/plugins/entitlements/index.d.ts +12 -0
- package/dist/plugins/entitlements/index.d.ts.map +1 -0
- package/dist/plugins/entitlements/index.js +16 -0
- package/dist/plugins/entitlements/index.js.map +1 -0
- package/dist/plugins/entitlements/sources/index.d.ts +9 -0
- package/dist/plugins/entitlements/sources/index.d.ts.map +1 -0
- package/dist/plugins/entitlements/sources/index.js +9 -0
- package/dist/plugins/entitlements/sources/index.js.map +1 -0
- package/dist/plugins/entitlements/sources/postgres-source.d.ts +29 -0
- package/dist/plugins/entitlements/sources/postgres-source.d.ts.map +1 -0
- package/dist/plugins/entitlements/sources/postgres-source.js +169 -0
- package/dist/plugins/entitlements/sources/postgres-source.js.map +1 -0
- package/dist/plugins/entitlements/types.d.ts +232 -0
- package/dist/plugins/entitlements/types.d.ts.map +1 -0
- package/dist/plugins/entitlements/types.js +11 -0
- package/dist/plugins/entitlements/types.js.map +1 -0
- package/dist/plugins/frontend-app-plugin.d.ts +9 -3
- package/dist/plugins/frontend-app-plugin.d.ts.map +1 -1
- package/dist/plugins/frontend-app-plugin.js +14 -9
- package/dist/plugins/frontend-app-plugin.js.map +1 -1
- package/dist/plugins/health-plugin.d.ts +5 -2
- package/dist/plugins/health-plugin.d.ts.map +1 -1
- package/dist/plugins/health-plugin.js +20 -5
- package/dist/plugins/health-plugin.js.map +1 -1
- package/dist/plugins/index.d.ts +10 -2
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +10 -2
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/logs-plugin.d.ts +3 -2
- package/dist/plugins/logs-plugin.d.ts.map +1 -1
- package/dist/plugins/logs-plugin.js +21 -12
- package/dist/plugins/logs-plugin.js.map +1 -1
- package/dist/plugins/postgres-plugin.d.ts +3 -3
- package/dist/plugins/postgres-plugin.d.ts.map +1 -1
- package/dist/plugins/postgres-plugin.js +9 -7
- package/dist/plugins/postgres-plugin.js.map +1 -1
- package/dist/plugins/postgres-plugin.test.js +50 -29
- package/dist/plugins/postgres-plugin.test.js.map +1 -1
- package/dist/plugins/preferences/__tests__/deep-merge.test.d.ts +7 -0
- package/dist/plugins/preferences/__tests__/deep-merge.test.d.ts.map +1 -0
- package/dist/plugins/preferences/__tests__/deep-merge.test.js +215 -0
- package/dist/plugins/preferences/__tests__/deep-merge.test.js.map +1 -0
- package/dist/plugins/preferences/__tests__/preferences-plugin.test.d.ts +7 -0
- package/dist/plugins/preferences/__tests__/preferences-plugin.test.d.ts.map +1 -0
- package/dist/plugins/preferences/__tests__/preferences-plugin.test.js +265 -0
- package/dist/plugins/preferences/__tests__/preferences-plugin.test.js.map +1 -0
- package/dist/plugins/preferences/index.d.ts +12 -0
- package/dist/plugins/preferences/index.d.ts.map +1 -0
- package/dist/plugins/preferences/index.js +13 -0
- package/dist/plugins/preferences/index.js.map +1 -0
- package/dist/plugins/preferences/preferences-plugin.d.ts +39 -0
- package/dist/plugins/preferences/preferences-plugin.d.ts.map +1 -0
- package/dist/plugins/preferences/preferences-plugin.js +226 -0
- package/dist/plugins/preferences/preferences-plugin.js.map +1 -0
- package/dist/plugins/preferences/stores/index.d.ts +9 -0
- package/dist/plugins/preferences/stores/index.d.ts.map +1 -0
- package/dist/plugins/preferences/stores/index.js +9 -0
- package/dist/plugins/preferences/stores/index.js.map +1 -0
- package/dist/plugins/preferences/stores/postgres-store.d.ts +41 -0
- package/dist/plugins/preferences/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/preferences/stores/postgres-store.js +181 -0
- package/dist/plugins/preferences/stores/postgres-store.js.map +1 -0
- package/dist/plugins/preferences/types.d.ts +91 -0
- package/dist/plugins/preferences/types.d.ts.map +1 -0
- package/dist/plugins/preferences/types.js +10 -0
- package/dist/plugins/preferences/types.js.map +1 -0
- package/dist/plugins/users/__tests__/users-plugin.test.d.ts +9 -0
- package/dist/plugins/users/__tests__/users-plugin.test.d.ts.map +1 -0
- package/dist/plugins/users/__tests__/users-plugin.test.js +546 -0
- package/dist/plugins/users/__tests__/users-plugin.test.js.map +1 -0
- package/dist/plugins/users/index.d.ts +12 -0
- package/dist/plugins/users/index.d.ts.map +1 -0
- package/dist/plugins/users/index.js +13 -0
- package/dist/plugins/users/index.js.map +1 -0
- package/dist/plugins/users/stores/index.d.ts +7 -0
- package/dist/plugins/users/stores/index.d.ts.map +1 -0
- package/dist/plugins/users/stores/index.js +7 -0
- package/dist/plugins/users/stores/index.js.map +1 -0
- package/dist/plugins/users/stores/postgres-store.d.ts +28 -0
- package/dist/plugins/users/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/users/stores/postgres-store.js +157 -0
- package/dist/plugins/users/stores/postgres-store.js.map +1 -0
- package/dist/plugins/users/types.d.ts +225 -0
- package/dist/plugins/users/types.d.ts.map +1 -0
- package/dist/plugins/users/types.js +12 -0
- package/dist/plugins/users/types.js.map +1 -0
- package/dist/plugins/users/users-plugin.d.ts +45 -0
- package/dist/plugins/users/users-plugin.d.ts.map +1 -0
- package/dist/plugins/users/users-plugin.js +359 -0
- package/dist/plugins/users/users-plugin.js.map +1 -0
- package/dist-ui/assets/index-BY8OxNgO.js +465 -0
- package/dist-ui/assets/index-BY8OxNgO.js.map +1 -0
- package/dist-ui/index.html +1 -1
- package/dist-ui-lib/api/controlPanelApi.d.ts +278 -0
- package/dist-ui-lib/components/ControlPanelApp.d.ts +61 -0
- package/dist-ui-lib/components/index.d.ts +18 -0
- package/dist-ui-lib/config/AppConfig.d.ts +7 -0
- package/dist-ui-lib/dashboard/DashboardWidgetRegistry.d.ts +62 -0
- package/dist-ui-lib/dashboard/DashboardWidgetRenderer.d.ts +8 -0
- package/dist-ui-lib/dashboard/PluginWidgetRenderer.d.ts +19 -0
- package/dist-ui-lib/dashboard/WidgetComponentRegistry.d.ts +48 -0
- package/dist-ui-lib/dashboard/builtInWidgets.d.ts +25 -0
- package/dist-ui-lib/dashboard/index.d.ts +13 -0
- package/dist-ui-lib/dashboard/widgets/ServiceHealthWidget.d.ts +12 -0
- package/dist-ui-lib/dashboard/widgets/index.d.ts +6 -0
- package/dist-ui-lib/index.js +5172 -0
- package/dist-ui-lib/index.js.map +1 -0
- package/dist-ui-lib/pages/AuthPage.d.ts +1 -0
- package/dist-ui-lib/pages/ConfigPage.d.ts +1 -0
- package/dist-ui-lib/pages/DashboardPage.d.ts +1 -0
- package/dist-ui-lib/pages/DiagnosticsPage.d.ts +1 -0
- package/dist-ui-lib/pages/EntitlementsPage.d.ts +17 -0
- package/dist-ui-lib/pages/LogsPage.d.ts +1 -0
- package/dist-ui-lib/pages/NotFoundPage.d.ts +1 -0
- package/dist-ui-lib/pages/PluginPage.d.ts +15 -0
- package/dist-ui-lib/pages/PluginsPage.d.ts +1 -0
- package/dist-ui-lib/pages/SystemPage.d.ts +1 -0
- package/dist-ui-lib/pages/UsersPage.d.ts +22 -0
- package/package.json +24 -7
- package/src/core/control-panel.ts +145 -61
- package/src/core/gateway.ts +863 -403
- package/src/core/index.ts +21 -2
- package/src/core/plugin-registry.ts +716 -0
- package/src/core/types.ts +31 -37
- package/src/index.ts +125 -19
- package/src/plugins/auth/adapters/auth0-adapter.ts +214 -0
- package/src/plugins/auth/adapters/basic-adapter.ts +61 -0
- package/src/plugins/auth/adapters/index.ts +10 -0
- package/src/plugins/auth/adapters/supabase-adapter.ts +149 -0
- package/src/plugins/auth/adapters/supertokens-adapter.ts +326 -0
- package/src/plugins/auth/auth-plugin.test.ts +176 -0
- package/src/plugins/auth/auth-plugin.ts +303 -0
- package/src/plugins/auth/env-config.ts +572 -0
- package/src/plugins/auth/index.ts +42 -0
- package/src/plugins/auth/supertokens-adapter.test.ts +621 -0
- package/src/plugins/auth/types.ts +245 -0
- package/src/plugins/bans/bans-plugin.ts +485 -0
- package/src/plugins/bans/index.ts +31 -0
- package/src/plugins/bans/stores/index.ts +7 -0
- package/src/plugins/bans/stores/postgres-store.ts +195 -0
- package/src/plugins/bans/types.ts +141 -0
- package/src/plugins/cache-plugin.test.ts +108 -32
- package/src/plugins/cache-plugin.ts +40 -9
- package/src/plugins/config-plugin.ts +23 -12
- package/src/plugins/diagnostics-plugin.ts +22 -12
- package/src/plugins/entitlements/entitlements-plugin.ts +820 -0
- package/src/plugins/entitlements/index.ts +51 -0
- package/src/plugins/entitlements/sources/index.ts +9 -0
- package/src/plugins/entitlements/sources/postgres-source.ts +253 -0
- package/src/plugins/entitlements/types.ts +256 -0
- package/src/plugins/frontend-app-plugin.ts +24 -12
- package/src/plugins/health-plugin.ts +27 -7
- package/src/plugins/index.ts +132 -4
- package/src/plugins/logs-plugin.ts +28 -14
- package/src/plugins/postgres-plugin.test.ts +52 -29
- package/src/plugins/postgres-plugin.ts +11 -9
- package/src/plugins/preferences/__tests__/deep-merge.test.ts +242 -0
- package/src/plugins/preferences/__tests__/preferences-plugin.test.ts +350 -0
- package/src/plugins/preferences/index.ts +30 -0
- package/src/plugins/preferences/preferences-plugin.ts +270 -0
- package/src/plugins/preferences/stores/index.ts +9 -0
- package/src/plugins/preferences/stores/postgres-store.ts +252 -0
- package/src/plugins/preferences/types.ts +100 -0
- package/src/plugins/users/__tests__/users-plugin.test.ts +690 -0
- package/src/plugins/users/index.ts +38 -0
- package/src/plugins/users/stores/index.ts +7 -0
- package/src/plugins/users/stores/postgres-store.ts +225 -0
- package/src/plugins/users/types.ts +247 -0
- package/src/plugins/users/users-plugin.ts +418 -0
- package/ui/src/App.tsx +188 -31
- package/ui/src/api/controlPanelApi.ts +453 -1
- package/ui/src/components/ControlPanelApp.tsx +212 -0
- package/ui/src/components/index.ts +62 -0
- package/ui/src/dashboard/DashboardWidgetRegistry.tsx +129 -0
- package/ui/src/dashboard/DashboardWidgetRenderer.tsx +34 -0
- package/ui/src/dashboard/PluginWidgetRenderer.tsx +118 -0
- package/ui/src/dashboard/WidgetComponentRegistry.tsx +120 -0
- package/ui/src/dashboard/builtInWidgets.tsx +35 -0
- package/ui/src/dashboard/index.ts +35 -0
- package/ui/src/dashboard/widgets/ServiceHealthWidget.tsx +140 -0
- package/ui/src/dashboard/widgets/index.ts +7 -0
- package/ui/src/pages/AuthPage.tsx +259 -0
- package/ui/src/pages/DashboardPage.tsx +28 -149
- package/ui/src/pages/EntitlementsPage.tsx +557 -0
- package/ui/src/pages/LogsPage.tsx +174 -8
- package/ui/src/pages/PluginPage.tsx +148 -0
- package/ui/src/pages/PluginsPage.tsx +394 -0
- package/ui/src/pages/SystemPage.tsx +445 -0
- package/ui/src/pages/UsersPage.tsx +837 -0
- package/ui/tsconfig.lib.json +11 -0
- package/ui/vite.lib.config.ts +56 -0
- package/dist-ui/assets/index-CW1BviRn.js +0 -465
- package/dist-ui/assets/index-CW1BviRn.js.map +0 -1
- package/ui/src/pages/HealthPage.tsx +0 -204
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Plugin
|
|
3
|
+
*
|
|
4
|
+
* Pluggable authentication plugin for @qwickapps/server.
|
|
5
|
+
* Supports multiple adapters (Auth0, Supabase, Basic) with fallback chain.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Request, Response, NextFunction, RequestHandler } from 'express';
|
|
11
|
+
import type { Plugin, PluginConfig, PluginRegistry } from '../../core/plugin-registry.js';
|
|
12
|
+
import type {
|
|
13
|
+
AuthPluginConfig,
|
|
14
|
+
AuthAdapter,
|
|
15
|
+
AuthenticatedUser,
|
|
16
|
+
AuthenticatedRequest,
|
|
17
|
+
} from './types.js';
|
|
18
|
+
|
|
19
|
+
// Store the plugin instance for helper access
|
|
20
|
+
let currentAdapter: AuthAdapter | null = null;
|
|
21
|
+
let fallbackAdapters: AuthAdapter[] = [];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create the Auth plugin
|
|
25
|
+
*/
|
|
26
|
+
export function createAuthPlugin(config: AuthPluginConfig): Plugin {
|
|
27
|
+
const excludePaths = config.excludePaths || [];
|
|
28
|
+
const authRequired = config.authRequired !== false;
|
|
29
|
+
const debug = config.debug || false;
|
|
30
|
+
|
|
31
|
+
function log(message: string, data?: Record<string, unknown>) {
|
|
32
|
+
if (debug) {
|
|
33
|
+
console.log(`[AuthPlugin] ${message}`, data || '');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
id: 'auth',
|
|
39
|
+
name: 'Auth Plugin',
|
|
40
|
+
version: '1.0.0',
|
|
41
|
+
|
|
42
|
+
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
43
|
+
const app = registry.getApp();
|
|
44
|
+
|
|
45
|
+
// Store adapters for helper access
|
|
46
|
+
currentAdapter = config.adapter;
|
|
47
|
+
fallbackAdapters = config.fallback || [];
|
|
48
|
+
|
|
49
|
+
log('Initializing auth plugin', {
|
|
50
|
+
adapter: config.adapter.name,
|
|
51
|
+
fallback: fallbackAdapters.map((a) => a.name),
|
|
52
|
+
excludePaths,
|
|
53
|
+
authRequired,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Initialize the primary adapter
|
|
57
|
+
const primaryMiddleware = config.adapter.initialize();
|
|
58
|
+
if (Array.isArray(primaryMiddleware)) {
|
|
59
|
+
primaryMiddleware.forEach((mw) => app.use(mw));
|
|
60
|
+
} else {
|
|
61
|
+
app.use(primaryMiddleware);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Initialize fallback adapters
|
|
65
|
+
for (const fallback of fallbackAdapters) {
|
|
66
|
+
const fallbackMiddleware = fallback.initialize();
|
|
67
|
+
if (Array.isArray(fallbackMiddleware)) {
|
|
68
|
+
fallbackMiddleware.forEach((mw) => app.use(mw));
|
|
69
|
+
} else {
|
|
70
|
+
app.use(fallbackMiddleware);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Add the auth checking middleware
|
|
75
|
+
app.use(createAuthMiddleware());
|
|
76
|
+
|
|
77
|
+
// Register auth status route
|
|
78
|
+
registry.addRoute({
|
|
79
|
+
method: 'get',
|
|
80
|
+
path: '/api/auth/status',
|
|
81
|
+
handler: (_req: Request, res: Response) => {
|
|
82
|
+
const authReq = _req as AuthenticatedRequest;
|
|
83
|
+
res.json({
|
|
84
|
+
authenticated: authReq.auth?.isAuthenticated || false,
|
|
85
|
+
user: authReq.auth?.user
|
|
86
|
+
? {
|
|
87
|
+
id: authReq.auth.user.id,
|
|
88
|
+
email: authReq.auth.user.email,
|
|
89
|
+
name: authReq.auth.user.name,
|
|
90
|
+
picture: authReq.auth.user.picture,
|
|
91
|
+
roles: authReq.auth.user.roles,
|
|
92
|
+
}
|
|
93
|
+
: null,
|
|
94
|
+
adapter: authReq.auth?.adapter,
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
pluginId: 'auth',
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
log('Auth plugin initialized');
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
async onStop(): Promise<void> {
|
|
104
|
+
log('Shutting down auth plugin');
|
|
105
|
+
|
|
106
|
+
// Cleanup adapters
|
|
107
|
+
if (currentAdapter?.shutdown) {
|
|
108
|
+
await currentAdapter.shutdown();
|
|
109
|
+
}
|
|
110
|
+
for (const fallback of fallbackAdapters) {
|
|
111
|
+
if (fallback.shutdown) {
|
|
112
|
+
await fallback.shutdown();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
currentAdapter = null;
|
|
117
|
+
fallbackAdapters = [];
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Create the auth checking middleware
|
|
123
|
+
*/
|
|
124
|
+
function createAuthMiddleware(): RequestHandler {
|
|
125
|
+
return async (req: Request, res: Response, next: NextFunction) => {
|
|
126
|
+
const authReq = req as AuthenticatedRequest;
|
|
127
|
+
|
|
128
|
+
// Initialize auth object
|
|
129
|
+
authReq.auth = {
|
|
130
|
+
isAuthenticated: false,
|
|
131
|
+
user: null,
|
|
132
|
+
adapter: 'none',
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Check if path is excluded
|
|
136
|
+
const isExcluded = excludePaths.some((path) => {
|
|
137
|
+
if (path.endsWith('*')) {
|
|
138
|
+
return req.path.startsWith(path.slice(0, -1));
|
|
139
|
+
}
|
|
140
|
+
return req.path === path || req.path.startsWith(path + '/');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
if (isExcluded) {
|
|
144
|
+
log('Path excluded from auth', { path: req.path });
|
|
145
|
+
return next();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Try primary adapter
|
|
149
|
+
let authenticated = false;
|
|
150
|
+
let user: AuthenticatedUser | null = null;
|
|
151
|
+
let activeAdapter = config.adapter;
|
|
152
|
+
|
|
153
|
+
if (config.adapter.isAuthenticated(req)) {
|
|
154
|
+
user = await Promise.resolve(config.adapter.getUser(req));
|
|
155
|
+
if (user) {
|
|
156
|
+
authenticated = true;
|
|
157
|
+
log('Authenticated via primary adapter', { adapter: config.adapter.name });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Try fallback adapters if primary didn't authenticate
|
|
162
|
+
if (!authenticated && fallbackAdapters.length > 0) {
|
|
163
|
+
for (const fallback of fallbackAdapters) {
|
|
164
|
+
if (fallback.isAuthenticated(req)) {
|
|
165
|
+
user = await Promise.resolve(fallback.getUser(req));
|
|
166
|
+
if (user) {
|
|
167
|
+
authenticated = true;
|
|
168
|
+
activeAdapter = fallback;
|
|
169
|
+
log('Authenticated via fallback adapter', { adapter: fallback.name });
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Set auth info on request
|
|
177
|
+
authReq.auth = {
|
|
178
|
+
isAuthenticated: authenticated,
|
|
179
|
+
user,
|
|
180
|
+
adapter: activeAdapter.name,
|
|
181
|
+
accessToken: activeAdapter.getAccessToken?.(req) || undefined,
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Check if auth is required but user is not authenticated
|
|
185
|
+
if (authRequired && !authenticated) {
|
|
186
|
+
log('Auth required but not authenticated', { path: req.path });
|
|
187
|
+
|
|
188
|
+
// Use custom handler if provided
|
|
189
|
+
if (config.onUnauthorized) {
|
|
190
|
+
return config.onUnauthorized(req, res);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Use adapter's unauthorized handler
|
|
194
|
+
if (activeAdapter.onUnauthorized) {
|
|
195
|
+
return activeAdapter.onUnauthorized(req, res);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Default unauthorized response
|
|
199
|
+
return res.status(401).json({
|
|
200
|
+
error: 'Unauthorized',
|
|
201
|
+
message: 'Authentication required',
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
next();
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Check if the current request is authenticated
|
|
212
|
+
*/
|
|
213
|
+
export function isAuthenticated(req: Request): boolean {
|
|
214
|
+
const authReq = req as AuthenticatedRequest;
|
|
215
|
+
return authReq.auth?.isAuthenticated || false;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Get the authenticated user from the request
|
|
220
|
+
*/
|
|
221
|
+
export function getAuthenticatedUser(req: Request): AuthenticatedUser | null {
|
|
222
|
+
const authReq = req as AuthenticatedRequest;
|
|
223
|
+
return authReq.auth?.user || null;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Get the access token from the request
|
|
228
|
+
*/
|
|
229
|
+
export function getAccessToken(req: Request): string | null {
|
|
230
|
+
const authReq = req as AuthenticatedRequest;
|
|
231
|
+
return authReq.auth?.accessToken || null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Middleware to require authentication
|
|
236
|
+
*/
|
|
237
|
+
export function requireAuth(): RequestHandler {
|
|
238
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
239
|
+
if (!isAuthenticated(req)) {
|
|
240
|
+
return res.status(401).json({
|
|
241
|
+
error: 'Unauthorized',
|
|
242
|
+
message: 'Authentication required',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
next();
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Middleware to require specific roles
|
|
251
|
+
*/
|
|
252
|
+
export function requireRoles(...roles: string[]): RequestHandler {
|
|
253
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
254
|
+
const user = getAuthenticatedUser(req);
|
|
255
|
+
|
|
256
|
+
if (!user) {
|
|
257
|
+
return res.status(401).json({
|
|
258
|
+
error: 'Unauthorized',
|
|
259
|
+
message: 'Authentication required',
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const userRoles = user.roles || [];
|
|
264
|
+
const hasAllRoles = roles.every((role) => userRoles.includes(role));
|
|
265
|
+
|
|
266
|
+
if (!hasAllRoles) {
|
|
267
|
+
return res.status(403).json({
|
|
268
|
+
error: 'Forbidden',
|
|
269
|
+
message: `Required roles: ${roles.join(', ')}`,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
next();
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Middleware to require any of the specified roles
|
|
279
|
+
*/
|
|
280
|
+
export function requireAnyRole(...roles: string[]): RequestHandler {
|
|
281
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
282
|
+
const user = getAuthenticatedUser(req);
|
|
283
|
+
|
|
284
|
+
if (!user) {
|
|
285
|
+
return res.status(401).json({
|
|
286
|
+
error: 'Unauthorized',
|
|
287
|
+
message: 'Authentication required',
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const userRoles = user.roles || [];
|
|
292
|
+
const hasAnyRole = roles.some((role) => userRoles.includes(role));
|
|
293
|
+
|
|
294
|
+
if (!hasAnyRole) {
|
|
295
|
+
return res.status(403).json({
|
|
296
|
+
error: 'Forbidden',
|
|
297
|
+
message: `Required one of roles: ${roles.join(', ')}`,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
next();
|
|
302
|
+
};
|
|
303
|
+
}
|