better-auth-studio 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +1 -0
  2. package/dist/auth-adapter.d.ts +24 -0
  3. package/dist/auth-adapter.d.ts.map +1 -0
  4. package/dist/auth-adapter.js +481 -0
  5. package/dist/auth-adapter.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +49 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +25 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +308 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/data.d.ts +38 -0
  15. package/dist/data.d.ts.map +1 -0
  16. package/dist/data.js +275 -0
  17. package/dist/data.js.map +1 -0
  18. package/dist/routes.d.ts +3 -0
  19. package/dist/routes.d.ts.map +1 -0
  20. package/dist/routes.js +1490 -0
  21. package/dist/routes.js.map +1 -0
  22. package/dist/studio.d.ts +10 -0
  23. package/dist/studio.d.ts.map +1 -0
  24. package/dist/studio.js +70 -0
  25. package/dist/studio.js.map +1 -0
  26. package/frontend/index.html +13 -0
  27. package/frontend/package-lock.json +4675 -0
  28. package/frontend/package.json +52 -0
  29. package/frontend/pnpm-lock.yaml +4020 -0
  30. package/frontend/postcss.config.js +6 -0
  31. package/frontend/src/App.tsx +36 -0
  32. package/frontend/src/components/CommandPalette.tsx +219 -0
  33. package/frontend/src/components/Layout.tsx +159 -0
  34. package/frontend/src/components/ui/badge.tsx +40 -0
  35. package/frontend/src/components/ui/button.tsx +53 -0
  36. package/frontend/src/components/ui/card.tsx +78 -0
  37. package/frontend/src/components/ui/input.tsx +20 -0
  38. package/frontend/src/components/ui/label.tsx +19 -0
  39. package/frontend/src/components/ui/select.tsx +71 -0
  40. package/frontend/src/index.css +130 -0
  41. package/frontend/src/lib/utils.ts +6 -0
  42. package/frontend/src/main.tsx +10 -0
  43. package/frontend/src/pages/Dashboard.tsx +231 -0
  44. package/frontend/src/pages/OrganizationDetails.tsx +1281 -0
  45. package/frontend/src/pages/Organizations.tsx +874 -0
  46. package/frontend/src/pages/Sessions.tsx +623 -0
  47. package/frontend/src/pages/Settings.tsx +1019 -0
  48. package/frontend/src/pages/TeamDetails.tsx +666 -0
  49. package/frontend/src/pages/Users.tsx +728 -0
  50. package/frontend/tailwind.config.js +75 -0
  51. package/frontend/tsconfig.json +31 -0
  52. package/frontend/tsconfig.node.json +10 -0
  53. package/frontend/vite.config.ts +31 -0
  54. package/package.json +59 -0
  55. package/public/assets/main-C-TXCXVW.css +1 -0
  56. package/public/assets/main-CCzTTP3P.js +296 -0
  57. package/public/index.html +14 -0
  58. package/src/auth-adapter.ts +471 -0
  59. package/src/cli.ts +51 -0
  60. package/src/config.ts +318 -0
  61. package/src/data.ts +351 -0
  62. package/src/routes.ts +1585 -0
  63. package/src/studio.ts +86 -0
  64. package/test-project/README.md +0 -0
  65. package/test-project/better-auth.db +0 -0
  66. package/test-project/better-auth_migrations/2025-08-27T15-55-04.099Z.sql +7 -0
  67. package/test-project/better-auth_migrations/2025-09-04T02-33-19.422Z.sql +7 -0
  68. package/test-project/package.json +29 -0
  69. package/test-project/pnpm-lock.yaml +1728 -0
  70. package/test-project/src/auth.ts +47 -0
  71. package/test-project/src/index.ts +40 -0
  72. package/tsconfig.json +21 -0
