(function () { "use strict"; const PRESETS_URL = "/ui/platform-overlay/presets.json"; const MAX_APPLY_ATTEMPTS = 40; const APPLY_INTERVAL_MS = 250; const DEFAULT_PRESETS = { namespace: "", method: "oidc", mount: "netkingdom", role: "platform-admin", title: "Sign in with KeyCape", signInLabel: "Sign in with KeyCape", banner: "Platform operators authenticate through KeyCape at kc.coulomb.social.", }; let presets = { ...DEFAULT_PRESETS }; let applyAttempts = 0; let applyTimer = null; let overlayApplied = false; function isAuthPage() { const path = window.location.pathname; return ( /\/ui\/vault\/auth(?:\/|$)/.test(path) || /\/ui\/?$/.test(path) ); } function hideNode(node) { if (!node || node.dataset.keycapeOverlayHidden === "true") return; const field = node.closest(".field.is-horizontal") || node.closest(".field") || node.closest(".box") || node; if (field.dataset.keycapeOverlayHidden === "true") return; field.style.display = "none"; field.setAttribute("aria-hidden", "true"); field.dataset.keycapeOverlayHidden = "true"; } function setInputValue(input, value) { if (!input || input.dataset.keycapeOverlayPreset === value) return; input.value = value; input.dataset.keycapeOverlayPreset = value; // Fire once so Ember picks up the preset without a mutation feedback loop. input.dispatchEvent(new Event("input", { bubbles: true })); input.dispatchEvent(new Event("change", { bubbles: true })); } function ensureAuthMountSelected() { const mount = presets.mount || "netkingdom"; const withValue = mount.endsWith("/") ? mount : `${mount}/`; const params = new URLSearchParams(window.location.search); const current = params.get("with") || ""; if (current.replace(/\/$/, "") === withValue.replace(/\/$/, "")) { return; } if (!isAuthPage() || window.location.pathname.includes("/oidc/")) { return; } params.set("with", withValue); const next = `${window.location.pathname}?${params.toString()}`; if (next !== `${window.location.pathname}${window.location.search}`) { window.location.replace(next); } } function loginShellReady() { return Boolean( document.querySelector(".login-form") || document.querySelector(".auth-form") || document.querySelector(".toolbar-namespace-picker") ); } function applyDom() { if (!isAuthPage() || overlayApplied) return false; hideNode(document.querySelector(".toolbar-namespace-picker")); document .querySelectorAll( '#namespace, input[name="namespace"], label[for="namespace"]' ) .forEach(hideNode); document .querySelectorAll('select[name="auth-method"], #auth-method') .forEach((el) => hideNode(el.closest(".field") || el)); document .querySelectorAll('#custom-path, input[name="custom-path"]') .forEach(hideNode); document .querySelectorAll('#role, input[name="role"], label[for="role"]') .forEach(hideNode); document.querySelectorAll("nav.tabs").forEach((el) => { if (el.dataset.keycapeOverlayHidden === "true") return; el.style.display = "none"; el.setAttribute("aria-hidden", "true"); el.dataset.keycapeOverlayHidden = "true"; }); document .querySelectorAll(".auth-form .has-bottom-margin-s") .forEach(hideNode); document.querySelectorAll("h1.title.is-3").forEach((heading) => { if ( /Sign in to OpenBao|Authenticate/.test(heading.textContent) && heading.textContent !== presets.title ) { heading.textContent = presets.title; } }); document .querySelectorAll('#auth-submit, button[data-test="auth-submit"]') .forEach((button) => { if (button.textContent !== presets.signInLabel) { button.textContent = presets.signInLabel; } }); document .querySelectorAll('#namespace, input[name="namespace"]') .forEach((input) => setInputValue(input, presets.namespace || "")); document .querySelectorAll('#role, input[name="role"]') .forEach((input) => setInputValue(input, presets.role || "platform-admin") ); if (!document.getElementById("keycape-overlay-banner")) { const banner = document.createElement("div"); banner.id = "keycape-overlay-banner"; banner.className = "keycape-overlay-banner"; banner.textContent = presets.banner; const loginForm = document.querySelector(".login-form"); if (loginForm) { loginForm.prepend(banner); } } document.documentElement.classList.add("keycape-overlay-active"); if (loginShellReady()) { overlayApplied = true; return true; } return false; } function stopApplyLoop() { if (applyTimer !== null) { window.clearInterval(applyTimer); applyTimer = null; } } function scheduleApply() { stopApplyLoop(); applyAttempts = 0; const tick = () => { applyAttempts += 1; if (applyDom() || applyAttempts >= MAX_APPLY_ATTEMPTS) { stopApplyLoop(); return; } }; tick(); applyTimer = window.setInterval(tick, APPLY_INTERVAL_MS); } async function loadPresets() { try { const response = await fetch(PRESETS_URL, { cache: "no-store" }); if (!response.ok) return; const data = await response.json(); presets = { ...DEFAULT_PRESETS, ...data }; } catch (_error) { presets = { ...DEFAULT_PRESETS }; } } async function init() { await loadPresets(); if (!isAuthPage()) return; ensureAuthMountSelected(); if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", scheduleApply, { once: true, }); } else { scheduleApply(); } } init(); })();