298 lines
12 KiB
JavaScript
298 lines
12 KiB
JavaScript
// ================================
|
|
// UTILIDADES DE AUTENTICACIÓN
|
|
// ================================
|
|
|
|
/** Devuelve el token JWT o null si no hay sesión. */
|
|
function getToken() {
|
|
return localStorage.getItem("token");
|
|
}
|
|
|
|
/** Devuelve el objeto usuario guardado en sesión, o null. */
|
|
function getUsuario() {
|
|
const u = localStorage.getItem("usuario");
|
|
return u ? JSON.parse(u) : null;
|
|
}
|
|
|
|
/**
|
|
* Verifica que el usuario esté autenticado.
|
|
* Si no lo está, redirige a login.html y devuelve null.
|
|
*/
|
|
function verificarAuth() {
|
|
if (!getToken()) {
|
|
window.location.href = "login.html";
|
|
return null;
|
|
}
|
|
return getUsuario();
|
|
}
|
|
|
|
/** Cierra la sesión y recarga la página actual (o va a index si es protegida). */
|
|
function cerrarSesion() {
|
|
localStorage.removeItem("token");
|
|
localStorage.removeItem("usuario");
|
|
const paginasProtegidas = ["intenciones.html", "diario-oracion.html"];
|
|
const actual = location.pathname.split("/").pop();
|
|
if (paginasProtegidas.includes(actual)) {
|
|
window.location.href = "index.html";
|
|
} else {
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Muestra el nombre del usuario y el botón de cerrar sesión en el header.
|
|
* Sin sesión: muestra botones que abren el modal de auth.
|
|
*/
|
|
function mostrarSesionEnHeader() {
|
|
const usuario = getUsuario();
|
|
const contenedor = document.getElementById("header-sesion");
|
|
if (!contenedor) return;
|
|
|
|
if (usuario) {
|
|
contenedor.innerHTML = `
|
|
<span class="header-usuario">👤 ${usuario.nombre}</span>
|
|
<button class="btn-cerrar-sesion" onclick="cerrarSesion()">Salir</button>
|
|
`;
|
|
} else {
|
|
contenedor.innerHTML = `
|
|
<button class="btn-registro" onclick="abrirModalAuth('registro')">Registrarse</button>
|
|
<button class="btn-sesion" onclick="abrirModalAuth('login')">Iniciar sesión</button>
|
|
`;
|
|
}
|
|
}
|
|
|
|
|
|
// ================================
|
|
// MODAL DE AUTENTICACIÓN
|
|
// ================================
|
|
|
|
/** Resuelve la base de la API aunque api-config.js no esté cargado en la página. */
|
|
function _apiBase() {
|
|
if (typeof API_BASE !== "undefined") return API_BASE;
|
|
return (location.hostname === "localhost" ||
|
|
location.hostname === "127.0.0.1" ||
|
|
location.hostname === "")
|
|
? "http://localhost:8080"
|
|
: "https://recursos-catolicos.es:8080";
|
|
}
|
|
|
|
/** Crea e inserta el modal en el DOM la primera vez que se abre. */
|
|
function _inyectarModalAuth() {
|
|
if (document.getElementById("modal-auth")) return;
|
|
|
|
const el = document.createElement("div");
|
|
el.id = "modal-auth";
|
|
el.className = "modal-auth-overlay";
|
|
el.setAttribute("role", "dialog");
|
|
el.setAttribute("aria-modal", "true");
|
|
el.setAttribute("aria-label", "Iniciar sesión o registrarse");
|
|
el.innerHTML = `
|
|
<div class="modal-auth-caja">
|
|
<button class="modal-auth-cerrar" id="modal-auth-cerrar" aria-label="Cerrar">×</button>
|
|
|
|
<div class="modal-auth-tabs" role="tablist">
|
|
<button class="modal-auth-tab activa" data-tab="login" role="tab">Iniciar sesión</button>
|
|
<button class="modal-auth-tab" data-tab="registro" role="tab">Registrarse</button>
|
|
</div>
|
|
|
|
<!-- Panel: Login -->
|
|
<div class="modal-auth-panel" id="modal-panel-login" role="tabpanel">
|
|
<p class="modal-auth-bienvenida">Bienvenido de nuevo 🙏</p>
|
|
<input type="email" id="modal-email" placeholder="correo@example.com" autocomplete="email">
|
|
<input type="password" id="modal-password" placeholder="Contraseña" autocomplete="current-password">
|
|
<button class="modal-auth-btn" id="modal-btn-login">Entrar</button>
|
|
<p id="modal-login-msg" class="modal-auth-msg" aria-live="polite"></p>
|
|
<p class="modal-auth-pie">¿Olvidaste tu contraseña? <a href="login.html">Más opciones</a></p>
|
|
</div>
|
|
|
|
<!-- Panel: Registro -->
|
|
<div class="modal-auth-panel" id="modal-panel-registro" role="tabpanel" style="display:none;">
|
|
<p class="modal-auth-bienvenida">Crea tu espacio personal ✝</p>
|
|
<input type="text" id="modal-nombre" placeholder="Tu nombre" autocomplete="name">
|
|
<input type="email" id="modal-email-reg" placeholder="correo@example.com" autocomplete="email">
|
|
<input type="password" id="modal-password-reg" placeholder="Mínimo 8 caracteres" autocomplete="new-password">
|
|
<button class="modal-auth-btn" id="modal-btn-registro">Registrarme</button>
|
|
<p id="modal-registro-msg" class="modal-auth-msg" aria-live="polite"></p>
|
|
<p class="modal-auth-pie">¿Quieres más opciones? <a href="register.html">Registro completo</a></p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
document.body.appendChild(el);
|
|
|
|
// — Cerrar —
|
|
document.getElementById("modal-auth-cerrar").addEventListener("click", cerrarModalAuth);
|
|
el.addEventListener("click", e => { if (e.target === el) cerrarModalAuth(); });
|
|
document.addEventListener("keydown", _modalKeyHandler);
|
|
|
|
// — Pestañas —
|
|
el.querySelectorAll(".modal-auth-tab").forEach(tab => {
|
|
tab.addEventListener("click", () => {
|
|
el.querySelectorAll(".modal-auth-tab").forEach(t => t.classList.remove("activa"));
|
|
tab.classList.add("activa");
|
|
document.getElementById("modal-panel-login").style.display = tab.dataset.tab === "login" ? "block" : "none";
|
|
document.getElementById("modal-panel-registro").style.display = tab.dataset.tab === "registro" ? "block" : "none";
|
|
_focoModal(tab.dataset.tab);
|
|
});
|
|
});
|
|
|
|
// — Enter para enviar —
|
|
["modal-email", "modal-password"].forEach(id =>
|
|
document.getElementById(id).addEventListener("keydown", e => { if (e.key === "Enter") _loginModal(); })
|
|
);
|
|
["modal-nombre", "modal-email-reg", "modal-password-reg"].forEach(id =>
|
|
document.getElementById(id).addEventListener("keydown", e => { if (e.key === "Enter") _registroModal(); })
|
|
);
|
|
|
|
document.getElementById("modal-btn-login").addEventListener("click", _loginModal);
|
|
document.getElementById("modal-btn-registro").addEventListener("click", _registroModal);
|
|
}
|
|
|
|
function _modalKeyHandler(e) {
|
|
if (e.key === "Escape") cerrarModalAuth();
|
|
}
|
|
|
|
function _focoModal(tab) {
|
|
setTimeout(() => {
|
|
const id = tab === "login" ? "modal-email" : "modal-nombre";
|
|
document.getElementById(id)?.focus();
|
|
}, 80);
|
|
}
|
|
|
|
/** Abre el modal en la pestaña indicada ('login' | 'registro'). */
|
|
function abrirModalAuth(tab = "login") {
|
|
_inyectarModalAuth();
|
|
const modal = document.getElementById("modal-auth");
|
|
|
|
// Limpiar mensajes y campos al abrir
|
|
["modal-login-msg", "modal-registro-msg"].forEach(id => {
|
|
const el = document.getElementById(id);
|
|
if (el) { el.textContent = ""; el.className = "modal-auth-msg"; }
|
|
});
|
|
|
|
modal.querySelectorAll(".modal-auth-tab").forEach(t => t.classList.remove("activa"));
|
|
modal.querySelector(`[data-tab="${tab}"]`).classList.add("activa");
|
|
document.getElementById("modal-panel-login").style.display = tab === "login" ? "block" : "none";
|
|
document.getElementById("modal-panel-registro").style.display = tab === "registro" ? "block" : "none";
|
|
|
|
modal.classList.add("activo");
|
|
document.body.classList.add("modal-abierto");
|
|
_focoModal(tab);
|
|
}
|
|
|
|
/** Cierra el modal. */
|
|
function cerrarModalAuth() {
|
|
const modal = document.getElementById("modal-auth");
|
|
if (!modal) return;
|
|
modal.classList.remove("activo");
|
|
document.body.classList.remove("modal-abierto");
|
|
}
|
|
|
|
/** Lógica de inicio de sesión desde el modal. */
|
|
async function _loginModal() {
|
|
const email = document.getElementById("modal-email").value.trim();
|
|
const password = document.getElementById("modal-password").value.trim();
|
|
const msg = document.getElementById("modal-login-msg");
|
|
const btn = document.getElementById("modal-btn-login");
|
|
|
|
msg.textContent = "";
|
|
msg.className = "modal-auth-msg";
|
|
|
|
if (!email || !password) {
|
|
msg.textContent = "Completa todos los campos.";
|
|
msg.classList.add("error");
|
|
return;
|
|
}
|
|
|
|
btn.disabled = true;
|
|
btn.textContent = "Entrando…";
|
|
|
|
try {
|
|
const res = await fetch(`${_apiBase()}/auth/login`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ email, password })
|
|
});
|
|
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
localStorage.setItem("token", data.token);
|
|
localStorage.setItem("usuario", JSON.stringify(data.usuario));
|
|
msg.textContent = `¡Bienvenido, ${data.usuario.nombre}! ✝`;
|
|
msg.classList.add("success");
|
|
setTimeout(() => location.reload(), 900);
|
|
} else {
|
|
msg.textContent = "Email o contraseña incorrectos.";
|
|
msg.classList.add("error");
|
|
btn.disabled = false;
|
|
btn.textContent = "Entrar";
|
|
}
|
|
} catch (e) {
|
|
msg.textContent = "No se pudo conectar con el servidor.";
|
|
msg.classList.add("error");
|
|
btn.disabled = false;
|
|
btn.textContent = "Entrar";
|
|
}
|
|
}
|
|
|
|
/** Lógica de registro desde el modal (individual; registro completo en register.html). */
|
|
async function _registroModal() {
|
|
const nombre = document.getElementById("modal-nombre").value.trim();
|
|
const email = document.getElementById("modal-email-reg").value.trim();
|
|
const password = document.getElementById("modal-password-reg").value.trim();
|
|
const msg = document.getElementById("modal-registro-msg");
|
|
const btn = document.getElementById("modal-btn-registro");
|
|
|
|
msg.textContent = "";
|
|
msg.className = "modal-auth-msg";
|
|
|
|
if (!nombre || !email || !password) {
|
|
msg.textContent = "Completa todos los campos.";
|
|
msg.classList.add("error");
|
|
return;
|
|
}
|
|
if (password.length < 8) {
|
|
msg.textContent = "La contraseña debe tener al menos 8 caracteres.";
|
|
msg.classList.add("error");
|
|
return;
|
|
}
|
|
|
|
btn.disabled = true;
|
|
btn.textContent = "Registrando…";
|
|
|
|
try {
|
|
const res = await fetch(`${_apiBase()}/auth/register`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ nombre, email, password, tipoUsuario: "individual" })
|
|
});
|
|
|
|
if (res.ok) {
|
|
msg.textContent = "¡Cuenta creada! Iniciando sesión…";
|
|
msg.classList.add("success");
|
|
|
|
// Auto-login tras el registro
|
|
const loginRes = await fetch(`${_apiBase()}/auth/login`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ email, password })
|
|
});
|
|
if (loginRes.ok) {
|
|
const data = await loginRes.json();
|
|
localStorage.setItem("token", data.token);
|
|
localStorage.setItem("usuario", JSON.stringify(data.usuario));
|
|
}
|
|
setTimeout(() => location.reload(), 900);
|
|
} else {
|
|
const error = await res.text();
|
|
msg.textContent = error || "No se pudo crear la cuenta.";
|
|
msg.classList.add("error");
|
|
btn.disabled = false;
|
|
btn.textContent = "Registrarme";
|
|
}
|
|
} catch (e) {
|
|
msg.textContent = "No se pudo conectar con el servidor.";
|
|
msg.classList.add("error");
|
|
btn.disabled = false;
|
|
btn.textContent = "Registrarme";
|
|
}
|
|
}
|