123 lines
4.3 KiB
JavaScript
123 lines
4.3 KiB
JavaScript
(() => {
|
|
"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");
|
|
// F3 (Umsetzungsauftrag_Sonnet5.md Teil F.2): "Verbinden" fuehrt in die
|
|
// Arbeitsflaeche statt (wie vor Teil F) direkt in einen neuen Tab mit
|
|
// /terminal/{id} bzw. /rdp/{id} -- diese Seiten bleiben als duenner
|
|
// Rahmen fuer Lesezeichen/Fehlersuche bestehen (F.2), sind aber nicht
|
|
// mehr der reguraere Einstiegspunkt. ?host= wird von workspace.js beim
|
|
// Laden ausgewertet und startet die Sitzung dort direkt.
|
|
connect.href = `/workspace?host=${host.id}`;
|
|
connect.textContent = "Verbinden";
|
|
// Weiterhin ein eigener Tab: das Dashboard bleibt dadurch erreichbar,
|
|
// waehrend die Arbeitsflaeche laeuft (dort fuehrt "Dashboard" im
|
|
// Topbar-Link zurueck, falls im selben Tab genavigiert wird).
|
|
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 = '<p class="hint">Keine Hosts zugewiesen. Bitte an einen Administrator wenden.</p>';
|
|
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));
|
|
})();
|