fix(ui): Tor status from the live probe, not from a leftover onion address
Demo images / Build & push demo images (push) Successful in 3m14s
Demo images / Build & push demo images (push) Successful in 3m14s
Home's Network card computed "Connected" from server-info's tor-address — a string read from the hidden-service hostname file, which persists on disk however dead the daemon is. Three fleet nodes ran with Tor down for days while their dashboards said Connected; that indicator is why nobody noticed. Server.vue's Tor label had the same flaw one step removed, inferring "running" from services having onion_address values while the correct signal (torDaemonRunning, backed by a real socket probe) sat computed and unused twelve lines above. Both now read liveness signals only: Home reads the new tor-running field (server-side connect to 127.0.0.1:9050), Server.vue uses torDaemonRunning. The address remains displayed as what it is — an address — never as proof of life. Verified: vue-tsc clean; rpc-client suite 79/79. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
aaa0651c8d
commit
e34937f497
@@ -25,6 +25,9 @@ export interface ServerInfo {
|
|||||||
'status-info': StatusInfo
|
'status-info': StatusInfo
|
||||||
'lan-address': string | null
|
'lan-address': string | null
|
||||||
'tor-address': string | null
|
'tor-address': string | null
|
||||||
|
/** Live probe of the Tor daemon. NOT the same as `tor-address`, which is read
|
||||||
|
* from the hidden-service hostname file and outlives a dead daemon. */
|
||||||
|
'tor-running': boolean
|
||||||
'node-address'?: string
|
'node-address'?: string
|
||||||
unread: number
|
unread: number
|
||||||
'wifi-ssids': string[]
|
'wifi-ssids': string[]
|
||||||
|
|||||||
@@ -424,10 +424,13 @@ function marketplaceDescription(app: MarketplaceApp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Network card data
|
// Network card data
|
||||||
const torConnected = computed(() => {
|
// Tor liveness, NOT "was an onion ever provisioned". This used to return
|
||||||
const torAddr = store.data?.['server-info']?.['tor-address']
|
// `!!server-info['tor-address']`, but that address is read from the
|
||||||
return !!torAddr && torAddr.length > 0
|
// hidden-service hostname file on disk and outlives the daemon — so this card
|
||||||
})
|
// showed "Connected" on three fleet nodes whose Tor had been dead for days
|
||||||
|
// (2026-08-09), which is precisely why nobody noticed. `tor-running` is a live
|
||||||
|
// probe of 127.0.0.1:9050 performed server-side.
|
||||||
|
const torConnected = computed(() => store.data?.['server-info']?.['tor-running'] === true)
|
||||||
const vpnConnected = computed(() => homeStatus.vpnStatus.connected === true || (!!packages.value['tailscale'] && packages.value['tailscale'].state === PackageState.Running))
|
const vpnConnected = computed(() => homeStatus.vpnStatus.connected === true || (!!packages.value['tailscale'] && packages.value['tailscale'].state === PackageState.Running))
|
||||||
const vpnDotClass = computed(() => {
|
const vpnDotClass = computed(() => {
|
||||||
if (vpnConnected.value) return 'bg-orange-400'
|
if (vpnConnected.value) return 'bg-orange-400'
|
||||||
|
|||||||
@@ -995,8 +995,14 @@ async function checkTorStatus() {
|
|||||||
checkingTor.value = true; torStatusLabel.value = 'checking'
|
checkingTor.value = true; torStatusLabel.value = 'checking'
|
||||||
try {
|
try {
|
||||||
await torServicesRes.refresh()
|
await torServicesRes.refresh()
|
||||||
|
// Report the DAEMON, not whether onion addresses exist. A .onion address is
|
||||||
|
// a config artifact — the hidden-service hostname file stays on disk when
|
||||||
|
// Tor is dead — so `some(s => s.onion_address)` reported "running" on three
|
||||||
|
// fleet nodes whose Tor had been down for days (2026-08-09). The backend
|
||||||
|
// already returns the truth: tor_running comes from an actual connect to
|
||||||
|
// 127.0.0.1:9050.
|
||||||
if (torServicesRes.error.value) torStatusLabel.value = 'stopped'
|
if (torServicesRes.error.value) torStatusLabel.value = 'stopped'
|
||||||
else torStatusLabel.value = torServices.value.some(s => s.onion_address) ? 'running' : 'stopped'
|
else torStatusLabel.value = torDaemonRunning.value ? 'running' : 'stopped'
|
||||||
} finally { checkingTor.value = false }
|
} finally { checkingTor.value = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user