@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.
- package/README.md +238 -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 +92 -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 +271 -0
- package/dist/core/plugin-registry.d.ts.map +1 -0
- package/dist/core/plugin-registry.js +326 -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 +9 -0
- package/dist/plugins/auth/adapters/index.d.ts.map +1 -0
- package/dist/plugins/auth/adapters/index.js +9 -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/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/index.d.ts +12 -0
- package/dist/plugins/auth/index.d.ts.map +1 -0
- package/dist/plugins/auth/index.js +13 -0
- package/dist/plugins/auth/index.js.map +1 -0
- package/dist/plugins/auth/types.d.ts +148 -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 +96 -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 +8 -2
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +8 -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 +47 -29
- package/dist/plugins/postgres-plugin.test.js.map +1 -1
- 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 +189 -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 +39 -0
- package/dist/plugins/users/users-plugin.d.ts.map +1 -0
- package/dist/plugins/users/users-plugin.js +242 -0
- package/dist/plugins/users/users-plugin.js.map +1 -0
- package/dist-ui/assets/index-Bsp2ntcw.js +465 -0
- package/dist-ui/assets/index-Bsp2ntcw.js.map +1 -0
- package/dist-ui/index.html +1 -1
- package/dist-ui-lib/api/controlPanelApi.d.ts +232 -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 +44 -0
- package/dist-ui-lib/dashboard/builtInWidgets.d.ts +19 -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 +6441 -0
- package/dist-ui-lib/index.js.map +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/SystemPage.d.ts +1 -0
- package/dist-ui-lib/pages/UsersPage.d.ts +22 -0
- package/package.json +18 -6
- package/src/core/control-panel.ts +114 -61
- package/src/core/gateway.ts +863 -403
- package/src/core/index.ts +21 -2
- package/src/core/plugin-registry.ts +653 -0
- package/src/core/types.ts +31 -37
- package/src/index.ts +118 -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 +9 -0
- package/src/plugins/auth/adapters/supabase-adapter.ts +141 -0
- package/src/plugins/auth/auth-plugin.test.ts +176 -0
- package/src/plugins/auth/auth-plugin.ts +303 -0
- package/src/plugins/auth/index.ts +33 -0
- package/src/plugins/auth/types.ts +165 -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 +105 -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 +106 -4
- package/src/plugins/logs-plugin.ts +28 -14
- package/src/plugins/postgres-plugin.test.ts +49 -29
- package/src/plugins/postgres-plugin.ts +11 -9
- package/src/plugins/users/index.ts +35 -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 +209 -0
- package/src/plugins/users/users-plugin.ts +281 -0
- package/ui/src/App.tsx +185 -31
- package/ui/src/api/controlPanelApi.ts +354 -1
- package/ui/src/components/ControlPanelApp.tsx +209 -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 +115 -0
- package/ui/src/dashboard/WidgetComponentRegistry.tsx +116 -0
- package/ui/src/dashboard/builtInWidgets.tsx +29 -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/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/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 +51 -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,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostgreSQL Ban Store
|
|
3
|
+
*
|
|
4
|
+
* Ban storage implementation using PostgreSQL.
|
|
5
|
+
* Requires the 'pg' package and the Users plugin to be installed.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Create a PostgreSQL ban store
|
|
11
|
+
*
|
|
12
|
+
* @param config Configuration including a pg Pool instance or a function that returns one
|
|
13
|
+
* @returns BanStore implementation
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { Pool } from 'pg';
|
|
18
|
+
* import { postgresBanStore } from '@qwickapps/server';
|
|
19
|
+
*
|
|
20
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
21
|
+
* const store = postgresBanStore({ pool });
|
|
22
|
+
*
|
|
23
|
+
* // Or with lazy initialization:
|
|
24
|
+
* const store = postgresBanStore({ pool: () => getPostgres().getPool() });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function postgresBanStore(config) {
|
|
28
|
+
const { pool: poolOrFn, tableName = 'user_bans', schema = 'public', autoCreateTables = true, } = config;
|
|
29
|
+
// Helper to get pool (supports lazy initialization via function)
|
|
30
|
+
const getPool = () => {
|
|
31
|
+
const pool = typeof poolOrFn === 'function' ? poolOrFn() : poolOrFn;
|
|
32
|
+
return pool;
|
|
33
|
+
};
|
|
34
|
+
const tableFullName = `"${schema}"."${tableName}"`;
|
|
35
|
+
return {
|
|
36
|
+
name: 'postgres',
|
|
37
|
+
async initialize() {
|
|
38
|
+
if (!autoCreateTables)
|
|
39
|
+
return;
|
|
40
|
+
// Create bans table
|
|
41
|
+
// Note: This does NOT have a foreign key to users table
|
|
42
|
+
// The relationship is enforced at the application level via Users Plugin
|
|
43
|
+
await getPool().query(`
|
|
44
|
+
CREATE TABLE IF NOT EXISTS ${tableFullName} (
|
|
45
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
46
|
+
user_id UUID NOT NULL,
|
|
47
|
+
reason TEXT NOT NULL,
|
|
48
|
+
banned_by VARCHAR(255) NOT NULL,
|
|
49
|
+
banned_at TIMESTAMPTZ DEFAULT NOW(),
|
|
50
|
+
expires_at TIMESTAMPTZ,
|
|
51
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
52
|
+
removed_at TIMESTAMPTZ,
|
|
53
|
+
removed_by VARCHAR(255),
|
|
54
|
+
metadata JSONB DEFAULT '{}'
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_${tableName}_user_id ON ${tableFullName}(user_id);
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_${tableName}_is_active ON ${tableFullName}(is_active);
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_${tableName}_expires_at ON ${tableFullName}(expires_at) WHERE expires_at IS NOT NULL;
|
|
60
|
+
`);
|
|
61
|
+
},
|
|
62
|
+
async isBanned(userId) {
|
|
63
|
+
const ban = await this.getActiveBan(userId);
|
|
64
|
+
return ban !== null;
|
|
65
|
+
},
|
|
66
|
+
async getActiveBan(userId) {
|
|
67
|
+
const result = await getPool().query(`SELECT * FROM ${tableFullName}
|
|
68
|
+
WHERE user_id = $1 AND is_active = TRUE
|
|
69
|
+
AND (expires_at IS NULL OR expires_at > NOW())`, [userId]);
|
|
70
|
+
return result.rows[0] || null;
|
|
71
|
+
},
|
|
72
|
+
async createBan(input) {
|
|
73
|
+
const expiresAt = input.duration
|
|
74
|
+
? new Date(Date.now() + input.duration * 1000)
|
|
75
|
+
: null;
|
|
76
|
+
// Deactivate any existing active bans for this user
|
|
77
|
+
await getPool().query(`UPDATE ${tableFullName}
|
|
78
|
+
SET is_active = FALSE, removed_at = NOW(), removed_by = $2
|
|
79
|
+
WHERE user_id = $1 AND is_active = TRUE`, [input.user_id, input.banned_by]);
|
|
80
|
+
// Create new ban
|
|
81
|
+
const result = await getPool().query(`INSERT INTO ${tableFullName} (user_id, reason, banned_by, expires_at, metadata)
|
|
82
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
83
|
+
RETURNING *`, [
|
|
84
|
+
input.user_id,
|
|
85
|
+
input.reason,
|
|
86
|
+
input.banned_by,
|
|
87
|
+
expiresAt,
|
|
88
|
+
JSON.stringify(input.metadata || {}),
|
|
89
|
+
]);
|
|
90
|
+
return result.rows[0];
|
|
91
|
+
},
|
|
92
|
+
async removeBan(input) {
|
|
93
|
+
const result = await getPool().query(`UPDATE ${tableFullName}
|
|
94
|
+
SET is_active = FALSE, removed_at = NOW(), removed_by = $2
|
|
95
|
+
WHERE user_id = $1 AND is_active = TRUE
|
|
96
|
+
RETURNING *`, [input.user_id, input.removed_by]);
|
|
97
|
+
return (result.rowCount ?? 0) > 0;
|
|
98
|
+
},
|
|
99
|
+
async listBans(userId) {
|
|
100
|
+
const result = await getPool().query(`SELECT * FROM ${tableFullName}
|
|
101
|
+
WHERE user_id = $1
|
|
102
|
+
ORDER BY banned_at DESC`, [userId]);
|
|
103
|
+
return result.rows;
|
|
104
|
+
},
|
|
105
|
+
async listActiveBans(options = {}) {
|
|
106
|
+
const { limit = 50, offset = 0 } = options;
|
|
107
|
+
// Get total count
|
|
108
|
+
const countResult = await getPool().query(`SELECT COUNT(*) FROM ${tableFullName}
|
|
109
|
+
WHERE is_active = TRUE AND (expires_at IS NULL OR expires_at > NOW())`);
|
|
110
|
+
const total = parseInt(countResult.rows[0].count, 10);
|
|
111
|
+
// Get bans
|
|
112
|
+
const result = await getPool().query(`SELECT * FROM ${tableFullName}
|
|
113
|
+
WHERE is_active = TRUE AND (expires_at IS NULL OR expires_at > NOW())
|
|
114
|
+
ORDER BY banned_at DESC
|
|
115
|
+
LIMIT $1 OFFSET $2`, [limit, offset]);
|
|
116
|
+
return {
|
|
117
|
+
bans: result.rows,
|
|
118
|
+
total,
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
async cleanupExpiredBans() {
|
|
122
|
+
const result = await getPool().query(`UPDATE ${tableFullName}
|
|
123
|
+
SET is_active = FALSE
|
|
124
|
+
WHERE is_active = TRUE AND expires_at IS NOT NULL AND expires_at <= NOW()`);
|
|
125
|
+
return result.rowCount ?? 0;
|
|
126
|
+
},
|
|
127
|
+
async shutdown() {
|
|
128
|
+
// Pool is managed externally, nothing to do here
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=postgres-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-store.js","sourceRoot":"","sources":["../../../../src/plugins/bans/stores/postgres-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bans Plugin Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for ban management.
|
|
5
|
+
* Bans are always on USER entities (by user_id), not emails.
|
|
6
|
+
* Email is just an identifier to resolve to a user.
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
9
|
+
*/
|
|
10
|
+
import type { User } from '../users/types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Ban record
|
|
13
|
+
*/
|
|
14
|
+
export interface Ban {
|
|
15
|
+
/** Primary key - UUID */
|
|
16
|
+
id: string;
|
|
17
|
+
/** User ID being banned */
|
|
18
|
+
user_id: string;
|
|
19
|
+
/** Reason for the ban */
|
|
20
|
+
reason: string;
|
|
21
|
+
/** Who created the ban (user ID or system) */
|
|
22
|
+
banned_by: string;
|
|
23
|
+
/** When the ban was created */
|
|
24
|
+
banned_at: Date;
|
|
25
|
+
/** When the ban expires (null = permanent) */
|
|
26
|
+
expires_at?: Date;
|
|
27
|
+
/** Whether the ban is currently active */
|
|
28
|
+
is_active: boolean;
|
|
29
|
+
/** When the ban was removed */
|
|
30
|
+
removed_at?: Date;
|
|
31
|
+
/** Who removed the ban */
|
|
32
|
+
removed_by?: string;
|
|
33
|
+
/** Additional metadata */
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Ban creation payload
|
|
38
|
+
*/
|
|
39
|
+
export interface CreateBanInput {
|
|
40
|
+
user_id: string;
|
|
41
|
+
reason: string;
|
|
42
|
+
banned_by: string;
|
|
43
|
+
/** Duration in seconds (null = permanent) */
|
|
44
|
+
duration?: number;
|
|
45
|
+
metadata?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Ban removal payload
|
|
49
|
+
*/
|
|
50
|
+
export interface RemoveBanInput {
|
|
51
|
+
user_id: string;
|
|
52
|
+
removed_by: string;
|
|
53
|
+
note?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Ban store interface - storage backend for bans
|
|
57
|
+
*/
|
|
58
|
+
export interface BanStore {
|
|
59
|
+
/** Store name (e.g., 'postgres', 'memory') */
|
|
60
|
+
name: string;
|
|
61
|
+
/** Initialize the store (create tables, etc.) */
|
|
62
|
+
initialize(): Promise<void>;
|
|
63
|
+
/** Check if user is banned */
|
|
64
|
+
isBanned(userId: string): Promise<boolean>;
|
|
65
|
+
/** Get active ban for user */
|
|
66
|
+
getActiveBan(userId: string): Promise<Ban | null>;
|
|
67
|
+
/** Create a ban */
|
|
68
|
+
createBan(input: CreateBanInput): Promise<Ban>;
|
|
69
|
+
/** Remove a ban */
|
|
70
|
+
removeBan(input: RemoveBanInput): Promise<boolean>;
|
|
71
|
+
/** List bans for a user (including history) */
|
|
72
|
+
listBans(userId: string): Promise<Ban[]>;
|
|
73
|
+
/** List all active bans */
|
|
74
|
+
listActiveBans(options?: {
|
|
75
|
+
limit?: number;
|
|
76
|
+
offset?: number;
|
|
77
|
+
}): Promise<{
|
|
78
|
+
bans: Ban[];
|
|
79
|
+
total: number;
|
|
80
|
+
}>;
|
|
81
|
+
/** Cleanup expired bans */
|
|
82
|
+
cleanupExpiredBans(): Promise<number>;
|
|
83
|
+
/** Shutdown the store */
|
|
84
|
+
shutdown(): Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Ban callbacks
|
|
88
|
+
*/
|
|
89
|
+
export interface BanCallbacks {
|
|
90
|
+
/** Called when a user is banned */
|
|
91
|
+
onBan?: (user: User, ban: Ban) => Promise<void>;
|
|
92
|
+
/** Called when a ban is removed */
|
|
93
|
+
onUnban?: (user: User) => Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Bans plugin configuration
|
|
97
|
+
*/
|
|
98
|
+
export interface BansPluginConfig {
|
|
99
|
+
/** Ban storage backend */
|
|
100
|
+
store: BanStore;
|
|
101
|
+
/** Support temporary bans (with expiration) */
|
|
102
|
+
supportTemporary?: boolean;
|
|
103
|
+
/** Callbacks */
|
|
104
|
+
callbacks?: BanCallbacks;
|
|
105
|
+
/** API configuration */
|
|
106
|
+
api?: {
|
|
107
|
+
/** API route prefix (default: '/api/bans') */
|
|
108
|
+
prefix?: string;
|
|
109
|
+
/** Enable API endpoints */
|
|
110
|
+
enabled?: boolean;
|
|
111
|
+
};
|
|
112
|
+
/** Enable debug logging */
|
|
113
|
+
debug?: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* PostgreSQL ban store configuration
|
|
117
|
+
*/
|
|
118
|
+
export interface PostgresBanStoreConfig {
|
|
119
|
+
/** PostgreSQL pool instance or a function that returns one (for lazy initialization) */
|
|
120
|
+
pool: unknown | (() => unknown);
|
|
121
|
+
/** Bans table name (default: 'user_bans') */
|
|
122
|
+
tableName?: string;
|
|
123
|
+
/** Schema name (default: 'public') */
|
|
124
|
+
schema?: string;
|
|
125
|
+
/** Auto-create tables on init (default: true) */
|
|
126
|
+
autoCreateTables?: boolean;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/bans/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bans Plugin Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for ban management.
|
|
5
|
+
* Bans are always on USER entities (by user_id), not emails.
|
|
6
|
+
* Email is just an identifier to resolve to a user.
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/plugins/bans/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
*
|
|
48
48
|
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
49
49
|
*/
|
|
50
|
-
import type {
|
|
50
|
+
import type { Plugin } from '../core/plugin-registry.js';
|
|
51
51
|
type Redis = import('ioredis').default;
|
|
52
52
|
/**
|
|
53
53
|
* Configuration for the cache plugin
|
|
@@ -152,8 +152,19 @@ export interface CacheInstance {
|
|
|
152
152
|
* Get all keys matching a pattern
|
|
153
153
|
* @param pattern - Pattern to match (prefix is applied automatically)
|
|
154
154
|
* @returns Array of matching keys (without prefix)
|
|
155
|
+
* @deprecated Use scanKeys() for production - keys() blocks Redis on large datasets
|
|
155
156
|
*/
|
|
156
157
|
keys(pattern: string): Promise<string[]>;
|
|
158
|
+
/**
|
|
159
|
+
* Scan keys matching a pattern using cursor-based iteration (non-blocking)
|
|
160
|
+
* @param pattern - Pattern to match (prefix is applied automatically)
|
|
161
|
+
* @param options - Optional scan configuration
|
|
162
|
+
* @param options.count - Hint for how many keys to return per iteration (default: 100)
|
|
163
|
+
* @returns Array of matching keys (without prefix)
|
|
164
|
+
*/
|
|
165
|
+
scanKeys(pattern: string, options?: {
|
|
166
|
+
count?: number;
|
|
167
|
+
}): Promise<string[]>;
|
|
157
168
|
/**
|
|
158
169
|
* Flush all keys with the configured prefix
|
|
159
170
|
* @returns Number of keys deleted
|
|
@@ -202,7 +213,7 @@ export declare function hasCache(name?: string): boolean;
|
|
|
202
213
|
*
|
|
203
214
|
* @param config - Cache configuration
|
|
204
215
|
* @param instanceName - Name for this cache instance (default: 'default')
|
|
205
|
-
* @returns A
|
|
216
|
+
* @returns A plugin
|
|
206
217
|
*
|
|
207
218
|
* @example
|
|
208
219
|
* ```typescript
|
|
@@ -214,6 +225,6 @@ export declare function hasCache(name?: string): boolean;
|
|
|
214
225
|
* });
|
|
215
226
|
* ```
|
|
216
227
|
*/
|
|
217
|
-
export declare function createCachePlugin(config: CachePluginConfig, instanceName?: string):
|
|
228
|
+
export declare function createCachePlugin(config: CachePluginConfig, instanceName?: string): Plugin;
|
|
218
229
|
export {};
|
|
219
230
|
//# sourceMappingURL=cache-plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/cache-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"cache-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/cache-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,7 +83,7 @@ export function hasCache(name = 'default') {
|
|
|
83
83
|
*
|
|
84
84
|
* @param config - Cache configuration
|
|
85
85
|
* @param instanceName - Name for this cache instance (default: 'default')
|
|
86
|
-
* @returns A
|
|
86
|
+
* @returns A plugin
|
|
87
87
|
*
|
|
88
88
|
* @example
|
|
89
89
|
* ```typescript
|
|
@@ -99,6 +99,7 @@ export function createCachePlugin(config, instanceName = 'default') {
|
|
|
99
99
|
let client = null;
|
|
100
100
|
const prefix = config.keyPrefix ?? '';
|
|
101
101
|
const defaultTtl = config.defaultTtl ?? 3600;
|
|
102
|
+
const pluginId = `cache:${instanceName}`;
|
|
102
103
|
const prefixKey = (key) => `${prefix}${key}`;
|
|
103
104
|
const unprefixKey = (key) => prefix && key.startsWith(prefix) ? key.slice(prefix.length) : key;
|
|
104
105
|
const createInstance = async () => {
|
|
@@ -210,6 +211,24 @@ export function createCachePlugin(config, instanceName = 'default') {
|
|
|
210
211
|
const keys = await client.keys(prefixKey(pattern));
|
|
211
212
|
return keys.map(unprefixKey);
|
|
212
213
|
},
|
|
214
|
+
async scanKeys(pattern, options) {
|
|
215
|
+
if (!client)
|
|
216
|
+
throw new Error('Cache client not initialized');
|
|
217
|
+
const results = [];
|
|
218
|
+
const stream = client.scanStream({
|
|
219
|
+
match: prefixKey(pattern),
|
|
220
|
+
count: options?.count ?? 100,
|
|
221
|
+
});
|
|
222
|
+
return new Promise((resolve, reject) => {
|
|
223
|
+
stream.on('data', (keys) => {
|
|
224
|
+
for (const key of keys) {
|
|
225
|
+
results.push(unprefixKey(key));
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
stream.on('end', () => resolve(results));
|
|
229
|
+
stream.on('error', (err) => reject(err));
|
|
230
|
+
});
|
|
231
|
+
},
|
|
213
232
|
async flush() {
|
|
214
233
|
if (!client)
|
|
215
234
|
throw new Error('Cache client not initialized');
|
|
@@ -262,10 +281,11 @@ export function createCachePlugin(config, instanceName = 'default') {
|
|
|
262
281
|
return instance;
|
|
263
282
|
};
|
|
264
283
|
return {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
284
|
+
id: pluginId,
|
|
285
|
+
name: `Redis Cache (${instanceName})`,
|
|
286
|
+
version: '1.0.0',
|
|
287
|
+
async onStart(_pluginConfig, registry) {
|
|
288
|
+
const logger = registry.getLogger(pluginId);
|
|
269
289
|
// Create and register the instance
|
|
270
290
|
const instance = await createInstance();
|
|
271
291
|
instances.set(instanceName, instance);
|
|
@@ -281,7 +301,7 @@ export function createCachePlugin(config, instanceName = 'default') {
|
|
|
281
301
|
}
|
|
282
302
|
// Register health check if enabled
|
|
283
303
|
if (config.healthCheck !== false) {
|
|
284
|
-
registerHealthCheck({
|
|
304
|
+
registry.registerHealthCheck({
|
|
285
305
|
name: config.healthCheckName ?? 'redis',
|
|
286
306
|
type: 'custom',
|
|
287
307
|
interval: config.healthCheckInterval ?? 30000,
|
|
@@ -314,7 +334,7 @@ export function createCachePlugin(config, instanceName = 'default') {
|
|
|
314
334
|
});
|
|
315
335
|
}
|
|
316
336
|
},
|
|
317
|
-
async
|
|
337
|
+
async onStop() {
|
|
318
338
|
const instance = instances.get(instanceName);
|
|
319
339
|
if (instance) {
|
|
320
340
|
await instance.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-plugin.js","sourceRoot":"","sources":["../../src/plugins/cache-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;
|
|
1
|
+
{"version":3,"file":"cache-plugin.js","sourceRoot":"","sources":["../../src/plugins/cache-plugin.ts"],"names":[],"mappings":"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"}
|