This commit is contained in:
2025-07-09 16:14:22 -06:00
parent 91b6806898
commit 287ad27274
39 changed files with 2517 additions and 2000 deletions

View File

@@ -4,8 +4,8 @@ require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../helpers/crypto.php';
require_once __DIR__ . '/../helpers/bitacoras.php';
require_once __DIR__ . '/../helpers/env.php';
require_once __DIR__ . '/../../vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
@@ -22,17 +22,18 @@ function enviarCodigoInterno()
}
$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'];
$email = $_SESSION['usuario_email'];
$id_usuario = $_SESSION['usuario_id'];
$email = $_SESSION['usuario_email'];
$emailEncrypted = encrypt($email);
// Verificar que la cuenta esté activa
$sql = "SELECT activo FROM usuarios_sistema WHERE id_usuario = ?";
$sql = "SELECT activo FROM usuarios_sistema WHERE id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$id_usuario]);
if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) {
@@ -46,11 +47,10 @@ function enviarCodigoInterno()
}
// Verificar si ya existe un código activo
$now = (new DateTime())->format('Y-m-d H:i:s');
$sqlCheck = "SELECT COUNT(*) AS total FROM recuperacion_password
WHERE email = ? AND estatus = 0 AND expiracion > ?";
$now = (new DateTime())->format('Y-m-d H:i:s');
$sqlCheck = "SELECT COUNT(*) AS total FROM recuperacion_password WHERE email = ? AND estatus = 0 AND expiracion > ?";
$checkStmt = sqlsrv_query($conn, $sqlCheck, [$emailEncrypted, $now]);
$checkRow = sqlsrv_fetch_array($checkStmt, SQLSRV_FETCH_ASSOC);
$checkRow = sqlsrv_fetch_array($checkStmt, SQLSRV_FETCH_ASSOC);
if ($checkRow['total'] > 0) {
echo json_encode(['success' => false, 'message' => '⚠️ Ya tienes un código activo. Revisa tu correo o espera 10 minutos.']);
@@ -58,8 +58,8 @@ function enviarCodigoInterno()
}
// Generar nuevo código
$codigo = strval(random_int(100000, 999999));
$expira = (new DateTime('+10 minutes'))->format('Y-m-d H:i:s');
$codigo = strval(random_int(100000, 999999));
$expira = (new DateTime('+10 minutes'))->format('Y-m-d H:i:s');
$estatus = 0;
$insert = "INSERT INTO recuperacion_password (email, codigo, expiracion, estatus) VALUES (?, ?, ?, ?)";
@@ -72,7 +72,7 @@ function enviarCodigoInterno()
}
// Establecer variables de sesión para el cambio interno
$_SESSION['cambio_interno'] = true;
$_SESSION['cambio_interno'] = true;
$_SESSION['codigo_timestamp'] = time();
// Agregar estos logs:
@@ -143,6 +143,7 @@ function reenviarCodigoInterno()
}
$conn = getConnection();
if (!$conn) {
echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']);
exit;
@@ -153,9 +154,7 @@ function reenviarCodigoInterno()
// 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";
$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))) {
@@ -167,7 +166,7 @@ function reenviarCodigoInterno()
// 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.']);
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.']);
}
@@ -261,15 +260,15 @@ function verificarCodigoInterno()
$conn = getConnection();
$email = $_SESSION['usuario_email'];
$email = $_SESSION['usuario_email'];
$emailEncrypted = encrypt($email); // aplica aquí también
try {
// Verificar conexión
if (!isset($conn) || $conn === false) {
echo json_encode([
'success' => false,
'message' => '❌ Error de conexión a la base de datos.',
'success' => false,
'message' => '❌ Error de conexión a la base de datos.',
'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0))
]);
exit;
@@ -279,8 +278,8 @@ function verificarCodigoInterno()
if (empty($codigo)) {
echo json_encode([
'success' => false,
'message' => '❌ Código requerido.',
'success' => false,
'message' => '❌ Código requerido.',
'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0))
]);
exit;
@@ -288,8 +287,8 @@ function verificarCodigoInterno()
if (!preg_match('/^\d{6}$/', $codigo)) {
echo json_encode([
'success' => false,
'message' => '❌ El código debe tener 6 dígitos numéricos.',
'success' => false,
'message' => '❌ El código debe tener 6 dígitos numéricos.',
'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0))
]);
exit;
@@ -299,10 +298,10 @@ function verificarCodigoInterno()
if ($intentosActuales >= 3) {
echo json_encode([
'success' => false,
'message' => '❌ Demasiados intentos fallidos. Solicita un nuevo código.',
'blocked' => true,
'redirect' => '/IMPORTADORES/seguridad/index',
'success' => false,
'message' => '❌ Demasiados intentos fallidos. Solicita un nuevo código.',
'blocked' => true,
'redirect' => '/IMPORTADORES/seguridad/index',
'intentos_restantes' => 0
]);
exit;
@@ -310,21 +309,23 @@ function verificarCodigoInterno()
if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email'])) {
echo json_encode([
'success' => false,
'message' => '❌ Sesión inválida. Intenta nuevamente.',
'blocked' => true,
'success' => false,
'message' => '❌ Sesión inválida. Intenta nuevamente.',
'blocked' => true,
'redirect' => '/IMPORTADORES/seguridad/index'
]);
exit;
}
// Consulta principal para verificar el código
$sql = "SELECT id, codigo, expiracion
$sql = "SELECT
id, codigo, expiracion
FROM recuperacion_password
WHERE email = ? AND estatus = 0 AND expiracion > GETDATE()
WHERE email = ?
AND estatus = 0
AND expiracion > GETDATE()
ORDER BY expiracion DESC
";
$stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]);
if (!$stmt) {
@@ -337,8 +338,8 @@ function verificarCodigoInterno()
if (!$row) {
$_SESSION['intentos_codigo_interno'] = $intentosActuales + 1;
echo json_encode([
'success' => false,
'message' => '❌ Código inválido o expirado.',
'success' => false,
'message' => '❌ Código inválido o expirado.',
'intentos_restantes' => max(0, 3 - $_SESSION['intentos_codigo_interno'])
]);
exit;
@@ -351,15 +352,15 @@ function verificarCodigoInterno()
if ($codigo !== $row['codigo']) {
$_SESSION['intentos_codigo_interno'] = $intentosActuales + 1;
echo json_encode([
'success' => false,
'message' => '❌ Código incorrecto.',
'success' => false,
'message' => '❌ Código incorrecto.',
'intentos_restantes' => max(0, 3 - $_SESSION['intentos_codigo_interno'])
]);
exit;
}
$expiracion = $row['expiracion'];
$ahora = new DateTime();
$ahora = new DateTime();
if ($expiracion instanceof DateTime) {
$expiracionStr = $expiracion->format('Y-m-d H:i:s');
@@ -367,8 +368,8 @@ function verificarCodigoInterno()
if ($expiracion <= $ahora) {
$_SESSION['intentos_codigo_interno'] = $intentosActuales + 1;
echo json_encode([
'success' => false,
'message' => '❌ El código ha expirado.',
'success' => false,
'message' => '❌ El código ha expirado.',
'intentos_restantes' => max(0, 3 - $_SESSION['intentos_codigo_interno'])
]);
exit;
@@ -390,15 +391,15 @@ function verificarCodigoInterno()
unset($_SESSION['intentos_codigo_interno']);
echo json_encode([
'success' => true,
'message' => '✅ Código verificado correctamente.',
'success' => true,
'message' => '✅ Código verificado correctamente.',
'redirect' => '/IMPORTADORES/reset/cambiarPasswordInternoView'
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => '❌ Error interno del servidor. Intenta nuevamente.',
'success' => false,
'message' => '❌ Error interno del servidor. Intenta nuevamente.',
'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0))
]);
exit;
@@ -413,7 +414,7 @@ function verificarCodigoInterno()
function cambiarPasswordInternoView()
{
// Verificar si el usuario ya está autenticado y el código verificado
if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) ||
if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) ||
!isset($_SESSION['cambio_interno']) || !isset($_SESSION['codigo_verificado_interno'])) {
header("Location: /IMPORTADORES/login");
exit;
@@ -425,23 +426,34 @@ function cambiarPasswordInternoView()
function cambiarPasswordInterno()
{
// Limpiar buffer de salida
if (ob_get_level()) {
ob_end_clean();
}
// Iniciar buffer limpio
ob_start();
header('Content-Type: application/json'); // ⬅️ AGREGAR ESTA LÍNEA
// Verificar autorización completa
if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) ||
if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) ||
!isset($_SESSION['cambio_interno']) || !isset($_SESSION['codigo_verificado_interno'])) {
ob_end_clean(); // Limpiar buffer antes de enviar JSON
echo json_encode(['success' => false, 'message' => '❌ No tienes autorización para cambiar la contraseña.']);
exit;
}
$conn = getConnection();
if (!$conn) {
echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']);
exit;
}
$passwordActual = $_POST['password_actual'] ?? '';
$passwordNueva = $_POST['password_nueva'] ?? '';
$passwordActual = $_POST['password_actual'] ?? '';
$passwordNueva = $_POST['password_nueva'] ?? '';
$confirmarPassword = $_POST['confirmar_password'] ?? '';
// Validaciones
@@ -465,12 +477,12 @@ function cambiarPasswordInterno()
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$email = $_SESSION['usuario_email'];
$id_usuario = $_SESSION['usuario_id'];
$email = $_SESSION['usuario_email'];
$emailEncrypted = encrypt($email);
// Verificar contraseña actual
$sql = "SELECT password_hash FROM usuarios_sistema WHERE id_usuario = ?";
$sql = "SELECT password_hash FROM usuarios_sistema WHERE id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$id_usuario]);
if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) {
@@ -484,8 +496,8 @@ function cambiarPasswordInterno()
}
// Actualizar contraseña
$hashNueva = password_hash($passwordNueva, PASSWORD_BCRYPT);
$sqlUpdate = "UPDATE usuarios_sistema SET password_hash = ? WHERE id_usuario = ?";
$hashNueva = password_hash($passwordNueva, PASSWORD_BCRYPT);
$sqlUpdate = "UPDATE usuarios_sistema SET password_hash = ? WHERE id_usuario = ?";
$stmtUpdate = sqlsrv_prepare($conn, $sqlUpdate, [$hashNueva, $id_usuario]);
if (!$stmtUpdate || !sqlsrv_execute($stmtUpdate)) {
@@ -495,18 +507,18 @@ function cambiarPasswordInterno()
// Registrar en bitácora
$ip = $_SERVER['REMOTE_ADDR'] ?? 'N/A';
registrarBitacora($conn, $id_usuario, $email, $ip, 1, 'Cambio de contraseña interno');
registrarBitacora($id_usuario, $email, $ip, 1, 'Cambio de contraseña interno');
// Enviar correo de confirmación
try {
$mail = new PHPMailer(true);
$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);
@@ -547,9 +559,11 @@ function cambiarPasswordInterno()
unset($_SESSION['codigo_verificado_interno']);
unset($_SESSION['codigo_timestamp']);
// Al final, antes de cada echo json_encode:
ob_end_clean();
echo json_encode([
'success' => true,
'message' => '✅ Contraseña actualizada exitosamente.',
'success' => true,
'message' => '✅ Contraseña actualizada exitosamente.',
'redirect' => '/IMPORTADORES/login' // Redirigir a la página de seguridad
]);
exit;
@@ -565,8 +579,8 @@ function cancelarCambioInterno()
if ($conn && isset($_SESSION['usuario_email'])) {
// Invalidar códigos activos
$emailEncrypted = encrypt($_SESSION['usuario_email']);
$sql = "UPDATE recuperacion_password SET estatus = 1 WHERE email = ? AND estatus = 0";
$stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]);
$sql = "UPDATE recuperacion_password SET estatus = 1 WHERE email = ? AND estatus = 0";
$stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]);
if ($stmt) sqlsrv_free_stmt($stmt);
}
@@ -587,16 +601,16 @@ function obtenerEstadoDosFactores()
// CORRIGIDO: Cambiar id_usuario por usuario_id
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario) {
return 0; // valor por defecto si no hay sesión
}
$sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?";
$params = [$id_usuario];
$sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?";
$params = [$id_usuario];
$stmt_dos_factores = sqlsrv_prepare($conn, $sql_dos_factores, $params);
$dos_factores_estado = 0; // valor por defecto
if ($stmt_dos_factores && sqlsrv_execute($stmt_dos_factores)) {
if ($row = sqlsrv_fetch_array($stmt_dos_factores, SQLSRV_FETCH_ASSOC)) {
$dos_factores_estado = (int)$row['dos_factores'];