hbox-docs/docs/publico/entrar.js

133 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Página de entrada (27-oct-2026).
- Si ya hay sesión, salta directo a donde ibas (nginx manda aquí con #/ruta/original).
- Entrar: POST /api/entrar → el servidor pone la cookie de sesión; el mensaje dice qué pasó.
- Avisos públicos del sitio (incidencias marcadas «publica») y reporte sin sesión (POST /api/incidencias/publica). */
(function () {
var $ = function (id) { return document.getElementById(id); };
function destino() {
// Solo rutas de ESTE sitio: se arma la URL completa y se exige el mismo origen (un «/\t/otro.com» o «/\\otro.com»
// se vuelve «//otro.com» en el navegador: comparar el origen lo cierra). Nunca regresa a la entrada.
var h = '';
try { h = decodeURIComponent((location.hash || '').slice(1)); } catch (e) { h = ''; }
if (!h || h.charAt(0) !== '/') return '/';
try {
var u = new URL(h, location.origin);
if (u.origin !== location.origin || /^\/entrar\.html/.test(u.pathname)) return '/';
return u.href; // absoluta y del mismo origen (un «/.//otro.com» relativo sería otro sitio)
} catch (e) { return '/'; }
}
function ir() { location.replace(destino()); }
function mensaje(el, html, bien) { el.className = 'en-msg ' + (bien ? 'ok' : 'err'); el.innerHTML = html; }
function esc(s) { var d = document.createElement('div'); d.textContent = s == null ? '' : String(s); return d.innerHTML; }
// ¿ya hay sesión?
fetch('/api/sesion', { cache: 'no-store', credentials: 'same-origin' })
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (j) { if (j && j.sesion) ir(); })
.catch(function () {});
// usuario recordado (solo el nombre, nunca la contraseña)
try { var u0 = localStorage.getItem('hbox.usuario'); if (u0) { $('usuario').value = u0; } } catch (e) {}
($('usuario').value ? $('password') : $('usuario')).focus();
$('ver').addEventListener('click', function () {
var p = $('password'), mostrar = p.type === 'password';
p.type = mostrar ? 'text' : 'password';
this.textContent = mostrar ? 'Ocultar' : 'Ver';
this.setAttribute('aria-pressed', mostrar ? 'true' : 'false');
this.setAttribute('aria-label', mostrar ? 'Ocultar la contraseña' : 'Mostrar la contraseña');
});
function revisarMayus(ev) {
if (ev.getModifierState) $('mayus').hidden = !ev.getModifierState('CapsLock');
}
$('password').addEventListener('keydown', revisarMayus);
$('password').addEventListener('keyup', revisarMayus);
$('fEntrar').addEventListener('submit', function (ev) {
ev.preventDefault();
var b = $('bEntrar'), msg = $('msg');
var usuario = $('usuario').value.trim(), password = $('password').value;
if (!usuario || !password) { mensaje(msg, 'Escribe tu usuario y tu contraseña.', false); return; }
b.disabled = true; b.textContent = 'Entrando…';
fetch('/api/entrar', {
method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ usuario: usuario, password: password, recordar: $('recordar').checked })
}).then(function (r) {
return r.json().catch(function () { return { ok: false, error: 'El servidor no respondió bien (HTTP ' + r.status + ').' }; });
}).then(function (j) {
if (j && j.ok) {
try { localStorage.setItem('hbox.usuario', usuario); } catch (e) {}
mensaje(msg, '<b>Listo, ' + esc(j.user) + '.</b> Abriendo el sitio…', true);
ir();
return;
}
var t = esc((j && j.error) || 'No se pudo entrar.');
if (j && j.codigo === 'contrasena') {
$('password').value = ''; $('password').focus();
} else if (j && j.codigo === 'usuario') {
$('usuario').focus();
}
if (j && (j.codigo === 'bloqueado' || j.codigo === 'contrasena')) {
t += ' <a href="#" id="abrirAyuda">Reportar el problema</a>.';
}
mensaje(msg, t, false);
var a = $('abrirAyuda');
if (a) a.addEventListener('click', function (e) { e.preventDefault(); abrirAyuda(); });
}).catch(function () {
mensaje(msg, 'No pude contactar al servidor. Revisa tu conexión e intenta otra vez; si sigue, repórtalo abajo.', false);
}).then(function () { b.disabled = false; b.textContent = 'Entrar'; });
});
function abrirAyuda() {
var d = $('ayuda'); d.open = true;
if (!$('rNombre').value) $('rNombre').value = $('usuario').value.trim();
d.scrollIntoView({ behavior: 'smooth', block: 'start' });
setTimeout(function () { $('rDesc').focus(); }, 300);
}
$('ayuda').addEventListener('toggle', function () {
if (this.open && !$('rNombre').value) $('rNombre').value = $('usuario').value.trim();
});
$('fReporte').addEventListener('submit', function (ev) {
ev.preventDefault();
var b = $('bReporte'), msg = $('msgR');
var tipo = (document.querySelector('input[name="rTipo"]:checked') || {}).value || 'acceso';
var cuerpo = { nombre: $('rNombre').value.trim(), contacto: $('rContacto').value.trim(), descripcion: $('rDesc').value.trim(),
tipo: tipo, sitio_web: $('rTrampa').value, pantalla: screen.width + '×' + screen.height };
if (cuerpo.descripcion.length < 5) { mensaje(msg, 'Cuéntanos qué pasa (aunque sea una línea).', false); return; }
if (!cuerpo.nombre && !cuerpo.contacto) { mensaje(msg, 'Dinos quién eres o cómo contactarte.', false); return; }
b.disabled = true; b.textContent = 'Enviando…';
fetch('/api/incidencias/publica', {
method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(cuerpo)
}).then(function (r) { return r.json().catch(function () { return { ok: false, error: 'HTTP ' + r.status }; }); })
.then(function (j) {
if (j && j.ok) {
mensaje(msg, '<b>Recibido: ' + esc(j.id) + '.</b> Se revisa todos los días; si dejaste cómo contactarte, te buscamos. '
+ 'Guarda el folio por si preguntas.', true);
$('rDesc').value = '';
} else {
mensaje(msg, esc((j && j.error) || 'No se pudo enviar.'), false);
}
})
.catch(function () { mensaje(msg, 'No pude contactar al servidor. Avísale a Leo o a Gibran por mensaje.', false); })
.then(function () { b.disabled = false; b.textContent = 'Enviar reporte'; });
});
// avisos públicos
fetch('/api/incidencias/publicas', { cache: 'no-store', credentials: 'same-origin' })
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (j) {
if (!j || !j.ok || !j.avisos || !j.avisos.length) return;
var ul = $('avisosLista');
j.avisos.forEach(function (a) {
var li = document.createElement('li');
li.innerHTML = '<span class="en-pill' + (a.resuelta ? ' ok' : '') + '">' + (a.resuelta ? 'Resuelto' : 'En atención') + '</span>'
+ '<span>' + esc(a.titulo) + '</span> <small>' + esc(a.actualizado) + '</small>';
ul.appendChild(li);
});
$('avisos').hidden = false;
})
.catch(function () {});
})();