better-auth-studio 1.0.26-beta.7 → 1.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +2 -2
  2. package/dist/auth-adapter.d.ts +1 -1
  3. package/dist/auth-adapter.d.ts.map +1 -1
  4. package/dist/auth-adapter.js +70 -107
  5. package/dist/auth-adapter.js.map +1 -1
  6. package/dist/cli.js +23 -34
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts +1 -1
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +5 -8
  11. package/dist/config.js.map +1 -1
  12. package/dist/data.d.ts +1 -1
  13. package/dist/data.d.ts.map +1 -1
  14. package/dist/data.js +21 -40
  15. package/dist/data.js.map +1 -1
  16. package/dist/geo-service.d.ts.map +1 -1
  17. package/dist/geo-service.js +10 -15
  18. package/dist/geo-service.js.map +1 -1
  19. package/dist/get-tsconfig-info.d.ts.map +1 -1
  20. package/dist/get-tsconfig-info.js +3 -4
  21. package/dist/get-tsconfig-info.js.map +1 -1
  22. package/dist/routes.d.ts.map +1 -1
  23. package/dist/routes.js +403 -273
  24. package/dist/routes.js.map +1 -1
  25. package/dist/studio.d.ts.map +1 -1
  26. package/dist/studio.js +13 -17
  27. package/dist/studio.js.map +1 -1
  28. package/dist/types/index.d.ts +9 -0
  29. package/dist/types/index.d.ts.map +1 -0
  30. package/dist/types/index.js +2 -0
  31. package/dist/types/index.js.map +1 -0
  32. package/dist/utils/database-detection.d.ts +20 -0
  33. package/dist/utils/database-detection.d.ts.map +1 -0
  34. package/dist/utils/database-detection.js +143 -0
  35. package/dist/utils/database-detection.js.map +1 -0
  36. package/dist/utils/package-json.d.ts +8 -0
  37. package/dist/utils/package-json.d.ts.map +1 -0
  38. package/dist/utils/package-json.js +63 -0
  39. package/dist/utils/package-json.js.map +1 -0
  40. package/package.json +3 -2
  41. package/public/assets/main-DWecCRCR.js +405 -0
  42. package/public/assets/main-FzP6n_gH.css +1 -0
  43. package/public/index.html +2 -2
  44. package/public/assets/main-6TIapMhx.css +0 -1
  45. 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 (error) {
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 resolveModuleWithExtensions(id, parent) {
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, 'index' + ext);
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 + '.ts'),
66
- join(authConfigDir, importName + '.js'),
67
- join(authConfigDir, importName + '.mjs'),
68
- join(authConfigDir, importName + '.cjs'),
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 (importError) {
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 (resolveError) {
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', (req, res) => {
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 (error) {
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 (req, res) => {
244
+ router.get('/api/config', async (_req, res) => {
248
245
  let databaseType = 'unknown';
249
- const configPath = await findAuthConfigPath();
250
- if (configPath) {
251
- const content = readFileSync(configPath, 'utf-8');
252
- if (content.includes('drizzleAdapter')) {
253
- databaseType = 'Drizzle';
254
- }
255
- else if (content.includes('prismaAdapter')) {
256
- databaseType = 'Prisma';
257
- }
258
- else if (content.includes('better-sqlite3') || content.includes('new Database(')) {
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
- let type = authConfig.database?.type || authConfig.database?.adapter || 'unknown';
264
- if (type && type !== 'unknown') {
265
- type = type.charAt(0).toUpperCase() + type.slice(1);
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 || 'unknown',
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
- ? Object.entries(authConfig.socialProviders).map(([provider, config]) => ({
299
- type: provider,
300
- clientId: config.clientId,
301
- clientSecret: config.clientSecret,
302
- redirectUri: config.redirectUri,
303
- ...config,
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 (req, res) => {
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 (error) {
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 (req, res) => {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (req, res) => {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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 (error) {
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,28 +809,40 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
818
809
  };
819
810
  res.json({ success: true, organization: transformedOrganization });
820
811
  }
821
- catch (error) {
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();
833
823
  if (adapter && typeof adapter.findMany === 'function') {
834
- const allUsers = await adapter.findMany({ model: 'user', limit: limit });
824
+ // If limit is very high (like 10000), fetch all users without pagination
825
+ const shouldPaginate = limit < 1000;
826
+ const fetchLimit = shouldPaginate ? limit : undefined;
827
+ const allUsers = await adapter.findMany({
828
+ model: 'user',
829
+ limit: fetchLimit
830
+ });
835
831
  let filteredUsers = allUsers || [];
836
832
  if (search) {
837
833
  filteredUsers = filteredUsers.filter((user) => user.email?.toLowerCase().includes(search.toLowerCase()) ||
838
834
  user.name?.toLowerCase().includes(search.toLowerCase()));
839
835
  }
840
- const startIndex = (page - 1) * limit;
841
- const endIndex = startIndex + limit;
842
- const paginatedUsers = filteredUsers.slice(startIndex, endIndex);
836
+ let paginatedUsers;
837
+ if (shouldPaginate) {
838
+ const startIndex = (page - 1) * limit;
839
+ const endIndex = startIndex + limit;
840
+ paginatedUsers = filteredUsers.slice(startIndex, endIndex);
841
+ }
842
+ else {
843
+ // Return all users if limit is high
844
+ paginatedUsers = filteredUsers;
845
+ }
843
846
  const transformedUsers = paginatedUsers.map((user) => ({
844
847
  id: user.id,
845
848
  email: user.email,
@@ -848,14 +851,16 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
848
851
  emailVerified: user.emailVerified,
849
852
  createdAt: user.createdAt,
850
853
  updatedAt: user.updatedAt,
854
+ role: user.role,
855
+ banned: user.banned,
856
+ banReason: user.banReason,
857
+ banExpires: user.banExpires,
851
858
  }));
852
859
  res.json({ users: transformedUsers });
853
860
  return;
854
861
  }
855
862
  }
856
- catch (adapterError) {
857
- console.error('Error fetching users from adapter:', adapterError);
858
- }
863
+ catch (_adapterError) { }
859
864
  const result = await getAuthData(authConfig, 'users', { page, limit, search }, configPath);
860
865
  const transformedUsers = (result.data || []).map((user) => ({
861
866
  id: user.id,
@@ -865,33 +870,35 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
865
870
  emailVerified: user.emailVerified,
866
871
  createdAt: user.createdAt,
867
872
  updatedAt: user.updatedAt,
873
+ role: user.role,
874
+ banned: user.banned,
875
+ banReason: user.banReason,
876
+ banExpires: user.banExpires,
877
+ ...user,
868
878
  }));
869
879
  res.json({ users: transformedUsers });
870
880
  }
871
- catch (error) {
872
- console.error('Error fetching users:', error);
881
+ catch (_error) {
873
882
  res.status(500).json({ error: 'Failed to fetch users' });
874
883
  }
875
884
  });
876
885
  router.get('/api/sessions', async (req, res) => {
877
886
  try {
878
- const page = parseInt(req.query.page) || 1;
879
- const limit = parseInt(req.query.limit) || 20;
887
+ const page = parseInt(req.query.page, 10) || 1;
888
+ const limit = parseInt(req.query.limit, 10) || 20;
880
889
  const sessions = await getAuthData(authConfig, 'sessions', { page, limit }, configPath);
881
890
  res.json(sessions);
882
891
  }
883
- catch (error) {
884
- console.error('Error fetching sessions:', error);
892
+ catch (_error) {
885
893
  res.status(500).json({ error: 'Failed to fetch sessions' });
886
894
  }
887
895
  });
888
- router.get('/api/providers', async (req, res) => {
896
+ router.get('/api/providers', async (_req, res) => {
889
897
  try {
890
898
  const providers = await getAuthData(authConfig, 'providers', undefined, configPath);
891
899
  res.json(providers);
892
900
  }
893
- catch (error) {
894
- console.error('Error fetching providers:', error);
901
+ catch (_error) {
895
902
  res.status(500).json({ error: 'Failed to fetch providers' });
896
903
  }
897
904
  });
@@ -901,12 +908,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
901
908
  await getAuthData(authConfig, 'deleteUser', { id }, configPath);
902
909
  res.json({ success: true });
903
910
  }
904
- catch (error) {
905
- console.error('Error deleting user:', error);
911
+ catch (_error) {
906
912
  res.status(500).json({ error: 'Failed to delete user' });
907
913
  }
908
914
  });
909
- router.get('/api/plugins', async (req, res) => {
915
+ router.get('/api/plugins', async (_req, res) => {
910
916
  try {
911
917
  const authConfigPath = configPath
912
918
  ? join(process.cwd(), configPath)
@@ -923,7 +929,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
923
929
  try {
924
930
  authModule = await safeImportAuthConfig(authConfigPath);
925
931
  }
926
- catch (importError) {
932
+ catch (_importError) {
927
933
  // Fallback: read file content directly
928
934
  const content = readFileSync(authConfigPath, 'utf-8');
929
935
  authModule = {
@@ -956,14 +962,13 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
956
962
  totalPlugins: pluginInfo.length,
957
963
  });
958
964
  }
959
- catch (error) {
960
- console.error('Error importing auth config:', error);
965
+ catch (_error) {
961
966
  try {
962
- const { readFileSync } = await import('fs');
967
+ const { readFileSync } = await import('node:fs');
963
968
  const content = readFileSync(authConfigPath, 'utf-8');
964
969
  const { extractBetterAuthConfig } = await import('./config');
965
970
  const config = extractBetterAuthConfig(content);
966
- if (config && config.plugins) {
971
+ if (config?.plugins) {
967
972
  const pluginInfo = config.plugins.map((plugin) => ({
968
973
  id: plugin.id || 'unknown',
969
974
  name: plugin.name || plugin.id || 'unknown',
@@ -979,9 +984,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
979
984
  });
980
985
  }
981
986
  }
982
- catch (fallbackError) {
983
- console.error('Fallback extraction also failed:', fallbackError);
984
- }
987
+ catch (_fallbackError) { }
985
988
  res.json({
986
989
  plugins: [],
987
990
  error: 'Failed to load auth config - import failed and regex extraction unavailable',
@@ -989,12 +992,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
989
992
  });
990
993
  }
991
994
  }
992
- catch (error) {
993
- console.error('Error fetching plugins:', error);
995
+ catch (_error) {
994
996
  res.status(500).json({ error: 'Failed to fetch plugins' });
995
997
  }
996
998
  });
997
- router.get('/api/database/info', async (req, res) => {
999
+ router.get('/api/database/info', async (_req, res) => {
998
1000
  try {
999
1001
  const authConfigPath = configPath || (await findAuthConfigPath());
1000
1002
  if (!authConfigPath) {
@@ -1020,14 +1022,13 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1020
1022
  configPath: authConfigPath,
1021
1023
  });
1022
1024
  }
1023
- catch (error) {
1024
- console.error('Error getting database info:', error);
1025
+ catch (_error) {
1025
1026
  try {
1026
- const { readFileSync } = await import('fs');
1027
+ const { readFileSync } = await import('node:fs');
1027
1028
  const content = readFileSync(authConfigPath, 'utf-8');
1028
1029
  const { extractBetterAuthConfig } = await import('./config');
1029
1030
  const config = extractBetterAuthConfig(content);
1030
- if (config && config.database) {
1031
+ if (config?.database) {
1031
1032
  return res.json({
1032
1033
  database: config.database,
1033
1034
  configPath: authConfigPath,
@@ -1035,9 +1036,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1035
1036
  });
1036
1037
  }
1037
1038
  }
1038
- catch (fallbackError) {
1039
- console.error('Fallback extraction also failed:', fallbackError);
1040
- }
1039
+ catch (_fallbackError) { }
1041
1040
  res.json({
1042
1041
  database: null,
1043
1042
  error: 'Failed to load auth config - import failed and regex extraction unavailable',
@@ -1045,11 +1044,221 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1045
1044
  });
1046
1045
  }
1047
1046
  }
1048
- catch (error) {
1049
- console.error('Error fetching database info:', error);
1047
+ catch (_error) {
1050
1048
  res.status(500).json({ error: 'Failed to fetch database info' });
1051
1049
  }
1052
1050
  });
1051
+ // Database Detection endpoint - Auto-detect database from installed packages
1052
+ router.get('/api/database/detect', async (_req, res) => {
1053
+ try {
1054
+ const detectedDb = await detectDatabaseWithDialect();
1055
+ if (detectedDb) {
1056
+ res.json({
1057
+ success: true,
1058
+ database: {
1059
+ name: detectedDb.name,
1060
+ version: detectedDb.version,
1061
+ dialect: detectedDb.dialect,
1062
+ adapter: detectedDb.adapter,
1063
+ displayName: detectedDb.name.charAt(0).toUpperCase() + detectedDb.name.slice(1),
1064
+ },
1065
+ });
1066
+ }
1067
+ else {
1068
+ res.json({
1069
+ success: false,
1070
+ database: null,
1071
+ message: 'No supported database packages detected',
1072
+ });
1073
+ }
1074
+ }
1075
+ catch (error) {
1076
+ res.status(500).json({
1077
+ success: false,
1078
+ error: 'Failed to detect database',
1079
+ message: error instanceof Error ? error.message : 'Unknown error',
1080
+ });
1081
+ }
1082
+ });
1083
+ router.get('/api/db', async (_req, res) => {
1084
+ try {
1085
+ const detectedDb = await detectDatabaseWithDialect();
1086
+ if (detectedDb) {
1087
+ res.json({
1088
+ success: true,
1089
+ name: detectedDb.name,
1090
+ version: detectedDb.version,
1091
+ dialect: detectedDb.dialect,
1092
+ adapter: detectedDb.adapter,
1093
+ displayName: detectedDb.name.charAt(0).toUpperCase() + detectedDb.name.slice(1),
1094
+ autoDetected: true,
1095
+ });
1096
+ }
1097
+ else {
1098
+ res.json({
1099
+ success: false,
1100
+ name: 'unknown',
1101
+ version: 'unknown',
1102
+ dialect: 'unknown',
1103
+ adapter: 'unknown',
1104
+ displayName: 'Unknown',
1105
+ autoDetected: false,
1106
+ message: 'No supported database packages detected',
1107
+ });
1108
+ }
1109
+ }
1110
+ catch (error) {
1111
+ res.status(500).json({
1112
+ success: false,
1113
+ error: 'Failed to get database information',
1114
+ message: error instanceof Error ? error.message : 'Unknown error',
1115
+ });
1116
+ }
1117
+ });
1118
+ router.post('/api/admin/ban-user', async (req, res) => {
1119
+ try {
1120
+ const authConfigPath = configPath || (await findAuthConfigPath());
1121
+ if (!authConfigPath) {
1122
+ return res.status(400).json({
1123
+ success: false,
1124
+ error: 'No auth config found',
1125
+ });
1126
+ }
1127
+ const { getConfig } = await import('./config.js');
1128
+ const auth = await getConfig({
1129
+ cwd: process.cwd(),
1130
+ configPath: authConfigPath,
1131
+ shouldThrowOnError: false,
1132
+ });
1133
+ if (!auth) {
1134
+ return res.status(400).json({
1135
+ success: false,
1136
+ error: 'Failed to load auth config',
1137
+ });
1138
+ }
1139
+ const plugins = auth.plugins || [];
1140
+ const adminPlugin = plugins.find((plugin) => plugin.id === 'admin');
1141
+ if (!adminPlugin) {
1142
+ return res.status(400).json({
1143
+ success: false,
1144
+ error: 'Admin plugin is not enabled. Please enable the admin plugin in your Better Auth configuration.',
1145
+ });
1146
+ }
1147
+ const adapter = await getAuthAdapterWithConfig();
1148
+ if (!adapter || !adapter.update) {
1149
+ return res.status(500).json({
1150
+ success: false,
1151
+ error: 'Auth adapter not available',
1152
+ });
1153
+ }
1154
+ const bannedUser = await adapter.update({
1155
+ model: 'user',
1156
+ where: [{ field: 'id', value: req.body.userId }],
1157
+ update: { banned: true, banReason: req.body.banReason, banExpires: req.body.banExpires },
1158
+ });
1159
+ res.json({ success: true, user: bannedUser });
1160
+ }
1161
+ catch (error) {
1162
+ res.status(500).json({
1163
+ success: false,
1164
+ error: 'Failed to ban user',
1165
+ message: error instanceof Error ? error.message : 'Unknown error',
1166
+ });
1167
+ }
1168
+ });
1169
+ router.post('/api/admin/unban-user', async (req, res) => {
1170
+ try {
1171
+ const authConfigPath = configPath || (await findAuthConfigPath());
1172
+ if (!authConfigPath) {
1173
+ return res.status(400).json({
1174
+ success: false,
1175
+ error: 'No auth config found',
1176
+ });
1177
+ }
1178
+ const { getConfig } = await import('./config.js');
1179
+ const auth = await getConfig({
1180
+ cwd: process.cwd(),
1181
+ configPath: authConfigPath,
1182
+ shouldThrowOnError: false,
1183
+ });
1184
+ if (!auth) {
1185
+ return res.status(400).json({
1186
+ success: false,
1187
+ error: 'Failed to load auth config',
1188
+ });
1189
+ }
1190
+ const plugins = auth.plugins || [];
1191
+ const adminPlugin = plugins.find((plugin) => plugin.id === 'admin');
1192
+ if (!adminPlugin) {
1193
+ return res.status(400).json({
1194
+ success: false,
1195
+ error: 'Admin plugin is not enabled. Please enable the admin plugin in your Better Auth configuration.',
1196
+ });
1197
+ }
1198
+ const adapter = await getAuthAdapterWithConfig();
1199
+ if (!adapter || !adapter.update) {
1200
+ return res.status(500).json({
1201
+ success: false,
1202
+ error: 'Auth adapter not available',
1203
+ });
1204
+ }
1205
+ const unbannedUser = await adapter.update({
1206
+ model: 'user',
1207
+ where: [{ field: 'id', value: req.body.userId }],
1208
+ update: { banned: false, banReason: null, banExpires: null },
1209
+ });
1210
+ res.json({ success: true, user: unbannedUser });
1211
+ }
1212
+ catch (error) {
1213
+ res.status(500).json({
1214
+ success: false,
1215
+ error: 'Failed to unban user',
1216
+ message: error instanceof Error ? error.message : 'Unknown error',
1217
+ });
1218
+ }
1219
+ });
1220
+ router.get('/api/admin/status', async (_req, res) => {
1221
+ try {
1222
+ const authConfigPath = configPath || (await findAuthConfigPath());
1223
+ if (!authConfigPath) {
1224
+ return res.json({
1225
+ enabled: false,
1226
+ error: 'No auth config found',
1227
+ configPath: null,
1228
+ });
1229
+ }
1230
+ const { getConfig } = await import('./config.js');
1231
+ const betterAuthConfig = await getConfig({
1232
+ cwd: process.cwd(),
1233
+ configPath: authConfigPath,
1234
+ shouldThrowOnError: false,
1235
+ });
1236
+ if (!betterAuthConfig) {
1237
+ return res.json({
1238
+ enabled: false,
1239
+ error: 'Failed to load auth config',
1240
+ configPath: authConfigPath,
1241
+ });
1242
+ }
1243
+ const plugins = betterAuthConfig.plugins || [];
1244
+ const adminPlugin = plugins.find((plugin) => plugin.id === 'admin');
1245
+ res.json({
1246
+ enabled: !!adminPlugin,
1247
+ configPath: authConfigPath,
1248
+ adminPlugin: adminPlugin || null,
1249
+ message: adminPlugin
1250
+ ? 'Admin plugin is enabled. Use Better Auth admin endpoints directly for ban/unban functionality.'
1251
+ : 'Admin plugin is not enabled. Please enable the admin plugin in your Better Auth configuration.',
1252
+ });
1253
+ }
1254
+ catch (error) {
1255
+ res.status(500).json({
1256
+ enabled: false,
1257
+ error: 'Failed to check admin status',
1258
+ message: error instanceof Error ? error.message : 'Unknown error',
1259
+ });
1260
+ }
1261
+ });
1053
1262
  // Database Schema Visualization endpoint
1054
1263
  // Schema definitions for different Better Auth plugins
1055
1264
  const BASE_SCHEMA = {
@@ -1664,15 +1873,14 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1664
1873
  selectedPlugins: selectedPlugins,
1665
1874
  });
1666
1875
  }
1667
- catch (error) {
1668
- console.error('Error fetching database schema:', error);
1876
+ catch (_error) {
1669
1877
  res.status(500).json({
1670
1878
  success: false,
1671
1879
  error: 'Failed to fetch database schema',
1672
1880
  });
1673
1881
  }
1674
1882
  });
1675
- router.get('/api/plugins/teams/status', async (req, res) => {
1883
+ router.get('/api/plugins/teams/status', async (_req, res) => {
1676
1884
  try {
1677
1885
  const authConfigPath = configPath || (await findAuthConfigPath());
1678
1886
  if (!authConfigPath) {
@@ -1710,11 +1918,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1710
1918
  }
1711
1919
  }
1712
1920
  try {
1713
- const { readFileSync } = await import('fs');
1921
+ const { readFileSync } = await import('node:fs');
1714
1922
  const content = readFileSync(authConfigPath, 'utf-8');
1715
1923
  const { extractBetterAuthConfig } = await import('./config.js');
1716
1924
  const config = extractBetterAuthConfig(content);
1717
- if (config && config.plugins) {
1925
+ if (config?.plugins) {
1718
1926
  const organizationPlugin = config.plugins.find((plugin) => plugin.id === 'organization');
1719
1927
  const teamsEnabled = organizationPlugin?.teams?.enabled === true;
1720
1928
  return res.json({
@@ -1725,22 +1933,18 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1725
1933
  });
1726
1934
  }
1727
1935
  }
1728
- catch (fallbackError) {
1729
- console.error('Fallback extraction also failed:', fallbackError);
1730
- }
1936
+ catch (_fallbackError) { }
1731
1937
  res.json({
1732
1938
  enabled: false,
1733
1939
  error: 'Failed to load auth config - getConfig failed and regex extraction unavailable',
1734
1940
  configPath: authConfigPath,
1735
1941
  });
1736
1942
  }
1737
- catch (error) {
1738
- console.error('Error checking teams plugin:', error);
1943
+ catch (_error) {
1739
1944
  res.status(500).json({ error: 'Failed to check teams status' });
1740
1945
  }
1741
1946
  }
1742
- catch (error) {
1743
- console.error('Error checking teams status:', error);
1947
+ catch (_error) {
1744
1948
  res.status(500).json({ error: 'Failed to check teams status' });
1745
1949
  }
1746
1950
  });
@@ -1771,14 +1975,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1771
1975
  res.json({ success: true, invitations: transformedInvitations });
1772
1976
  return;
1773
1977
  }
1774
- catch (error) {
1775
- console.error('Error fetching invitations from adapter:', error);
1776
- }
1978
+ catch (_error) { }
1777
1979
  }
1778
1980
  res.json({ success: true, invitations: [] });
1779
1981
  }
1780
- catch (error) {
1781
- console.error('Error fetching invitations:', error);
1982
+ catch (_error) {
1782
1983
  res.status(500).json({ error: 'Failed to fetch invitations' });
1783
1984
  }
1784
1985
  });
@@ -1821,23 +2022,19 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1821
2022
  }
1822
2023
  return null;
1823
2024
  }
1824
- catch (error) {
1825
- console.error('Error fetching user for member:', error);
2025
+ catch (_error) {
1826
2026
  return null;
1827
2027
  }
1828
2028
  }));
1829
- const validMembers = membersWithUsers.filter((member) => member && member.user);
2029
+ const validMembers = membersWithUsers.filter((member) => member?.user);
1830
2030
  res.json({ success: true, members: validMembers });
1831
2031
  return;
1832
2032
  }
1833
- catch (error) {
1834
- console.error('Error fetching members from adapter:', error);
1835
- }
2033
+ catch (_error) { }
1836
2034
  }
1837
2035
  res.json({ success: true, members: [] });
1838
2036
  }
1839
- catch (error) {
1840
- console.error('Error fetching members:', error);
2037
+ catch (_error) {
1841
2038
  res.status(500).json({ error: 'Failed to fetch members' });
1842
2039
  }
1843
2040
  });
@@ -1911,8 +2108,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1911
2108
  results,
1912
2109
  });
1913
2110
  }
1914
- catch (error) {
1915
- console.error('Error seeding members:', error);
2111
+ catch (_error) {
1916
2112
  res.status(500).json({ error: 'Failed to seed members' });
1917
2113
  }
1918
2114
  });
@@ -1983,8 +2179,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1983
2179
  results,
1984
2180
  });
1985
2181
  }
1986
- catch (error) {
1987
- console.error('Error seeding teams:', error);
2182
+ catch (_error) {
1988
2183
  res.status(500).json({ error: 'Failed to seed teams' });
1989
2184
  }
1990
2185
  });
@@ -2004,8 +2199,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2004
2199
  });
2005
2200
  res.json({ success: true });
2006
2201
  }
2007
- catch (error) {
2008
- console.error('Error removing member:', error);
2202
+ catch (_error) {
2009
2203
  res.status(500).json({ error: 'Failed to remove member' });
2010
2204
  }
2011
2205
  });
