From a79cfadf517b3bb11aa57cf6ff1ba98bb1969308 Mon Sep 17 00:00:00 2001 From: Vusa Date: Wed, 24 Jun 2026 00:59:19 +0200 Subject: [PATCH] minor fixes --- .vscode/launch.json | 3 +- Dockerfile | 7 ++- {assets => config}/.env | 0 {assets => config}/.env.live | 0 {assets => config}/.env.test | 0 lib/config/app_config.dart | 53 +++++++++++++++++++++ lib/http/http.dart | 4 +- lib/interop.dart | 8 +--- lib/main.dart | 18 +------ lib/screens/gateway/gateway_screen.dart | 4 +- lib/screens/gateway/gateway_web_screen.dart | 6 +-- pubspec.lock | 8 ---- pubspec.yaml | 1 - 13 files changed, 70 insertions(+), 42 deletions(-) rename {assets => config}/.env (100%) rename {assets => config}/.env.live (100%) rename {assets => config}/.env.test (100%) create mode 100644 lib/config/app_config.dart diff --git a/.vscode/launch.json b/.vscode/launch.json index 2bd70d1..99370a7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,8 @@ "deviceId": "chrome", "args": [ "--dart-define=APP_ENV=test", - "--web-port=9005" + "--web-port=9005", + "--dart-define=BASE_URL=http://localhost:6950/api" ] }, diff --git a/Dockerfile b/Dockerfile index d421854..bd2d71c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,12 @@ WORKDIR $APP # Run build: 1 - clean, 2 - pub get, 3 - build web RUN flutter clean RUN flutter pub get -RUN flutter build web --dart-define=APP_ENV=live +RUN flutter build web \ + --dart-define=APP_ENV=live \ + --dart-define=BASE_URL=https://payapi.velocityafrica.net/api \ + --dart-define=CLIENTID=77433712483-ng7pntvcpf6tnjccriuqm8dbna8vvp3b.apps.googleusercontent.com \ + --dart-define=SIMULATE_PAYMENT_SUCCESS=false \ + --dart-define=GATEWAY_SCRIPT_URL=https://na.gateway.mastercard.com/static/checkout/checkout.min.js # once heare the app will be compiled and ready to deploy diff --git a/assets/.env b/config/.env similarity index 100% rename from assets/.env rename to config/.env diff --git a/assets/.env.live b/config/.env.live similarity index 100% rename from assets/.env.live rename to config/.env.live diff --git a/assets/.env.test b/config/.env.test similarity index 100% rename from assets/.env.test rename to config/.env.test diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart new file mode 100644 index 0000000..5fa0d13 --- /dev/null +++ b/lib/config/app_config.dart @@ -0,0 +1,53 @@ +/// Application configuration sourced entirely from compile-time +/// `--dart-define` flags. No `.env` file is read at runtime, so no +/// secrets can leak into the web bundle via asset files. +/// +/// Every value has a sensible default so the project still builds and +/// runs locally without specifying any flags. +class AppConfig { + AppConfig._(); + + // ----------------------------------------------------------------- + // Compile-time values (set via `--dart-define==`) + // ----------------------------------------------------------------- + + /// Runtime environment: `test`, `live`, etc. + static const String env = String.fromEnvironment( + 'APP_ENV', + defaultValue: 'test', + ); + + /// Base URL of the backend API. + static const String baseUrl = String.fromEnvironment( + 'BASE_URL', + defaultValue: 'http://localhost:6950/api', + ); + + /// Google OAuth web client ID. This is *not* a secret — it is + /// intended to be embedded in public-facing web applications. + static const String clientId = String.fromEnvironment( + 'CLIENTID', + defaultValue: '', + ); + + /// When `true` the payment gateway screens skip the real flow and + /// return a simulated success immediately. Useful during development. + static const bool simulatePaymentSuccess = bool.fromEnvironment( + 'SIMULATE_PAYMENT_SUCCESS', + defaultValue: false, + ); + + /// URL of the Mastercard Gateway checkout JavaScript bundle. + static const String gatewayScriptUrl = String.fromEnvironment( + 'GATEWAY_SCRIPT_URL', + defaultValue: + 'https://test-gateway.mastercard.com/static/checkout/checkout.min.js', + ); + + // ----------------------------------------------------------------- + // Helpers + // ----------------------------------------------------------------- + + /// `true` when [env] is `live`. + static bool get isLive => env.toLowerCase() == 'live'; +} \ No newline at end of file diff --git a/lib/http/http.dart b/lib/http/http.dart index 980aeb4..2920bd6 100644 --- a/lib/http/http.dart +++ b/lib/http/http.dart @@ -1,14 +1,14 @@ import 'package:dio/dio.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:logger/logger.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:qpay/config/app_config.dart'; var logger = Logger(printer: PrettyPrinter()); class Http { final Dio dio = Dio(); - final String baseUrl = dotenv.env['BASE_URL'] ?? ''; + final String baseUrl = AppConfig.baseUrl; Http() { dio.options.baseUrl = baseUrl; diff --git a/lib/interop.dart b/lib/interop.dart index a671e85..9fc206d 100644 --- a/lib/interop.dart +++ b/lib/interop.dart @@ -1,12 +1,9 @@ import 'dart:async'; import 'dart:js_interop'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:qpay/config/app_config.dart'; import 'package:web/web.dart' as web; -const String _defaultGatewayScriptUrl = - 'https://test-gateway.mastercard.com/static/checkout/checkout.min.js'; - @JS('Checkout') external JSAny? _checkout; @@ -23,8 +20,7 @@ Future ensureCheckoutScriptLoaded() async { return; } - final scriptUrl = - dotenv.env['GATEWAY_SCRIPT_URL'] ?? _defaultGatewayScriptUrl; + final scriptUrl = AppConfig.gatewayScriptUrl; final scriptElement = web.HTMLScriptElement() ..id = 'mastercard-checkout-script' diff --git a/lib/main.dart b/lib/main.dart index 302fe87..c627b51 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,23 +10,9 @@ import 'package:qpay/providers/splash_provider.dart'; import 'package:qpay/screens/workspaces/workspace_provider.dart'; import 'package:qpay/providers/uptime_provider.dart'; import 'package:qpay/theme/app_theme.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:firebase_core/firebase_core.dart'; import 'firebase_options.dart'; - -const String testEnv = 'assets/.env.test'; -const String liveEnv = 'assets/.env.live'; -const String appEnv = String.fromEnvironment('APP_ENV', defaultValue: 'test'); - -String resolveEnvFile(String env) { - switch (env.toLowerCase()) { - case 'live': - return liveEnv; - case 'test': - default: - return testEnv; - } -} +import 'config/app_config.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -35,8 +21,6 @@ void main() async { } await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); - await dotenv.load(fileName: resolveEnvFile(appEnv)); - // Read the persisted auth token before the first frame so the router // knows whether the user is already signed in on cold start. Without // this we would briefly treat logged-in users as guests and bounce diff --git a/lib/screens/gateway/gateway_screen.dart b/lib/screens/gateway/gateway_screen.dart index f3a8cce..53e31dc 100644 --- a/lib/screens/gateway/gateway_screen.dart +++ b/lib/screens/gateway/gateway_screen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:go_router/go_router.dart'; +import 'package:qpay/config/app_config.dart'; import 'package:qpay/screens/gateway/gateway_controller.dart'; import 'package:qpay/widgets/app_snack_bar.dart'; import 'package:webview_flutter/webview_flutter.dart'; @@ -56,7 +56,7 @@ class _GatewayScreenState extends State { ) ..loadRequest(Uri.parse(url)); - bool simulate = bool.parse(dotenv.env['SIMULATE_PAYMENT_SUCCESS']!); + bool simulate = AppConfig.simulatePaymentSuccess; if (simulate) { await Future.delayed(Duration(seconds: 10)); String targetUrl = url.replaceAll("/pay/", "/receipt/"); diff --git a/lib/screens/gateway/gateway_web_screen.dart b/lib/screens/gateway/gateway_web_screen.dart index 4f9f343..d11bfa7 100644 --- a/lib/screens/gateway/gateway_web_screen.dart +++ b/lib/screens/gateway/gateway_web_screen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:go_router/go_router.dart'; +import 'package:qpay/config/app_config.dart'; import 'package:qpay/models/responsive_policy.dart'; import 'package:qpay/screens/gateway/gateway_controller.dart'; import 'package:qpay/browser.dart'; @@ -34,9 +34,7 @@ class _GatewayWebScreenState extends State { redirecting = true; }); - bool simulate = bool.parse( - dotenv.env['SIMULATE_PAYMENT_SUCCESS'] ?? 'false', - ); + bool simulate = AppConfig.simulatePaymentSuccess; if (simulate) { // In simulation mode, just go to polling WidgetsBinding.instance.addPostFrameCallback((_) { diff --git a/pubspec.lock b/pubspec.lock index 21f8464..803631c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -294,14 +294,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.9+2" - flutter_dotenv: - dependency: "direct main" - description: - name: flutter_dotenv - sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b - url: "https://pub.dev" - source: hosted - version: "5.2.1" flutter_lints: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index 0b1e735..2bb5330 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,7 +46,6 @@ dependencies: timeago: ^3.6.1 freezed_annotation: ^3.0.0 json_annotation: ^4.9.0 - flutter_dotenv: ^5.2.1 logger: ^2.6.0 webview_flutter: ^4.13.0 widgets_to_image: ^2.0.1