{"version":3,"file":"session-manager.mjs","sources":["../../src/services/session-manager.ts"],"sourcesContent":["import crypto from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport type { VerifyOptions, Algorithm } from 'jsonwebtoken';\nimport type { Database } from '@strapi/database';\nimport { DEFAULT_ALGORITHM } from '../constants';\n\nexport interface SessionProvider {\n  create(session: SessionData): Promise<SessionData>;\n  findBySessionId(sessionId: string): Promise<SessionData | null>;\n  findByUser(criteria: {\n    userId: string;\n    origin: string;\n    status?: SessionData['status'];\n  }): Promise<SessionData[]>;\n  updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void>;\n  deleteBySessionId(sessionId: string): Promise<void>;\n  deleteExpired(): Promise<void>;\n  deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void>;\n}\n\nexport interface SessionData {\n  id?: string;\n  userId: string; // User ID stored as string (key-value store)\n  sessionId: string;\n  deviceId?: string; // Optional for origins that don't need device tracking\n  origin: string;\n  childId?: string | null;\n\n  type?: 'refresh' | 'session';\n  status?: 'active' | 'rotated' | 'revoked';\n  // Free-form, origin-defined metadata (e.g. deviceName, loginAt). The session manager only\n  // persists and returns this verbatim; it never interprets its contents.\n  metadata?: Record<string, unknown> | null;\n  expiresAt: Date;\n  absoluteExpiresAt?: Date | null;\n  createdAt?: Date;\n  updatedAt?: Date;\n}\n\nexport interface RefreshTokenPayload {\n  userId: string;\n  sessionId: string;\n  type: 'refresh';\n  exp: number;\n  iat: number;\n}\n\nexport interface AccessTokenPayload {\n  userId: string;\n  sessionId: string;\n  type: 'access';\n  exp: number;\n  iat: number;\n}\n\nexport type TokenPayload = RefreshTokenPayload | AccessTokenPayload;\n\nexport interface ValidateRefreshTokenResult {\n  isValid: boolean;\n  userId?: string;\n  sessionId?: string;\n  error?:\n    | 'invalid_token'\n    | 'token_expired'\n    | 'session_not_found'\n    | 'session_expired'\n    | 'wrong_token_type';\n}\n\nclass DatabaseSessionProvider implements SessionProvider {\n  private db: Database;\n\n  private contentType: string;\n\n  constructor(db: Database, contentType: string) {\n    this.db = db;\n    this.contentType = contentType;\n  }\n\n  async create(session: SessionData): Promise<SessionData> {\n    const result = await this.db.query(this.contentType).create({\n      data: session,\n    });\n    return result as SessionData;\n  }\n\n  async findBySessionId(sessionId: string): Promise<SessionData | null> {\n    const result = await this.db.query(this.contentType).findOne({\n      where: { sessionId },\n    });\n    return result as SessionData | null;\n  }\n\n  async findByUser(criteria: {\n    userId: string;\n    origin: string;\n    status?: SessionData['status'];\n  }): Promise<SessionData[]> {\n    const results = await this.db.query(this.contentType).findMany({\n      where: {\n        userId: criteria.userId,\n        origin: criteria.origin,\n        ...(criteria.status ? { status: criteria.status } : {}),\n      },\n      orderBy: { createdAt: 'DESC' },\n    });\n    return results as SessionData[];\n  }\n\n  async updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void> {\n    await this.db.query(this.contentType).update({ where: { sessionId }, data });\n  }\n\n  async deleteBySessionId(sessionId: string): Promise<void> {\n    await this.db.query(this.contentType).delete({\n      where: { sessionId },\n    });\n  }\n\n  async deleteExpired(): Promise<void> {\n    await this.db.query(this.contentType).deleteMany({\n      where: { absoluteExpiresAt: { $lt: new Date() } },\n    });\n  }\n\n  async deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void> {\n    await this.db.query(this.contentType).deleteMany({\n      where: {\n        ...(criteria.userId ? { userId: criteria.userId } : {}),\n        ...(criteria.origin ? { origin: criteria.origin } : {}),\n        ...(criteria.deviceId ? { deviceId: criteria.deviceId } : {}),\n      },\n    });\n  }\n}\n\nexport interface SessionManagerConfig {\n  jwtSecret?: string;\n  accessTokenLifespan: number;\n  maxRefreshTokenLifespan: number;\n  idleRefreshTokenLifespan: number;\n  maxSessionLifespan: number;\n  idleSessionLifespan: number;\n  algorithm?: Algorithm;\n  jwtOptions?: Record<string, unknown>;\n}\n\nclass OriginSessionManager {\n  private sessionManager: SessionManager;\n\n  private origin: string;\n\n  constructor(sessionManager: SessionManager, origin: string) {\n    this.sessionManager = sessionManager;\n    this.origin = origin;\n  }\n\n  async generateRefreshToken(\n    userId: string,\n    deviceId: string | undefined,\n    options?: { type?: 'refresh' | 'session'; metadata?: Record<string, unknown> }\n  ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n    return this.sessionManager.generateRefreshToken(userId, deviceId, this.origin, options);\n  }\n\n  async generateAccessToken(refreshToken: string): Promise<{ token: string } | { error: string }> {\n    return this.sessionManager.generateAccessToken(refreshToken, this.origin);\n  }\n\n  async rotateRefreshToken(refreshToken: string): Promise<\n    | {\n        token: string;\n        sessionId: string;\n        absoluteExpiresAt: string;\n        type: 'refresh' | 'session';\n      }\n    | { error: string }\n  > {\n    return this.sessionManager.rotateRefreshToken(refreshToken, this.origin);\n  }\n\n  validateAccessToken(\n    token: string\n  ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n    return this.sessionManager.validateAccessToken(token, this.origin);\n  }\n\n  async validateRefreshToken(token: string): Promise<ValidateRefreshTokenResult> {\n    return this.sessionManager.validateRefreshToken(token, this.origin);\n  }\n\n  async invalidateRefreshToken(userId: string, deviceId?: string): Promise<void> {\n    return this.sessionManager.invalidateRefreshToken(this.origin, userId, deviceId);\n  }\n\n  /**\n   * Lists the active sessions of a user for this origin. Rotated/expired records\n   * are excluded so each live login family yields a single entry.\n   */\n  async listSessions(userId: string): Promise<SessionData[]> {\n    return this.sessionManager.listSessions(this.origin, userId);\n  }\n\n  /**\n   * Revokes a single session by id, but only if it belongs to the given user and origin.\n   * Returns true when a matching session was found and deleted.\n   */\n  async revokeSessionById(userId: string, sessionId: string): Promise<boolean> {\n    return this.sessionManager.revokeSessionById(this.origin, userId, sessionId);\n  }\n\n  /**\n   * Returns true when a session exists and is not expired for this origin.\n   * If the session exists but is expired, it will be deleted as part of this check.\n   */\n  async isSessionActive(sessionId: string): Promise<boolean> {\n    return this.sessionManager.isSessionActive(sessionId, this.origin);\n  }\n}\n\nclass SessionManager {\n  private provider: SessionProvider;\n\n  // Store origin-specific configurations\n  private originConfigs: Map<string, SessionManagerConfig> = new Map();\n\n  // Run expired cleanup only every N calls to avoid extra queries\n  private cleanupInvocationCounter: number = 0;\n\n  private readonly cleanupEveryCalls: number = 50;\n\n  constructor(provider: SessionProvider) {\n    this.provider = provider;\n  }\n\n  /**\n   * Define configuration for a specific origin\n   */\n  defineOrigin(origin: string, config: SessionManagerConfig): void {\n    this.originConfigs.set(origin, config);\n  }\n\n  /**\n   * Check if an origin is defined\n   */\n  hasOrigin(origin: string): boolean {\n    return this.originConfigs.has(origin);\n  }\n\n  /**\n   * Get configuration for a specific origin, throw error if not defined\n   */\n  private getConfigForOrigin(origin: string): SessionManagerConfig {\n    const originConfig = this.originConfigs.get(origin);\n    if (originConfig) {\n      return originConfig;\n    }\n    throw new Error(\n      `SessionManager: Origin '${origin}' is not defined. Please define it using defineOrigin('${origin}', config).`\n    );\n  }\n\n  /**\n   * Get the appropriate JWT key based on the algorithm\n   */\n  private getJwtKey(\n    config: SessionManagerConfig,\n    algorithm: Algorithm,\n    operation: 'sign' | 'verify'\n  ): string {\n    const isAsymmetric =\n      algorithm.startsWith('RS') || algorithm.startsWith('ES') || algorithm.startsWith('PS');\n\n    if (isAsymmetric) {\n      // For asymmetric algorithms, check if user has provided proper key configuration\n      if (operation === 'sign') {\n        const privateKey = config.jwtOptions?.privateKey as string;\n        if (privateKey) {\n          return privateKey;\n        }\n        throw new Error(\n          `SessionManager: Private key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.privateKey.`\n        );\n      } else {\n        const publicKey = config.jwtOptions?.publicKey as string;\n        if (publicKey) {\n          return publicKey;\n        }\n        throw new Error(\n          `SessionManager: Public key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.publicKey.`\n        );\n      }\n    } else {\n      if (!config.jwtSecret) {\n        throw new Error(\n          `SessionManager: Secret key is required for symmetric algorithm ${algorithm}`\n        );\n      }\n      return config.jwtSecret;\n    }\n  }\n\n  generateSessionId(): string {\n    return crypto.randomBytes(16).toString('hex');\n  }\n\n  private async maybeCleanupExpired(): Promise<void> {\n    this.cleanupInvocationCounter += 1;\n    if (this.cleanupInvocationCounter >= this.cleanupEveryCalls) {\n      this.cleanupInvocationCounter = 0;\n\n      await this.provider.deleteExpired();\n    }\n  }\n\n  /**\n   * Get the cleanup every calls threshold\n   */\n  get cleanupThreshold(): number {\n    return this.cleanupEveryCalls;\n  }\n\n  async generateRefreshToken(\n    userId: string,\n    deviceId: string | undefined,\n    origin: string,\n    options?: { type?: 'refresh' | 'session'; metadata?: Record<string, unknown> }\n  ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n\n    await this.maybeCleanupExpired();\n\n    const config = this.getConfigForOrigin(origin);\n    const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n    const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n    const sessionId = this.generateSessionId();\n    const tokenType = options?.type ?? 'refresh';\n    const isRefresh = tokenType === 'refresh';\n\n    const idleLifespan = isRefresh ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n    const maxLifespan = isRefresh ? config.maxRefreshTokenLifespan : config.maxSessionLifespan;\n\n    const now = Date.now();\n    const expiresAt = new Date(now + idleLifespan * 1000);\n    const absoluteExpiresAt = new Date(now + maxLifespan * 1000);\n\n    // Create the root record first so createdAt can be used for signing.\n    const record = await this.provider.create({\n      userId,\n      sessionId,\n      ...(deviceId && { deviceId }),\n      origin,\n      childId: null,\n      type: tokenType,\n      status: 'active',\n      ...(options?.metadata ? { metadata: options.metadata } : {}),\n      expiresAt,\n      absoluteExpiresAt,\n    });\n\n    const issuedAtSeconds = Math.floor(new Date(record.createdAt ?? new Date()).getTime() / 1000);\n    const expiresAtSeconds = Math.floor(new Date(record.expiresAt).getTime() / 1000);\n\n    const payload: RefreshTokenPayload = {\n      userId,\n      sessionId,\n      type: 'refresh',\n      iat: issuedAtSeconds,\n      exp: expiresAtSeconds,\n    };\n\n    // Filter out conflicting options that are already handled by the payload or used for key selection\n    const jwtOptions = config.jwtOptions || {};\n    const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n    const token = jwt.sign(payload, jwtKey, {\n      algorithm,\n      noTimestamp: true,\n      ...jwtSignOptions,\n    });\n\n    return {\n      token,\n      sessionId,\n      absoluteExpiresAt: absoluteExpiresAt.toISOString(),\n    };\n  }\n\n  validateAccessToken(\n    token: string,\n    origin: string\n  ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n\n    try {\n      const config = this.getConfigForOrigin(origin);\n      const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n      const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n      const payload = jwt.verify(token, jwtKey, {\n        algorithms: [algorithm],\n        ...config.jwtOptions,\n      }) as TokenPayload;\n\n      // Ensure this is an access token\n      if (!payload || payload.type !== 'access') {\n        return { isValid: false, payload: null };\n      }\n\n      return { isValid: true, payload };\n    } catch (err) {\n      return { isValid: false, payload: null };\n    }\n  }\n\n  async validateRefreshToken(token: string, origin: string): Promise<ValidateRefreshTokenResult> {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n\n    try {\n      const config = this.getConfigForOrigin(origin);\n      const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n      const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n      const verifyOptions: VerifyOptions = {\n        algorithms: [algorithm],\n        ...config.jwtOptions,\n      };\n\n      const payload = jwt.verify(token, jwtKey, verifyOptions) as RefreshTokenPayload;\n\n      if (payload.type !== 'refresh') {\n        return { isValid: false };\n      }\n\n      const session = await this.provider.findBySessionId(payload.sessionId);\n      if (!session) {\n        return { isValid: false };\n      }\n\n      const now = new Date();\n      if (new Date(session.expiresAt) <= now) {\n        return { isValid: false };\n      }\n\n      // Absolute family expiry check\n      if (session.absoluteExpiresAt && new Date(session.absoluteExpiresAt) <= now) {\n        return { isValid: false };\n      }\n\n      // Only 'active' sessions are eligible to create access tokens.\n      if (session.status !== 'active') {\n        return { isValid: false };\n      }\n\n      if (session.userId !== payload.userId) {\n        return { isValid: false };\n      }\n\n      return {\n        isValid: true,\n        userId: payload.userId,\n        sessionId: payload.sessionId,\n      };\n    } catch (error: any) {\n      if (error instanceof jwt.JsonWebTokenError) {\n        return { isValid: false };\n      }\n\n      throw error;\n    }\n  }\n\n  async invalidateRefreshToken(origin: string, userId: string, deviceId?: string): Promise<void> {\n    await this.provider.deleteBy({ userId, origin, deviceId });\n  }\n\n  async listSessions(origin: string, userId: string): Promise<SessionData[]> {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n\n    return this.provider.findByUser({ userId, origin, status: 'active' });\n  }\n\n  async revokeSessionById(origin: string, userId: string, sessionId: string): Promise<boolean> {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n\n    const session = await this.provider.findBySessionId(sessionId);\n\n    // Only allow revoking a session that belongs to the requesting user and origin.\n    if (session?.userId !== userId || session?.origin !== origin) {\n      return false;\n    }\n\n    await this.provider.deleteBySessionId(sessionId);\n    return true;\n  }\n\n  async generateAccessToken(\n    refreshToken: string,\n    origin: string\n  ): Promise<{ token: string } | { error: string }> {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n\n    const validation = await this.validateRefreshToken(refreshToken, origin);\n\n    if (!validation.isValid) {\n      return { error: 'invalid_refresh_token' };\n    }\n\n    const payload: Omit<AccessTokenPayload, 'iat' | 'exp'> = {\n      userId: String(validation.userId!),\n      sessionId: validation.sessionId!,\n      type: 'access',\n    };\n\n    const config = this.getConfigForOrigin(origin);\n    const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n    const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n    // Filter out conflicting options that are already handled by the payload or used for key selection\n    const jwtOptions = config.jwtOptions || {};\n    const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n    const token = jwt.sign(payload, jwtKey, {\n      algorithm,\n      expiresIn: config.accessTokenLifespan,\n      ...jwtSignOptions,\n    });\n\n    return { token };\n  }\n\n  async rotateRefreshToken(\n    refreshToken: string,\n    origin: string\n  ): Promise<\n    | {\n        token: string;\n        sessionId: string;\n        absoluteExpiresAt: string;\n        type: 'refresh' | 'session';\n      }\n    | { error: string }\n  > {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n\n    try {\n      const config = this.getConfigForOrigin(origin);\n      const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n      const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n      const payload = jwt.verify(refreshToken, jwtKey, {\n        algorithms: [algorithm],\n        ...config.jwtOptions,\n      }) as RefreshTokenPayload;\n\n      if (!payload || payload.type !== 'refresh') {\n        return { error: 'invalid_refresh_token' };\n      }\n\n      const current = await this.provider.findBySessionId(payload.sessionId);\n      if (!current) {\n        return { error: 'invalid_refresh_token' };\n      }\n\n      // If parent already has a child, return the same child token\n      if (current.childId) {\n        const child = await this.provider.findBySessionId(current.childId);\n\n        if (child) {\n          const childIat = Math.floor(new Date(child.createdAt ?? new Date()).getTime() / 1000);\n          const childExp = Math.floor(new Date(child.expiresAt).getTime() / 1000);\n\n          const childPayload: RefreshTokenPayload = {\n            userId: child.userId,\n            sessionId: child.sessionId,\n            type: 'refresh',\n            iat: childIat,\n            exp: childExp,\n          };\n\n          // Filter out conflicting options that are already handled by the payload\n          const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n          const childToken = jwt.sign(childPayload, jwtKey, {\n            algorithm,\n            noTimestamp: true,\n            ...jwtSignOptions,\n          });\n\n          let absoluteExpiresAt;\n          if (child.absoluteExpiresAt) {\n            absoluteExpiresAt =\n              typeof child.absoluteExpiresAt === 'string'\n                ? child.absoluteExpiresAt\n                : child.absoluteExpiresAt.toISOString();\n          } else {\n            absoluteExpiresAt = new Date(0).toISOString();\n          }\n\n          return {\n            token: childToken,\n            sessionId: child.sessionId,\n            absoluteExpiresAt,\n            type: child.type ?? 'refresh',\n          };\n        }\n      }\n\n      const now = Date.now();\n      const tokenType = current.type ?? 'refresh';\n      const idleLifespan =\n        tokenType === 'refresh' ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n      // Enforce idle window since creation of the current token\n      if (current.createdAt && now - new Date(current.createdAt).getTime() > idleLifespan * 1000) {\n        return { error: 'idle_window_elapsed' };\n      }\n\n      // Enforce max family window using absoluteExpiresAt\n      const absolute = current.absoluteExpiresAt\n        ? new Date(current.absoluteExpiresAt).getTime()\n        : now;\n      if (absolute <= now) {\n        return { error: 'max_window_elapsed' };\n      }\n\n      // Create child token\n      const childSessionId = this.generateSessionId();\n      const childExpiresAt = new Date(now + idleLifespan * 1000);\n\n      const childRecord = await this.provider.create({\n        userId: current.userId,\n        sessionId: childSessionId,\n        ...(current.deviceId && { deviceId: current.deviceId }),\n        origin: current.origin,\n        childId: null,\n        type: tokenType,\n        status: 'active',\n        // Preserve origin-defined metadata (e.g. deviceName, loginAt) across rotation so the\n        // active record always reflects the original session details.\n        ...(current.metadata ? { metadata: current.metadata } : {}),\n        expiresAt: childExpiresAt,\n        absoluteExpiresAt: current.absoluteExpiresAt ?? new Date(absolute),\n      });\n\n      const childIat = Math.floor(new Date(childRecord.createdAt ?? new Date()).getTime() / 1000);\n      const childExp = Math.floor(new Date(childRecord.expiresAt).getTime() / 1000);\n      const payloadOut: RefreshTokenPayload = {\n        userId: current.userId,\n        sessionId: childSessionId,\n        type: 'refresh',\n        iat: childIat,\n        exp: childExp,\n      };\n      // Filter out conflicting options that are already handled by the payload\n      const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n      const childToken = jwt.sign(payloadOut, jwtKey, {\n        algorithm,\n        noTimestamp: true,\n        ...jwtSignOptions,\n      });\n\n      await this.provider.updateBySessionId(current.sessionId, {\n        status: 'rotated',\n        childId: childSessionId,\n      });\n\n      let absoluteExpiresAt;\n      if (childRecord.absoluteExpiresAt) {\n        absoluteExpiresAt =\n          typeof childRecord.absoluteExpiresAt === 'string'\n            ? childRecord.absoluteExpiresAt\n            : childRecord.absoluteExpiresAt.toISOString();\n      } else {\n        absoluteExpiresAt = new Date(absolute).toISOString();\n      }\n\n      return {\n        token: childToken,\n        sessionId: childSessionId,\n        absoluteExpiresAt,\n        type: tokenType,\n      };\n    } catch {\n      return { error: 'invalid_refresh_token' };\n    }\n  }\n\n  /**\n   * Returns true when a session exists and is not expired.\n   * If the session exists but is expired, it will be deleted as part of this check.\n   */\n  async isSessionActive(sessionId: string, origin: string): Promise<boolean> {\n    const session = await this.provider.findBySessionId(sessionId);\n    if (!session) {\n      return false;\n    }\n\n    if (session.origin !== origin) {\n      return false;\n    }\n\n    if (new Date(session.expiresAt) <= new Date()) {\n      // Clean up expired session eagerly\n      await this.provider.deleteBySessionId(sessionId);\n\n      return false;\n    }\n\n    return true;\n  }\n}\n\nconst createDatabaseProvider = (db: Database, contentType: string): SessionProvider => {\n  return new DatabaseSessionProvider(db, contentType);\n};\n\nconst createSessionManager = ({\n  db,\n}: {\n  db: Database;\n}): SessionManager & ((origin: string) => OriginSessionManager) => {\n  const provider = createDatabaseProvider(db, 'admin::session');\n  const sessionManager = new SessionManager(provider);\n\n  // Add callable functionality\n  const fluentApi = (origin: string): OriginSessionManager => {\n    if (!origin || typeof origin !== 'string') {\n      throw new Error(\n        'SessionManager: Origin parameter is required and must be a non-empty string'\n      );\n    }\n    return new OriginSessionManager(sessionManager, origin);\n  };\n\n  // Attach only the public SessionManagerService API to the callable\n  const api = fluentApi as unknown as any;\n  api.generateSessionId = sessionManager.generateSessionId.bind(sessionManager);\n  api.defineOrigin = sessionManager.defineOrigin.bind(sessionManager);\n  api.hasOrigin = sessionManager.hasOrigin.bind(sessionManager);\n  // Note: isSessionActive is origin-scoped and exposed on OriginSessionManager only\n\n  // Forward the cleanupThreshold getter (used in tests)\n  Object.defineProperty(api, 'cleanupThreshold', {\n    get() {\n      return sessionManager.cleanupThreshold;\n    },\n    enumerable: true,\n  });\n\n  return api as SessionManager & ((origin: string) => OriginSessionManager);\n};\n\nexport { createSessionManager, createDatabaseProvider };\n"],"names":["DatabaseSessionProvider","create","session","result","db","query","contentType","data","findBySessionId","sessionId","findOne","where","findByUser","criteria","results","findMany","userId","origin","status","orderBy","createdAt","updateBySessionId","update","deleteBySessionId","delete","deleteExpired","deleteMany","absoluteExpiresAt","$lt","Date","deleteBy","deviceId","OriginSessionManager","generateRefreshToken","options","sessionManager","generateAccessToken","refreshToken","rotateRefreshToken","validateAccessToken","token","validateRefreshToken","invalidateRefreshToken","listSessions","revokeSessionById","isSessionActive","SessionManager","defineOrigin","config","originConfigs","set","hasOrigin","has","getConfigForOrigin","originConfig","get","Error","getJwtKey","algorithm","operation","isAsymmetric","startsWith","privateKey","jwtOptions","publicKey","jwtSecret","generateSessionId","crypto","randomBytes","toString","maybeCleanupExpired","cleanupInvocationCounter","cleanupEveryCalls","provider","cleanupThreshold","DEFAULT_ALGORITHM","jwtKey","tokenType","type","isRefresh","idleLifespan","idleRefreshTokenLifespan","idleSessionLifespan","maxLifespan","maxRefreshTokenLifespan","maxSessionLifespan","now","expiresAt","record","childId","metadata","issuedAtSeconds","Math","floor","getTime","expiresAtSeconds","payload","iat","exp","expiresIn","jwtSignOptions","jwt","sign","noTimestamp","toISOString","verify","algorithms","isValid","err","verifyOptions","error","JsonWebTokenError","validation","String","accessTokenLifespan","current","child","childIat","childExp","childPayload","childToken","absolute","childSessionId","childExpiresAt","childRecord","payloadOut","Map","createDatabaseProvider","createSessionManager","fluentApi","api","bind","Object","defineProperty","enumerable"],"mappings":"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"}