import { showToast, toggleVisibility, attachEnterKeyListener } from './domUtils.js'; import { sendRequest } from './networkUtils.js'; import { t, applyTranslations, setLocale } from './i18n.js'; const version = "v1.0.9"; const adminTitle = `Admin Panel ${version}`; let lastLoginData = null; export function setLastLoginData(data) { lastLoginData = data; // expose to auth.js so it can tell form-login vs basic/oidc //window.__lastLoginData = data; } export 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 = `
`; document.body.appendChild(totpLoginModal); // Close button document.getElementById("closeTOTPLoginModal").addEventListener("click", () => { totpLoginModal.style.display = "none"; }); // Toggle between TOTP and Recovery document.getElementById("toggleRecovery").addEventListener("click", function (e) { e.preventDefault(); const totpSection = document.getElementById("totpSection"); const recoverySection = document.getElementById("recoverySection"); const toggleLink = this; if (recoverySection.style.display === "none") { // Switch to recovery totpSection.style.display = "none"; recoverySection.style.display = "block"; toggleLink.textContent = "Use TOTP Code instead"; } else { // Switch back to TOTP recoverySection.style.display = "none"; totpSection.style.display = "block"; toggleLink.textContent = "Use Recovery Code instead"; } }); // Recovery submission document.getElementById("submitRecovery").addEventListener("click", () => { const recoveryCode = document.getElementById("recoveryInput").value.trim(); if (!recoveryCode) { showToast("Please enter your recovery code."); return; } fetch("totp_recover.php", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-CSRF-Token": window.csrfToken }, body: JSON.stringify({ recovery_code: recoveryCode }) }) .then(res => res.json()) .then(json => { if (json.status === "ok") { // recovery succeeded → finalize login window.location.href = "index.html"; } else { showToast(json.message || "Recovery code verification failed"); } }) .catch(() => { showToast("Error verifying recovery code."); }); }); // TOTP submission const totpInput = document.getElementById("totpLoginInput"); totpInput.focus(); totpInput.addEventListener("input", function () { const code = this.value.trim(); if (code.length === 6) { fetch("totp_verify.php", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-CSRF-Token": window.csrfToken }, body: JSON.stringify({ totp_code: code }) }) .then(res => res.json()) .then(json => { if (json.status === "ok") { window.location.href = "index.html"; } else { showToast(json.message || "TOTP verification failed"); this.value = ""; totpLoginModal.style.display = "flex"; totpInput.focus(); } }) .catch(() => { showToast("TOTP verification failed"); this.value = ""; totpLoginModal.style.display = "flex"; totpInput.focus(); }); } }); } else { // Re-open existing modal totpLoginModal.style.display = "flex"; const totpInput = document.getElementById("totpLoginInput"); totpInput.value = ""; totpInput.style.display = "block"; totpInput.focus(); document.getElementById("recoverySection").style.display = "none"; } } export function openUserPanel() { const username = localStorage.getItem("username") || "User"; 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)"; 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; `; // Retrieve the language setting from local storage, default to English ("en") const savedLanguage = localStorage.getItem("language") || "en"; 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); // Close button handler document.getElementById("closeUserPanel").addEventListener("click", () => { userPanelModal.style.display = "none"; }); // Change Password button document.getElementById("openChangePasswordModalBtn").addEventListener("click", () => { document.getElementById("changePasswordModal").style.display = "block"; }); // TOTP checkbox behavior const totpCheckbox = document.getElementById("userTOTPEnabled"); totpCheckbox.checked = localStorage.getItem("userTOTPEnabled") === "true"; totpCheckbox.addEventListener("change", function () { 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) { openTOTPModal(); } }) .catch(() => { showToast("Error updating TOTP setting."); }); }); // Language dropdown initialization const languageSelector = document.getElementById("languageSelector"); languageSelector.value = savedLanguage; languageSelector.addEventListener("change", function () { const selectedLanguage = this.value; localStorage.setItem("language", selectedLanguage); setLocale(selectedLanguage); applyTranslations(); }); } else { // If the modal already exists, update its colors 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"; } function showRecoveryCodeModal(recoveryCode) { const recoveryModal = document.createElement("div"); recoveryModal.id = "recoveryModal"; recoveryModal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: rgba(0,0,0,0.3); display: flex; justify-content: center; align-items: center; z-index: 3200; `; recoveryModal.innerHTML = `Please save this code securely. It will not be shown again and can only be used once.
${recoveryCode}
No users found.
"; return; } users.forEach(user => { // Skip admin users. if ((user.role && user.role === "1") || user.username.toLowerCase() === "admin") return; // Use stored permissions if available; otherwise fall back to localStorage defaults. const defaultPerm = { folderOnly: localStorage.getItem("folderOnly") === "true", readOnly: localStorage.getItem("readOnly") === "true", disableUpload: localStorage.getItem("disableUpload") === "true" }; const userPerm = (permissionsData && typeof permissionsData === "object" && permissionsData[user.username]) || defaultPerm; // Create a row for the user. const row = document.createElement("div"); row.classList.add("user-permission-row"); row.setAttribute("data-username", user.username); row.style.padding = "10px 0"; row.innerHTML = `Error loading users.
"; }); }