Mejoras de seguridad y nueva tabla de turnos para ayudantes

- Agregado sistema de protección CSRF con tokens
- Creada clase Session para gestión centralizada de sesiones
- Mejorado manejo de errores en Database (sin die())
- Refactorizado Auth para usar nueva clase Session
- Agregada validación CSRF a formularios de login y admin
- Agregada validación de roles en modelo User
- Mejorada vista de ayudante con tabla de horarios por semana
- Agregada tabla de Turnos de Ayudantes con fechas en columnas
This commit is contained in:
nickpons666
2026-01-20 15:24:07 -06:00
parent dc8e83db6c
commit 05631e4a63
10 changed files with 467 additions and 254 deletions

View File

@@ -7,6 +7,7 @@ require_once BASE_PATH . '/src/Auth.php';
require_once BASE_PATH . '/src/User.php';
require_once BASE_PATH . '/src/DiasHorarios.php';
require_once BASE_PATH . '/src/Asignacion.php';
require_once BASE_PATH . '/src/CSRF.php';
$auth = new Auth();
$auth->requireAdmin();
@@ -19,52 +20,57 @@ $message = '';
$messageType = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if (!CSRF::isValidRequest()) {
$message = 'Error de validación del formulario';
$messageType = 'danger';
} else {
$action = $_POST['action'] ?? '';
if ($action === 'asignar') {
$userId = $_POST['user_id'] ?? 0;
$semana = $_POST['semana'] ?? '';
if ($action === 'asignar') {
$userId = $_POST['user_id'] ?? 0;
$semana = $_POST['semana'] ?? '';
if ($userId && $semana) {
$asignacionModel->asignar($userId, $semana);
$message = 'Turno asignado correctamente';
$messageType = 'success';
}
} elseif ($action === 'rotar') {
$semana = $_POST['semana'] ?? '';
$asignacionActual = $asignacionModel->getAsignacionPorSemana($semana);
if ($asignacionActual) {
$proximaPersona = $asignacionModel->getProximaPersona($asignacionActual['user_id']);
if ($proximaPersona) {
$asignacionModel->asignar($proximaPersona['id'], $semana);
$message = 'Turno rotado a: ' . htmlspecialchars($proximaPersona['nombre']);
if ($userId && $semana) {
$asignacionModel->asignar($userId, $semana);
$message = 'Turno asignado correctamente';
$messageType = 'success';
}
}
} elseif ($action === 'asignar_masivo') {
$userIds = $_POST['user_ids'] ?? [];
$semanaInicio = $_POST['semana_inicio'] ?? '';
$rotacionAutomatica = isset($_POST['rotacion_automatica']) ? true : false;
if (!empty($userIds) && $semanaInicio) {
$resultado = $asignacionModel->asignarMasivo($userIds, $semanaInicio, $rotacionAutomatica);
} elseif ($action === 'rotar') {
$semana = $_POST['semana'] ?? '';
$asignacionActual = $asignacionModel->getAsignacionPorSemana($semana);
if ($resultado['success'] > 0) {
$message = "Se asignaron {$resultado['success']} turnos correctamente";
if ($rotacionAutomatica) {
$message .= " con rotación automática para la siguiente semana";
if ($asignacionActual) {
$proximaPersona = $asignacionModel->getProximaPersona($asignacionActual['user_id']);
if ($proximaPersona) {
$asignacionModel->asignar($proximaPersona['id'], $semana);
$message = 'Turno rotado a: ' . htmlspecialchars($proximaPersona['nombre']);
$messageType = 'success';
}
$messageType = 'success';
}
if (!empty($resultado['errors'])) {
$message .= "<br>Errores: " . implode('<br>', $resultado['errors']);
$messageType = 'warning';
} elseif ($action === 'asignar_masivo') {
$userIds = $_POST['user_ids'] ?? [];
$semanaInicio = $_POST['semana_inicio'] ?? '';
$rotacionAutomatica = isset($_POST['rotacion_automatica']) ? true : false;
if (!empty($userIds) && $semanaInicio) {
$resultado = $asignacionModel->asignarMasivo($userIds, $semanaInicio, $rotacionAutomatica);
if ($resultado['success'] > 0) {
$message = "Se asignaron {$resultado['success']} turnos correctamente";
if ($rotacionAutomatica) {
$message .= " con rotación automática para la siguiente semana";
}
$messageType = 'success';
}
if (!empty($resultado['errors'])) {
$message .= "<br>Errores: " . implode('<br>', $resultado['errors']);
$messageType = 'warning';
}
} else {
$message = 'Debes seleccionar al menos un ayudante y una semana';
$messageType = 'danger';
}
} else {
$message = 'Debes seleccionar al menos un ayudante y una semana';
$messageType = 'danger';
}
}
}
@@ -167,6 +173,7 @@ $pageTitle = 'Asignación de Turnos';
</div>
<form method="POST" class="d-flex gap-2">
<?= CSRF::getTokenField() ?>
<input type="hidden" name="action" value="rotar">
<input type="hidden" name="semana" value="<?= $currentWeekStart ?>">
<button type="submit" class="btn btn-outline-primary">
@@ -178,6 +185,7 @@ $pageTitle = 'Asignación de Turnos';
<form method="POST">
<input type="hidden" name="action" value="asignar">
<?= CSRF::getTokenField() ?>
<input type="hidden" name="semana" value="<?= $currentWeekStart ?>">
<div class="mb-3">
<label class="form-label">Asignar a:</label>
@@ -260,6 +268,7 @@ $pageTitle = 'Asignación de Turnos';
</div>
<form method="POST" class="d-flex gap-2">
<?= CSRF::getTokenField() ?>
<input type="hidden" name="action" value="asignar">
<input type="hidden" name="semana" value="<?= $semanaVer ?>">
<select class="form-select" name="user_id" style="max-width: 250px;">
@@ -302,6 +311,7 @@ No hay asignación para la semana <?= $posicionSinAsignar ?> de 4 (<?= date('d/m
</div>
<div class="card-body">
<form method="POST" id="asignacionMasivaForm">
<?= CSRF::getTokenField() ?>
<input type="hidden" name="action" value="asignar_masivo">
<div class="row mb-3">
@@ -401,6 +411,7 @@ No hay asignación para la semana <?= $posicionSinAsignar ?> de 4 (<?= date('d/m
</div>
<div class="col-md-4">
<form method="POST" class="h-100 d-flex flex-column justify-content-center">
<?= CSRF::getTokenField() ?>
<input type="hidden" name="action" value="rotacion_automatica">
<button type="submit" class="btn btn-warning w-100">
<i class="fas fa-sync"></i> Generar Rotación Automática
@@ -429,6 +440,7 @@ No hay asignación para la semana <?= $posicionSinAsignar ?> de 4 (<?= date('d/m
</div>
<div class="card-body">
<form method="POST" id="reordenarForm">
<?= CSRF::getTokenField() ?>
<input type="hidden" name="action" value="reordenar">
<p class="text-muted">