diff --git a/app/controllers/reset.php b/app/controllers/reset.php index bf704af..f905525 100644 --- a/app/controllers/reset.php +++ b/app/controllers/reset.php @@ -83,12 +83,12 @@ function enviarCodigoInterno() try { $mail = new PHPMailer(true); $mail->isSMTP(); - $mail->Host = 'secure.emailsrvr.com'; - $mail->SMTPAuth = true; - $mail->Username = 'noreply@aduanasoft.com.mx'; - $mail->Password = $_ENV['SMTP_PASS']; + $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; + $mail->Port = 587; $mail->setFrom('noreply@aduanasoft.com.mx', 'SIIH | AduanaSoft'); $mail->addAddress($email); @@ -132,6 +132,111 @@ function enviarCodigoInterno() } } +function reenviarCodigoInterno() +{ + header('Content-Type: application/json'); + + // Validar sesión y datos requeridos + if (!isset($_SESSION['usuario_id'], $_SESSION['usuario_email'])) { + echo json_encode(['success' => false, 'message' => '⚠️ Sesión expirada. Vuelve a ingresar tu correo.']); + exit; + } + + $conn = getConnection(); + if (!$conn) { + echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']); + exit; + } + + $id_usuario = $_SESSION['usuario_id']; + $emailEncrypted = encrypt($_SESSION['usuario_email']); + + // Obtener el último código activo de recuperación + $now = (new DateTime())->format('Y-m-d H:i:s'); + $sql = "SELECT TOP 1 codigo FROM recuperacion_password + WHERE email = ? AND estatus = 0 AND expiracion > ? + ORDER BY expiracion DESC"; + $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted, $now]); + + if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) { + echo json_encode(['success' => false, 'message' => '❌ No se encontró un código activo para reenviar.']); + exit; + } + + $codigo = $row['codigo']; + + // Llamar a la función para reenviar el correo al respaldo + if (enviarCorreoRespaldo($conn, $id_usuario, $codigo)) { + echo json_encode(['success' => true, 'message' => '📤 Código reenviado al correo de respaldo.']); + } else { + echo json_encode(['success' => false, 'message' => '❌ Error al reenviar el código al correo de respaldo.']); + } + + exit; +} + +function enviarCorreoRespaldo($conn, $id_usuario, $codigo) +{ + // Obtener correo de respaldo del usuario + $sql = "SELECT correo FROM correo_respaldo WHERE id_usuario = ?"; + $stmt = sqlsrv_query($conn, $sql, [$id_usuario]); + + if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) { + return false; + } + + $correoRespaldo = $row['correo']; + if (empty($correoRespaldo)) { + return false; + } + + // Enviar código por correo al correo de respaldo + try { + $mail = new PHPMailer(true); + $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; + + $mail->setFrom('noreply@aduanasoft.com.mx', 'SIIH | AduanaSoft'); + $mail->addAddress($correoRespaldo); + $mail->CharSet = 'UTF-8'; + $mail->isHTML(true); + $mail->Subject = 'Código para cambio de contraseña'; + + $mail->Body = " +
+
+
+

Cambio de contraseña

+
+
+

Has solicitado cambiar tu contraseña desde tu cuenta.

+
+

Tu código de verificación es:

+

$codigo

+
+

Este código expirará en 10 minutos.

+

Si no solicitaste este cambio, ignora este correo.

+
+
+ © " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos +
+
+
"; + + $mail->send(); + return true; + + } catch (Exception $e) { + error_log("Error al enviar correo de respaldo: {$mail->ErrorInfo}"); + return false; + } +} + function verificarCodigoInternoView() { // Verificar si el usuario ya está autenticado diff --git a/views/reset/verificar_codigo.php b/views/reset/verificar_codigo.php index 97a24c4..a576989 100644 --- a/views/reset/verificar_codigo.php +++ b/views/reset/verificar_codigo.php @@ -12,6 +12,8 @@ $dos_factores_estado = obtenerEstadoDosFactores(); + + @@ -137,6 +141,12 @@ $dos_factores_estado = obtenerEstadoDosFactores(); + +
+ +
@@ -252,7 +262,7 @@ $dos_factores_estado = obtenerEstadoDosFactores(); const intentosInfo = document.getElementById('intentosInfo'); let intentosRealizados = 0; - const maxIntentos = 3; + const maxIntentos = 3; // Auto-focus en el input al cargar inputCodigo.focus(); @@ -328,7 +338,7 @@ $dos_factores_estado = obtenerEstadoDosFactores(); } // 1. SOLUCIÓN PARA EL CONTADOR DE INTENTOS - // REEMPLAZA tu función enviarCodigo con esta versión de debug: + // REEMPLAZA tu función enviarCodigo con esta versión de debug: function enviarCodigo(codigo) { btnVerificar.disabled = true; btnVerificar.classList.add('loading'); @@ -526,7 +536,7 @@ $dos_factores_estado = obtenerEstadoDosFactores(); this.disabled = true; this.innerHTML = 'Enviando...'; - fetch("/IMPORTADORES/reset/reenviarCodigo", { + fetch("/IMPORTADORES/reset/reenviarCodigoInterno", { method: "POST", headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: "accion=reenviarCodigo" @@ -567,6 +577,52 @@ $dos_factores_estado = obtenerEstadoDosFactores(); this.dispatchEvent(new Event('input')); }); }); + document.getElementById('btnCancelarCambio').addEventListener('click', () => { + Swal.fire({ + title: '¿Cancelar cambio de contraseña?', + text: 'Se invalidará el código y se cancelará el proceso actual.', + icon: 'warning', + showCancelButton: true, + confirmButtonColor: '#d33', + cancelButtonColor: '#3085d6', + confirmButtonText: 'Sí, cancelar', + cancelButtonText: 'No, continuar' + }).then((result) => { + if (result.isConfirmed) { + fetch('/IMPORTADORES/reset/cancelarCambioInterno', { + method: 'POST' + }) + .then(resp => resp.json()) + .then(data => { + if (data.success) { + Swal.fire({ + icon: 'success', + title: 'Proceso cancelado', + text: data.message, + confirmButtonText: 'Aceptar' + }).then(() => { + // Redirigir al usuario + window.location.href = '/IMPORTADORES/seguridad/index'; + }); + } else { + Swal.fire({ + icon: 'error', + title: 'Error', + text: 'No se pudo cancelar el proceso.' + }); + } + }) + .catch(err => { + console.error('Error al cancelar:', err); + Swal.fire({ + icon: 'error', + title: 'Error', + text: 'Ocurrió un error al intentar cancelar.' + }); + }); + } + }); + });