{"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  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  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 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  constructor(\n    private sessionManager: SessionManager,\n    private origin: string\n  ) {}\n\n  async generateRefreshToken(\n    userId: string,\n    deviceId: string | undefined,\n    options?: { type?: 'refresh' | 'session' }\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   * 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' }\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      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 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        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","updateBySessionId","update","deleteBySessionId","delete","deleteExpired","deleteMany","absoluteExpiresAt","$lt","Date","deleteBy","criteria","userId","origin","deviceId","OriginSessionManager","generateRefreshToken","options","sessionManager","generateAccessToken","refreshToken","rotateRefreshToken","validateAccessToken","token","validateRefreshToken","invalidateRefreshToken","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","status","issuedAtSeconds","Math","floor","createdAt","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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"}