Skip to content

Conversation

@chrisvanbuskirk
Copy link

Fix Tailscale Integration and Add Complete iOS Support

Summary

This PR comprehensively fixes Tailscale integration issues introduced in Release 15 and adds full Tailscale support to the iOS companion app, enabling secure remote access to VibeTunnel servers from mobile devices.

Changes Overview

🐛 Bug Fixes (macOS)

Release 15 Regression Fix

  • Fixed server binding issue that prevented network access (was incorrectly forced to localhost only)
  • Fixed exit code 0 being incorrectly treated as an error, causing false failure states
  • Fixed Tailscale toggle auto-disabling after 10 seconds
  • Added clear fallback mode messaging for users

Tailscale CLI Compatibility

  • Updated to support new Tailscale CLI --bg (background) flag syntax
  • Fixed Tailscale Funnel command to preserve proxy destination (http://localhost:4020)
  • Added support for multiple Tailscale binary locations (/Applications, /opt/homebrew, /usr/local)
  • Enhanced IP validation to handle error messages from tailscale ip command gracefully

URL Display and Status Handling

  • Fixed HTTPS prefix display for public Funnel URLs in menu bar
  • Added proper display of both Public and Private URLs in settings when Funnel is enabled
  • Implemented fallback mechanisms when Funnel is enabled but not working
  • Fixed crash by properly adding TailscaleServeStatusService to environment
  • Updated menu labels to show accurate status: (Public/Private/Error/Starting)

✨ New Features

Complete iOS Tailscale Integration

  • Full OAuth-based authentication with Tailscale API
  • Automatic discovery of VibeTunnel servers on your tailnet
  • Smart connection mode switching between HTTPS (Public/Funnel) and HTTP (Private/Serve)
  • Visual indicators (🔒/🔓) showing connection security status
  • Comprehensive settings UI with three key switches:
    • Auto-Discover Servers: Automatically find VibeTunnel servers on Tailscale network
    • Prefer Tailscale Connections: Choose Tailscale over local when both are available
    • Auto-Refresh Discovery: Check for new/changed servers every 30 seconds

Public/Private Mode Support (macOS & iOS)

  • Private Mode (Default): Secure HTTPS access within your Tailscale network only
  • Public Mode: Internet-accessible via Tailscale Funnel with automatic HTTPS
  • Seamless mode transitions with automatic fallback from HTTPS to HTTP
  • Health checks on app startup to verify server capabilities
  • Automatic profile updates based on current server status

🔧 Technical Improvements

Code Quality

  • Fixed all critical SwiftLint warnings (force unwrapping, data conversion)
  • Removed 46+ verbose logging statements for cleaner output
  • Set default web server logger to ERROR level
  • Added proper error handling and validation throughout
  • Updated all tests to match new API requirements (305/326 tests passing)

Security

  • Added SSL certificate patterns to .gitignore to prevent accidental commits
  • Implemented WebSocket authentication for Tailscale users
  • Secure credential storage using iOS Keychain

📚 Documentation

  • Created comprehensive Tailscale integration guide at ios/docs/tailscale-guide.md
  • Updated README with clear explanations of fallback mode behavior
  • Documented OAuth setup process with step-by-step instructions
  • Added troubleshooting section for common connection issues

Testing

Test Coverage

  • Added TailscaleFallbackRegressionTests.swift for regression prevention
  • Added tailscale-regression.test.ts for server-side validation
  • Added tailscale-serve-service.test.ts for service testing
  • Added E2E tests in tailscale-regression.spec.ts
  • All iOS tests pass: 305 passed, 21 skipped, 0 failed

Manual Testing Performed

  • ✅ Tailscale Private mode (HTTP within tailnet)
  • ✅ Tailscale Public mode (HTTPS via Funnel)
  • ✅ Mode transitions and automatic fallback
  • ✅ iOS OAuth authentication flow
  • ✅ Server discovery and connection from iOS
  • ✅ Settings navigation and configuration
  • ✅ Credential reset and UI state clearing

Migration Guide

For users upgrading from Release 15:

  1. The Tailscale integration will automatically detect your configuration
  2. iOS users need to obtain OAuth credentials from Tailscale Admin Console
  3. No action required for existing Direct Access users - it continues to work

Breaking Changes

None. This PR maintains full backward compatibility while fixing existing issues.

Screenshots

Note: The iOS app now shows visual indicators for connection security (lock icons) and properly opens Settings to the Tailscale tab when accessing from Tailscale-related buttons.

Related Issues

Fixes the Tailscale regression introduced in Release 15 where direct Tailscale access was broken.


Co-authored-by: Claude noreply@anthropic.com

- Fix server binding to allow network access (not forced to localhost)
- Fix exit code 0 being incorrectly treated as error
- Fix toggle auto-disabling after 10 seconds
- Add clear fallback mode messaging for users
- Update to new Tailscale CLI syntax (--bg flag)
- Add WebSocket authentication for Tailscale users
- Implement smooth mode detection and status reporting
- Fix race conditions during mode transitions
The funnel command was incorrectly using 'tailscale funnel --bg 443' which
overrode the proxy destination to http://127.0.0.1:443 instead of keeping
it pointed at http://localhost:4020.

Fixed by using: tailscale funnel --bg --https=443 http://localhost:4020

This ensures Funnel preserves the correct proxy target when enabling
public access mode.
- Add TailscaleURLHelper with IP validation and fallback mechanisms
- Support multiple Tailscale binary locations
- Implement URL construction for private vs public Funnel modes
- Add auto-start monitoring in TailscaleServeStatusService
- Show https:// prefix for public Funnel URLs in menu bar
- Display both Public and Private URLs when Funnel enabled
- Add status indicators (Public/Private/Error/Starting)
- Fix TailscaleServeStatusService environment integration
- Implement OAuth-based authentication with Tailscale API
- Add automatic server discovery on tailnet
- Create comprehensive Tailscale settings UI
- Add three key switches: Auto-Discover, Prefer Tailscale, Auto-Refresh
- Implement HTTPS to HTTP fallback for mode transitions
- Add visual lock/unlock indicators for connection security
- Create detailed integration guide at ios/docs/tailscale-guide.md
- Add notification when Tailscale credentials are cleared
- Update ServerListView to observe credential clear notification
- Force UI refresh in TailscaleSettingsView after reset
- Ensure discovered servers disappear from home screen after reset
- Fix device count to clear when configuration is reset
- Fix Tailscale settings navigation to open correct tab when accessed from Tailscale buttons
- Fix Tailscale reset to properly remove saved servers from UI
- Remove excessive debug logging throughout the app
- Fix all critical linting warnings (force unwrapping, data conversion)
- Update tests to match new TailscaleServer API with httpsUrl and isPublic parameters
- Clean up notification handling for credential clearing

All tests pass (305/326 passed, 21 skipped)
@chrisvanbuskirk
Copy link
Author

chrisvanbuskirk commented Sep 1, 2025

@steipete I did quite a bunch of work on Tailscale on the server and iOS app. First, I fixed the regression in release 15. The server app supports public internet and private Tailnet support. Funnel was added to public internet support, and also includes SSL for secure connections if enabled. The iOS app supports creating an OAuth connection to Tailscale and discovering and adding Vibetunnel servers. I didn't touch the web app, but in the future it may benefit from the changes on the iOS version. There seems to be a bug in Bonjour discovery in the iOS app, but that's not the work I intended here. Anyhow, I'm stopping here until I see a response. I get it and know you are futzing around with that Twitter app trying to ship, but it would be nice for you to review when you get the oppurtunity. I'm going to try and ship a few things myself.

- Fix Tailscale server not being saved when Add button tapped in Settings
- Correct storage key from "serverProfiles" to "savedServerProfiles"
- Add automatic settings dismissal after adding Tailscale server
- Refresh profiles on settings dismissal to show newly added servers
- Remove debug logging added during troubleshooting
- Fix SwiftLint for-where violation in TailscaleURLHelper
- Fix force unwrapping violation in IP validation logic

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant