// Map config keys to input IDs const CONFIG_FIELDS = { "TORN_API_KEY": "torn-api-key", "FFSCOUTER_KEY": "ffscouter-key", "DISCORD_TOKEN": "discord-token", "ALLOWED_CHANNEL_ID": "allowed-channel-id", "HIT_CHECK_INTERVAL": "hit-check-interval", "REASSIGN_DELAY": "reassign-delay", "ASSIGNMENT_TIMEOUT": "assignment-timeout", "ASSIGNMENT_REMINDER": "assignment-reminder", "CHAIN_TIMER_THRESHOLD": "chain-timer-threshold", "AUTH_PASSWORD": "auth-password", "JWT_SECRET": "jwt-secret" }; let sensitiveFields = []; async function loadConfig() { try { const res = await fetch("/api/config", { cache: "no-store" }); if (!res.ok) { console.error("Failed to load config:", res.status); return; } const data = await res.json(); sensitiveFields = data.sensitive_fields || []; // Populate form fields for (const [key, inputId] of Object.entries(CONFIG_FIELDS)) { const input = document.getElementById(inputId); if (input && data.config[key] !== undefined) { input.value = data.config[key]; // Add placeholder for masked sensitive fields if (sensitiveFields.includes(key) && String(data.config[key]).startsWith("****")) { input.placeholder = "Current: " + data.config[key]; input.value = ""; // Clear the masked value } } } } catch (err) { console.error("Error loading config:", err); } } async function saveConfigValue(key) { console.log("saveConfigValue called with key:", key); const inputId = CONFIG_FIELDS[key]; console.log("Input ID:", inputId); const input = document.getElementById(inputId); console.log("Input element:", input); if (!input) { console.error("Input not found:", inputId); return; } let value = input.value.trim(); console.log("Value to save:", value); // Don't save if sensitive field is empty (means user didn't change it) if (sensitiveFields.includes(key) && value === "") { console.log("No changes to save - field is empty"); alert("No changes to save"); return; } console.log("Proceeding with save..."); // Convert to number if needed if (input.type === "number") { value = parseInt(value); if (isNaN(value)) { alert("Invalid number"); return; } } try { console.log("Sending API request to /api/config with:", { key, value }); const res = await fetch("/api/config", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key, value }) }); console.log("API response status:", res.status); if (!res.ok) { console.error("Save failed:", res.status); alert("Failed to save config"); return; } const data = await res.json(); console.log("Config saved:", data); // Reload to show masked value await loadConfig(); alert("Saved successfully"); } catch (err) { console.error("Error saving config:", err); alert("Error saving config"); } } function wireUp() { console.log("wireUp called"); // Attach save handlers to all save buttons const saveButtons = document.querySelectorAll(".config-save-btn"); console.log("Found save buttons:", saveButtons.length); saveButtons.forEach(btn => { const key = btn.dataset.key; console.log("Attaching handler for key:", key); btn.addEventListener("click", () => saveConfigValue(key)); }); // Attach logout handler const logoutBtn = document.getElementById("logout-btn"); if (logoutBtn) logoutBtn.addEventListener("click", handleLogout); } async function handleLogout() { console.log("handleLogout called"); try { console.log("Sending logout request to /auth/logout"); const response = await fetch("/auth/logout", { method: "POST" }); console.log("Logout response status:", response.status); if (response.ok) { console.log("Logout successful, redirecting to /login"); window.location.href = "/login"; } else { console.error("Logout failed with status:", response.status); window.location.href = "/login"; } } catch (error) { console.error("Error during logout:", error); window.location.href = "/login"; } } document.addEventListener("DOMContentLoaded", async () => { wireUp(); await loadConfig(); });