@@ -2029,8 +2223,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2029
2223
  });
2030
2224
  res.json({ success: true });
2031
2225
  }
2032
- catch (error) {
2033
- console.error('Error resending invitation:', error);
2226
+ catch (_error) {
2034
2227
  res.status(500).json({ error: 'Failed to resend invitation' });
2035
2228
  }
2036
2229
  });
@@ -2054,8 +2247,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2054
2247
  });
2055
2248
  res.json({ success: true });
2056
2249
  }
2057
- catch (error) {
2058
- console.error('Error cancelling invitation:', error);
2250
+ catch (_error) {
2059
2251
  res.status(500).json({ error: 'Failed to cancel invitation' });
2060
2252
  }
2061
2253
  });
@@ -2100,8 +2292,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2100
2292
  });
2101
2293
  res.json({ success: true, invitation });
2102
2294
  }
2103
- catch (error) {
2104
- console.error('Error creating invitation:', error);
2295
+ catch (_error) {
2105
2296
  res.status(500).json({ error: 'Failed to create invitation' });
2106
2297
  }
2107
2298
  });
@@ -2138,14 +2329,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2138
2329
  res.json({ success: true, teams: transformedTeams });
2139
2330
  return;
2140
2331
  }
2141
- catch (error) {
2142
- console.error('Error fetching teams from adapter:', error);
2143
- }
2332
+ catch (_error) { }
2144
2333
  }
