diff --git a/CHANGELOG.md b/CHANGELOG.md index af97534..539b0e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- API defaults now use LAN IPs for local development (no auth required) +- Auth interceptor skips authentication when using LAN endpoints + ## [0.3.0] - 2025-12-30 ### Added diff --git a/lib/core/api/api_interceptors.dart b/lib/core/api/api_interceptors.dart index 2973596..135d292 100644 --- a/lib/core/api/api_interceptors.dart +++ b/lib/core/api/api_interceptors.dart @@ -4,9 +4,12 @@ import 'package:dio/dio.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../auth/auth_provider.dart'; +import '../config/app_config.dart'; import '../error/app_exception.dart'; /// Adds authentication token to requests. +/// +/// Skipped entirely when [AppConfig.requiresAuth] is false (LAN development). class AuthInterceptor extends Interceptor { AuthInterceptor(this._ref); @@ -14,6 +17,12 @@ class AuthInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { + // Skip auth for LAN development + if (!AppConfig.requiresAuth) { + handler.next(options); + return; + } + final authState = _ref.read(authNotifierProvider); authState.whenData((auth) { @@ -27,6 +36,12 @@ class AuthInterceptor extends Interceptor { @override void onError(DioException err, ErrorInterceptorHandler handler) { + // Skip auth error handling for LAN development + if (!AppConfig.requiresAuth) { + handler.next(err); + return; + } + if (err.response?.statusCode == 401) { // Token expired - trigger re-authentication _ref.read(authNotifierProvider.notifier).signOut(); diff --git a/lib/core/config/app_config.dart b/lib/core/config/app_config.dart index 76946be..4fefa51 100644 --- a/lib/core/config/app_config.dart +++ b/lib/core/config/app_config.dart @@ -1,19 +1,35 @@ /// Application configuration from compile-time environment variables. /// -/// Set via: flutter build --dart-define=API_URL=https://... +/// ## Development (LAN - no auth required) +/// Default values use LAN IPs for local development: +/// ```bash +/// flutter run -d chrome +/// ``` +/// +/// ## Production (public URLs - auth required) +/// Override with public URLs for production builds: +/// ```bash +/// flutter build web \ +/// --dart-define=CORE_API_URL=https://api.schweitz.net \ +/// --dart-define=TATLOCK_API_URL=https://tatlock.schweitz.net +/// ``` class AppConfig { AppConfig._(); /// Core API base URL + /// - LAN default: No auth required + /// - Production: https://api.schweitz.net (requires OIDC) static const coreApiUrl = String.fromEnvironment( 'CORE_API_URL', - defaultValue: 'https://api.schweitz.net', + defaultValue: 'http://192.168.86.149:8083', ); /// Tatlock API base URL + /// - LAN default: No auth required + /// - Production: https://tatlock.schweitz.net (requires OIDC) static const tatlockApiUrl = String.fromEnvironment( 'TATLOCK_API_URL', - defaultValue: 'https://tatlock.schweitz.net', + defaultValue: 'http://192.168.86.149:8000', ); /// Authentik OIDC discovery URL @@ -37,4 +53,9 @@ class AppConfig { /// Whether running in debug mode static const isDebug = bool.fromEnvironment('DEBUG', defaultValue: false); + + /// Whether auth is required (false for LAN development) + static bool get requiresAuth => + coreApiUrl.contains('schweitz.net') || + tatlockApiUrl.contains('schweitz.net'); }