const API = "https://baim-security-api.baimstore0908.workers.dev"; const MAX_SIZE = 2 * 1024 * 1024; const $ = id => document.getElementById(id); const codeInput = $("scriptCode"); const fileInput = $("luaFile"); const feedback = $("feedback"); const loginFeedback = $("loginFeedback"); let adminToken = sessionStorage.getItem("baim_admin_token"); async function apiRequest(path, options = {}) { const headers = { "Content-Type": "application/json", ...(options.headers || {}) }; if (adminToken) { headers.Authorization = "Bearer " + adminToken; } const response = await fetch(API + path, { ...options, headers }); const data = await response.json(); if (!response.ok) { throw new Error(data.message || "Permintaan gagal."); } return data; } // Cek koneksi server async function checkConnection() { const status = $("serverStatus"); try { const response = await fetch(API + "/api/health"); const data = await response.json(); if (!response.ok || !data.success) { throw new Error("Server tidak tersedia"); } status.textContent = "TERHUBUNG"; status.className = "status-on"; } catch { status.textContent = "TERPUTUS"; status.className = "status-off"; } } // Buka form login $("adminLoginButton").addEventListener("click", () => { $("loginPanel").hidden = false; $("publicPanel").hidden = true; }); // Kembali ke halaman utama $("closeLoginButton").addEventListener("click", () => { $("loginPanel").hidden = true; $("publicPanel").hidden = false; loginFeedback.textContent = ""; }); // Tampilkan admin function showAdmin() { $("publicPanel").hidden = true; $("loginPanel").hidden = true; $("adminArea").hidden = false; loadScripts(); } // Tampilkan halaman awal function showLogin() { $("publicPanel").hidden = false; $("loginPanel").hidden = true; $("adminArea").hidden = true; $("adminCode").value = ""; } // Login admin $("loginForm").addEventListener("submit", async event => { event.preventDefault(); const code = $("adminCode").value.trim(); if (!code) return; loginFeedback.textContent = "Memeriksa kode admin..."; try { const data = await apiRequest("/api/admin/login", { method: "POST", body: JSON.stringify({ code }) }); adminToken = data.token; sessionStorage.setItem( "baim_admin_token", adminToken ); loginFeedback.textContent = "Login berhasil."; showAdmin(); } catch (error) { loginFeedback.textContent = error.message; } }); // Logout $("logoutButton").addEventListener("click", () => { adminToken = null; sessionStorage.removeItem("baim_admin_token"); showLogin(); }); // Upload file Lua fileInput.addEventListener("change", async function () { const file = this.files[0]; if (!file) return; if (!file.name.toLowerCase().endsWith(".lua")) { feedback.textContent = "File harus berformat .lua"; this.value = ""; return; } if (file.size > MAX_SIZE) { feedback.textContent = "Ukuran file maksimal 2 MB."; this.value = ""; return; } codeInput.value = await file.text(); const match = codeInput.value.match( /script_name\s*\(\s*["']([^"']+)["']\s*\)/ ); if (match && !$("scriptName").value.trim()) { $("scriptName").value = match[1]; } feedback.textContent = "File Lua berhasil dimuat."; }); // Daftarkan script $("processButton").addEventListener("click", async () => { const name = $("scriptName").value.trim(); const code = codeInput.value; const size = new Blob([code]).size; if (!name) { feedback.textContent = "Nama script wajib diisi."; return; } if (!code.trim()) { feedback.textContent = "Masukkan kode Lua terlebih dahulu."; return; } if (size > MAX_SIZE) { feedback.textContent = "Kode melebihi batas 2 MB."; return; } $("processButton").disabled = true; feedback.textContent = "Mendaftarkan script..."; try { const data = await apiRequest("/api/admin/scripts", { method: "POST", body: JSON.stringify({ script_name: name }) }); feedback.textContent = "SCRIPT BERHASIL DIDAFTARKAN. ID: " + data.script_id + ". Integrasi Lua belum dipasang."; $("scriptName").value = ""; codeInput.value = ""; fileInput.value = ""; await loadScripts(); } catch (error) { feedback.textContent = "Gagal: " + error.message; } finally { $("processButton").disabled = false; } }); // Tampilkan daftar script async function loadScripts() { const list = $("scriptList"); list.textContent = "Memuat data script..."; try { const data = await apiRequest("/api/admin/scripts"); $("totalScripts").textContent = data.total; list.replaceChildren(); if (!data.scripts.length) { list.textContent = "Belum ada script terdaftar."; return; } data.scripts.forEach(script => { const card = document.createElement("div"); card.className = "script-card"; const title = document.createElement("h4"); title.textContent = script.script_name; const id = document.createElement("p"); id.className = "script-id"; id.textContent = "SCRIPT_ID: " + script.script_id; const status = document.createElement("p"); status.textContent = script.revoked_at ? "STATUS: REVOKED" : "STATUS: " + script.status; status.className = script.status === "ON" ? "status-on" : "status-off"; if (script.revoked_at) { status.className = "status-off"; } const date = document.createElement("p"); date.className = "script-id"; date.textContent = "Dibuat: " + script.created_at; card.append(title, id, status, date); if (!script.revoked_at) { const actions = document.createElement("div"); actions.className = "action-row"; const toggle = document.createElement("button"); toggle.textContent = script.status === "ON" ? "MATIKAN (OFF)" : "AKTIFKAN (ON)"; toggle.addEventListener("click", () => { changeStatus( script.script_id, script.status === "ON" ? "OFF" : "ON" ); }); const revoke = document.createElement("button"); revoke.textContent = "CABUT PERMANEN"; revoke.className = "danger"; revoke.addEventListener("click", () => { revokeScript(script.script_id); }); actions.append(toggle, revoke); card.append(actions); } list.append(card); }); } catch (error) { list.textContent = error.message; if (error.message.includes("Akses admin") || error.message.includes("sesi berakhir")) { adminToken = null; sessionStorage.removeItem("baim_admin_token"); showLogin(); } } } // Ubah ON/OFF async function changeStatus(id, status) { if (!confirm("Ubah status menjadi " + status + "?")) { return; } try { await apiRequest( "/api/admin/scripts/" + id + "/status", { method: "PATCH", body: JSON.stringify({ status }) } ); await loadScripts(); } catch (error) { alert(error.message); } } // Cabut permanen async function revokeScript(id) { if (!confirm( "Cabut SCRIPT_ID " + id + " secara permanen?" )) { return; } try { await apiRequest("/api/admin/scripts/" + id, { method: "DELETE" }); await loadScripts(); } catch (error) { alert(error.message); } } // Jalankan awal checkConnection(); if (adminToken) { showAdmin(); } else { showLogin(); }