import { sendRequest } from './networkUtils.js'; import { toggleVisibility, showToast, attachEnterKeyListener, showCustomConfirmModal } from './domUtils.js'; import { loadFileList, renderFileTable, displayFilePreview, initFileActions } from './fileManager.js'; import { loadFolderTree } from './folderManager.js'; // Default OIDC configuration (can be overridden via API in production) const currentOIDCConfig = { providerUrl: "https://your-oidc-provider.com", clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", redirectUri: "https://yourdomain.com/auth.php?oidc=callback", // Global OTPAuth URL; default applied if not set. globalOtpauthUrl: "" }; /* ----------------- Utility Functions ----------------- */ function updateItemsPerPageSelect() { const selectElem = document.querySelector(".form-control.bottom-select"); if (selectElem) { selectElem.value = localStorage.getItem("itemsPerPage") || "10"; } } function updateLoginOptionsUI({ disableFormLogin, disableBasicAuth, disableOIDCLogin }) { const authForm = document.getElementById("authForm"); if (authForm) authForm.style.display = disableFormLogin ? "none" : "block"; const basicAuthLink = document.querySelector("a[href='login_basic.php']"); if (basicAuthLink) basicAuthLink.style.display = disableBasicAuth ? "none" : "inline-block"; const oidcLoginBtn = document.getElementById("oidcLoginBtn"); if (oidcLoginBtn) oidcLoginBtn.style.display = disableOIDCLogin ? "none" : "inline-block"; } function updateLoginOptionsUIFromStorage() { updateLoginOptionsUI({ disableFormLogin: localStorage.getItem("disableFormLogin") === "true", disableBasicAuth: localStorage.getItem("disableBasicAuth") === "true", disableOIDCLogin: localStorage.getItem("disableOIDCLogin") === "true" }); } function loadAdminConfigFunc() { return fetch("getConfig.php", { credentials: "include" }) .then(response => response.json()) .then(config => { localStorage.setItem("disableFormLogin", config.loginOptions.disableFormLogin); localStorage.setItem("disableBasicAuth", config.loginOptions.disableBasicAuth); localStorage.setItem("disableOIDCLogin", config.loginOptions.disableOIDCLogin); localStorage.setItem("globalOtpauthUrl", config.globalOtpauthUrl || "otpauth://totp/FileRise?issuer=FileRise"); updateLoginOptionsUIFromStorage(); }) .catch(() => { localStorage.setItem("disableFormLogin", "false"); localStorage.setItem("disableBasicAuth", "false"); localStorage.setItem("disableOIDCLogin", "false"); localStorage.setItem("globalOtpauthUrl", "otpauth://totp/FileRise?issuer=FileRise"); updateLoginOptionsUIFromStorage(); }); } function insertAfter(newNode, referenceNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } function updateAuthenticatedUI(data) { toggleVisibility("loginForm", false); toggleVisibility("mainOperations", true); toggleVisibility("uploadFileForm", true); toggleVisibility("fileListContainer", true); attachEnterKeyListener("addUserModal", "saveUserBtn"); attachEnterKeyListener("removeUserModal", "deleteUserBtn"); attachEnterKeyListener("changePasswordModal", "saveNewPasswordBtn"); document.querySelector(".header-buttons").style.visibility = "visible"; // Update TOTP state from the server response. if (typeof data.totp_enabled !== "undefined") { localStorage.setItem("userTOTPEnabled", data.totp_enabled ? "true" : "false"); } const headerButtons = document.querySelector(".header-buttons"); const firstButton = headerButtons.firstElementChild; // first button in container // Admin controls: restore and admin panel buttons are shown only for admins. if (data.isAdmin) { // Create restore button. let restoreBtn = document.getElementById("restoreFilesBtn"); if (!restoreBtn) { restoreBtn = document.createElement("button"); restoreBtn.id = "restoreFilesBtn"; restoreBtn.classList.add("btn", "btn-warning"); restoreBtn.innerHTML = 'restore_from_trash'; // Insert restoreBtn right after the first button. if (firstButton) { insertAfter(restoreBtn, firstButton); } else { headerButtons.appendChild(restoreBtn); } } restoreBtn.style.display = "block"; // Create admin panel button. let adminPanelBtn = document.getElementById("adminPanelBtn"); if (!adminPanelBtn) { adminPanelBtn = document.createElement("button"); adminPanelBtn.id = "adminPanelBtn"; adminPanelBtn.classList.add("btn", "btn-info"); adminPanelBtn.innerHTML = 'admin_panel_settings'; // Insert adminPanelBtn right after the restore button. insertAfter(adminPanelBtn, restoreBtn); adminPanelBtn.addEventListener("click", openAdminPanel); } else { adminPanelBtn.style.display = "block"; } } else { const restoreBtn = document.getElementById("restoreFilesBtn"); if (restoreBtn) restoreBtn.style.display = "none"; const adminPanelBtn = document.getElementById("adminPanelBtn"); if (adminPanelBtn) adminPanelBtn.style.display = "none"; } // User panel button: Always visible for authenticated users. let userPanelBtn = document.getElementById("userPanelBtn"); if (!userPanelBtn) { userPanelBtn = document.createElement("button"); userPanelBtn.id = "userPanelBtn"; userPanelBtn.classList.add("btn", "btn-user"); userPanelBtn.innerHTML = 'account_circle'; // Try to insert the user panel button right after the admin panel button if it exists. let adminPanelBtn = document.getElementById("adminPanelBtn"); if (adminPanelBtn) { insertAfter(userPanelBtn, adminPanelBtn); } else { // If no admin panel button exists, insert right after the first button in headerButtons. const firstButton = headerButtons.firstElementChild; if (firstButton) { insertAfter(userPanelBtn, firstButton); } else { headerButtons.appendChild(userPanelBtn); } } userPanelBtn.addEventListener("click", openUserPanel); } else { userPanelBtn.style.display = "block"; } updateItemsPerPageSelect(); updateLoginOptionsUIFromStorage(); } function checkAuthentication(showLoginToast = true) { return sendRequest("checkAuth.php") .then(data => { if (data.setup) { window.setupMode = true; if (showLoginToast) showToast("Setup mode: No users found. Please add an admin user."); toggleVisibility("loginForm", false); toggleVisibility("mainOperations", false); document.querySelector(".header-buttons").style.visibility = "hidden"; toggleVisibility("addUserModal", true); document.getElementById("newUsername").focus(); return false; } window.setupMode = false; if (data.authenticated) { // Update localStorage for TOTP state if provided by the server. if (typeof data.totp_enabled !== "undefined") { localStorage.setItem("userTOTPEnabled", data.totp_enabled ? "true" : "false"); } updateAuthenticatedUI(data); return data; } else { if (showLoginToast) showToast("Please log in to continue."); toggleVisibility("loginForm", true); toggleVisibility("mainOperations", false); toggleVisibility("uploadFileForm", false); toggleVisibility("fileListContainer", false); document.querySelector(".header-buttons").style.visibility = "hidden"; return false; } }) .catch(() => false); } /* ----------------- TOTP Login Modal ----------------- */ let lastLoginData = null; // For auto-submission function submitLogin(data) { lastLoginData = data; sendRequest("auth.php", "POST", data, { "X-CSRF-Token": window.csrfToken }) .then(response => { if (response.success) { sessionStorage.setItem("welcomeMessage", "Welcome back, " + data.username + "!"); window.location.reload(); } else if (response.totp_required) { openTOTPLoginModal(); } else if (response.error && response.error.includes("Too many failed login attempts")) { showToast(response.error); const loginButton = document.getElementById("authForm").querySelector("button[type='submit']"); if (loginButton) { loginButton.disabled = true; setTimeout(() => { loginButton.disabled = false; showToast("You can now try logging in again."); }, 30 * 60 * 1000); } } else { showToast("Login failed: " + (response.error || "Unknown error")); } }) .catch(() => { showToast("Login failed: Unknown error"); }); } function openTOTPLoginModal() { let totpLoginModal = document.getElementById("totpLoginModal"); const isDarkMode = document.body.classList.contains("dark-mode"); const modalBg = isDarkMode ? "#2c2c2c" : "#fff"; const textColor = isDarkMode ? "#e0e0e0" : "#000"; if (!totpLoginModal) { totpLoginModal = document.createElement("div"); totpLoginModal.id = "totpLoginModal"; totpLoginModal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: rgba(0,0,0,0.5); display: flex; justify-content: center; align-items: center; z-index: 3200; `; totpLoginModal.innerHTML = `
×

