@objectstack/plugin-auth 6.3.0 → 6.4.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.
- package/dist/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +70 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +70 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/dist/index.mjs
CHANGED
|
@@ -1081,7 +1081,8 @@ var AuthManager = class {
|
|
|
1081
1081
|
*/
|
|
1082
1082
|
async handleRequest(request) {
|
|
1083
1083
|
const auth = await this.getOrCreateAuth();
|
|
1084
|
-
const
|
|
1084
|
+
const { runWithRequestState } = await import("@better-auth/core/context");
|
|
1085
|
+
const response = await runWithRequestState(/* @__PURE__ */ new WeakMap(), () => auth.handler(request));
|
|
1085
1086
|
if (response.status >= 500) {
|
|
1086
1087
|
try {
|
|
1087
1088
|
const body = await response.clone().text();
|
|
@@ -1100,6 +1101,19 @@ var AuthManager = class {
|
|
|
1100
1101
|
const auth = await this.getOrCreateAuth();
|
|
1101
1102
|
return auth.api;
|
|
1102
1103
|
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Get the underlying better-auth context for low-level operations such as
|
|
1106
|
+
* `internalAdapter.createAccount` / `password.hash`.
|
|
1107
|
+
*
|
|
1108
|
+
* Used by routes that need to write to better-auth's tables outside the
|
|
1109
|
+
* normal endpoint surface — currently only `set-initial-password`, which
|
|
1110
|
+
* provisions a credential account for SSO-onboarded users so they can
|
|
1111
|
+
* sign in with email/password going forward.
|
|
1112
|
+
*/
|
|
1113
|
+
async getAuthContext() {
|
|
1114
|
+
const auth = await this.getOrCreateAuth();
|
|
1115
|
+
return auth.$context;
|
|
1116
|
+
}
|
|
1103
1117
|
// ---------------------------------------------------------------------------
|
|
1104
1118
|
// Device Flow (CLI browser-based login)
|
|
1105
1119
|
//
|
|
@@ -1416,6 +1430,61 @@ var AuthPlugin = class {
|
|
|
1416
1430
|
return c.json({ hasOwner: true });
|
|
1417
1431
|
}
|
|
1418
1432
|
});
|
|
1433
|
+
rawApp.post(`${basePath}/set-initial-password`, async (c) => {
|
|
1434
|
+
try {
|
|
1435
|
+
let body = {};
|
|
1436
|
+
try {
|
|
1437
|
+
body = await c.req.json();
|
|
1438
|
+
} catch {
|
|
1439
|
+
body = {};
|
|
1440
|
+
}
|
|
1441
|
+
const newPassword = body?.newPassword;
|
|
1442
|
+
if (typeof newPassword !== "string" || newPassword.length === 0) {
|
|
1443
|
+
return c.json({ success: false, error: { code: "invalid_request", message: "newPassword is required" } }, 400);
|
|
1444
|
+
}
|
|
1445
|
+
const authApi = await this.authManager.getApi();
|
|
1446
|
+
const session = await authApi.getSession({ headers: c.req.raw.headers });
|
|
1447
|
+
if (!session?.user?.id) {
|
|
1448
|
+
return c.json({ success: false, error: { code: "unauthorized", message: "Sign in first" } }, 401);
|
|
1449
|
+
}
|
|
1450
|
+
const userId = session.user.id;
|
|
1451
|
+
const authCtx = await this.authManager.getAuthContext();
|
|
1452
|
+
if (!authCtx?.internalAdapter || !authCtx?.password) {
|
|
1453
|
+
return c.json({ success: false, error: { code: "unavailable", message: "Auth context unavailable" } }, 503);
|
|
1454
|
+
}
|
|
1455
|
+
const minLen = authCtx.password?.config?.minPasswordLength ?? 8;
|
|
1456
|
+
const maxLen = authCtx.password?.config?.maxPasswordLength ?? 128;
|
|
1457
|
+
if (newPassword.length < minLen) {
|
|
1458
|
+
return c.json({ success: false, error: { code: "password_too_short", message: `Password must be at least ${minLen} characters` } }, 400);
|
|
1459
|
+
}
|
|
1460
|
+
if (newPassword.length > maxLen) {
|
|
1461
|
+
return c.json({ success: false, error: { code: "password_too_long", message: `Password must be at most ${maxLen} characters` } }, 400);
|
|
1462
|
+
}
|
|
1463
|
+
const accounts = await authCtx.internalAdapter.findAccounts(userId);
|
|
1464
|
+
const existingCredential = accounts?.find?.((a) => a.providerId === "credential" && a.password);
|
|
1465
|
+
if (existingCredential) {
|
|
1466
|
+
return c.json({
|
|
1467
|
+
success: false,
|
|
1468
|
+
error: {
|
|
1469
|
+
code: "credential_account_exists",
|
|
1470
|
+
message: "A local password is already set for this account. Use change-password instead."
|
|
1471
|
+
}
|
|
1472
|
+
}, 409);
|
|
1473
|
+
}
|
|
1474
|
+
const passwordHash = await authCtx.password.hash(newPassword);
|
|
1475
|
+
await authCtx.internalAdapter.createAccount({
|
|
1476
|
+
userId,
|
|
1477
|
+
providerId: "credential",
|
|
1478
|
+
accountId: userId,
|
|
1479
|
+
password: passwordHash
|
|
1480
|
+
});
|
|
1481
|
+
return c.json({ success: true });
|
|
1482
|
+
} catch (error) {
|
|
1483
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1484
|
+
ctx.logger.error("[AuthPlugin] set-initial-password failed", err);
|
|
1485
|
+
return c.json({ success: false, error: { code: "internal", message: err.message } }, 500);
|
|
1486
|
+
}
|
|
1487
|
+
});
|
|
1419
1488
|
rawApp.all(`${basePath}/*`, async (c) => {
|
|
1420
1489
|
try {
|
|
1421
1490
|
const response = await this.authManager.handleRequest(c.req.raw);
|