@objectstack/plugin-auth 7.9.0 → 8.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.
package/dist/index.mjs CHANGED
@@ -1128,14 +1128,17 @@ var AuthManager = class {
1128
1128
  */
1129
1129
  generateSecret() {
1130
1130
  const envSecret = readEnvWithDeprecation("OS_AUTH_SECRET", ["AUTH_SECRET", "BETTER_AUTH_SECRET"]);
1131
- if (!envSecret) {
1132
- const fallbackSecret = "dev-secret-" + Date.now();
1133
- console.warn(
1134
- "\u26A0\uFE0F WARNING: No OS_AUTH_SECRET environment variable set! Using a temporary development secret. This is NOT secure for production use. Please set OS_AUTH_SECRET in your environment variables."
1131
+ if (envSecret) return envSecret;
1132
+ if (process.env.NODE_ENV === "production") {
1133
+ throw new Error(
1134
+ "[auth] OS_AUTH_SECRET is required in production but is not set. Refusing to boot with a temporary development secret \u2014 session tokens would be forgeable. Set OS_AUTH_SECRET to a strong random value."
1135
1135
  );
1136
- return fallbackSecret;
1137
1136
  }
1138
- return envSecret;
1137
+ const fallbackSecret = "dev-secret-" + Date.now();
1138
+ console.warn(
1139
+ "\u26A0\uFE0F WARNING: No OS_AUTH_SECRET environment variable set! Using a temporary development secret. This is NOT secure for production use. Please set OS_AUTH_SECRET in your environment variables."
1140
+ );
1141
+ return fallbackSecret;
1139
1142
  }
1140
1143
  /**
1141
1144
  * Update the base URL at runtime.
@@ -1341,6 +1344,37 @@ var AuthManager = class {
1341
1344
  }
1342
1345
  };
1343
1346
 
1347
+ // src/set-initial-password.ts
1348
+ async function runSetInitialPassword(authApi, request) {
1349
+ let parsed;
1350
+ try {
1351
+ parsed = await request.json();
1352
+ } catch {
1353
+ parsed = {};
1354
+ }
1355
+ const newPassword = parsed?.newPassword;
1356
+ if (typeof newPassword !== "string" || newPassword.length === 0) {
1357
+ return {
1358
+ status: 400,
1359
+ body: { success: false, error: { code: "invalid_request", message: "newPassword is required" } }
1360
+ };
1361
+ }
1362
+ try {
1363
+ await authApi.setPassword({ body: { newPassword }, headers: request.headers });
1364
+ return { status: 200, body: { success: true } };
1365
+ } catch (error) {
1366
+ return mapSetPasswordError(error);
1367
+ }
1368
+ }
1369
+ function mapSetPasswordError(error) {
1370
+ const e = error;
1371
+ const code = e?.body?.code ?? "internal";
1372
+ const message = e?.body?.message ?? e?.message ?? "set-initial-password failed";
1373
+ const rawStatus = typeof e?.statusCode === "number" ? e.statusCode : typeof e?.status === "number" ? e.status : 500;
1374
+ const status = code === "PASSWORD_ALREADY_SET" ? 409 : rawStatus;
1375
+ return { status, body: { success: false, error: { code, message } } };
1376
+ }
1377
+
1344
1378
  // src/manifest.ts
1345
1379
  import {
1346
1380
  SysAccount,
@@ -1657,53 +1691,9 @@ var AuthPlugin = class {
1657
1691
  });
1658
1692
  rawApp.post(`${basePath}/set-initial-password`, async (c) => {
1659
1693
  try {
1660
- let body = {};
1661
- try {
1662
- body = await c.req.json();
1663
- } catch {
1664
- body = {};
1665
- }
1666
- const newPassword = body?.newPassword;
1667
- if (typeof newPassword !== "string" || newPassword.length === 0) {
1668
- return c.json({ success: false, error: { code: "invalid_request", message: "newPassword is required" } }, 400);
1669
- }
1670
1694
  const authApi = await this.authManager.getApi();
1671
- const session = await authApi.getSession({ headers: c.req.raw.headers });
1672
- if (!session?.user?.id) {
1673
- return c.json({ success: false, error: { code: "unauthorized", message: "Sign in first" } }, 401);
1674
- }
1675
- const userId = session.user.id;
1676
- const authCtx = await this.authManager.getAuthContext();
1677
- if (!authCtx?.internalAdapter || !authCtx?.password) {
1678
- return c.json({ success: false, error: { code: "unavailable", message: "Auth context unavailable" } }, 503);
1679
- }
1680
- const minLen = authCtx.password?.config?.minPasswordLength ?? 8;
1681
- const maxLen = authCtx.password?.config?.maxPasswordLength ?? 128;
1682
- if (newPassword.length < minLen) {
1683
- return c.json({ success: false, error: { code: "password_too_short", message: `Password must be at least ${minLen} characters` } }, 400);
1684
- }
1685
- if (newPassword.length > maxLen) {
1686
- return c.json({ success: false, error: { code: "password_too_long", message: `Password must be at most ${maxLen} characters` } }, 400);
1687
- }
1688
- const accounts = await authCtx.internalAdapter.findAccounts(userId);
1689
- const existingCredential = accounts?.find?.((a) => a.providerId === "credential" && a.password);
1690
- if (existingCredential) {
1691
- return c.json({
1692
- success: false,
1693
- error: {
1694
- code: "credential_account_exists",
1695
- message: "A local password is already set for this account. Use change-password instead."
1696
- }
1697
- }, 409);
1698
- }
1699
- const passwordHash = await authCtx.password.hash(newPassword);
1700
- await authCtx.internalAdapter.createAccount({
1701
- userId,
1702
- providerId: "credential",
1703
- accountId: userId,
1704
- password: passwordHash
1705
- });
1706
- return c.json({ success: true });
1695
+ const { status, body } = await runSetInitialPassword(authApi, c.req.raw);
1696
+ return c.json(body, status);
1707
1697
  } catch (error) {
1708
1698
  const err = error instanceof Error ? error : new Error(String(error));
1709
1699
  ctx.logger.error("[AuthPlugin] set-initial-password failed", err);
@@ -1928,6 +1918,7 @@ export {
1928
1918
  buildTwoFactorPluginSchema,
1929
1919
  createObjectQLAdapter,
1930
1920
  createObjectQLAdapterFactory,
1931
- resolveProtocolName
1921
+ resolveProtocolName,
1922
+ runSetInitialPassword
1932
1923
  };
1933
1924
  //# sourceMappingURL=index.mjs.map