feat: add more security enviroment variable based settings

This commit is contained in:
Patryk Hegenberg 2026-01-04 18:54:24 +01:00
parent fc3e1d98ef
commit 940f73809c
4 changed files with 147 additions and 2 deletions

View file

@ -3,10 +3,20 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'src/app.dart';
import 'src/shared/data/local/app_database.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
try {
await dotenv.load(fileName: '.env');
debugPrint('✅ Environment loaded: ${dotenv.env['ENVIRONMENT']}');
debugPrint('✅ API URL: ${dotenv.env['API_BASE_URL']}');
} catch (e) {
debugPrint('⚠️ Could not load .env file: $e');
debugPrint('⚠️ Using default production values');
}
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,

View file

@ -1,10 +1,36 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
class AppConstants {
// API Configuration aus Environment
static String get apiBaseUrl =>
dotenv.env['API_BASE_URL'] ?? 'https://slift.patanix.de';
static String get apiVersion => dotenv.env['API_VERSION'] ?? 'v1';
static String get environment => dotenv.env['ENVIRONMENT'] ?? 'production';
static bool get isDebugMode =>
dotenv.env['DEBUG_MODE']?.toLowerCase() == 'true';
// Helper Getter
static bool get isDevelopment => environment == 'development';
static bool get isProduction => environment == 'production';
// Debug Info
static void printConfig() {
debugPrint('═══════════════════════════════════');
debugPrint('🔧 APP CONFIGURATION');
debugPrint('Environment: $environment');
debugPrint('API Base URL: $apiBaseUrl');
debugPrint('API Version: $apiVersion');
debugPrint('Debug Mode: $isDebugMode');
debugPrint('═══════════════════════════════════');
}
// API Configuration
// static const String apiBaseUrl = 'http://10.0.2.2:8090'; // Android emulator
static const String apiBaseUrl = 'https://slift.patanix.de';
static const String apiVersion = 'v1';
// static const String apiBaseUrl = 'https://slift.patanix.de';
// static const String apiVersion = 'v1';
// Wendler 5/3/1 Constants
static const double trainingMaxPercentage = 0.9;

View file

@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import '../constants/app_constants.dart';
import '../theme/app_theme.dart';
class DebugConfigScreen extends StatelessWidget {
const DebugConfigScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('🔧 Configuration'),
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildSection(
'Environment',
[
_buildRow('Environment', AppConstants.environment),
_buildRow('Debug Mode', AppConstants.isDebugMode.toString()),
_buildRow(
'Is Development', AppConstants.isDevelopment.toString()),
_buildRow('Is Production', AppConstants.isProduction.toString()),
],
),
const SizedBox(height: 16),
_buildSection(
'API Configuration',
[
_buildRow('Base URL', AppConstants.apiBaseUrl),
_buildRow('API Version', AppConstants.apiVersion),
],
),
const SizedBox(height: 16),
_buildSection(
'All Environment Variables',
dotenv.env.entries.map((e) => _buildRow(e.key, e.value)).toList(),
),
],
),
);
}
Widget _buildSection(String title, List<Widget> children) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppTheme.primaryColor,
),
),
const Divider(),
...children,
],
),
),
);
}
Widget _buildRow(String key, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 120,
child: Text(
key,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey,
),
),
),
Expanded(
child: Text(
value,
style: const TextStyle(color: Colors.white),
),
),
],
),
);
}
}

View file

@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../../core/constants/app_constants.dart';
import '../../../../core/debug/debug_config_screen.dart';
import '../../../../core/theme/app_theme.dart';
import '../../../../shared/data/local/app_database.dart';
import '../../../../shared/data/repositories/user_repository.dart';
@ -292,6 +294,17 @@ class _HubScreenState extends ConsumerState<HubScreen> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (AppConstants.isDevelopment)
IconButton(
icon: const Icon(Icons.settings),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const DebugConfigScreen(),
),
),
),
IconButton(
icon: const Icon(Icons.person_outline),
onPressed: () => context.go('/profile'),