Saltar al contenido principal

Autenticación

Archivo: api/src/routes/auth.js · Prefijo: /api/auth

POST /api/auth/login​

Inicia sesión con email y contraseña.

Acceso: Público

Body

CampoTipoRequerido
emailstring (email)Sí
passwordstringSí
{ "email": "usuario@empresa.com", "password": "••••••••" }

Respuesta 200

{
"token": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi...",
"user": {
"id": "22222222-0001-0000-0000-000000000001",
"name": "Admin Daval",
"email": "admin@daval.com",
"role": "admin",
"companyId": null,
"branchId": null
}
}

Errores

HTTPerrorCausa
400VALIDATION_ERROREmail mal formado o contraseña vacía
401INVALID_CREDENTIALSUsuario inexistente, inactivo o contraseña incorrecta

POST /api/auth/refresh​

Emite un access token y un refresh token nuevos (rotación). El frontend lo llama automáticamente cuando recibe un 401.

Acceso: Público (requiere un refresh token válido)

Body

{ "refreshToken": "eyJhbGciOi..." }

Respuesta 200: misma forma que /login (token, refreshToken, user).

Errores

HTTPerrorCausa
400MISSING_TOKENNo se envió refreshToken
401INVALID_REFRESH_TOKENFirma inválida, vencido, o la sesión fue revocada (contraseña cambiada o usuario desactivado después de emitirlo)
401USER_INACTIVEEl usuario ya no existe o fue desactivado

GET /api/auth/me​

Devuelve el usuario autenticado. Para clientes incluye su lista de precios.

Acceso: Autenticado

Respuesta 200

{
"user": {
"id": "22222222-0003-0000-0000-000000000001",
"name": "Juan Cliente",
"email": "cliente@daval.com",
"role": "client",
"companyId": "…",
"branchId": "…",
"priceListId": "…"
}
}

Errores: 401 sin token o token inválido; 404 USER_NOT_FOUND.


Ciclo de vida de los tokens​

login ──► token (8h) + refreshToken (30d)
│
├─ petición con token ─► 200
├─ petición con token vencido ─► 401
│ └─ frontend: POST /auth/refresh ─► tokens nuevos ─► reintenta la petición
└─ refresh vencido, revocado o usuario inactivo ─► 401 ─► evento daval:logout ─► /login

Las duraciones se configuran con JWT_EXPIRES_IN y JWT_REFRESH_EXPIRES_IN.

Revocación de sesiones​

El refresh token lleva tv, la users.token_version del momento en que se emitió. Un trigger en la base incrementa token_version cuando cambia la contraseña (password_hash) o el usuario se desactiva, aunque el cambio se haga directo por SQL. Desde ese momento POST /auth/refresh rechaza los refresh tokens anteriores.

El access token ya emitido sigue siendo válido hasta que vence (JWT_EXPIRES_IN, 8 h por defecto). Para cortar todas las sesiones de inmediato, rota JWT_SECRET y JWT_REFRESH_SECRET. Ver Credenciales y seguridad.