@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.js
CHANGED
|
@@ -49,6 +49,7 @@ __export(index_exports, {
|
|
|
49
49
|
SysTeamMember: () => SysTeamMember,
|
|
50
50
|
SysTwoFactor: () => SysTwoFactor,
|
|
51
51
|
SysUser: () => SysUser,
|
|
52
|
+
SysUserPreference: () => SysUserPreference,
|
|
52
53
|
SysVerification: () => SysVerification,
|
|
53
54
|
buildOrganizationPluginSchema: () => buildOrganizationPluginSchema,
|
|
54
55
|
buildTwoFactorPluginSchema: () => buildTwoFactorPluginSchema,
|
|
@@ -432,7 +433,20 @@ var AuthManager = class {
|
|
|
432
433
|
// better-auth plugins — registered based on AuthPluginConfig flags
|
|
433
434
|
plugins: this.buildPluginList(),
|
|
434
435
|
// Trusted origins for CSRF protection (supports wildcards like "https://*.example.com")
|
|
435
|
-
|
|
436
|
+
// Auto-includes origins from CORS_ORIGIN env var so CORS and CSRF stay in sync.
|
|
437
|
+
...(() => {
|
|
438
|
+
const origins = [...this.config.trustedOrigins || []];
|
|
439
|
+
const corsOrigin = process.env.CORS_ORIGIN;
|
|
440
|
+
if (corsOrigin && corsOrigin !== "*") {
|
|
441
|
+
corsOrigin.split(",").map((s) => s.trim()).filter(Boolean).forEach((o) => {
|
|
442
|
+
if (!origins.includes(o)) origins.push(o);
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
if (!origins.length && (!corsOrigin || corsOrigin === "*")) {
|
|
446
|
+
origins.push("http://localhost:*");
|
|
447
|
+
}
|
|
448
|
+
return origins.length ? { trustedOrigins: origins } : {};
|
|
449
|
+
})(),
|
|
436
450
|
// Advanced options (cross-subdomain cookies, secure cookies, CSRF, etc.)
|
|
437
451
|
...this.config.advanced ? {
|
|
438
452
|
advanced: {
|
|
@@ -568,6 +582,59 @@ var AuthManager = class {
|
|
|
568
582
|
get api() {
|
|
569
583
|
return this.getOrCreateAuth().api;
|
|
570
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* Get public authentication configuration
|
|
587
|
+
* Returns safe, non-sensitive configuration that can be exposed to the frontend
|
|
588
|
+
*
|
|
589
|
+
* This allows the frontend to discover:
|
|
590
|
+
* - Which social/OAuth providers are available
|
|
591
|
+
* - Whether email/password login is enabled
|
|
592
|
+
* - Which advanced features are enabled (2FA, magic links, etc.)
|
|
593
|
+
*/
|
|
594
|
+
getPublicConfig() {
|
|
595
|
+
const socialProviders = [];
|
|
596
|
+
if (this.config.socialProviders) {
|
|
597
|
+
for (const [id, providerConfig] of Object.entries(this.config.socialProviders)) {
|
|
598
|
+
if (providerConfig.enabled !== false) {
|
|
599
|
+
const nameMap = {
|
|
600
|
+
google: "Google",
|
|
601
|
+
github: "GitHub",
|
|
602
|
+
microsoft: "Microsoft",
|
|
603
|
+
apple: "Apple",
|
|
604
|
+
facebook: "Facebook",
|
|
605
|
+
twitter: "Twitter",
|
|
606
|
+
discord: "Discord",
|
|
607
|
+
gitlab: "GitLab",
|
|
608
|
+
linkedin: "LinkedIn"
|
|
609
|
+
};
|
|
610
|
+
socialProviders.push({
|
|
611
|
+
id,
|
|
612
|
+
name: nameMap[id] || id.charAt(0).toUpperCase() + id.slice(1),
|
|
613
|
+
enabled: true
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
const emailPasswordConfig = this.config.emailAndPassword ?? {};
|
|
619
|
+
const emailPassword = {
|
|
620
|
+
enabled: emailPasswordConfig.enabled !== false,
|
|
621
|
+
// Default to true
|
|
622
|
+
disableSignUp: emailPasswordConfig.disableSignUp ?? false,
|
|
623
|
+
requireEmailVerification: emailPasswordConfig.requireEmailVerification ?? false
|
|
624
|
+
};
|
|
625
|
+
const pluginConfig = this.config.plugins ?? {};
|
|
626
|
+
const features = {
|
|
627
|
+
twoFactor: pluginConfig.twoFactor ?? false,
|
|
628
|
+
passkeys: pluginConfig.passkeys ?? false,
|
|
629
|
+
magicLink: pluginConfig.magicLink ?? false,
|
|
630
|
+
organization: pluginConfig.organization ?? false
|
|
631
|
+
};
|
|
632
|
+
return {
|
|
633
|
+
emailPassword,
|
|
634
|
+
socialProviders,
|
|
635
|
+
features
|
|
636
|
+
};
|
|
637
|
+
}
|
|
571
638
|
};
|
|
572
639
|
|
|
573
640
|
// src/objects/sys-user.object.ts
|
|
@@ -1280,6 +1347,65 @@ var SysTwoFactor = import_data11.ObjectSchema.create({
|
|
|
1280
1347
|
}
|
|
1281
1348
|
});
|
|
1282
1349
|
|
|
1350
|
+
// src/objects/sys-user-preference.object.ts
|
|
1351
|
+
var import_data12 = require("@objectstack/spec/data");
|
|
1352
|
+
var SysUserPreference = import_data12.ObjectSchema.create({
|
|
1353
|
+
namespace: "sys",
|
|
1354
|
+
name: "user_preference",
|
|
1355
|
+
label: "User Preference",
|
|
1356
|
+
pluralLabel: "User Preferences",
|
|
1357
|
+
icon: "settings",
|
|
1358
|
+
isSystem: true,
|
|
1359
|
+
description: "Per-user key-value preferences (theme, locale, etc.)",
|
|
1360
|
+
titleFormat: "{key}",
|
|
1361
|
+
compactLayout: ["user_id", "key"],
|
|
1362
|
+
fields: {
|
|
1363
|
+
id: import_data12.Field.text({
|
|
1364
|
+
label: "Preference ID",
|
|
1365
|
+
required: true,
|
|
1366
|
+
readonly: true
|
|
1367
|
+
}),
|
|
1368
|
+
created_at: import_data12.Field.datetime({
|
|
1369
|
+
label: "Created At",
|
|
1370
|
+
defaultValue: "NOW()",
|
|
1371
|
+
readonly: true
|
|
1372
|
+
}),
|
|
1373
|
+
updated_at: import_data12.Field.datetime({
|
|
1374
|
+
label: "Updated At",
|
|
1375
|
+
defaultValue: "NOW()",
|
|
1376
|
+
readonly: true
|
|
1377
|
+
}),
|
|
1378
|
+
user_id: import_data12.Field.text({
|
|
1379
|
+
label: "User ID",
|
|
1380
|
+
required: true,
|
|
1381
|
+
maxLength: 255,
|
|
1382
|
+
description: "Owner user of this preference"
|
|
1383
|
+
}),
|
|
1384
|
+
key: import_data12.Field.text({
|
|
1385
|
+
label: "Key",
|
|
1386
|
+
required: true,
|
|
1387
|
+
maxLength: 255,
|
|
1388
|
+
description: "Preference key (e.g., theme, locale, plugin.ai.auto_save)"
|
|
1389
|
+
}),
|
|
1390
|
+
value: import_data12.Field.json({
|
|
1391
|
+
label: "Value",
|
|
1392
|
+
description: "Preference value (any JSON-serializable type)"
|
|
1393
|
+
})
|
|
1394
|
+
},
|
|
1395
|
+
indexes: [
|
|
1396
|
+
{ fields: ["user_id", "key"], unique: true },
|
|
1397
|
+
{ fields: ["user_id"], unique: false }
|
|
1398
|
+
],
|
|
1399
|
+
enable: {
|
|
1400
|
+
trackHistory: false,
|
|
1401
|
+
searchable: false,
|
|
1402
|
+
apiEnabled: true,
|
|
1403
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1404
|
+
trash: false,
|
|
1405
|
+
mru: false
|
|
1406
|
+
}
|
|
1407
|
+
});
|
|
1408
|
+
|
|
1283
1409
|
// src/auth-plugin.ts
|
|
1284
1410
|
var AuthPlugin = class {
|
|
1285
1411
|
constructor(options = {}) {
|
|
@@ -1325,7 +1451,8 @@ var AuthPlugin = class {
|
|
|
1325
1451
|
SysTeam,
|
|
1326
1452
|
SysTeamMember,
|
|
1327
1453
|
SysApiKey,
|
|
1328
|
-
SysTwoFactor
|
|
1454
|
+
SysTwoFactor,
|
|
1455
|
+
SysUserPreference
|
|
1329
1456
|
]
|
|
1330
1457
|
});
|
|
1331
1458
|
try {
|
|
@@ -1425,6 +1552,25 @@ var AuthPlugin = class {
|
|
|
1425
1552
|
);
|
|
1426
1553
|
}
|
|
1427
1554
|
const rawApp = httpServer.getRawApp();
|
|
1555
|
+
rawApp.get(`${basePath}/config`, async (c) => {
|
|
1556
|
+
try {
|
|
1557
|
+
const config = this.authManager.getPublicConfig();
|
|
1558
|
+
return c.json({
|
|
1559
|
+
success: true,
|
|
1560
|
+
data: config
|
|
1561
|
+
});
|
|
1562
|
+
} catch (error) {
|
|
1563
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1564
|
+
ctx.logger.error("Auth config error:", err);
|
|
1565
|
+
return c.json({
|
|
1566
|
+
success: false,
|
|
1567
|
+
error: {
|
|
1568
|
+
code: "auth_config_error",
|
|
1569
|
+
message: err.message
|
|
1570
|
+
}
|
|
1571
|
+
}, 500);
|
|
1572
|
+
}
|
|
1573
|
+
});
|
|
1428
1574
|
rawApp.all(`${basePath}/*`, async (c) => {
|
|
1429
1575
|
try {
|
|
1430
1576
|
const response = await this.authManager.handleRequest(c.req.raw);
|
|
@@ -1486,6 +1632,7 @@ var AuthPlugin = class {
|
|
|
1486
1632
|
SysTeamMember,
|
|
1487
1633
|
SysTwoFactor,
|
|
1488
1634
|
SysUser,
|
|
1635
|
+
SysUserPreference,
|
|
1489
1636
|
SysVerification,
|
|
1490
1637
|
buildOrganizationPluginSchema,
|
|
1491
1638
|
buildTwoFactorPluginSchema,
|