2145
2334
  res.json({ success: true, teams: [] });
2146
2335
  }
2147
- catch (error) {
2148
- console.error('Error fetching teams:', error);
2336
+ catch (_error) {
2149
2337
  res.status(500).json({ error: 'Failed to fetch teams' });
2150
2338
  }
2151
2339
  });
@@ -2182,8 +2370,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2182
2370
  });
2183
2371
  res.json({ success: true, team });
2184
2372
  }
2185
- catch (error) {
2186
- console.error('Error creating team:', error);
2373
+ catch (_error) {
2187
2374
  res.status(500).json({ error: 'Failed to create team' });
2188
2375
  }
2189
2376
  });
@@ -2226,23 +2413,19 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2226
2413
  }
2227
2414
  return null;
2228
2415
  }
2229
- catch (error) {
2230
- console.error('Error fetching user for team member:', error);
2416
+ catch (_error) {
2231
2417
  return null;
2232
2418
  }
2233
2419
  }));
2234
- const validMembers = membersWithUsers.filter((member) => member && member.user);
2420
+ const validMembers = membersWithUsers.filter((member) => member?.user);
2235
2421
  res.json({ success: true, members: validMembers });
2236
2422
  return;
2237
2423
  }
2238
- catch (error) {
2239
- console.error('Error fetching team members from adapter:', error);
2240
- }
2424
+ catch (_error) { }
2241
2425
  }
