This commit is contained in:
2025-07-22 10:44:40 -06:00
parent 597ab73d4a
commit 8bb0f84fd1
11 changed files with 589 additions and 307 deletions

View File

@@ -173,16 +173,16 @@ if (!isset($_SESSION['email_recuperacion'])) {
<script>
document.addEventListener('DOMContentLoaded', function () {
const form = document.getElementById('formCodigo');
const mensaje = document.getElementById('mensaje');
const inputCodigo = document.getElementById('codigo');
const form = document.getElementById('formCodigo');
const mensaje = document.getElementById('mensaje');
const inputCodigo = document.getElementById('codigo');
const btnVerificar = document.getElementById('btnVerificar');
const btnReenviar = document.getElementById('btnReenviarRespaldo');
const clearBtn = document.getElementById('clearCode');
const btnReenviar = document.getElementById('btnReenviarRespaldo');
const clearBtn = document.getElementById('clearCode');
const intentosInfo = document.getElementById('intentosInfo');
let intentosRealizados = 0;
const maxIntentos = 3; // ⬅️ Cambiado de 5 a 3 para el controlador interno
const maxIntentos = 5;
// Auto-focus en el input al cargar
inputCodigo.focus();
@@ -220,6 +220,14 @@ if (!isset($_SESSION['email_recuperacion'])) {
}
});
// 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();
@@ -227,7 +235,7 @@ if (!isset($_SESSION['email_recuperacion'])) {
const codigo = inputCodigo.value.trim();
if (!validarCodigo(codigo)) return;
enviarCodigoInterno(codigo);
enviarCodigo(codigo);
});
// Validación del código
@@ -252,8 +260,8 @@ if (!isset($_SESSION['email_recuperacion'])) {
return true;
}
// ⬅️ NUEVA FUNCIÓN: Enviar código para verificación INTERNA
function enviarCodigoInterno(codigo) {
// Enviar código para verificación
function enviarCodigo(codigo) {
// Mostrar estado de carga
btnVerificar.disabled = true;
btnVerificar.classList.add('loading');
@@ -262,43 +270,34 @@ if (!isset($_SESSION['email_recuperacion'])) {
const formData = new FormData();
formData.append('codigo', codigo);
fetch('/IMPORTADORES/reset/verificarCodigoInterno', {
fetch('/IMPORTADORES/login/verificarCodigo', {
method: 'POST',
body: formData,
credentials: 'same-origin'
})
.then(response => {
// ⬅️ IMPORTANTE: Verificar si la respuesta es un redirect (302/200 HTML)
if (response.ok && response.headers.get('content-type')?.includes('text/html')) {
// Si el servidor devolvió HTML, significa que hubo un redirect exitoso
mostrarExito("✅ Código verificado correctamente. Redirigiendo...");
inputCodigo.classList.add('success');
inputCodigo.disabled = true;
setTimeout(() => {
window.location.href = '/IMPORTADORES/reset/cambiarPasswordInternoView';
}, 1500);
return;
}
// Si no es HTML, intentar parsear como JSON (para errores)
return response.json();
})
.then(response => response.json())
.then(data => {
if (!data) return; // Ya fue manejado arriba como éxito
// Manejar respuestas de error JSON
if (data.blocked) {
mostrarError(data.message); // <-- función personalizada con un div bonito
setTimeout(() => {
window.location.href = data.redirect;
}, 4000);
}
if (data.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/reset/cambiarPasswordInternoView';
window.location.href = '/IMPORTADORES/login/cambiarPasswordVista';
}, 1500);
} else {
manejarCodigoIncorrectoInterno(data);
// Código incorrecto
manejarCodigoIncorrecto(data);
}
})
.catch(error => {
@@ -315,56 +314,35 @@ if (!isset($_SESSION['email_recuperacion'])) {
});
}
// ⬅️ NUEVA FUNCIÓN: Manejar errores específicos del controlador interno
function manejarCodigoIncorrectoInterno(data) {
// Mostrar error de cuenta bloqueada
function mostrarError(mensaje) {
const mensajeDiv = document.getElementById('mensaje');
mensajeDiv.innerHTML = `
<div class="text-danger fade-in">
<i class="fas fa-exclamation-triangle me-2"></i> ${mensaje}
</div>
`;
}
// Manejar código incorrecto
function manejarCodigoIncorrecto(data) {
intentosRealizados++;
mostrarError(data.message || "❌ Código incorrecto.");
mostrarError(data.message);
inputCodigo.classList.add('error');
// Limpiar input y enfocar para nuevo intento
limpiarYEnfocarInput();
// Actualizar contador de intentos
actualizarContadorIntentosInterno();
actualizarContadorIntentos();
// Si se excedieron los intentos (3 para interno)
if (intentosRealizados >= maxIntentos) {
bloquearFormularioInterno();
// Si se bloqueó el código
if (data.blocked) {
bloquearFormulario();
}
}
// ⬅️ MODIFICADA: Actualizar contador de intentos para interno
function actualizarContadorIntentosInterno() {
if (intentosRealizados > 0) {
const restantes = maxIntentos - intentosRealizados;
intentosInfo.innerHTML = `
<i class="fas fa-exclamation-triangle text-warning me-1"></i>
Intentos restantes: <strong>${restantes}</strong> de ${maxIntentos}
`;
intentosInfo.classList.add('fade-in');
}
}
// ⬅️ MODIFICADA: Bloquear formulario para interno
function bloquearFormularioInterno() {
inputCodigo.disabled = true;
btnVerificar.disabled = true;
if (btnReenviar) btnReenviar.disabled = true;
intentosInfo.innerHTML = `
<i class="fas fa-ban text-danger me-1"></i>
<span class="text-danger">Demasiados intentos fallidos</span>
`;
mostrarError("❌ Demasiados intentos fallidos. Redirigiendo...");
// Redirigir a la página de seguridad después de 3 segundos
setTimeout(() => {
window.location.href = '/IMPORTADORES/seguridad/index';
}, 3000);
}
// Limpiar input y enfocar
function limpiarYEnfocarInput() {
setTimeout(() => {
@@ -372,7 +350,7 @@ if (!isset($_SESSION['email_recuperacion'])) {
inputCodigo.classList.remove('error');
inputCodigo.focus();
clearBtn.style.display = 'none';
}, 1500);
}, 1500); // Esperar 1.5 segundos antes de limpiar
}
// Actualizar contador visual
@@ -385,6 +363,35 @@ if (!isset($_SESSION['email_recuperacion'])) {
}
}
// Actualizar contador de intentos
function actualizarContadorIntentos() {
if (intentosRealizados > 0) {
const restantes = maxIntentos - intentosRealizados;
intentosInfo.innerHTML = `
<i class="fas fa-exclamation-triangle text-warning me-1"></i>
Intentos restantes: <strong>${restantes}</strong> 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 = `
<i class="fas fa-ban text-danger me-1"></i>
<span class="text-danger">Código bloqueado por seguridad</span>
`;
// 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 = `<div class="${tipo} fade-in">${texto}</div>`;
@@ -407,39 +414,40 @@ if (!isset($_SESSION['email_recuperacion'])) {
mensaje.innerHTML = '';
}
// Manejo del botón de reenvío (si existe)
if (btnReenviar) {
btnReenviar.addEventListener("click", function() {
const btnOriginalText = this.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 = '<i class="fas fa-spinner fa-spin me-1"></i>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);
this.disabled = true;
this.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Enviando...';
fetch("/IMPORTADORES/reset/reenviarCodigoInterno", {
method: "POST",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: "accion=reenviarCodigo"
})
.then(response => response.json())
.then(data => {
mostrarInfo(data.message);
setTimeout(() => {
this.disabled = false;
this.innerHTML = btnOriginalText;
}, 30000);
})
.catch(error => {
console.error('Error:', error);
mostrarError("❌ Error al reenviar código.");
// 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;
});
}
});
// Manejar tecla Enter
// Manejar tecla Enter en cualquier parte del formulario
document.addEventListener('keypress', function(e) {
if (e.key === 'Enter' && !btnVerificar.disabled) {
form.dispatchEvent(new Event('submit'));