Autenticación
Base path: /api/auth
POST /auth/login
Iniciar sesión con email y contraseña.
Auth: Ninguna
Request body:
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
email | string | Sí | Dirección de email |
password | string | Sí | Contraseña |
mobile | boolean | No | Si true, se devuelve un refresh token de 30 días |
Response (200):
{
"token": "jwt-access-token",
"refresh_token": "solo-cuando-mobile-true",
"user": {
"id": 1,
"name": "Admin",
"email": "admin@salon.nl",
"role": "admin",
"require_password_change": false
}
}
Los access tokens expiran a las 8 horas. Con mobile: true se devuelve también un refresh token (válido 30 días).
Errores: 401 — Credenciales inválidas
POST /auth/logout
Cerrar sesión y revocar refresh/device token.
Auth: Requerida (cualquier rol)
Request body:
| Campo | Tipo | Descripción |
|---|---|---|
refresh_token | string | Refresh token a revocar |
device_token | string | Device token push a eliminar |
POST /auth/refresh
Renovar access token mediante refresh token. El token antiguo se elimina y se emite uno nuevo (rotación de tokens).
Auth: Ninguna
Request body:
| Campo | Tipo | Obligatorio |
|---|---|---|
refresh_token | string | Sí |
Response (200):
{
"token": "nuevo-access-token",
"refresh_token": "nuevo-refresh-token",
"user": {
"id": 1,
"name": "Admin",
"email": "admin@salon.nl",
"role": "admin",
"require_password_change": false
}
}
Errores: 401 — Refresh token inválido o expirado
POST /auth/register
Crear nuevo usuario (solo admin). Envía email de bienvenida con contraseña temporal. El nuevo usuario tendrá require_password_change: true.
Auth: Admin
Request body:
| Campo | Tipo | Obligatorio | Por defecto |
|---|---|---|---|
email | string | Sí | — |
name | string | Sí | — |
role | string | No | staff |
Response (200): { id, email, role, name }
Errores: 409 — Email ya registrado
POST /auth/forgot-password
Enviar email de restablecimiento de contraseña. Siempre devuelve 200 (evita enumeración de emails). Los enlaces expiran a la 1 hora.
Auth: Ninguna
Request body: { "email": "user@example.com" }
POST /auth/reset-password
Restablecer contraseña con token del email de restablecimiento.
Auth: Ninguna
Request body:
| Campo | Tipo | Obligatorio |
|---|---|---|
email | string | Sí |
token | string | Sí |
password | string (min 8) | Sí |
Errores: 400 — Token inválido o expirado
POST /auth/change-password
Cambiar contraseña para usuario autenticado.
Auth: Requerida (cualquier rol)
Request body:
| Campo | Tipo | Obligatorio |
|---|---|---|
email | string | Sí |
currentPassword | string | Sí |
newPassword | string (min 8) | Sí |
confirmPassword | string (min 8) | Sí |
Errores: 400 — Las contraseñas no coinciden; 401 — Contraseña actual incorrecta
GET /auth/users
Obtener todos los usuarios (solo admin).
Auth: Admin
Response: Array de objetos { id, name, email, role }.
POST /auth/device
Registrar device token para notificaciones push.
Auth: Requerida
Request body:
| Campo | Tipo | Obligatorio |
|---|---|---|
token | string (max 512) | Sí |
platform | ios / android / web | Sí |
DELETE /auth/device
Eliminar un device token.
Auth: Requerida
Request body: { "token": "device-token" }
GET /auth/setup-status
Verificar si se requiere la configuración inicial.
Auth: Ninguna
Response:
{ "needsSetup": true }
POST /auth/setup
Endpoint de configuración inicial. Solo funciona cuando no existen cuentas de usuario.
Auth: Ninguna
Request body:
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
admin_name | string | Sí | Nombre del admin |
admin_email | string | Sí | Email del admin |
admin_password | string (min 8) | Sí | Contraseña |
salon_name | string | Sí | Nombre del salón |
salon_email | string | No | Email de contacto |
salon_phone | string | No | Teléfono |
salon_address | string | No | Dirección |
opening_hours | array | No | Array de { day_of_week, open_time, close_time, is_closed } |
Response (201):
{
"token": "jwt-access-token",
"user": { "id": 1, "name": "Admin", "role": "admin" }
}
Errores: 400 — Configuración ya completada