better-auth-studio 1.0.26-beta.7 → 1.0.26
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 +2 -2
- package/dist/auth-adapter.d.ts +1 -1
- package/dist/auth-adapter.d.ts.map +1 -1
- package/dist/auth-adapter.js +70 -107
- package/dist/auth-adapter.js.map +1 -1
- package/dist/cli.js +26 -52
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -8
- package/dist/config.js.map +1 -1
- package/dist/data.d.ts +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +21 -40
- package/dist/data.js.map +1 -1
- package/dist/geo-service.d.ts.map +1 -1
- package/dist/geo-service.js +10 -15
- package/dist/geo-service.js.map +1 -1
- package/dist/get-tsconfig-info.d.ts.map +1 -1
- package/dist/get-tsconfig-info.js +3 -4
- package/dist/get-tsconfig-info.js.map +1 -1
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +380 -232
- package/dist/routes.js.map +1 -1
- package/dist/studio.d.ts.map +1 -1
- package/dist/studio.js +6 -19
- package/dist/studio.js.map +1 -1
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/database-detection.d.ts +20 -0
- package/dist/utils/database-detection.d.ts.map +1 -0
- package/dist/utils/database-detection.js +143 -0
- package/dist/utils/database-detection.js.map +1 -0
- package/dist/utils/package-json.d.ts +8 -0
- package/dist/utils/package-json.d.ts.map +1 -0
- package/dist/utils/package-json.js +63 -0
- package/dist/utils/package-json.js.map +1 -0
- package/package.json +3 -2
- package/public/assets/main-C14wu34m.css +1 -0
- package/public/assets/main-yHRaRyCA.js +410 -0
- package/public/index.html +2 -2
- package/public/assets/main-6TIapMhx.css +0 -1
- package/public/assets/main-BUBnw2oe.js +0 -405
package/dist/routes.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
1
4
|
import { Router } from 'express';
|
|
2
|
-
import { existsSync, readFileSync } from 'fs';
|
|
3
5
|
import { createJiti } from 'jiti';
|
|
4
|
-
import { dirname, join } from 'path';
|
|
5
|
-
import { fileURLToPath, pathToFileURL } from 'url';
|
|
6
6
|
import { createMockAccount, createMockSession, createMockUser, createMockVerification, getAuthAdapter, } from './auth-adapter.js';
|
|
7
7
|
import { getAuthData } from './data.js';
|
|
8
8
|
import { initializeGeoService, resolveIPLocation, setGeoDbPath } from './geo-service.js';
|
|
9
|
+
import { detectDatabaseWithDialect } from './utils/database-detection.js';
|
|
9
10
|
function getStudioVersion() {
|
|
10
11
|
try {
|
|
11
12
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -15,12 +16,10 @@ function getStudioVersion() {
|
|
|
15
16
|
return packageJson.version || '1.0.0';
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
|
-
catch (
|
|
19
|
-
console.warn('Failed to read package.json for version:', error);
|
|
20
|
-
}
|
|
19
|
+
catch (_error) { }
|
|
21
20
|
return '1.0.0';
|
|
22
21
|
}
|
|
23
|
-
function
|
|
22
|
+
function _resolveModuleWithExtensions(id, parent) {
|
|
24
23
|
if (!id.startsWith('./') && !id.startsWith('../')) {
|
|
25
24
|
return id;
|
|
26
25
|
}
|
|
@@ -35,7 +34,7 @@ function resolveModuleWithExtensions(id, parent) {
|
|
|
35
34
|
}
|
|
36
35
|
if (existsSync(basePath)) {
|
|
37
36
|
for (const ext of extensions) {
|
|
38
|
-
const indexPath = join(basePath,
|
|
37
|
+
const indexPath = join(basePath, `index${ext}`);
|
|
39
38
|
if (existsSync(indexPath)) {
|
|
40
39
|
return pathToFileURL(indexPath).href;
|
|
41
40
|
}
|
|
@@ -62,10 +61,10 @@ export async function safeImportAuthConfig(authConfigPath) {
|
|
|
62
61
|
for (const importPath of foundImports) {
|
|
63
62
|
const importName = importPath.replace('./', '');
|
|
64
63
|
const possiblePaths = [
|
|
65
|
-
join(authConfigDir, importName
|
|
66
|
-
join(authConfigDir, importName
|
|
67
|
-
join(authConfigDir, importName
|
|
68
|
-
join(authConfigDir, importName
|
|
64
|
+
join(authConfigDir, `${importName}.ts`),
|
|
65
|
+
join(authConfigDir, `${importName}.js`),
|
|
66
|
+
join(authConfigDir, `${importName}.mjs`),
|
|
67
|
+
join(authConfigDir, `${importName}.cjs`),
|
|
69
68
|
join(authConfigDir, importName, 'index.ts'),
|
|
70
69
|
join(authConfigDir, importName, 'index.js'),
|
|
71
70
|
join(authConfigDir, importName, 'index.mjs'),
|
|
@@ -88,7 +87,7 @@ export async function safeImportAuthConfig(authConfigPath) {
|
|
|
88
87
|
try {
|
|
89
88
|
return await jiti.import(authConfigPath);
|
|
90
89
|
}
|
|
91
|
-
catch (
|
|
90
|
+
catch (_importError) {
|
|
92
91
|
const content = readFileSync(authConfigPath, 'utf-8');
|
|
93
92
|
return {
|
|
94
93
|
auth: {
|
|
@@ -103,9 +102,9 @@ export async function safeImportAuthConfig(authConfigPath) {
|
|
|
103
102
|
}
|
|
104
103
|
catch (importError) {
|
|
105
104
|
try {
|
|
106
|
-
const { dirname, join } = await import('path');
|
|
107
|
-
const { existsSync, readFileSync, writeFileSync, mkdtempSync, unlinkSync, rmdirSync } = await import('fs');
|
|
108
|
-
const { tmpdir } = await import('os');
|
|
105
|
+
const { dirname, join } = await import('node:path');
|
|
106
|
+
const { existsSync, readFileSync, writeFileSync, mkdtempSync, unlinkSync, rmdirSync } = await import('node:fs');
|
|
107
|
+
const { tmpdir } = await import('node:os');
|
|
109
108
|
const projectDir = dirname(authConfigPath);
|
|
110
109
|
const content = readFileSync(authConfigPath, 'utf-8');
|
|
111
110
|
let resolvedContent = content;
|
|
@@ -158,15 +157,14 @@ export async function safeImportAuthConfig(authConfigPath) {
|
|
|
158
157
|
throw new Error('No node_modules found');
|
|
159
158
|
}
|
|
160
159
|
}
|
|
161
|
-
catch (
|
|
162
|
-
console.error('Import resolution also failed:', resolveError);
|
|
160
|
+
catch (_resolveError) {
|
|
163
161
|
throw importError;
|
|
164
162
|
}
|
|
165
163
|
}
|
|
166
164
|
}
|
|
167
165
|
async function findAuthConfigPath() {
|
|
168
|
-
const { join, dirname } = await import('path');
|
|
169
|
-
const { existsSync } = await import('fs');
|
|
166
|
+
const { join, dirname } = await import('node:path');
|
|
167
|
+
const { existsSync } = await import('node:fs');
|
|
170
168
|
const possiblePaths = [
|
|
171
169
|
'auth.js',
|
|
172
170
|
'auth.ts',
|
|
@@ -190,7 +188,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
190
188
|
}
|
|
191
189
|
initializeGeoService().catch(console.error);
|
|
192
190
|
const getAuthAdapterWithConfig = () => getAuthAdapter(configPath);
|
|
193
|
-
router.get('/api/health', (
|
|
191
|
+
router.get('/api/health', (_req, res) => {
|
|
194
192
|
const uptime = process.uptime();
|
|
195
193
|
const hours = Math.floor(uptime / 3600);
|
|
196
194
|
const minutes = Math.floor((uptime % 3600) / 60);
|
|
@@ -236,35 +234,49 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
236
234
|
location,
|
|
237
235
|
});
|
|
238
236
|
}
|
|
239
|
-
catch (
|
|
240
|
-
console.error('Error resolving IP location:', error);
|
|
237
|
+
catch (_error) {
|
|
241
238
|
res.status(500).json({
|
|
242
239
|
success: false,
|
|
243
240
|
error: 'Failed to resolve IP location',
|
|
244
241
|
});
|
|
245
242
|
}
|
|
246
243
|
});
|
|
247
|
-
router.get('/api/config', async (
|
|
244
|
+
router.get('/api/config', async (_req, res) => {
|
|
248
245
|
let databaseType = 'unknown';
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
databaseType = 'SQLite';
|
|
246
|
+
let databaseDialect = 'unknown';
|
|
247
|
+
let databaseAdapter = 'unknown';
|
|
248
|
+
let databaseVersion = 'unknown';
|
|
249
|
+
try {
|
|
250
|
+
const detectedDb = await detectDatabaseWithDialect();
|
|
251
|
+
if (detectedDb) {
|
|
252
|
+
databaseType = detectedDb.name.charAt(0).toUpperCase() + detectedDb.name.slice(1);
|
|
253
|
+
databaseDialect = detectedDb.dialect || detectedDb.name;
|
|
254
|
+
databaseAdapter = detectedDb.adapter || detectedDb.name;
|
|
255
|
+
databaseVersion = detectedDb.version;
|
|
260
256
|
}
|
|
261
257
|
}
|
|
258
|
+
catch (_error) { }
|
|
262
259
|
if (databaseType === 'unknown') {
|
|
263
|
-
|
|
264
|
-
if (
|
|
265
|
-
|
|
260
|
+
const configPath = await findAuthConfigPath();
|
|
261
|
+
if (configPath) {
|
|
262
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
263
|
+
if (content.includes('drizzleAdapter')) {
|
|
264
|
+
databaseType = 'Drizzle';
|
|
265
|
+
}
|
|
266
|
+
else if (content.includes('prismaAdapter')) {
|
|
267
|
+
databaseType = 'Prisma';
|
|
268
|
+
}
|
|
269
|
+
else if (content.includes('better-sqlite3') || content.includes('new Database(')) {
|
|
270
|
+
databaseType = 'SQLite';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (databaseType === 'unknown') {
|
|
274
|
+
let type = authConfig.database?.type || authConfig.database?.adapter || 'unknown';
|
|
275
|
+
if (type && type !== 'unknown') {
|
|
276
|
+
type = type.charAt(0).toUpperCase() + type.slice(1);
|
|
277
|
+
}
|
|
278
|
+
databaseType = type;
|
|
266
279
|
}
|
|
267
|
-
databaseType = type;
|
|
268
280
|
}
|
|
269
281
|
const config = {
|
|
270
282
|
appName: authConfig.appName || 'Better Auth',
|
|
@@ -273,7 +285,9 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
273
285
|
secret: authConfig.secret ? 'Configured' : 'Not set',
|
|
274
286
|
database: {
|
|
275
287
|
type: databaseType,
|
|
276
|
-
dialect: authConfig.database?.dialect || authConfig.database?.provider ||
|
|
288
|
+
dialect: authConfig.database?.dialect || authConfig.database?.provider || databaseDialect,
|
|
289
|
+
adapter: authConfig.database?.adapter || databaseAdapter,
|
|
290
|
+
version: databaseVersion,
|
|
277
291
|
casing: authConfig.database?.casing || 'camel',
|
|
278
292
|
debugLogs: authConfig.database?.debugLogs || false,
|
|
279
293
|
url: authConfig.database?.url,
|
|
@@ -295,12 +309,12 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
295
309
|
revokeSessionsOnPasswordReset: authConfig.emailAndPassword?.revokeSessionsOnPasswordReset ?? false,
|
|
296
310
|
},
|
|
297
311
|
socialProviders: authConfig.socialProviders
|
|
298
|
-
?
|
|
299
|
-
type: provider,
|
|
300
|
-
clientId:
|
|
301
|
-
clientSecret:
|
|
302
|
-
redirectUri:
|
|
303
|
-
...
|
|
312
|
+
? authConfig.socialProviders.map((provider) => ({
|
|
313
|
+
type: provider.id,
|
|
314
|
+
clientId: provider.clientId,
|
|
315
|
+
clientSecret: provider.clientSecret,
|
|
316
|
+
redirectUri: provider.redirectUri,
|
|
317
|
+
...provider,
|
|
304
318
|
}))
|
|
305
319
|
: authConfig.providers || [],
|
|
306
320
|
user: {
|
|
@@ -384,17 +398,16 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
384
398
|
};
|
|
385
399
|
res.json(config);
|
|
386
400
|
});
|
|
387
|
-
router.get('/api/stats', async (
|
|
401
|
+
router.get('/api/stats', async (_req, res) => {
|
|
388
402
|
try {
|
|
389
403
|
const stats = await getAuthData(authConfig, 'stats', undefined, configPath);
|
|
390
404
|
res.json(stats);
|
|
391
405
|
}
|
|
392
|
-
catch (
|
|
393
|
-
console.error('Error fetching stats:', error);
|
|
406
|
+
catch (_error) {
|
|
394
407
|
res.status(500).json({ error: 'Failed to fetch statistics' });
|
|
395
408
|
}
|
|
396
409
|
});
|
|
397
|
-
router.get('/api/counts', async (
|
|
410
|
+
router.get('/api/counts', async (_req, res) => {
|
|
398
411
|
try {
|
|
399
412
|
const adapter = await getAuthAdapterWithConfig();
|
|
400
413
|
let userCount = 0;
|
|
@@ -422,8 +435,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
422
435
|
}
|
|
423
436
|
}
|
|
424
437
|
}
|
|
425
|
-
catch (
|
|
426
|
-
console.error('Error checking plugin status:', error);
|
|
438
|
+
catch (_error) {
|
|
427
439
|
organizationPluginEnabled = false;
|
|
428
440
|
teamsPluginEnabled = false;
|
|
429
441
|
}
|
|
@@ -434,18 +446,14 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
434
446
|
userCount = users?.length || 0;
|
|
435
447
|
}
|
|
436
448
|
}
|
|
437
|
-
catch (
|
|
438
|
-
console.error('Error fetching user count:', error);
|
|
439
|
-
}
|
|
449
|
+
catch (_error) { }
|
|
440
450
|
try {
|
|
441
451
|
if (typeof adapter.findMany === 'function') {
|
|
442
452
|
const sessions = await adapter.findMany({ model: 'session', limit: 10000 });
|
|
443
453
|
sessionCount = sessions?.length || 0;
|
|
444
454
|
}
|
|
445
455
|
}
|
|
446
|
-
catch (
|
|
447
|
-
console.error('Error fetching session count:', error);
|
|
448
|
-
}
|
|
456
|
+
catch (_error) { }
|
|
449
457
|
if (organizationPluginEnabled) {
|
|
450
458
|
try {
|
|
451
459
|
if (typeof adapter.findMany === 'function') {
|
|
@@ -453,8 +461,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
453
461
|
organizationCount = organizations?.length || 0;
|
|
454
462
|
}
|
|
455
463
|
}
|
|
456
|
-
catch (
|
|
457
|
-
console.error('Error fetching organization count:', error);
|
|
464
|
+
catch (_error) {
|
|
458
465
|
organizationCount = 0;
|
|
459
466
|
}
|
|
460
467
|
}
|
|
@@ -465,8 +472,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
465
472
|
teamCount = teams?.length || 0;
|
|
466
473
|
}
|
|
467
474
|
}
|
|
468
|
-
catch (
|
|
469
|
-
console.error('Error fetching team count:', error);
|
|
475
|
+
catch (_error) {
|
|
470
476
|
teamCount = 0;
|
|
471
477
|
}
|
|
472
478
|
}
|
|
@@ -478,12 +484,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
478
484
|
teams: teamCount,
|
|
479
485
|
});
|
|
480
486
|
}
|
|
481
|
-
catch (
|
|
482
|
-
console.error('Error fetching counts:', error);
|
|
487
|
+
catch (_error) {
|
|
483
488
|
res.status(500).json({ error: 'Failed to fetch counts' });
|
|
484
489
|
}
|
|
485
490
|
});
|
|
486
|
-
router.get('/api/users/all', async (
|
|
491
|
+
router.get('/api/users/all', async (_req, res) => {
|
|
487
492
|
try {
|
|
488
493
|
const adapter = await getAuthAdapterWithConfig();
|
|
489
494
|
if (!adapter) {
|
|
@@ -497,8 +502,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
497
502
|
res.json({ success: true, users: [] });
|
|
498
503
|
}
|
|
499
504
|
}
|
|
500
|
-
catch (
|
|
501
|
-
console.error('Error fetching all users:', error);
|
|
505
|
+
catch (_error) {
|
|
502
506
|
res.status(500).json({ error: 'Failed to fetch users' });
|
|
503
507
|
}
|
|
504
508
|
});
|
|
@@ -520,8 +524,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
520
524
|
}
|
|
521
525
|
res.json({ user });
|
|
522
526
|
}
|
|
523
|
-
catch (
|
|
524
|
-
console.error('Error fetching user:', error);
|
|
527
|
+
catch (_error) {
|
|
525
528
|
res.status(500).json({ error: 'Failed to fetch user' });
|
|
526
529
|
}
|
|
527
530
|
});
|
|
@@ -540,8 +543,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
540
543
|
});
|
|
541
544
|
res.json({ success: true, user });
|
|
542
545
|
}
|
|
543
|
-
catch (
|
|
544
|
-
console.error('Error updating user:', error);
|
|
546
|
+
catch (_error) {
|
|
545
547
|
res.status(500).json({ error: 'Failed to update user' });
|
|
546
548
|
}
|
|
547
549
|
});
|
|
@@ -555,8 +557,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
555
557
|
await adapter.delete({ model: 'user', where: [{ field: 'id', value: userId }] });
|
|
556
558
|
res.json({ success: true });
|
|
557
559
|
}
|
|
558
|
-
catch (
|
|
559
|
-
console.error('Error deleting user:', error);
|
|
560
|
+
catch (_error) {
|
|
560
561
|
res.status(500).json({ error: 'Failed to delete user' });
|
|
561
562
|
}
|
|
562
563
|
});
|
|
@@ -596,8 +597,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
596
597
|
});
|
|
597
598
|
res.json({ memberships: formattedMemberships });
|
|
598
599
|
}
|
|
599
|
-
catch (
|
|
600
|
-
console.error('Error fetching user organizations:', error);
|
|
600
|
+
catch (_error) {
|
|
601
601
|
res.status(500).json({ error: 'Failed to fetch user organizations' });
|
|
602
602
|
}
|
|
603
603
|
});
|
|
@@ -642,8 +642,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
642
642
|
});
|
|
643
643
|
res.json({ memberships: formattedMemberships });
|
|
644
644
|
}
|
|
645
|
-
catch (
|
|
646
|
-
console.error('Error fetching user teams:', error);
|
|
645
|
+
catch (_error) {
|
|
647
646
|
res.status(500).json({ error: 'Failed to fetch user teams' });
|
|
648
647
|
}
|
|
649
648
|
});
|
|
@@ -657,8 +656,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
657
656
|
await adapter.delete({ model: 'member', id: membershipId });
|
|
658
657
|
res.json({ success: true });
|
|
659
658
|
}
|
|
660
|
-
catch (
|
|
661
|
-
console.error('Error removing user from organization:', error);
|
|
659
|
+
catch (_error) {
|
|
662
660
|
res.status(500).json({ error: 'Failed to remove user from organization' });
|
|
663
661
|
}
|
|
664
662
|
});
|
|
@@ -672,8 +670,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
672
670
|
await adapter.delete({ model: 'teamMember', id: membershipId });
|
|
673
671
|
res.json({ success: true });
|
|
674
672
|
}
|
|
675
|
-
catch (
|
|
676
|
-
console.error('Error removing user from team:', error);
|
|
673
|
+
catch (_error) {
|
|
677
674
|
res.status(500).json({ error: 'Failed to remove user from team' });
|
|
678
675
|
}
|
|
679
676
|
});
|
|
@@ -691,8 +688,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
691
688
|
});
|
|
692
689
|
res.json({ success: true, user });
|
|
693
690
|
}
|
|
694
|
-
catch (
|
|
695
|
-
console.error('Error banning user:', error);
|
|
691
|
+
catch (_error) {
|
|
696
692
|
res.status(500).json({ error: 'Failed to ban user' });
|
|
697
693
|
}
|
|
698
694
|
});
|
|
@@ -721,8 +717,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
721
717
|
}));
|
|
722
718
|
res.json({ sessions: formattedSessions });
|
|
723
719
|
}
|
|
724
|
-
catch (
|
|
725
|
-
console.error('Error fetching user sessions:', error);
|
|
720
|
+
catch (_error) {
|
|
726
721
|
res.status(500).json({ error: 'Failed to fetch user sessions' });
|
|
727
722
|
}
|
|
728
723
|
});
|
|
@@ -736,8 +731,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
736
731
|
await adapter.delete({ model: 'session', id: sessionId });
|
|
737
732
|
res.json({ success: true });
|
|
738
733
|
}
|
|
739
|
-
catch (
|
|
740
|
-
console.error('Error deleting session:', error);
|
|
734
|
+
catch (_error) {
|
|
741
735
|
res.status(500).json({ error: 'Failed to delete session' });
|
|
742
736
|
}
|
|
743
737
|
});
|
|
@@ -767,9 +761,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
767
761
|
});
|
|
768
762
|
organization = orgs && orgs.length > 0 ? orgs[0] : null;
|
|
769
763
|
}
|
|
770
|
-
catch (
|
|
771
|
-
console.error('Error fetching organization for team:', error);
|
|
772
|
-
}
|
|
764
|
+
catch (_error) { }
|
|
773
765
|
const transformedTeam = {
|
|
774
766
|
id: team.id,
|
|
775
767
|
name: team.name,
|
|
@@ -787,8 +779,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
787
779
|
};
|
|
788
780
|
res.json({ success: true, team: transformedTeam });
|
|
789
781
|
}
|
|
790
|
-
catch (
|
|
791
|
-
console.error('Error fetching team:', error);
|
|
782
|
+
catch (_error) {
|
|
792
783
|
res.status(500).json({ error: 'Failed to fetch team' });
|
|
793
784
|
}
|
|
794
785
|
});
|
|
@@ -818,15 +809,14 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
818
809
|
};
|
|
819
810
|
res.json({ success: true, organization: transformedOrganization });
|
|
820
811
|
}
|
|
821
|
-
catch (
|
|
822
|
-
console.error('Error fetching organization:', error);
|
|
812
|
+
catch (_error) {
|
|
823
813
|
res.status(500).json({ error: 'Failed to fetch organization' });
|
|
824
814
|
}
|
|
825
815
|
});
|
|
826
816
|
router.get('/api/users', async (req, res) => {
|
|
827
817
|
try {
|
|
828
|
-
const page = parseInt(req.query.page) || 1;
|
|
829
|
-
const limit = parseInt(req.query.limit) || 20;
|
|
818
|
+
const page = parseInt(req.query.page, 10) || 1;
|
|
819
|
+
const limit = parseInt(req.query.limit, 10) || 20;
|
|
830
820
|
const search = req.query.search;
|
|
831
821
|
try {
|
|
832
822
|
const adapter = await getAuthAdapterWithConfig();
|
|
@@ -848,14 +838,16 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
848
838
|
emailVerified: user.emailVerified,
|
|
849
839
|
createdAt: user.createdAt,
|
|
850
840
|
updatedAt: user.updatedAt,
|
|
841
|
+
role: user.role,
|
|
842
|
+
banned: user.banned,
|
|
843
|
+
banReason: user.banReason,
|
|
844
|
+
banExpires: user.banExpires,
|
|
851
845
|
}));
|
|
852
846
|
res.json({ users: transformedUsers });
|
|
853
847
|
return;
|
|
854
848
|
}
|
|
855
849
|
}
|
|
856
|
-
catch (
|
|
857
|
-
console.error('Error fetching users from adapter:', adapterError);
|
|
858
|
-
}
|
|
850
|
+
catch (_adapterError) { }
|
|
859
851
|
const result = await getAuthData(authConfig, 'users', { page, limit, search }, configPath);
|
|
860
852
|
const transformedUsers = (result.data || []).map((user) => ({
|
|
861
853
|
id: user.id,
|
|
@@ -865,33 +857,35 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
865
857
|
emailVerified: user.emailVerified,
|
|
866
858
|
createdAt: user.createdAt,
|
|
867
859
|
updatedAt: user.updatedAt,
|
|
860
|
+
role: user.role,
|
|
861
|
+
banned: user.banned,
|
|
862
|
+
banReason: user.banReason,
|
|
863
|
+
banExpires: user.banExpires,
|
|
864
|
+
...user,
|
|
868
865
|
}));
|
|
869
866
|
res.json({ users: transformedUsers });
|
|
870
867
|
}
|
|
871
|
-
catch (
|
|
872
|
-
console.error('Error fetching users:', error);
|
|
868
|
+
catch (_error) {
|
|
873
869
|
res.status(500).json({ error: 'Failed to fetch users' });
|
|
874
870
|
}
|
|
875
871
|
});
|
|
876
872
|
router.get('/api/sessions', async (req, res) => {
|
|
877
873
|
try {
|
|
878
|
-
const page = parseInt(req.query.page) || 1;
|
|
879
|
-
const limit = parseInt(req.query.limit) || 20;
|
|
874
|
+
const page = parseInt(req.query.page, 10) || 1;
|
|
875
|
+
const limit = parseInt(req.query.limit, 10) || 20;
|
|
880
876
|
const sessions = await getAuthData(authConfig, 'sessions', { page, limit }, configPath);
|
|
881
877
|
res.json(sessions);
|
|
882
878
|
}
|
|
883
|
-
catch (
|
|
884
|
-
console.error('Error fetching sessions:', error);
|
|
879
|
+
catch (_error) {
|
|
885
880
|
res.status(500).json({ error: 'Failed to fetch sessions' });
|
|
886
881
|
}
|
|
887
882
|
});
|
|
888
|
-
router.get('/api/providers', async (
|
|
883
|
+
router.get('/api/providers', async (_req, res) => {
|
|
889
884
|
try {
|
|
890
885
|
const providers = await getAuthData(authConfig, 'providers', undefined, configPath);
|
|
891
886
|
res.json(providers);
|
|
892
887
|
}
|
|
893
|
-
catch (
|
|
894
|
-
console.error('Error fetching providers:', error);
|
|
888
|
+
catch (_error) {
|
|
895
889
|
res.status(500).json({ error: 'Failed to fetch providers' });
|
|
896
890
|
}
|
|
897
891
|
});
|
|
@@ -901,12 +895,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
901
895
|
await getAuthData(authConfig, 'deleteUser', { id }, configPath);
|
|
902
896
|
res.json({ success: true });
|
|
903
897
|
}
|
|
904
|
-
catch (
|
|
905
|
-
console.error('Error deleting user:', error);
|
|
898
|
+
catch (_error) {
|
|
906
899
|
res.status(500).json({ error: 'Failed to delete user' });
|
|
907
900
|
}
|
|
908
901
|
});
|
|
909
|
-
router.get('/api/plugins', async (
|
|
902
|
+
router.get('/api/plugins', async (_req, res) => {
|
|
910
903
|
try {
|
|
911
904
|
const authConfigPath = configPath
|
|
912
905
|
? join(process.cwd(), configPath)
|
|
@@ -923,7 +916,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
923
916
|
try {
|
|
924
917
|
authModule = await safeImportAuthConfig(authConfigPath);
|
|
925
918
|
}
|
|
926
|
-
catch (
|
|
919
|
+
catch (_importError) {
|
|
927
920
|
// Fallback: read file content directly
|
|
928
921
|
const content = readFileSync(authConfigPath, 'utf-8');
|
|
929
922
|
authModule = {
|
|
@@ -956,14 +949,13 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
956
949
|
totalPlugins: pluginInfo.length,
|
|
957
950
|
});
|
|
958
951
|
}
|
|
959
|
-
catch (
|
|
960
|
-
console.error('Error importing auth config:', error);
|
|
952
|
+
catch (_error) {
|
|
961
953
|
try {
|
|
962
|
-
const { readFileSync } = await import('fs');
|
|
954
|
+
const { readFileSync } = await import('node:fs');
|
|
963
955
|
const content = readFileSync(authConfigPath, 'utf-8');
|
|
964
956
|
const { extractBetterAuthConfig } = await import('./config');
|
|
965
957
|
const config = extractBetterAuthConfig(content);
|
|
966
|
-
if (config
|
|
958
|
+
if (config?.plugins) {
|
|
967
959
|
const pluginInfo = config.plugins.map((plugin) => ({
|
|
968
960
|
id: plugin.id || 'unknown',
|
|
969
961
|
name: plugin.name || plugin.id || 'unknown',
|
|
@@ -979,9 +971,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
979
971
|
});
|
|
980
972
|
}
|
|
981
973
|
}
|
|
982
|
-
catch (
|
|
983
|
-
console.error('Fallback extraction also failed:', fallbackError);
|
|
984
|
-
}
|
|
974
|
+
catch (_fallbackError) { }
|
|
985
975
|
res.json({
|
|
986
976
|
plugins: [],
|
|
987
977
|
error: 'Failed to load auth config - import failed and regex extraction unavailable',
|
|
@@ -989,12 +979,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
989
979
|
});
|
|
990
980
|
}
|
|
991
981
|
}
|
|
992
|
-
catch (
|
|
993
|
-
console.error('Error fetching plugins:', error);
|
|
982
|
+
catch (_error) {
|
|
994
983
|
res.status(500).json({ error: 'Failed to fetch plugins' });
|
|
995
984
|
}
|
|
996
985
|
});
|
|
997
|
-
router.get('/api/database/info', async (
|
|
986
|
+
router.get('/api/database/info', async (_req, res) => {
|
|
998
987
|
try {
|
|
999
988
|
const authConfigPath = configPath || (await findAuthConfigPath());
|
|
1000
989
|
if (!authConfigPath) {
|
|
@@ -1020,14 +1009,13 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1020
1009
|
configPath: authConfigPath,
|
|
1021
1010
|
});
|
|
1022
1011
|
}
|
|
1023
|
-
catch (
|
|
1024
|
-
console.error('Error getting database info:', error);
|
|
1012
|
+
catch (_error) {
|
|
1025
1013
|
try {
|
|
1026
|
-
const { readFileSync } = await import('fs');
|
|
1014
|
+
const { readFileSync } = await import('node:fs');
|
|
1027
1015
|
const content = readFileSync(authConfigPath, 'utf-8');
|
|
1028
1016
|
const { extractBetterAuthConfig } = await import('./config');
|
|
1029
1017
|
const config = extractBetterAuthConfig(content);
|
|
1030
|
-
if (config
|
|
1018
|
+
if (config?.database) {
|
|
1031
1019
|
return res.json({
|
|
1032
1020
|
database: config.database,
|
|
1033
1021
|
configPath: authConfigPath,
|
|
@@ -1035,9 +1023,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1035
1023
|
});
|
|
1036
1024
|
}
|
|
1037
1025
|
}
|
|
1038
|
-
catch (
|
|
1039
|
-
console.error('Fallback extraction also failed:', fallbackError);
|
|
1040
|
-
}
|
|
1026
|
+
catch (_fallbackError) { }
|
|
1041
1027
|
res.json({
|
|
1042
1028
|
database: null,
|
|
1043
1029
|
error: 'Failed to load auth config - import failed and regex extraction unavailable',
|
|
@@ -1045,11 +1031,221 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1045
1031
|
});
|
|
1046
1032
|
}
|
|
1047
1033
|
}
|
|
1048
|
-
catch (
|
|
1049
|
-
console.error('Error fetching database info:', error);
|
|
1034
|
+
catch (_error) {
|
|
1050
1035
|
res.status(500).json({ error: 'Failed to fetch database info' });
|
|
1051
1036
|
}
|
|
1052
1037
|
});
|
|
1038
|
+
// Database Detection endpoint - Auto-detect database from installed packages
|
|
1039
|
+
router.get('/api/database/detect', async (_req, res) => {
|
|
1040
|
+
try {
|
|
1041
|
+
const detectedDb = await detectDatabaseWithDialect();
|
|
1042
|
+
if (detectedDb) {
|
|
1043
|
+
res.json({
|
|
1044
|
+
success: true,
|
|
1045
|
+
database: {
|
|
1046
|
+
name: detectedDb.name,
|
|
1047
|
+
version: detectedDb.version,
|
|
1048
|
+
dialect: detectedDb.dialect,
|
|
1049
|
+
adapter: detectedDb.adapter,
|
|
1050
|
+
displayName: detectedDb.name.charAt(0).toUpperCase() + detectedDb.name.slice(1),
|
|
1051
|
+
},
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
else {
|
|
1055
|
+
res.json({
|
|
1056
|
+
success: false,
|
|
1057
|
+
database: null,
|
|
1058
|
+
message: 'No supported database packages detected',
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
catch (error) {
|
|
1063
|
+
res.status(500).json({
|
|
1064
|
+
success: false,
|
|
1065
|
+
error: 'Failed to detect database',
|
|
1066
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
router.get('/api/db', async (_req, res) => {
|
|
1071
|
+
try {
|
|
1072
|
+
const detectedDb = await detectDatabaseWithDialect();
|
|
1073
|
+
if (detectedDb) {
|
|
1074
|
+
res.json({
|
|
1075
|
+
success: true,
|
|
1076
|
+
name: detectedDb.name,
|
|
1077
|
+
version: detectedDb.version,
|
|
1078
|
+
dialect: detectedDb.dialect,
|
|
1079
|
+
adapter: detectedDb.adapter,
|
|
1080
|
+
displayName: detectedDb.name.charAt(0).toUpperCase() + detectedDb.name.slice(1),
|
|
1081
|
+
autoDetected: true,
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
else {
|
|
1085
|
+
res.json({
|
|
1086
|
+
success: false,
|
|
1087
|
+
name: 'unknown',
|
|
1088
|
+
version: 'unknown',
|
|
1089
|
+
dialect: 'unknown',
|
|
1090
|
+
adapter: 'unknown',
|
|
1091
|
+
displayName: 'Unknown',
|
|
1092
|
+
autoDetected: false,
|
|
1093
|
+
message: 'No supported database packages detected',
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
catch (error) {
|
|
1098
|
+
res.status(500).json({
|
|
1099
|
+
success: false,
|
|
1100
|
+
error: 'Failed to get database information',
|
|
1101
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
router.post('/api/admin/ban-user', async (req, res) => {
|
|
1106
|
+
try {
|
|
1107
|
+
const authConfigPath = configPath || (await findAuthConfigPath());
|
|
1108
|
+
if (!authConfigPath) {
|
|
1109
|
+
return res.status(400).json({
|
|
1110
|
+
success: false,
|
|
1111
|
+
error: 'No auth config found',
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
const { getConfig } = await import('./config.js');
|
|
1115
|
+
const auth = await getConfig({
|
|
1116
|
+
cwd: process.cwd(),
|
|
1117
|
+
configPath: authConfigPath,
|
|
1118
|
+
shouldThrowOnError: false,
|
|
1119
|
+
});
|
|
1120
|
+
if (!auth) {
|
|
1121
|
+
return res.status(400).json({
|
|
1122
|
+
success: false,
|
|
1123
|
+
error: 'Failed to load auth config',
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
const plugins = auth.plugins || [];
|
|
1127
|
+
const adminPlugin = plugins.find((plugin) => plugin.id === 'admin');
|
|
1128
|
+
if (!adminPlugin) {
|
|
1129
|
+
return res.status(400).json({
|
|
1130
|
+
success: false,
|
|
1131
|
+
error: 'Admin plugin is not enabled. Please enable the admin plugin in your Better Auth configuration.',
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
const adapter = await getAuthAdapterWithConfig();
|
|
1135
|
+
if (!adapter || !adapter.update) {
|
|
1136
|
+
return res.status(500).json({
|
|
1137
|
+
success: false,
|
|
1138
|
+
error: 'Auth adapter not available',
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
const bannedUser = await adapter.update({
|
|
1142
|
+
model: 'user',
|
|
1143
|
+
where: [{ field: 'id', value: req.body.userId }],
|
|
1144
|
+
update: { banned: true, banReason: req.body.banReason, banExpires: req.body.banExpires },
|
|
1145
|
+
});
|
|
1146
|
+
res.json({ success: true, user: bannedUser });
|
|
1147
|
+
}
|
|
1148
|
+
catch (error) {
|
|
1149
|
+
res.status(500).json({
|
|
1150
|
+
success: false,
|
|
1151
|
+
error: 'Failed to ban user',
|
|
1152
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
router.post('/api/admin/unban-user', async (req, res) => {
|
|
1157
|
+
try {
|
|
1158
|
+
const authConfigPath = configPath || (await findAuthConfigPath());
|
|
1159
|
+
if (!authConfigPath) {
|
|
1160
|
+
return res.status(400).json({
|
|
1161
|
+
success: false,
|
|
1162
|
+
error: 'No auth config found',
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
const { getConfig } = await import('./config.js');
|
|
1166
|
+
const auth = await getConfig({
|
|
1167
|
+
cwd: process.cwd(),
|
|
1168
|
+
configPath: authConfigPath,
|
|
1169
|
+
shouldThrowOnError: false,
|
|
1170
|
+
});
|
|
1171
|
+
if (!auth) {
|
|
1172
|
+
return res.status(400).json({
|
|
1173
|
+
success: false,
|
|
1174
|
+
error: 'Failed to load auth config',
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
const plugins = auth.plugins || [];
|
|
1178
|
+
const adminPlugin = plugins.find((plugin) => plugin.id === 'admin');
|
|
1179
|
+
if (!adminPlugin) {
|
|
1180
|
+
return res.status(400).json({
|
|
1181
|
+
success: false,
|
|
1182
|
+
error: 'Admin plugin is not enabled. Please enable the admin plugin in your Better Auth configuration.',
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
const adapter = await getAuthAdapterWithConfig();
|
|
1186
|
+
if (!adapter || !adapter.update) {
|
|
1187
|
+
return res.status(500).json({
|
|
1188
|
+
success: false,
|
|
1189
|
+
error: 'Auth adapter not available',
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
const unbannedUser = await adapter.update({
|
|
1193
|
+
model: 'user',
|
|
1194
|
+
where: [{ field: 'id', value: req.body.userId }],
|
|
1195
|
+
update: { banned: false, banReason: null, banExpires: null },
|
|
1196
|
+
});
|
|
1197
|
+
res.json({ success: true, user: unbannedUser });
|
|
1198
|
+
}
|
|
1199
|
+
catch (error) {
|
|
1200
|
+
res.status(500).json({
|
|
1201
|
+
success: false,
|
|
1202
|
+
error: 'Failed to unban user',
|
|
1203
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
router.get('/api/admin/status', async (_req, res) => {
|
|
1208
|
+
try {
|
|
1209
|
+
const authConfigPath = configPath || (await findAuthConfigPath());
|
|
1210
|
+
if (!authConfigPath) {
|
|
1211
|
+
return res.json({
|
|
1212
|
+
enabled: false,
|
|
1213
|
+
error: 'No auth config found',
|
|
1214
|
+
configPath: null,
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
const { getConfig } = await import('./config.js');
|
|
1218
|
+
const betterAuthConfig = await getConfig({
|
|
1219
|
+
cwd: process.cwd(),
|
|
1220
|
+
configPath: authConfigPath,
|
|
1221
|
+
shouldThrowOnError: false,
|
|
1222
|
+
});
|
|
1223
|
+
if (!betterAuthConfig) {
|
|
1224
|
+
return res.json({
|
|
1225
|
+
enabled: false,
|
|
1226
|
+
error: 'Failed to load auth config',
|
|
1227
|
+
configPath: authConfigPath,
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
const plugins = betterAuthConfig.plugins || [];
|
|
1231
|
+
const adminPlugin = plugins.find((plugin) => plugin.id === 'admin');
|
|
1232
|
+
res.json({
|
|
1233
|
+
enabled: !!adminPlugin,
|
|
1234
|
+
configPath: authConfigPath,
|
|
1235
|
+
adminPlugin: adminPlugin || null,
|
|
1236
|
+
message: adminPlugin
|
|
1237
|
+
? 'Admin plugin is enabled. Use Better Auth admin endpoints directly for ban/unban functionality.'
|
|
1238
|
+
: 'Admin plugin is not enabled. Please enable the admin plugin in your Better Auth configuration.',
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
catch (error) {
|
|
1242
|
+
res.status(500).json({
|
|
1243
|
+
enabled: false,
|
|
1244
|
+
error: 'Failed to check admin status',
|
|
1245
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
});
|
|
1053
1249
|
// Database Schema Visualization endpoint
|
|
1054
1250
|
// Schema definitions for different Better Auth plugins
|
|
1055
1251
|
const BASE_SCHEMA = {
|
|
@@ -1664,15 +1860,14 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1664
1860
|
selectedPlugins: selectedPlugins,
|
|
1665
1861
|
});
|
|
1666
1862
|
}
|
|
1667
|
-
catch (
|
|
1668
|
-
console.error('Error fetching database schema:', error);
|
|
1863
|
+
catch (_error) {
|
|
1669
1864
|
res.status(500).json({
|
|
1670
1865
|
success: false,
|
|
1671
1866
|
error: 'Failed to fetch database schema',
|
|
1672
1867
|
});
|
|
1673
1868
|
}
|
|
1674
1869
|
});
|
|
1675
|
-
router.get('/api/plugins/teams/status', async (
|
|
1870
|
+
router.get('/api/plugins/teams/status', async (_req, res) => {
|
|
1676
1871
|
try {
|
|
1677
1872
|
const authConfigPath = configPath || (await findAuthConfigPath());
|
|
1678
1873
|
if (!authConfigPath) {
|
|
@@ -1710,11 +1905,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1710
1905
|
}
|
|
1711
1906
|
}
|
|
1712
1907
|
try {
|
|
1713
|
-
const { readFileSync } = await import('fs');
|
|
1908
|
+
const { readFileSync } = await import('node:fs');
|
|
1714
1909
|
const content = readFileSync(authConfigPath, 'utf-8');
|
|
1715
1910
|
const { extractBetterAuthConfig } = await import('./config.js');
|
|
1716
1911
|
const config = extractBetterAuthConfig(content);
|
|
1717
|
-
if (config
|
|
1912
|
+
if (config?.plugins) {
|
|
1718
1913
|
const organizationPlugin = config.plugins.find((plugin) => plugin.id === 'organization');
|
|
1719
1914
|
const teamsEnabled = organizationPlugin?.teams?.enabled === true;
|
|
1720
1915
|
return res.json({
|
|
@@ -1725,22 +1920,18 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1725
1920
|
});
|
|
1726
1921
|
}
|
|
1727
1922
|
}
|
|
1728
|
-
catch (
|
|
1729
|
-
console.error('Fallback extraction also failed:', fallbackError);
|
|
1730
|
-
}
|
|
1923
|
+
catch (_fallbackError) { }
|
|
1731
1924
|
res.json({
|
|
1732
1925
|
enabled: false,
|
|
1733
1926
|
error: 'Failed to load auth config - getConfig failed and regex extraction unavailable',
|
|
1734
1927
|
configPath: authConfigPath,
|
|
1735
1928
|
});
|
|
1736
1929
|
}
|
|
1737
|
-
catch (
|
|
1738
|
-
console.error('Error checking teams plugin:', error);
|
|
1930
|
+
catch (_error) {
|
|
1739
1931
|
res.status(500).json({ error: 'Failed to check teams status' });
|
|
1740
1932
|
}
|
|
1741
1933
|
}
|
|
1742
|
-
catch (
|
|
1743
|
-
console.error('Error checking teams status:', error);
|
|
1934
|
+
catch (_error) {
|
|
1744
1935
|
res.status(500).json({ error: 'Failed to check teams status' });
|
|
1745
1936
|
}
|
|
1746
1937
|
});
|
|
@@ -1771,14 +1962,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1771
1962
|
res.json({ success: true, invitations: transformedInvitations });
|
|
1772
1963
|
return;
|
|
1773
1964
|
}
|
|
1774
|
-
catch (
|
|
1775
|
-
console.error('Error fetching invitations from adapter:', error);
|
|
1776
|
-
}
|
|
1965
|
+
catch (_error) { }
|
|
1777
1966
|
}
|
|
1778
1967
|
res.json({ success: true, invitations: [] });
|
|
1779
1968
|
}
|
|
1780
|
-
catch (
|
|
1781
|
-
console.error('Error fetching invitations:', error);
|
|
1969
|
+
catch (_error) {
|
|
1782
1970
|
res.status(500).json({ error: 'Failed to fetch invitations' });
|
|
1783
1971
|
}
|
|
1784
1972
|
});
|
|
@@ -1821,23 +2009,19 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1821
2009
|
}
|
|
1822
2010
|
return null;
|
|
1823
2011
|
}
|
|
1824
|
-
catch (
|
|
1825
|
-
console.error('Error fetching user for member:', error);
|
|
2012
|
+
catch (_error) {
|
|
1826
2013
|
return null;
|
|
1827
2014
|
}
|
|
1828
2015
|
}));
|
|
1829
|
-
const validMembers = membersWithUsers.filter((member) => member
|
|
2016
|
+
const validMembers = membersWithUsers.filter((member) => member?.user);
|
|
1830
2017
|
res.json({ success: true, members: validMembers });
|
|
1831
2018
|
return;
|
|
1832
2019
|
}
|
|
1833
|
-
catch (
|
|
1834
|
-
console.error('Error fetching members from adapter:', error);
|
|
1835
|
-
}
|
|
2020
|
+
catch (_error) { }
|
|
1836
2021
|
}
|
|
1837
2022
|
res.json({ success: true, members: [] });
|
|
1838
2023
|
}
|
|
1839
|
-
catch (
|
|
1840
|
-
console.error('Error fetching members:', error);
|
|
2024
|
+
catch (_error) {
|
|
1841
2025
|
res.status(500).json({ error: 'Failed to fetch members' });
|
|
1842
2026
|
}
|
|
1843
2027
|
});
|
|
@@ -1911,8 +2095,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1911
2095
|
results,
|
|
1912
2096
|
});
|
|
1913
2097
|
}
|
|
1914
|
-
catch (
|
|
1915
|
-
console.error('Error seeding members:', error);
|
|
2098
|
+
catch (_error) {
|
|
1916
2099
|
res.status(500).json({ error: 'Failed to seed members' });
|
|
1917
2100
|
}
|
|
1918
2101
|
});
|
|
@@ -1983,8 +2166,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
1983
2166
|
results,
|
|
1984
2167
|
});
|
|
1985
2168
|
}
|
|
1986
|
-
catch (
|
|
1987
|
-
console.error('Error seeding teams:', error);
|
|
2169
|
+
catch (_error) {
|
|
1988
2170
|
res.status(500).json({ error: 'Failed to seed teams' });
|
|
1989
2171
|
}
|
|
1990
2172
|
});
|
|
@@ -2004,8 +2186,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2004
2186
|
});
|
|
2005
2187
|
res.json({ success: true });
|
|
2006
2188
|
}
|
|
2007
|
-
catch (
|
|
2008
|
-
console.error('Error removing member:', error);
|
|
2189
|
+
catch (_error) {
|
|
2009
2190
|
res.status(500).json({ error: 'Failed to remove member' });
|
|
2010
2191
|
}
|
|
2011
2192
|
});
|
|
@@ -2029,8 +2210,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2029
2210
|
});
|
|
2030
2211
|
res.json({ success: true });
|
|
2031
2212
|
}
|
|
2032
|
-
catch (
|
|
2033
|
-
console.error('Error resending invitation:', error);
|
|
2213
|
+
catch (_error) {
|
|
2034
2214
|
res.status(500).json({ error: 'Failed to resend invitation' });
|
|
2035
2215
|
}
|
|
2036
2216
|
});
|
|
@@ -2054,8 +2234,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2054
2234
|
});
|
|
2055
2235
|
res.json({ success: true });
|
|
2056
2236
|
}
|
|
2057
|
-
catch (
|
|
2058
|
-
console.error('Error cancelling invitation:', error);
|
|
2237
|
+
catch (_error) {
|
|
2059
2238
|
res.status(500).json({ error: 'Failed to cancel invitation' });
|
|
2060
2239
|
}
|
|
2061
2240
|
});
|
|
@@ -2100,8 +2279,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2100
2279
|
});
|
|
2101
2280
|
res.json({ success: true, invitation });
|
|
2102
2281
|
}
|
|
2103
|
-
catch (
|
|
2104
|
-
console.error('Error creating invitation:', error);
|
|
2282
|
+
catch (_error) {
|
|
2105
2283
|
res.status(500).json({ error: 'Failed to create invitation' });
|
|
2106
2284
|
}
|
|
2107
2285
|
});
|
|
@@ -2138,14 +2316,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2138
2316
|
res.json({ success: true, teams: transformedTeams });
|
|
2139
2317
|
return;
|
|
2140
2318
|
}
|
|
2141
|
-
catch (
|
|
2142
|
-
console.error('Error fetching teams from adapter:', error);
|
|
2143
|
-
}
|
|
2319
|
+
catch (_error) { }
|
|
2144
2320
|
}
|
|
2145
2321
|
res.json({ success: true, teams: [] });
|
|
2146
2322
|
}
|
|
2147
|
-
catch (
|
|
2148
|
-
console.error('Error fetching teams:', error);
|
|
2323
|
+
catch (_error) {
|
|
2149
2324
|
res.status(500).json({ error: 'Failed to fetch teams' });
|
|
2150
2325
|
}
|
|
2151
2326
|
});
|
|
@@ -2182,8 +2357,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2182
2357
|
});
|
|
2183
2358
|
res.json({ success: true, team });
|
|
2184
2359
|
}
|
|
2185
|
-
catch (
|
|
2186
|
-
console.error('Error creating team:', error);
|
|
2360
|
+
catch (_error) {
|
|
2187
2361
|
res.status(500).json({ error: 'Failed to create team' });
|
|
2188
2362
|
}
|
|
2189
2363
|
});
|
|
@@ -2226,23 +2400,19 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2226
2400
|
}
|
|
2227
2401
|
return null;
|
|
2228
2402
|
}
|
|
2229
|
-
catch (
|
|
2230
|
-
console.error('Error fetching user for team member:', error);
|
|
2403
|
+
catch (_error) {
|
|
2231
2404
|
return null;
|
|
2232
2405
|
}
|
|
2233
2406
|
}));
|
|
2234
|
-
const validMembers = membersWithUsers.filter((member) => member
|
|
2407
|
+
const validMembers = membersWithUsers.filter((member) => member?.user);
|
|
2235
2408
|
res.json({ success: true, members: validMembers });
|
|
2236
2409
|
return;
|
|
2237
2410
|
}
|
|
2238
|
-
catch (
|
|
2239
|
-
console.error('Error fetching team members from adapter:', error);
|
|
2240
|
-
}
|
|
2411
|
+
catch (_error) { }
|
|
2241
2412
|
}
|
|
2242
2413
|
res.json({ success: true, members: [] });
|
|
2243
2414
|
}
|
|
2244
|
-
catch (
|
|
2245
|
-
console.error('Error fetching team members:', error);
|
|
2415
|
+
catch (_error) {
|
|
2246
2416
|
res.status(500).json({ error: 'Failed to fetch team members' });
|
|
2247
2417
|
}
|
|
2248
2418
|
});
|
|
@@ -2285,8 +2455,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2285
2455
|
results,
|
|
2286
2456
|
});
|
|
2287
2457
|
}
|
|
2288
|
-
catch (
|
|
2289
|
-
console.error('Error adding team members:', error);
|
|
2458
|
+
catch (_error) {
|
|
2290
2459
|
res.status(500).json({ error: 'Failed to add team members' });
|
|
2291
2460
|
}
|
|
2292
2461
|
});
|
|
@@ -2303,8 +2472,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2303
2472
|
});
|
|
2304
2473
|
res.json({ success: true });
|
|
2305
2474
|
}
|
|
2306
|
-
catch (
|
|
2307
|
-
console.error('Error removing team member:', error);
|
|
2475
|
+
catch (_error) {
|
|
2308
2476
|
res.status(500).json({ error: 'Failed to remove team member' });
|
|
2309
2477
|
}
|
|
2310
2478
|
});
|
|
@@ -2332,8 +2500,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2332
2500
|
});
|
|
2333
2501
|
res.json({ success: true, team: updatedTeam });
|
|
2334
2502
|
}
|
|
2335
|
-
catch (
|
|
2336
|
-
console.error('Error updating team:', error);
|
|
2503
|
+
catch (_error) {
|
|
2337
2504
|
res.status(500).json({ error: 'Failed to update team' });
|
|
2338
2505
|
}
|
|
2339
2506
|
});
|
|
@@ -2353,12 +2520,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2353
2520
|
});
|
|
2354
2521
|
res.json({ success: true });
|
|
2355
2522
|
}
|
|
2356
|
-
catch (
|
|
2357
|
-
console.error('Error deleting team:', error);
|
|
2523
|
+
catch (_error) {
|
|
2358
2524
|
res.status(500).json({ error: 'Failed to delete team' });
|
|
2359
2525
|
}
|
|
2360
2526
|
});
|
|
2361
|
-
router.get('/api/plugins/organization/status', async (
|
|
2527
|
+
router.get('/api/plugins/organization/status', async (_req, res) => {
|
|
2362
2528
|
try {
|
|
2363
2529
|
const authConfigPath = configPath || (await findAuthConfigPath());
|
|
2364
2530
|
if (!authConfigPath) {
|
|
@@ -2386,11 +2552,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2386
2552
|
});
|
|
2387
2553
|
}
|
|
2388
2554
|
try {
|
|
2389
|
-
const { readFileSync } = await import('fs');
|
|
2555
|
+
const { readFileSync } = await import('node:fs');
|
|
2390
2556
|
const content = readFileSync(authConfigPath, 'utf-8');
|
|
2391
2557
|
const { extractBetterAuthConfig } = await import('./config.js');
|
|
2392
2558
|
const config = extractBetterAuthConfig(content);
|
|
2393
|
-
if (config
|
|
2559
|
+
if (config?.plugins) {
|
|
2394
2560
|
const hasOrganizationPlugin = config.plugins.find((plugin) => plugin.id === 'organization');
|
|
2395
2561
|
return res.json({
|
|
2396
2562
|
enabled: !!hasOrganizationPlugin,
|
|
@@ -2401,29 +2567,25 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2401
2567
|
});
|
|
2402
2568
|
}
|
|
2403
2569
|
}
|
|
2404
|
-
catch (
|
|
2405
|
-
console.error('Fallback extraction also failed:', fallbackError);
|
|
2406
|
-
}
|
|
2570
|
+
catch (_fallbackError) { }
|
|
2407
2571
|
res.json({
|
|
2408
2572
|
enabled: false,
|
|
2409
2573
|
error: 'Failed to load auth config - getConfig failed and regex extraction unavailable',
|
|
2410
2574
|
configPath: authConfigPath,
|
|
2411
2575
|
});
|
|
2412
2576
|
}
|
|
2413
|
-
catch (
|
|
2414
|
-
console.error('Error checking organization plugin:', error);
|
|
2577
|
+
catch (_error) {
|
|
2415
2578
|
res.status(500).json({ error: 'Failed to check plugin status' });
|
|
2416
2579
|
}
|
|
2417
2580
|
}
|
|
2418
|
-
catch (
|
|
2419
|
-
console.error('Error checking plugin status:', error);
|
|
2581
|
+
catch (_error) {
|
|
2420
2582
|
res.status(500).json({ error: 'Failed to check plugin status' });
|
|
2421
2583
|
}
|
|
2422
2584
|
});
|
|
2423
2585
|
router.get('/api/organizations', async (req, res) => {
|
|
2424
2586
|
try {
|
|
2425
|
-
const page = parseInt(req.query.page) || 1;
|
|
2426
|
-
const limit = parseInt(req.query.limit) || 20;
|
|
2587
|
+
const page = parseInt(req.query.page, 10) || 1;
|
|
2588
|
+
const limit = parseInt(req.query.limit, 10) || 20;
|
|
2427
2589
|
const search = req.query.search;
|
|
2428
2590
|
try {
|
|
2429
2591
|
const adapter = await getAuthAdapterWithConfig();
|
|
@@ -2449,9 +2611,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2449
2611
|
return;
|
|
2450
2612
|
}
|
|
2451
2613
|
}
|
|
2452
|
-
catch (
|
|
2453
|
-
console.error('Error fetching organizations from adapter:', adapterError);
|
|
2454
|
-
}
|
|
2614
|
+
catch (_adapterError) { }
|
|
2455
2615
|
const mockOrganizations = [
|
|
2456
2616
|
{
|
|
2457
2617
|
id: 'org_1',
|
|
@@ -2472,8 +2632,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2472
2632
|
];
|
|
2473
2633
|
res.json({ organizations: mockOrganizations });
|
|
2474
2634
|
}
|
|
2475
|
-
catch (
|
|
2476
|
-
console.error('Error fetching organizations:', error);
|
|
2635
|
+
catch (_error) {
|
|
2477
2636
|
res.status(500).json({ error: 'Failed to fetch organizations' });
|
|
2478
2637
|
}
|
|
2479
2638
|
});
|
|
@@ -2493,8 +2652,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2493
2652
|
const organization = await adapter.createOrganization(orgData);
|
|
2494
2653
|
res.json({ success: true, organization });
|
|
2495
2654
|
}
|
|
2496
|
-
catch (
|
|
2497
|
-
console.error('Error creating organization:', error);
|
|
2655
|
+
catch (_error) {
|
|
2498
2656
|
res.status(500).json({ error: 'Failed to create organization' });
|
|
2499
2657
|
}
|
|
2500
2658
|
});
|
|
@@ -2524,8 +2682,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2524
2682
|
});
|
|
2525
2683
|
res.json({ success: true, organization: updatedOrg });
|
|
2526
2684
|
}
|
|
2527
|
-
catch (
|
|
2528
|
-
console.error('Error updating organization:', error);
|
|
2685
|
+
catch (_error) {
|
|
2529
2686
|
res.status(500).json({ error: 'Failed to update organization' });
|
|
2530
2687
|
}
|
|
2531
2688
|
});
|
|
@@ -2542,8 +2699,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2542
2699
|
});
|
|
2543
2700
|
res.json({ success: true, organization: deletedOrg });
|
|
2544
2701
|
}
|
|
2545
|
-
catch (
|
|
2546
|
-
console.error('Error deleting organization:', error);
|
|
2702
|
+
catch (_error) {
|
|
2547
2703
|
res.status(500).json({ error: 'Failed to delete organization' });
|
|
2548
2704
|
}
|
|
2549
2705
|
});
|
|
@@ -2557,8 +2713,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2557
2713
|
const user = await adapter.createUser(userData);
|
|
2558
2714
|
res.json({ success: true, user });
|
|
2559
2715
|
}
|
|
2560
|
-
catch (
|
|
2561
|
-
console.error('Error creating user:', error);
|
|
2716
|
+
catch (_error) {
|
|
2562
2717
|
res.status(500).json({ error: 'Failed to create user' });
|
|
2563
2718
|
}
|
|
2564
2719
|
});
|
|
@@ -2569,8 +2724,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2569
2724
|
const updatedUser = await getAuthData(authConfig, 'updateUser', { id, userData }, configPath);
|
|
2570
2725
|
res.json({ success: true, user: updatedUser });
|
|
2571
2726
|
}
|
|
2572
|
-
catch (
|
|
2573
|
-
console.error('Error updating user:', error);
|
|
2727
|
+
catch (_error) {
|
|
2574
2728
|
res.status(500).json({ error: 'Failed to update user' });
|
|
2575
2729
|
}
|
|
2576
2730
|
});
|
|
@@ -2613,8 +2767,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2613
2767
|
results,
|
|
2614
2768
|
});
|
|
2615
2769
|
}
|
|
2616
|
-
catch (
|
|
2617
|
-
console.error('Error seeding users:', error);
|
|
2770
|
+
catch (_error) {
|
|
2618
2771
|
res.status(500).json({ error: 'Failed to seed users' });
|
|
2619
2772
|
}
|
|
2620
2773
|
});
|
|
@@ -2629,7 +2782,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2629
2782
|
try {
|
|
2630
2783
|
user = await createMockUser(adapter, 1);
|
|
2631
2784
|
}
|
|
2632
|
-
catch (
|
|
2785
|
+
catch (_error) {
|
|
2633
2786
|
return res.status(500).json({ error: 'Failed to create user for session' });
|
|
2634
2787
|
}
|
|
2635
2788
|
const results = [];
|
|
@@ -2663,8 +2816,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2663
2816
|
results,
|
|
2664
2817
|
});
|
|
2665
2818
|
}
|
|
2666
|
-
catch (
|
|
2667
|
-
console.error('Error seeding sessions:', error);
|
|
2819
|
+
catch (_error) {
|
|
2668
2820
|
res.status(500).json({ error: 'Failed to seed sessions' });
|
|
2669
2821
|
}
|
|
2670
2822
|
});
|
|
@@ -2718,8 +2870,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2718
2870
|
results,
|
|
2719
2871
|
});
|
|
2720
2872
|
}
|
|
2721
|
-
catch (
|
|
2722
|
-
console.error('Error seeding sessions for user:', error);
|
|
2873
|
+
catch (_error) {
|
|
2723
2874
|
res.status(500).json({ error: 'Failed to seed sessions for user' });
|
|
2724
2875
|
}
|
|
2725
2876
|
});
|
|
@@ -2734,7 +2885,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2734
2885
|
try {
|
|
2735
2886
|
user = await createMockUser(adapter, 1);
|
|
2736
2887
|
}
|
|
2737
|
-
catch (
|
|
2888
|
+
catch (_error) {
|
|
2738
2889
|
return res.status(500).json({ error: 'Failed to create user for account' });
|
|
2739
2890
|
}
|
|
2740
2891
|
const results = [];
|
|
@@ -2769,8 +2920,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2769
2920
|
results,
|
|
2770
2921
|
});
|
|
2771
2922
|
}
|
|
2772
|
-
catch (
|
|
2773
|
-
console.error('Error seeding accounts:', error);
|
|
2923
|
+
catch (_error) {
|
|
2774
2924
|
res.status(500).json({ error: 'Failed to seed accounts' });
|
|
2775
2925
|
}
|
|
2776
2926
|
});
|
|
@@ -2812,8 +2962,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2812
2962
|
results,
|
|
2813
2963
|
});
|
|
2814
2964
|
}
|
|
2815
|
-
catch (
|
|
2816
|
-
console.error('Error seeding verifications:', error);
|
|
2965
|
+
catch (_error) {
|
|
2817
2966
|
res.status(500).json({ error: 'Failed to seed verifications' });
|
|
2818
2967
|
}
|
|
2819
2968
|
});
|
|
@@ -2869,8 +3018,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
|
|
|
2869
3018
|
results,
|
|
2870
3019
|
});
|
|
2871
3020
|
}
|
|
2872
|
-
catch (
|
|
2873
|
-
console.error('Error seeding organizations:', error);
|
|
3021
|
+
catch (_error) {
|
|
2874
3022
|
res.status(500).json({ error: 'Failed to seed organizations' });
|
|
2875
3023
|
}
|
|
2876
3024
|
});
|