# Despliegue seguro en cPanel con PHP 8.2+

## Requisitos

- PHP 8.2 o superior.
- MySQL 5.7+ o MariaDB 10.4+.
- Extensiones: `ctype`, `curl`, `fileinfo`, `gd`, `iconv`, `json`, `mbstring`, `mysqli`, `openssl`, `session`, `xml` y `zlib`.
- Apache 2.4 con `mod_rewrite` y `mod_headers`.
- HTTPS obligatorio.

## Preparación

1. Cree una base y un usuario MySQL nuevos. No reutilice las credenciales expuestas en copias anteriores.
2. Importe una copia de base de datos saneada desde una ubicación privada. Los volcados SQL no se incluyen en este paquete.
3. Copie `admin/config/config.local.php.example` como `admin/config/config.local.php` y escriba las credenciales nuevas.
4. Verifique que `admin/config/config.local.php` no sea legible por HTTP y no se encuentre en Git.
5. Cambie también la contraseña SMTP en el proveedor y actualice la tabla `configuration`.
6. Revise `url_base` y use exclusivamente la URL HTTPS de SERINTSA.
7. Mantenga `Documentos` y sus subdirectorios escribibles por PHP con el mínimo permiso necesario; evite `0777`.
8. Suba `vendor` junto con el proyecto o ejecute Composer en un entorno controlado.

## Contraseñas heredadas

Las contraseñas nuevas se guardan con `password_hash()` y se actualizan automáticamente al iniciar sesión.

Las cuentas antiguas cifradas con AES solo podrán iniciar sesión si se configura temporalmente la clave heredada mediante `APP_LEGACY_KEY` o `legacy_key` en `config.local.php`. Como esa clave estuvo incluida en una copia anterior, la opción más segura es forzar el restablecimiento de todas las contraseñas y después eliminarla.

## Recuperación de contraseña

- El token tiene 20 caracteres aleatorios.
- Vence en una hora.
- Solo puede utilizarse una vez.
- Una solicitud nueva invalida los tokens anteriores del usuario.
- El navegador no envía IDs de usuario ni de recuperación.

## Cron

`cron.php` solo responde desde la línea de comandos. Ejemplo:

```text
/usr/local/bin/php -q /home/USUARIO/public_html/cron.php
```

No lo invoque mediante una URL.

## Verificación mínima antes de publicar

- Inicio de sesión de empleado con código y contraseña.
- Inicio de sesión de administrador/agente.
- Alta y edición de usuarios con contraseñas de al menos 10 caracteres.
- Recuperación de contraseña y vencimiento del enlace.
- Envío SMTP sin contraseñas en el contenido del mensaje.
- Creación, asignación, actualización y cierre de tickets.
- Subida y descarga de archivos.
- Ejecución de `cron.php` desde CLI.

## Acciones externas obligatorias

El código no puede rotar credenciales en MySQL ni en el proveedor de correo. Cambie manualmente ambas contraseñas antes de desplegar y revise los registros reales del servidor para detectar accesos anómalos.
