@syncello/auth 3.3.0 → 3.3.1

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
@@ -1582,6 +1582,19 @@ var problems = {
1582
1582
  };
1583
1583
 
1584
1584
  // src/middleware/auth.ts
1585
+ var SESSION_MAX_LIFETIME_MS = AUTH_DEFAULTS.SESSION_MAX_LIFETIME_DAYS * 24 * 60 * 60 * 1e3;
1586
+ async function revokeIfPastMaxLifetime(db, sessions, sessionId, session) {
1587
+ if (Date.now() - session.createdAt <= SESSION_MAX_LIFETIME_MS) return false;
1588
+ logger_default.info("Session exceeded absolute lifetime - revoked", {
1589
+ type: "security",
1590
+ event: "session_max_lifetime_exceeded",
1591
+ severity: "low",
1592
+ sessionId: sessionId.slice(0, 8),
1593
+ userId: session.userId
1594
+ });
1595
+ await deleteSession(db, { sessions }, sessionId);
1596
+ return true;
1597
+ }
1585
1598
  async function getSessionFromCookie(db, sessions, cookieHeader, request, env) {
1586
1599
  const cookieName = getSessionCookieName(env);
1587
1600
  const cookiePattern = new RegExp(`${cookieName}=([^;]+)`);
@@ -1591,10 +1604,13 @@ async function getSessionFromCookie(db, sessions, cookieHeader, request, env) {
1591
1604
  const foundSessions = await db.select({
1592
1605
  userId: sessions.userId,
1593
1606
  expiresAt: sessions.expiresAt,
1607
+ createdAt: sessions.createdAt,
1594
1608
  fingerprint: sessions.fingerprint
1595
1609
  }).from(sessions).where((0, import_drizzle_orm4.and)((0, import_drizzle_orm4.eq)(sessions.id, sessionId), (0, import_drizzle_orm4.gt)(sessions.expiresAt, Date.now()))).limit(1);
1596
1610
  if (foundSessions.length === 0) return null;
1597
1611
  const session = foundSessions[0];
1612
+ if (await revokeIfPastMaxLifetime(db, sessions, sessionId, session)) return null;
1613
+ await refreshSession(db, { sessions }, sessionId);
1598
1614
  const userAgent = request.headers.get("user-agent") || "";
1599
1615
  const cfWorker = request.headers.get("cf-worker") || "";
1600
1616
  const clientIp = request.headers.get("cf-connecting-ip") || request.headers.get("x-real-ip") || "";
@@ -1638,10 +1654,12 @@ async function getSessionFromBearerToken(db, sessions, authHeader) {
1638
1654
  const sessionId = authHeader.slice(7);
1639
1655
  const foundSessions = await db.select({
1640
1656
  userId: sessions.userId,
1641
- expiresAt: sessions.expiresAt
1657
+ expiresAt: sessions.expiresAt,
1658
+ createdAt: sessions.createdAt
1642
1659
  }).from(sessions).where((0, import_drizzle_orm4.and)((0, import_drizzle_orm4.eq)(sessions.id, sessionId), (0, import_drizzle_orm4.gt)(sessions.expiresAt, Date.now()))).limit(1);
1643
1660
  if (foundSessions.length === 0) return null;
1644
1661
  const session = foundSessions[0];
1662
+ if (await revokeIfPastMaxLifetime(db, sessions, sessionId, session)) return null;
1645
1663
  await refreshSession(db, { sessions }, sessionId);
1646
1664
  return {
1647
1665
  userId: session.userId,
@@ -4804,10 +4822,10 @@ var statusRoute = (0, import_zod_openapi24.createRoute)({
4804
4822
  content: { "application/json": { schema: statusResponseSchema } },
4805
4823
  headers: {
4806
4824
  "Cache-Control": {
4807
- description: "Cache for 24 hours",
4825
+ description: "Cache for 60 seconds",
4808
4826
  schema: {
4809
4827
  type: "string",
4810
- example: "private, max-age=86400, stale-while-revalidate=3600"
4828
+ example: "private, max-age=60"
4811
4829
  }
4812
4830
  }
4813
4831
  }
@@ -4824,7 +4842,7 @@ var statusHandler = async (c) => {
4824
4842
  const { db, schema } = getAuthContext(c);
4825
4843
  const methods = await getUserEnabled2faMethods(db, userId, schema.user2faMethods);
4826
4844
  const backupCodes = await db.select({ id: schema.userBackupCodes.id }).from(schema.userBackupCodes).where((0, import_drizzle_orm20.and)((0, import_drizzle_orm20.eq)(schema.userBackupCodes.userId, userId), (0, import_drizzle_orm20.isNull)(schema.userBackupCodes.usedAt)));
4827
- c.header("Cache-Control", "private, max-age=86400, stale-while-revalidate=3600");
4845
+ c.header("Cache-Control", "private, max-age=60");
4828
4846
  c.header("Vary", "Cookie");
4829
4847
  return c.json({
4830
4848
  enabled: methods.length > 0,
@@ -5315,10 +5333,10 @@ var trustedDevicesGetRoute = (0, import_zod_openapi32.createRoute)({
5315
5333
  content: { "application/json": { schema: trustedDevicesResponseSchema } },
5316
5334
  headers: {
5317
5335
  "Cache-Control": {
5318
- description: "Cache for 24 hours",
5336
+ description: "Cache for 60 seconds",
5319
5337
  schema: {
5320
5338
  type: "string",
5321
- example: "private, max-age=86400, stale-while-revalidate=3600"
5339
+ example: "private, max-age=60"
5322
5340
  }
5323
5341
  }
5324
5342
  }
@@ -5342,7 +5360,7 @@ var trustedDevicesGetHandler = async (c) => {
5342
5360
  lastUsedAt: schema.userTrustedDevices.lastUsedAt,
5343
5361
  createdAt: schema.userTrustedDevices.createdAt
5344
5362
  }).from(schema.userTrustedDevices).where((0, import_drizzle_orm28.and)((0, import_drizzle_orm28.eq)(schema.userTrustedDevices.userId, userId), (0, import_drizzle_orm28.gt)(schema.userTrustedDevices.expiresAt, now)));
5345
- c.header("Cache-Control", "private, max-age=86400, stale-while-revalidate=3600");
5363
+ c.header("Cache-Control", "private, max-age=60");
5346
5364
  c.header("Vary", "Cookie");
5347
5365
  return c.json({ devices });
5348
5366
  };