2242
2426
  res.json({ success: true, members: [] });
2243
2427
  }
2244
- catch (error) {
2245
- console.error('Error fetching team members:', error);
2428
+ catch (_error) {
2246
2429
  res.status(500).json({ error: 'Failed to fetch team members' });
2247
2430
  }
2248
2431
  });
@@ -2285,8 +2468,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2285
2468
  results,
2286
2469
  });
2287
2470
  }
2288
- catch (error) {
2289
- console.error('Error adding team members:', error);
2471
+ catch (_error) {
2290
2472
  res.status(500).json({ error: 'Failed to add team members' });
2291
2473
  }
2292
2474
  });
@@ -2303,8 +2485,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2303
2485
  });
2304
2486
  res.json({ success: true });
2305
2487
  }
2306
- catch (error) {
2307
- console.error('Error removing team member:', error);
2488
+ catch (_error) {
2308
2489
  res.status(500).json({ error: 'Failed to remove team member' });
2309
2490
  }
2310
2491
  });
@@ -2332,8 +2513,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2332
2513
  });
2333
2514
  res.json({ success: true, team: updatedTeam });
2334
2515
  }
2335
- catch (error) {
2336
- console.error('Error updating team:', error);
2516
+ catch (_error) {
2337
2517
  res.status(500).json({ error: 'Failed to update team' });
2338
2518
  }
2339
2519
  });
