From 11c9505b5a35b5ee37edfe455a8946147d062f2f Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Sun, 25 Jan 2026 12:06:43 -0300 Subject: [PATCH 1/2] fix: remove hardcoded default server URL from mobile app Users now set the server URL during first login instead of having a hardcoded default. Also fixed missing import for authStorage functions. --- ushadow/mobile/app/_utils/authStorage.ts | 13 ++++++++----- ushadow/mobile/app/components/LoginScreen.tsx | 7 ++++++- ushadow/mobile/app/config.ts | 6 +++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ushadow/mobile/app/_utils/authStorage.ts b/ushadow/mobile/app/_utils/authStorage.ts index d69ee18d..b4ff2d4f 100644 --- a/ushadow/mobile/app/_utils/authStorage.ts +++ b/ushadow/mobile/app/_utils/authStorage.ts @@ -7,7 +7,6 @@ */ import AsyncStorage from '@react-native-async-storage/async-storage'; -import AppConfig from '../config'; const AUTH_TOKEN_KEY = '@ushadow_auth_token'; const API_URL_KEY = '@ushadow_api_url'; @@ -143,7 +142,8 @@ export function appendTokenToUrl(wsUrl: string, token: string): string { /** * Get the default server URL. - * Returns user-configured default if set, otherwise returns app config default. + * Returns user-configured default if set, otherwise returns empty string. + * Users set this during their first login via the "Save as default" checkbox. */ export async function getDefaultServerUrl(): Promise { try { @@ -154,7 +154,9 @@ export async function getDefaultServerUrl(): Promise { } catch (error) { console.error('[AuthStorage] Failed to get default server URL:', error); } - return AppConfig.DEFAULT_SERVER_URL; + // Return empty string if no default is configured + // This prompts users to enter their server URL on first use + return ''; } /** @@ -172,7 +174,8 @@ export async function setDefaultServerUrl(url: string): Promise { } /** - * Clear the custom default server URL (revert to app config default). + * Clear the custom default server URL. + * After clearing, users will need to enter the URL manually on next login. */ export async function clearDefaultServerUrl(): Promise { try { @@ -186,7 +189,7 @@ export async function clearDefaultServerUrl(): Promise { /** * Get the effective server URL to use. - * Priority: stored API URL > custom default > app config default + * Priority: stored API URL from login > saved default server URL > empty string */ export async function getEffectiveServerUrl(): Promise { // First check if there's a stored API URL from login diff --git a/ushadow/mobile/app/components/LoginScreen.tsx b/ushadow/mobile/app/components/LoginScreen.tsx index 3ebaccc3..cf6732c0 100644 --- a/ushadow/mobile/app/components/LoginScreen.tsx +++ b/ushadow/mobile/app/components/LoginScreen.tsx @@ -25,7 +25,12 @@ import { ScrollView, } from 'react-native'; import { colors, theme, spacing, borderRadius, fontSize } from '../theme'; -import { saveAuthToken, saveApiUrl } from '../_utils/authStorage'; +import { + saveAuthToken, + saveApiUrl, + getDefaultServerUrl, + setDefaultServerUrl, +} from '../_utils/authStorage'; interface LoginScreenProps { visible: boolean; diff --git a/ushadow/mobile/app/config.ts b/ushadow/mobile/app/config.ts index d668c4f8..c4afe7d2 100644 --- a/ushadow/mobile/app/config.ts +++ b/ushadow/mobile/app/config.ts @@ -8,13 +8,13 @@ export const AppConfig = { /** * Default server URL. - * This is used as the initial value when the app is first installed. - * Users can change this in the login screen. + * Empty by default - users set this during first login. + * Once set, it's persisted in AsyncStorage and used for future logins. * * Format: https://{your-tailscale-host} * Example: https://blue.spangled-kettle.ts.net */ - DEFAULT_SERVER_URL: 'https://ushadow.wolf-tawny.ts.net', + DEFAULT_SERVER_URL: '', /** * App version info From efdcf27a40af471aa99e453997e95ec55483d753 Mon Sep 17 00:00:00 2001 From: Petr Korolev Date: Sun, 25 Jan 2026 12:14:08 -0300 Subject: [PATCH 2/2] feat: read default server URL from env variable - Add EXPO_PUBLIC_DEFAULT_SERVER_URL env var support - Create .env.example for documentation - Update README with build configuration instructions --- ushadow/mobile/.env.example | 11 ++++++++ ushadow/mobile/README.md | 32 ++++++++++++++++++++++++ ushadow/mobile/app/_utils/authStorage.ts | 12 +++++---- ushadow/mobile/app/config.ts | 16 +++++++++--- 4 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 ushadow/mobile/.env.example diff --git a/ushadow/mobile/.env.example b/ushadow/mobile/.env.example new file mode 100644 index 00000000..37048cce --- /dev/null +++ b/ushadow/mobile/.env.example @@ -0,0 +1,11 @@ +# Ushadow Mobile App Environment Variables +# Copy this file to .env and customize for your build +# +# Note: Variables must be prefixed with EXPO_PUBLIC_ to be accessible in the app + +# Default server URL (optional) +# If set, this will pre-fill the server URL field on first login +# Users can still change it during login +# Format: https://{your-tailscale-host} +# Example: https://blue.spangled-kettle.ts.net +EXPO_PUBLIC_DEFAULT_SERVER_URL= diff --git a/ushadow/mobile/README.md b/ushadow/mobile/README.md index b1ed8e86..abe6f19b 100644 --- a/ushadow/mobile/README.md +++ b/ushadow/mobile/README.md @@ -44,6 +44,38 @@ eas build --profile preview --platform ios # Requires Apple Developer accou --- +## Build Configuration + +### Setting a Default Server URL (Optional) + +You can pre-configure a default server URL that will be filled in automatically when users first open the app. This is useful when distributing the app to your team. + +**Option 1: Environment Variable (Recommended)** + +Create a `.env` file in the `ushadow/mobile/` directory: + +```bash +# Copy the example file +cp .env.example .env + +# Edit with your server URL +echo 'EXPO_PUBLIC_DEFAULT_SERVER_URL=https://your-server.ts.net' > .env +``` + +Then build the app normally. The URL will be embedded at build time. + +**Option 2: EAS Build Secrets** + +For EAS builds, set the environment variable in your EAS secrets: + +```bash +eas secret:create --name EXPO_PUBLIC_DEFAULT_SERVER_URL --value "https://your-server.ts.net" +``` + +**Note:** Users can always change the server URL during login, even if a default is set. The URL they use is saved for future logins. + +--- + ## Detailed Setup Instructions ### Prerequisites diff --git a/ushadow/mobile/app/_utils/authStorage.ts b/ushadow/mobile/app/_utils/authStorage.ts index b4ff2d4f..f881de3c 100644 --- a/ushadow/mobile/app/_utils/authStorage.ts +++ b/ushadow/mobile/app/_utils/authStorage.ts @@ -7,6 +7,7 @@ */ import AsyncStorage from '@react-native-async-storage/async-storage'; +import AppConfig from '../config'; const AUTH_TOKEN_KEY = '@ushadow_auth_token'; const API_URL_KEY = '@ushadow_api_url'; @@ -142,8 +143,10 @@ export function appendTokenToUrl(wsUrl: string, token: string): string { /** * Get the default server URL. - * Returns user-configured default if set, otherwise returns empty string. - * Users set this during their first login via the "Save as default" checkbox. + * Priority: + * 1. User-saved default (from "Save as default" checkbox) + * 2. Build-time default from EXPO_PUBLIC_DEFAULT_SERVER_URL env var + * 3. Empty string (user must enter URL manually) */ export async function getDefaultServerUrl(): Promise { try { @@ -154,9 +157,8 @@ export async function getDefaultServerUrl(): Promise { } catch (error) { console.error('[AuthStorage] Failed to get default server URL:', error); } - // Return empty string if no default is configured - // This prompts users to enter their server URL on first use - return ''; + // Fall back to build-time default from env var (or empty string) + return AppConfig.DEFAULT_SERVER_URL; } /** diff --git a/ushadow/mobile/app/config.ts b/ushadow/mobile/app/config.ts index c4afe7d2..984140da 100644 --- a/ushadow/mobile/app/config.ts +++ b/ushadow/mobile/app/config.ts @@ -2,19 +2,27 @@ * App Configuration * * Central configuration for the Ushadow mobile app. - * The default server URL can be changed here or overridden by the user during setup. + * Configuration is read from environment variables at build time. + * + * To set a default server URL for your build: + * 1. Create a .env file in ushadow/mobile/ + * 2. Add: EXPO_PUBLIC_DEFAULT_SERVER_URL=https://your-server.ts.net + * 3. Build the app + * + * See README.md for more details. */ export const AppConfig = { /** * Default server URL. - * Empty by default - users set this during first login. - * Once set, it's persisted in AsyncStorage and used for future logins. + * Read from EXPO_PUBLIC_DEFAULT_SERVER_URL environment variable. + * If not set, users enter the URL manually during first login. + * Once logged in, the URL is persisted in AsyncStorage. * * Format: https://{your-tailscale-host} * Example: https://blue.spangled-kettle.ts.net */ - DEFAULT_SERVER_URL: '', + DEFAULT_SERVER_URL: process.env.EXPO_PUBLIC_DEFAULT_SERVER_URL || '', /** * App version info