Enter TOTP Code

`; document.body.appendChild(totpLoginModal); document.getElementById("closeTOTPLoginModal").addEventListener("click", () => { totpLoginModal.style.display = "none"; }); const totpInput = document.getElementById("totpLoginInput"); document.getElementById("totpLoginInput").focus(); totpInput.addEventListener("input", function () { if (this.value.trim().length === 6 && lastLoginData) { lastLoginData.totp_code = this.value.trim(); totpLoginModal.style.display = "none"; submitLogin(lastLoginData); } }); } else { totpLoginModal.style.display = "flex"; // Update colors in case dark mode changed. const modalContent = totpLoginModal.firstElementChild; modalContent.style.background = modalBg; modalContent.style.color = textColor; } } /* ----------------- User Panel Modal ----------------- */ function openUserPanel() { let userPanelModal = document.getElementById("userPanelModal"); const isDarkMode = document.body.classList.contains("dark-mode"); const overlayBackground = isDarkMode ? "rgba(0,0,0,0.7)" : "rgba(0,0,0,0.3)"; // Added transform and transition none to prevent scaling on click. const modalContentStyles = ` background: ${isDarkMode ? "#2c2c2c" : "#fff"}; color: ${isDarkMode ? "#e0e0e0" : "#000"}; padding: 20px; max-width: 600px; width: 90%; border-radius: 8px; position: relative; overflow-y: auto; max-height: 90vh; border: ${isDarkMode ? "1px solid #444" : "1px solid #ccc"}; transform: none; transition: none; `; if (!userPanelModal) { userPanelModal = document.createElement("div"); userPanelModal.id = "userPanelModal"; userPanelModal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: ${overlayBackground}; display: flex; justify-content: center; align-items: center; z-index: 3000; `; userPanelModal.innerHTML = ` `; document.body.appendChild(userPanelModal); document.getElementById("closeUserPanel").addEventListener("click", () => { userPanelModal.style.display = "none"; }); // Bind the "Change Password" button to open the changePasswordModal. document.getElementById("openChangePasswordModalBtn").addEventListener("click", () => { document.getElementById("changePasswordModal").style.display = "block"; }); // Initialize TOTP checkbox state and TOTP configuration button. const totpCheckbox = document.getElementById("userTOTPEnabled"); // Initialize checkbox based on stored setting. totpCheckbox.checked = localStorage.getItem("userTOTPEnabled") === "true"; totpCheckbox.addEventListener("change", function () { // Save the new state. localStorage.setItem("userTOTPEnabled", this.checked ? "true" : "false"); const enabled = this.checked; fetch("updateUserPanel.php", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-CSRF-Token": window.csrfToken }, body: JSON.stringify({ totp_enabled: enabled }) }) .then(r => r.json()) .then(result => { if (!result.success) { showToast("Error updating TOTP setting: " + result.error); } else if (enabled) { // Automatically open the TOTP modal when TOTP is enabled. openTOTPModal(); } }) .catch(() => { showToast("Error updating TOTP setting."); }); }); } else { // Update colors in case dark mode changed. userPanelModal.style.backgroundColor = overlayBackground; const modalContent = userPanelModal.querySelector(".modal-content"); modalContent.style.background = isDarkMode ? "#2c2c2c" : "#fff"; modalContent.style.color = isDarkMode ? "#e0e0e0" : "#000"; modalContent.style.border = isDarkMode ? "1px solid #444" : "1px solid #ccc"; } userPanelModal.style.display = "flex"; } /* ----------------- TOTP Setup Modal ----------------- */ function openTOTPModal() { let totpModal = document.getElementById("totpModal"); const isDarkMode = document.body.classList.contains("dark-mode"); const overlayBackground = isDarkMode ? "rgba(0,0,0,0.7)" : "rgba(0,0,0,0.3)"; const modalContentStyles = ` background: ${isDarkMode ? "#2c2c2c" : "#fff"}; color: ${isDarkMode ? "#e0e0e0" : "#000"}; padding: 20px; max-width: 400px; width: 90%; border-radius: 8px; position: relative; `; if (!totpModal) { totpModal = document.createElement("div"); totpModal.id = "totpModal"; totpModal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: ${overlayBackground}; display: flex; justify-content: center; align-items: center; z-index: 3100; `; totpModal.innerHTML = ` `; document.body.appendChild(totpModal); document.getElementById("closeTOTPModal").addEventListener("click", closeTOTPModal); const totpInput = document.getElementById("totpSetupInput"); totpInput.addEventListener("input", function () { if (this.value.trim().length === 6 && lastLoginData) { lastLoginData.totp_code = this.value.trim(); totpModal.style.display = "none"; submitLogin(lastLoginData); } }); } else { totpModal.style.display = "flex"; totpModal.style.backgroundColor = overlayBackground; const modalContent = totpModal.querySelector(".modal-content"); modalContent.style.background = isDarkMode ? "#2c2c2c" : "#fff"; modalContent.style.color = isDarkMode ? "#e0e0e0" : "#000"; } } function closeTOTPModal() { const totpModal = document.getElementById("totpModal"); if (totpModal) totpModal.style.display = "none"; } function openAdminPanel() { fetch("getConfig.php", { credentials: "include" }) .then(response => response.json()) .then(config => { if (config.oidc) Object.assign(currentOIDCConfig, config.oidc); if (config.globalOtpauthUrl) currentOIDCConfig.globalOtpauthUrl = config.globalOtpauthUrl; const isDarkMode = document.body.classList.contains("dark-mode"); const overlayBackground = isDarkMode ? "rgba(0,0,0,0.7)" : "rgba(0,0,0,0.3)"; const modalContentStyles = ` background: ${isDarkMode ? "#2c2c2c" : "#fff"}; color: ${isDarkMode ? "#e0e0e0" : "#000"}; padding: 20px; max-width: 600px; width: 90%; border-radius: 8px; position: relative; overflow-y: auto; max-height: 90vh; border: ${isDarkMode ? "1px solid #444" : "1px solid #ccc"}; `; let adminModal = document.getElementById("adminPanelModal"); if (!adminModal) { adminModal = document.createElement("div"); adminModal.id = "adminPanelModal"; adminModal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: ${overlayBackground}; display: flex; justify-content: center; align-items: center; z-index: 3000; `; adminModal.innerHTML = ` `; document.body.appendChild(adminModal); document.getElementById("closeAdminPanel").addEventListener("click", closeAdminPanel); adminModal.addEventListener("click", (e) => { if (e.target === adminModal) closeAdminPanel(); }); document.getElementById("cancelAdminSettings").addEventListener("click", closeAdminPanel); document.getElementById("adminOpenAddUser").addEventListener("click", () => { toggleVisibility("addUserModal", true); document.getElementById("newUsername").focus(); }); document.getElementById("adminOpenRemoveUser").addEventListener("click", () => { loadUserList(); toggleVisibility("removeUserModal", true); }); document.getElementById("saveAdminSettings").addEventListener("click", () => { const disableFormLoginCheckbox = document.getElementById("disableFormLogin"); const disableBasicAuthCheckbox = document.getElementById("disableBasicAuth"); const disableOIDCLoginCheckbox = document.getElementById("disableOIDCLogin"); const totalDisabled = [disableFormLoginCheckbox, disableBasicAuthCheckbox, disableOIDCLoginCheckbox].filter(cb => cb.checked).length; if (totalDisabled === 3) { showToast("At least one login method must remain enabled."); disableOIDCLoginCheckbox.checked = false; localStorage.setItem("disableOIDCLogin", "false"); updateLoginOptionsUI({ disableFormLogin: disableFormLoginCheckbox.checked, disableBasicAuth: disableBasicAuthCheckbox.checked, disableOIDCLogin: disableOIDCLoginCheckbox.checked }); return; } const newOIDCConfig = { providerUrl: document.getElementById("oidcProviderUrl").value.trim(), clientId: document.getElementById("oidcClientId").value.trim(), clientSecret: document.getElementById("oidcClientSecret").value.trim(), redirectUri: document.getElementById("oidcRedirectUri").value.trim() }; const disableFormLogin = disableFormLoginCheckbox.checked; const disableBasicAuth = disableBasicAuthCheckbox.checked; const disableOIDCLogin = disableOIDCLoginCheckbox.checked; const globalOtpauthUrl = document.getElementById("globalOtpauthUrl").value.trim(); sendRequest("updateConfig.php", "POST", { oidc: newOIDCConfig, disableFormLogin, disableBasicAuth, disableOIDCLogin, globalOtpauthUrl }, { "X-CSRF-Token": window.csrfToken }) .then(response => { if (response.success) { showToast("Settings updated successfully."); localStorage.setItem("disableFormLogin", disableFormLogin); localStorage.setItem("disableBasicAuth", disableBasicAuth); localStorage.setItem("disableOIDCLogin", disableOIDCLogin); updateLoginOptionsUI({ disableFormLogin, disableBasicAuth, disableOIDCLogin }); closeAdminPanel(); } else { showToast("Error updating settings: " + (response.error || "Unknown error")); } }) .catch(() => { }); }); // Enforce that at least one login method remains enabled. const disableFormLoginCheckbox = document.getElementById("disableFormLogin"); const disableBasicAuthCheckbox = document.getElementById("disableBasicAuth"); const disableOIDCLoginCheckbox = document.getElementById("disableOIDCLogin"); function enforceLoginOptionConstraint(changedCheckbox) { const totalDisabled = [disableFormLoginCheckbox, disableBasicAuthCheckbox, disableOIDCLoginCheckbox].filter(cb => cb.checked).length; if (changedCheckbox.checked && totalDisabled === 3) { showToast("At least one login method must remain enabled."); changedCheckbox.checked = false; } } disableFormLoginCheckbox.addEventListener("change", function () { enforceLoginOptionConstraint(this); }); disableBasicAuthCheckbox.addEventListener("change", function () { enforceLoginOptionConstraint(this); }); disableOIDCLoginCheckbox.addEventListener("change", function () { enforceLoginOptionConstraint(this); }); // UPDATE checkboxes using fetched configuration: document.getElementById("disableFormLogin").checked = config.loginOptions.disableFormLogin === true; document.getElementById("disableBasicAuth").checked = config.loginOptions.disableBasicAuth === true; document.getElementById("disableOIDCLogin").checked = config.loginOptions.disableOIDCLogin === true; } else { // If the modal already exists, update its styles and values. adminModal.style.backgroundColor = overlayBackground; const modalContent = adminModal.querySelector(".modal-content"); if (modalContent) { modalContent.style.background = isDarkMode ? "#2c2c2c" : "#fff"; modalContent.style.color = isDarkMode ? "#e0e0e0" : "#000"; modalContent.style.border = isDarkMode ? "1px solid #444" : "1px solid #ccc"; } document.getElementById("oidcProviderUrl").value = currentOIDCConfig.providerUrl; document.getElementById("oidcClientId").value = currentOIDCConfig.clientId; document.getElementById("oidcClientSecret").value = currentOIDCConfig.clientSecret; document.getElementById("oidcRedirectUri").value = currentOIDCConfig.redirectUri; document.getElementById("globalOtpauthUrl").value = currentOIDCConfig.globalOtpauthUrl || 'otpauth://totp/FileRise?issuer=FileRise'; // UPDATE checkboxes using fetched configuration: document.getElementById("disableFormLogin").checked = config.loginOptions.disableFormLogin === true; document.getElementById("disableBasicAuth").checked = config.loginOptions.disableBasicAuth === true; document.getElementById("disableOIDCLogin").checked = config.loginOptions.disableOIDCLogin === true; adminModal.style.display = "flex"; } }) .catch(() => { // In case of error, fallback to localStorage values let adminModal = document.getElementById("adminPanelModal"); if (adminModal) { adminModal.style.backgroundColor = "rgba(0,0,0,0.5)"; const modalContent = adminModal.querySelector(".modal-content"); if (modalContent) { modalContent.style.background = "#fff"; modalContent.style.color = "#000"; modalContent.style.border = "1px solid #ccc"; } document.getElementById("oidcProviderUrl").value = currentOIDCConfig.providerUrl; document.getElementById("oidcClientId").value = currentOIDCConfig.clientId; document.getElementById("oidcClientSecret").value = currentOIDCConfig.clientSecret; document.getElementById("oidcRedirectUri").value = currentOIDCConfig.redirectUri; document.getElementById("globalOtpauthUrl").value = currentOIDCConfig.globalOtpauthUrl || 'otpauth://totp/FileRise?issuer=FileRise'; document.getElementById("disableFormLogin").checked = localStorage.getItem("disableFormLogin") === "true"; document.getElementById("disableBasicAuth").checked = localStorage.getItem("disableBasicAuth") === "true"; document.getElementById("disableOIDCLogin").checked = localStorage.getItem("disableOIDCLogin") === "true"; adminModal.style.display = "flex"; } else { openAdminPanel(); } }); } function closeAdminPanel() { const adminModal = document.getElementById("adminPanelModal"); if (adminModal) adminModal.style.display = "none"; } /* ----------------- Other Helpers ----------------- */ window.changeItemsPerPage = function (value) { localStorage.setItem("itemsPerPage", value); if (typeof renderFileTable === "function") renderFileTable(window.currentFolder || "root"); }; function resetUserForm() { document.getElementById("newUsername").value = ""; document.getElementById("addUserPassword").value = ""; } function closeAddUserModal() { toggleVisibility("addUserModal", false); resetUserForm(); } function closeRemoveUserModal() { toggleVisibility("removeUserModal", false); document.getElementById("removeUsernameSelect").innerHTML = ""; } function loadUserList() { fetch("getUsers.php", { credentials: "include" }) .then(response => response.json()) .then(data => { const users = Array.isArray(data) ? data : (data.users || []); const selectElem = document.getElementById("removeUsernameSelect"); selectElem.innerHTML = ""; users.forEach(user => { const option = document.createElement("option"); option.value = user.username; option.textContent = user.username; selectElem.appendChild(option); }); if (selectElem.options.length === 0) { showToast("No other users found to remove."); closeRemoveUserModal(); } }) .catch(() => { }); } /* ----------------- Initialization ----------------- */ function initAuth() { checkAuthentication(false); loadAdminConfigFunc(); const authForm = document.getElementById("authForm"); if (authForm) { authForm.addEventListener("submit", function (event) { event.preventDefault(); const rememberMe = document.getElementById("rememberMeCheckbox") ? document.getElementById("rememberMeCheckbox").checked : false; const formData = { username: document.getElementById("loginUsername").value.trim(), password: document.getElementById("loginPassword").value.trim(), remember_me: rememberMe }; submitLogin(formData); }); } document.getElementById("logoutBtn").addEventListener("click", function () { fetch("logout.php", { method: "POST", credentials: "include", headers: { "X-CSRF-Token": window.csrfToken } }).then(() => window.location.reload(true)).catch(() => { }); }); const oidcLoginBtn = document.getElementById("oidcLoginBtn"); if (oidcLoginBtn) { oidcLoginBtn.addEventListener("click", function () { window.location.href = "auth.php?oidc"; }); } document.getElementById("addUserBtn").addEventListener("click", function () { resetUserForm(); toggleVisibility("addUserModal", true); document.getElementById("newUsername").focus(); }); document.getElementById("saveUserBtn").addEventListener("click", function () { const newUsername = document.getElementById("newUsername").value.trim(); const newPassword = document.getElementById("addUserPassword").value.trim(); const isAdmin = document.getElementById("isAdmin").checked; if (!newUsername || !newPassword) { showToast("Username and password are required!"); return; } let url = "addUser.php"; if (window.setupMode) url += "?setup=1"; fetch(url, { method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-CSRF-Token": window.csrfToken }, body: JSON.stringify({ username: newUsername, password: newPassword, isAdmin }) }) .then(response => response.json()) .then(data => { if (data.success) { showToast("User added successfully!"); closeAddUserModal(); checkAuthentication(false); } else { showToast("Error: " + (data.error || "Could not add user")); } }) .catch(() => { }); }); document.getElementById("cancelUserBtn").addEventListener("click", closeAddUserModal); document.getElementById("removeUserBtn").addEventListener("click", function () { loadUserList(); toggleVisibility("removeUserModal", true); }); document.getElementById("deleteUserBtn").addEventListener("click", async function () { const selectElem = document.getElementById("removeUsernameSelect"); const usernameToRemove = selectElem.value; if (!usernameToRemove) { showToast("Please select a user to remove."); return; } const confirmed = await showCustomConfirmModal("Are you sure you want to delete user " + usernameToRemove + "?"); if (!confirmed) return; fetch("removeUser.php", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-CSRF-Token": window.csrfToken }, body: JSON.stringify({ username: usernameToRemove }) }) .then(response => response.json()) .then(data => { if (data.success) { showToast("User removed successfully!"); closeRemoveUserModal(); loadUserList(); } else { showToast("Error: " + (data.error || "Could not remove user")); } }) .catch(() => { }); }); document.getElementById("cancelRemoveUserBtn").addEventListener("click", closeRemoveUserModal); // Change password bindings. document.getElementById("changePasswordBtn").addEventListener("click", function () { document.getElementById("changePasswordModal").style.display = "block"; document.getElementById("oldPassword").focus(); }); document.getElementById("closeChangePasswordModal").addEventListener("click", function () { document.getElementById("changePasswordModal").style.display = "none"; }); document.getElementById("saveNewPasswordBtn").addEventListener("click", function () { const oldPassword = document.getElementById("oldPassword").value.trim(); const newPassword = document.getElementById("newPassword").value.trim(); const confirmPassword = document.getElementById("confirmPassword").value.trim(); if (!oldPassword || !newPassword || !confirmPassword) { showToast("Please fill in all fields."); return; } if (newPassword !== confirmPassword) { showToast("New passwords do not match."); return; } const data = { oldPassword, newPassword, confirmPassword }; fetch("changePassword.php", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-CSRF-Token": window.csrfToken }, body: JSON.stringify(data) }) .then(response => response.json()) .then(result => { if (result.success) { showToast(result.success); document.getElementById("oldPassword").value = ""; document.getElementById("newPassword").value = ""; document.getElementById("confirmPassword").value = ""; document.getElementById("changePasswordModal").style.display = "none"; } else { showToast("Error: " + (result.error || "Could not change password.")); } }) .catch(() => { showToast("Error changing password."); }); }); } document.addEventListener("DOMContentLoaded", function () { updateItemsPerPageSelect(); updateLoginOptionsUI({ disableFormLogin: localStorage.getItem("disableFormLogin") === "true", disableBasicAuth: localStorage.getItem("disableBasicAuth") === "true", disableOIDCLogin: localStorage.getItem("disableOIDCLogin") === "true" }); }); export { initAuth, checkAuthentication };