@@ -2353,12 +2533,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2353
2533
  });
2354
2534
  res.json({ success: true });
2355
2535
  }
2356
- catch (error) {
2357
- console.error('Error deleting team:', error);
2536
+ catch (_error) {
2358
2537
  res.status(500).json({ error: 'Failed to delete team' });
2359
2538
  }
2360
2539
  });
2361
- router.get('/api/plugins/organization/status', async (req, res) => {
2540
+ router.get('/api/plugins/organization/status', async (_req, res) => {
2362
2541
  try {
2363
2542
  const authConfigPath = configPath || (await findAuthConfigPath());
2364
2543
  if (!authConfigPath) {
@@ -2386,11 +2565,11 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2386
2565
  });
2387
2566
  }
2388
2567
  try {
2389
- const { readFileSync } = await import('fs');
2568
+ const { readFileSync } = await import('node:fs');
2390
2569
  const content = readFileSync(authConfigPath, 'utf-8');
2391
2570
  const { extractBetterAuthConfig } = await import('./config.js');
2392
2571
  const config = extractBetterAuthConfig(content);
2393
- if (config && config.plugins) {
2572
+ if (config?.plugins) {
2394
2573
  const hasOrganizationPlugin = config.plugins.find((plugin) => plugin.id === 'organization');
2395
2574
  return res.json({
2396
2575
  enabled: !!hasOrganizationPlugin,
@@ -2401,79 +2580,41 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2401
2580
  });
2402
2581
  }
2403
2582
  }
2404
- catch (fallbackError) {
2405
- console.error('Fallback extraction also failed:', fallbackError);
2406
- }
2583
+ catch (_fallbackError) { }
2407
2584
  res.json({
2408
2585
  enabled: false,
2409
2586
  error: 'Failed to load auth config - getConfig failed and regex extraction unavailable',
2410
2587
  configPath: authConfigPath,
2411
2588
  });
2412
2589
  }
2413
- catch (error) {
2414
- console.error('Error checking organization plugin:', error);
2590
+ catch (_error) {
2415
2591
  res.status(500).json({ error: 'Failed to check plugin status' });
2416
2592
  }
2417
2593
  }
2418
- catch (error) {
2419
- console.error('Error checking plugin status:', error);
2594
+ catch (_error) {
2420
2595
  res.status(500).json({ error: 'Failed to check plugin status' });
2421
2596
  }
2422
2597
  });
2423
2598
  router.get('/api/organizations', async (req, res) => {
2424
2599
  try {
2425
- const page = parseInt(req.query.page) || 1;
2426
- const limit = parseInt(req.query.limit) || 20;
2600
+ const page = parseInt(req.query.page, 10) || 1;
2601
+ const limit = parseInt(req.query.limit, 10) || 20;
2427
2602
  const search = req.query.search;
2428
2603
  try {
2429
2604
  const adapter = await getAuthAdapterWithConfig();
2430
2605
  if (adapter && typeof adapter.findMany === 'function') {
2431
- const allOrganizations = await adapter.findMany({ model: 'organization' });
2432
- let filteredOrganizations = allOrganizations || [];
2433
- if (search) {
2434
- filteredOrganizations = filteredOrganizations.filter((org) => org.name?.toLowerCase().includes(search.toLowerCase()) ||
2435
- org.slug?.toLowerCase().includes(search.toLowerCase()));
2436
- }
2437
- const startIndex = (page - 1) * limit;
2438
- const endIndex = startIndex + limit;
2439
- const paginatedOrganizations = filteredOrganizations.slice(startIndex, endIndex);
2440
- const transformedOrganizations = paginatedOrganizations.map((org) => ({
2441
- id: org.id,
2442
- name: org.name,
2443
- slug: org.slug,
2444
- metadata: org.metadata,
2445
- createdAt: org.createdAt,
2446
- updatedAt: org.updatedAt,
2447
- }));
2448
- res.json({ organizations: transformedOrganizations });
2449
- return;
2606
+ const allOrganizations = await adapter.findMany({
2607
+ model: 'organization',
2608
+ limit: limit
2609
+ });
2610
+ res.json({ organizations: allOrganizations });
2450
2611
  }
2451
2612
  }
2452
- catch (adapterError) {
2453
- console.error('Error fetching organizations from adapter:', adapterError);
2613
+ catch (_error) {
2614
+ res.status(500).json({ error: 'Failed to fetch organizations' });
2454
2615
  }
2455
- const mockOrganizations = [
2456
- {
2457
- id: 'org_1',
2458
- name: 'Acme Corp',
2459
- slug: 'acme-corp',
2460
- metadata: { status: 'active' },
2461
- createdAt: new Date().toISOString(),
2462
- updatedAt: new Date().toISOString(),
2463
- },
2464
- {
2465
- id: 'org_2',
2466
- name: 'Tech Solutions',
2467
- slug: 'tech-solutions',
2468
- metadata: { status: 'active' },
2469
- createdAt: new Date().toISOString(),
2470
- updatedAt: new Date().toISOString(),
2471
- },
2472
- ];
2473
- res.json({ organizations: mockOrganizations });
2474
2616
  }
2475
- catch (error) {
2476
- console.error('Error fetching organizations:', error);
2617
+ catch (_error) {
2477
2618
  res.status(500).json({ error: 'Failed to fetch organizations' });
2478
2619
  }
2479
2620
  });
@@ -2493,8 +2634,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2493
2634
  const organization = await adapter.createOrganization(orgData);
2494
2635
  res.json({ success: true, organization });
2495
2636
  }
2496
- catch (error) {
2497
- console.error('Error creating organization:', error);
2637
+ catch (_error) {
2498
2638
  res.status(500).json({ error: 'Failed to create organization' });
2499
2639
  }
2500
2640
  });
@@ -2524,8 +2664,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2524
2664
  });
