Port-forward UX: drop tile Step 4 and misleading local 'ready' status

The Element Call tile still appended a synthetic 'Step 4: Router Setup
Needed' to the domain diagnostic checklist, and every port table carried a
'Sovran_SystemsOS Status' column with Ready / Not ready yet verdicts.

Both were misleading: port forwarding happens on the router, which this
computer cannot inspect. A local ss/firewall probe can neither prove nor
disprove that forwarding works — and the LiveKit TURN relay range binds on
demand, so it reported 'Not ready yet' even on a perfectly working system.

- server.py: add ROUTER_FORWARD_ONLY_UNITS ({livekit.service}); skip the
  local probe for those units, drop the step-4 append, replace extra_ports
  with router_ports (no status field), and exclude router-only ports from
  both tile health and /api/ports/health so they can't raise false alarms.
- helpers.js: new shared renderPortForwardGuideHtml() — one intro naming the
  internal IP, explicit instructions (same internal/external port, match the
  protocol, use port-range fields for 30000-40000), a colour-coded
  TCP / UDP / TCP+UDP badge per row, and a closing note that the only real
  test is loading the service from a phone on mobile data.
- features.js: enable-time modal uses the shared guide and now always lists
  every port to forward (the old local pre-filter hid ports the user still
  had to open).
- service-detail.js: tile port section uses the same guide; the SSH/non-domain
  branch keeps a small 'not open on this computer yet' hint, which is a real
  local fact, separate from router forwarding.
- onboarding.js: step 3 router note reworded to match (same number for
  internal/external, notes that Element Call adds UDP ports).
- domain-setup.css: styles for the protocol badges and instruction list.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
This commit is contained in:
naturallaw777
2026-07-28 22:34:39 +00:00
co-authored by arena-agent
parent 0e3cab78f8
commit 419680a847
6 changed files with 195 additions and 153 deletions
@@ -383,10 +383,12 @@ async function loadStep3() {
? ' to this computer&rsquo;s internal IP <strong>' + escHtml(internalIp) + '</strong>'
: ' to this computer&rsquo;s internal IP';
html += '<div class="onboarding-port-warn" style="margin-bottom:16px;">'
+ '🔌 <strong>One router task:</strong> forward ports <strong>80</strong> and <strong>443</strong> (TCP)'
+ routerIpPart + '. They are required for HTTPS and SSL certificates — without them your services cannot be reached from outside your home network. '
+ 'Forward port <strong>22</strong> (TCP) too if you want remote SSH access. '
+ 'Element Call needs a few extra ports, but you&rsquo;ll be shown those when you enable it.'
+ '🔌 <strong>One router task:</strong> in your router&rsquo;s <strong>port forwarding</strong> settings, forward '
+ 'port <strong>80 (TCP)</strong> and port <strong>443 (TCP)</strong>'
+ routerIpPart + '. Use the <strong>same number for the internal and external port</strong>. '
+ 'These are required for HTTPS and SSL certificates — without them your services cannot be reached from outside your home network. '
+ 'Add port <strong>22 (TCP)</strong> as well if you want remote SSH access. '
+ 'Element Call needs a few extra ports (some UDP), and you&rsquo;ll be shown exactly which when you enable it.'
+ '</div>';
relevantDomains.forEach(function(d) {