diff --git a/app/controllers/login.php b/app/controllers/login.php
index 35968f6..8402cd7 100644
--- a/app/controllers/login.php
+++ b/app/controllers/login.php
@@ -145,9 +145,7 @@ function validar()
header('Location: /IMPORTADORES/login');
}
-/**
- * Función auxiliar para redirección por rol
- */
+/** Función auxiliar para redirección por rol **/
function redirectByRole($tipoUsuario)
{
switch ($tipoUsuario) {
@@ -498,7 +496,6 @@ function verificarCodigoVista()
function verificarCodigo()
{
- // ❌ REMOVER session_start() - ya se maneja en session.php
header('Content-Type: application/json');
$conn = getConnection();
@@ -507,8 +504,24 @@ function verificarCodigo()
$codigo = isset($_POST['codigo']) ? trim($_POST['codigo']) : '';
$email = $_SESSION['email_recuperacion'] ?? '';
- if (!$conn || empty($codigo) || empty($email)) {
- echo json_encode(['success' => false, 'message' => '❌ Código o correo faltante.']);
+ if (!$conn) {
+ echo json_encode(['success' => false, 'message' => '❌ Error de conexión a la base de datos.']);
+ exit;
+ }
+
+ if (empty($codigo)) {
+ echo json_encode(['success' => false, 'message' => '❌ Código requerido.']);
+ exit;
+ }
+
+ if (empty($email)) {
+ echo json_encode(['success' => false, 'message' => '❌ Sesión expirada. Solicita un nuevo código.']);
+ exit;
+ }
+
+ // Validar formato del código
+ if (!preg_match('/^\d{6}$/', $codigo)) {
+ echo json_encode(['success' => false, 'message' => '❌ Formato de código inválido. Debe ser de 6 dígitos.']);
exit;
}
@@ -521,11 +534,14 @@ function verificarCodigo()
$stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]);
if ($stmt === false) {
+ $errors = sqlsrv_errors();
+ error_log("Error SQL en verificarCodigo: " . print_r($errors, true));
echo json_encode(['success' => false, 'message' => '❌ Error al consultar el código.']);
exit;
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
+ sqlsrv_free_stmt($stmt);
if (!$row) {
echo json_encode(['success' => false, 'message' => '❌ Código no encontrado o ya usado.']);
@@ -539,18 +555,43 @@ function verificarCodigo()
$_SESSION['intentos_codigo']++;
- if ($_SESSION['intentos_codigo'] > 5) {
- // Bloquea el código en la base y resetea intentos
- sqlsrv_query($conn, "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?", [$row['id']]);
+ // Verificar si se han excedido los intentos
+ if ($_SESSION['intentos_codigo'] >= 5) {
+ // Bloquear el código en la base de datos
+ $sqlUpdate = "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?";
+ $stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$row['id']]);
+
+ if ($stmtUpdate) {
+ sqlsrv_free_stmt($stmtUpdate);
+ }
+
+ // 🚨 ENVIAR NOTIFICACIÓN DE SEGURIDAD
+ try {
+ enviarNotificacionIntentosExcedidos($email);
+ } catch (Exception $e) {
+ error_log("❌ Error al enviar notificación de intentos excedidos: " . $e->getMessage());
+ }
+
+ // Limpiar sesión
unset($_SESSION['intentos_codigo']);
-
- echo json_encode(['success' => false, 'message' => '🚫 Has excedido el número de intentos. Solicita un nuevo código.']);
+ unset($_SESSION['email_recuperacion']);
+
+ echo json_encode([
+ 'success' => false,
+ 'message' => '🚫 Has excedido el número de intentos permitidos. Por seguridad, se ha bloqueado el código. Solicita uno nuevo.',
+ 'blocked' => true
+ ]);
exit;
}
// Compara códigos - asegurando que no haya problemas con mayúsculas o espacios
if (strcasecmp($codigo, $row['codigo']) !== 0) {
- echo json_encode(['success' => false, 'message' => "❌ Código incorrecto. Intento {$_SESSION['intentos_codigo']} de 5."]);
+ $intentosRestantes = 5 - $_SESSION['intentos_codigo'];
+ echo json_encode([
+ 'success' => false,
+ 'message' => "❌ Código incorrecto. Te quedan {$intentosRestantes} intentos.",
+ 'intentos_restantes' => $intentosRestantes
+ ]);
exit;
}
@@ -566,21 +607,218 @@ function verificarCodigo()
if ($expiracionTimestamp === false || $expiracionTimestamp < time()) {
// Código expirado: marcar como usado y enviar mensaje
- sqlsrv_query($conn, "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?", [$row['id']]);
- echo json_encode(['success' => false, 'message' => '⏰ El código ha expirado.']);
+ $sqlExpired = "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?";
+ $stmtExpired = sqlsrv_query($conn, $sqlExpired, [$row['id']]);
+
+ if ($stmtExpired) {
+ sqlsrv_free_stmt($stmtExpired);
+ }
+
+ echo json_encode(['success' => false, 'message' => '⏰ El código ha expirado. Solicita uno nuevo.']);
exit;
}
// Código correcto: actualizar estado y permitir cambio de contraseña
- sqlsrv_query($conn, "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?", [$row['id']]);
+ $sqlSuccess = "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?";
+ $stmtSuccess = sqlsrv_query($conn, $sqlSuccess, [$row['id']]);
+
+ if ($stmtSuccess) {
+ sqlsrv_free_stmt($stmtSuccess);
+ }
$_SESSION['recuperacion_autorizada'] = true;
unset($_SESSION['intentos_codigo']);
- echo json_encode(['success' => true, 'message' => '✅ Código verificado. Redirigiendo...']);
+ echo json_encode(['success' => true, 'message' => '✅ Código verificado correctamente. Redirigiendo...']);
exit;
}
+/** Envía notificación cuando se exceden los intentos de verificación **/
+function enviarNotificacionIntentosExcedidos($email)
+{
+ $conn = getConnection();
+ if (!$conn) {
+ throw new Exception("No se pudo conectar a la base de datos");
+ }
+
+ // Buscar información del usuario por email
+ $emailEncrypted = encrypt($email);
+ $sqlNotif = "
+ SELECT
+ u.nombre,
+ u.email,
+ u.notificaciones,
+ u.notificaciones_extra,
+ COALESCE(p.intentos_fallidos, 0) as intentos_fallidos,
+ ce.correo as correo_extra
+ FROM usuarios_sistema u
+ LEFT JOIN preferencias_notificaciones_usuario p ON u.id_usuario = p.id_usuario
+ LEFT JOIN correo_extra ce ON u.id_usuario = ce.id_usuario
+ WHERE u.email = ?";
+
+ $stmtUsuario = sqlsrv_query($conn, $sqlNotif, [$emailEncrypted]);
+
+ if ($stmtUsuario === false) {
+ throw new Exception("Error al consultar información del usuario");
+ }
+
+ $usuario = sqlsrv_fetch_array($stmtUsuario, SQLSRV_FETCH_ASSOC);
+ sqlsrv_free_stmt($stmtUsuario);
+
+ if (!$usuario) {
+ error_log("⚠️ No se encontró usuario para email: $email");
+ return false;
+ }
+
+ // 🔐 Desencriptar datos sensibles
+ $usuario['email'] = decrypt($usuario['email']);
+ $usuario['nombre'] = decrypt($usuario['nombre']);
+
+ // Verificar si el usuario tiene habilitadas las notificaciones de seguridad
+ if ($usuario['notificaciones'] != 1 || $usuario['intentos_fallidos'] != 1) {
+ error_log("ℹ️ Usuario {$usuario['email']} no tiene habilitadas las notificaciones de intentos fallidos");
+ return false;
+ }
+
+ // Preparar datos para la notificación
+ $datosNotificacion = [
+ 'email' => $usuario['email'],
+ 'nombre' => $usuario['nombre'],
+ 'fecha_hora' => date('Y-m-d H:i:s'),
+ 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'Desconocida',
+ 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Desconocido'
+ ];
+
+ $resultadoEnvio = false;
+
+ // Enviar al correo principal
+ $resultadoPrincipal = enviarNotificacionSeguridadIntentos(
+ $usuario['email'],
+ $usuario['nombre'],
+ $datosNotificacion
+ );
+
+ if ($resultadoPrincipal) {
+ $resultadoEnvio = true;
+ error_log("✅ Notificación de seguridad enviada a: {$usuario['email']}");
+ }
+
+ // Enviar al correo adicional si está configurado
+ if ($usuario['notificaciones_extra'] == 1 && !empty($usuario['correo_extra'])) {
+ $resultadoExtra = enviarNotificacionSeguridadIntentos(
+ $usuario['correo_extra'],
+ $usuario['nombre'],
+ $datosNotificacion,
+ true // Indicar que es correo adicional
+ );
+
+ if ($resultadoExtra) {
+ $resultadoEnvio = true;
+ error_log("✅ Notificación de seguridad enviada a correo adicional: {$usuario['correo_extra']}");
+ }
+ }
+
+ // Registrar el evento de seguridad en logs del sistema
+ registrarEventoSeguridad($usuario['id_usuario'], 'INTENTOS_CODIGO_EXCEDIDOS', $datosNotificacion);
+
+ return $resultadoEnvio;
+}
+
+/** Función para enviar el email de notificación de seguridad **/
+function enviarNotificacionSeguridadIntentos($emailDestino, $nombreUsuario, $datos, $esCorreoAdicional = false)
+{
+ try {
+ $mail = new PHPMailer(true);
+
+ // Configuración de servidor SMTP
+ $mail->isSMTP();
+ $mail->Host = 'secure.emailsrvr.com';
+ $mail->SMTPAuth = true;
+ $mail->Username = 'noreply@aduanasoft.com.mx';
+ $mail->Password = $_ENV['SMTP_PASS'];
+ $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
+ $mail->Port = 587;
+
+ // Configuración del correo
+ $mail->setFrom('noreply@aduanasoft.com.mx', 'SIIH | AduanaSoft');
+ $mail->addAddress($emailDestino);
+ $mail->CharSet = 'UTF-8';
+ $mail->isHTML(true);
+
+ $asunto = "🚨 Alerta de Seguridad - Intentos de Verificación Excedidos";
+ $mail->Subject = $asunto;
+
+ $tipoCorreo = $esCorreoAdicional ? "(Correo Adicional)" : "";
+
+ $mail->Body = "
+
+
+
+ Alerta de Seguridad
+
+
+
+
+
🚨 Alerta de Seguridad
+
$tipoCorreo
+
+
+
+
Intentos de Verificación Excedidos
+
Hola " . htmlspecialchars($nombreUsuario) . ",
+
Se han detectado múltiples intentos fallidos para verificar el código de recuperación de contraseña en tu cuenta.
+
+
+
+
📋 Detalles del Evento:
+
+ - Fecha y Hora: " . htmlspecialchars($datos['fecha_hora']) . "
+ - Dirección IP: " . htmlspecialchars($datos['ip']) . "
+ - Navegador: " . htmlspecialchars(substr($datos['user_agent'], 0, 100)) . "...
+
+
+
+
+
🔒 Medidas de Seguridad Aplicadas:
+
+ - El código de verificación ha sido bloqueado automáticamente
+ - Será necesario solicitar un nuevo código de recuperación
+ - Este evento ha sido registrado en nuestros logs de seguridad
+
+
+
+
+
⚠️ ¿No fuiste tú?
+
Si no intentaste recuperar tu contraseña, esto podría indicar que alguien está tratando de acceder a tu cuenta.
+
Te recomendamos:
+
+ - Verificar la seguridad de tu cuenta
+ - Cambiar tu contraseña inmediatamente
+ - Revisar tus configuraciones de seguridad
+ - Contactar a soporte si sospechas actividad no autorizada
+
+
+
+
+
+ Esta es una notificación automática de seguridad.
+ Si tienes preguntas, contacta a nuestro equipo de soporte.
+
+
+
+
+ ";
+
+ // Enviar el correo
+ $mail->send();
+ return true;
+
+ } catch (Exception $e) {
+ error_log("❌ Error al enviar notificación de seguridad: " . $e->getMessage());
+ return false;
+ }
+}
+
function cambiarPasswordVista()
{
if (!isset($_SESSION['recuperacion_autorizada'])) {
diff --git a/views/login/verificar_codigo.php b/views/login/verificar_codigo.php
index 1631935..16f25fe 100644
--- a/views/login/verificar_codigo.php
+++ b/views/login/verificar_codigo.php
@@ -54,6 +54,18 @@ $mensajeMantenimiento = $config['mensaje_mantenimiento'] ?? 'El sistema se encue
.form-control {
border-radius: 6px;
+ transition: all 0.3s ease;
+ }
+
+ .form-control.error {
+ border-color: #dc3545;
+ background-color: #fff5f5;
+ animation: shake 0.5s ease-in-out;
+ }
+
+ .form-control.success {
+ border-color: #28a745;
+ background-color: #f8fff9;
}
footer {
@@ -75,14 +87,111 @@ $mensajeMantenimiento = $config['mensaje_mantenimiento'] ?? 'El sistema se encue
background: rgba(0, 0, 0, 0.5);
z-index: 5;
}
+
#mensaje {
- transition: opacity 0.3s ease;
+ transition: all 0.3s ease;
+ min-height: 24px;
}
+
+ #btnReenviarRespaldo {
+ background: none;
+ border: none;
+ color: = $color1 ?>;
+ text-decoration: underline;
+ cursor: pointer;
+ font-size: 14px;
+ padding: 0;
+ transition: color 0.3s ease;
+ }
+
+ #btnReenviarRespaldo:hover {
+ color: = $color2 ?>;
+ }
+
+ #btnReenviarRespaldo:disabled {
+ color: #ccc;
+ cursor: not-allowed;
+ text-decoration: none;
+ }
+
+ .btn:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+ }
+
+ .loading {
+ position: relative;
+ pointer-events: none;
+ }
+
+ .loading::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 20px;
+ height: 20px;
+ border: 2px solid transparent;
+ border-top: 2px solid #fff;
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+ transform: translate(-50%, -50%);
+ }
+
+ @keyframes shake {
+ 0%, 100% { transform: translateX(0); }
+ 25% { transform: translateX(-5px); }
+ 75% { transform: translateX(5px); }
+ }
+
+ @keyframes spin {
+ 0% { transform: translate(-50%, -50%) rotate(0deg); }
+ 100% { transform: translate(-50%, -50%) rotate(360deg); }
+ }
+
+ @keyframes fadeIn {
+ from { opacity: 0; transform: translateY(-10px); }
+ to { opacity: 1; transform: translateY(0); }
+ }
+
+ .fade-in {
+ animation: fadeIn 0.3s ease-out;
+ }
+
@media (max-height: 600px) {
footer {
position: static !important;
}
}
+
+ /* Estilos para input de código */
+ #codigo {
+ font-size: 18px;
+ letter-spacing: 3px;
+ text-align: center;
+ font-weight: bold;
+ }
+
+ .input-group {
+ position: relative;
+ }
+
+ .clear-input {
+ position: absolute;
+ right: 10px;
+ top: 50%;
+ transform: translateY(-50%);
+ background: none;
+ border: none;
+ color: #ccc;
+ cursor: pointer;
+ z-index: 5;
+ display: none;
+ }
+
+ .clear-input:hover {
+ color: #666;
+ }
@@ -128,6 +237,10 @@ $mensajeMantenimiento = $config['mensaje_mantenimiento'] ?? 'El sistema se encue
Verifica tu código
+
+
+ Hemos enviado un código de 6 dígitos a tu correo electrónico
+
+
-
= $_SESSION['codigo_error'] ?>
+
+
+ = $_SESSION['codigo_error'] ?>
+
-
= $_SESSION['codigo_exito'] ?>
+
+
+ = $_SESSION['codigo_exito'] ?>
+
+
+
+
+
+
@@ -171,64 +322,276 @@ $mensajeMantenimiento = $config['mensaje_mantenimiento'] ?? 'El sistema se encue
document.addEventListener('DOMContentLoaded', function () {
const form = document.getElementById('formCodigo');
const mensaje = document.getElementById('mensaje');
- const inputCodigo = form.querySelector('input[name="codigo"]');
+ const inputCodigo = document.getElementById('codigo');
+ const btnVerificar = document.getElementById('btnVerificar');
+ const btnReenviar = document.getElementById('btnReenviarRespaldo');
+ const clearBtn = document.getElementById('clearCode');
+ const intentosInfo = document.getElementById('intentosInfo');
- inputCodigo.addEventListener('input', () => {
- mensaje.innerHTML = '';
- mensaje.classList.remove("text-danger", "text-success");
+ let intentosRealizados = 0;
+ const maxIntentos = 5;
+
+ // Auto-focus en el input al cargar
+ inputCodigo.focus();
+
+ // Mostrar/ocultar botón de limpiar
+ inputCodigo.addEventListener('input', function() {
+ clearBtn.style.display = this.value.length > 0 ? 'block' : 'none';
+
+ // Limpiar mensajes previos
+ limpiarMensajes();
+
+ // Remover clases de error/éxito
+ inputCodigo.classList.remove('error', 'success');
+
+ // Solo permitir números
+ this.value = this.value.replace(/[^0-9]/g, '');
+
+ // Actualizar contador visual
+ actualizarContadorVisual();
});
+ // Limpiar input
+ clearBtn.addEventListener('click', function() {
+ inputCodigo.value = '';
+ inputCodigo.focus();
+ clearBtn.style.display = 'none';
+ limpiarMensajes();
+ inputCodigo.classList.remove('error', 'success');
+ });
+
+ // Permitir solo números en tiempo real
+ inputCodigo.addEventListener('keypress', function(e) {
+ if (!/[0-9]/.test(e.key) && !['Backspace', 'Delete', 'Tab', 'Enter'].includes(e.key)) {
+ e.preventDefault();
+ }
+ });
+
+ // Auto-envío cuando se completen 6 dígitos (opcional)
+ inputCodigo.addEventListener('input', function() {
+ if (this.value.length === 6) {
+ // Opcional: enviar automáticamente después de un breve delay
+ // setTimeout(() => form.dispatchEvent(new Event('submit')), 500);
+ }
+ });
+
+ // Manejo del formulario
form.addEventListener('submit', function(e) {
e.preventDefault();
const codigo = inputCodigo.value.trim();
- if (!codigo || codigo.length !== 6) {
- mensaje.textContent = "❌ Ingresa un código de 6 dígitos.";
- mensaje.classList.add("text-danger");
- return;
- }
+ if (!validarCodigo(codigo)) return;
+ enviarCodigo(codigo);
+ });
+
+ // Validación del código
+ function validarCodigo(codigo) {
+ if (!codigo) {
+ mostrarError("❌ Por favor, ingresa el código.");
+ return false;
+ }
+
+ if (codigo.length !== 6) {
+ mostrarError("❌ El código debe tener exactamente 6 dígitos.");
+ inputCodigo.classList.add('error');
+ return false;
+ }
+
+ if (!/^\d{6}$/.test(codigo)) {
+ mostrarError("❌ El código solo debe contener números.");
+ inputCodigo.classList.add('error');
+ return false;
+ }
+
+ return true;
+ }
+
+ // Enviar código para verificación
+ function enviarCodigo(codigo) {
+ // Mostrar estado de carga
+ btnVerificar.disabled = true;
+ btnVerificar.classList.add('loading');
+ btnVerificar.innerHTML = 'Verificando...';
+
const formData = new FormData();
formData.append('codigo', codigo);
fetch('/IMPORTADORES/login/verificarCodigo', {
method: 'POST',
body: formData,
- credentials: 'same-origin' // ✅ Importante para mantener sesión
+ credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
if (data.success) {
- mensaje.textContent = data.message;
- mensaje.classList.remove("text-danger");
- mensaje.classList.add("text-success");
-
+ // Código correcto
+ mostrarExito(data.message);
+ inputCodigo.classList.add('success');
+ inputCodigo.disabled = true;
+
// Redirigir al formulario de cambio de contraseña
setTimeout(() => {
window.location.href = '/IMPORTADORES/login/cambiarPasswordVista';
}, 1500);
+
} else {
- mensaje.textContent = "❌ " + data.message;
- mensaje.classList.remove("text-success");
- mensaje.classList.add("text-danger");
+ // Código incorrecto
+ manejarCodigoIncorrecto(data);
}
})
- .catch(() => {
- mensaje.textContent = "❌ Error al verificar el código.";
- mensaje.classList.remove("text-success");
- mensaje.classList.add("text-danger");
+ .catch(error => {
+ console.error('Error:', error);
+ mostrarError("❌ Error de conexión. Intenta nuevamente.");
+ inputCodigo.classList.add('error');
+ limpiarYEnfocarInput();
+ })
+ .finally(() => {
+ // Restaurar botón
+ btnVerificar.disabled = false;
+ btnVerificar.classList.remove('loading');
+ btnVerificar.innerHTML = 'Verificar código';
+ });
+ }
+
+ // Manejar código incorrecto
+ function manejarCodigoIncorrecto(data) {
+ intentosRealizados++;
+
+ mostrarError(data.message);
+ inputCodigo.classList.add('error');
+
+ // Limpiar input y enfocar para nuevo intento
+ limpiarYEnfocarInput();
+
+ // Actualizar contador de intentos
+ actualizarContadorIntentos();
+
+ // Si se bloqueó el código
+ if (data.blocked) {
+ bloquearFormulario();
+ }
+ }
+
+ // Limpiar input y enfocar
+ function limpiarYEnfocarInput() {
+ setTimeout(() => {
+ inputCodigo.value = '';
+ inputCodigo.classList.remove('error');
+ inputCodigo.focus();
+ clearBtn.style.display = 'none';
+ }, 1500); // Esperar 1.5 segundos antes de limpiar
+ }
+
+ // Actualizar contador visual
+ function actualizarContadorVisual() {
+ const longitud = inputCodigo.value.length;
+ if (longitud > 0) {
+ inputCodigo.setAttribute('placeholder', '0'.repeat(6 - longitud) + inputCodigo.value);
+ } else {
+ inputCodigo.setAttribute('placeholder', '000000');
+ }
+ }
+
+ // Actualizar contador de intentos
+ function actualizarContadorIntentos() {
+ if (intentosRealizados > 0) {
+ const restantes = maxIntentos - intentosRealizados;
+ intentosInfo.innerHTML = `
+
+ Intentos restantes: ${restantes} de ${maxIntentos}
+ `;
+ intentosInfo.classList.add('fade-in');
+ }
+ }
+
+ // Bloquear formulario cuando se exceden intentos
+ function bloquearFormulario() {
+ inputCodigo.disabled = true;
+ btnVerificar.disabled = true;
+ btnReenviar.disabled = true;
+
+ intentosInfo.innerHTML = `
+
+ Código bloqueado por seguridad
+ `;
+
+ // Redirigir a solicitar nuevo código después de 5 segundos
+ setTimeout(() => {
+ window.location.href = '/IMPORTADORES/login/recuperar';
+ }, 5000);
+ }
+
+ // Funciones de utilidad para mensajes
+ function mostrarMensaje(texto, tipo) {
+ mensaje.innerHTML = `${texto}
`;
+ mensaje.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
+
+ function mostrarError(texto) {
+ mostrarMensaje(`${texto}`, 'text-danger');
+ }
+
+ function mostrarExito(texto) {
+ mostrarMensaje(`${texto}`, 'text-success');
+ }
+
+ function mostrarInfo(texto) {
+ mostrarMensaje(`${texto}`, 'text-info');
+ }
+
+ function limpiarMensajes() {
+ mensaje.innerHTML = '';
+ }
+
+ // Manejo del botón de reenvío
+ btnReenviar.addEventListener("click", function() {
+ const btnOriginalText = this.innerHTML;
+
+ // Deshabilitar botón temporalmente
+ this.disabled = true;
+ this.innerHTML = 'Enviando...';
+
+ fetch("/IMPORTADORES/login/reenviarCodigo", {
+ method: "POST",
+ headers: {'Content-Type': 'application/x-www-form-urlencoded'},
+ body: "accion=reenviarCodigo"
+ })
+ .then(response => response.json())
+ .then(data => {
+ mostrarInfo(data.message);
+
+ // Habilitar botón después de 30 segundos
+ setTimeout(() => {
+ this.disabled = false;
+ this.innerHTML = btnOriginalText;
+ }, 30000);
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ mostrarError("❌ Error al reenviar código.");
+
+ // Restaurar botón en caso de error
+ this.disabled = false;
+ this.innerHTML = btnOriginalText;
});
});
- });
- document.getElementById("btnReenviarRespaldo").addEventListener("click", () => {
- fetch("/IMPORTADORES/login/reenviarCodigo", {
- method: "POST",
- headers: {'Content-Type': 'application/x-www-form-urlencoded'},
- body: "accion=reenviarCodigo"
- })
- .then(response => response.json())
- .then(data => alert(data.message));
+ // Manejar tecla Enter en cualquier parte del formulario
+ document.addEventListener('keypress', function(e) {
+ if (e.key === 'Enter' && !btnVerificar.disabled) {
+ form.dispatchEvent(new Event('submit'));
+ }
+ });
+
+ // Prevenir paste de contenido no numérico
+ inputCodigo.addEventListener('paste', function(e) {
+ e.preventDefault();
+ const paste = (e.clipboardData || window.clipboardData).getData('text');
+ const numericPaste = paste.replace(/[^0-9]/g, '').substring(0, 6);
+ this.value = numericPaste;
+ this.dispatchEvent(new Event('input'));
+ });
});