Client Configuration
Client API Configuration Guide
Multi-Platform Client Configuration for web, desktop, and mobile applications
Overview
All three client applications (web, desktop, mobile) use similar patterns but with platform-specific implementations:
- Hardcoded default to localhost:8080 for development
- Runtime configuration via settings screens for production deployments
- Persistent configuration storage using platform-appropriate mechanisms
- No server discovery mechanisms - manual configuration only
- Separate WebSocket endpoint configuration for real-time features
Configuration by Client Type
1. Web Client (/web-client)
API Service Configuration:
- Default URLs:
http://localhost:8080(API),ws://localhost:8080(WebSocket) - Configuration Storage: Browser localStorage (
incident-web-config) - Configuration Interface: Comprehensive settings UI with form validation
- Proxy Setup: Vite dev server proxies
/api,/ws,/sseto localhost:8080
Key Features:
- Runtime URL validation
- Connection testing capabilities
- WebSocket status monitoring
- Auth token management with automatic retry logic
- OIDC provider support with callback handling
Configuration Schema:
interface AppConfig {
apiBaseUrl: string; // Default: 'http://localhost:8080'
wsBaseUrl: string; // Default: 'ws://localhost:8080'
notificationsEnabled: boolean;
theme: "light" | "dark" | "system";
refreshInterval: number; // Default: 30000ms
dateFormat: string;
}Authentication Architecture:
// JWT Token Management
setAuthToken(token: string): void
clearAuthToken(): void
getAuthToken(): string | null
isTokenExpired(): boolean
// OIDC Integration
initiateOIDCLogin(provider: string): void
handleOIDCCallback(code: string, state: string): Promise<void>2. Desktop Client (/desktop)
Tauri-Based Configuration:
- Default URLs: Same as web client (
http://localhost:8080) - Configuration Storage: Tauri’s
app-data-dirwith JSON config file - Configuration Interface: React-based settings screen using desktop components
- Native Features: System notifications, tray integration, auto-launch
Desktop-Specific Features:
- Deep linking support for incident URLs
- System notification handling with click-to-action
- Auto-launch configuration for startup behavior
- Native file system access for log exports
Configuration File Location:
# macOS
~/Library/Application Support/com.incidents.app/config.json
# Windows
%APPDATA%/com.incidents.app/config.json
# Linux
~/.config/com.incidents.app/config.jsonConfiguration Schema:
{
"apiBaseUrl": "http://localhost:8080",
"wsBaseUrl": "ws://localhost:8080",
"notifications": {
"enabled": true,
"sound": true,
"showInTray": true
},
"window": {
"startMinimized": false,
"minimizeToTray": true
},
"autoLaunch": false
}3. Mobile Client (/mobile)
React Native Configuration:
- Default URLs: Same localhost pattern for development
- Configuration Storage: React Native AsyncStorage
- Configuration Interface: Native mobile settings screens
- Push Notifications: Expo push notification integration
Mobile-Specific Features:
- Push notification registration with server sync
- Offline incident caching for connectivity gaps
- Biometric authentication for secure access
- Background refresh for incident updates
Configuration Interface:
// AsyncStorage key patterns
const CONFIG_KEYS = {
API_BASE_URL: '@incidents:apiBaseUrl',
WS_BASE_URL: '@incidents:wsBaseUrl',
NOTIFICATION_TOKEN: '@incidents:pushToken',
AUTH_TOKEN: '@incidents:authToken',
BIOMETRIC_ENABLED: '@incidents:biometricAuth'
};
// Configuration methods
export const ConfigService = {
async setApiUrl(url: string): Promise<void>
async getApiUrl(): Promise<string>
async setNotificationToken(token: string): Promise<void>
async enableBiometrics(enabled: boolean): Promise<void>
};Common Configuration Patterns
Environment-Based Defaults
All clients support environment-specific defaults:
const getDefaultApiUrl = (): string => {
const env = process.env.NODE_ENV || "development";
switch (env) {
case "development":
return "http://localhost:8080";
case "staging":
return "https://staging-api.incidents.example.com";
case "production":
return "https://api.incidents.example.com";
default:
return "http://localhost:8080";
}
};Connection Testing
All clients implement server connectivity testing:
interface ConnectionTest {
url: string;
status: "testing" | "success" | "failed";
latency?: number;
error?: string;
}
const testConnection = async (baseUrl: string): Promise<ConnectionTest> => {
const start = Date.now();
try {
const response = await fetch(`${baseUrl}/health`, {
method: "GET",
timeout: 5000
});
if (response.ok) {
return {
url: baseUrl,
status: "success",
latency: Date.now() - start
};
}
return {
url: baseUrl,
status: "failed",
error: `HTTP ${response.status}: ${response.statusText}`
};
} catch (error) {
return {
url: baseUrl,
status: "failed",
error: error.message
};
}
};Authentication Token Management
Consistent token handling across all platforms:
interface AuthTokenManager {
// Token storage
setToken(token: string): Promise<void>;
getToken(): Promise<string | null>;
clearToken(): Promise<void>;
// Token validation
isTokenValid(): Promise<boolean>;
refreshToken(): Promise<string>;
// Auth state
onTokenExpired(callback: () => void): void;
onAuthRequired(callback: () => void): void;
}Production Deployment Configuration
Server-Side Configuration Discovery
For production deployments, consider implementing server configuration discovery:
// Optional: Server configuration endpoint
GET /api/v1/config/client
Response:
{
"apiVersion": "v1",
"endpoints": {
"api": "https://api.incidents.example.com",
"websocket": "wss://api.incidents.example.com/ws",
"sse": "https://api.incidents.example.com/sse"
},
"features": {
"oidcEnabled": true,
"pushNotificationsEnabled": true,
"realtimeEnabled": true
},
"oidc": {
"providers": ["okta", "azure", "google"]
}
}Environment Variable Override
Support environment variable configuration for containerized deployments:
const config = {
apiBaseUrl: process.env.REACT_APP_API_URL || "http://localhost:8080",
wsBaseUrl: process.env.REACT_APP_WS_URL || "ws://localhost:8080",
oidcClientId: process.env.REACT_APP_OIDC_CLIENT_ID,
oidcAuthority: process.env.REACT_APP_OIDC_AUTHORITY
};Docker Deployment Configuration
Configure clients for Docker deployments:
# Web client environment
ENV REACT_APP_API_URL=https://api.incidents.example.com
ENV REACT_APP_WS_URL=wss://api.incidents.example.com/ws
ENV REACT_APP_OIDC_AUTHORITY=https://auth.incidents.example.com
# Build with environment variables
RUN npm run buildSecurity Considerations
Token Storage Security
Web Client:
- Store JWT tokens in httpOnly cookies when possible
- Use secure localStorage with encryption for sensitive data
- Clear tokens on tab close or browser shutdown
Desktop Client:
- Use Tauri’s secure storage APIs
- Encrypt configuration files containing sensitive data
- Support OS-level keychain/credential manager integration
Mobile Client:
- Use React Native Keychain for secure token storage
- Enable biometric authentication for token access
- Support device encryption requirements
API Endpoint Validation
All clients should validate API endpoints:
const validateApiUrl = (url: string): boolean => {
try {
const parsed = new URL(url);
// Require HTTPS in production
if (process.env.NODE_ENV === "production" && parsed.protocol !== "https:") {
return false;
}
// Validate hostname format
if (!parsed.hostname || (parsed.hostname === "localhost" && process.env.NODE_ENV === "production")) {
return false;
}
return true;
} catch {
return false;
}
};Troubleshooting
Common Configuration Issues
Connection Failures:
Error: Network request failed- Verify API server is running and accessible
- Check firewall/proxy settings
- Validate API URL format and protocol
Authentication Issues:
Error: 401 Unauthorized- Check JWT token expiration
- Verify OIDC provider configuration
- Confirm user permissions
WebSocket Connection Problems:
Error: WebSocket connection failed- Verify WebSocket URL format (ws:// or wss://)
- Check proxy configuration for WebSocket support
- Confirm server WebSocket endpoint is enabled
Debug Configuration
Enable debug logging for configuration issues:
// Debug configuration loading
console.log("Loading configuration:", {
apiBaseUrl: config.apiBaseUrl,
wsBaseUrl: config.wsBaseUrl,
authEnabled: !!config.authToken,
storageAvailable: typeof Storage !== "undefined"
});
// Test connectivity
testConnection(config.apiBaseUrl)
.then((result) => console.log("Connection test:", result))
.catch((error) => console.error("Connection test failed:", error));Configuration Migration
Version Compatibility
Handle configuration schema changes gracefully:
const migrateConfig = (storedConfig: any): AppConfig => {
// Handle legacy configuration formats
if (storedConfig.version === 1) {
return {
...storedConfig,
apiBaseUrl: storedConfig.serverUrl, // Renamed field
version: 2
};
}
return storedConfig;
};Configuration Reset
Provide configuration reset functionality:
const resetConfiguration = async (): Promise<void> => {
// Clear stored configuration
await AsyncStorage.multiRemove([CONFIG_KEYS.API_BASE_URL, CONFIG_KEYS.WS_BASE_URL, CONFIG_KEYS.AUTH_TOKEN]);
// Reload default configuration
window.location.reload(); // Web
// or app restart for desktop/mobile
};Related Documentation:
- API Reference - Complete API endpoint documentation
- Authentication Guide - JWT and OIDC authentication setup
- WebSocket API - Real-time WebSocket API reference
- Deployment Guide - Production deployment configuration