Repository navigation
fix(web): Tailscale HTTPS can be turned on while Network access is off - #26170
juliusmarminge wants to merge 3 commits into
Conversation
With Network access off and Tailscale Serve never enabled, the desktop skips Tailscale detection, so the Tailscale HTTPS row showed "Turn on Network access to detect Tailscale." and no switch. Enabling HTTPS meant toggling Network access on and off again. The row now shows an unchecked switch in that state, and the setup dialog can open without a detected endpoint. While Serve is enabled but no endpoint is found, a checked switch stays so Serve can be turned off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tates Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Tailscale HTTPS can now be explicitly enabled while Network access is off, even before endpoint discovery. Existing confirmation and authorization checks remain, and access defaults are unchanged. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Fallback description and switch state apps/web/src/components/settings/ConnectionsSettings.logic.ts, apps/web/src/components/settings/ConnectionsSettings.logic.test.ts |
The fallback helper returns a description and switch state. Tests cover local-only, unknown, Serve-enabled, and network-accessible states. |
Endpoint-optional settings flow apps/web/src/components/settings/ConnectionsSettings.tsx |
Pending setup now stores a nullable endpoint. When no endpoint exists, the row uses the fallback description and switch state, and the setup dialog opens from the pending setup state. |
Priority:
Estimated code review effort: 2 (Simple) | ~12 minutes
Change: Bug fix · Severity of issue fixed: Medium
Possibly related PRs
- pingdotgg/t3code#24638: Updates the earlier helper for the same Tailscale HTTPS row.
- pingdotgg/t3code#24890: Changes the setup dialog preview URL in the same Tailscale HTTPS setup flow.
- pingdotgg/t3code#23605: Changes Tailscale Serve retry and cleanup behavior along the activation path.
Suggested labels: bugfix, size:M
Suggested reviewers: mnigos, maria-rcks
Merge Risk: 
Minimal · up to 8250c
-
Users can open Tailscale HTTPS setup while Network access is off and confirm it without an endpoint. No merge-blocking issue was identified.
Pre-merge checks: 
4
-
Full details: Title check
-
Explanation
The title follows the conventional commit format and names the primary change: Tailscale HTTPS can now be turned on while Network access is off. It matches the raw summary, which adds an unchecked switch that opens the setup dialog without an endpoint when Network access and Serve are off. The title is 70 characters, within a reasonable length for a commit subject.
Full details: Description check
-
Explanation
The description follows the repository template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section gives the observed behavior, the environment, and the reproduction steps. The Change section explains the fix and why detection stays behind an explicit action. The Scope section links the issue and the accepted scope. The Verification section lists focused tests, the check run, and the Linux Electron evidence with before and after screenshots. It also lists what was not verified. The description states that the macOS privacy prompt and a successful Serve proxy were not verified. The template asks for a model and harness line, and the description includes one. Minor point: the Scope section links an issue (#26136) and a follow-up scope issue, which satisfies the requirement for a linked triaged issue.
Full details: Linked Issues check
-
Explanation
For
#26136, the whole-PR diff addsmissingTailscaleEndpointRowand tests the skipped-detection, unknown-state, Serve-enabled, and network-accessible cases. InConnectionsSettings.tsx, the skipped-detection case renders an unchecked switch, passes a nullable endpoint to the existing setup dialog, and keeps the existing Serve enable path. The diff does not change detection or add a contract, IPC, or desktop change. This preserves the explicit-action requirement and the no-prompt-by-default behavior from the contextual#18753scope.
Full details: Out of Scope Changes check
-
Explanation
The whole-PR diff changes only the Tailscale row logic, its dialog state needed for a nullable endpoint, and focused automated tests. These changes directly support
#26136. No unrelated behavior, contract, IPC, or desktop changes are present.
-
Finishing Touches
-
📝 Generate docstrings
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
|
Note 🤖 Claude Opus 5.5 responding on behalf of Theo Superseded by #26757, which folds in turning on Tailscale HTTPS while Network access is off. You are credited with a Co-authored-by trailer. Closing this so the two don't conflict. |
Problem
In the desktop app, Settings → Sharing & access, the Tailscale HTTPS row shows "Turn on Network access to detect Tailscale." and no switch while Network access is off. To get tailnet HTTPS without exposing the backend on LAN, a user has to turn Network access on (binds
0.0.0.0, relaunch), enable Tailscale HTTPS, then turn Network access off again (another relaunch). Reproduced on main5808469018in the Linux Electron app on a fresh database, with Tailscale running with MagicDNS and HTTPS.Change
When the desktop skipped Tailscale detection (Network access off, Serve off), the row now shows an unchecked switch. It opens the existing "Set up Tailscale HTTPS?" dialog without an endpoint, which shows its existing "Pending MagicDNS endpoint" fallback. Confirming calls the existing
setTailscaleServeEnabled({ enabled: true, port }). Detection still only runs after that explicit action, so the no-prompt-by-default behaviour from https://git.cafe/pingdotgg/t3code/pulls/2745 is unchanged.So that turning it on is not a one-way door: when Serve is on but no Tailscale HTTPS endpoint is found (Tailscale stopped), the row keeps a checked switch that opens the existing disable dialog. On main that state had no switch at all.
The row's decision lives in a pure helper,
missingTailscaleEndpointRow, inConnectionsSettings.logic.ts, replacingmissingTailscaleEndpointDescription. The setup dialog's open state no longer depends on having an endpoint. The branch where an endpoint exists is unchanged. No contract, IPC or desktop change.Scope and approval
Fixes #26136
Follow-up to the accepted scope on https://git.cafe/pingdotgg/t3code/issues/18753 ("offer an explicit on-demand action … keeps the no-prompt-by-default guarantee").
Verification
vp test run apps/web/src/components/settings/ConnectionsSettings.logic.test.ts: 11 pass. The fourmissingTailscaleEndpointRowcases cover detection skipped (unchecked switch, Serve copy), state unknown (no switch), Serve on with no endpoint (checked switch), and Network access on with nothing found (no switch, as on main).vp run check:changed: format, lint, knip, typecheck and tests pass.5808469018, after =d437f84d37(this branch before merging main).Evidence (1440×1000 dark; light and 840×620 in the full evidence index)
R3: Network access off, Serve off (the reported state)
5808469018
d437f84d37
5808469018 → d437f84d37
5808469018 → d437f84d37
S1: switch → setup dialog without an endpoint
5808469018
d437f84d37
5808469018 → d437f84d37
5808469018 → d437f84d37
R5: Serve on, no Tailscale endpoint (stopped-Tailscale CLI stub on PATH, real app). Before there is no way to turn Serve off; after there is a checked switch
5808469018
d437f84d37
5808469018 → d437f84d37
5808469018 → d437f84d37
O1: the checked switch opens the disable confirmation
5808469018
d437f84d37
5808469018 → d437f84d37
5808469018 → d437f84d37
R6 control: endpoint present (unavailable), unchanged code path. 0 changed pixels at threshold 0 in all four viewport/theme variants
5808469018
d437f84d37
5808469018 → d437f84d37
5808469018 → d437f84d37
Recordings (1440×1000 dark)
tailscaleServeEnabled:false:| Before recording · transcript · storyboard | After recording · transcript · storyboard |
127.0.0.1, Network access off, Tailscale HTTPS endpoint detected:| Before recording · transcript · storyboard | After recording · transcript · storyboard |
| Before recording · transcript · storyboard | After recording · transcript · storyboard |
Scripts: launch.sh · driver.mjs · flows.mjs · seed.mjs. Environment: Electron 44.9.3 / Chromium 152, Xvfb, DPR 1, no emulation; 840×620 is Electron's minimum usable window.
What else changed: at 840 px the new switch stacks under the row text, moving Permissions and Authorized clients down 30 px and adding a scrollbar. S12's post-Cancel frames differ by 1–2/255 on 22–29 panel-corner pixels, which disappear at threshold 8.
Not verified:
cannot-verify macos: the macOS privacy prompt itself. By code, the CLI is spawned only after Enable setstailscaleServeEnabled.tailscale servefails with permission-denied and the detected endpoint staysunavailable.Implemented with Claude Opus 5.5, reviewed with GPT-6.1 Sol and Claude Opus 5.5, evidence by GPT-6.1 Sol, coordinated by Claude Opus 5.5 in T3 Code (Claude Code harness).
🤖 Generated with Claude Code