"use strict"; /* * ========================================================= * CONFIGURATION * ========================================================= */ const API_LOGIN = "../php/api_login.php"; const API = "../php/securite/"; /* * ========================================================= * ELEMENTS HTML * ========================================================= */ const listeUtilisateurs = document.getElementById("listeUtilisateurs"); const message = document.getElementById("message"); const btnNouvelUtilisateur = document.getElementById("btnNouvelUtilisateur"); /* Modal création */ const modalCreation = document.getElementById("modalCreation"); const formCreation = document.getElementById("formCreation"); const btnAnnulerCreation = document.getElementById("btnAnnulerCreation"); const creationNom = document.getElementById("creationNom"); const creationPass = document.getElementById("creationPass"); const creationPass2 = document.getElementById("creationPass2"); /* Modal mot de passe */ const modalPassword = document.getElementById("modalPassword"); const formPassword = document.getElementById("formPassword"); const btnAnnulerPassword = document.getElementById("btnAnnulerPassword"); const passwordId = document.getElementById("passwordId"); const passwordUtilisateur = document.getElementById("passwordUtilisateur"); const nouveauPass = document.getElementById("nouveauPass"); const nouveauPass2 = document.getElementById("nouveauPass2"); /* * ========================================================= * MESSAGE * ========================================================= */ function afficherMessage(texte, type = "success") { if (!message) { return; } message.textContent = texte; message.className = "mb-4 px-4 py-3 rounded-lg"; if (type === "success") { message.classList.add( "bg-emerald-900", "text-emerald-300", "border", "border-emerald-700", ); } else if (type === "error") { message.classList.add( "bg-rose-900", "text-rose-300", "border", "border-rose-700", ); } else { message.classList.add( "bg-yellow-900", "text-yellow-300", "border", "border-yellow-700", ); } setTimeout(() => { message.classList.add("hidden"); }, 5000); } /* * ========================================================= * VERIFICATION SESSION * ========================================================= */ async function verifierSession() { try { const response = await fetch(API_LOGIN, { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "same-origin", cache: "no-store", body: JSON.stringify({ action: "check", }), }); if (!response.ok) { window.location.href = "/html/admin.html"; return false; } const data = await response.json(); console.log("Vérification session :", data); if (data.status !== "success" || data.authenticated !== true) { window.location.href = "/html/admin.html"; return false; } return true; } catch (error) { console.error("Erreur vérification session :", error); window.location.href = "/html/admin.html"; return false; } } /* * ========================================================= * ECHAPPER HTML * ========================================================= */ function escapeHtml(value) { if (value === null || value === undefined) { return ""; } return String(value) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } /* * ========================================================= * FORMAT DATE * ========================================================= */ function formaterDate(date) { if (!date || date === "0000-00-00 00:00:00") { return "Jamais"; } const d = new Date(String(date).replace(" ", "T")); if (Number.isNaN(d.getTime())) { return date; } return d.toLocaleString("fr-FR", { dateStyle: "short", timeStyle: "short", }); } /* * ========================================================= * CHARGER UTILISATEURS * ========================================================= */ async function chargerUtilisateurs() { if (!listeUtilisateurs) { console.error("ERREUR : #listeUtilisateurs introuvable dans securite.html"); return; } listeUtilisateurs.innerHTML = ` Chargement... `; try { const response = await fetch(API + "users.php", { method: "GET", credentials: "same-origin", cache: "no-store", }); console.log("users.php HTTP :", response.status); if (response.status === 401) { window.location.href = "/html/admin.html"; return; } const data = await response.json(); console.log("Réponse users.php :", data); if (data.success !== true) { throw new Error( data.message || "Impossible de charger les utilisateurs.", ); } const utilisateurs = Array.isArray(data.users) ? data.users : []; console.log("Utilisateurs reçus :", utilisateurs.length); console.table(utilisateurs); afficherUtilisateurs(utilisateurs); } catch (error) { console.error("Erreur chargement utilisateurs :", error); listeUtilisateurs.innerHTML = ` Erreur lors du chargement des utilisateurs. `; afficherMessage(error.message || "Erreur lors du chargement.", "error"); } } /* * ========================================================= * AFFICHER UTILISATEURS * ========================================================= */ function afficherUtilisateurs(utilisateurs) { if (!utilisateurs || utilisateurs.length === 0) { listeUtilisateurs.innerHTML = ` Aucun utilisateur. `; return; } listeUtilisateurs.innerHTML = utilisateurs .map((utilisateur) => { const id = Number(utilisateur.id); const nom = escapeHtml(utilisateur.nom); const actif = Number(utilisateur.actif) === 1; const created = formaterDate(utilisateur.created_at); const dernierLogin = formaterDate(utilisateur.dernier_login); return `
${nom}
ID : ${id}
${created} ${dernierLogin} ${ actif ? ` Actif ` : ` Inactif ` }
`; }) .join(""); /* * Boutons mot de passe */ document.querySelectorAll(".btn-password").forEach((button) => { button.addEventListener("click", () => { ouvrirModalPassword(button.dataset.id, button.dataset.nom); }); }); /* * Boutons statut */ document.querySelectorAll(".btn-status").forEach((button) => { button.addEventListener("click", () => { changerStatut(button.dataset.id, Number(button.dataset.actif)); }); }); } /* * ========================================================= * MODALE CREATION * ========================================================= */ function ouvrirModalCreation() { if (!modalCreation) { return; } modalCreation.classList.remove("hidden"); modalCreation.classList.add("flex"); setTimeout(() => creationNom?.focus(), 100); } function fermerModalCreation() { if (!modalCreation) { return; } modalCreation.classList.add("hidden"); modalCreation.classList.remove("flex"); formCreation?.reset(); } /* * ========================================================= * CREER UTILISATEUR * ========================================================= */ async function creerUtilisateur() { const nom = creationNom.value.trim(); const pass = creationPass.value; const pass2 = creationPass2.value; if (!nom) { afficherMessage("Veuillez saisir un nom utilisateur.", "error"); creationNom.focus(); return; } if (pass.length < 4) { afficherMessage( "Le mot de passe doit contenir au moins 4 caractères.", "error", ); creationPass.focus(); return; } if (pass !== pass2) { afficherMessage("Les deux mots de passe ne correspondent pas.", "error"); creationPass2.focus(); return; } const bouton = formCreation.querySelector('button[type="submit"]'); bouton.disabled = true; bouton.textContent = "Création..."; try { const response = await fetch(API + "create.php", { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "same-origin", body: JSON.stringify({ nom: nom, pass: pass, }), }); if (response.status === 401) { window.location.href = "/html/admin.html"; return; } const data = await response.json(); if (data.success !== true) { throw new Error(data.message || "Impossible de créer l'utilisateur."); } fermerModalCreation(); afficherMessage("Utilisateur créé avec succès.", "success"); await chargerUtilisateurs(); } catch (error) { console.error("Erreur création utilisateur :", error); afficherMessage(error.message || "Erreur lors de la création.", "error"); } finally { bouton.disabled = false; bouton.textContent = "Créer"; } } /* * ========================================================= * MODALE PASSWORD * ========================================================= */ function ouvrirModalPassword(id, nom) { passwordId.value = id; passwordUtilisateur.textContent = "Utilisateur : " + nom; nouveauPass.value = ""; nouveauPass2.value = ""; modalPassword.classList.remove("hidden"); modalPassword.classList.add("flex"); setTimeout(() => nouveauPass?.focus(), 100); } function fermerModalPassword() { modalPassword.classList.add("hidden"); modalPassword.classList.remove("flex"); formPassword?.reset(); passwordId.value = ""; passwordUtilisateur.textContent = ""; } /* * ========================================================= * MODIFIER PASSWORD * ========================================================= */ async function modifierPassword() { const id = Number(passwordId.value); const pass = nouveauPass.value; const pass2 = nouveauPass2.value; if (!id) { afficherMessage("Utilisateur invalide.", "error"); return; } if (pass.length < 4) { afficherMessage( "Le mot de passe doit contenir au moins 4 caractères.", "error", ); nouveauPass.focus(); return; } if (pass !== pass2) { afficherMessage("Les deux mots de passe ne correspondent pas.", "error"); nouveauPass2.focus(); return; } const bouton = formPassword.querySelector('button[type="submit"]'); bouton.disabled = true; bouton.textContent = "Modification..."; try { const response = await fetch(API + "password.php", { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "same-origin", body: JSON.stringify({ id: id, pass: pass, }), }); if (response.status === 401) { window.location.href = "/html/admin.html"; return; } const data = await response.json(); if (data.success !== true) { throw new Error( data.message || "Impossible de modifier le mot de passe.", ); } fermerModalPassword(); afficherMessage("Mot de passe modifié avec succès.", "success"); } catch (error) { console.error("Erreur modification mot de passe :", error); afficherMessage( error.message || "Erreur lors de la modification.", "error", ); } finally { bouton.disabled = false; bouton.textContent = "Modifier"; } } /* * ========================================================= * CHANGER STATUT * ========================================================= */ async function changerStatut(id, actifActuel) { const nouveauStatut = actifActuel === 1 ? 0 : 1; const confirmation = nouveauStatut === 1 ? "Voulez-vous activer cet utilisateur ?" : "Voulez-vous désactiver cet utilisateur ?"; if (!window.confirm(confirmation)) { return; } try { const response = await fetch(API + "status.php", { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "same-origin", body: JSON.stringify({ id: Number(id), actif: nouveauStatut, }), }); if (response.status === 401) { window.location.href = "/html/admin.html"; return; } const data = await response.json(); if (data.success !== true) { throw new Error(data.message || "Impossible de modifier le statut."); } afficherMessage( nouveauStatut === 1 ? "Utilisateur activé." : "Utilisateur désactivé.", "success", ); await chargerUtilisateurs(); } catch (error) { console.error("Erreur changement statut :", error); afficherMessage( error.message || "Erreur lors de la modification.", "error", ); } } /* * ========================================================= * EVENEMENTS * ========================================================= */ btnNouvelUtilisateur?.addEventListener("click", ouvrirModalCreation); btnAnnulerCreation?.addEventListener("click", fermerModalCreation); btnAnnulerPassword?.addEventListener("click", fermerModalPassword); formCreation?.addEventListener("submit", (event) => { event.preventDefault(); creerUtilisateur(); }); formPassword?.addEventListener("submit", (event) => { event.preventDefault(); modifierPassword(); }); /* * Fermeture modales */ modalCreation?.addEventListener("click", (event) => { if (event.target === modalCreation) { fermerModalCreation(); } }); modalPassword?.addEventListener("click", (event) => { if (event.target === modalPassword) { fermerModalPassword(); } }); /* * ESC */ document.addEventListener("keydown", (event) => { if (event.key !== "Escape") { return; } if (modalCreation && !modalCreation.classList.contains("hidden")) { fermerModalCreation(); } if (modalPassword && !modalPassword.classList.contains("hidden")) { fermerModalPassword(); } }); /* * ========================================================= * INITIALISATION * ========================================================= */ document.addEventListener("DOMContentLoaded", async () => { console.log("securite.js chargé"); console.log("listeUtilisateurs =", listeUtilisateurs); const authentifie = await verifierSession(); if (!authentifie) { return; } await chargerUtilisateurs(); });