2525
2665
  res.json({ success: true, organization: updatedOrg });
2526
2666
  }
2527
- catch (error) {
2528
- console.error('Error updating organization:', error);
2667
+ catch (_error) {
2529
2668
  res.status(500).json({ error: 'Failed to update organization' });
2530
2669
  }
2531
2670
  });
@@ -2542,8 +2681,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2542
2681
  });
2543
2682
  res.json({ success: true, organization: deletedOrg });
2544
2683
  }
2545
- catch (error) {
2546
- console.error('Error deleting organization:', error);
2684
+ catch (_error) {
2547
2685
  res.status(500).json({ error: 'Failed to delete organization' });
2548
2686
  }
2549
2687
  });
@@ -2557,8 +2695,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2557
2695
  const user = await adapter.createUser(userData);
2558
2696
  res.json({ success: true, user });
2559
2697
  }
2560
- catch (error) {
2561
- console.error('Error creating user:', error);
2698
+ catch (_error) {
2562
2699
  res.status(500).json({ error: 'Failed to create user' });
2563
2700
  }
2564
2701
  });
@@ -2569,8 +2706,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2569
2706
  const updatedUser = await getAuthData(authConfig, 'updateUser', { id, userData }, configPath);
2570
2707
  res.json({ success: true, user: updatedUser });
