// aclGuard.js (function () { const DEBUG = true; function log(...args) { if (DEBUG) console.debug("[aclGuard]", ...args); } function getCookie(name) { const match = document.cookie.match( new RegExp("(^| )" + name + "=([^;]+)") ); return match ? decodeURIComponent(match[2]) : null; } function getAccessToken() { if (typeof env === "undefined" || !env.FRONTEND_APP_NAME) return null; const cookieName = env.FRONTEND_APP_NAME + "AccessToken"; return getCookie(cookieName); } async function fetchAclMode(clientid) { const ok = await checkToken(); if (!ok) return { usermode: null, error: "token" }; if (!clientid) return { usermode: null, error: "no-clientid" }; const token = getAccessToken(); if (!token) return { usermode: null, error: "no-token" }; try { const res = await fetch(`${env.ACLMODE_ENDPOINT}_search`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, Accept: "*/*", }, body: JSON.stringify({ clientid }), }); if (!res.ok) { return { usermode: null, error: `http:${res.status}` }; } const data = await res.json(); return { usermode: data?.results?.[0]?.usermode ?? null, error: null, }; } catch (err) { return { usermode: null, error: String(err) }; } } function detectPageType() { const file = ( window.location.pathname.split("/").pop() || "" ).toLowerCase(); if (file.includes("blacklist")) return "blacklist"; if (file.includes("whitelist")) return "whitelist"; return null; } // ✅ Pending usermode = allow function isAllowed(usermode, pageType) { if (!pageType) return true; if (usermode === null) return true; // ⬅️ key fix if (usermode === "") return false; return usermode === pageType; } function showBlockedModal(details) { const id = "aclGuardModal"; let modal = document.getElementById(id); let message = "Access restricted for this client."; if (details.aclResult?.usermode === "whitelist") { message = "Access restricted as this client only allows whitelist mode."; } else if (details.aclResult?.usermode === "blacklist") { message = "Access restricted as this client only allows blacklist mode."; } if (!modal) { modal = document.createElement("div"); modal.id = id; Object.assign(modal.style, { position: "fixed", inset: "0", display: "flex", justifyContent: "center", alignItems: "center", backgroundColor: "rgba(0,0,0,0.6)", zIndex: 99999, }); const box = document.createElement("div"); Object.assign(box.style, { background: "#fff", padding: "20px 30px", borderRadius: "8px", maxWidth: "360px", fontFamily: "Poppins", textAlign: "center", }); const text = document.createElement("p"); text.style.marginBottom = "16px"; box.appendChild(text); const back = document.createElement("button"); back.textContent = "Back"; Object.assign(back.style, { padding: "6px 14px", border: "none", borderRadius: "4px", cursor: "pointer", background: "#007bff", color: "#fff", }); back.onclick = () => location.replace("index.html"); box.appendChild(back); modal.appendChild(box); document.body.appendChild(modal); } modal.querySelector("p").textContent = message; log("Modal shown:", message); } function hideBlockedModal() { const modal = document.getElementById("aclGuardModal"); if (modal) modal.remove(); } let _lastRunId = 0; async function runGuard(pageType, dropdown) { if (!pageType || !dropdown) return; const runId = ++_lastRunId; const clientid = dropdown.value; log(`[runGuard #${runId}] client=${clientid}, page=${pageType}`); const aclResult = await fetchAclMode(clientid); if (runId !== _lastRunId) return; // ⏳ Pending / unknown → do nothing (no flash) if (aclResult.usermode === null) { log("ACL pending — skipping modal"); return; } const allowed = isAllowed(aclResult.usermode, pageType); log( `[runGuard #${runId}] usermode="${aclResult.usermode}" allowed=${allowed}` ); if (!allowed) { showBlockedModal({ pageType, clientid, aclResult }); } else { hideBlockedModal(); } } function setupGuardOnceReady() { const pageType = detectPageType(); if (!pageType) return; function getDropdown() { return ( document.getElementById("systemDropdown") || document.getElementById("defaultClientDropdown") ); } function setup() { const dropdown = getDropdown(); if (!dropdown) return; runGuard(pageType, dropdown); dropdown.addEventListener("change", () => runGuard(pageType, dropdown)); window.addEventListener("pageshow", () => runGuard(pageType, dropdown)); window.addEventListener("storage", (e) => { if (e.key === "currentClient") { runGuard(pageType, getDropdown() || dropdown); } }); } if (getDropdown()) { setup(); } else { document.addEventListener("sidebarLoaded", setup, { once: true }); } } window.aclGuard = function () { setupGuardOnceReady(); }; })();