From 1f6c7cf349e1acb27fb106dbf2dec8f23d18ef74 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 28 Jul 2026 18:04:36 +0000 Subject: [PATCH] Default new extensions to TLS, with transport behind an Advanced disclosure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Making the transport a visible, equally-weighted choice meant new users had to know the answer before they could get one right — and the wrong answer fails in the least diagnosable way available: a UDP-only endpoint doesn't refuse a TLS registration, it ignores it, so the phone times out and nothing is logged anywhere. The add form now creates Remote/FQDN (TLS 5061) extensions without asking. TLS is listed first in the markup so it is the default before any script runs, and the JS no longer switches it to LAN on a box with no domain — that box is not better served by UDP, it just needs the phone told to trust a self-signed certificate, which the disclosure now says at the point of choosing. Transport and auto-answer moved behind an "Advanced…" toggle, leaving name, extension and category as the whole form. The toggle resets on cancel and after a successful add so it doesn't stay open across uses. Verified in the browser on two fixtures — with and without DOMAIN_NAME set — that the panel starts hidden, the transport reads fqdn untouched in both cases, and each shows the right hint when opened. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01NAddJGE1G6eGaPzmScG5Vh --- services/security-dashboard.sh | 67 ++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/services/security-dashboard.sh b/services/security-dashboard.sh index 2415b84..d11b747 100644 --- a/services/security-dashboard.sh +++ b/services/security-dashboard.sh @@ -270,7 +270,10 @@ which tab a given extension's settings live on. choice is the usual reason a phone which looks correctly configured never registers: an endpoint written \`transport=transport-udp\` does not refuse a TLS registration, it ignores it, so the phone times out - and nothing is logged anywhere. This is a native reimplementation of Easy Asterisk's + and nothing is logged anywhere. With no \`DOMAIN_NAME\` set that TLS + certificate can only be self-signed and the phone has to be told to + accept it, which the disclosure says where the choice is rather than + silently picking UDP for you. This is a native reimplementation of Easy Asterisk's own vendored web admin (\`vendor/easy-asterisk/easy-asterisk-v0.10.0.sh\`'s device/room management), not a link or an iframe to that separate process — one page, one login. Reads \`pjsip.conf\`/\`rooms.conf\` @@ -2795,6 +2798,16 @@ INDEX_HTML = """ background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); } .add-form.open { display: flex; } + /* Transport and auto-answer are answers most people never need to change; + they stay out of the way until asked for. */ + .add-advanced { display: none; width: 100%; gap: var(--sp-2); align-items: center; flex-wrap: wrap; } + .add-advanced.open { display: flex; } + button.link { + background: none; border: none; color: var(--accent); font: inherit; + font-size: 0.85rem; cursor: pointer; padding: 0.2rem 0; + text-decoration: underline dotted; text-underline-offset: 3px; + } + button.link:hover { color: #7aa9ff; } /* ── Save bar ─────────────────────────────────────────────────────────── */ /* One commit point for the whole table, pinned to the bottom of the viewport @@ -2951,17 +2964,26 @@ INDEX_HTML = """
- - + + +
+ + + +
@@ -3276,12 +3298,17 @@ async function initExtensionsTab() { ]); eaInstalled = !!ea.installed; pstnInstalled = !!pstn.installed; - // A box with a domain is reachable from anywhere and its phones must use - // TLS; defaulting the form to LAN there produces an endpoint that silently - // refuses every remote registration. - if (ea.default_conn_type) { - const sel = document.getElementById("ea-dev-conn"); - if (sel) sel.value = ea.default_conn_type; + // The form defaults to TLS in the markup and stays there — no box is worse + // off for it, and the failure mode of the other default (a UDP-only + // endpoint silently refusing TLS registrations) is far harder to diagnose + // than a phone being told to trust a self-signed certificate. Without a + // domain configured that certificate can only be self-signed, so say so + // where the choice is rather than quietly switching it. + const connHint = document.getElementById("ext-add-conn-hint"); + if (connHint) { + connHint.textContent = ea.domain + ? "Phones register against " + ea.domain + ":5061." + : "No DOMAIN_NAME set in Asterisk's .env — TLS will use a self-signed certificate the phone must be told to accept. LAN only (UDP) avoids that on a local network."; } if (ea.installed && ea.env_readable === false) { toast("Can't read Asterisk's .env — connection details will be incomplete. Re-run: sudo ./setup.sh security-dashboard", "err"); @@ -3605,6 +3632,14 @@ document.getElementById("ext-add-toggle").addEventListener("click", () => { }); document.getElementById("ext-add-cancel").addEventListener("click", () => { extAddForm.classList.remove("open"); + document.getElementById("ext-add-advanced").classList.remove("open"); + document.getElementById("ext-add-advanced-toggle").textContent = "Advanced…"; +}); +document.getElementById("ext-add-advanced-toggle").addEventListener("click", () => { + const adv = document.getElementById("ext-add-advanced"); + adv.classList.toggle("open"); + document.getElementById("ext-add-advanced-toggle").textContent = + adv.classList.contains("open") ? "Hide advanced" : "Advanced…"; }); document.getElementById("ext-password-dismiss").addEventListener("click", () => { document.getElementById("ext-password-callout").classList.remove("show"); @@ -3682,6 +3717,8 @@ document.getElementById("ea-dev-save").addEventListener("click", async () => { document.getElementById("ea-dev-ext").value = ""; document.getElementById("ea-dev-mobile").checked = false; extAddForm.classList.remove("open"); + document.getElementById("ext-add-advanced").classList.remove("open"); + document.getElementById("ext-add-advanced-toggle").textContent = "Advanced…"; // The password alone isn't enough to configure a phone — open the full // details (server, transport, TURN) immediately rather than making the // user hunt for them.