package/dist/routes.js ADDED
@@ -0,0 +1,1490 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createRoutes = createRoutes;
37
+ const express_1 = require("express");
38
+ const data_1 = require("./data");
39
+ const auth_adapter_1 = require("./auth-adapter");
40
+ async function findAuthConfigPath() {
41
+ const { join, dirname } = await Promise.resolve().then(() => __importStar(require('path')));
42
+ const { existsSync } = await Promise.resolve().then(() => __importStar(require('fs')));
43
+ const possiblePaths = [
44
+ 'test-project/src/auth.ts',
45
+ 'test-project/src/auth.js',
46
+ 'src/auth.ts',
47
+ 'src/auth.js',
48
+ 'auth.ts',
49
+ 'auth.js'
50
+ ];
51
+ for (const path of possiblePaths) {
52
+ if (existsSync(path)) {
53
+ return join(process.cwd(), path);
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+ function createRoutes(authConfig) {
59
+ const router = (0, express_1.Router)();
60
+ router.get('/api/health', (req, res) => {
61
+ const uptime = process.uptime();
62
+ const hours = Math.floor(uptime / 3600);
63
+ const minutes = Math.floor((uptime % 3600) / 60);
64
+ const seconds = Math.floor(uptime % 60);
65
+ res.json({
66
+ status: 'ok',
67
+ timestamp: new Date().toISOString(),
68
+ system: {
69
+ studioVersion: '1.0.0',
70
+ nodeVersion: process.version,
71
+ platform: process.platform,
72
+ arch: process.arch,
73
+ uptime: `${hours}h ${minutes}m ${seconds}s`,
74
+ memory: {
75
+ used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
76
+ total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
77
+ external: Math.round(process.memoryUsage().external / 1024 / 1024)
78
+ },
79
+ pid: process.pid,
80
+ cwd: process.cwd()
81
+ }
82
+ });
83
+ });
84
+ router.get('/api/config', (req, res) => {
85
+ console.log('Raw authConfig:', JSON.stringify(authConfig, null, 2));
86
+ const config = {
87
+ appName: authConfig.appName || 'Better Auth',
88
+ baseURL: authConfig.baseURL || process.env.BETTER_AUTH_URL,
89
+ basePath: authConfig.basePath || '/api/auth',
90
+ secret: authConfig.secret ? 'Configured' : 'Not set',
91
+ database: {
92
+ type: authConfig.database?.type || 'unknown',
93
+ dialect: authConfig.database?.dialect,
94
+ casing: authConfig.database?.casing || 'camel',
95
+ debugLogs: authConfig.database?.debugLogs || false,
96
+ url: authConfig.database?.url
97
+ },
98
+ emailVerification: {
99
+ sendOnSignUp: authConfig.emailVerification?.sendOnSignUp || false,
100
+ sendOnSignIn: authConfig.emailVerification?.sendOnSignIn || false,
101
+ autoSignInAfterVerification: authConfig.emailVerification?.autoSignInAfterVerification || false,
102
+ expiresIn: authConfig.emailVerification?.expiresIn || 3600
103
+ },
104
+ emailAndPassword: {
105
+ enabled: authConfig.emailAndPassword?.enabled ?? false,
106
+ disableSignUp: authConfig.emailAndPassword?.disableSignUp ?? false,
107
+ requireEmailVerification: authConfig.emailAndPassword?.requireEmailVerification ?? false,
108
+ maxPasswordLength: authConfig.emailAndPassword?.maxPasswordLength ?? 128,
109
+ minPasswordLength: authConfig.emailAndPassword?.minPasswordLength ?? 8,
110
+ resetPasswordTokenExpiresIn: authConfig.emailAndPassword?.resetPasswordTokenExpiresIn ?? 3600,
111
+ autoSignIn: authConfig.emailAndPassword?.autoSignIn ?? true, // defaults to true
112
+ revokeSessionsOnPasswordReset: authConfig.emailAndPassword?.revokeSessionsOnPasswordReset ?? false
113
+ },
114
+ socialProviders: authConfig.socialProviders ?
115
+ Object.entries(authConfig.socialProviders).map(([provider, config]) => ({
116
+ type: provider,
117
+ clientId: config.clientId,
118
+ clientSecret: config.clientSecret,
119
+ redirectUri: config.redirectUri,
120
+ ...config
121
+ })) :
122
+ (authConfig.providers || []),
123
+ user: {
124
+ modelName: authConfig.user?.modelName || 'user',
125
+ changeEmail: {
126
+ enabled: authConfig.user?.changeEmail?.enabled || false
127
+ },
128
+ deleteUser: {
129
+ enabled: authConfig.user?.deleteUser?.enabled || false,
130
+ deleteTokenExpiresIn: authConfig.user?.deleteUser?.deleteTokenExpiresIn || 86400
131
+ }
132
+ },
133
+ session: {
134
+ modelName: authConfig.session?.modelName || 'session',
135
+ expiresIn: authConfig.session?.expiresIn || 604800, // 7 days
136
+ updateAge: authConfig.session?.updateAge || 86400, // 1 day
137
+ disableSessionRefresh: authConfig.session?.disableSessionRefresh || false,
138
+ storeSessionInDatabase: authConfig.session?.storeSessionInDatabase || false,
139
+ preserveSessionInDatabase: authConfig.session?.preserveSessionInDatabase || false,
140
+ cookieCache: {
141
+ enabled: authConfig.session?.cookieCache?.enabled || false,
142
+ maxAge: authConfig.session?.cookieCache?.maxAge || 300
143
+ },
144
+ freshAge: authConfig.session?.freshAge || 86400
145
+ },
146
+ account: {
147
+ modelName: authConfig.account?.modelName || 'account',
148
+ updateAccountOnSignIn: authConfig.account?.updateAccountOnSignIn !== false, // defaults to true
149
+ accountLinking: {
150
+ enabled: authConfig.account?.accountLinking?.enabled !== false, // defaults to true
151
+ trustedProviders: authConfig.account?.accountLinking?.trustedProviders || [],
152
+ allowDifferentEmails: authConfig.account?.accountLinking?.allowDifferentEmails || false,
153
+ allowUnlinkingAll: authConfig.account?.accountLinking?.allowUnlinkingAll || false,
154
+ updateUserInfoOnLink: authConfig.account?.accountLinking?.updateUserInfoOnLink || false
155
+ },
156
+ encryptOAuthTokens: authConfig.account?.encryptOAuthTokens || false
157
+ },
158
+ verification: {
159
+ modelName: authConfig.verification?.modelName || 'verification',
160
+ disableCleanup: authConfig.verification?.disableCleanup || false
161
+ },
162
+ trustedOrigins: Array.isArray(authConfig.trustedOrigins) ? authConfig.trustedOrigins : [],
163
+ rateLimit: {
164
+ enabled: authConfig.rateLimit?.enabled ?? false,
165
+ window: authConfig.rateLimit?.window || 10,
166
+ max: authConfig.rateLimit?.max || 100,
167
+ storage: authConfig.rateLimit?.storage || 'memory',
168
+ modelName: authConfig.rateLimit?.modelName || 'rateLimit'
169
+ },
170
+ advanced: {
171
+ ipAddress: {
172
+ ipAddressHeaders: authConfig.advanced?.ipAddress?.ipAddressHeaders || [],
173
+ disableIpTracking: authConfig.advanced?.ipAddress?.disableIpTracking || false
174
+ },
175
+ useSecureCookies: authConfig.advanced?.useSecureCookies || false,
176
+ disableCSRFCheck: authConfig.advanced?.disableCSRFCheck || false,
177
+ crossSubDomainCookies: {
178
+ enabled: authConfig.advanced?.crossSubDomainCookies?.enabled || false,
179
+ additionalCookies: authConfig.advanced?.crossSubDomainCookies?.additionalCookies || [],
180
+ domain: authConfig.advanced?.crossSubDomainCookies?.domain
181
+ },
182
+ cookies: authConfig.advanced?.cookies || {},
183
+ defaultCookieAttributes: authConfig.advanced?.defaultCookieAttributes || {},
184
+ cookiePrefix: authConfig.advanced?.cookiePrefix,
185
+ database: {
186
+ defaultFindManyLimit: authConfig.advanced?.database?.defaultFindManyLimit || 100,
187
+ useNumberId: authConfig.advanced?.database?.useNumberId || false
188
+ }
189
+ },
190
+ disabledPaths: authConfig.disabledPaths || [],
191
+ telemetry: {
192
+ enabled: authConfig.telemetry?.enabled ?? false,
193
+ debug: authConfig.telemetry?.debug || false
194
+ },
195
+ studio: {
196
+ version: '1.0.0',
197
+ nodeVersion: process.version,
198
+ platform: process.platform,
199
+ uptime: process.uptime()
200
+ }
201
+ };
202
+ console.log('Processed config:', JSON.stringify(config, null, 2));
203
+ res.json(config);
204
+ });
205
+ router.get('/api/stats', async (req, res) => {
206
+ try {
207
+ const stats = await (0, data_1.getAuthData)(authConfig, 'stats');
208
+ res.json(stats);
209
+ }
210
+ catch (error) {
211
+ console.error('Error fetching stats:', error);
212
+ res.status(500).json({ error: 'Failed to fetch statistics' });
213
+ }
214
+ });
215
+ router.get('/api/counts', async (req, res) => {
216
+ try {
217
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
218
+ let userCount = 0;
219
+ let sessionCount = 0;
220
+ let organizationCount = 0;
221
+ if (adapter) {
222
+ try {
223
+ if (typeof adapter.findMany === 'function') {
224
+ const users = await adapter.findMany({ model: 'user', limit: 10000 });
225
+ userCount = users?.length || 0;
226
+ }
227
+ }
228
+ catch (error) {
229
+ console.error('Error fetching user count:', error);
230
+ }
231
+ try {
232
+ if (typeof adapter.findMany === 'function') {
233
+ const sessions = await adapter.findMany({ model: 'session', limit: 10000 });
234
+ sessionCount = sessions?.length || 0;
235
+ }
236
+ }
237
+ catch (error) {
238
+ console.error('Error fetching session count:', error);
239
+ }
240
+ try {
241
+ if (typeof adapter.findMany === 'function') {
242
+ const organizations = await adapter.findMany({ model: 'organization', limit: 10000 });
243
+ organizationCount = organizations?.length || 0;
244
+ }
245
+ }
246
+ catch (error) {
247
+ console.error('Error fetching organization count:', error);
248
+ organizationCount = 0;
249
+ }
250
+ }
251
+ res.json({
252
+ users: userCount,
253
+ sessions: sessionCount,
254
+ organizations: organizationCount
255
+ });
256
+ }
257
+ catch (error) {
258
+ console.error('Error fetching counts:', error);
259
+ res.status(500).json({ error: 'Failed to fetch counts' });
260
+ }
261
+ });
262
+ router.get('/api/users', async (req, res) => {
263
+ try {
264
+ const page = parseInt(req.query.page) || 1;
265
+ const limit = parseInt(req.query.limit) || 20;
266
+ const search = req.query.search;
267
+ try {
268
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
269
+ if (adapter && typeof adapter.findMany === 'function') {
270
+ const allUsers = await adapter.findMany({ model: 'user', limit: limit });
271
+ console.log('Found users via findMany:', allUsers?.length || 0);
272
+ let filteredUsers = allUsers || [];
273
+ if (search) {
274
+ filteredUsers = filteredUsers.filter((user) => user.email?.toLowerCase().includes(search.toLowerCase()) ||
275
+ user.name?.toLowerCase().includes(search.toLowerCase()));
276
+ }
277
+ const startIndex = (page - 1) * limit;
278
+ const endIndex = startIndex + limit;
279
+ const paginatedUsers = filteredUsers.slice(startIndex, endIndex);
280
+ const transformedUsers = paginatedUsers.map((user) => ({
281
+ id: user.id,
282
+ email: user.email,
283
+ name: user.name,
284
+ image: user.image,
285
+ emailVerified: user.emailVerified,
286
+ createdAt: user.createdAt,
287
+ updatedAt: user.updatedAt,
288
+ }));
289
+ res.json({ users: transformedUsers });
290
+ return;
291
+ }
292
+ }
293
+ catch (adapterError) {
294
+ console.error('Error fetching users from adapter:', adapterError);
295
+ }
296
+ const result = await (0, data_1.getAuthData)(authConfig, 'users', { page, limit, search });
297
+ const transformedUsers = (result.data || []).map((user) => ({
298
+ id: user.id,
299
+ email: user.email,
300
+ name: user.name,
301
+ image: user.image,
302
+ emailVerified: user.emailVerified,
303
+ createdAt: user.createdAt,
304
+ updatedAt: user.updatedAt,
305
+ }));
306
+ res.json({ users: transformedUsers });
307
+ }
308
+ catch (error) {
309
+ console.error('Error fetching users:', error);
310
+ res.status(500).json({ error: 'Failed to fetch users' });
311
+ }
312
+ });
313
+ router.get('/api/sessions', async (req, res) => {
314
+ try {
315
+ const page = parseInt(req.query.page) || 1;
316
+ const limit = parseInt(req.query.limit) || 20;
317
+ const sessions = await (0, data_1.getAuthData)(authConfig, 'sessions', { page, limit });
318
+ res.json(sessions);
319
+ }
320
+ catch (error) {
321
+ console.error('Error fetching sessions:', error);
322
+ res.status(500).json({ error: 'Failed to fetch sessions' });
323
+ }
324
+ });
325
+ router.get('/api/providers', async (req, res) => {
326
+ try {
327
+ const providers = await (0, data_1.getAuthData)(authConfig, 'providers');
328
+ res.json(providers);
329
+ }
330
+ catch (error) {
331
+ console.error('Error fetching providers:', error);
332
+ res.status(500).json({ error: 'Failed to fetch providers' });
333
+ }
334
+ });
335
+ router.delete('/api/users/:id', async (req, res) => {
336
+ try {
337
+ const { id } = req.params;
338
+ await (0, data_1.getAuthData)(authConfig, 'deleteUser', { id });
339
+ res.json({ success: true });
340
+ }
341
+ catch (error) {
342
+ console.error('Error deleting user:', error);
343
+ res.status(500).json({ error: 'Failed to delete user' });
344
+ }
345
+ });
346
+ router.get('/api/plugins', async (req, res) => {
347
+ try {
348
+ const authConfigPath = await findAuthConfigPath();
349
+ if (!authConfigPath) {
350
+ return res.json({
351
+ plugins: [],
352
+ error: 'No auth config found',
353
+ configPath: null
354
+ });
355
+ }
356
+ try {
357
+ const authModule = await Promise.resolve(`${authConfigPath}`).then(s => __importStar(require(s)));
358
+ const auth = authModule.auth || authModule.default;
359
+ if (!auth) {
360
+ return res.json({
361
+ plugins: [],
362
+ error: 'No auth export found',
363
+ configPath: authConfigPath
364
+ });
365
+ }
366
+ const plugins = auth.options?.plugins || [];
367
+ const pluginInfo = plugins.map((plugin) => ({
368
+ id: plugin.id,
369
+ name: plugin.name || plugin.id,
370
+ version: plugin.version || 'unknown',
371
+ description: plugin.description || `${plugin.id} plugin for Better Auth`,
372
+ enabled: true
373
+ }));
374
+ res.json({
375
+ plugins: pluginInfo,
376
+ configPath: authConfigPath,
377
+ totalPlugins: pluginInfo.length
378
+ });
379
+ }
380
+ catch (error) {
381
+ console.error('Error getting plugins:', error);
382
+ res.json({
383
+ plugins: [],
384
+ error: 'Failed to load auth config',
385
+ configPath: authConfigPath
386
+ });
387
+ }
388
+ }
389
+ catch (error) {
390
+ console.error('Error fetching plugins:', error);
391
+ res.status(500).json({ error: 'Failed to fetch plugins' });
392
+ }
393
+ });
394
+ router.get('/api/plugins/teams/status', async (req, res) => {
395
+ try {
396
+ const authConfigPath = await findAuthConfigPath();
397
+ if (!authConfigPath) {
398
+ return res.json({
399
+ enabled: false,
400
+ error: 'No auth config found',
401
+ configPath: null
402
+ });
403
+ }
404
+ try {
405
+ const authModule = await Promise.resolve(`${authConfigPath}`).then(s => __importStar(require(s)));
406
+ const auth = authModule.auth || authModule.default;
407
+ if (!auth) {
408
+ return res.json({
409
+ enabled: false,
410
+ error: 'No auth export found',
411
+ configPath: authConfigPath
412
+ });
413
+ }
414
+ const organizationPlugin = auth.options?.plugins?.find((plugin) => plugin.id === "organization");
415
+ const teamsEnabled = organizationPlugin?.teams?.enabled === true;
416
+ res.json({
417
+ enabled: teamsEnabled,
418
+ configPath: authConfigPath,
419
+ organizationPlugin: organizationPlugin || null
420
+ });
421
+ }
422
+ catch (error) {
423
+ console.error('Error checking teams plugin:', error);
424
+ res.json({
425
+ enabled: false,
426
+ error: 'Failed to load auth config',
427
+ configPath: authConfigPath
428
+ });
429
+ }
430
+ }
431
+ catch (error) {
432
+ console.error('Error checking teams status:', error);
433
+ res.status(500).json({ error: 'Failed to check teams status' });
434
+ }
435
+ });
436
+ router.get('/api/organizations/:orgId/invitations', async (req, res) => {
437
+ try {
438
+ console.log('fetching invitations', req.params);
439
+ const { orgId } = req.params;
440
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
441
+ if (adapter && typeof adapter.findMany === 'function') {
442
+ try {
443
+ const invitations = await adapter.findMany({
444
+ model: 'invitation',
445
+ where: [
446
+ { field: 'organizationId', value: orgId },
447
+ { field: 'status', value: 'pending' }
448
+ ],
449
+ });
450
+ const transformedInvitations = (invitations || []).map((invitation) => ({
451
+ id: invitation.id,
452
+ email: invitation.email,
453
+ role: invitation.role || 'member',
454
+ status: invitation.status || 'pending',
455
+ organizationId: invitation.organizationId,
456
+ teamId: invitation.teamId,
457
+ inviterId: invitation.inviterId,
458
+ expiresAt: invitation.expiresAt,
459
+ createdAt: invitation.createdAt
460
+ }));
461
+ res.json({ success: true, invitations: transformedInvitations });
462
+ return;
463
+ }
464
+ catch (error) {
465
+ console.error('Error fetching invitations from adapter:', error);
466
+ }
467
+ }
468
+ res.json({ success: true, invitations: [] });
469
+ }
470
+ catch (error) {
471
+ console.error('Error fetching invitations:', error);
472
+ res.status(500).json({ error: 'Failed to fetch invitations' });
473
+ }
474
+ });
475
+ router.get('/api/organizations/:orgId/members', async (req, res) => {
476
+ try {
477
+ const { orgId } = req.params;
478
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
479
+ if (adapter && typeof adapter.findMany === 'function') {
480
+ try {
481
+ const members = await adapter.findMany({
482
+ model: 'member',
483
+ where: [{ field: 'organizationId', value: orgId }],
484
+ limit: 10000
485
+ });
486
+ const membersWithUsers = await Promise.all((members || []).map(async (member) => {
487
+ try {
488
+ if (adapter.findMany) {
489
+ const users = await adapter.findMany({
490
+ model: 'user',
491
+ where: [{ field: 'id', value: member.userId }],
492
+ limit: 1
493
+ });
494
+ const user = users?.[0];
495
+ return {
496
+ id: member.id,
497
+ userId: member.userId,
498
+ organizationId: member.organizationId,
499
+ role: member.role || 'member',
500
+ joinedAt: member.joinedAt || member.createdAt,
501
+ user: user ? {
502
+ id: user.id,
503
+ name: user.name,
504
+ email: user.email,
505
+ image: user.image,
506
+ emailVerified: user.emailVerified
507
+ } : null
508
+ };
509
+ }
510
+ return null;
511
+ }
512
+ catch (error) {
513
+ console.error('Error fetching user for member:', error);
514
+ return null;
515
+ }
516
+ }));
517
+ const validMembers = membersWithUsers.filter(member => member && member.user);
518
+ res.json({ success: true, members: validMembers });
519
+ return;
520
+ }
521
+ catch (error) {
522
+ console.error('Error fetching members from adapter:', error);
523
+ }
524
+ }
525
+ res.json({ success: true, members: [] });
526
+ }
527
+ catch (error) {
528
+ console.error('Error fetching members:', error);
529
+ res.status(500).json({ error: 'Failed to fetch members' });
530
+ }
531
+ });
532
+ router.post('/api/organizations/:orgId/seed-members', async (req, res) => {
533
+ try {
534
+ const { orgId } = req.params;
535
+ const { count = 5 } = req.body;
536
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
537
+ if (!adapter) {
538
+ return res.status(500).json({ error: 'Auth adapter not available' });
539
+ }
540
+ if (!adapter.findMany || !adapter.create) {
541
+ return res.status(500).json({ error: 'Adapter findMany method not available' });
542
+ }
543
+ const generateRandomString = (length) => {
544
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
545
+ let result = '';
546
+ for (let i = 0; i < length; i++) {
547
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
548
+ }
549
+ return result;
550
+ };
551
+ const results = [];
552
+ for (let i = 0; i < count; i++) {
553
+ try {
554
+ const randomString = generateRandomString(8);
555
+ const email = `user${randomString}@example.com`;
556
+ const name = `User ${randomString}`;
557
+ const userData = {
558
+ name,
559
+ email,
560
+ emailVerified: false,
561
+ createdAt: new Date(),
562
+ updatedAt: new Date()
563
+ };
564
+ const user = await adapter.create({
565
+ model: 'user',
566
+ data: userData
567
+ });
568
+ const memberData = {
569
+ organizationId: orgId,
570
+ userId: user.id,
571
+ role: 'member',
572
+ createdAt: new Date()
573
+ };
574
+ await adapter.create({
575
+ model: 'member',
576
+ data: memberData
577
+ });
578
+ results.push({
579
+ success: true,
580
+ member: {
581
+ userId: user.id,
582
+ user: {
583
+ name,
584
+ email
585
+ }
586
+ }
587
+ });
588
+ }
589
+ catch (error) {
590
+ results.push({
591
+ success: false,
592
+ error: error instanceof Error ? error.message : 'Unknown error'
593
+ });
594
+ }
595
+ }
596
+ res.json({
597
+ success: true,
598
+ message: `Added ${results.filter(r => r.success).length} members`,
599
+ results
600
+ });
601
+ }
602
+ catch (error) {
603
+ console.error('Error seeding members:', error);
604
+ res.status(500).json({ error: 'Failed to seed members' });
605
+ }
606
+ });
607
+ router.delete('/api/members/:id', async (req, res) => {
608
+ try {
609
+ const { id } = req.params;
610
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
611
+ if (!adapter) {
612
+ return res.status(500).json({ error: 'Auth adapter not available' });
613
+ }
614
+ if (!adapter.delete) {
615
+ return res.status(500).json({ error: 'Adapter delete method not available' });
616
+ }
617
+ await adapter.delete({
618
+ model: 'member',
619
+ where: [{ field: 'id', value: id }]
620
+ });
621
+ res.json({ success: true });
622
+ }
623
+ catch (error) {
624
+ console.error('Error removing member:', error);
625
+ res.status(500).json({ error: 'Failed to remove member' });
626
+ }
627
+ });
628
+ router.post('/api/invitations/:id/resend', async (req, res) => {
629
+ try {
630
+ const { id } = req.params;
631
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
632
+ if (!adapter) {
633
+ return res.status(500).json({ error: 'Auth adapter not available' });
634
+ }
635
+ if (!adapter.update) {
636
+ return res.status(500).json({ error: 'Adapter update method not available' });
637
+ }
638
+ await adapter.update({
639
+ model: 'invitation',
640
+ where: [{ field: 'id', value: id }],
641
+ update: {
642
+ expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days from now
643
+ updatedAt: new Date().toISOString()
644
+ }
645
+ });
646
+ res.json({ success: true });
647
+ }
648
+ catch (error) {
649
+ console.error('Error resending invitation:', error);
650
+ res.status(500).json({ error: 'Failed to resend invitation' });
651
+ }
652
+ });
653
+ router.delete('/api/invitations/:id', async (req, res) => {
654
+ try {
655
+ const { id } = req.params;
656
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
657
+ if (!adapter) {
658
+ return res.status(500).json({ error: 'Auth adapter not available' });
659
+ }
660
+ if (!adapter.update) {
661
+ return res.status(500).json({ error: 'Adapter update method not available' });
662
+ }
663
+ await adapter.update({
664
+ model: 'invitation',
665
+ where: [{ field: 'id', value: id }],
666
+ update: {
667
+ status: 'cancelled',
668
+ updatedAt: new Date().toISOString()
669
+ }
670
+ });
671
+ res.json({ success: true });
672
+ }
673
+ catch (error) {
674
+ console.error('Error cancelling invitation:', error);
675
+ res.status(500).json({ error: 'Failed to cancel invitation' });
676
+ }
677
+ });
678
+ router.post('/api/organizations/:orgId/invitations', async (req, res) => {
679
+ try {
680
+ const { orgId } = req.params;
681
+ const { email, role = 'member' } = req.body;
682
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
683
+ if (!adapter) {
684
+ return res.status(500).json({ error: 'Auth adapter not available' });
685
+ }
686
+ const invitationData = {
687
+ email,
688
+ role,
689
+ organizationId: orgId,
690
+ status: 'pending',
691
+ expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days
692
+ createdAt: new Date(),
693
+ inviterId: 'admin' // In real app, get from session
694
+ };
695
+ const invitation = {
696
+ id: `inv_${Date.now()}`,
697
+ ...invitationData
698
+ };
699
+ if (!adapter.create) {
700
+ return res.status(500).json({ error: 'Adapter create method not available' });
701
+ }
702
+ const adminId = "dQ2aAFgMwmRKvoqLiM1MCbjbka5g1Nzc";
703
+ await adapter.create({
704
+ model: 'invitation',
705
+ data: {
706
+ organizationId: invitationData.organizationId,
707
+ email: invitationData.email,
708
+ role: invitationData.role,
709
+ status: invitationData.status,
710
+ inviterId: adminId,
711
+ expiresAt: invitationData.expiresAt,
712
+ createdAt: invitationData.createdAt,
713
+ }
714
+ });
715
+ res.json({ success: true, invitation });
716
+ }
717
+ catch (error) {
718
+ console.error('Error creating invitation:', error);
719
+ res.status(500).json({ error: 'Failed to create invitation' });
720
+ }
721
+ });
722
+ router.get('/api/organizations/:orgId/teams', async (req, res) => {
723
+ try {
724
+ const { orgId } = req.params;
725
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
726
+ if (adapter && typeof adapter.findMany === 'function') {
727
+ try {
728
+ const teams = await adapter.findMany({
729
+ model: 'team',
730
+ where: [{ field: 'organizationId', value: orgId }],
731
+ limit: 10000
732
+ });
733
+ const transformedTeams = await Promise.all((teams || []).map(async (team) => {
734
+ if (!adapter.findMany) {
735
+ return null;
736
+ }
737
+ const teamMembers = await adapter.findMany({
738
+ model: 'teamMember',
739
+ where: [{ field: 'teamId', value: team.id }],
740
+ limit: 10000
741
+ });
742
+ return {
743
+ id: team.id,
744
+ name: team.name,
745
+ organizationId: team.organizationId,
746
+ metadata: team.metadata,
747
+ createdAt: team.createdAt,
748
+ updatedAt: team.updatedAt,
749
+ memberCount: teamMembers ? teamMembers.length : 0
750
+ };
751
+ }));
752
+ res.json({ success: true, teams: transformedTeams });
753
+ return;
754
+ }
755
+ catch (error) {
756
+ console.error('Error fetching teams from adapter:', error);
757
+ }
758
+ }
759
+ res.json({ success: true, teams: [] });
760
+ }
761
+ catch (error) {
762
+ console.error('Error fetching teams:', error);
763
+ res.status(500).json({ error: 'Failed to fetch teams' });
764
+ }
765
+ });
766
+ router.post('/api/organizations/:orgId/teams', async (req, res) => {
767
+ try {
768
+ const { orgId } = req.params;
769
+ const { name } = req.body;
770
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
771
+ if (!adapter) {
772
+ return res.status(500).json({ error: 'Auth adapter not available' });
773
+ }
774
+ const teamData = {
775
+ name,
776
+ organizationId: orgId,
777
+ createdAt: new Date(),
778
+ updatedAt: new Date(),
779
+ memberCount: 0
780
+ };
781
+ const team = {
782
+ id: `team_${Date.now()}`,
783
+ ...teamData
784
+ };
785
+ if (!adapter.create) {
786
+ return res.status(500).json({ error: 'Adapter create method not available' });
787
+ }
788
+ await adapter.create({
789
+ model: 'team',
790
+ data: {
791
+ name: teamData.name,
792
+ organizationId: teamData.organizationId,
793
+ createdAt: teamData.createdAt,
794
+ updatedAt: teamData.updatedAt,
795
+ }
796
+ });
797
+ res.json({ success: true, team });
798
+ }
799
+ catch (error) {
800
+ console.error('Error creating team:', error);
801
+ res.status(500).json({ error: 'Failed to create team' });
802
+ }
803
+ });
804
+ router.get('/api/teams/:id', async (req, res) => {
805
+ try {
806
+ const { id } = req.params;
807
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
808
+ if (adapter && typeof adapter.findMany === 'function') {
809
+ try {
810
+ const teams = await adapter.findMany({
811
+ model: 'team',
812
+ where: [{ field: 'id', value: id }],
813
+ limit: 1
814
+ });
815
+ const team = teams?.[0];
816
+ if (team) {
817
+ let organization = null;
818
+ try {
819
+ const orgs = await adapter.findMany({
820
+ model: 'organization',
821
+ where: [{ field: 'id', value: team.organizationId }],
822
+ limit: 1
823
+ });
824
+ organization = orgs?.[0];
825
+ }
826
+ catch (error) {
827
+ console.error('Error fetching organization for team:', error);
828
+ }
829
+ const transformedTeam = {
830
+ id: team.id,
831
+ name: team.name,
832
+ organizationId: team.organizationId,
833
+ metadata: team.metadata,
834
+ createdAt: team.createdAt,
835
+ updatedAt: team.updatedAt,
836
+ memberCount: team.memberCount || 0,
837
+ organization: organization ? {
838
+ id: organization.id,
839
+ name: organization.name
840
+ } : null
841
+ };
842
+ res.json({ success: true, team: transformedTeam });
843
+ return;
844
+ }
845
+ }
846
+ catch (error) {
847
+ console.error('Error fetching team from adapter:', error);
848
+ }
849
+ }
850
+ res.status(404).json({ success: false, error: 'Team not found' });
851
+ }
852
+ catch (error) {
853
+ console.error('Error fetching team:', error);
854
+ res.status(500).json({ error: 'Failed to fetch team' });
855
+ }
856
+ });
857
+ router.get('/api/teams/:teamId/members', async (req, res) => {
858
+ try {
859
+ const { teamId } = req.params;
860
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
861
+ if (adapter && typeof adapter.findMany === 'function') {
862
+ try {
863
+ const teamMembers = await adapter.findMany({
864
+ model: 'teamMember',
865
+ where: [{ field: 'teamId', value: teamId }],
866
+ limit: 10000
867
+ });
868
+ const membersWithUsers = await Promise.all((teamMembers || []).map(async (member) => {
869
+ try {
870
+ if (adapter.findMany) {
871
+ const users = await adapter.findMany({
872
+ model: 'user',
873
+ where: [{ field: 'id', value: member.userId }],
874
+ limit: 1
875
+ });
876
+ const user = users?.[0];
877
+ return {
878
+ id: member.id,
879
+ userId: member.userId,
880
+ teamId: member.teamId,
881
+ role: member.role || 'member',
882
+ joinedAt: member.joinedAt || member.createdAt,
883
+ user: user ? {
884
+ id: user.id,
885
+ name: user.name,
886
+ email: user.email,
887
+ image: user.image,
888
+ emailVerified: user.emailVerified
889
+ } : null
890
+ };
891
+ }
892
+ return null;
893
+ }
894
+ catch (error) {
895
+ console.error('Error fetching user for team member:', error);
896
+ return null;
897
+ }
898
+ }));
899
+ const validMembers = membersWithUsers.filter(member => member && member.user);
900
+ res.json({ success: true, members: validMembers });
901
+ return;
902
+ }
903
+ catch (error) {
904
+ console.error('Error fetching team members from adapter:', error);
905
+ }
906
+ }
907
+ res.json({ success: true, members: [] });
908
+ }
909
+ catch (error) {
910
+ console.error('Error fetching team members:', error);
911
+ res.status(500).json({ error: 'Failed to fetch team members' });
912
+ }
913
+ });
914
+ router.post('/api/teams/:teamId/members', async (req, res) => {
915
+ try {
916
+ const { teamId } = req.params;
917
+ const { userIds } = req.body;
918
+ if (!Array.isArray(userIds) || userIds.length === 0) {
919
+ return res.status(400).json({ error: 'userIds array is required' });
920
+ }
921
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
922
+ if (!adapter || !adapter.create) {
923
+ return res.status(500).json({ error: 'Adapter not available' });
924
+ }
925
+ const results = [];
926
+ for (const userId of userIds) {
927
+ try {
928
+ await adapter.create({
929
+ model: 'teamMember',
930
+ data: {
931
+ teamId,
932
+ userId,
933
+ role: 'member',
934
+ createdAt: new Date()
935
+ }
936
+ });
937
+ results.push({ success: true, userId });
938
+ }
939
+ catch (error) {
940
+ results.push({
941
+ success: false,
942
+ userId,
943
+ error: error instanceof Error ? error.message : 'Unknown error'
944
+ });
945
+ }
946
+ }
947
+ res.json({
948
+ success: true,
949
+ message: `Added ${results.filter(r => r.success).length} members`,
950
+ results
951
+ });
952
+ }
953
+ catch (error) {
954
+ console.error('Error adding team members:', error);
955
+ res.status(500).json({ error: 'Failed to add team members' });
956
+ }
957
+ });
958
+ router.delete('/api/team-members/:id', async (req, res) => {
959
+ try {
960
+ const { id } = req.params;
961
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
962
+ if (!adapter || !adapter.delete) {
963
+ return res.status(500).json({ error: 'Adapter not available' });
964
+ }
965
+ await adapter.delete({
966
+ model: 'teamMember',
967
+ where: [{ field: 'id', value: id }]
968
+ });
969
+ res.json({ success: true });
970
+ }
971
+ catch (error) {
972
+ console.error('Error removing team member:', error);
973
+ res.status(500).json({ error: 'Failed to remove team member' });
974
+ }
975
+ });
976
+ router.put('/api/teams/:id', async (req, res) => {
977
+ try {
978
+ const { id } = req.params;
979
+ const { name } = req.body;
980
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
981
+ if (!adapter) {
982
+ return res.status(500).json({ error: 'Auth adapter not available' });
983
+ }
984
+ const updatedTeam = {
985
+ id,
986
+ name,
987
+ updatedAt: new Date().toISOString()
988
+ };
989
+ if (!adapter.update) {
990
+ return res.status(500).json({ error: 'Adapter update method not available' });
991
+ }
992
+ await adapter.update({
993
+ model: 'team',
994
+ where: [{ field: 'id', value: id }],
995
+ update: {
996
+ name: updatedTeam.name,
997
+ updatedAt: updatedTeam.updatedAt
998
+ }
999
+ });
1000
+ res.json({ success: true, team: updatedTeam });
1001
+ }
1002
+ catch (error) {
1003
+ console.error('Error updating team:', error);
1004
+ res.status(500).json({ error: 'Failed to update team' });
1005
+ }
1006
+ });
1007
+ router.delete('/api/teams/:id', async (req, res) => {
1008
+ try {
1009
+ const { id } = req.params;
1010
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1011
+ if (!adapter) {
1012
+ return res.status(500).json({ error: 'Auth adapter not available' });
1013
+ }
1014
+ if (!adapter.delete) {
1015
+ return res.status(500).json({ error: 'Adapter delete method not available' });
1016
+ }
1017
+ await adapter.delete({
1018
+ model: 'team',
1019
+ where: [{ field: 'id', value: id }],
1020
+ });
1021
+ res.json({ success: true });
1022
+ }
1023
+ catch (error) {
1024
+ console.error('Error deleting team:', error);
1025
+ res.status(500).json({ error: 'Failed to delete team' });
1026
+ }
1027
+ });
1028
+ router.get('/api/plugins/organization/status', async (req, res) => {
1029
+ try {
1030
+ const authConfigPath = await findAuthConfigPath();
1031
+ if (!authConfigPath) {
1032
+ return res.json({
1033
+ enabled: false,
1034
+ error: 'No auth config found',
1035
+ configPath: null
1036
+ });
1037
+ }
1038
+ try {
1039
+ const authModule = await Promise.resolve(`${authConfigPath}`).then(s => __importStar(require(s)));
1040
+ const auth = authModule.auth || authModule.default;
1041
+ console.log({ auth });
1042
+ if (!auth) {
1043
+ return res.json({
1044
+ enabled: false,
1045
+ error: 'No auth export found',
1046
+ configPath: authConfigPath
1047
+ });
1048
+ }
1049
+ const hasOrganizationPlugin = auth.options?.plugins?.find((plugin) => plugin.id === "organization");
1050
+ console.log({ hasOrganizationPlugin });
1051
+ res.json({
1052
+ enabled: !!hasOrganizationPlugin,
1053
+ configPath: authConfigPath,
1054
+ availablePlugins: auth.options?.plugins?.map((p) => p.id) || [],
1055
+ organizationPlugin: hasOrganizationPlugin || null
1056
+ });
1057
+ }
1058
+ catch (error) {
1059
+ console.error('Error checking organization plugin:', error);
1060
+ res.json({
1061
+ enabled: false,
1062
+ error: 'Failed to load auth config',
1063
+ configPath: authConfigPath
1064
+ });
1065
+ }
1066
+ }
1067
+ catch (error) {
1068
+ console.error('Error checking plugin status:', error);
1069
+ res.status(500).json({ error: 'Failed to check plugin status' });
1070
+ }
1071
+ });
1072
+ router.get('/api/organizations', async (req, res) => {
1073
+ try {
1074
+ const page = parseInt(req.query.page) || 1;
1075
+ const limit = parseInt(req.query.limit) || 20;
1076
+ const search = req.query.search;
1077
+ try {
1078
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1079
+ if (adapter && typeof adapter.findMany === 'function') {
1080
+ const allOrganizations = await adapter.findMany({ model: 'organization' });
1081
+ console.log('Found organizations via findMany:', allOrganizations?.length || 0);
1082
+ let filteredOrganizations = allOrganizations || [];
1083
+ if (search) {
1084
+ filteredOrganizations = filteredOrganizations.filter((org) => org.name?.toLowerCase().includes(search.toLowerCase()) ||
1085
+ org.slug?.toLowerCase().includes(search.toLowerCase()));
1086
+ }
1087
+ const startIndex = (page - 1) * limit;
1088
+ const endIndex = startIndex + limit;
1089
+ const paginatedOrganizations = filteredOrganizations.slice(startIndex, endIndex);
1090
+ const transformedOrganizations = paginatedOrganizations.map((org) => ({
1091
+ id: org.id,
1092
+ name: org.name,
1093
+ slug: org.slug,
1094
+ metadata: org.metadata,
1095
+ createdAt: org.createdAt,
1096
+ updatedAt: org.updatedAt,
1097
+ }));
1098
+ res.json({ organizations: transformedOrganizations });
1099
+ return;
1100
+ }
1101
+ }
1102
+ catch (adapterError) {
1103
+ console.error('Error fetching organizations from adapter:', adapterError);
1104
+ }
1105
+ const mockOrganizations = [
1106
+ {
1107
+ id: 'org_1',
1108
+ name: 'Acme Corp',
1109
+ slug: 'acme-corp',
1110
+ metadata: { status: 'active' },
1111
+ createdAt: new Date().toISOString(),
1112
+ updatedAt: new Date().toISOString()
1113
+ },
1114
+ {
1115
+ id: 'org_2',
1116
+ name: 'Tech Solutions',
1117
+ slug: 'tech-solutions',
1118
+ metadata: { status: 'active' },
1119
+ createdAt: new Date().toISOString(),
1120
+ updatedAt: new Date().toISOString()
1121
+ }
1122
+ ];
1123
+ res.json({ organizations: mockOrganizations });
1124
+ }
1125
+ catch (error) {
1126
+ console.error('Error fetching organizations:', error);
1127
+ res.status(500).json({ error: 'Failed to fetch organizations' });
1128
+ }
1129
+ });
1130
+ router.post('/api/organizations', async (req, res) => {
1131
+ try {
1132
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1133
+ if (!adapter) {
1134
+ return res.status(500).json({ error: 'Auth adapter not available' });
1135
+ }
1136
+ const orgData = req.body;
1137
+ if (!orgData.slug && orgData.name) {
1138
+ orgData.slug = orgData.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
1139
+ }
1140
+ const organization = await adapter.createOrganization(orgData);
1141
+ res.json({ success: true, organization });
1142
+ }
1143
+ catch (error) {
1144
+ console.error('Error creating organization:', error);
1145
+ res.status(500).json({ error: 'Failed to create organization' });
1146
+ }
1147
+ });
1148
+ router.put('/api/organizations/:id', async (req, res) => {
1149
+ try {
1150
+ const { id } = req.params;
1151
+ const orgData = req.body;
1152
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1153
+ if (!adapter) {
1154
+ return res.status(500).json({ error: 'Auth adapter not available' });
1155
+ }
1156
+ if (orgData.name && !orgData.slug) {
1157
+ orgData.slug = orgData.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
1158
+ }
1159
+ const updatedOrganization = {
1160
+ id,
1161
+ ...orgData,
1162
+ updatedAt: new Date().toISOString()
1163
+ };
1164
+ const updatedOrg = await adapter.update({
1165
+ model: 'organization',
1166
+ where: [
1167
+ { field: 'id', value: id }
1168
+ ],
1169
+ update: updatedOrganization
1170
+ });
1171
+ res.json({ success: true, organization: updatedOrg });
1172
+ }
1173
+ catch (error) {
1174
+ console.error('Error updating organization:', error);
1175
+ res.status(500).json({ error: 'Failed to update organization' });
1176
+ }
1177
+ });
1178
+ router.get('/api/organizations/:id', async (req, res) => {
1179
+ try {
1180
+ const { id } = req.params;
1181
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1182
+ if (adapter && typeof adapter.findMany === 'function') {
1183
+ const organizations = await adapter.findMany({ model: 'organization', limit: 10000 });
1184
+ const organization = organizations?.find((org) => org.id === id);
1185
+ if (organization) {
1186
+ const transformedOrganization = {
1187
+ id: organization.id,
1188
+ name: organization.name,
1189
+ slug: organization.slug,
1190
+ metadata: organization.metadata,
1191
+ createdAt: organization.createdAt,
1192
+ updatedAt: organization.updatedAt,
1193
+ };
1194
+ res.json({ success: true, organization: transformedOrganization });
1195
+ return;
1196
+ }
1197
+ }
1198
+ res.status(404).json({ success: false, error: 'Organization not found' });
1199
+ }
1200
+ catch (error) {
1201
+ console.error('Error fetching organization:', error);
1202
+ res.status(500).json({ error: 'Failed to fetch organization' });
1203
+ }
1204
+ });
1205
+ router.delete('/api/organizations/:id', async (req, res) => {
1206
+ try {
1207
+ const { id } = req.params;
1208
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1209
+ if (!adapter) {
1210
+ return res.status(500).json({ error: 'Auth adapter not available' });
1211
+ }
1212
+ const deletedOrg = await adapter.delete({
1213
+ model: 'organization',
1214
+ where: [
1215
+ { field: 'id', value: id }
1216
+ ]
1217
+ });
1218
+ res.json({ success: true, organization: deletedOrg });
1219
+ }
1220
+ catch (error) {
1221
+ console.error('Error deleting organization:', error);
1222
+ res.status(500).json({ error: 'Failed to delete organization' });
1223
+ }
1224
+ });
1225
+ router.post('/api/users', async (req, res) => {
1226
+ try {
1227
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1228
+ if (!adapter) {
1229
+ return res.status(500).json({ error: 'Auth adapter not available' });
1230
+ }
1231
+ const userData = req.body;
1232
+ const user = await adapter.createUser(userData);
1233
+ res.json({ success: true, user });
1234
+ }
1235
+ catch (error) {
1236
+ console.error('Error creating user:', error);
1237
+ res.status(500).json({ error: 'Failed to create user' });
1238
+ }
1239
+ });
1240
+ router.put('/api/users/:id', async (req, res) => {
1241
+ try {
1242
+ const { id } = req.params;
1243
+ const userData = req.body;
1244
+ const updatedUser = await (0, data_1.getAuthData)(authConfig, 'updateUser', { id, userData });
1245
+ res.json({ success: true, user: updatedUser });
1246
+ }
1247
+ catch (error) {
1248
+ console.error('Error updating user:', error);
1249
+ res.status(500).json({ error: 'Failed to update user' });
1250
+ }
1251
+ });
1252
+ router.post('/api/seed/users', async (req, res) => {
1253
+ try {
1254
+ const { count = 1 } = req.body;
1255
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1256
+ console.log({ adapter });
1257
+ if (!adapter) {
1258
+ return res.status(500).json({ error: 'Auth adapter not available' });
1259
+ }
1260
+ const results = [];
1261
+ for (let i = 0; i < count; i++) {
1262
+ try {
1263
+ if (typeof adapter.createUser !== 'function') {
1264
+ throw new Error('createUser method not available on adapter');
1265
+ }
1266
+ const user = await (0, auth_adapter_1.createMockUser)(adapter, i + 1);
1267
+ results.push({
1268
+ success: true,
1269
+ user: {
1270
+ id: user.id,
1271
+ email: user.email,
1272
+ name: user.name,
1273
+ emailVerified: user.emailVerified,
1274
+ image: user.image,
1275
+ createdAt: user.createdAt
1276
+ }
1277
+ });
1278
+ }
1279
+ catch (error) {
1280
+ results.push({
1281
+ success: false,
1282
+ error: error instanceof Error ? error.message : 'Unknown error'
1283
+ });
1284
+ }
1285
+ }
1286
+ res.json({
1287
+ success: true,
1288
+ message: `Seeded ${results.filter(r => r.success).length} users`,
1289
+ results
1290
+ });
1291
+ }
1292
+ catch (error) {
1293
+ console.error('Error seeding users:', error);
1294
+ res.status(500).json({ error: 'Failed to seed users' });
1295
+ }
1296
+ });
1297
+ router.post('/api/seed/sessions', async (req, res) => {
1298
+ try {
1299
+ const { count = 1 } = req.body;
1300
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1301
+ if (!adapter) {
1302
+ return res.status(500).json({ error: 'Auth adapter not available' });
1303
+ }
1304
+ let user;
1305
+ try {
1306
+ user = await (0, auth_adapter_1.createMockUser)(adapter, 1);
1307
+ }
1308
+ catch (error) {
1309
+ return res.status(500).json({ error: 'Failed to create user for session' });
1310
+ }
1311
+ const results = [];
1312
+ for (let i = 0; i < count; i++) {
1313
+ try {
1314
+ if (typeof adapter.createSession !== 'function') {
1315
+ throw new Error('createSession method not available on adapter');
1316
+ }
1317
+ const session = await (0, auth_adapter_1.createMockSession)(adapter, user.id, i + 1);
1318
+ results.push({
1319
+ success: true,
1320
+ session: {
1321
+ id: session.id,
1322
+ userId: session.userId,
1323
+ expires: session.expires,
1324
+ sessionToken: session.sessionToken,
1325
+ createdAt: session.createdAt
1326
+ }
1327
+ });
1328
+ }
1329
+ catch (error) {
1330
+ results.push({
1331
+ success: false,
1332
+ error: error instanceof Error ? error.message : 'Unknown error'
1333
+ });
1334
+ }
1335
+ }
1336
+ res.json({
1337
+ success: true,
1338
+ message: `Seeded ${results.filter(r => r.success).length} sessions`,
1339
+ results
1340
+ });
1341
+ }
1342
+ catch (error) {
1343
+ console.error('Error seeding sessions:', error);
1344
+ res.status(500).json({ error: 'Failed to seed sessions' });
1345
+ }
1346
+ });
1347
+ router.post('/api/seed/accounts', async (req, res) => {
1348
+ try {
1349
+ const { count = 1 } = req.body;
1350
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1351
+ if (!adapter) {
1352
+ return res.status(500).json({ error: 'Auth adapter not available' });
1353
+ }
1354
+ let user;
1355
+ try {
1356
+ user = await (0, auth_adapter_1.createMockUser)(adapter, 1);
1357
+ }
1358
+ catch (error) {
1359
+ return res.status(500).json({ error: 'Failed to create user for account' });
1360
+ }
1361
+ const results = [];
1362
+ for (let i = 0; i < count; i++) {
1363
+ try {
1364
+ if (typeof adapter.createAccount !== 'function') {
1365
+ throw new Error('createAccount method not available on adapter');
1366
+ }
1367
+ const account = await (0, auth_adapter_1.createMockAccount)(adapter, user.id, i + 1);
1368
+ results.push({
1369
+ success: true,
1370
+ account: {
1371
+ id: account.id,
1372
+ userId: account.userId,
1373
+ type: account.type,
1374
+ provider: account.provider,
1375
+ providerAccountId: account.providerAccountId,
1376
+ createdAt: account.createdAt
1377
+ }
1378
+ });
1379
+ }
1380
+ catch (error) {
1381
+ results.push({
1382
+ success: false,
1383
+ error: error instanceof Error ? error.message : 'Unknown error'
1384
+ });
1385
+ }
1386
+ }
1387
+ res.json({
1388
+ success: true,
1389
+ message: `Seeded ${results.filter(r => r.success).length} accounts`,
1390
+ results
1391
+ });
1392
+ }
1393
+ catch (error) {
1394
+ console.error('Error seeding accounts:', error);
1395
+ res.status(500).json({ error: 'Failed to seed accounts' });
1396
+ }
1397
+ });
1398
+ router.post('/api/seed/verifications', async (req, res) => {
1399
+ try {
1400
+ const { count = 1 } = req.body;
1401
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1402
+ if (!adapter) {
1403
+ return res.status(500).json({ error: 'Auth adapter not available' });
1404
+ }
1405
+ const results = [];
1406
+ for (let i = 0; i < count; i++) {
1407
+ try {
1408
+ if (typeof adapter.createVerification !== 'function') {
1409
+ throw new Error('createVerification method not available on adapter');
1410
+ }
1411
+ const verification = await (0, auth_adapter_1.createMockVerification)(adapter, `user${i + 1}@example.com`, i + 1);
1412
+ results.push({
1413
+ success: true,
1414
+ verification: {
1415
+ id: verification.id,
1416
+ identifier: verification.identifier,
1417
+ token: verification.token,
1418
+ expires: verification.expires,
1419
+ createdAt: verification.createdAt
1420
+ }
1421
+ });
1422
+ }
1423
+ catch (error) {
1424
+ results.push({
1425
+ success: false,
1426
+ error: error instanceof Error ? error.message : 'Unknown error'
1427
+ });
1428
+ }
1429
+ }
1430
+ res.json({
1431
+ success: true,
1432
+ message: `Seeded ${results.filter(r => r.success).length} verifications`,
1433
+ results
1434
+ });
1435
+ }
1436
+ catch (error) {
1437
+ console.error('Error seeding verifications:', error);
1438
+ res.status(500).json({ error: 'Failed to seed verifications' });
1439
+ }
1440
+ });
1441
+ router.post('/api/seed/organizations', async (req, res) => {
1442
+ try {
1443
+ const { count = 1 } = req.body;
1444
+ const adapter = await (0, auth_adapter_1.getAuthAdapter)();
1445
+ if (!adapter) {
1446
+ return res.status(500).json({ error: 'Auth adapter not available' });
1447
+ }
1448
+ const results = [];
1449
+ for (let i = 0; i < count; i++) {
1450
+ try {
1451
+ const organizationData = {
1452
+ name: `Organization ${i + 1}`,
1453
+ slug: `org-${i + 1}`,
1454
+ image: `https://api.dicebear.com/7.x/identicon/svg?seed=org${i + 1}`,
1455
+ createdAt: new Date(),
1456
+ updatedAt: new Date()
1457
+ };
1458
+ const organization = await adapter.createOrganization(organizationData);
1459
+ results.push({
1460
+ success: true,
1461
+ organization: {
1462
+ id: organization.id,
1463
+ name: organization.name,
1464
+ slug: organization.slug,
1465
+ image: organization.image,
1466
+ createdAt: organization.createdAt
1467
+ }
1468
+ });
1469
+ }
1470
+ catch (error) {
1471
+ results.push({
1472
+ success: false,
1473
+ error: error instanceof Error ? error.message : 'Unknown error'
1474
+ });
1475
+ }
1476
+ }
1477
+ res.json({
1478
+ success: true,
1479
+ message: `Seeded ${results.filter(r => r.success).length} organizations`,
1480
+ results
1481
+ });
1482
+ }
1483
+ catch (error) {
1484
+ console.error('Error seeding organizations:', error);
1485
+ res.status(500).json({ error: 'Failed to seed organizations' });
1486
+ }
1487
+ });
1488
+ return router;
1489
+ }
1490
+ //# sourceMappingURL=routes.js.map