connect fix 4

This commit is contained in:
2026-08-21 06:14:10 +02:00
parent bf2a02679d
commit 5e506c9921
17 changed files with 1266 additions and 162 deletions

View File

@ -505,6 +505,27 @@
box.replaceChildren(el("div", { className: `banner ${type === "error" ? "error" : "ok"}`, textContent: message }));
}
function describeEffectiveUsername(host, isRdp) {
if (isRdp) {
if (host.rdp_credentials_username) {
const domain = host.rdp_credentials_domain ? `, Domaene ${host.rdp_credentials_domain}` : "";
return `Anmeldung als "${host.rdp_credentials_username}"${domain} (aus den RDP-Zugangsdaten unten).`;
}
if (host.rdp_username) {
return `Noch kein Benutzername in den Zugangsdaten -- es wird der alte Wert am Host verwendet ("${host.rdp_username}"). Bitte unten bei den RDP-Zugangsdaten neu setzen.`;
}
return "Kein Windows-Benutzername hinterlegt -- unten bei den RDP-Zugangsdaten eintragen, sonst schlaegt die Anmeldung fehl.";
}
const named = (host.ssh_keys || []).filter((k) => k.username);
if (named.length) {
return `Anmeldung als ${named.map((k) => `"${k.username}" (Key ${k.label})`).join(", ")}.`;
}
if (host.ssh_username) {
return `Noch kein Benutzername am SSH-Key -- es wird der alte Wert am Host verwendet ("${host.ssh_username}"). Bitte im Reiter "Zugangsdaten" am Schluessel eintragen.`;
}
return 'Kein SSH-Benutzername hinterlegt -- im Reiter "Zugangsdaten" am zugeordneten Schluessel eintragen, sonst kommt keine Verbindung zustande.';
}
async function showHostDetail(hostId) {
setDetailBanner("", "ok");
try {
@ -516,9 +537,6 @@
document.getElementById("he-hostname").value = host.hostname;
document.getElementById("he-address").value = host.address;
document.getElementById("he-port").value = String(host.port);
document.getElementById("he-ssh-username").value = host.ssh_username || "";
document.getElementById("he-rdp-username").value = host.rdp_username || "";
document.getElementById("he-rdp-domain").value = host.rdp_domain || "";
document.getElementById("he-clipboard").checked = host.clipboard_enabled;
document.getElementById("he-filetransfer").checked = host.file_transfer_enabled;
document.getElementById("he-nla").checked = host.rdp_require_nla;
@ -526,9 +544,11 @@
document.getElementById("he-active").checked = host.is_active;
const isRdp = host.protocol === "rdp";
document.getElementById("he-ssh-username-box").classList.toggle("hidden", isRdp);
document.getElementById("he-rdp-username-box").classList.toggle("hidden", !isRdp);
document.getElementById("he-rdp-domain-box").classList.toggle("hidden", !isRdp);
// Der Anmeldename steht bei den Zugangsdaten (SSH-Key bzw.
// RDP-Passwortsatz). Hier wird nur angezeigt, welcher Name greifen
// wuerde -- inklusive des Altbestands am Host, solange er noch benutzt
// wird.
document.getElementById("he-username-hint").textContent = describeEffectiveUsername(host, isRdp);
document.getElementById("he-nla-box").classList.toggle("hidden", !isRdp);
document.getElementById("he-ignorecert-box").classList.toggle("hidden", !isRdp);
document.getElementById("host-detail-ssh").classList.toggle("hidden", isRdp);
@ -548,6 +568,7 @@
el("tr", {}, [
el("td", { textContent: String(k.id) }),
el("td", { textContent: k.label }),
el("td", { textContent: k.username || "(kein Benutzername)" }),
el("td", {}, [
actionButton("Entfernen", "btn-danger", async () => {
await apiFetch(`/admin/hosts/${host.id}/ssh-keys/${k.id}`, { method: "DELETE" });
@ -561,8 +582,10 @@
keySelect.replaceChildren(...optionsFromList(cachedSshKeys, "id", (k) => `${k.label} (#${k.id})`));
document.getElementById("rdp-cred-status").textContent = host.rdp_credentials_set
? `RDP-Passwort ist gesetzt (zuletzt aktualisiert: ${host.rdp_credentials_updated_at}).`
: "Noch kein RDP-Passwort gesetzt.";
? `RDP-Zugangsdaten gesetzt fuer "${host.rdp_credentials_username || "(kein Benutzername)"}" (zuletzt aktualisiert: ${host.rdp_credentials_updated_at}).`
: "Noch keine RDP-Zugangsdaten gesetzt.";
document.getElementById("hrc-username").value = host.rdp_credentials_username || host.rdp_username || "";
document.getElementById("hrc-domain").value = host.rdp_credentials_domain || host.rdp_domain || "";
} catch (err) {
setDetailBanner(err.message, "error");
}
@ -575,9 +598,6 @@
hostname: document.getElementById("he-hostname").value.trim(),
address: document.getElementById("he-address").value.trim(),
port: Number(document.getElementById("he-port").value),
ssh_username: document.getElementById("he-ssh-username").value.trim() || null,
rdp_username: document.getElementById("he-rdp-username").value.trim() || null,
rdp_domain: document.getElementById("he-rdp-domain").value.trim() || null,
clipboard_enabled: document.getElementById("he-clipboard").checked,
file_transfer_enabled: document.getElementById("he-filetransfer").checked,
rdp_require_nla: document.getElementById("he-nla").checked,
@ -594,9 +614,6 @@
document.getElementById("hc-protocol").addEventListener("change", (ev) => {
const isRdp = ev.target.value === "rdp";
document.getElementById("hc-ssh-username-box").classList.toggle("hidden", isRdp);
document.getElementById("hc-rdp-username-box").classList.toggle("hidden", !isRdp);
document.getElementById("hc-rdp-domain-box").classList.toggle("hidden", !isRdp);
document.getElementById("hc-nla-box").classList.toggle("hidden", !isRdp);
document.getElementById("hc-ignorecert-box").classList.toggle("hidden", !isRdp);
document.getElementById("hc-ignorecert-hint").classList.toggle("hidden", !isRdp);
@ -632,9 +649,6 @@
protocol,
port: Number(document.getElementById("hc-port").value),
os_type: document.getElementById("hc-os-type").value,
ssh_username: document.getElementById("hc-ssh-username").value.trim() || null,
rdp_username: document.getElementById("hc-rdp-username").value.trim() || null,
rdp_domain: document.getElementById("hc-rdp-domain").value.trim() || null,
rdp_require_nla: document.getElementById("hc-nla").checked,
rdp_ignore_cert: document.getElementById("hc-ignorecert").checked,
clipboard_enabled: document.getElementById("hc-clipboard").checked,
@ -679,7 +693,9 @@
ev.preventDefault();
try {
const password = document.getElementById("hrc-password").value;
await sendJson(`/admin/hosts/${activeHostId}/rdp-credentials`, "PUT", { password });
const username = document.getElementById("hrc-username").value.trim();
const domain = document.getElementById("hrc-domain").value.trim() || null;
await sendJson(`/admin/hosts/${activeHostId}/rdp-credentials`, "PUT", { password, username, domain });
showBanner("RDP-Zugangsdaten gespeichert.", "ok");
ev.target.reset();
await showHostDetail(activeHostId);
@ -709,6 +725,7 @@
el("tr", {}, [
el("td", { textContent: String(k.id) }),
el("td", { textContent: k.label }),
el("td", { textContent: k.username || "-" }),
el("td", { textContent: k.key_type }),
el("td", { textContent: k.owner_user_id === null ? "-" : String(k.owner_user_id) }),
el("td", { textContent: k.tenant_name }),
@ -736,6 +753,7 @@
document.getElementById("ssh-key-edit-panel").classList.remove("hidden");
document.getElementById("ssh-key-edit-name").textContent = `${k.label} (#${k.id})`;
document.getElementById("ske-label").value = k.label;
document.getElementById("ske-username").value = k.username || "";
document.getElementById("ske-owner").value = k.owner_user_id === null ? "" : String(k.owner_user_id);
document.getElementById("skr-type").value = k.key_type;
document.getElementById("skp-passphrase").value = "";
@ -784,6 +802,9 @@
const ownerRaw = document.getElementById("ske-owner").value.trim();
await sendJson(`/admin/ssh-keys/${editingSshKeyId}`, "PUT", {
label: document.getElementById("ske-label").value.trim() || null,
// Leeres Feld -> null entfernt den Benutzernamen bewusst (die
// Server-Semantik unterscheidet zwischen "Feld fehlt" und "null").
username: document.getElementById("ske-username").value.trim() || null,
owner_user_id: ownerRaw ? Number(ownerRaw) : null,
});
showBanner("SSH-Key aktualisiert.", "ok");
@ -817,6 +838,7 @@
const tenantSelect = document.getElementById("skc-tenant");
const payload = {
label: document.getElementById("skc-label").value.trim(),
username: document.getElementById("skc-username").value.trim() || null,
owner_user_id: ownerRaw ? Number(ownerRaw) : null,
key_type: document.getElementById("skc-type").value,
private_key_pem: document.getElementById("skc-private").value,
@ -844,6 +866,7 @@
el("td", { textContent: r.hostname }),
el("td", { textContent: r.address }),
el("td", { textContent: r.host_group_name }),
el("td", { textContent: r.username || "-" }),
el("td", {}, [el("span", { className: `badge ${r.credentials_set ? "ok" : ""}`, textContent: r.credentials_set ? "gesetzt" : "nicht gesetzt" })]),
el("td", { textContent: r.updated_at || "-" }),
el("td", {}, [