Commit f77bb03a authored by jan.koester's avatar jan.koester
Browse files

test

parent 415c0c15
Loading
Loading
Loading
Loading
+93 −0
Changes for admin/static/app.js: 93 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -28,6 +28,16 @@ const ProxyPlusAdmin = (() => {
    tr.lastElementChild.appendChild(btn);
  }

  // Appends a "Bearbeiten" button into a row's last (empty) <td>. All create
  // endpoints upsert by id/key (see ConfigStore::put*), so editing just means:
  // show the create form again, pre-filled from this row, then resubmit.
  function addEditButton(tr, onClick) {
    const btn = document.createElement("button");
    btn.textContent = "Bearbeiten";
    btn.onclick = onClick;
    tr.lastElementChild.appendChild(btn);
  }

  async function login() {
    const username = document.getElementById("login-username").value;
    const password = document.getElementById("login-password").value;
@@ -84,11 +94,25 @@ const ProxyPlusAdmin = (() => {
            : "")
        : "keine";
      tr.innerHTML = `<td>${r.id}</td><td>${r.domain}</td><td>${r.path_prefix}</td><td>${r.upstream}</td><td>${r.upstream_pool}</td><td>${r.required_permission}</td><td>${tlsInfo}</td><td></td>`;
      addEditButton(tr, () => editRoute(r));
      addDeleteButton(tr, () => deleteRoute(r.id));
      body.appendChild(tr);
    }
  }

  function editRoute(r) {
    showNewRouteForm();
    document.getElementById("route-id").value = r.id;
    document.getElementById("route-id").readOnly = true;
    document.getElementById("route-domain").value = r.domain;
    document.getElementById("route-path").value = r.path_prefix;
    document.getElementById("route-upstream").value = r.upstream;
    document.getElementById("route-upstream-pool").value = r.upstream_pool;
    document.getElementById("route-permission").value = r.required_permission;
    document.getElementById("route-tls-verify").checked = r.tls_verify_upstream;
    document.getElementById("route-tls-pins").value = (r.tls_pinned_fingerprints_sha256 || []).join(", ");
  }

  async function deleteRoute(id) {
    if (!confirm("Route '" + id + "' wirklich löschen?")) return;
    try {
@@ -106,11 +130,22 @@ const ProxyPlusAdmin = (() => {
    for (const r of relays) {
      const tr = document.createElement("tr");
      tr.innerHTML = `<td>${r.id}</td><td>${r.domain}</td><td>${r.smarthost}</td><td>${r.smarthost_pool}</td><td>${r.owner_group_id}</td><td></td>`;
      addEditButton(tr, () => editRelay(r));
      addDeleteButton(tr, () => deleteRelay(r.id));
      body.appendChild(tr);
    }
  }

  function editRelay(r) {
    showNewRelayForm();
    document.getElementById("relay-id").value = r.id;
    document.getElementById("relay-id").readOnly = true;
    document.getElementById("relay-domain").value = r.domain;
    document.getElementById("relay-smarthost").value = r.smarthost;
    document.getElementById("relay-smarthost-pool").value = r.smarthost_pool;
    document.getElementById("relay-group").value = r.owner_group_id;
  }

  async function deleteRelay(id) {
    if (!confirm("Relay '" + id + "' wirklich löschen?")) return;
    try {
@@ -131,11 +166,23 @@ const ProxyPlusAdmin = (() => {
        .join(", ");
      const tr = document.createElement("tr");
      tr.innerHTML = `<td>${p.id}</td><td>${p.kind}</td><td>${p.algorithm}</td><td>${targets}</td><td></td>`;
      addEditButton(tr, () => editPool(p));
      addDeleteButton(tr, () => deletePool(p.id));
      body.appendChild(tr);
    }
  }

  function editPool(p) {
    showNewPoolForm();
    document.getElementById("pool-id").value = p.id;
    document.getElementById("pool-id").readOnly = true;
    document.getElementById("pool-kind").value = p.kind;
    document.getElementById("pool-algorithm").value = p.algorithm;
    document.getElementById("pool-targets").value = (p.targets || [])
      .map((t) => `${t.address}:${t.weight}`)
      .join(", ");
  }

  async function deletePool(id) {
    if (!confirm("Pool '" + id + "' wirklich löschen?")) return;
    try {
@@ -153,11 +200,38 @@ const ProxyPlusAdmin = (() => {
    for (const p of profiles) {
      const tr = document.createElement("tr");
      tr.innerHTML = `<td>${p.profile}</td><td>${(p.domains || []).join(", ")}</td><td>${p.acme_enabled ? "ja" : "nein"}</td><td>${p.self_signed ? "ja" : "nein"}</td><td>${p.has_manual_cert ? "ja" : "nein"}</td><td>${p.acme_email}</td><td>${p.ca_plugin}</td><td></td>`;
      addEditButton(tr, () => editTlsProfile(p));
      addDeleteButton(tr, () => deleteTlsProfile(p.profile));
      body.appendChild(tr);
    }
  }

  function editTlsProfile(p) {
    showNewTlsProfileForm();
    document.getElementById("tls-profile-id").value = p.profile;
    document.getElementById("tls-profile-id").readOnly = true;
    document.getElementById("tls-profile-domains").value = (p.domains || []).join(", ");
    document.getElementById("tls-profile-acme").checked = p.acme_enabled;
    document.getElementById("tls-profile-email").value = p.acme_email || "";
    document.getElementById("tls-profile-directory").value = p.acme_directory_url || "";
    document.getElementById("tls-profile-ca-plugin").value = p.ca_plugin || "";
    document.getElementById("tls-profile-selfsigned").checked = p.self_signed;
    // GET never returns cert/key PEM (it's private key material) and POST fully
    // replaces the record, so leaving these blank on save would silently erase
    // an existing manual certificate -- warn rather than let that happen quietly.
    const certField = document.getElementById("tls-profile-cert-pem");
    const keyField = document.getElementById("tls-profile-key-pem");
    certField.value = "";
    keyField.value = "";
    const hint = p.has_manual_cert
      ? "Vorhandenes Zertifikat -- leer lassen entfernt es beim Speichern! Zum Behalten erneut einfuegen."
      : "Eigenes Zertifikat (PEM) -- nur im Cluster-Modus, sonst Datei direkt unter <data>/tls/<profil>.crt ablegen";
    certField.placeholder = hint;
    keyField.placeholder = p.has_manual_cert
      ? "Vorhandener Schluessel -- leer lassen entfernt ihn beim Speichern! Zum Behalten erneut einfuegen."
      : "Eigener privater Schluessel (PEM) -- wird vor der Speicherung mit dem Cluster-Schluessel versiegelt";
  }

  async function deleteTlsProfile(profile) {
    if (!confirm("TLS-Profil '" + profile + "' wirklich löschen?")) return;
    try {
@@ -175,11 +249,21 @@ const ProxyPlusAdmin = (() => {
    for (const k of keys) {
      const tr = document.createElement("tr");
      tr.innerHTML = `<td>${k.domain}</td><td>${k.selector}</td><td>${k.key_path}</td><td>${k.enabled ? "ja" : "nein"}</td><td></td>`;
      addEditButton(tr, () => editDkimKey(k));
      addDeleteButton(tr, () => deleteDkimKey(k.domain));
      body.appendChild(tr);
    }
  }

  function editDkimKey(k) {
    showNewDkimKeyForm();
    document.getElementById("dkim-domain").value = k.domain;
    document.getElementById("dkim-domain").readOnly = true;
    document.getElementById("dkim-selector").value = k.selector;
    document.getElementById("dkim-keypath").value = k.key_path;
    document.getElementById("dkim-enabled").checked = k.enabled;
  }

  async function deleteDkimKey(domain) {
    if (!confirm("DKIM-Key fuer '" + domain + "' wirklich löschen?")) return;
    try {
@@ -202,6 +286,7 @@ const ProxyPlusAdmin = (() => {
  }

  function showNewRouteForm() {
    document.getElementById("route-id").readOnly = false;
    document.getElementById("new-route-form").hidden = false;
  }

@@ -229,6 +314,7 @@ const ProxyPlusAdmin = (() => {
  }

  function showNewRelayForm() {
    document.getElementById("relay-id").readOnly = false;
    document.getElementById("new-relay-form").hidden = false;
  }

@@ -249,6 +335,11 @@ const ProxyPlusAdmin = (() => {
  }

  function showNewTlsProfileForm() {
    document.getElementById("tls-profile-id").readOnly = false;
    document.getElementById("tls-profile-cert-pem").placeholder =
      "Eigenes Zertifikat (PEM) -- nur im Cluster-Modus, sonst Datei direkt unter <data>/tls/<profil>.crt ablegen";
    document.getElementById("tls-profile-key-pem").placeholder =
      "Eigener privater Schluessel (PEM) -- wird vor der Speicherung mit dem Cluster-Schluessel versiegelt";
    document.getElementById("new-tls-profile-form").hidden = false;
  }

@@ -277,6 +368,7 @@ const ProxyPlusAdmin = (() => {
  }

  function showNewDkimKeyForm() {
    document.getElementById("dkim-domain").readOnly = false;
    document.getElementById("new-dkim-key-form").hidden = false;
  }

@@ -296,6 +388,7 @@ const ProxyPlusAdmin = (() => {
  }

  function showNewPoolForm() {
    document.getElementById("pool-id").readOnly = false;
    document.getElementById("new-pool-form").hidden = false;
  }