2571
2708
  }
2572
- catch (error) {
2573
- console.error('Error updating user:', error);
2709
+ catch (_error) {
2574
2710
  res.status(500).json({ error: 'Failed to update user' });
2575
2711
  }
2576
2712
  });
@@ -2613,8 +2749,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2613
2749
  results,
2614
2750
  });
2615
2751
  }
2616
- catch (error) {
2617
- console.error('Error seeding users:', error);
2752
+ catch (_error) {
2618
2753
  res.status(500).json({ error: 'Failed to seed users' });
2619
2754
  }
2620
2755
  });
@@ -2629,7 +2764,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2629
2764
  try {
2630
2765
  user = await createMockUser(adapter, 1);
2631
2766
  }
2632
- catch (error) {
2767
+ catch (_error) {
2633
2768
  return res.status(500).json({ error: 'Failed to create user for session' });
2634
2769
  }
2635
2770
  const results = [];
@@ -2663,8 +2798,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2663
2798
  results,
2664
2799
  });
2665
2800
  }
2666
- catch (error) {
2667
- console.error('Error seeding sessions:', error);
2801
+ catch (_error) {
2668
2802
  res.status(500).json({ error: 'Failed to seed sessions' });
2669
2803
  }
2670
2804
  });
@@ -2718,8 +2852,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2718
2852
  results,
