const DENY_LABELS = { feature: "You do not have permission to access this feature.", client: "You do not have access to this client.", }; /** * @param {string} feature * @param {string} clientId * @returns {Promise} */ export async function checkFeatureAccess(feature, clientId) { try { const params = new URLSearchParams({ feature, clientId }); const res = await fetch(`/api/auth/feature-check?${params}`, { credentials: "include" }); if (res.status === 401) { window.location.href = "/"; return false; } if (!res.ok) return true; const data = await res.json(); if (data.allowed) return true; const reasons = Array.isArray(data.denied) ? data.denied : []; showAccessDenied(reasons); return false; } catch { return true; } } function showAccessDenied(reasons) { const messages = reasons.map((r) => DENY_LABELS[r] || "Access denied.").join(" "); document.body.style.visibility = "hidden"; const overlay = document.createElement("div"); overlay.id = "access-denied-overlay"; overlay.style.cssText = "position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:#0f172a;visibility:visible;"; const card = document.createElement("div"); card.style.cssText = "max-width:420px;width:90%;text-align:center;padding:2rem;border-radius:1rem;background:#1e293b;border:1px solid #dc2626;"; card.innerHTML = `

Access Denied

${escapeHtml(messages)}

Contact your administrator to request access.

`; const closeBtn = document.createElement("button"); closeBtn.textContent = "Close Tab"; closeBtn.style.cssText = "padding:0.5rem 1.25rem;border-radius:0.5rem;background:#334155;color:#e2e8f0;border:1px solid #475569;cursor:pointer;font-size:0.875rem;"; closeBtn.addEventListener("click", () => window.close()); card.appendChild(closeBtn); overlay.appendChild(card); document.body.appendChild(overlay); } function escapeHtml(text) { const el = document.createElement("span"); el.textContent = text; return el.innerHTML; }