fix(vpn): show the sign-in form when there is nothing to sign into

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 <noreply@anthropic.com>
This commit is contained in:
2026-08-15 01:03:55 +01:00
co-authored by Claude Opus 5
parent 7672cf57bb
commit 409ee11e9e
+16 -1
View File
@@ -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 ? (
<ManualLogin vm={vm} />
) : null}