@objectstack/plugin-auth 4.0.2 → 4.0.4
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +15 -0
- package/dist/index.d.mts +1410 -91
- package/dist/index.d.ts +1410 -91
- package/dist/index.js +149 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +148 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/auth-manager.test.ts +129 -4
- package/src/auth-manager.ts +83 -2
- package/src/auth-plugin.test.ts +12 -5
- package/src/auth-plugin.ts +24 -2
- package/src/objects/index.ts +1 -0
- package/src/objects/sys-user-preference.object.ts +82 -0
package/dist/index.mjs
CHANGED
|
@@ -372,7 +372,20 @@ var AuthManager = class {
|
|
|
372
372
|
// better-auth plugins — registered based on AuthPluginConfig flags
|
|
373
373
|
plugins: this.buildPluginList(),
|
|
374
374
|
// Trusted origins for CSRF protection (supports wildcards like "https://*.example.com")
|
|
375
|
-
|
|
375
|
+
// Auto-includes origins from CORS_ORIGIN env var so CORS and CSRF stay in sync.
|
|
376
|
+
...(() => {
|
|
377
|
+
const origins = [...this.config.trustedOrigins || []];
|
|
378
|
+
const corsOrigin = process.env.CORS_ORIGIN;
|
|
379
|
+
if (corsOrigin && corsOrigin !== "*") {
|
|
380
|
+
corsOrigin.split(",").map((s) => s.trim()).filter(Boolean).forEach((o) => {
|
|
381
|
+
if (!origins.includes(o)) origins.push(o);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
if (!origins.length && (!corsOrigin || corsOrigin === "*")) {
|
|
385
|
+
origins.push("http://localhost:*");
|
|
386
|
+
}
|
|
387
|
+
return origins.length ? { trustedOrigins: origins } : {};
|
|
388
|
+
})(),
|
|
376
389
|
// Advanced options (cross-subdomain cookies, secure cookies, CSRF, etc.)
|
|
377
390
|
...this.config.advanced ? {
|
|
378
391
|
advanced: {
|
|
@@ -508,6 +521,59 @@ var AuthManager = class {
|
|
|
508
521
|
get api() {
|
|
509
522
|
return this.getOrCreateAuth().api;
|
|
510
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* Get public authentication configuration
|
|
526
|
+
* Returns safe, non-sensitive configuration that can be exposed to the frontend
|
|
527
|
+
*
|
|
528
|
+
* This allows the frontend to discover:
|
|
529
|
+
* - Which social/OAuth providers are available
|
|
530
|
+
* - Whether email/password login is enabled
|
|
531
|
+
* - Which advanced features are enabled (2FA, magic links, etc.)
|
|
532
|
+
*/
|
|
533
|
+
getPublicConfig() {
|
|
534
|
+
const socialProviders = [];
|
|
535
|
+
if (this.config.socialProviders) {
|
|
536
|
+
for (const [id, providerConfig] of Object.entries(this.config.socialProviders)) {
|
|
537
|
+
if (providerConfig.enabled !== false) {
|
|
538
|
+
const nameMap = {
|
|
539
|
+
google: "Google",
|
|
540
|
+
github: "GitHub",
|
|
541
|
+
microsoft: "Microsoft",
|
|
542
|
+
apple: "Apple",
|
|
543
|
+
facebook: "Facebook",
|
|
544
|
+
twitter: "Twitter",
|
|
545
|
+
discord: "Discord",
|
|
546
|
+
gitlab: "GitLab",
|
|
547
|
+
linkedin: "LinkedIn"
|
|
548
|
+
};
|
|
549
|
+
socialProviders.push({
|
|
550
|
+
id,
|
|
551
|
+
name: nameMap[id] || id.charAt(0).toUpperCase() + id.slice(1),
|
|
552
|
+
enabled: true
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
const emailPasswordConfig = this.config.emailAndPassword ?? {};
|
|
558
|
+
const emailPassword = {
|
|
559
|
+
enabled: emailPasswordConfig.enabled !== false,
|
|
560
|
+
// Default to true
|
|
561
|
+
disableSignUp: emailPasswordConfig.disableSignUp ?? false,
|
|
562
|
+
requireEmailVerification: emailPasswordConfig.requireEmailVerification ?? false
|
|
563
|
+
};
|
|
564
|
+
const pluginConfig = this.config.plugins ?? {};
|
|
565
|
+
const features = {
|
|
566
|
+
twoFactor: pluginConfig.twoFactor ?? false,
|
|
567
|
+
passkeys: pluginConfig.passkeys ?? false,
|
|
568
|
+
magicLink: pluginConfig.magicLink ?? false,
|
|
569
|
+
organization: pluginConfig.organization ?? false
|
|
570
|
+
};
|
|
571
|
+
return {
|
|
572
|
+
emailPassword,
|
|
573
|
+
socialProviders,
|
|
574
|
+
features
|
|
575
|
+
};
|
|
576
|
+
}
|
|
511
577
|
};
|
|
512
578
|
|
|
513
579
|
// src/objects/sys-user.object.ts
|
|
@@ -1220,6 +1286,65 @@ var SysTwoFactor = ObjectSchema11.create({
|
|
|
1220
1286
|
}
|
|
1221
1287
|
});
|
|
1222
1288
|
|
|
1289
|
+
// src/objects/sys-user-preference.object.ts
|
|
1290
|
+
import { ObjectSchema as ObjectSchema12, Field as Field12 } from "@objectstack/spec/data";
|
|
1291
|
+
var SysUserPreference = ObjectSchema12.create({
|
|
1292
|
+
namespace: "sys",
|
|
1293
|
+
name: "user_preference",
|
|
1294
|
+
label: "User Preference",
|
|
1295
|
+
pluralLabel: "User Preferences",
|
|
1296
|
+
icon: "settings",
|
|
1297
|
+
isSystem: true,
|
|
1298
|
+
description: "Per-user key-value preferences (theme, locale, etc.)",
|
|
1299
|
+
titleFormat: "{key}",
|
|
1300
|
+
compactLayout: ["user_id", "key"],
|
|
1301
|
+
fields: {
|
|
1302
|
+
id: Field12.text({
|
|
1303
|
+
label: "Preference ID",
|
|
1304
|
+
required: true,
|
|
1305
|
+
readonly: true
|
|
1306
|
+
}),
|
|
1307
|
+
created_at: Field12.datetime({
|
|
1308
|
+
label: "Created At",
|
|
1309
|
+
defaultValue: "NOW()",
|
|
1310
|
+
readonly: true
|
|
1311
|
+
}),
|
|
1312
|
+
updated_at: Field12.datetime({
|
|
1313
|
+
label: "Updated At",
|
|
1314
|
+
defaultValue: "NOW()",
|
|
1315
|
+
readonly: true
|
|
1316
|
+
}),
|
|
1317
|
+
user_id: Field12.text({
|
|
1318
|
+
label: "User ID",
|
|
1319
|
+
required: true,
|
|
1320
|
+
maxLength: 255,
|
|
1321
|
+
description: "Owner user of this preference"
|
|
1322
|
+
}),
|
|
1323
|
+
key: Field12.text({
|
|
1324
|
+
label: "Key",
|
|
1325
|
+
required: true,
|
|
1326
|
+
maxLength: 255,
|
|
1327
|
+
description: "Preference key (e.g., theme, locale, plugin.ai.auto_save)"
|
|
1328
|
+
}),
|
|
1329
|
+
value: Field12.json({
|
|
1330
|
+
label: "Value",
|
|
1331
|
+
description: "Preference value (any JSON-serializable type)"
|
|
1332
|
+
})
|
|
1333
|
+
},
|
|
1334
|
+
indexes: [
|
|
1335
|
+
{ fields: ["user_id", "key"], unique: true },
|
|
1336
|
+
{ fields: ["user_id"], unique: false }
|
|
1337
|
+
],
|
|
1338
|
+
enable: {
|
|
1339
|
+
trackHistory: false,
|
|
1340
|
+
searchable: false,
|
|
1341
|
+
apiEnabled: true,
|
|
1342
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1343
|
+
trash: false,
|
|
1344
|
+
mru: false
|
|
1345
|
+
}
|
|
1346
|
+
});
|
|
1347
|
+
|
|
1223
1348
|
// src/auth-plugin.ts
|
|
1224
1349
|
var AuthPlugin = class {
|
|
1225
1350
|
constructor(options = {}) {
|
|
@@ -1265,7 +1390,8 @@ var AuthPlugin = class {
|
|
|
1265
1390
|
SysTeam,
|
|
1266
1391
|
SysTeamMember,
|
|
1267
1392
|
SysApiKey,
|
|
1268
|
-
SysTwoFactor
|
|
1393
|
+
SysTwoFactor,
|
|
1394
|
+
SysUserPreference
|
|
1269
1395
|
]
|
|
1270
1396
|
});
|
|
1271
1397
|
try {
|
|
@@ -1365,6 +1491,25 @@ var AuthPlugin = class {
|
|
|
1365
1491
|
);
|
|
1366
1492
|
}
|
|
1367
1493
|
const rawApp = httpServer.getRawApp();
|
|
1494
|
+
rawApp.get(`${basePath}/config`, async (c) => {
|
|
1495
|
+
try {
|
|
1496
|
+
const config = this.authManager.getPublicConfig();
|
|
1497
|
+
return c.json({
|
|
1498
|
+
success: true,
|
|
1499
|
+
data: config
|
|
1500
|
+
});
|
|
1501
|
+
} catch (error) {
|
|
1502
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1503
|
+
ctx.logger.error("Auth config error:", err);
|
|
1504
|
+
return c.json({
|
|
1505
|
+
success: false,
|
|
1506
|
+
error: {
|
|
1507
|
+
code: "auth_config_error",
|
|
1508
|
+
message: err.message
|
|
1509
|
+
}
|
|
1510
|
+
}, 500);
|
|
1511
|
+
}
|
|
1512
|
+
});
|
|
1368
1513
|
rawApp.all(`${basePath}/*`, async (c) => {
|
|
1369
1514
|
try {
|
|
1370
1515
|
const response = await this.authManager.handleRequest(c.req.raw);
|
|
@@ -1425,6 +1570,7 @@ export {
|
|
|
1425
1570
|
SysTeamMember,
|
|
1426
1571
|
SysTwoFactor,
|
|
1427
1572
|
SysUser,
|
|
1573
|
+
SysUserPreference,
|
|
1428
1574
|
SysVerification,
|
|
1429
1575
|
buildOrganizationPluginSchema,
|
|
1430
1576
|
buildTwoFactorPluginSchema,
|