@syncello/auth 3.2.1 → 3.3.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.cjs CHANGED
@@ -644,6 +644,9 @@ async function hashToken(token) {
644
644
  // src/core/config.ts
645
645
  var AUTH_DEFAULTS = {
646
646
  SESSION_TTL_DAYS: 7,
647
+ // Absolute cap: a session dies this long after creation regardless of
648
+ // sliding-window activity (limits the value of a stolen session token).
649
+ SESSION_MAX_LIFETIME_DAYS: 30,
647
650
  LOCKOUT_DURATION_MINUTES: 30,
648
651
  LOCKOUT_MAX_ATTEMPTS: 5,
649
652
  PASSWORD_RESET_TTL_MINUTES: 15,
@@ -676,7 +679,7 @@ async function createSession(db, tables2, userId, fingerprint, ipAddress, sessio
676
679
  });
677
680
  return sessionId;
678
681
  }
679
- async function validateSession(db, tables2, sessionId, currentFingerprint) {
682
+ async function validateSession(db, tables2, sessionId, currentFingerprint, sessionMaxLifetimeMs = AUTH_DEFAULTS.SESSION_MAX_LIFETIME_DAYS * 24 * 60 * 60 * 1e3) {
680
683
  const { sessions, users } = tables2;
681
684
  logger_default.debug("Validating session", {
682
685
  sessionId: sessionId?.slice(0, 8),
@@ -703,6 +706,17 @@ async function validateSession(db, tables2, sessionId, currentFingerprint) {
703
706
  return null;
704
707
  }
705
708
  const row = result[0];
709
+ if (Date.now() - row.sessionCreatedAt > sessionMaxLifetimeMs) {
710
+ logger_default.info("Session exceeded absolute lifetime - revoked", {
711
+ type: "security",
712
+ event: "session_max_lifetime_exceeded",
713
+ severity: "low",
714
+ sessionId: sessionId.slice(0, 8),
715
+ userId: row.userId
716
+ });
717
+ await deleteSession(db, { sessions }, sessionId);
718
+ return null;
719
+ }
706
720
  if (currentFingerprint && row.sessionFingerprint && row.sessionFingerprint !== currentFingerprint) {
707
721
  logger_default.info("Session fingerprint mismatch - likely SSR request", {
708
722
  type: "security",
@@ -981,8 +995,7 @@ function getSessionCookieName(env) {
981
995
  return COOKIE_NAMES[environment] || COOKIE_NAMES.development;
982
996
  }
983
997
  function isProduction(env) {
984
- const environment = env?.ENVIRONMENT;
985
- return environment === "production" || environment === "staging";
998
+ return env?.ENVIRONMENT !== "development";
986
999
  }
987
1000
  function getCookieSecurityFlags(env) {
988
1001
  if (isProduction(env)) {
@@ -2627,7 +2640,7 @@ var CloudflareEmailAdapter = class {
2627
2640
  logger_default.error("Cloudflare send error", {
2628
2641
  provider: this.providerName,
2629
2642
  error: errorText,
2630
- rawError: error,
2643
+ errorName: error instanceof Error ? error.name : typeof error,
2631
2644
  to: options.to,
2632
2645
  subject: options.subject
2633
2646
  });