(() => { "use strict"; async function getJson(url) { const res = await fetch(url, { credentials: "same-origin" }); if (res.status === 401) { window.location.href = "/"; throw new Error("nicht angemeldet"); } return res.json(); } async function showCredentials(host) { const box = document.getElementById("credentials-box"); box.className = "reveal-box"; box.textContent = `Lade Zugangsdaten fuer ${host.hostname} ...`; try { const info = await getJson(`/admin/hosts/${host.id}/credentials`); const lines = [`Zugangsdaten fuer ${host.hostname}:`]; lines.push( info.ssh_keys.length ? `SSH-Keys: ${info.ssh_keys.map((k) => k.label).join(", ")}` : "SSH-Keys: keine zugeordnet" ); lines.push( info.rdp_credentials_set ? `RDP-Passwort gesetzt (zuletzt aktualisiert: ${info.rdp_credentials_updated_at}).` : "RDP-Passwort: nicht gesetzt." ); box.textContent = lines.join("\n"); } catch (err) { box.className = "banner error"; box.textContent = `Zugangsdaten konnten nicht geladen werden: ${err.message}`; } } function hostCard(host) { const div = document.createElement("div"); div.className = "host-card"; const name = document.createElement("div"); name.className = "hostname"; name.textContent = host.hostname; div.appendChild(name); const meta = document.createElement("div"); meta.className = "meta"; meta.textContent = `${host.protocol.toUpperCase()} · ${host.os_type} · ${host.address}`; div.appendChild(meta); const actions = document.createElement("div"); actions.className = "actions"; const connect = document.createElement("a"); connect.href = host.protocol === "ssh" ? `/terminal/${host.id}` : `/rdp/${host.id}`; connect.textContent = "Verbinden"; // Oeffnet die Sitzung in einem eigenen Tab statt im Dashboard-Tab zu // navigieren -- das Dashboard bleibt dadurch erreichbar, waehrend die // Sitzung laeuft, und der Exit-Button der Sitzung (session-toolbar in // terminal.html/rdp.html) kann genau diesen Tab wieder schliessen. connect.target = "_blank"; actions.appendChild(connect); if (host.can_view_credentials) { const credBtn = document.createElement("button"); credBtn.type = "button"; credBtn.textContent = "Zugangsdaten"; credBtn.addEventListener("click", () => { document.getElementById("credentials-box").classList.remove("hidden"); showCredentials(host); }); actions.appendChild(credBtn); } div.appendChild(actions); return div; } async function main() { const me = await getJson("/auth/me"); document.getElementById("whoami").textContent = `${me.username}${me.is_admin ? " (Admin)" : ""}`; if (me.is_admin) { document.getElementById("admin-link").classList.remove("hidden"); } const hosts = await getJson("/catalog/hosts"); const byGroup = {}; for (const h of hosts) { (byGroup[h.host_group_name] = byGroup[h.host_group_name] || []).push(h); } const container = document.getElementById("groups"); if (hosts.length === 0) { container.innerHTML = '

Keine Hosts zugewiesen. Bitte an einen Administrator wenden.

'; return; } for (const [groupName, groupHosts] of Object.entries(byGroup)) { const section = document.createElement("div"); section.className = "group"; const h2 = document.createElement("h2"); h2.textContent = groupName; section.appendChild(h2); const list = document.createElement("div"); list.className = "host-list"; for (const host of groupHosts) list.appendChild(hostCard(host)); section.appendChild(list); container.appendChild(section); } } document.getElementById("logout-btn").addEventListener("click", async () => { await fetch("/auth/logout", { method: "POST", credentials: "same-origin" }); window.location.href = "/"; }); main().catch((err) => console.error(err)); })();