import type { HttpContext } from '@adonisjs/core/http' import { Exception } from '@adonisjs/core/exceptions' import { consumeRefreshToken } from '#services/refresh_token' import { emitAuthSession } from '#services/auth_session' export default class RefreshController { /** * POST /auth/refresh * * Lit le cookie `rubis_refresh` (httpOnly), valide son hash en DB, * révoque l'ancien et émet une AuthSession fraîche (nouveau access * token + nouveau refresh cookie posé via emitAuthSession). * * Codes d'erreur : * - 401 no_session : pas de cookie envoyé * - 401 session_expired : cookie inconnu, expiré, ou révoqué * (réutilisation d'un token révoqué = vol présumé → panic mode : * tous les tokens actifs du user sont invalidés) */ async handle(ctx: HttpContext) { const result = await consumeRefreshToken(ctx) if ('errorCode' in result) { throw new Exception( result.errorCode === 'no_session' ? 'Pas de session active' : 'Session expirée', { status: 401, code: result.errorCode } ) } const session = await emitAuthSession(result.user, ctx) return ctx.serialize(session) } }