2719
2853
  });
2720
2854
  }
2721
- catch (error) {
2722
- console.error('Error seeding sessions for user:', error);
2855
+ catch (_error) {
2723
2856
  res.status(500).json({ error: 'Failed to seed sessions for user' });
2724
2857
  }
2725
2858
  });
@@ -2734,7 +2867,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2734
2867
  try {
2735
2868
  user = await createMockUser(adapter, 1);
2736
2869
  }
2737
- catch (error) {
2870
+ catch (_error) {
2738
2871
  return res.status(500).json({ error: 'Failed to create user for account' });
2739
2872
  }
2740
2873
  const results = [];
@@ -2769,8 +2902,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2769
2902
  results,
2770
2903
  });
2771
2904
  }
2772
- catch (error) {
2773
- console.error('Error seeding accounts:', error);
2905
+ catch (_error) {
2774
2906
  res.status(500).json({ error: 'Failed to seed accounts' });
2775
2907
  }
2776
2908
  });
@@ -2812,8 +2944,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2812
2944
  results,
2813
2945
  });
2814
2946
  }
2815
- catch (error) {
2816
- console.error('Error seeding verifications:', error);
2947
+ catch (_error) {
2817
2948
  res.status(500).json({ error: 'Failed to seed verifications' });
2818
2949
  }
2819
2950
  });
@@ -2869,8 +3000,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
2869
3000
  results,
2870
3001
  });
2871
3002
  }
2872
- catch (error) {
2873
- console.error('Error seeding organizations:', error);
3003
+ catch (_error) {
2874
3004
  res.status(500).json({ error: 'Failed to seed organizations' });
2875
3005
  }
2876
3006
  });