From d336c5ecc26656a5ac8e39b9cddcb01b70af9c47 Mon Sep 17 00:00:00 2001 From: Julius Caesar Date: Tue, 18 Aug 2026 15:26:14 -0700 Subject: [PATCH 1/4] feat: login by code added --- .../kotlin/com/defyx/defyx/MainActivity.kt | 26 ++ .../main/kotlin/com/defyx/defyx/VpnService.kt | 9 + ios/Podfile.lock | 123 +++---- ios/Runner/VPNPlugin.swift | 20 ++ lib/common/components/button.dart | 25 +- lib/l10n/app_en.arb | 40 +++ lib/l10n/app_fa.arb | 10 +- lib/l10n/app_localizations.dart | 48 +++ lib/l10n/app_localizations_en.dart | 26 ++ lib/l10n/app_localizations_fa.dart | 26 ++ lib/l10n/app_localizations_ru.dart | 26 ++ lib/l10n/app_localizations_zh.dart | 25 ++ lib/l10n/app_ru.arb | 10 +- lib/l10n/app_zh.arb | 10 +- lib/modules/core/vpn_bridge.dart | 10 +- .../widgets/settings_premium_info_dialog.dart | 8 +- ...settings_premium_login_by_code_dialog.dart | 170 ++++++++++ .../settings_premium_login_dialog.dart | 21 +- linux/flutter/generated_plugins.cmake | 1 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 + macos/Podfile.lock | 69 +++- pubspec.lock | 320 ++++++++---------- windows/flutter/generated_plugins.cmake | 1 - windows/runner/dxcore_bridge.cpp | 11 + windows/runner/dxcore_bridge.h | 5 +- windows/runner/vpn_channel_handler.cpp | 22 ++ 26 files changed, 805 insertions(+), 259 deletions(-) create mode 100644 lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart diff --git a/android/app/src/main/kotlin/com/defyx/defyx/MainActivity.kt b/android/app/src/main/kotlin/com/defyx/defyx/MainActivity.kt index 002b461d..8c3f8ff6 100644 --- a/android/app/src/main/kotlin/com/defyx/defyx/MainActivity.kt +++ b/android/app/src/main/kotlin/com/defyx/defyx/MainActivity.kt @@ -113,6 +113,7 @@ class MainActivity : FlutterActivity() { "setConnectionMethod" -> setConnectionMethod(call.arguments as? Map, result) "login" -> login(call.arguments as? Map, result) + "loginByCode" -> loginByCode(call.arguments as? Map, result) else -> result.notImplemented() } } catch (e: Exception) { @@ -474,6 +475,31 @@ class MainActivity : FlutterActivity() { } } } + + private fun loginByCode(args: Map?, result: MethodChannel.Result) { + CoroutineScope(Dispatchers.IO).launch { + try { + val code = args?.get("code") as? String + if (code.isNullOrEmpty()) { + withContext(Dispatchers.Main) { + result.error( + "INVALID_ARGUMENT", + "code is missing or empty", + null + ) + } + return@launch + } + val loginResult = DefyxVpnService.getInstance().loginByCode(code) + result.success(loginResult) + } catch (e: Exception) { + Log.e("Login by code", "Login failed: ${e.message}", e) + withContext(Dispatchers.Main) { + result.error("LOGIN_ERROR", "Failed to login by code", e.localizedMessage) + } + } + } + } } class ProgressStreamHandler : EventChannel.StreamHandler, ProgressListener { diff --git a/android/app/src/main/kotlin/com/defyx/defyx/VpnService.kt b/android/app/src/main/kotlin/com/defyx/defyx/VpnService.kt index 323ce062..218853f8 100644 --- a/android/app/src/main/kotlin/com/defyx/defyx/VpnService.kt +++ b/android/app/src/main/kotlin/com/defyx/defyx/VpnService.kt @@ -409,4 +409,13 @@ class DefyxVpnService : VpnService() { "" } } + + fun loginByCode(code: String): String { + return try { + Android.loginByCode(code) + } catch (e: Exception) { + log("Login by code failed: ${e.message}") + "" + } + } } diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 11c7a60a..76fea201 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -42,67 +42,67 @@ PODS: - file_picker (0.0.1): - DKImagePickerController/PhotoGallery - Flutter - - Firebase/CoreOnly (12.17.0): - - FirebaseCore (~> 12.17.0) - - Firebase/Crashlytics (12.17.0): + - Firebase/CoreOnly (12.4.0): + - FirebaseCore (~> 12.4.0) + - Firebase/Crashlytics (12.4.0): - Firebase/CoreOnly - - FirebaseCrashlytics (~> 12.17.0) - - firebase_analytics (12.4.6): + - FirebaseCrashlytics (~> 12.4.0) + - firebase_analytics (12.0.4): - firebase_core - - FirebaseAnalytics (= 12.17.0) + - FirebaseAnalytics (= 12.4.0) - Flutter - - firebase_core (4.13.0): - - Firebase/CoreOnly (= 12.17.0) + - firebase_core (4.2.1): + - Firebase/CoreOnly (= 12.4.0) - Flutter - - firebase_crashlytics (5.2.7): - - Firebase/Crashlytics (= 12.17.0) + - firebase_crashlytics (5.0.5): + - Firebase/Crashlytics (= 12.4.0) - firebase_core - Flutter - - FirebaseAnalytics (12.17.0): - - FirebaseAnalytics/Default (= 12.17.0) - - FirebaseCore (~> 12.17.0) - - FirebaseInstallations (~> 12.17.0) + - FirebaseAnalytics (12.4.0): + - FirebaseAnalytics/Default (= 12.4.0) + - FirebaseCore (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - FirebaseAnalytics/Default (12.17.0): - - FirebaseCore (~> 12.17.0) - - FirebaseInstallations (~> 12.17.0) - - GoogleAppMeasurement/Default (= 12.17.0) + - FirebaseAnalytics/Default (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) + - GoogleAppMeasurement/Default (= 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - FirebaseCore (12.17.0): - - FirebaseCoreInternal (~> 12.17.0) + - FirebaseCore (12.4.0): + - FirebaseCoreInternal (~> 12.4.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Logger (~> 8.1) - - FirebaseCoreExtension (12.17.0): - - FirebaseCore (~> 12.17.0) - - FirebaseCoreInternal (12.17.0): + - FirebaseCoreExtension (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseCoreInternal (12.4.0): - "GoogleUtilities/NSData+zlib (~> 8.1)" - - FirebaseCrashlytics (12.17.0): - - FirebaseCore (~> 12.17.0) - - FirebaseInstallations (~> 12.17.0) - - FirebaseRemoteConfigInterop (~> 12.17.0) - - FirebaseSessions (~> 12.17.0) + - FirebaseCrashlytics (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) + - FirebaseRemoteConfigInterop (~> 12.4.0) + - FirebaseSessions (~> 12.4.0) - GoogleDataTransport (~> 10.1) - GoogleUtilities/Environment (~> 8.1) - nanopb (~> 3.30910.0) - PromisesObjC (~> 2.4) - - FirebaseInstallations (12.17.0): - - FirebaseCore (~> 12.17.0) + - FirebaseInstallations (12.4.0): + - FirebaseCore (~> 12.4.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/UserDefaults (~> 8.1) - PromisesObjC (~> 2.4) - - FirebaseRemoteConfigInterop (12.17.0) - - FirebaseSessions (12.17.0): - - FirebaseCore (~> 12.17.0) - - FirebaseCoreExtension (~> 12.17.0) - - FirebaseInstallations (~> 12.17.0) + - FirebaseRemoteConfigInterop (12.4.0) + - FirebaseSessions (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseCoreExtension (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) - GoogleDataTransport (~> 10.1) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/UserDefaults (~> 8.1) @@ -122,28 +122,28 @@ PODS: - Flutter - Google-Mobile-Ads-SDK (~> 12.2.0) - webview_flutter_wkwebview - - GoogleAdsOnDeviceConversion (3.6.1): + - GoogleAdsOnDeviceConversion (3.1.0): - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Logger (~> 8.1) - GoogleUtilities/Network (~> 8.1) - nanopb (~> 3.30910.0) - - GoogleAppMeasurement/Core (12.17.0): + - GoogleAppMeasurement/Core (12.4.0): - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - GoogleAppMeasurement/Default (12.17.0): - - GoogleAdsOnDeviceConversion (~> 3.6.0) - - GoogleAppMeasurement/Core (= 12.17.0) - - GoogleAppMeasurement/IdentitySupport (= 12.17.0) + - GoogleAppMeasurement/Default (12.4.0): + - GoogleAdsOnDeviceConversion (~> 3.1.0) + - GoogleAppMeasurement/Core (= 12.4.0) + - GoogleAppMeasurement/IdentitySupport (= 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - GoogleAppMeasurement/IdentitySupport (12.17.0): - - GoogleAppMeasurement/Core (= 12.17.0) + - GoogleAppMeasurement/IdentitySupport (12.4.0): + - GoogleAppMeasurement/Core (= 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) @@ -187,6 +187,9 @@ PODS: - nanopb/encode (3.30910.0) - package_info_plus (0.4.5): - Flutter + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS - PromisesObjC (2.4.1) - PromisesSwift (2.4.1): - PromisesObjC (= 2.4.1) @@ -221,6 +224,7 @@ DEPENDENCIES: - google_mobile_ads (from `.symlinks/plugins/google_mobile_ads/ios`) - GoogleUserMessagingPlatform - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - sensors_plus (from `.symlinks/plugins/sensors_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) @@ -280,6 +284,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/google_mobile_ads/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" sensors_plus: :path: ".symlinks/plugins/sensors_plus/ios" shared_preferences_foundation: @@ -291,37 +297,38 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: app_tracking_transparency: 3d84f147f67ca82d3c15355c36b1fa6b66ca7c92 - audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5 + audioplayers_darwin: 4f9ca89d92d3d21cec7ec580e78ca888e5fb68bd battery_plus: b42253f6d2dde71712f8c36fef456d99121c5977 connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be - Firebase: e8400c058702940d53f31fc0653e4e7a06332326 - firebase_analytics: 4dc4986181e6f58d24f879716f175a53e837c914 - firebase_core: c94f9efeed0ded590b7eecaf6110a374eb865d7a - firebase_crashlytics: 36d85edffd4bfd025c13025b0009f63754983536 - FirebaseAnalytics: 652858a1424ca8c549b62261876814ff56dff650 - FirebaseCore: 52d4512296984a44a8c8870c6494870fc7aeee2f - FirebaseCoreExtension: be2d62bfcf339c7dd94646d43d910aaf37fe17c1 - FirebaseCoreInternal: 3b310521b34a51ce3a6c605e4618b9aef8f6c112 - FirebaseCrashlytics: 33f4bb8b7140f1864a4db6b819edf36e6d2b1b0d - FirebaseInstallations: bd8e80f51d4c8bdc6c872011dede0b800c5b49ea - FirebaseRemoteConfigInterop: 785e617ae4cbc778eea97dde952b88fb934e11ff - FirebaseSessions: 83cf567ddcef20303eb85e003dfdbe030343ef8d + Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e + firebase_analytics: 67fbdd9f3c04e55048024f3da21cfc36f05e56cf + firebase_core: f1aafb21c14f497e5498f7ffc4dc63cbb52b2594 + firebase_crashlytics: c039028126cb45e32f4c217aa392408b0963d081 + FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f + FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3 + FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018 + FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6 + FirebaseCrashlytics: a6ece278a837c7e88de2d9b5da0a3542f2342395 + FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2 + FirebaseRemoteConfigInterop: 1e31ec72b89c9924367c59bfb5ec9ab60d1d6766 + FirebaseSessions: ba7c7a7ca8696a8d540eb3fe3800fbe98c79786d Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_secure_storage_darwin: acdb3f316ed05a3e68f856e0353b133eec373a23 flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544 Google-Mobile-Ads-SDK: 1dfb0c3cb46c7e2b00b0f4de74a1e06d9ea25d67 google_mobile_ads: 535223588a6791b7a3cc3513a1bc7b89d12f3e62 - GoogleAdsOnDeviceConversion: e3b71da24ff4cf01cf520756ac1c2b93c07b86ff - GoogleAppMeasurement: 2234668e2451f9da37b93dad7830e457600c008f + GoogleAdsOnDeviceConversion: e03a386840803ea7eef3fd22a061930142c039c1 + GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d GoogleDataTransport: a24e58982ab3ba2f64d79613e027fe7f57e88539 GoogleUserMessagingPlatform: befe603da6501006420c206222acd449bba45a9c GoogleUtilities: 766ace00c6b10d8148408f329d10c4f051931850 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880 PromisesObjC: 752c3227f599e3467650e47ea36f433eeb10c273 PromisesSwift: 217dea0fd5d2ad65222a109c48698add13cc1c5b SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf diff --git a/ios/Runner/VPNPlugin.swift b/ios/Runner/VPNPlugin.swift index bea5d9cb..569159b6 100644 --- a/ios/Runner/VPNPlugin.swift +++ b/ios/Runner/VPNPlugin.swift @@ -99,6 +99,8 @@ class VpnPlugin: VpnStatusDelegate { isVPNPrepared(result) case "login": login(call.arguments as? [String: Any], result) + case "loginByCode" + loginByCode(call.arguments as? [String: Any], result) default: result(FlutterMethodNotImplemented) } @@ -288,6 +290,24 @@ class VpnPlugin: VpnStatusDelegate { } + private func loginByCode(_ arguments: [String: Any]?, _ result: @escaping FlutterResult) { + guard let args = arguments, + let code = args["code"] as? String + else { + result( + FlutterError( + code: "INVALID_ARGUMENTS", message: "Missing required parameters", details: nil) + ) + return + } + + goQueue.async { + let token = IosLoginByCode(code) + result(token) + } + + } + private func getFlowLine(_ arguments: [String: Any]?, _ result: @escaping FlutterResult) { diff --git a/lib/common/components/button.dart b/lib/common/components/button.dart index be632a7d..8e8006dd 100644 --- a/lib/common/components/button.dart +++ b/lib/common/components/button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -enum AppButtonVariant { primary, secondary } +enum AppButtonVariant { primary, secondary, tertiary } enum AppButtonSize { small, medium } @@ -29,6 +29,7 @@ class AppButton extends StatelessWidget { height: config.height, child: ElevatedButton( onPressed: isLoading ? null : onPressed, + style: ElevatedButton.styleFrom( minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, @@ -40,6 +41,7 @@ class AppButton extends StatelessWidget { disabledForegroundColor: _textColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.r), + side: BorderSide(color: _borderColor, width: 1), ), ), child: AnimatedSwitcher( @@ -77,6 +79,9 @@ class AppButton extends StatelessWidget { case AppButtonVariant.secondary: return const Color(0xFFEAEAEA); + + case AppButtonVariant.tertiary: + return Colors.transparent; } } @@ -87,6 +92,9 @@ class AppButton extends StatelessWidget { case AppButtonVariant.secondary: return const Color(0xFF4B4B4B); + + case AppButtonVariant.tertiary: + return const Color(0xFF4B4B4B); } } @@ -97,6 +105,21 @@ class AppButton extends StatelessWidget { case AppButtonVariant.secondary: return const Color(0xFF4B4B4B); + case AppButtonVariant.tertiary: + return const Color(0xFF9E9E9E); + } + } + + Color get _borderColor { + switch (variant) { + case AppButtonVariant.primary: + return Colors.transparent; + + case AppButtonVariant.secondary: + return Colors.transparent; + + case AppButtonVariant.tertiary: + return const Color(0xFFEAEAEA); } } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index b385f478..f836eef4 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -516,6 +516,26 @@ "description": "Login success toast message" }, + "code": "Code", + "@code": { + "description": "Code field label" + }, + + "codeHint": "Enter your access code", + "@codeHint": { + "description": "Code field hint text" + }, + + "codeValidation": "Please enter your code", + "@codeValidation": { + "description": "Code validation error message" + }, + + "premiumLoginByCodeDescription": "To access your Premium subscription(s), enter the access code provided to you.", + "@premiumLoginByCodeDescription": { + "description": "Premium login by code dialog description" + }, + "havingTrouble": "Having trouble?", "@havingTrouble": { "description": "Premium trouble dialog title" @@ -564,5 +584,25 @@ "loginOrRegister": "LOGIN OR REGISTER", "@loginOrRegister": { "description": "Premium widget - login/register prompt" + }, + + "loginByCode": "Login by code", + "@loginByCode": { + "description": "Login by code button text" + }, + + "backToLoginByEmail": "Back to login by email", + "@backToLoginByEmail": { + "description": "Back to email login button text" + }, + + "connectionRequired": "Connection Required", + "@connectionRequired": { + "description": "Connection required dialog title" + }, + + "connectionRequiredDescription": "To complete a secure login or registration process, you must first establish a connection using one of the available connection methods.", + "@connectionRequiredDescription": { + "description": "Connection required dialog description" } } diff --git a/lib/l10n/app_fa.arb b/lib/l10n/app_fa.arb index 8b820688..0c38af14 100644 --- a/lib/l10n/app_fa.arb +++ b/lib/l10n/app_fa.arb @@ -105,6 +105,10 @@ "signUp": "ثبت نام", "loginFailed": "ورود ناموفق بود. لطفاً اطلاعات ورود خود را بررسی کنید و دوباره تلاش کنید.", "loginSuccess": "ورود موفقیت‌آمیز بود!", + "code": "کد", + "codeHint": "کد دسترسی خود را وارد کنید", + "codeValidation": "لطفاً کد خود را وارد کنید", + "premiumLoginByCodeDescription": "برای دسترسی به اشتراک پرمیوم خود، کد دسترسی ارائه شده به شما را وارد کنید.", "havingTrouble": "مشکل دارید؟", "signedInAs": "شما در حال حاضر با آدرس ایمیل", "premiumImportDescription": "اگر اشتراک‌های پرمیوم شما به دلیل محدودیت‌های اینترنتی قابل بارگذاری نیستند و نمی‌توانید با روش‌های موجود متصل شوید، می‌توانید فایل دریافتی از فروشگاه را در برنامه وارد کنید.", @@ -114,5 +118,9 @@ "settingsMarketplace": "فروشگاه", "marketplaceDescription": "پیکربندی‌های امن VPN را از تامین‌کنندگان قابل اعتماد مرور کنید.", "loggedIn": "وارد شده", - "loginOrRegister": "ورود یا ثبت نام" + "loginOrRegister": "ورود یا ثبت نام", + "loginByCode": "ورود با کد", + "backToLoginByEmail": "بازگشت به ورود با ایمیل", + "connectionRequired": "اتصال لازم است", + "connectionRequiredDescription": "برای تکمیل فرآیند امن ورود یا ثبت‌نام، ابتدا باید با استفاده از یکی از روش‌های اتصال موجود، اتصال برقرار کنید." } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 262034f9..83c2e3a1 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -714,6 +714,30 @@ abstract class AppLocalizations { /// **'Login successful!'** String get loginSuccess; + /// Code field label + /// + /// In en, this message translates to: + /// **'Code'** + String get code; + + /// Code field hint text + /// + /// In en, this message translates to: + /// **'Enter your access code'** + String get codeHint; + + /// Code validation error message + /// + /// In en, this message translates to: + /// **'Please enter your code'** + String get codeValidation; + + /// Premium login by code dialog description + /// + /// In en, this message translates to: + /// **'To access your Premium subscription(s), enter the access code provided to you.'** + String get premiumLoginByCodeDescription; + /// Premium trouble dialog title /// /// In en, this message translates to: @@ -773,6 +797,30 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'LOGIN OR REGISTER'** String get loginOrRegister; + + /// Login by code button text + /// + /// In en, this message translates to: + /// **'Login by code'** + String get loginByCode; + + /// Back to email login button text + /// + /// In en, this message translates to: + /// **'Back to login by email'** + String get backToLoginByEmail; + + /// Connection required dialog title + /// + /// In en, this message translates to: + /// **'Connection Required'** + String get connectionRequired; + + /// Connection required dialog description + /// + /// In en, this message translates to: + /// **'To complete a secure login or registration process, you must first establish a connection using one of the available connection methods.'** + String get connectionRequiredDescription; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index ead08d1f..1baf22b7 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -325,6 +325,19 @@ class AppLocalizationsEn extends AppLocalizations { @override String get loginSuccess => 'Login successful!'; + @override + String get code => 'Code'; + + @override + String get codeHint => 'Enter your access code'; + + @override + String get codeValidation => 'Please enter your code'; + + @override + String get premiumLoginByCodeDescription => + 'To access your Premium subscription(s), enter the access code provided to you.'; + @override String get havingTrouble => 'Having trouble?'; @@ -356,4 +369,17 @@ class AppLocalizationsEn extends AppLocalizations { @override String get loginOrRegister => 'LOGIN OR REGISTER'; + + @override + String get loginByCode => 'Login by code'; + + @override + String get backToLoginByEmail => 'Back to login by email'; + + @override + String get connectionRequired => 'Connection Required'; + + @override + String get connectionRequiredDescription => + 'To complete a secure login or registration process, you must first establish a connection using one of the available connection methods.'; } diff --git a/lib/l10n/app_localizations_fa.dart b/lib/l10n/app_localizations_fa.dart index 7609b2e3..b8a5e306 100644 --- a/lib/l10n/app_localizations_fa.dart +++ b/lib/l10n/app_localizations_fa.dart @@ -325,6 +325,19 @@ class AppLocalizationsFa extends AppLocalizations { @override String get loginSuccess => 'ورود موفقیت‌آمیز بود!'; + @override + String get code => 'کد'; + + @override + String get codeHint => 'کد دسترسی خود را وارد کنید'; + + @override + String get codeValidation => 'لطفاً کد خود را وارد کنید'; + + @override + String get premiumLoginByCodeDescription => + 'برای دسترسی به اشتراک پرمیوم خود، کد دسترسی ارائه شده به شما را وارد کنید.'; + @override String get havingTrouble => 'مشکل دارید؟'; @@ -356,4 +369,17 @@ class AppLocalizationsFa extends AppLocalizations { @override String get loginOrRegister => 'ورود یا ثبت نام'; + + @override + String get loginByCode => 'ورود با کد'; + + @override + String get backToLoginByEmail => 'بازگشت به ورود با ایمیل'; + + @override + String get connectionRequired => 'اتصال لازم است'; + + @override + String get connectionRequiredDescription => + 'برای تکمیل فرآیند امن ورود یا ثبت‌نام، ابتدا باید با استفاده از یکی از روش‌های اتصال موجود، اتصال برقرار کنید.'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 19bd2511..d828561c 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -326,6 +326,19 @@ class AppLocalizationsRu extends AppLocalizations { @override String get loginSuccess => 'Вход выполнен успешно!'; + @override + String get code => 'Код'; + + @override + String get codeHint => 'Введите ваш код доступа'; + + @override + String get codeValidation => 'Пожалуйста, введите ваш код'; + + @override + String get premiumLoginByCodeDescription => + 'Для доступа к вашим премиум-подпискам введите предоставленный вам код доступа.'; + @override String get havingTrouble => 'Возникли проблемы?'; @@ -358,4 +371,17 @@ class AppLocalizationsRu extends AppLocalizations { @override String get loginOrRegister => 'ВОЙТИ ИЛИ ЗАРЕГИСТРИРОВАТЬСЯ'; + + @override + String get loginByCode => 'Войти по коду'; + + @override + String get backToLoginByEmail => 'Вернуться к входу по электронной почте'; + + @override + String get connectionRequired => 'Требуется подключение'; + + @override + String get connectionRequiredDescription => + 'Чтобы завершить безопасный процесс входа или регистрации, вы должны сначала установить соединение, используя один из доступных методов подключения.'; } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 7b1b7bcc..df5f9817 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -317,6 +317,18 @@ class AppLocalizationsZh extends AppLocalizations { @override String get loginSuccess => '登录成功!'; + @override + String get code => '代码'; + + @override + String get codeHint => '输入您的访问代码'; + + @override + String get codeValidation => '请输入您的代码'; + + @override + String get premiumLoginByCodeDescription => '要访问您的高级订阅,请输入提供给您的访问代码。'; + @override String get havingTrouble => '遇到问题?'; @@ -347,4 +359,17 @@ class AppLocalizationsZh extends AppLocalizations { @override String get loginOrRegister => '登录或注册'; + + @override + String get loginByCode => '使用代码登录'; + + @override + String get backToLoginByEmail => '返回电子邮件登录'; + + @override + String get connectionRequired => '需要连接'; + + @override + String get connectionRequiredDescription => + '要完成安全的登录或注册过程,您必须首先使用可用的连接方法之一建立连接。'; } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 822551c5..6e133c77 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -105,6 +105,10 @@ "signUp": "Зарегистрироваться", "loginFailed": "Ошибка входа. Проверьте свои учетные данные и попробуйте снова.", "loginSuccess": "Вход выполнен успешно!", + "code": "Код", + "codeHint": "Введите ваш код доступа", + "codeValidation": "Пожалуйста, введите ваш код", + "premiumLoginByCodeDescription": "Для доступа к вашим премиум-подпискам введите предоставленный вам код доступа.", "havingTrouble": "Возникли проблемы?", "signedInAs": "Вы в настоящее время вошли в систему с адресом электронной почты", "premiumImportDescription": "Если ваши премиум-подписки не могут быть загружены из-за ограничений интернета и вы не можете подключиться доступными методами, вы можете импортировать файл, полученный из Маркетплейса, в приложение.", @@ -114,5 +118,9 @@ "settingsMarketplace": "Маркетплейс", "marketplaceDescription": "Просмотрите безопасные конфигурации VPN от проверенных поставщиков.", "loggedIn": "ВОШЛИ В СИСТЕМУ", - "loginOrRegister": "ВОЙТИ ИЛИ ЗАРЕГИСТРИРОВАТЬСЯ" + "loginOrRegister": "ВОЙТИ ИЛИ ЗАРЕГИСТРИРОВАТЬСЯ", + "loginByCode": "Войти по коду", + "backToLoginByEmail": "Вернуться к входу по электронной почте", + "connectionRequired": "Требуется подключение", + "connectionRequiredDescription": "Чтобы завершить безопасный процесс входа или регистрации, вы должны сначала установить соединение, используя один из доступных методов подключения." } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 86f4b485..2308852b 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -103,6 +103,10 @@ "signUp": "注册", "loginFailed": "登录失败。请检查您的凭据并重试。", "loginSuccess": "登录成功!", + "code": "代码", + "codeHint": "输入您的访问代码", + "codeValidation": "请输入您的代码", + "premiumLoginByCodeDescription": "要访问您的高级订阅,请输入提供给您的访问代码。", "havingTrouble": "遇到问题?", "signedInAs": "您当前已使用电子邮件地址登录", "premiumImportDescription": "如果由于互联网限制无法加载您的高级订阅,并且您无法使用可用方法连接,您可以将从市场获得的文件导入应用程序。", @@ -112,5 +116,9 @@ "settingsMarketplace": "市场", "marketplaceDescription": "浏览来自可信供应商的安全VPN配置。", "loggedIn": "已登录", - "loginOrRegister": "登录或注册" + "loginOrRegister": "登录或注册", + "loginByCode": "使用代码登录", + "backToLoginByEmail": "返回电子邮件登录", + "connectionRequired": "需要连接", + "connectionRequiredDescription": "要完成安全的登录或注册过程,您必须首先使用可用的连接方法之一建立连接。" } diff --git a/lib/modules/core/vpn_bridge.dart b/lib/modules/core/vpn_bridge.dart index e5c6c424..3fd04ea3 100644 --- a/lib/modules/core/vpn_bridge.dart +++ b/lib/modules/core/vpn_bridge.dart @@ -94,15 +94,23 @@ class VpnBridge { Future verifyGateway() async { try { - return (await _methodChannel.invokeMethod('verifyGateway')) ?? false; + return (await _methodChannel.invokeMethod('verifyGateway')) ?? + false; } catch (_) { return false; } } + Future login(String email, String password) async => (await _methodChannel.invokeMethod('login', { "email": email, "password": password, }) ?? ""); + + Future loginByCode(String code) async => + (await _methodChannel.invokeMethod('loginByCode', { + "code": code, + }) ?? + ""); } diff --git a/lib/modules/settings/presentation/widgets/settings_premium_info_dialog.dart b/lib/modules/settings/presentation/widgets/settings_premium_info_dialog.dart index 2c5cd7c5..e7bc4e6f 100644 --- a/lib/modules/settings/presentation/widgets/settings_premium_info_dialog.dart +++ b/lib/modules/settings/presentation/widgets/settings_premium_info_dialog.dart @@ -1,4 +1,5 @@ import 'package:defyx_vpn/common/components/button.dart'; +import 'package:defyx_vpn/l10n/app_localizations.dart'; import 'package:defyx_vpn/modules/settings/presentation/widgets/settings_premium_login_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -35,6 +36,7 @@ class _SettingsPremiumInfoDialogState extends State { @override Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context); final screenWidth = 1.sw; const double baseScreenWidth = 375.0; final ratio = screenWidth / baseScreenWidth; @@ -55,7 +57,7 @@ class _SettingsPremiumInfoDialogState extends State { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - 'Connection Required', + l10n.connectionRequired, style: TextStyle( fontFamily: 'Lato', fontSize: fontSize * 1.4, @@ -65,7 +67,7 @@ class _SettingsPremiumInfoDialogState extends State { ), SizedBox(height: 20.h), Text( - "To complete a secure login or registration process, you must first establish a connection using one of the available connection methods.", + l10n.connectionRequiredDescription, style: TextStyle( fontSize: fontSize, fontFamily: 'Lato', @@ -75,7 +77,7 @@ class _SettingsPremiumInfoDialogState extends State { ), SizedBox(height: 20.h), AppButton( - label: "Got it", + label: l10n.gotIt, onPressed: _handleGotIt, size: AppButtonSize.small, variant: AppButtonVariant.secondary, diff --git a/lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart b/lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart new file mode 100644 index 00000000..2e73ba16 --- /dev/null +++ b/lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart @@ -0,0 +1,170 @@ +import 'package:defyx_vpn/common/components/button.dart'; +import 'package:defyx_vpn/common/components/dialog.dart'; +import 'package:defyx_vpn/common/components/text_field.dart'; +import 'package:defyx_vpn/core/data/local/remote/api/flowline_service.dart'; +import 'package:defyx_vpn/core/utils/toast_util.dart'; +import 'package:defyx_vpn/l10n/app_localizations.dart'; +import 'package:defyx_vpn/modules/core/vpn_bridge.dart'; +import 'package:defyx_vpn/modules/settings/presentation/widgets/settings_premium_login_dialog.dart'; +import 'package:defyx_vpn/modules/settings/providers/auth_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class SettingsPremiumLoginByCodeDialog extends StatefulWidget { + final WidgetRef ref; + + const SettingsPremiumLoginByCodeDialog({super.key, required this.ref}); + + @override + State createState() => + _SettingsPremiumLoginByCodeDialogState(); + + static Future show(BuildContext context, WidgetRef ref) { + return showDialog( + context: context, + barrierDismissible: true, + builder: (BuildContext context) { + return PopScope( + canPop: true, + child: SettingsPremiumLoginByCodeDialog(ref: ref), + ); + }, + ); + } +} + +class _SettingsPremiumLoginByCodeDialogState + extends State { + final _formKey = GlobalKey(); + + bool isSubmitting = false; + + final TextEditingController _codeController = TextEditingController(); + + Future _submitLoginByCodeData() async { + final l10n = AppLocalizations.of(context); + try { + setState(() => isSubmitting = true); + if (!(_formKey.currentState?.validate() ?? false)) { + setState(() => isSubmitting = false); + return; + } + + final code = _codeController.text.trim(); + + final vpnBridge = VpnBridge(); + + final token = await vpnBridge.loginByCode(code); + + if (token.isEmpty) { + ToastUtil.showToast(l10n.loginFailed); + return; + } + + await widget.ref.read(authProvider.notifier).login(code, token); + + await widget.ref + .read(flowlineServiceProvider) + .saveFlowline(offlineMode: false, forceUpdate: true); + + ToastUtil.showToast(l10n.loginSuccess); + + if (mounted) { + Navigator.of(context).pop(); + } + } catch (e, stack) { + debugPrint(e.toString()); + debugPrint(stack.toString()); + } finally { + setState(() => isSubmitting = false); + } + } + + void _handleOpenLogin() { + Navigator.of(context).pop(); + SettingsPremiumLoginDialog.show(context, widget.ref); + } + + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context); + final screenWidth = 1.sw; + const double baseScreenWidth = 375.0; + final ratio = screenWidth / baseScreenWidth; + final fontSize = (16.0 * ratio).clamp(14.0, 18.0).toDouble(); + + return AppDialog( + child: Form( + key: _formKey, + child: Column( + // mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + l10n.authenticationRequired, + style: TextStyle( + fontFamily: 'Lato', + fontSize: fontSize * 1.4, + color: Colors.black, + fontWeight: FontWeight.w700, + ), + ), + SizedBox(height: 20.h), + Column( + children: [ + Row( + children: [ + Expanded( + child: Text( + l10n.premiumLoginByCodeDescription, + style: TextStyle( + fontSize: fontSize, + fontFamily: 'Lato', + color: Colors.black.withValues(alpha: 0.5), + height: 1.4, + ), + ), + ), + ], + ), + ], + ), + SizedBox(height: 20.h), + AppTextField( + controller: _codeController, + label: l10n.code.toUpperCase(), + hintText: l10n.codeHint, + prefixIcon: Icons.vpn_key, + keyboardType: TextInputType.text, + validator: (value) { + if (value == null || value.isEmpty) { + return l10n.codeValidation; + } + return null; + }, + ), + + SizedBox(height: 16.h), + AppButton( + label: l10n.login, + onPressed: _submitLoginByCodeData, + size: AppButtonSize.medium, + variant: AppButtonVariant.primary, + isLoading: isSubmitting, + ), + SizedBox(height: 10.h), + AppButton( + label: l10n.backToLoginByEmail, + onPressed: _handleOpenLogin, + size: AppButtonSize.small, + variant: AppButtonVariant.secondary, + isLoading: isSubmitting, + ), + SizedBox(height: 10.h), + ], + ), + ), + ); + } +} diff --git a/lib/modules/settings/presentation/widgets/settings_premium_login_dialog.dart b/lib/modules/settings/presentation/widgets/settings_premium_login_dialog.dart index fa2bd6cd..79f7bd46 100644 --- a/lib/modules/settings/presentation/widgets/settings_premium_login_dialog.dart +++ b/lib/modules/settings/presentation/widgets/settings_premium_login_dialog.dart @@ -5,6 +5,7 @@ import 'package:defyx_vpn/core/data/local/remote/api/flowline_service.dart'; import 'package:defyx_vpn/core/utils/toast_util.dart'; import 'package:defyx_vpn/l10n/app_localizations.dart'; import 'package:defyx_vpn/modules/core/vpn_bridge.dart'; +import 'package:defyx_vpn/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart'; import 'package:defyx_vpn/modules/settings/providers/auth_provider.dart'; import 'package:defyx_vpn/shared/layout/navbar/widgets/custom_webview_screen.dart'; import 'package:flutter/material.dart'; @@ -61,9 +62,7 @@ class _SettingsPremiumLoginDialogState final token = await vpnBridge.login(email, password); if (token.isEmpty) { - ToastUtil.showToast( - l10n.loginFailed, - ); + ToastUtil.showToast(l10n.loginFailed); return; } @@ -91,11 +90,17 @@ class _SettingsPremiumLoginDialogState final url = dotenv.env["WEBSITE_SIGN_UP"]; Navigator.of(context).push( MaterialPageRoute( - builder: (context) => CustomWebViewScreen(url: url!, title: l10n.signUp), + builder: (context) => + CustomWebViewScreen(url: url!, title: l10n.signUp), ), ); } + void _openLoginByCodeDialog() { + Navigator.of(context).pop(); + SettingsPremiumLoginByCodeDialog.show(context, widget.ref); + } + void _handleNotNow() { Navigator.of(context).pop(); } @@ -184,6 +189,14 @@ class _SettingsPremiumLoginDialogState isLoading: isSubmitting, ), SizedBox(height: 10.h), + AppButton( + label: l10n.loginByCode, + onPressed: _openLoginByCodeDialog, + size: AppButtonSize.small, + variant: AppButtonVariant.tertiary, + isLoading: isSubmitting, + ), + SizedBox(height: 10.h), AppButton( label: l10n.notNow, onPressed: _handleNotNow, diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index afaf5cc0..3f80f7b6 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - jni ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 90f79107..e046c699 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -15,6 +15,7 @@ import firebase_crashlytics import flutter_secure_storage_darwin import flutter_timezone import package_info_plus +import path_provider_foundation import shared_preferences_foundation import url_launcher_macos import webview_flutter_wkwebview @@ -30,6 +31,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterSecureStorageDarwinPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageDarwinPlugin")) FlutterTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterTimezonePlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index c476ab7a..606096c1 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -6,8 +6,13 @@ PODS: - FlutterMacOS - connectivity_plus (0.0.1): - FlutterMacOS + - file_picker (0.0.1): + - FlutterMacOS - Firebase/CoreOnly (12.4.0): - FirebaseCore (~> 12.4.0) + - Firebase/Crashlytics (12.4.0): + - Firebase/CoreOnly + - FirebaseCrashlytics (~> 12.4.0) - firebase_analytics (12.0.4): - firebase_core - FirebaseAnalytics (= 12.4.0) @@ -15,6 +20,11 @@ PODS: - firebase_core (4.2.1): - Firebase/CoreOnly (~> 12.4.0) - FlutterMacOS + - firebase_crashlytics (5.0.5): + - Firebase/CoreOnly (~> 12.4.0) + - Firebase/Crashlytics (~> 12.4.0) + - firebase_core + - FlutterMacOS - FirebaseAnalytics (12.4.0): - FirebaseAnalytics/Default (= 12.4.0) - FirebaseCore (~> 12.4.0) @@ -37,14 +47,36 @@ PODS: - FirebaseCoreInternal (~> 12.4.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.4.0): + - FirebaseCore (~> 12.4.0) - FirebaseCoreInternal (12.4.0): - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseCrashlytics (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) + - FirebaseRemoteConfigInterop (~> 12.4.0) + - FirebaseSessions (~> 12.4.0) + - GoogleDataTransport (~> 10.1) + - GoogleUtilities/Environment (~> 8.1) + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) - FirebaseInstallations (12.4.0): - FirebaseCore (~> 12.4.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/UserDefaults (~> 8.1) - PromisesObjC (~> 2.4) - - flutter_secure_storage_macos (6.1.3): + - FirebaseRemoteConfigInterop (12.4.0) + - FirebaseSessions (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseCoreExtension (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) + - GoogleDataTransport (~> 10.1) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - nanopb (~> 3.30910.0) + - PromisesSwift (~> 2.1) + - flutter_secure_storage_darwin (10.0.0): + - Flutter - FlutterMacOS - flutter_timezone (0.1.0): - FlutterMacOS @@ -71,6 +103,9 @@ PODS: - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) + - GoogleDataTransport (10.1.1): + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) - GoogleUtilities/AppDelegateSwizzler (8.1.0): - GoogleUtilities/Environment - GoogleUtilities/Logger @@ -109,6 +144,8 @@ PODS: - Flutter - FlutterMacOS - PromisesObjC (2.4.0) + - PromisesSwift (2.4.0): + - PromisesObjC (= 2.4.0) - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS @@ -122,9 +159,11 @@ DEPENDENCIES: - audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/darwin`) - battery_plus (from `Flutter/ephemeral/.symlinks/plugins/battery_plus/macos`) - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) + - file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`) - firebase_analytics (from `Flutter/ephemeral/.symlinks/plugins/firebase_analytics/macos`) - firebase_core (from `Flutter/ephemeral/.symlinks/plugins/firebase_core/macos`) - - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) + - firebase_crashlytics (from `Flutter/ephemeral/.symlinks/plugins/firebase_crashlytics/macos`) + - flutter_secure_storage_darwin (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_darwin/darwin`) - flutter_timezone (from `Flutter/ephemeral/.symlinks/plugins/flutter_timezone/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) @@ -138,12 +177,18 @@ SPEC REPOS: - Firebase - FirebaseAnalytics - FirebaseCore + - FirebaseCoreExtension - FirebaseCoreInternal + - FirebaseCrashlytics - FirebaseInstallations + - FirebaseRemoteConfigInterop + - FirebaseSessions - GoogleAppMeasurement + - GoogleDataTransport - GoogleUtilities - nanopb - PromisesObjC + - PromisesSwift EXTERNAL SOURCES: audioplayers_darwin: @@ -152,12 +197,16 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/battery_plus/macos connectivity_plus: :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos + file_picker: + :path: Flutter/ephemeral/.symlinks/plugins/file_picker/macos firebase_analytics: :path: Flutter/ephemeral/.symlinks/plugins/firebase_analytics/macos firebase_core: :path: Flutter/ephemeral/.symlinks/plugins/firebase_core/macos - flutter_secure_storage_macos: - :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos + firebase_crashlytics: + :path: Flutter/ephemeral/.symlinks/plugins/firebase_crashlytics/macos + flutter_secure_storage_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_darwin/darwin flutter_timezone: :path: Flutter/ephemeral/.symlinks/plugins/flutter_timezone/macos FlutterMacOS: @@ -177,26 +226,34 @@ SPEC CHECKSUMS: audioplayers_darwin: 4f9ca89d92d3d21cec7ec580e78ca888e5fb68bd battery_plus: f51ad29136e025b714b96f7d096f44f604615da7 connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e + file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e firebase_analytics: 09241c4796c1c42a02349ef8bf30025f5b640f0e firebase_core: e054894ab56033ef9bcbe2d9eac9395e5306e2fc + firebase_crashlytics: add6934cf4413d6c1307ca5251dbdbfe580e4caf FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3 + FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018 FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6 + FirebaseCrashlytics: a6ece278a837c7e88de2d9b5da0a3542f2342395 FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2 - flutter_secure_storage_macos: 7f45e30f838cf2659862a4e4e3ee1c347c2b3b54 + FirebaseRemoteConfigInterop: 1e31ec72b89c9924367c59bfb5ec9ab60d1d6766 + FirebaseSessions: ba7c7a7ca8696a8d540eb3fe3800fbe98c79786d + flutter_secure_storage_darwin: acdb3f316ed05a3e68f856e0353b133eec373a23 flutter_timezone: d59eea86178cbd7943cd2431cc2eaa9850f935d8 FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d + GoogleDataTransport: a24e58982ab3ba2f64d79613e027fe7f57e88539 GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 package_info_plus: f0052d280d17aa382b932f399edf32507174e870 path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d PODFILE CHECKSUM: 180da7a1dbc1d932db021ebc8007656e7c46dd99 -COCOAPODS: 1.16.2 +COCOAPODS: 1.17.0 diff --git a/pubspec.lock b/pubspec.lock index 443a28e2..3c19b81f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "6727cf2ced9b104abca9daa278380be2eca2b98ce33d4b46f11708e387dc6b4d" + sha256: "8a1f5f3020ef2a74fb93f7ab3ef127a8feea33a7a2276279113660784ee7516a" url: "https://pub.dev" source: hosted - version: "1.3.76" + version: "1.3.64" analyzer: dependency: transitive description: @@ -45,18 +45,18 @@ packages: dependency: "direct main" description: name: app_tracking_transparency - sha256: "3a52669c0645ffd7efe9a460047616de3e3f2128338f9ec7cdb681628d36238e" + sha256: "1f71f4d8402552fbf8b191d4edab301f233c1af794878b7bc56c708470ffd74c" url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.6+1" archive: dependency: transitive description: name: archive - sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" url: "https://pub.dev" source: hosted - version: "4.0.9" + version: "4.0.7" args: dependency: transitive description: @@ -69,18 +69,18 @@ packages: dependency: "direct main" description: name: async - sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.13.1" + version: "2.13.0" audioplayers: dependency: "direct main" description: name: audioplayers - sha256: f16640453cc47487b7de72a2b28d37c7df1ac97999849f4a46d92b1d2b0f093d + sha256: "5441fa0ceb8807a5ad701199806510e56afde2b4913d9d17c2f19f2902cf0ae4" url: "https://pub.dev" source: hosted - version: "6.7.1" + version: "6.5.1" audioplayers_android: dependency: transitive description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: audioplayers_darwin - sha256: c994b3bb3a921e4904ac40e013fbc94488e824fd7c1de6326f549943b0b44a91 + sha256: "0811d6924904ca13f9ef90d19081e4a87f7297ddc19fc3d31f60af1aaafee333" url: "https://pub.dev" source: hosted - version: "6.4.0" + version: "6.3.0" audioplayers_linux: dependency: transitive description: @@ -117,18 +117,18 @@ packages: dependency: transitive description: name: audioplayers_web - sha256: "24a6f258062bd7da8cb2157e83fccb9816a08dd306cbaaa24f9813d071470545" + sha256: "1c0f17cec68455556775f1e50ca85c40c05c714a99c5eb1d2d57cc17ba5522d7" url: "https://pub.dev" source: hosted - version: "5.2.1" + version: "5.1.1" audioplayers_windows: dependency: transitive description: name: audioplayers_windows - sha256: "95f875a96c88c3dbbcb608d4f8288e300b0113d256a81d0b3197fcc18f0dc91a" + sha256: "4048797865105b26d47628e6abb49231ea5de84884160229251f37dfcbe52fd7" url: "https://pub.dev" source: hosted - version: "4.3.1" + version: "4.2.1" battery_plus: dependency: "direct main" description: @@ -213,18 +213,18 @@ packages: dependency: transitive description: name: built_value - sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" + sha256: "426cf75afdb23aa74bd4e471704de3f9393f3c7b04c1e2d9c6f1073ae0b8b139" url: "https://pub.dev" source: hosted - version: "8.12.6" + version: "8.12.1" characters: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -249,22 +249,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" - code_assets: - dependency: transitive - description: - name: code_assets - sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8 - url: "https://pub.dev" - source: hosted - version: "1.2.1" code_builder: dependency: transitive description: name: code_builder - sha256: "6a6cab2ba4680d6423f34a9b972a4c9a94ebe1b62ecec4e1a1f2cba91fd1319d" + sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243" url: "https://pub.dev" source: hosted - version: "4.11.1" + version: "4.11.0" collection: dependency: transitive description: @@ -277,18 +269,18 @@ packages: dependency: "direct main" description: name: connectivity_plus - sha256: "62ffa266d9a23b79fb3fcbc206afc00bb979417ba57b1324c546b5aab95ba057" + sha256: "33bae12a398f841c6cda09d1064212957265869104c478e5ad51e2fb26c3973c" url: "https://pub.dev" source: hosted - version: "7.1.1" + version: "7.0.0" connectivity_plus_platform_interface: dependency: transitive description: name: connectivity_plus_platform_interface - sha256: "3c09627c536d22fd24691a905cdd8b14520de69da52c7a97499c8be5284a32ed" + sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.0.1" console: dependency: transitive description: @@ -333,10 +325,10 @@ packages: dependency: "direct main" description: name: cupertino_icons - sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.9" + version: "1.0.8" custom_lint_core: dependency: transitive description: @@ -365,18 +357,18 @@ packages: dependency: transitive description: name: dbus - sha256: "0ce9b0a839e6dee59a37a623d2fc26a35bbbe6404213e419b0d6411023d62645" + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" url: "https://pub.dev" source: hosted - version: "0.7.14" + version: "0.7.11" dio: dependency: "direct main" description: name: dio - sha256: aff32c08f92787a557dd5c0145ac91536481831a01b4648136373cddb0e64f8c + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 url: "https://pub.dev" source: hosted - version: "5.9.2" + version: "5.9.0" dio_http_formatter: dependency: "direct main" description: @@ -389,18 +381,18 @@ packages: dependency: transitive description: name: dio_web_adapter - sha256: "2f9e64323a7c3c7ef69567d5c800424a11f8337b8b228bad02524c9fb3c1f340" + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" equatable: dependency: transitive description: name: equatable - sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b" + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" url: "https://pub.dev" source: hosted - version: "2.0.8" + version: "2.0.7" fake_async: dependency: transitive description: @@ -413,10 +405,10 @@ packages: dependency: transitive description: name: ffi - sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.1.4" file: dependency: transitive description: @@ -437,66 +429,66 @@ packages: dependency: "direct main" description: name: firebase_analytics - sha256: a139dd0ada1c6e0ffd77bfdb877ac9061ffdec7c415e3e06113bdf8844db771f + sha256: bfb80d92eee10a6585ebd5a7e60de5caf0f2c06329e5676c0578130aea1bfe85 url: "https://pub.dev" source: hosted - version: "12.4.6" + version: "12.0.4" firebase_analytics_platform_interface: dependency: transitive description: name: firebase_analytics_platform_interface - sha256: "448c319ea895da002e43892c7d3f15dccbc3c4c3b81d3e307e37da885ea52bdf" + sha256: "3b803077907def997044774f6c022d8e9204e9c0f5e205e3572d887c93dafd72" url: "https://pub.dev" source: hosted - version: "6.0.6" + version: "5.0.4" firebase_analytics_web: dependency: transitive description: name: firebase_analytics_web - sha256: "67f287a0df75f27eafdd4a66a41e44f232c3aba713ea4794a1159893665a8bf5" + sha256: "0dbd96dbe77b51185319000c0078477fdcffb4abb0018c362dd9afb9845c1e06" url: "https://pub.dev" source: hosted - version: "0.6.1+12" + version: "0.6.1" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "9478ca6700c02d315c6aba37e206e612317f98bb4f335bb1cbd6e0ce67dcf764" + sha256: "1f2dfd9f535d81f8b06d7a50ecda6eac1e6922191ed42e09ca2c84bd2288927c" url: "https://pub.dev" source: hosted - version: "4.13.0" + version: "4.2.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: e28f9afdcb5b0f0a8ea74ea3b322f5a7592c81cb45dd9d189913bdae08a2089a + sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64 url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "6.0.2" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: f471a288b0101a45567548322ac4a5ad31e3ecbf87a576dcc0e424e6a11e04ea + sha256: ff18fabb0ad0ed3595d2f2c85007ecc794aadecdff5b3bb1460b7ee47cded398 url: "https://pub.dev" source: hosted - version: "3.10.0" + version: "3.3.0" firebase_crashlytics: dependency: "direct main" description: name: firebase_crashlytics - sha256: "96c1d85de9eddc07061d3f7e2fb75596e75a45c9cec9c2e3a7cc9f97e6f3a748" + sha256: bd4eadd620071ae48ef0e3617499be2a0ea4062d6d5c6fea6c1cec41ebbb2435 url: "https://pub.dev" source: hosted - version: "5.2.7" + version: "5.0.5" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "47d83b71fd39c580297c696a507a7c2652680ea2045e40c6c4e3c371b0ee7bc6" + sha256: a8ca502fe3aa48b4f0b9e6e3bc0019085a247b5d1214cd342a189457975662db url: "https://pub.dev" source: hosted - version: "3.8.27" + version: "3.8.15" fixnum: dependency: transitive description: @@ -509,10 +501,10 @@ packages: dependency: "direct main" description: name: flame - sha256: d084557523a45ad446d2480a4fa5a1c75aade5f8eb54251418e0ed4ee73ff3b8 + sha256: "348136b7d928188a8c9a11cd844d9125b02e7afc6c83bb9a52a16aee88ab7e81" url: "https://pub.dev" source: hosted - version: "1.35.1" + version: "1.34.0" flutter: dependency: "direct main" description: flutter @@ -522,10 +514,10 @@ packages: dependency: "direct main" description: name: flutter_dotenv - sha256: d41da11fb497314fbf89811ec30af02d1d898b47980a129f0a8c0a1720460ba2 + sha256: d4130c4a43e0b13fefc593bc3961f2cb46e30cb79e253d4a526b1b5d24ae1ce4 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.0.0" flutter_lints: dependency: "direct dev" description: @@ -551,10 +543,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "3854fe5e3bff0b113c658f260b90c95dea17c92db0f2addeac2e343dd9969785" + sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1 url: "https://pub.dev" source: hosted - version: "2.0.35" + version: "2.0.33" flutter_riverpod: dependency: "direct main" description: @@ -591,18 +583,18 @@ packages: dependency: transitive description: name: flutter_secure_storage_linux - sha256: a5f35ddab43cf5c8215d2feb4ce1957851f28c5c37e6f04335066a0602087bf5 + sha256: "76fa9c841b3b1619fc5b5bc36efc7d158fa2356f223b6caeb1d0c80a54168546" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" flutter_secure_storage_platform_interface: dependency: transitive description: name: flutter_secure_storage_platform_interface - sha256: "8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6" + sha256: "788060052712555182aba55ecb5f8b6e5cb9cfe8f776c83249a61fe3ce877db4" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" flutter_secure_storage_web: dependency: transitive description: @@ -623,10 +615,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f" + sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.2.3" flutter_test: dependency: "direct dev" description: flutter @@ -673,10 +665,10 @@ packages: dependency: transitive description: name: get_it - sha256: "568d62f0e68666fb5d95519743b3c24a34c7f19d834b0658c46e26d778461f66" + sha256: ae78de7c3f2304b8d81f2bb6e320833e5e81de942188542328f074978cc0efa9 url: "https://pub.dev" source: hosted - version: "9.2.1" + version: "8.3.0" glob: dependency: transitive description: @@ -709,14 +701,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" - hooks: - dependency: transitive - description: - name: hooks - sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba" - url: "https://pub.dev" - source: hosted - version: "2.0.2" html: dependency: transitive description: @@ -749,14 +733,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + iconsax_flutter: + dependency: transitive + description: + name: iconsax_flutter + sha256: d14b4cec8586025ac15276bdd40f6eea308cb85748135965bb6255f14beb2564 + url: "https://pub.dev" + source: hosted + version: "1.0.1" image: dependency: transitive description: name: image - sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce + sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.5.4" intl: dependency: "direct main" description: @@ -773,30 +765,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" - jni: - dependency: transitive - description: - name: jni - sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f - url: "https://pub.dev" - source: hosted - version: "1.0.0" - jni_flutter: - dependency: transitive - description: - name: jni_flutter - sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" - url: "https://pub.dev" - source: hosted - version: "1.0.1" js: dependency: transitive description: name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.6.7" json_annotation: dependency: "direct main" description: @@ -849,10 +825,10 @@ packages: dependency: transitive description: name: logger - sha256: "25aee487596a6257655a1e091ec2ae66bc30e7af663592cc3a27e6591e05035c" + sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3 url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.6.2" logging: dependency: transitive description: @@ -865,34 +841,34 @@ packages: dependency: "direct main" description: name: lottie - sha256: "8b6359a7422167014aa73ce763fa133fb832065dcc0ac4d1dec1f603a5cef7d0" + sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95" url: "https://pub.dev" source: hosted - version: "3.3.3" + version: "3.3.2" matcher: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.17.0" mime: dependency: transitive description: @@ -905,10 +881,10 @@ packages: dependency: "direct main" description: name: msix - sha256: b6b08e7a7b5d1845f2b1d31216d5b1fb558e98251efefe54eb79ed00d27bc2ac + sha256: f88033fcb9e0dd8de5b18897cbebbd28ea30596810f4a7c86b12b0c03ace87e5 url: "https://pub.dev" source: hosted - version: "3.16.13" + version: "3.16.12" nm: dependency: transitive description: @@ -917,14 +893,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.0" - objective_c: - dependency: transitive - description: - name: objective_c - sha256: "6cb691c686fa2838c6deb34980d426145c2a5d537491cb83d463c33cdbc726ed" - url: "https://pub.dev" - source: hosted - version: "9.4.1" ordered_set: dependency: transitive description: @@ -993,18 +961,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.2.22" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + sha256: "97390a0719146c7c3e71b6866c34f1cde92685933165c1c671984390d2aca776" url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.4.4" path_provider_linux: dependency: transitive description: @@ -1041,10 +1009,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" + sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" url: "https://pub.dev" source: hosted - version: "7.0.2" + version: "7.0.1" platform: dependency: transitive description: @@ -1073,10 +1041,10 @@ packages: dependency: transitive description: name: posix - sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" url: "https://pub.dev" source: hosted - version: "6.5.0" + version: "6.0.3" protobuf: dependency: transitive description: @@ -1101,22 +1069,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" - record_use: - dependency: transitive - description: - name: record_use - sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" - url: "https://pub.dev" - source: hosted - version: "0.6.0" retrofit: dependency: "direct main" description: name: retrofit - sha256: "0f629ed26b2c48c66fe54bd548313c6fdf7955be18bff37e08a46dd3f97f8eaf" + sha256: "7d78824afa6eeeaf6ac58220910ee7a97597b39e93360d4bda230b7c6df45089" url: "https://pub.dev" source: hosted - version: "4.9.2" + version: "4.9.0" retrofit_generator: dependency: "direct dev" description: @@ -1185,18 +1145,18 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" url: "https://pub.dev" source: hosted - version: "2.5.5" + version: "2.5.3" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 + sha256: "46a46fd64659eff15f4638bbe19de43f9483f0e0bf024a9fb6b3582064bacc7b" url: "https://pub.dev" source: hosted - version: "2.4.23" + version: "2.4.17" shared_preferences_foundation: dependency: transitive description: @@ -1217,10 +1177,10 @@ packages: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1" shared_preferences_web: dependency: transitive description: @@ -1286,10 +1246,10 @@ packages: dependency: transitive description: name: source_span - sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.2" + version: "1.10.1" stack_trace: dependency: transitive description: @@ -1350,10 +1310,10 @@ packages: dependency: transitive description: name: test_api - sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.7" timing: dependency: transitive description: @@ -1366,10 +1326,10 @@ packages: dependency: "direct main" description: name: toastification - sha256: "66c96678e3dece8ba24de3ea31634bd65a80aaecb8105f9bafe946e5f0d7590a" + sha256: "69db2bff425b484007409650d8bcd5ed1ce2e9666293ece74dcd917dacf23112" url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.0.3" typed_data: dependency: transitive description: @@ -1406,18 +1366,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "17bc677f0b301615530dd1d67e0a9828cafa2d0b6b6eae4cd3679b7eac4a273c" + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" url: "https://pub.dev" source: hosted - version: "6.3.30" + version: "6.3.28" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.3.6" url_launcher_linux: dependency: transitive description: @@ -1446,10 +1406,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" url: "https://pub.dev" source: hosted - version: "2.4.3" + version: "2.4.1" url_launcher_windows: dependency: transitive description: @@ -1462,18 +1422,18 @@ packages: dependency: transitive description: name: uuid - sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" + sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 url: "https://pub.dev" source: hosted - version: "4.5.3" + version: "4.5.2" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: "2306c03da2ba81724afeb589c351ebbc0aa7d86005925be8f8735856dbe5e42d" + sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.1.19" vector_graphics_codec: dependency: transitive description: @@ -1486,10 +1446,10 @@ packages: dependency: transitive description: name: vector_graphics_compiler - sha256: "7ee12e6dffe0fc8e755179d6d91b3b34f5924223fc104d85572ef9180d73d172" + sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc url: "https://pub.dev" source: hosted - version: "1.2.5" + version: "1.1.19" vector_math: dependency: transitive description: @@ -1510,18 +1470,18 @@ packages: dependency: transitive description: name: vm_service - sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" url: "https://pub.dev" source: hosted - version: "15.2.0" + version: "15.0.2" watcher: dependency: transitive description: name: watcher - sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" + sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.1.4" web: dependency: transitive description: @@ -1550,34 +1510,34 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: a3da219916aba44947d3a5478b1927876a09781174b5a2b67fa5be0555154bf9 + sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba url: "https://pub.dev" source: hosted - version: "4.13.1" + version: "4.13.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: ad5182eff9a550925330cb9f0cb038eddfdd5712aba8b77aa0f0400e50f6e688 + sha256: "3fcca88ee2ae568807ebd42deed235bb8dd8e62b3e4d5caff67daa6bce062cca" url: "https://pub.dev" source: hosted - version: "4.12.0" + version: "4.10.9" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "1221c1b12f5278791042f2ec2841743784cf25c5a644e23d6680e5d718824f04" + sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" url: "https://pub.dev" source: hosted - version: "2.15.1" + version: "2.14.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "82648217f537573e1ca9ae9952d3eacedca6ab5aee69dc84445fc763766dcea2" + sha256: a57b76a081bed3bf3a71a486bdf83642b00f1a7342043d50367cea68f338b1af url: "https://pub.dev" source: hosted - version: "3.25.1" + version: "3.23.4" win32: dependency: transitive description: @@ -1611,5 +1571,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.10.3 <4.0.0" - flutter: ">=3.38.4" + dart: ">=3.9.0 <4.0.0" + flutter: ">=3.35.0" diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 9fb10378..710015ea 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -13,7 +13,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - jni ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/windows/runner/dxcore_bridge.cpp b/windows/runner/dxcore_bridge.cpp index d3a5416a..9efb6be1 100644 --- a/windows/runner/dxcore_bridge.cpp +++ b/windows/runner/dxcore_bridge.cpp @@ -64,6 +64,7 @@ bool DXCoreBridge::Load() { load(pRequestHandshake_, "WinRequestHandshake"); load(pCompleteHandshake_, "WinCompleteHandshake"); ok &= load(pLogin_, "WinLogin"); + ok &= load(pLoginByCode_, "WinLoginByCode"); if (!ok) { Unload(); @@ -325,3 +326,13 @@ std::string DXCoreBridge::Login(const std::string& email, const std::string& pas if (s && pFreeString_) pFreeString_(const_cast(s)); return out; } + +std::string DXCoreBridge::LoginByCode(const std::string& code) { + if (!pLoginByCode_) return {}; + const char* s = pLoginByCode_(code.c_str()); + std::string out = s ? std::string(s) : std::string(); + if (s && pFreeString_) pFreeString_(const_cast(s)); + return out; +} + + diff --git a/windows/runner/dxcore_bridge.h b/windows/runner/dxcore_bridge.h index 240bbc75..bc11a957 100644 --- a/windows/runner/dxcore_bridge.h +++ b/windows/runner/dxcore_bridge.h @@ -33,6 +33,7 @@ class DXCoreBridge { int SetSystemProxy(); int ResetSystemProxy(); std::string Login(const std::string& email, const std::string& password); + std::string LoginByCode(const std::string& code); // Gateway handshake — verifies the loaded DXcore.dll is authentic. // Returns true only when the full HMAC challenge-response succeeds. @@ -63,6 +64,7 @@ class DXCoreBridge { using WinRequestHandshake_t = char* (*)(char*, char*); using WinCompleteHandshake_t = char* (*)(char*); using WinLogin_t = const char* (*)(const char*, const char*); + using WinLoginByCode_t = const char* (*)(const char*); WinSetProgressListener_t pSetProgress_ = nullptr; WinStop_t pStop_ = nullptr; @@ -83,7 +85,8 @@ class DXCoreBridge { WinRequestHandshake_t pRequestHandshake_ = nullptr; WinCompleteHandshake_t pCompleteHandshake_ = nullptr; WinLogin_t pLogin_ = nullptr; - + WinLogin_t pLogin_ = nullptr; + WinLoginByCode_t pLoginByCode_ = nullptr; static void __stdcall ProgressTrampoline(const char* msg); static DXCoreBridge* s_instance_; std::function progress_cb_; diff --git a/windows/runner/vpn_channel_handler.cpp b/windows/runner/vpn_channel_handler.cpp index 762edd0a..939a2808 100644 --- a/windows/runner/vpn_channel_handler.cpp +++ b/windows/runner/vpn_channel_handler.cpp @@ -552,6 +552,28 @@ void VPNChannelHandler::SetupMethodChannel() { return; } + if (method == "loginByCode") { + if (call.arguments() && std::holds_alternative(*call.arguments())) { + auto m = std::get(*call.arguments()); + auto code = get_string_arg(m, "code"); + if (!code.empty()) { + std::thread([this, code, result = std::move(result)]() mutable { + try { + std::string token = dxcore_->LoginByCode(code); + result->Success(flutter::EncodableValue(token)); + } catch (...) { + result->Error("LOGIN_ERROR", "Failed to login by code"); + } + }).detach(); + } else { + result->Error("INVALID_ARGUMENT", "code is missing or empty"); + } + } else { + result->Error("INVALID_ARGUMENT", "missing args"); + } + return; + } + result->NotImplemented(); }); } From 8732cab8d70395c263cefa160426a48e4d0c68ff Mon Sep 17 00:00:00 2001 From: Julius Caesar Date: Fri, 21 Aug 2026 06:45:05 -0700 Subject: [PATCH 2/4] fix: sysntax bug on ios side fixed --- ios/Runner/VPNPlugin.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Runner/VPNPlugin.swift b/ios/Runner/VPNPlugin.swift index 569159b6..459ff72a 100644 --- a/ios/Runner/VPNPlugin.swift +++ b/ios/Runner/VPNPlugin.swift @@ -99,7 +99,7 @@ class VpnPlugin: VpnStatusDelegate { isVPNPrepared(result) case "login": login(call.arguments as? [String: Any], result) - case "loginByCode" + case "loginByCode": loginByCode(call.arguments as? [String: Any], result) default: result(FlutterMethodNotImplemented) From 26d0c2f15d7cd51bb9cfec722cb5d6e6251efecd Mon Sep 17 00:00:00 2001 From: Julius Caesar Date: Fri, 21 Aug 2026 09:31:34 -0700 Subject: [PATCH 3/4] feat: empty email mode for login by code added --- ...settings_premium_login_by_code_dialog.dart | 2 +- .../settings_premium_trouble_dialog.dart | 37 ++++++++++--------- .../settings/providers/auth_provider.dart | 8 ++++ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart b/lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart index 2e73ba16..feff5839 100644 --- a/lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart +++ b/lib/modules/settings/presentation/widgets/settings_premium_login_by_code_dialog.dart @@ -62,7 +62,7 @@ class _SettingsPremiumLoginByCodeDialogState return; } - await widget.ref.read(authProvider.notifier).login(code, token); + await widget.ref.read(authProvider.notifier).loginByCode(token); await widget.ref .read(flowlineServiceProvider) diff --git a/lib/modules/settings/presentation/widgets/settings_premium_trouble_dialog.dart b/lib/modules/settings/presentation/widgets/settings_premium_trouble_dialog.dart index d9add102..1df44de3 100644 --- a/lib/modules/settings/presentation/widgets/settings_premium_trouble_dialog.dart +++ b/lib/modules/settings/presentation/widgets/settings_premium_trouble_dialog.dart @@ -90,25 +90,28 @@ class _SettingsPremiumTroubleDialogState fontWeight: FontWeight.w700, ), ), - SizedBox(height: 18.h), - RichText( - text: TextSpan( - style: TextStyle( - fontSize: fontSize, - fontFamily: 'Lato', - color: Colors.black.withValues(alpha: 0.5), - height: 1.4, - ), - children: [ - TextSpan(text: '${l10n.signedInAs} '), - TextSpan( - text: widget.email, - style: const TextStyle(color: Color(0xFF5374BD)), + if (widget.email.isNotEmpty) ...[ + SizedBox(height: 18.h), + + RichText( + text: TextSpan( + style: TextStyle( + fontSize: fontSize, + fontFamily: 'Lato', + color: Colors.black.withValues(alpha: 0.5), + height: 1.4, ), - const TextSpan(text: '.'), - ], + children: [ + TextSpan(text: '${l10n.signedInAs} '), + TextSpan( + text: widget.email, + style: const TextStyle(color: Color(0xFF5374BD)), + ), + const TextSpan(text: '.'), + ], + ), ), - ), + ], SizedBox(height: 18.h), Text( l10n.premiumImportDescription, diff --git a/lib/modules/settings/providers/auth_provider.dart b/lib/modules/settings/providers/auth_provider.dart index f3e40354..f52fb494 100644 --- a/lib/modules/settings/providers/auth_provider.dart +++ b/lib/modules/settings/providers/auth_provider.dart @@ -33,6 +33,14 @@ class AuthNotifier extends AsyncNotifier { state = AsyncData(AuthData(email: email, isLoggedIn: true)); } + Future loginByCode(String token) async { + final storage = ref.read(secureStorageProvider); + + await storage.write(premiumTokenKey, token); + + state = AsyncData(AuthData(email: "", isLoggedIn: true)); + } + Future logout() async { final storage = ref.read(secureStorageProvider); From 5349cb33043f468b412237207c62dad3bfca5b78 Mon Sep 17 00:00:00 2001 From: Julius Caesar Date: Fri, 21 Aug 2026 10:40:34 -0700 Subject: [PATCH 4/4] fix: duplicate define login method on windwos fixed --- windows/runner/dxcore_bridge.h | 1 - 1 file changed, 1 deletion(-) diff --git a/windows/runner/dxcore_bridge.h b/windows/runner/dxcore_bridge.h index bc11a957..f3931e9b 100644 --- a/windows/runner/dxcore_bridge.h +++ b/windows/runner/dxcore_bridge.h @@ -85,7 +85,6 @@ class DXCoreBridge { WinRequestHandshake_t pRequestHandshake_ = nullptr; WinCompleteHandshake_t pCompleteHandshake_ = nullptr; WinLogin_t pLogin_ = nullptr; - WinLogin_t pLogin_ = nullptr; WinLoginByCode_t pLoginByCode_ = nullptr; static void __stdcall ProgressTrampoline(const char* msg); static DXCoreBridge* s_instance_;