Bienvenido a SATURNOS
Sistema de gestión de turnos. Ingresa con tu usuario institucional.
40) { turneroFlash('Verifica el correo y el número de documento.'); turneroRedirigir('index.php?vista=recordar'); } // Respuesta genérica: no revela si el usuario existe en la base de datos. $respuestaPublica = 'Si los datos coinciden con un usuario activo, recibirás instrucciones en tu correo.'; $ahora = time(); if ((int) ($_SESSION['turnero_recuperacion_desde'] ?? 0) + 900 < $ahora) { $_SESSION['turnero_recuperacion_desde'] = $ahora; $_SESSION['turnero_recuperacion_intentos'] = 0; } $_SESSION['turnero_recuperacion_intentos'] = (int) ($_SESSION['turnero_recuperacion_intentos'] ?? 0) + 1; if ($_SESSION['turnero_recuperacion_intentos'] > 3) { turneroFlash($respuestaPublica, 'ok'); turneroRedirigir('index.php'); } try { if (TURNERO_SMTP_PASSWORD === 'PON_AQUI_NUEVA_CLAVE_SMTP' || TURNERO_SMTP_FROM === 'PON_AQUI_CORREO_REMITENTE') { throw new RuntimeException('Configura SMTP en funciones.php antes de utilizar la recuperación.'); } $conexion = conectar(); $registro = $conexion->Execute( "SELECT id, loginturn, password, ema FROM usuarios WHERE ema = ? AND doc = ? AND est = 'on' LIMIT 1", [$correo, $documento] ); if ($registro === false) { throw new RuntimeException('Error al buscar el usuario para recuperación.'); } if (!$registro->EOF) { // password_hash() requiere una columna amplia; evita truncar claves. $columna = $conexion->Execute("SHOW COLUMNS FROM usuarios LIKE 'password'"); if ($columna === false || $columna->EOF) { throw new RuntimeException('No se pudo consultar la longitud de usuarios.password.'); } $tipo = strtolower((string) ($columna->fields['Type'] ?? '')); if (preg_match('/^(?:var)?char\((\d+)\)/', $tipo, $coincide) && (int) $coincide[1] < 255) { throw new RuntimeException('Actualiza usuarios.password a VARCHAR(255) antes de recuperar contraseñas.'); } $id = (int) $registro->fields['id']; $hashAnterior = (string) $registro->fields['password']; $claveTemporal = strtoupper(bin2hex(random_bytes(8))); $hashNuevo = password_hash($claveTemporal, PASSWORD_DEFAULT); if ($hashNuevo === false) { throw new RuntimeException('No se pudo generar la clave temporal.'); } $cambio = $conexion->Execute( 'UPDATE usuarios SET password = ? WHERE id = ? AND password = ?', [$hashNuevo, $id, $hashAnterior] ); if ($cambio === false) { throw new RuntimeException('Error al guardar la clave temporal. Verifica que usuarios.password tenga longitud 255.'); } if ($conexion->Affected_Rows() === 1) { $enviado = turneroEnviarClaveTemporal( (string) $registro->fields['ema'], (string) $registro->fields['loginturn'], $claveTemporal ); if (!$enviado) { // Si no salió el correo, la contraseña anterior sigue funcionando. $reversion = $conexion->Execute( 'UPDATE usuarios SET password = ? WHERE id = ? AND password = ?', [$hashAnterior, $id, $hashNuevo] ); if ($reversion === false) { error_log('SATURNOS: No fue posible revertir un cambio de contraseña sin correo. Usuario ID ' . $id); } } } } desconectar($conexion); } catch (\Throwable $e) { error_log('SATURNOS recuperar: ' . $e->getMessage()); } turneroFlash($respuestaPublica, 'ok'); turneroRedirigir('index.php');}// CAPTCHA del esquema existente, sin modificar globalmente preguntas.est.$idCaptcha = 0;if (!$recuperacion) { try { $conexion = conectar(); $pregunta = $conexion->Execute('SELECT id FROM preguntas ORDER BY RAND() LIMIT 1'); if ($pregunta !== false && !$pregunta->EOF) { $idCaptcha = (int) $pregunta->fields['id']; $_SESSION['turnero_captcha_id'] = $idCaptcha; } else { $errorSistema = 'No hay preguntas de verificación disponibles. Contacta al administrador.'; } desconectar($conexion); } catch (\Throwable $e) { error_log('SATURNOS index: ' . $e->getMessage()); $errorSistema = 'El servicio no se encuentra disponible en este momento.'; }}$flash = turneroLeerFlash();$bloqueado = (int) ($_SESSION['turnero_bloqueo_hasta'] ?? 0) > time();?>
Sistema de gestión de turnos. Ingresa con tu usuario institucional.