From 409ee11e9e3e6a9c5cdc432c4de37fa2a67d9f43 Mon Sep 17 00:00:00 2001 From: Andre Padez Date: Sat, 15 Aug 2026 01:03:55 +0100 Subject: [PATCH] fix(vpn): show the sign-in form when there is nothing to sign into MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A state existed that the screen could not render: the core reaches NeedsLogin, no profile is persisted, nothing connects. signingIn is then true, so the manual form was suppressed as 'already in progress'. But there was no profile, nothing was connecting, and nothing would ever complete. What the screen showed was 'Waiting for sign-in' above a toggle whose value is bound to connected — so it could not move, and tapping it appeared to do nothing — with no form, no chooser, and (until the previous commit) no reset. The only exit was deleting the app from the home screen. A node in NeedsLogin with no profile is not signing in. It is stuck, and the way out of stuck is the form that asks where to connect. Co-Authored-By: Claude Opus 5 --- src/vpn/VpnScreen.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/vpn/VpnScreen.tsx b/src/vpn/VpnScreen.tsx index b1e8a00..f79bde2 100644 --- a/src/vpn/VpnScreen.tsx +++ b/src/vpn/VpnScreen.tsx @@ -1551,7 +1551,22 @@ export const VpnScreen = ({ embedded, onShowCredits, wordmark, wordmarkLight }: Headscale form, and showing a second copy here would put two on the screen at once. */} {/* `vm.showManual` forces it open even mid sign-in: for a Headscale node in needsLogin the form is the ONLY way forward, so hiding it there strands the user. */} - {showManual && !vm.needsSetup && (!vm.signingIn || vm.showManual) && vm.authorized !== false ? ( + {/* + `vm.profiles.length === 0` is the third way in, and it exists because of a state the other two + could not describe: a sign-in that got as far as NeedsLogin and no further. + + `signingIn` is then true, so the form is suppressed as "already in progress" — but there is no + profile, nothing is connected, and nothing will ever complete. The screen showed "Waiting for + sign-in" above a toggle bound to `connected` (so it could not move) with no form, no chooser + and no reset. The only exit was deleting the app. + + A node in NeedsLogin with no profile is not signing in. It is stuck, and the way out of stuck + is the form that asks where to connect. + */} + {showManual && + !vm.needsSetup && + (!vm.signingIn || vm.showManual || vm.profiles.length === 0) && + vm.authorized !== false ? ( ) : null}