better-auth-studio 1.0.23-beta.4 → 1.0.24-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,8 @@ A web-based studio interface for managing Better Auth applications. Better Auth
11
11
 
12
12
  ### Installation
13
13
 
14
+ 📖 **[Documentation](https://better-auth-studio.vercel.app)**
15
+
14
16
  Install Better Auth Studio globally using pnpm:
15
17
 
16
18
  ```bash
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAY9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+C9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA4J/E;AAwBD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAktER"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAY9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+C9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA4J/E;AAwBD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAk2FR"}
package/dist/routes.js CHANGED
@@ -1030,6 +1030,638 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1030
1030
  res.status(500).json({ error: 'Failed to fetch database info' });
1031
1031
  }
1032
1032
  });
1033
+ // Database Schema Visualization endpoint
1034
+ // Schema definitions for different Better Auth plugins
1035
+ const BASE_SCHEMA = {
1036
+ user: {
1037
+ name: 'user',
1038
+ displayName: 'User',
1039
+ fields: [
1040
+ {
1041
+ name: 'id',
1042
+ type: 'string',
1043
+ required: true,
1044
+ primaryKey: true,
1045
+ description: 'Unique user identifier',
1046
+ },
1047
+ { name: 'name', type: 'string', required: true, description: 'User display name' },
1048
+ {
1049
+ name: 'email',
1050
+ type: 'string',
1051
+ required: true,
1052
+ unique: true,
1053
+ description: 'User email address',
1054
+ },
1055
+ {
1056
+ name: 'emailVerified',
1057
+ type: 'boolean',
1058
+ required: true,
1059
+ defaultValue: false,
1060
+ description: 'Email verification status',
1061
+ },
1062
+ { name: 'image', type: 'string', required: false, description: 'User profile image URL' },
1063
+ {
1064
+ name: 'createdAt',
1065
+ type: 'date',
1066
+ required: true,
1067
+ description: 'Account creation timestamp',
1068
+ },
1069
+ { name: 'updatedAt', type: 'date', required: true, description: 'Last update timestamp' },
1070
+ ],
1071
+ relationships: [
1072
+ { type: 'one-to-many', target: 'session', field: 'userId' },
1073
+ { type: 'one-to-many', target: 'account', field: 'userId' },
1074
+ ],
1075
+ },
1076
+ session: {
1077
+ name: 'session',
1078
+ displayName: 'Session',
1079
+ fields: [
1080
+ {
1081
+ name: 'id',
1082
+ type: 'string',
1083
+ required: true,
1084
+ primaryKey: true,
1085
+ description: 'Unique session identifier',
1086
+ },
1087
+ {
1088
+ name: 'expiresAt',
1089
+ type: 'date',
1090
+ required: true,
1091
+ description: 'Session expiration timestamp',
1092
+ },
1093
+ {
1094
+ name: 'token',
1095
+ type: 'string',
1096
+ required: true,
1097
+ unique: true,
1098
+ description: 'Session token',
1099
+ },
1100
+ {
1101
+ name: 'createdAt',
1102
+ type: 'date',
1103
+ required: true,
1104
+ description: 'Session creation timestamp',
1105
+ },
1106
+ { name: 'updatedAt', type: 'date', required: true, description: 'Last update timestamp' },
1107
+ { name: 'ipAddress', type: 'string', required: false, description: 'Client IP address' },
1108
+ { name: 'userAgent', type: 'string', required: false, description: 'Client user agent' },
1109
+ { name: 'userId', type: 'string', required: true, description: 'Associated user ID' },
1110
+ ],
1111
+ relationships: [{ type: 'many-to-one', target: 'user', field: 'userId' }],
1112
+ },
1113
+ account: {
1114
+ name: 'account',
1115
+ displayName: 'Account',
1116
+ fields: [
1117
+ {
1118
+ name: 'id',
1119
+ type: 'string',
1120
+ required: true,
1121
+ primaryKey: true,
1122
+ description: 'Unique account identifier',
1123
+ },
1124
+ { name: 'accountId', type: 'string', required: true, description: 'Provider account ID' },
1125
+ {
1126
+ name: 'providerId',
1127
+ type: 'string',
1128
+ required: true,
1129
+ description: 'Authentication provider',
1130
+ },
1131
+ { name: 'userId', type: 'string', required: true, description: 'Associated user ID' },
1132
+ { name: 'accessToken', type: 'string', required: false, description: 'OAuth access token' },
1133
+ {
1134
+ name: 'refreshToken',
1135
+ type: 'string',
1136
+ required: false,
1137
+ description: 'OAuth refresh token',
1138
+ },
1139
+ { name: 'idToken', type: 'string', required: false, description: 'OAuth ID token' },
1140
+ {
1141
+ name: 'accessTokenExpiresAt',
1142
+ type: 'date',
1143
+ required: false,
1144
+ description: 'Access token expiration',
1145
+ },
1146
+ {
1147
+ name: 'refreshTokenExpiresAt',
1148
+ type: 'date',
1149
+ required: false,
1150
+ description: 'Refresh token expiration',
1151
+ },
1152
+ { name: 'scope', type: 'string', required: false, description: 'OAuth scope' },
1153
+ {
1154
+ name: 'password',
1155
+ type: 'string',
1156
+ required: false,
1157
+ description: 'Hashed password (if applicable)',
1158
+ },
1159
+ {
1160
+ name: 'createdAt',
1161
+ type: 'date',
1162
+ required: true,
1163
+ description: 'Account creation timestamp',
1164
+ },
1165
+ { name: 'updatedAt', type: 'date', required: true, description: 'Last update timestamp' },
1166
+ ],
1167
+ relationships: [{ type: 'many-to-one', target: 'user', field: 'userId' }],
1168
+ },
1169
+ verification: {
1170
+ name: 'verification',
1171
+ displayName: 'Verification',
1172
+ fields: [
1173
+ {
1174
+ name: 'id',
1175
+ type: 'string',
1176
+ required: true,
1177
+ primaryKey: true,
1178
+ description: 'Unique verification identifier',
1179
+ },
1180
+ {
1181
+ name: 'identifier',
1182
+ type: 'string',
1183
+ required: true,
1184
+ description: 'Email or phone being verified',
1185
+ },
1186
+ {
1187
+ name: 'value',
1188
+ type: 'string',
1189
+ required: true,
1190
+ description: 'Verification code or token',
1191
+ },
1192
+ {
1193
+ name: 'expiresAt',
1194
+ type: 'date',
1195
+ required: true,
1196
+ description: 'Verification expiration timestamp',
1197
+ },
1198
+ {
1199
+ name: 'createdAt',
1200
+ type: 'date',
1201
+ required: true,
1202
+ description: 'Verification creation timestamp',
1203
+ },
1204
+ { name: 'updatedAt', type: 'date', required: true, description: 'Last update timestamp' },
1205
+ ],
1206
+ relationships: [],
1207
+ },
1208
+ };
1209
+ // Plugin schemas that extend the base schema
1210
+ const PLUGIN_SCHEMAS = {
1211
+ organization: {
1212
+ tables: {
1213
+ organization: {
1214
+ name: 'organization',
1215
+ displayName: 'Organization',
1216
+ fields: [
1217
+ {
1218
+ name: 'id',
1219
+ type: 'string',
1220
+ required: true,
1221
+ primaryKey: true,
1222
+ description: 'Unique organization identifier',
1223
+ },
1224
+ { name: 'name', type: 'string', required: true, description: 'Organization name' },
1225
+ {
1226
+ name: 'slug',
1227
+ type: 'string',
1228
+ required: false,
1229
+ unique: true,
1230
+ description: 'Organization URL slug',
1231
+ },
1232
+ { name: 'logo', type: 'string', required: false, description: 'Organization logo URL' },
1233
+ {
1234
+ name: 'createdAt',
1235
+ type: 'date',
1236
+ required: true,
1237
+ description: 'Organization creation timestamp',
1238
+ },
1239
+ {
1240
+ name: 'metadata',
1241
+ type: 'json',
1242
+ required: false,
1243
+ description: 'Additional organization metadata',
1244
+ },
1245
+ ],
1246
+ relationships: [
1247
+ { type: 'one-to-many', target: 'member', field: 'organizationId' },
1248
+ { type: 'one-to-many', target: 'invitation', field: 'organizationId' },
1249
+ ],
1250
+ },
1251
+ member: {
1252
+ name: 'member',
1253
+ displayName: 'Member',
1254
+ fields: [
1255
+ {
1256
+ name: 'id',
1257
+ type: 'string',
1258
+ required: true,
1259
+ primaryKey: true,
1260
+ description: 'Unique member identifier',
1261
+ },
1262
+ {
1263
+ name: 'organizationId',
1264
+ type: 'string',
1265
+ required: true,
1266
+ description: 'Organization ID',
1267
+ },
1268
+ { name: 'userId', type: 'string', required: true, description: 'User ID' },
1269
+ {
1270
+ name: 'role',
1271
+ type: 'string',
1272
+ required: true,
1273
+ defaultValue: 'member',
1274
+ description: 'Member role in organization',
1275
+ },
1276
+ {
1277
+ name: 'createdAt',
1278
+ type: 'date',
1279
+ required: true,
1280
+ description: 'Membership creation timestamp',
1281
+ },
1282
+ ],
1283
+ relationships: [
1284
+ { type: 'many-to-one', target: 'organization', field: 'organizationId' },
1285
+ { type: 'many-to-one', target: 'user', field: 'userId' },
1286
+ ],
1287
+ },
1288
+ invitation: {
1289
+ name: 'invitation',
1290
+ displayName: 'Invitation',
1291
+ fields: [
1292
+ {
1293
+ name: 'id',
1294
+ type: 'string',
1295
+ required: true,
1296
+ primaryKey: true,
1297
+ description: 'Unique invitation identifier',
1298
+ },
1299
+ {
1300
+ name: 'organizationId',
1301
+ type: 'string',
1302
+ required: true,
1303
+ description: 'Organization ID',
1304
+ },
1305
+ { name: 'email', type: 'string', required: true, description: 'Invited email address' },
1306
+ { name: 'role', type: 'string', required: false, description: 'Invited role' },
1307
+ {
1308
+ name: 'status',
1309
+ type: 'string',
1310
+ required: true,
1311
+ defaultValue: 'pending',
1312
+ description: 'Invitation status',
1313
+ },
1314
+ {
1315
+ name: 'expiresAt',
1316
+ type: 'date',
1317
+ required: true,
1318
+ description: 'Invitation expiration timestamp',
1319
+ },
1320
+ {
1321
+ name: 'inviterId',
1322
+ type: 'string',
1323
+ required: true,
1324
+ description: 'User who sent the invitation',
1325
+ },
1326
+ ],
1327
+ relationships: [
1328
+ { type: 'many-to-one', target: 'organization', field: 'organizationId' },
1329
+ { type: 'many-to-one', target: 'user', field: 'inviterId' },
1330
+ ],
1331
+ },
1332
+ },
1333
+ userExtensions: {
1334
+ fields: [],
1335
+ relationships: [
1336
+ { type: 'one-to-many', target: 'member', field: 'userId' },
1337
+ { type: 'one-to-many', target: 'invitation', field: 'inviterId' },
1338
+ ],
1339
+ },
1340
+ sessionExtensions: {
1341
+ fields: [
1342
+ {
1343
+ name: 'activeOrganizationId',
1344
+ type: 'string',
1345
+ required: false,
1346
+ description: 'Active organization ID',
1347
+ },
1348
+ ],
1349
+ relationships: [],
1350
+ },
1351
+ },
1352
+ teams: {
1353
+ tables: {
1354
+ team: {
1355
+ name: 'team',
1356
+ displayName: 'Team',
1357
+ fields: [
1358
+ {
1359
+ name: 'id',
1360
+ type: 'string',
1361
+ required: true,
1362
+ primaryKey: true,
1363
+ description: 'Unique team identifier',
1364
+ },
1365
+ { name: 'name', type: 'string', required: true, description: 'Team name' },
1366
+ {
1367
+ name: 'organizationId',
1368
+ type: 'string',
1369
+ required: true,
1370
+ description: 'Organization ID',
1371
+ },
1372
+ {
1373
+ name: 'createdAt',
1374
+ type: 'date',
1375
+ required: true,
1376
+ description: 'Team creation timestamp',
1377
+ },
1378
+ {
1379
+ name: 'updatedAt',
1380
+ type: 'date',
1381
+ required: false,
1382
+ description: 'Last update timestamp',
1383
+ },
1384
+ ],
1385
+ relationships: [
1386
+ { type: 'many-to-one', target: 'organization', field: 'organizationId' },
1387
+ { type: 'one-to-many', target: 'teamMember', field: 'teamId' },
1388
+ ],
1389
+ },
1390
+ teamMember: {
1391
+ name: 'teamMember',
1392
+ displayName: 'Team Member',
1393
+ fields: [
1394
+ {
1395
+ name: 'id',
1396
+ type: 'string',
1397
+ required: true,
1398
+ primaryKey: true,
1399
+ description: 'Unique team member identifier',
1400
+ },
1401
+ { name: 'teamId', type: 'string', required: true, description: 'Team ID' },
1402
+ { name: 'userId', type: 'string', required: true, description: 'User ID' },
1403
+ {
1404
+ name: 'createdAt',
1405
+ type: 'date',
1406
+ required: false,
1407
+ description: 'Team membership creation timestamp',
1408
+ },
1409
+ ],
1410
+ relationships: [
1411
+ { type: 'many-to-one', target: 'team', field: 'teamId' },
1412
+ { type: 'many-to-one', target: 'user', field: 'userId' },
1413
+ ],
1414
+ },
1415
+ },
1416
+ organizationExtensions: {
1417
+ relationships: [{ type: 'one-to-many', target: 'team', field: 'organizationId' }],
1418
+ },
1419
+ sessionExtensions: {
1420
+ fields: [
1421
+ { name: 'activeTeamId', type: 'string', required: false, description: 'Active team ID' },
1422
+ ],
1423
+ relationships: [],
1424
+ },
1425
+ },
1426
+ twoFactor: {
1427
+ tables: {
1428
+ twoFactor: {
1429
+ name: 'twoFactor',
1430
+ displayName: 'Two Factor',
1431
+ fields: [
1432
+ {
1433
+ name: 'id',
1434
+ type: 'string',
1435
+ required: true,
1436
+ primaryKey: true,
1437
+ description: 'Unique two-factor authentication identifier',
1438
+ },
1439
+ { name: 'userId', type: 'string', required: true, description: 'Associated user ID' },
1440
+ {
1441
+ name: 'secret',
1442
+ type: 'string',
1443
+ required: true,
1444
+ description: 'Two-factor authentication secret',
1445
+ },
1446
+ {
1447
+ name: 'backupCodes',
1448
+ type: 'string',
1449
+ required: true,
1450
+ description: 'Backup codes for two-factor authentication',
1451
+ },
1452
+ ],
1453
+ relationships: [{ type: 'many-to-one', target: 'user', field: 'userId' }],
1454
+ },
1455
+ },
1456
+ userExtensions: {
1457
+ fields: [
1458
+ {
1459
+ name: 'twoFactorEnabled',
1460
+ type: 'boolean',
1461
+ required: false,
1462
+ description: 'Two-factor authentication enabled status',
1463
+ },
1464
+ ],
1465
+ relationships: [{ type: 'one-to-one', target: 'twoFactor', field: 'userId' }],
1466
+ },
1467
+ },
1468
+ apiKey: {
1469
+ tables: {
1470
+ apiKey: {
1471
+ name: 'apiKey',
1472
+ displayName: 'API Key',
1473
+ fields: [
1474
+ {
1475
+ name: 'id',
1476
+ type: 'string',
1477
+ required: true,
1478
+ primaryKey: true,
1479
+ description: 'Unique API key identifier',
1480
+ },
1481
+ { name: 'userId', type: 'string', required: true, description: 'Associated user ID' },
1482
+ { name: 'name', type: 'string', required: true, description: 'API key name' },
1483
+ {
1484
+ name: 'key',
1485
+ type: 'string',
1486
+ required: true,
1487
+ unique: true,
1488
+ description: 'API key value',
1489
+ },
1490
+ {
1491
+ name: 'expiresAt',
1492
+ type: 'date',
1493
+ required: false,
1494
+ description: 'API key expiration timestamp',
1495
+ },
1496
+ {
1497
+ name: 'lastUsedAt',
1498
+ type: 'date',
1499
+ required: false,
1500
+ description: 'Last usage timestamp',
1501
+ },
1502
+ {
1503
+ name: 'createdAt',
1504
+ type: 'date',
1505
+ required: true,
1506
+ description: 'API key creation timestamp',
1507
+ },
1508
+ ],
1509
+ relationships: [{ type: 'many-to-one', target: 'user', field: 'userId' }],
1510
+ },
1511
+ },
1512
+ userExtensions: {
1513
+ relationships: [{ type: 'one-to-many', target: 'apiKey', field: 'userId' }],
1514
+ },
1515
+ },
1516
+ passkey: {
1517
+ tables: {
1518
+ passkey: {
1519
+ name: 'passkey',
1520
+ displayName: 'Passkey',
1521
+ fields: [
1522
+ {
1523
+ name: 'id',
1524
+ type: 'string',
1525
+ required: true,
1526
+ primaryKey: true,
1527
+ description: 'Unique passkey identifier',
1528
+ },
1529
+ { name: 'userId', type: 'string', required: true, description: 'Associated user ID' },
1530
+ { name: 'name', type: 'string', required: true, description: 'Passkey name' },
1531
+ {
1532
+ name: 'credentialId',
1533
+ type: 'string',
1534
+ required: true,
1535
+ unique: true,
1536
+ description: 'WebAuthn credential ID',
1537
+ },
1538
+ { name: 'publicKey', type: 'string', required: true, description: 'Public key' },
1539
+ { name: 'counter', type: 'number', required: true, description: 'Usage counter' },
1540
+ {
1541
+ name: 'createdAt',
1542
+ type: 'date',
1543
+ required: true,
1544
+ description: 'Passkey creation timestamp',
1545
+ },
1546
+ {
1547
+ name: 'lastUsedAt',
1548
+ type: 'date',
1549
+ required: false,
1550
+ description: 'Last usage timestamp',
1551
+ },
1552
+ ],
1553
+ relationships: [{ type: 'many-to-one', target: 'user', field: 'userId' }],
1554
+ },
1555
+ },
1556
+ userExtensions: {
1557
+ relationships: [{ type: 'one-to-many', target: 'passkey', field: 'userId' }],
1558
+ },
1559
+ },
1560
+ };
1561
+ // Function to generate schema based on selected plugins
1562
+ function generateSchema(selectedPlugins) {
1563
+ const schema = { tables: [] };
1564
+ // Start with base tables (deep clone to avoid mutations)
1565
+ const baseTables = Object.values(BASE_SCHEMA).map((table) => ({
1566
+ ...table,
1567
+ fields: [...table.fields],
1568
+ relationships: [...table.relationships],
1569
+ }));
1570
+ schema.tables.push(...baseTables);
1571
+ // Apply plugin extensions
1572
+ selectedPlugins.forEach((pluginName) => {
1573
+ const plugin = PLUGIN_SCHEMAS[pluginName];
1574
+ if (!plugin)
1575
+ return;
1576
+ // Add plugin-specific tables
1577
+ if (plugin.tables) {
1578
+ Object.values(plugin.tables).forEach((table) => {
1579
+ schema.tables.push({
1580
+ ...table,
1581
+ fields: [...table.fields],
1582
+ relationships: [...table.relationships],
1583
+ });
1584
+ });
1585
+ }
1586
+ // Extend existing tables (with duplicate prevention)
1587
+ if ('userExtensions' in plugin && plugin.userExtensions) {
1588
+ const userTable = schema.tables.find((t) => t.name === 'user');
1589
+ if (userTable && 'fields' in plugin.userExtensions) {
1590
+ // Add fields only if they don't already exist
1591
+ (plugin.userExtensions.fields || []).forEach((field) => {
1592
+ if (!userTable.fields.some((f) => f.name === field.name)) {
1593
+ userTable.fields.push(field);
1594
+ }
1595
+ });
1596
+ // Add relationships only if they don't already exist
1597
+ (plugin.userExtensions.relationships || []).forEach((rel) => {
1598
+ if (!userTable.relationships.some((r) => r.target === rel.target && r.field === rel.field && r.type === rel.type)) {
1599
+ userTable.relationships.push(rel);
1600
+ }
1601
+ });
1602
+ }
1603
+ }
1604
+ if ('sessionExtensions' in plugin && plugin.sessionExtensions) {
1605
+ const sessionTable = schema.tables.find((t) => t.name === 'session');
1606
+ if (sessionTable && 'fields' in plugin.sessionExtensions) {
1607
+ // Add fields only if they don't already exist
1608
+ (plugin.sessionExtensions.fields || []).forEach((field) => {
1609
+ if (!sessionTable.fields.some((f) => f.name === field.name)) {
1610
+ sessionTable.fields.push(field);
1611
+ }
1612
+ });
1613
+ // Add relationships only if they don't already exist
1614
+ (plugin.sessionExtensions.relationships || []).forEach((rel) => {
1615
+ if (!sessionTable.relationships.some((r) => r.target === rel.target && r.field === rel.field && r.type === rel.type)) {
1616
+ sessionTable.relationships.push(rel);
1617
+ }
1618
+ });
1619
+ }
1620
+ }
1621
+ if ('organizationExtensions' in plugin && plugin.organizationExtensions) {
1622
+ const orgTable = schema.tables.find((t) => t.name === 'organization');
1623
+ if (orgTable) {
1624
+ // Add relationships only if they don't already exist
1625
+ (plugin.organizationExtensions.relationships || []).forEach((rel) => {
1626
+ if (!orgTable.relationships.some((r) => r.target === rel.target && r.field === rel.field && r.type === rel.type)) {
1627
+ orgTable.relationships.push(rel);
1628
+ }
1629
+ });
1630
+ }
1631
+ }
1632
+ });
1633
+ return schema;
1634
+ }
1635
+ router.get('/api/database/schema', async (req, res) => {
1636
+ try {
1637
+ const adapter = await getAuthAdapterWithConfig();
1638
+ const { plugins } = req.query;
1639
+ let selectedPlugins = [];
1640
+ if (plugins && typeof plugins === 'string') {
1641
+ selectedPlugins = plugins.split(',').filter(Boolean);
1642
+ }
1643
+ if (!adapter) {
1644
+ return res.json({
1645
+ schema: null,
1646
+ error: 'Auth adapter not available',
1647
+ });
1648
+ }
1649
+ const schema = generateSchema(selectedPlugins);
1650
+ res.json({
1651
+ success: true,
1652
+ schema: schema,
1653
+ availablePlugins: Object.keys(PLUGIN_SCHEMAS),
1654
+ selectedPlugins: selectedPlugins,
1655
+ });
1656
+ }
1657
+ catch (error) {
1658
+ console.error('Error fetching database schema:', error);
1659
+ res.status(500).json({
1660
+ success: false,
1661
+ error: 'Failed to fetch database schema',
1662
+ });
1663
+ }
1664
+ });
1033
1665
  router.get('/api/plugins/teams/status', async (req, res) => {
1034
1666
  try {
1035
1667
  const authConfigPath = configPath || (await findAuthConfigPath());
@@ -1066,7 +1698,8 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
1066
1698
  });
1067
1699
  }
1068
1700
  const organizationPlugin = auth.options?.plugins?.find((plugin) => plugin.id === 'organization');
1069
- const teamsEnabled = organizationPlugin?.teams?.enabled === true;
1701
+ const teamOptions = organizationPlugin.options.teams;
1702
+ const teamsEnabled = teamOptions?.enabled;
1070
1703
  res.json({
1071
1704
  enabled: teamsEnabled,
1072
1705
  configPath: authConfigPath,