"use strict"; const rows = document.getElementById("rows"); const nameInput = document.getElementById("name"); const createBtn = document.getElementById("create"); const errorEl = document.getElementById("error"); const statusEl = document.getElementById("status"); const modal = document.getElementById("secret-modal"); const secretEl = document.getElementById("secret"); const copyBtn = document.getElementById("copy"); const closeBtn = document.getElementById("close"); function showError(text) { errorEl.hidden = !text; errorEl.textContent = text || ""; } function admin(method, args) { return browser.runtime.sendMessage({ type: "admin", method, args }).then((resp) => { if (!resp || !resp.ok) { throw new Error((resp && resp.error) || "host error"); } return resp.result; }); } function render(clients) { if (!clients.length) { rows.innerHTML = 'No clients yet. Generate a secret to get started.'; return; } rows.innerHTML = ""; for (const client of clients) { const tr = document.createElement("tr"); tr.innerHTML = ` ${escapeHtml(client.name)} ${escapeHtml(client.created || "")} ${escapeHtml(client.last_used || "never")} `; rows.appendChild(tr); } } function escapeHtml(value) { return String(value) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); } async function refresh() { const info = await browser.runtime.sendMessage({ type: "status" }); statusEl.textContent = info && info.hostUp ? `Native host connected ยท http://127.0.0.1:${info.port}` : "Native host is not connected. Install the host, then reload this add-on."; if (!info || !info.hostUp) { rows.innerHTML = 'Host offline.'; return; } render(await admin("clients.list")); } createBtn.addEventListener("click", async () => { showError(""); try { const created = await admin("clients.create", [nameInput.value.trim()]); nameInput.value = ""; secretEl.value = created.token; modal.showModal(); await refresh(); } catch (err) { showError(err.message); } }); rows.addEventListener("click", async (event) => { const id = event.target && event.target.getAttribute("data-revoke"); if (!id) { return; } showError(""); try { await admin("clients.revoke", [id]); await refresh(); } catch (err) { showError(err.message); } }); copyBtn.addEventListener("click", async () => { try { await navigator.clipboard.writeText(secretEl.value); copyBtn.textContent = "Copied"; } catch (err) { showError(err.message); } }); closeBtn.addEventListener("click", () => { secretEl.value = ""; copyBtn.textContent = "Copy"; modal.close(); }); refresh().catch((err) => showError(err.message));