From be06b3ce2b4d3edf96997b174b484de0d253b720 Mon Sep 17 00:00:00 2001 From: ssmithx Date: Sat, 5 Sep 2026 15:14:07 +0000 Subject: [PATCH] fix(ui): stop sending an empty ssh_password over the saved router connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit provisionTollgate/saveTollgateConfig/scanWifi/configureWan all fell back to the Connect form's local refs (host/sshUser/sshPassword) when connectedParams was null. Those refs only get populated if the form was actually submitted this session — on a normal page load the router reconnects via the server-persisted config instead, leaving sshPassword at its default ''. Sending that as an explicit (empty-but-present) ssh_password overrides the backend's saved-config fallback, so every action auths with a blank password instead of the real saved one. Added authParams(): omit host/ssh_user/ssh_password entirely unless connectedParams is actually set, same as the status poll already does. Caught live: dropbear on archy-x250-pa3's router logged a single bad password attempt at the exact moment "Install TollGate" was clicked, sandwiched between periodic status-poll connections succeeding with the real saved password. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0176RpCxFNS9ZaSJjL72W9Z5 --- neode-ui/src/views/server/OpenWrtGateway.vue | 38 +++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/neode-ui/src/views/server/OpenWrtGateway.vue b/neode-ui/src/views/server/OpenWrtGateway.vue index 5811074d..1905b02e 100644 --- a/neode-ui/src/views/server/OpenWrtGateway.vue +++ b/neode-ui/src/views/server/OpenWrtGateway.vue @@ -115,6 +115,24 @@ const showConnectForm = ref(false) const connecting = ref(false) const connectedParams = ref | null>(null) +// Every action below (install/edit TollGate, WiFi scan, WAN configure) needs +// host/ssh_user/ssh_password to reach the router. `connectedParams` only gets +// set when the Connect form was actually submitted this session (WR-03 above) +// — on a normal page load the router reconnects via the server-persisted +// config instead, so `sshPassword`/`sshUser`/`host` (the Connect form's own +// local refs) sit at their untouched defaults ('', 'root', ''). Falling back +// to those refs here used to send an explicit-but-empty ssh_password, which +// the backend treats as "the caller provided this" and never falls back to +// the real saved password — a real router password then fails auth on every +// action even though the status poll (which sends no params at all) keeps +// working fine (archy-x250-pa3, 2026-09-05: dropbear logged one bad-password +// attempt at the exact moment "Install TollGate" was clicked). Omitting the +// fields entirely when there's no explicit connectedParams lets the backend's +// own saved-config fallback do the right thing, same as the status poll. +function authParams(): Record { + return connectedParams.value ?? {} +} + const detecting = ref(false) const detectError = ref('') const detectedCandidates = ref([]) @@ -271,11 +289,7 @@ async function provisionTollgate() { provisionError.value = '' provisionSuccess.value = false try { - const params: Record = { - host: connectedParams.value?.host ?? status.value?.host, - ssh_user: connectedParams.value?.ssh_user ?? sshUser.value, - ssh_password: connectedParams.value?.ssh_password ?? sshPassword.value, - } + const params: Record = { ...authParams() } await rpcClient.call({ method: 'openwrt.provision-tollgate', params, timeout: 300000 }) provisionSuccess.value = true await load(connectedParams.value ?? undefined) @@ -302,9 +316,7 @@ async function saveTollgateConfig() { updateTollgateError.value = '' try { const params: Record = { - host: connectedParams.value?.host ?? status.value?.host, - ssh_user: connectedParams.value?.ssh_user ?? sshUser.value, - ssh_password: connectedParams.value?.ssh_password ?? sshPassword.value, + ...authParams(), price_sats: editPriceSats.value, step_size_ms: editStepSizeMin.value * 60_000, min_steps: editMinSteps.value, @@ -336,11 +348,7 @@ async function scanWifi() { wanStep.value = 'scanning' wanError.value = '' try { - const params: Record = { - host: connectedParams.value?.host ?? status.value?.host, - ssh_user: connectedParams.value?.ssh_user ?? sshUser.value, - ssh_password: connectedParams.value?.ssh_password ?? sshPassword.value, - } + const params: Record = { ...authParams() } const result = await rpcClient.call<{ networks: ScannedNetwork[] }>({ method: 'openwrt.scan-wifi', params, @@ -367,9 +375,7 @@ async function configureWan() { wanError.value = '' try { const params: Record = { - host: connectedParams.value?.host ?? status.value?.host, - ssh_user: connectedParams.value?.ssh_user ?? sshUser.value, - ssh_password: connectedParams.value?.ssh_password ?? sshPassword.value, + ...authParams(), ssid: selectedNetwork.value.ssid, password: wanPassword.value, encryption: selectedNetwork.value.encryption,