diff --git a/.env b/.env index a041842..b4f9388 100644 --- a/.env +++ b/.env @@ -21,23 +21,7 @@ seferPaymentServer=https://seferpw.shop/sefer seferCairoServer=https://server.sefer.live/sefer.click/sefer seferGizaServer=https://gizasefer.online/sefer anthropicAIkeySeferNewHamzaayedpython=zg-qbc-qvo39-vCB-WnzEwFNArO0YlTapvfhtmguKWsXJSKqg_NZSjHBYVXMZK1yUK88SobdckV0KuPaBh0c_WHtGsRO_439PBk-e2QqgkQQXrXlBl - -privateKeyFCM=''' -{ - "type": "service_account", - "project_id": "ride-b1bd8", - "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\n" - , - "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com", - "client_id": "111210077025005706623", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} -''' +getapiKey=https://server.sefer.live/sefer.click/sefer/ride/apiKey/get.php cohere=Aulwd8y5SPWos0hJhG0toUf8gOhUUrpf5Q2TPmVGXrXlBl claudeAiAPI=zg-qbc-qvo39-xWOxIGwWTOzCFBnIYSKKhfyz_KVAvrH-6_4ZEJL68G_QBH26oeTOMMoQug9KuOjjKSP_A4S3SUDlbxR9duVzoQ-MkX_UQQQXrXlBl payPalClientId=QALymfNI5Tzt4s-ysoz6vD4_nqX0SUtkC_qYV-Ugk5gaM_8Z-kg4L53k8Uux_4jEWXDkNpXGSWPpIzDFXrXlBl @@ -62,7 +46,12 @@ payMobOutPassword='D2zJFxkE#LN3vz38z2dYxpNfWXrXlBl' payMobOutUserName='zjujl_qvo_fwjfgjlXrXlBl' keyOfApp=nqryjp@1737wqnmqqsjyzjujljksvceiXrXlBl initializationVector=abcdefghijklmnop - +sss_pass=wqnmqqsjyvwv:nqrYJP@17378XrXlBl +sss_encryptionSalt=zg-vlie-2l1ZlpxiLJ6wQOvbb4TnC9XrxgUEyVQIu6TID4qP4FUUqoS5XrXlBl +addd=BlBlNl +allowed=TripzDriver: +passnpassenger=hbgbitbXrXrBr +newId=new a=q diff --git a/android/app/build.gradle b/android/app/build.gradle index 90dae8c..98bb790 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -55,8 +55,8 @@ android { // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdk = 23 targetSdk = flutter.targetSdkVersion - versionCode = 135 - versionName = '2.0.135' + versionCode = 136 + versionName = '2.0.136' multiDexEnabled =true } @@ -89,7 +89,7 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - + implementation 'com.scottyab:rootbeer-lib:0.1.0' implementation 'com.stripe:paymentsheet:20.52.2' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.4' diff --git a/android/app/src/main/kotlin/com/sefer_driver/MainActivity.kt b/android/app/src/main/kotlin/com/sefer_driver/MainActivity.kt index fee2cc8..c726bc5 100644 --- a/android/app/src/main/kotlin/com/sefer_driver/MainActivity.kt +++ b/android/app/src/main/kotlin/com/sefer_driver/MainActivity.kt @@ -1,21 +1,95 @@ package com.sefer_driver -import android.content.Intent +// import android.content.Intent +// import io.flutter.embedding.android.FlutterFragmentActivity +// import io.flutter.embedding.engine.FlutterEngine + +// class MainActivity : FlutterFragmentActivity() { +// override fun configureFlutterEngine(flutterEngine: FlutterEngine) { +// try { +// super.configureFlutterEngine(MyApplication.flutterEngine) +// } catch (e: UninitializedPropertyAccessException) { +// super.configureFlutterEngine(flutterEngine) +// } +// } + +// private fun bringAppToForeground() { +// val intent = Intent(this, MainActivity::class.java) +// intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) +// startActivity(intent) +// } +// } +import android.app.AlertDialog +import android.os.Bundle +import android.util.Log import io.flutter.embedding.android.FlutterFragmentActivity -import io.flutter.embedding.engine.FlutterEngine +import java.util.* class MainActivity : FlutterFragmentActivity() { - override fun configureFlutterEngine(flutterEngine: FlutterEngine) { - try { - super.configureFlutterEngine(MyApplication.flutterEngine) - } catch (e: UninitializedPropertyAccessException) { - super.configureFlutterEngine(flutterEngine) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + Log.d("DEBUG", "onCreate executed - Checking root status...") + + // بدء فحص الأمان + performSecurityChecks() + } + + private fun performSecurityChecks() { + val rootDetection = RootDetection + + val isRooted = rootDetection.isRooted() + val isDevMode = rootDetection.isDevMode(this) + val isTampered = rootDetection.isTampered(this) + val isRealDevice = rootDetection.isRealDevice() + val isOnExternalStorage = rootDetection.isOnExternalStorage() + val isNotTrust = rootDetection.isNotTrust() + val checkForIssues = rootDetection.checkForIssues() + + // Log.d("DEBUG", "Security Check Results:") + // Log.d("DEBUG", "isRooted: $isRooted") + // Log.d("DEBUG", "isDevMode: $isDevMode") + // Log.d("DEBUG", "isTampered: $isTampered") + // Log.d("DEBUG", "isRealDevice: $isRealDevice") + // Log.d("DEBUG", "isOnExternalStorage: $isOnExternalStorage") + // Log.d("DEBUG", "isNotTrust: $isNotTrust") + // Log.d("DEBUG", "checkForIssues: $checkForIssues") + + if (isRooted || isTampered || !isRealDevice || isOnExternalStorage || isNotTrust) { + // Log.e("DEBUG", "Security issue detected! Showing dialog.") + showSecurityWarningDialog() + } else { + // Log.d( + // "DEBUG", + // getString(R.string.device_secure) + // ) // Using dynamic string based on the device language } } - private fun bringAppToForeground() { - val intent = Intent(this, MainActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) - startActivity(intent) + private fun showSecurityWarningDialog() { + val builder = AlertDialog.Builder(this) + builder.setTitle(getString(R.string.security_warning_title)) // Title based on language + builder.setMessage( + getString(R.string.security_warning_message) + ) // Message based on language + + builder.setPositiveButton(getString(R.string.exit_button)) { _, _ -> + Log.e("DEBUG", "User clicked exit. Closing app.") + clearAppDataAndExit() + } + + builder.setCancelable(false) + val alertDialog = builder.create() + alertDialog.show() + } + + private fun clearAppDataAndExit() { + // حذف جميع البيانات هنا، مثل ملفات التخزين وبيانات التطبيق + // يمكنك استخدام SharedPreferences أو قاعدة بيانات + Log.d("DEBUG", "Clearing app data...") + + // يمكنك استخدام كود لحذف جميع البيانات (SharedPreferences, DB, ملفات) + // ثم إغلاق التطبيق: + finishAffinity() // يغلق جميع الأنشطة ويفتح نافذة جديدة } } diff --git a/android/app/src/main/kotlin/com/sefer_driver/RootDetection.kt b/android/app/src/main/kotlin/com/sefer_driver/RootDetection.kt new file mode 100644 index 0000000..86c82bd --- /dev/null +++ b/android/app/src/main/kotlin/com/sefer_driver/RootDetection.kt @@ -0,0 +1,61 @@ +package com.sefer_driver + +import android.content.Context +import android.os.Build +import android.os.Environment +import android.provider.Settings +import com.scottyab.rootbeer.RootBeer +import java.io.File + +object RootDetection { + + fun isRooted(): Boolean { + val paths = + arrayOf( + "/system/app/Superuser.apk", + "/system/xbin/su", + "/system/bin/su", + "/system/bin/magisk", + "/system/xbin/magisk", + "/sbin/magisk" + ) + for (path in paths) { + if (File(path).exists()) { + return true + } + } + return false + } + + fun isDevMode(context: Context): Boolean { + return Settings.Global.getInt( + context.contentResolver, + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, + 0 + ) == 1 + } + + fun isTampered(context: Context): Boolean { + val rootBeer = RootBeer(context) + return rootBeer.isRooted + } + + fun checkForIssues(): Boolean { + // يمكنك إضافة المزيد من الفحوصات حسب حاجتك + return false // نفترض أنه لا توجد مشاكل للأجهزة غير المتجذرة + } + + fun isRealDevice(): Boolean { + return !Build.FINGERPRINT.contains("generic") && !Build.MODEL.contains("google_sdk") + } + + fun isOnExternalStorage(): Boolean { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && + Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED + } + + fun isNotTrust(): Boolean { + // مثال تحقق من الثقة (قد تحتاج لتطوير هذا حسب متطلباتك) + return false // نفترض أن الجهاز موثوق + } +} diff --git a/android/app/src/main/res/values-ar/strings.xml b/android/app/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..6b7cb35 --- /dev/null +++ b/android/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,6 @@ + + تحذير أمني + تم اكتشاف مشكلة أمنية أو تعديل على هذا الجهاز. لا يمكن تشغيل التطبيق على هذا الجهاز. + إغلاق التطبيق + الجهاز آمن. الاستمرار بشكل طبيعي. + \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 5490443..ef37fb6 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -4,6 +4,11 @@ AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0 FCM Notifications Notifications from Firebase Cloud Messaging + Security Warning + A security issue or modification has been detected on + this device. The app cannot run on this device. + Exit App + Device is secure. Proceeding normally. \ No newline at end of file diff --git a/android/gradle.properties b/android/gradle.properties index 673be0c..e6860ca 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,8 +1,8 @@ -# org.gradle.jvmargs=-Xmx1536M +org.gradle.jvmargs=-Xmx4096M android.useAndroidX=true android.enableJetifier=true -org.gradle.jvmargs=-Xmx4096m android.defaults.buildfeatures.buildconfig=true -android.nonTransitiveRClass=false -android.nonFinalResIds=false +android.nonTransitiveRClass=true +android.nonFinalResIds=true +dart.obfuscation=true android.enableR8.fullMode=true \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b0a7bc3..3c98409 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -89,6 +89,8 @@ PODS: - GoogleUtilities/UserDefaults (~> 8.0) - nanopb (~> 3.30910.0) - Flutter (1.0.0) + - flutter_app_group_directory (0.0.1): + - Flutter - flutter_contacts (0.0.1): - Flutter - flutter_image_compress_common (1.0.0): @@ -195,6 +197,10 @@ PODS: - TOCropViewController (~> 2.7.4) - image_picker_ios (0.0.1): - Flutter + - IOSSecuritySuite (1.9.11) + - jailbreak_root_detection (1.0.1): + - Flutter + - IOSSecuritySuite (~> 1.9.10) - just_audio (0.0.1): - Flutter - libwebp (1.3.2): @@ -209,6 +215,8 @@ PODS: - libwebp/sharpyuv (1.3.2) - libwebp/webp (1.3.2): - libwebp/sharpyuv + - live_activities (0.0.1): + - Flutter - local_auth_darwin (0.0.1): - Flutter - FlutterMacOS @@ -231,6 +239,8 @@ PODS: - permission_handler_apple (9.3.0): - Flutter - PromisesObjC (2.4.0) + - quick_actions_ios (0.0.1): + - Flutter - RecaptchaInterop (100.0.0) - record_darwin (1.0.0): - Flutter @@ -310,6 +320,7 @@ DEPENDENCIES: - FirebaseCore - FirebaseMessaging - Flutter (from `Flutter`) + - flutter_app_group_directory (from `.symlinks/plugins/flutter_app_group_directory/ios`) - flutter_contacts (from `.symlinks/plugins/flutter_contacts/ios`) - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) @@ -321,12 +332,15 @@ DEPENDENCIES: - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`) - image_cropper (from `.symlinks/plugins/image_cropper/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + - jailbreak_root_detection (from `.symlinks/plugins/jailbreak_root_detection/ios`) - just_audio (from `.symlinks/plugins/just_audio/ios`) + - live_activities (from `.symlinks/plugins/live_activities/ios`) - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - location (from `.symlinks/plugins/location/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - quick_actions_ios (from `.symlinks/plugins/quick_actions_ios/ios`) - record_darwin (from `.symlinks/plugins/record_darwin/ios`) - share (from `.symlinks/plugins/share/ios`) - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`) @@ -359,6 +373,7 @@ SPEC REPOS: - GoogleUtilities - GTMAppAuth - GTMSessionFetcher + - IOSSecuritySuite - libwebp - Mantle - nanopb @@ -394,6 +409,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/firebase_messaging/ios" Flutter: :path: Flutter + flutter_app_group_directory: + :path: ".symlinks/plugins/flutter_app_group_directory/ios" flutter_contacts: :path: ".symlinks/plugins/flutter_contacts/ios" flutter_image_compress_common: @@ -416,8 +433,12 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/image_cropper/ios" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" + jailbreak_root_detection: + :path: ".symlinks/plugins/jailbreak_root_detection/ios" just_audio: :path: ".symlinks/plugins/just_audio/ios" + live_activities: + :path: ".symlinks/plugins/live_activities/ios" local_auth_darwin: :path: ".symlinks/plugins/local_auth_darwin/darwin" location: @@ -428,6 +449,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" + quick_actions_ios: + :path: ".symlinks/plugins/quick_actions_ios/ios" record_darwin: :path: ".symlinks/plugins/record_darwin/ios" share: @@ -469,6 +492,7 @@ SPEC CHECKSUMS: FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414 FirebaseMessaging: f8a160d99c2c2e5babbbcc90c4a3e15db036aee2 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + flutter_app_group_directory: d2c3337f424828558953172f9378d00df9b7756d flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983 flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 @@ -488,8 +512,11 @@ SPEC CHECKSUMS: GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 + IOSSecuritySuite: b51056d5411aee567153ca86ce7f6edfdc5d2654 + jailbreak_root_detection: b95de80c3e51eec1fc7d0225784d2fc038fa95ed just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 + live_activities: 5a5ddcfe2bd2cbbe7555a5da9c35b07d1a4ff2e8 local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3 location: d5cf8598915965547c3f36761ae9cc4f4e87d22e Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d @@ -499,6 +526,7 @@ SPEC CHECKSUMS: path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + quick_actions_ios: 56f3cbaa71e94f212838d1f9fe354bd0734779bf RecaptchaInterop: 7d1a4a01a6b2cb1610a47ef3f85f0c411434cb21 record_darwin: 3b1a8e7d5c0cbf45ad6165b4d83a6ca643d929c3 SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index c14b593..067e56c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -16,6 +16,9 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + C604FDB02D6C8D6A00CF8873 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C604FDAF2D6C8D6000CF8873 /* Constants.swift */; }; + C604FDB22D6C953400CF8873 /* JailbreakDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C604FDB12D6C953100CF8873 /* JailbreakDetection.swift */; }; + C604FDB52D6C96D000CF8873 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C604FDB32D6C96D000CF8873 /* Localizable.strings */; }; C624C4642BD56D34002834AF /* tone1.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C624C45C2BD56D34002834AF /* tone1.mp3 */; }; C624C4652BD56D34002834AF /* start.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C45D2BD56D34002834AF /* start.wav */; }; C624C4672BD56D34002834AF /* promo.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C45F2BD56D34002834AF /* promo.wav */; }; @@ -73,6 +76,9 @@ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A1987A597103D3E58DD06571 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C604FDAF2D6C8D6000CF8873 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + C604FDB12D6C953100CF8873 /* JailbreakDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JailbreakDetection.swift; sourceTree = ""; }; + C604FDB42D6C96D000CF8873 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; C624C45C2BD56D34002834AF /* tone1.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = tone1.mp3; path = ../../android/app/src/main/res/raw/tone1.mp3; sourceTree = ""; }; C624C45D2BD56D34002834AF /* start.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = start.wav; path = ../../android/app/src/main/res/raw/start.wav; sourceTree = ""; }; C624C45F2BD56D34002834AF /* promo.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = promo.wav; path = ../../android/app/src/main/res/raw/promo.wav; sourceTree = ""; }; @@ -182,6 +188,9 @@ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + C604FDB12D6C953100CF8873 /* JailbreakDetection.swift */, + C604FDB32D6C96D000CF8873 /* Localizable.strings */, + C604FDAF2D6C8D6000CF8873 /* Constants.swift */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, ); path = Runner; @@ -302,6 +311,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, C628BC3F2C31427000E4D33B /* ding.wav in Resources */, C690B4752A80554500E1D66E /* GoogleService-Info.plist in Resources */, + C604FDB52D6C96D000CF8873 /* Localizable.strings in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, C624C4692BD56D34002834AF /* iphone_ringtone.wav in Resources */, C624C4642BD56D34002834AF /* tone1.mp3 in Resources */, @@ -438,6 +448,8 @@ files = ( 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + C604FDB02D6C8D6A00CF8873 /* Constants.swift in Sources */, + C604FDB22D6C953400CF8873 /* JailbreakDetection.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -468,6 +480,14 @@ name = LaunchScreen.storyboard; sourceTree = ""; }; + C604FDB32D6C96D000CF8873 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + C604FDB42D6C96D000CF8873 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 3966f9f..a5f250b 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,19 +2,39 @@ import UIKit import Flutter import FirebaseCore import GoogleMaps -// import Constants @main @objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GMSServices.provideAPIKey(Constants.googleMapsAPIKey) + FirebaseApp.configure() + GeneratedPluginRegistrant.register(with: self) - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GMSServices.provideAPIKey("AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0") - FirebaseApp.configure() - GeneratedPluginRegistrant.register(with: self) - return true - } + if JailbreakDetection.isJailbroken() { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + self.showJailbreakAlert() + } + } + + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func showJailbreakAlert() { + guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else { return } + + let alert = UIAlertController( + title: "تحذير أمني", + message: "تم اكتشاف أن جهازك يحتوي على جيلبريك. لا يمكن تشغيل التطبيق على هذا الجهاز.", + preferredStyle: .alert + ) + + alert.addAction(UIAlertAction(title: "إنهاء التطبيق", style: .destructive) { _ in + exit(0) + }) + + rootVC.present(alert, animated: true, completion: nil) + } } - diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index f3c2851..19d3697 100644 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -1,8 +1,10 @@ - - + + + - + + @@ -14,13 +16,14 @@ - + - + + diff --git a/ios/Runner/Constants.swift b/ios/Runner/Constants.swift index b60605b..75776b7 100644 --- a/ios/Runner/Constants.swift +++ b/ios/Runner/Constants.swift @@ -2,7 +2,11 @@ // Constants.swift // Runner // -// Created by Hamza Aleghwairyeen on 15/01/2024. +// Created by Hamza Aleghwairyeen on 24/02/2025. // import Foundation + +struct Constants { + static let googleMapsAPIKey = "AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0" +} diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index ca5aa29..711ea95 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -35,7 +35,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 93 + 94 CFBundleSignature ???? CFBundleURLTypes @@ -50,7 +50,7 @@ CFBundleVersion - 5.0.93 + 5.0.94 FirebaseAppDelegateProxyEnabled NO GMSApiKey diff --git a/ios/Runner/JailbreakDetection.swift b/ios/Runner/JailbreakDetection.swift new file mode 100644 index 0000000..17eb672 --- /dev/null +++ b/ios/Runner/JailbreakDetection.swift @@ -0,0 +1,26 @@ +// +// JailbreakDetection.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 24/02/2025. +// + + +import Foundation + +class JailbreakDetection { + static func isJailbroken() -> Bool { + let paths = [ + "/Applications/Cydia.app", + "/Library/MobileSubstrate/MobileSubstrate.dylib", + "/usr/sbin/sshd", + "/etc/apt" + ] + for path in paths { + if FileManager.default.fileExists(atPath: path) { + return true + } + } + return false + } +} diff --git a/ios/Runner/en.lproj/Localizable.strings b/ios/Runner/en.lproj/Localizable.strings new file mode 100644 index 0000000..dda4b9d --- /dev/null +++ b/ios/Runner/en.lproj/Localizable.strings @@ -0,0 +1,7 @@ +/* + Localizable.strings + Runner + + Created by Hamza Aleghwairyeen on 24/02/2025. + +*/ diff --git a/lib/constant/api_key.dart b/lib/constant/api_key.dart index b7c1340..466ee1e 100644 --- a/lib/constant/api_key.dart +++ b/lib/constant/api_key.dart @@ -4,6 +4,16 @@ import '../env/env.dart'; import 'char_map.dart'; class AK { + static final String sss_pass = X.r(X.r(X.r(Env.sss_pass, cn), cC), cs); + static final String allowed = Env.allowed; + static final String passnpassenger = X + .r(X.r(X.r(Env.passnpassenger, cn), cC), cs) + .toString() + .split(Env.addd)[0]; + static final String newId = Env.newId; + static final String sss_encryptionSalt = + X.r(X.r(X.r(Env.sss_encryptionSalt, cn), cC), cs); + static final String publishableKeyStripe = X.r(X.r(X.r(Env.stripePublishableKe, cn), cC), cs); static final String secretKeyStripe = @@ -65,7 +75,7 @@ class AK { static final String payMobOutPassword = X.r(X.r(X.r(Env.payMobOutPassword, cn), cC), cs); - static final String privateKeyFCM = Env.privateKeyFCM; + // static final String privateKeyFCM = Env.privateKeyFCM; static final String payMobOutUserName = X.r(X.r(X.r(Env.payMobOutUserName, cn), cC), cs); diff --git a/lib/constant/box_name.dart b/lib/constant/box_name.dart index e5d1beb..f095fb5 100644 --- a/lib/constant/box_name.dart +++ b/lib/constant/box_name.dart @@ -2,7 +2,13 @@ class BoxName { static const String driverID = "driverID"; static const String countryCode = "countryCode"; static const String googlaMapApp = "googlaMapApp"; - + static const String keyOfApp = 'keyOfApp'; + static const String initializationVector = 'initializationVector'; + static const String firstTimeLoadKey = 'firstTimeLoadKey'; + static const String jwt = "jwt"; + static const String fingerPrint = "fingerPrint"; + static const String payMobApikey = "payMobApikey"; + static const String refreshToken = "refreshToken"; static const String lang = "lang"; static const String isvibrate = "isvibrate"; static const String myListString = "myListString"; diff --git a/lib/constant/info.dart b/lib/constant/info.dart index 20798f0..452080b 100644 --- a/lib/constant/info.dart +++ b/lib/constant/info.dart @@ -9,7 +9,7 @@ class AppInformation { static const String email = 'hamzaayed@Sefer.live'; static const String complaintPrompt = 'for this data for complaint from driver or passenger i collect all data i want you analyze this complaint and show what is reason and what is solution .this data collected from many table to find solution if payment in visa not complete and if ride status is finished it will be paymnet in payment table if ride status is not finished there is no need to pay and payment table is null for this ride and if paymentFromPaymentTable not null and visa type not cash the payment sucssessed . if ratingpassenger is low or passengr rating drivers low grade then dont mine of this passenger ,look at driver too like passengerratingdriver with rating or ratingtopassenger .in json add status of complaint and message to passenger and message to driver and message to call center write in arabic in json output with key in english .for output please just json i want'; - + static const String addd = 'BlBlNl'; static const String privacyPolicy = ''' diff --git a/lib/constant/links.dart b/lib/constant/links.dart index 705d595..41dd795 100644 --- a/lib/constant/links.dart +++ b/lib/constant/links.dart @@ -1,5 +1,7 @@ // import 'package:sefer_driver/env/env.dart'; +import 'package:sefer_driver/env/env.dart'; + import '../main.dart'; import 'box_name.dart'; @@ -29,6 +31,12 @@ class AppLink { static String seferAlexandriaServer = box.read('Alexandria'); // static final String server = Env.serverPHP; + static String loginJwtDriver = "$server/loginJwtDriver.php"; + static String loginJwtWalletDriver = + "$seferPaymentServer/loginJwtWalletDriver.php"; + static String loginFirstTimeDriver = + "https://server.sefer.live/sefer.click/sefer/loginFirstTimeDriver.php"; + static String googleMapsLink = 'https://maps.googleapis.com/maps/api/'; static String llama = 'https://api.llama-api.com/chat/completions'; static String gemini = @@ -93,7 +101,8 @@ class AppLink { static String getTripCountByCaptain = "$ride/rides/getTripCountByCaptain.php"; static String getRideOrderID = "$ride/rides/getRideOrderID.php"; static String getRideStatus = "$ride/rides/getRideStatus.php"; - static String getapiKey = "$ride/apiKey/get.php"; + static String getapiKey = Env.getapiKey; + static String getapiKeySefer = "https://api.sefer.live/sefer/ride/apiKey/get.php"; static String getRideStatusBegin = "$ride/rides/getRideStatusBegin.php"; diff --git a/lib/constant/table_names.dart b/lib/constant/table_names.dart index b3c8353..4366a34 100644 --- a/lib/constant/table_names.dart +++ b/lib/constant/table_names.dart @@ -8,3 +8,11 @@ class TableName { static const String captainNotification = "captainNotification"; static const String applyRideFromOverLay = "applyRideFromOverLay"; } + +class Driver { + static const String driverPass = 'MG6DEJZSczBT6Rx0jOlehQ=='; + static const String payMobApikey = 'payMobApikey'; + static const String initializationVector = 'initializationVector'; + static const String keyOfApp = 'keyOfApp'; + static const String FCM_PRIVATE_KEY = 'FCM_PRIVATE_KEY'; +} diff --git a/lib/controller/auth/captin/history_captain.dart b/lib/controller/auth/captin/history_captain.dart index 82e9011..9b66762 100644 --- a/lib/controller/auth/captin/history_captain.dart +++ b/lib/controller/auth/captin/history_captain.dart @@ -47,7 +47,7 @@ class HistoryCaptainController extends GetxController { isloading = true; var res = await CRUD().get( link: AppLink.getRideOrderID, - payload: {'id': encryptionHelper.encryptData(orderId)}); + payload: {'id': EncryptionHelper.instance.encryptData(orderId)}); historyDetailsData = jsonDecode(res); isloading = false; update(); diff --git a/lib/controller/auth/captin/invit_controller.dart b/lib/controller/auth/captin/invit_controller.dart index b768d22..576b0b7 100644 --- a/lib/controller/auth/captin/invit_controller.dart +++ b/lib/controller/auth/captin/invit_controller.dart @@ -149,9 +149,9 @@ Download the Tripz app now and enjoy your ride! void onSelectDriverInvitation(int index) async { MyDialog().getDialog( int.parse((driverInvitationData[index]['countOfInvitDriver'])) < 100 - ? '${'When'.tr} ${encryptionHelper.decryptData(driverInvitationData[index]['invitorName'])} ${"complete, you can claim your gift".tr} ' + ? '${'When'.tr} ${EncryptionHelper.instance.decryptData(driverInvitationData[index]['invitorName'])} ${"complete, you can claim your gift".tr} ' : 'You deserve the gift'.tr, - '${encryptionHelper.decryptData(driverInvitationData[index]['invitorName'])} ${(driverInvitationData[index]['countOfInvitDriver'])} / 100 ${'Trip'.tr}', + '${EncryptionHelper.instance.decryptData(driverInvitationData[index]['invitorName'])} ${(driverInvitationData[index]['countOfInvitDriver'])} / 100 ${'Trip'.tr}', () async { if (int.parse((driverInvitationData[index]['countOfInvitDriver'])) < 100) { @@ -161,23 +161,24 @@ Download the Tripz app now and enjoy your ride! if ((driverInvitationData[index]['isGiftToken']).toString() == '0') { Get.back(); await CRUD().post(link: AppLink.updateInviteDriver, payload: { - 'id': encryptionHelper + 'id': EncryptionHelper.instance .encryptData(driverInvitationData[index]['id']) }); await Get.find().addDriverPayment( 'paymentMethod', - encryptionHelper.encryptData('500'), + EncryptionHelper.instance.encryptData('500'), '', ); // add for invitor too await Get.find().addDriverWalletToInvitor( 'paymentMethod', - encryptionHelper + EncryptionHelper.instance .encryptData(driverInvitationData[index]['driverInviterId']), - encryptionHelper.encryptData('500'), + EncryptionHelper.instance.encryptData('500'), ); await Get.find().addSeferWallet( - 'giftInvitation', encryptionHelper.encryptData('-1000')); + 'giftInvitation', + EncryptionHelper.instance.encryptData('-1000')); NotificationCaptainController().addNotificationCaptain( driverInvitationData[index]['driverInviterId'].toString(), "You have got a gift for invitation".tr, @@ -205,9 +206,9 @@ Download the Tripz app now and enjoy your ride! int.parse(driverInvitationDataToPassengers[index]['countOfInvitDriver'] .toString()) < 3 - ? '${'When'.tr} ${encryptionHelper.decryptData(driverInvitationDataToPassengers[index]['passengerName'].toString())} ${"complete, you can claim your gift".tr} ' + ? '${'When'.tr} ${EncryptionHelper.instance.decryptData(driverInvitationDataToPassengers[index]['passengerName'].toString())} ${"complete, you can claim your gift".tr} ' : 'You deserve the gift'.tr, - '${encryptionHelper.decryptData(driverInvitationDataToPassengers[index]['passengerName'].toString())} ${driverInvitationDataToPassengers[index]['countOfInvitDriver']} / 3 ${'Trip'.tr}', + '${EncryptionHelper.instance.decryptData(driverInvitationDataToPassengers[index]['passengerName'].toString())} ${driverInvitationDataToPassengers[index]['countOfInvitDriver']} / 3 ${'Trip'.tr}', () async { if (int.parse(driverInvitationDataToPassengers[index] ['countOfInvitDriver'] diff --git a/lib/controller/auth/captin/login_captin_controller.dart b/lib/controller/auth/captin/login_captin_controller.dart index 3e421a2..18ebfa3 100644 --- a/lib/controller/auth/captin/login_captin_controller.dart +++ b/lib/controller/auth/captin/login_captin_controller.dart @@ -1,6 +1,8 @@ import 'dart:convert'; +import 'dart:io'; import 'dart:math'; - +import 'package:http/http.dart' as http; +import 'package:secure_string_operations/secure_string_operations.dart'; import 'package:sefer_driver/controller/functions/location_background_controller.dart'; import 'package:sefer_driver/views/auth/captin/cards/sms_signup.dart'; import 'package:sefer_driver/views/widgets/elevated_btn.dart'; @@ -15,10 +17,16 @@ import 'package:sefer_driver/main.dart'; import 'package:sefer_driver/views/home/Captin/home_captain/home_captin.dart'; import 'package:location/location.dart'; +import '../../../constant/api_key.dart'; +import '../../../constant/char_map.dart'; import '../../../constant/info.dart'; +import '../../../constant/table_names.dart'; +import '../../../print.dart'; import '../../../views/auth/captin/cards/egypt_card_a_i.dart'; import '../../firebase/firbase_messge.dart'; import '../../functions/encrypt_decrypt.dart'; +import '../../functions/package_info.dart'; +import '../../functions/secure_storage.dart'; class LoginDriverController extends GetxController { final formKey = GlobalKey(); @@ -82,6 +90,77 @@ class LoginDriverController extends GetxController { update(); } + var dev = ''; + getJwtWallet() async { + await SecurityHelper.performSecurityChecks(); + String fingerPrint = await getDeviceFingerprint(); + dev = Platform.isAndroid ? 'android' : 'ios'; + var payload = { + 'id': box.read(BoxName.passengerID), + 'password': AK.passnpassenger, + 'aud': '${AK.allowed}$dev', + 'fingerPrint': fingerPrint + }; + var response1 = await http.post( + Uri.parse(AppLink.loginJwtWalletDriver), + body: payload, + ); + + return jsonDecode(response1.body)['jwt'].toString(); + } + + getJWT() async { + // await SecurityHelper.performSecurityChecks(); + dev = Platform.isAndroid ? 'android' : 'ios'; + if (box.read(BoxName.firstTimeLoadKey).toString() != 'false') { + var response0 = await http.post( + Uri.parse(AppLink.loginFirstTimeDriver), + body: { + 'id': box.read(BoxName.passengerID) ?? AK.newId, + 'password': AK.passnpassenger, + 'aud': '${AK.allowed}$dev', + }, + ); + if (response0.statusCode == 200) { + final decodedResponse1 = jsonDecode(response0.body); + + final jwt = decodedResponse1['jwt']; + box.write(BoxName.jwt, X.c(X.c(X.c(jwt, cn), cC), cs)); + + await AppInitializer().getAIKey(Driver.keyOfApp); + await AppInitializer().getAIKey(Driver.initializationVector); + await Future.delayed(Duration.zero); + await EncryptionHelper.initialize(); + + await AppInitializer().getAIKey(Driver.payMobApikey); + await AppInitializer().getAIKey(Driver.FCM_PRIVATE_KEY); + + await AppInitializer().getKey(); + } else {} + } else { + await EncryptionHelper.initialize(); + + var payload = { + 'id': box.read(BoxName.passengerID), + 'password': AK.passnpassenger, + 'aud': '${AK.allowed}$dev', + }; + var response1 = await http.post( + Uri.parse(AppLink.loginJwtDriver), + body: payload, + ); + + if (response1.statusCode == 200) { + final decodedResponse1 = jsonDecode(response1.body); + Log.print('decodedResponse1: ${decodedResponse1}'); + + final jwt = decodedResponse1['jwt']; + await box.write(BoxName.jwt, X.c(X.c(X.c(jwt, cn), cC), cs)); + await AppInitializer().getKey(); + } + } + } + Future getLocationPermission() async { Get.put(LocationBackgroundController()).requestLocationPermission(); @@ -119,7 +198,7 @@ class LoginDriverController extends GetxController { update(); var res = await CRUD().get(link: AppLink.loginFromGoogleCaptin, payload: { 'email': email.toString().contains('@') - ? encryptionHelper.encryptData(email) + ? EncryptionHelper.instance.encryptData(email) : email, 'id': driverID, }); @@ -161,13 +240,13 @@ class LoginDriverController extends GetxController { (jsonDecoeded['data'][0]['accountBank'])); box.write( BoxName.nameDriver, - '${encryptionHelper.decryptData(jsonDecoeded['data'][0]['first_name'])}' - ' ${encryptionHelper.decryptData(jsonDecoeded['data'][0]['last_name'])}'); + '${EncryptionHelper.instance.decryptData(jsonDecoeded['data'][0]['first_name'])}' + ' ${EncryptionHelper.instance.decryptData(jsonDecoeded['data'][0]['last_name'])}'); if (((jsonDecoeded['data'][0]['model']) .toString() .contains('دراجه') || jsonDecoeded['data'][0]['make'].toString().contains('دراجه '))) { - if (encryptionHelper + if (EncryptionHelper.instance .decryptData(jsonDecoeded['data'][0]['gender']) .toString() == 'Male') { @@ -197,13 +276,14 @@ class LoginDriverController extends GetxController { payload: {'captain_id': (box.read(BoxName.driverID)).toString()}); if (token != 'failure') { - if (encryptionHelper + if (EncryptionHelper.instance .decryptData(jsonDecode(token)['data'][0]['token']) != - encryptionHelper.decryptData(box.read(BoxName.tokenDriver))) { + EncryptionHelper.instance + .decryptData(box.read(BoxName.tokenDriver))) { Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP( 'token change'.tr, 'change device'.tr, - encryptionHelper + EncryptionHelper.instance .decryptData(jsonDecode(token)['data'][0]['token']) .toString(), [], @@ -262,11 +342,11 @@ class LoginDriverController extends GetxController { update(); var res = await CRUD() .get(link: AppLink.loginUsingCredentialsWithoutGoogle, payload: { - 'email': encryptionHelper.encryptData(email), + 'email': EncryptionHelper.instance.encryptData(email), 'password': password, }); - box.write( - BoxName.emailDriver, encryptionHelper.encryptData(email).toString()); + box.write(BoxName.emailDriver, + EncryptionHelper.instance.encryptData(email).toString()); print(res); if (res == 'failure') { //Failure @@ -292,7 +372,7 @@ class LoginDriverController extends GetxController { box.write(BoxName.phoneDriver, (jsonDecoeded['data'][0]['phone'])); box.write( BoxName.nameArabic, - encryptionHelper + EncryptionHelper.instance .decryptData(jsonDecoeded['data'][0]['name_arabic'])); box.write( BoxName.bankCodeDriver, (jsonDecoeded['data'][0]['bankCode'])); @@ -300,11 +380,11 @@ class LoginDriverController extends GetxController { jsonDecoeded['data'][0]['accountBank']); box.write( BoxName.nameDriver, - '${encryptionHelper.decryptData(jsonDecoeded['data'][0]['first_name'])}' - ' ${encryptionHelper.decryptData(jsonDecoeded['data'][0]['last_name'])}'); + '${EncryptionHelper.instance.decryptData(jsonDecoeded['data'][0]['first_name'])}' + ' ${EncryptionHelper.instance.decryptData(jsonDecoeded['data'][0]['last_name'])}'); if ((jsonDecoeded['data'][0]['model'].toString().contains('دراجه') || jsonDecoeded['data'][0]['make'].toString().contains('دراجه '))) { - if (encryptionHelper + if (EncryptionHelper.instance .decryptData(jsonDecoeded['data'][0]['gender']) .toString() == 'Male') { @@ -314,7 +394,7 @@ class LoginDriverController extends GetxController { } } else if (int.parse(jsonDecoeded['data'][0]['year'].toString()) > 2017) { - if (encryptionHelper + if (EncryptionHelper.instance .decryptData(jsonDecoeded['data'][0]['gender']) .toString() != 'Male') { @@ -337,13 +417,14 @@ class LoginDriverController extends GetxController { payload: {'captain_id': box.read(BoxName.driverID).toString()}); if (token != 'failure') { - if (encryptionHelper + if (EncryptionHelper.instance .decryptData(jsonDecode(token)['data'][0]['token']) != - encryptionHelper.decryptData(box.read(BoxName.tokenDriver))) { + EncryptionHelper.instance + .decryptData(box.read(BoxName.tokenDriver))) { Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP( 'token change'.tr, 'change device'.tr, - encryptionHelper + EncryptionHelper.instance .decryptData(jsonDecode(token)['data'][0]['token']) .toString(), [], diff --git a/lib/controller/auth/captin/register_captin_controller.dart b/lib/controller/auth/captin/register_captin_controller.dart index 5ed8d52..bc1473b 100644 --- a/lib/controller/auth/captin/register_captin_controller.dart +++ b/lib/controller/auth/captin/register_captin_controller.dart @@ -108,8 +108,8 @@ class RegisterCaptainController extends GetxController { if (isValidEgyptianPhoneNumber(phoneController.text)) { var responseCheker = await CRUD() .post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: { - 'phone_number': - encryptionHelper.encryptData('+2${phoneController.text}'), + 'phone_number': EncryptionHelper.instance + .encryptData('+2${phoneController.text}'), }); if (responseCheker != 'failure') { var d = jsonDecode(responseCheker); @@ -117,18 +117,20 @@ class RegisterCaptainController extends GetxController { Get.snackbar('Phone number is verified before'.tr, '', backgroundColor: AppColor.greenColor); box.write(BoxName.phoneVerified, '1'); - box.write(BoxName.phone, - encryptionHelper.encryptData('+2${phoneController.text}')); + box.write( + BoxName.phone, + EncryptionHelper.instance + .encryptData('+2${phoneController.text}')); await Get.put(LoginDriverController()).loginWithGoogleCredential( box.read(BoxName.driverID).toString(), box.read(BoxName.emailDriver).toString(), ); } else { await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { - 'phone_number': - encryptionHelper.encryptData('+2${phoneController.text}'), - 'token_code': - encryptionHelper.encryptData(randomNumber.toString()), + 'phone_number': EncryptionHelper.instance + .encryptData('+2${phoneController.text}'), + 'token_code': EncryptionHelper.instance + .encryptData(randomNumber.toString()), "driverId": box.read(BoxName.driverID), "email": box.read(BoxName.emailDriver), }); @@ -143,10 +145,10 @@ class RegisterCaptainController extends GetxController { } } else { await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { - 'phone_number': - encryptionHelper.encryptData('+2${phoneController.text}'), - 'token_code': - encryptionHelper.encryptData(randomNumber.toString()), + 'phone_number': EncryptionHelper.instance + .encryptData('+2${phoneController.text}'), + 'token_code': EncryptionHelper.instance + .encryptData(randomNumber.toString()), "driverId": box.read(BoxName.driverID), "email": box.read(BoxName.emailDriver), }); @@ -247,7 +249,7 @@ class RegisterCaptainController extends GetxController { mySnackbarSuccess('Phone number is already verified'.tr); box.write(BoxName.phoneVerified, '1'); box.write(BoxName.phone, - encryptionHelper.encryptData('+2${phoneController.text}')); + EncryptionHelper.instance.encryptData('+2${phoneController.text}')); Get.put(LoginDriverController()).loginWithGoogleCredential( box.read(BoxName.driverID).toString(), box.read(BoxName.emailDriver).toString(), @@ -262,8 +264,9 @@ class RegisterCaptainController extends GetxController { await CRUD().post( link: AppLink.sendVerifyOtpMessage, payload: { - 'phone_number': encryptionHelper.encryptData('+2$phoneNumber'), - 'token_code': encryptionHelper.encryptData(randomNumber.toString()), + 'phone_number': EncryptionHelper.instance.encryptData('+2$phoneNumber'), + 'token_code': + EncryptionHelper.instance.encryptData(randomNumber.toString()), 'driverId': box.read(BoxName.driverID), 'email': box.read(BoxName.emailDriver), }, @@ -282,13 +285,14 @@ class RegisterCaptainController extends GetxController { if (formKey3.currentState!.validate()) { var res = await CRUD().post(link: AppLink.verifyOtpDriver, payload: { 'phone_number': - encryptionHelper.encryptData('+2${phoneController.text}'), - 'token_code': encryptionHelper.encryptData(verifyCode.text.toString()), + EncryptionHelper.instance.encryptData('+2${phoneController.text}'), + 'token_code': + EncryptionHelper.instance.encryptData(verifyCode.text.toString()), }); if (res != 'failure') { // var dec = jsonDecode(res); box.write(BoxName.phoneDriver, - encryptionHelper.encryptData('+2${phoneController.text}')); + EncryptionHelper.instance.encryptData('+2${phoneController.text}')); box.write(BoxName.phoneVerified, '1'); // loginDriverController.isGoogleLogin == true @@ -313,10 +317,10 @@ class RegisterCaptainController extends GetxController { sendVerifications() async { var res = await CRUD().post(link: AppLink.verifyEmail, payload: { 'email': emailController.text.isEmpty - ? encryptionHelper.encryptData( + ? EncryptionHelper.instance.encryptData( Get.find().emailController.text.toString()) - : encryptionHelper.encryptData(emailController.text), - 'token': encryptionHelper.encryptData(verifyCode.text), + : EncryptionHelper.instance.encryptData(emailController.text), + 'token': EncryptionHelper.instance.encryptData(verifyCode.text), }); if (res != 'failure') { diff --git a/lib/controller/auth/google_sign.dart b/lib/controller/auth/google_sign.dart index 576fd3f..59cf9de 100644 --- a/lib/controller/auth/google_sign.dart +++ b/lib/controller/auth/google_sign.dart @@ -126,7 +126,7 @@ class GoogleSignInHelper { box.write(BoxName.driverID, (user.id) ?? 'Unknown ID'); // Ensure there's a fallback value box.write(BoxName.emailDriver, - encryptionHelper.encryptData(user.email) ?? 'Unknown Email'); + EncryptionHelper.instance.encryptData(user.email) ?? 'Unknown Email'); } // Method to handle Google Sign-Out diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart index 1e904dd..91436c3 100644 --- a/lib/controller/firebase/firbase_messge.dart +++ b/lib/controller/firebase/firbase_messge.dart @@ -71,7 +71,8 @@ class FirebaseMessagesController extends GetxController { Future getToken() async { fcmToken.getToken().then((token) { // Log.print('token: ${token}'); - box.write(BoxName.tokenDriver, encryptionHelper.encryptData(token!)); + box.write( + BoxName.tokenDriver, EncryptionHelper.instance.encryptData(token!)); }); FirebaseMessaging.onMessage.listen((RemoteMessage message) { @@ -400,6 +401,25 @@ class FirebaseMessagesController extends GetxController { })); } + late String serviceAccountKeyJson; + @override + Future onInit() async { + super.onInit(); + try { + var encryptedKey = await storage.read(key: 'FCM_PRIVATE_KEY'); + // Log.print('encryptedKey: ${encryptedKey}'); + if (encryptedKey != null) { + serviceAccountKeyJson = + EncryptionHelper.instance.decryptData(encryptedKey); + // Log.print('serviceAccountKeyJson: ${serviceAccountKeyJson}'); + } else { + print('🔴 Error: FCM_PRIVATE_KEY not found in Secure Storage'); + } + } catch (e) { + print('🔴 Error decrypting FCM key: $e'); + } + } + void sendNotificationAll(String title, body, tone) async { // Get the token you want to subtract. String token = box.read(BoxName.tokenFCM); @@ -411,26 +431,16 @@ class FirebaseMessagesController extends GetxController { // box.write(BoxName.tokens, tokens); tokens = box.read(BoxName.tokens); for (var i = 0; i < tokens.length; i++) { - String serviceAccountKeyJson = '''{ - "type": "service_account", - "project_id": "ride-b1bd8", - "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249", - "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n", - "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com", - "client_id": "111210077025005706623", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} -'''; // As defined above - + if (serviceAccountKeyJson.isEmpty) { + print("🔴 Error: Service Account Key is empty"); + return; + } // Initialize AccessTokenManager final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); // Obtain an OAuth 2.0 access token final accessToken = await accessTokenManager.getAccessToken(); + // Log.print('accessToken: ${accessToken}'); // Send the notification final response = await http @@ -479,26 +489,16 @@ class FirebaseMessagesController extends GetxController { String title, body, token, List map, String tone, {int retryCount = 2}) async { try { - String serviceAccountKeyJson = '''{ - "type": "service_account", - "project_id": "ride-b1bd8", - "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249", - "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n", - "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com", - "client_id": "111210077025005706623", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} -'''; // As defined above - + if (serviceAccountKeyJson.isEmpty) { + print("🔴 Error: Service Account Key is empty"); + return; + } // Initialize AccessTokenManager final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); // Obtain an OAuth 2.0 access token final accessToken = await accessTokenManager.getAccessToken(); + // Log.print('accessToken: ${accessToken}'); // Send the notification final response = await http.post( @@ -571,26 +571,16 @@ class FirebaseMessagesController extends GetxController { String title, body, token, List map, String tone, {int retryCount = 2}) async { try { - String serviceAccountKeyJson = '''{ - "type": "service_account", - "project_id": "ride-b1bd8", - "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249", - "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n", - "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com", - "client_id": "111210077025005706623", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} -'''; // As defined above - + if (serviceAccountKeyJson.isEmpty) { + print("🔴 Error: Service Account Key is empty"); + return; + } // Initialize AccessTokenManager final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); // Obtain an OAuth 2.0 access token final accessToken = await accessTokenManager.getAccessToken(); + // Log.print('accessToken: ${accessToken}'); // Send the notification final response = await http.post( @@ -666,26 +656,16 @@ class FirebaseMessagesController extends GetxController { {int retryCount = 2}) async { try { final privateKey = await storage.read(key: 'FCM_PRIVATE_KEY'); - String serviceAccountKeyJson = '''{ - "type": "service_account", - "project_id": "ride-b1bd8", - "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249", - "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n", - "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com", - "client_id": "111210077025005706623", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} -'''; // As defined above - + if (serviceAccountKeyJson.isEmpty) { + print("🔴 Error: Service Account Key is empty"); + return; + } // Initialize AccessTokenManager final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); // Obtain an OAuth 2.0 access token final accessToken = await accessTokenManager.getAccessToken(); + // Log.print('accessToken: ${accessToken}'); // Send the notification final response = await http.post( diff --git a/lib/controller/functions/crud.dart b/lib/controller/functions/crud.dart index 7c06e58..6987f5d 100644 --- a/lib/controller/functions/crud.dart +++ b/lib/controller/functions/crud.dart @@ -1,12 +1,18 @@ import 'dart:convert'; +import 'package:secure_string_operations/secure_string_operations.dart'; import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/constant/links.dart'; +import 'package:sefer_driver/controller/auth/captin/login_captin_controller.dart'; +import 'package:sefer_driver/controller/functions/add_error.dart'; import 'package:sefer_driver/main.dart'; import 'package:get/get.dart'; import 'package:http/http.dart' as http; import 'package:sefer_driver/env/env.dart'; +import 'package:sefer_driver/views/widgets/error_snakbar.dart'; import '../../constant/api_key.dart'; +import '../../constant/char_map.dart'; +import '../../constant/info.dart'; import '../../print.dart'; import 'gemeni.dart'; import 'upload_image.dart'; @@ -25,28 +31,43 @@ class CRUD { headers: { "Content-Type": "application/x-www-form-urlencoded", 'Authorization': - 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}', + 'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}' }, ); - Log.print('request: ${response.request}'); - Log.print('response: ${response.body}'); - Log.print('payload: ${payload}'); - // if (response.statusCode == 200) { - var jsonData = jsonDecode(response.body); - if (jsonData['status'] == 'success') { - return response.body; - } + if (response.statusCode == 200) { + var jsonData = jsonDecode(response.body); + if (jsonData['status'] == 'success') { + return response.body; + } - return jsonData['status']; + return jsonData['status']; + } else if (response.statusCode == 401) { + // Specifically handle 401 Unauthorized + var jsonData = jsonDecode(response.body); + + if (jsonData['error'] == 'Token expired') { + // Show snackbar prompting to re-login + await Get.put(LoginDriverController()).getJWT(); + mySnackbarSuccess('please order now'.tr); + + return 'token_expired'; // Return a specific value for token expiration + } else { + // Other 401 errors + addError('Unauthorized: ${jsonData['error']}', 'crud().post - 401'); + return 'failure'; + } + } else { + addError('Non-200 response code: ${response.statusCode}', + 'crud().post - Other'); + return 'failure'; + } } - // } - Future post({ + Future getWallet({ required String link, Map? payload, }) async { - // String? basicAuthCredentials = - // await storage.read(key: BoxName.basicAuthCredentials); + var s = await LoginDriverController().getJwtWallet(); var url = Uri.parse( link, ); @@ -55,25 +76,94 @@ class CRUD { body: payload, headers: { "Content-Type": "application/x-www-form-urlencoded", - 'Authorization': - 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}', + 'Authorization': 'Bearer $s' }, ); - Log.print('request: ${response.request}'); - Log.print('response: ${response.body}'); - Log.print('payload: ${payload}'); - var jsonData = jsonDecode(response.body); if (response.statusCode == 200) { + var jsonData = jsonDecode(response.body); if (jsonData['status'] == 'success') { return response.body; + } + + return jsonData['status']; + } else if (response.statusCode == 401) { + // Specifically handle 401 Unauthorized + var jsonData = jsonDecode(response.body); + + if (jsonData['error'] == 'Token expired') { + // Show snackbar prompting to re-login + await Get.put(LoginDriverController()).getJwtWallet(); + + return 'token_expired'; // Return a specific value for token expiration } else { - // String errorMessage = jsonData['message']; - // Get.snackbar('Error'.tr, errorMessage.tr, - // backgroundColor: AppColor.redColor); - return (jsonData['status']); + // Other 401 errors + addError('Unauthorized: ${jsonData['error']}', 'crud().post - 401'); + return 'failure'; } } else { - return response.statusCode; + addError('Non-200 response code: ${response.statusCode}', + 'crud().post - Other'); + return 'failure'; + } + } + + Future post( + {required String link, Map? payload}) async { + var url = Uri.parse(link); + try { + var response = await http.post( + url, + body: payload, + headers: { + "Content-Type": "application/x-www-form-urlencoded", + 'Authorization': + 'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}' + // 'Authorization': 'Bearer ${box.read(BoxName.jwt)}' + }, + ); + if (response.statusCode == 200) { + try { + var jsonData = jsonDecode(response.body); + if (jsonData['status'] == 'success') { + return jsonData; + } else { + return jsonData['status']; + } + } catch (e) { + addError(e.toString(), 'crud().post - JSON decoding'); + return 'failure'; + } + } else if (response.statusCode == 401) { + // Specifically handle 401 Unauthorized + var jsonData = jsonDecode(response.body); + + if (jsonData['error'] == 'Token expired') { + // Show snackbar prompting to re-login + await Get.put(LoginDriverController()).getJWT(); + // MyDialog().getDialog( + // 'Session expired. Please log in again.'.tr, + // '', + // () { + // Get.put(LoginController()).loginUsingCredentials( + // box.read(BoxName.passengerID), box.read(BoxName.email)); + // Get.back(); + // }, + // ); + + return 'token_expired'; // Return a specific value for token expiration + } else { + // Other 401 errors + addError('Unauthorized: ${jsonData['error']}', 'crud().post - 401'); + return 'failure'; + } + } else { + addError('Non-200 response code: ${response.statusCode}', + 'crud().post - Other'); + return 'failure'; + } + } catch (e) { + addError('HTTP request error: $e', 'crud().post - HTTP'); + return 'failure'; } } diff --git a/lib/controller/functions/encrypt_decrypt.dart b/lib/controller/functions/encrypt_decrypt.dart index d6f6536..4a97641 100644 --- a/lib/controller/functions/encrypt_decrypt.dart +++ b/lib/controller/functions/encrypt_decrypt.dart @@ -1,34 +1,50 @@ import 'package:encrypt/encrypt.dart' as encrypt; import 'package:flutter/foundation.dart'; -import '../../env/env.dart'; - -var secretKey = Env.keyOfApp - .toString() - .split('XrXlBl')[0]; // Must be 16 characters for AES-128 -String initializationVector = Env.initializationVector; // Must be 16 characters - -final encryptionHelper = EncryptionHelper( - secretKey: secretKey, - initializationVector: initializationVector, -); +import '../../constant/box_name.dart'; +import '../../main.dart'; class EncryptionHelper { - final encrypt.Key key; - final encrypt.IV iv; + static EncryptionHelper? _instance; - EncryptionHelper( - {required String secretKey, required String initializationVector}) - : key = encrypt.Key.fromUtf8(secretKey), - iv = encrypt.IV.fromUtf8(initializationVector); + late final encrypt.Key key; + late final encrypt.IV iv; - // Initialize the helper + EncryptionHelper._(this.key, this.iv); + static EncryptionHelper get instance { + if (_instance == null) { + throw Exception( + "EncryptionHelper is not initialized. Call `await EncryptionHelper.initialize()` in main."); + } + return _instance!; + } - /// Encrypts the given plain text + /// Initializes and stores the instance globally + static Future initialize() async { + if (_instance != null) { + debugPrint("EncryptionHelper is already initialized."); + return; // Prevent re-initialization + } + debugPrint("Initializing EncryptionHelper..."); + // Read stored keys + String? keyOfApp = await storage.read(key: BoxName.keyOfApp); + // Log.print('keyOfApp: ${keyOfApp}'); + String? initializationVector = + await storage.read(key: BoxName.initializationVector); + // Log.print('initializationVector: ${initializationVector}'); + // Set the global instance + _instance = EncryptionHelper._( + encrypt.Key.fromUtf8(keyOfApp!), + encrypt.IV.fromUtf8(initializationVector!), + ); + debugPrint("EncryptionHelper initialized successfully."); + } + + /// Encrypts a string String encryptData(String plainText) { try { - final encrypter = encrypt.Encrypter(encrypt.AES(key, - mode: encrypt.AESMode.cbc)); // Explicitly use CBC mode + final encrypter = + encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc)); final encrypted = encrypter.encrypt(plainText, iv: iv); return encrypted.base64; } catch (e) { @@ -37,14 +53,13 @@ class EncryptionHelper { } } - /// Decrypts the given encrypted text + /// Decrypts a string String decryptData(String encryptedText) { try { - final encrypter = encrypt.Encrypter(encrypt.AES(key, - mode: encrypt.AESMode.cbc)); // Explicitly use CBC mode + final encrypter = + encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc)); final encrypted = encrypt.Encrypted.fromBase64(encryptedText); - final decrypted = encrypter.decrypt(encrypted, iv: iv); - return decrypted; + return encrypter.decrypt(encrypted, iv: iv); } catch (e) { debugPrint('Decryption Error: $e'); return ''; diff --git a/lib/controller/functions/face_detect.dart b/lib/controller/functions/face_detect.dart index 9b10461..e310dc7 100644 --- a/lib/controller/functions/face_detect.dart +++ b/lib/controller/functions/face_detect.dart @@ -24,9 +24,9 @@ Future faceDetector() async { request.body = json.encode({ "url1": - "${AppLink.seferCairoServer}/card_image/id_front-${encryptionHelper.decryptData(box.read(BoxName.driverID))}.jpg", + "${AppLink.seferCairoServer}/card_image/id_front-${EncryptionHelper.instance.decryptData(box.read(BoxName.driverID))}.jpg", "url2": - "https://api.sefer.live/sefer/card_image/face_detect-${encryptionHelper.decryptData(box.read(BoxName.driverID))}.jpg" + "https://api.sefer.live/sefer/card_image/face_detect-${EncryptionHelper.instance.decryptData(box.read(BoxName.driverID))}.jpg" }); print('request.body: ${request.body}'); request.headers.addAll(headers); diff --git a/lib/controller/functions/gemeni.dart b/lib/controller/functions/gemeni.dart index 530fb49..70448a1 100644 --- a/lib/controller/functions/gemeni.dart +++ b/lib/controller/functions/gemeni.dart @@ -394,10 +394,10 @@ class AI extends GetxController { update(); var payload = { - 'first_name': encryptionHelper.encryptData( + 'first_name': EncryptionHelper.instance.encryptData( responseNonIdCardFront['full_name'].toString().split(' ')[0]) ?? 'Not specified', - 'last_name': encryptionHelper.encryptData( + 'last_name': EncryptionHelper.instance.encryptData( responseNonIdCardFront['full_name'].toString().split(' ').last) ?? 'Not specified', 'email': box.read(BoxName.emailDriver)?.toString() ?? 'Not specified', @@ -410,14 +410,14 @@ class AI extends GetxController { .passwordController .text .toString(), - 'gender': encryptionHelper + 'gender': EncryptionHelper.instance .encryptData(responseNonIdCardFront['gender'].toString()) ?? 'Not specified', 'license_type': 'Foreign', - 'national_number': encryptionHelper + 'national_number': EncryptionHelper.instance .encryptData(responseNonIdCardFront['passport_no'].toString()) ?? 'Not specified', - 'name_arabic': encryptionHelper + 'name_arabic': EncryptionHelper.instance .encryptData(responseNonIdCardFront['full_name'].toString()) ?? 'Not specified', 'name_english': 'Not specified', @@ -431,30 +431,30 @@ class AI extends GetxController { ? responseIdEgyptDriverLicense['license_categories'].join(', ') : responseIdEgyptDriverLicense['license_categories']?.toString() ?? 'Not specified', - 'address': encryptionHelper + 'address': EncryptionHelper.instance .encryptData(responseNonIdCardFront['address'].toString()) ?? 'Not specified', - 'card_id': encryptionHelper + 'card_id': EncryptionHelper.instance .encryptData(responseNonIdCardFront['card_id'].toString()) ?? 'Not specified', - 'occupation': encryptionHelper + 'occupation': EncryptionHelper.instance .encryptData(responseNonIdCardBack['workStatus'].toString()) ?? 'Not specified', 'education': 'Not specified', 'licenseIssueDate': responseNonIdCardBack['issueDate']?.toString() ?? 'Not specified', - 'religion': encryptionHelper + 'religion': EncryptionHelper.instance .encryptData(responseNonIdCardFront['country'].toString()) ?? 'Not specified', 'status': 'yet', - 'birthdate': encryptionHelper + 'birthdate': EncryptionHelper.instance .encryptData(responseNonIdCardFront['birthdate'].toString()) ?? 'Not specified', 'maritalStatus': 'Not specified', - 'site': encryptionHelper + 'site': EncryptionHelper.instance .encryptData(responseNonIdCardFront['address'].toString()) ?? 'Not specified', - 'employmentType': encryptionHelper + 'employmentType': EncryptionHelper.instance .encryptData(responseNonIdCardBack['residencyType'].toString()) ?? 'Not specified', }; @@ -499,10 +499,10 @@ class AI extends GetxController { update(); var payload = { - 'first_name': encryptionHelper.encryptData( + 'first_name': EncryptionHelper.instance.encryptData( responseIdEgyptDriverLicense['firstName'].toString()) ?? 'Not specified', - 'last_name': encryptionHelper.encryptData( + 'last_name': EncryptionHelper.instance.encryptData( responseIdEgyptDriverLicense['lastName'].toString()) ?? 'Not specified', 'email': box.read(BoxName.emailDriver)?.toString() ?? 'Not specified', @@ -515,18 +515,18 @@ class AI extends GetxController { .passwordController .text .toString(), - 'gender': encryptionHelper + 'gender': EncryptionHelper.instance .encryptData(responseIdEgyptBack['gender'].toString()) ?? 'Not specified', - 'license_type': encryptionHelper.encryptData( + 'license_type': EncryptionHelper.instance.encryptData( responseIdEgyptDriverLicense['license_type'].toString()) ?? 'Not specified', - 'national_number': encryptionHelper + 'national_number': EncryptionHelper.instance .encryptData(responseIdEgyptBack['nationalID'].toString()) ?? 'Not specified', - 'name_arabic': encryptionHelper + 'name_arabic': EncryptionHelper.instance .encryptData(responseIdEgyptDriverLicense['name_arabic'].toString()), - 'name_english': encryptionHelper + 'name_english': EncryptionHelper.instance .encryptData(responseIdEgyptDriverLicense['name_english'].toString()), 'issue_date': responseIdEgyptDriverLicense['issue_date']?.toString() ?? 'Not specified', @@ -537,34 +537,34 @@ class AI extends GetxController { ? responseIdEgyptDriverLicense['license_categories'].join(', ') : responseIdEgyptDriverLicense['license_categories']?.toString() ?? 'Not specified', - 'address': encryptionHelper + 'address': EncryptionHelper.instance .encryptData(responseIdEgyptFront['address'].toString()) ?? 'Not specified', - 'card_id': encryptionHelper + 'card_id': EncryptionHelper.instance .encryptData(responseIdEgyptFront['card_id'].toString()) ?? 'Not specified', - 'occupation': encryptionHelper + 'occupation': EncryptionHelper.instance .encryptData(responseIdEgyptBack['occupation'].toString()) ?? 'Not specified', - 'education': encryptionHelper + 'education': EncryptionHelper.instance .encryptData(responseIdEgyptBack['occupation'].toString()) ?? 'Not specified', 'licenseIssueDate': responseIdEgyptDriverLicense['issue_date'].toString() ?? 'Not specified', - 'religion': encryptionHelper + 'religion': EncryptionHelper.instance .encryptData(responseIdEgyptBack['religion'].toString()) ?? 'Not specified', 'status': 'yet', - 'birthdate': encryptionHelper.encryptData(extractDOB( + 'birthdate': EncryptionHelper.instance.encryptData(extractDOB( responseIdEgyptDriverLicense['national_number'].toString())), - 'maritalStatus': encryptionHelper + 'maritalStatus': EncryptionHelper.instance .encryptData(responseIdEgyptBack['maritalStatus'].toString()) ?? 'Not specified', - 'site': encryptionHelper.encryptData( + 'site': EncryptionHelper.instance.encryptData( responseIdEgyptDriverLicense['address'].toString()) ?? 'Not specified', - 'employmentType': encryptionHelper.encryptData( + 'employmentType': EncryptionHelper.instance.encryptData( responseIdEgyptDriverLicense['employmentType'].toString()) ?? 'Not specified', }; @@ -609,7 +609,7 @@ class AI extends GetxController { var res = await CRUD().post(link: AppLink.addCriminalDocuments, payload: { "driverId": box.read(BoxName.driverID), "IssueDate": responseCriminalRecordEgypt['IssueDate'], - "InspectionResult": encryptionHelper + "InspectionResult": EncryptionHelper.instance .encryptData(responseCriminalRecordEgypt['InspectionResult']), }); if (res != 'failure') { @@ -624,7 +624,7 @@ class AI extends GetxController { var res = await CRUD().post(link: AppLink.addRegisrationCar, payload: { 'driverID': box.read(BoxName.driverID), 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), - 'car_plate': encryptionHelper.encryptData( + 'car_plate': EncryptionHelper.instance.encryptData( responseIdCardDriverEgyptFront['car_plate'].toString()), 'make': (responseIdCardDriverEgyptBack['make'].toString()), 'model': (responseIdCardDriverEgyptBack['model']), @@ -632,10 +632,10 @@ class AI extends GetxController { 'expiration_date': responseIdCardDriverEgyptFront['LicenseExpirationDate'].toString(), 'color': responseIdCardDriverEgyptBack['color'], - 'owner': encryptionHelper + 'owner': EncryptionHelper.instance .encryptData(responseIdCardDriverEgyptFront['owner']), 'color_hex': responseIdCardDriverEgyptBack['color_hex'].toString(), - 'address': encryptionHelper + 'address': EncryptionHelper.instance .encryptData(responseIdCardDriverEgyptFront['address'].toString()), 'displacement': responseIdCardDriverEgyptBack['engine'].toString(), 'fuel': responseIdCardDriverEgyptBack['fuel'].toString(), @@ -654,7 +654,7 @@ class AI extends GetxController { payload: { 'driverID': box.read(BoxName.driverID), 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), - 'car_plate': encryptionHelper.encryptData( + 'car_plate': EncryptionHelper.instance.encryptData( responseIdCardDriverEgyptFront['car_plate'].toString()), 'make': (responseIdCardDriverEgyptBack['make'].toString()), 'model': (responseIdCardDriverEgyptBack['model']), @@ -663,11 +663,11 @@ class AI extends GetxController { responseIdCardDriverEgyptFront['LicenseExpirationDate'] .toString(), 'color': responseIdCardDriverEgyptBack['color'], - 'owner': encryptionHelper + 'owner': EncryptionHelper.instance .encryptData(responseIdCardDriverEgyptFront['owner']), 'color_hex': responseIdCardDriverEgyptBack['color_hex'].toString(), - 'address': encryptionHelper.encryptData( + 'address': EncryptionHelper.instance.encryptData( responseIdCardDriverEgyptFront['address'].toString()), 'displacement': responseIdCardDriverEgyptBack['engine'].toString(), @@ -680,7 +680,7 @@ class AI extends GetxController { payload: { 'driverID': box.read(BoxName.driverID), 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), - 'car_plate': encryptionHelper.encryptData( + 'car_plate': EncryptionHelper.instance.encryptData( responseIdCardDriverEgyptFront['car_plate'].toString()), 'make': (responseIdCardDriverEgyptBack['make'].toString()), 'model': (responseIdCardDriverEgyptBack['model']), @@ -689,11 +689,11 @@ class AI extends GetxController { responseIdCardDriverEgyptFront['LicenseExpirationDate'] .toString(), 'color': responseIdCardDriverEgyptBack['color'], - 'owner': encryptionHelper + 'owner': EncryptionHelper.instance .encryptData(responseIdCardDriverEgyptFront['owner']), 'color_hex': responseIdCardDriverEgyptBack['color_hex'].toString(), - 'address': encryptionHelper.encryptData( + 'address': EncryptionHelper.instance.encryptData( responseIdCardDriverEgyptFront['address'].toString()), 'displacement': responseIdCardDriverEgyptBack['engine'].toString(), diff --git a/lib/controller/functions/location_controller.dart b/lib/controller/functions/location_controller.dart index 61e5677..74e60e6 100644 --- a/lib/controller/functions/location_controller.dart +++ b/lib/controller/functions/location_controller.dart @@ -91,7 +91,7 @@ class LocationController extends GetxController { longitude >= minLongitude && longitude <= maxLongitude) { box.write(BoxName.serverChosen, - encryptionHelper.decryptData(locationData['server_link'])); + EncryptionHelper.instance.decryptData(locationData['server_link'])); // Log.print( // 'locationData----server_link: ${locationData['server_link']}'); return locationData['name']; diff --git a/lib/controller/functions/log_out.dart b/lib/controller/functions/log_out.dart index 6fb3021..661a8f6 100644 --- a/lib/controller/functions/log_out.dart +++ b/lib/controller/functions/log_out.dart @@ -76,7 +76,8 @@ class LogOutController extends GetxController { title: 'Delete'.tr, onPressed: () async { if (checkTxtController.text == - encryptionHelper.decryptData(box.read(BoxName.nameDriver))) { + EncryptionHelper.instance + .decryptData(box.read(BoxName.nameDriver))) { // deletecaptainAccount(); var id = await checkBeforeDelete(); @@ -101,23 +102,10 @@ class LogOutController extends GetxController { style: ButtonStyle( backgroundColor: MaterialStateProperty.all(AppColor.redColor), ), - onPressed: () { + onPressed: () async { // box.remove(BoxName.agreeTerms); - box.remove(BoxName.driverID); - box.remove(BoxName.email); - box.remove(BoxName.lang); - box.remove(BoxName.name); - box.remove(BoxName.passengerID); - box.remove(BoxName.phone); - box.remove(BoxName.tokenFCM); - box.remove(BoxName.tokens); - box.remove(BoxName.addHome); - box.remove(BoxName.addWork); - box.remove(BoxName.agreeTerms); - box.remove(BoxName.apiKeyRun); - box.remove(BoxName.countryCode); - box.remove(BoxName.accountIdStripeConnect); - box.remove(BoxName.passengerWalletTotal); + await box.erase(); + await storage.deleteAll(); Get.offAll(OnBoardingPage()); }, child: Text( @@ -144,27 +132,10 @@ class LogOutController extends GetxController { style: ButtonStyle( backgroundColor: MaterialStateProperty.all(AppColor.redColor), ), - onPressed: () { + onPressed: () async { // box.remove(BoxName.agreeTerms); - box.remove(BoxName.driverID); - box.remove(BoxName.sexDriver); - box.remove(BoxName.dobDriver); - box.remove(BoxName.nameDriver); - box.remove(BoxName.emailDriver); - box.remove(BoxName.phoneDriver); - box.remove(BoxName.statusDriverLocation); - box.remove(BoxName.cvvCodeDriver); - box.remove(BoxName.lastNameDriver); - box.remove(BoxName.passwordDriver); - box.remove(BoxName.cardNumberDriver); - box.remove(BoxName.expiryDateDriver); - box.remove(BoxName.cardHolderNameDriver); - box.remove(BoxName.vin); - box.remove(BoxName.make); - box.remove(BoxName.year); - box.remove(BoxName.owner); - box.remove(BoxName.onBoarding); - box.remove(BoxName.agreeTerms); + await box.erase(); + await storage.deleteAll(); Get.offAll(OnBoardingPage()); }, child: Text( diff --git a/lib/controller/functions/package_info.dart b/lib/controller/functions/package_info.dart index 82def9a..1517464 100644 --- a/lib/controller/functions/package_info.dart +++ b/lib/controller/functions/package_info.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'dart:io'; import 'dart:ui'; +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:jailbreak_root_detection/jailbreak_root_detection.dart'; import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/constant/colors.dart'; import 'package:sefer_driver/constant/links.dart'; @@ -12,6 +14,7 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../constant/info.dart'; import '../../main.dart'; +import 'encrypt_decrypt.dart'; Future checkForUpdate(BuildContext context) async { final packageInfo = await PackageInfo.fromPlatform(); @@ -159,3 +162,122 @@ void showUpdateDialog(BuildContext context) { }, ); } + +getDeviceFingerprint() async { + final deviceInfo = await DeviceInfoPlugin().deviceInfo; + var deviceData; + + if (Platform.isAndroid) { + deviceData = deviceInfo.data; + } else if (Platform.isIOS) { + deviceData = deviceInfo.data; + } + + final String deviceId = + deviceData['androidId'] ?? deviceData['identifierForVendor']; + final String deviceModel = deviceData['model']; + final String osVersion = deviceData['systemVersion']; + + return EncryptionHelper.instance + .encryptData('${deviceId}_${deviceModel}_$osVersion'); +} + +class SecurityHelper { + /// Performs security checks and handles potential risks + static Future performSecurityChecks() async { + bool isNotTrust = false; + bool isJailBroken = false; + bool isRealDevice = true; + bool isOnExternalStorage = false; + bool checkForIssues = false; + bool isDevMode = false; + bool isTampered = false; + String bundleId = ""; + + try { + isNotTrust = await JailbreakRootDetection.instance.isNotTrust; + isJailBroken = await JailbreakRootDetection.instance.isJailBroken; + isRealDevice = await JailbreakRootDetection.instance.isRealDevice; + isOnExternalStorage = + await JailbreakRootDetection.instance.isOnExternalStorage; + + List issues = + await JailbreakRootDetection.instance.checkForIssues; + checkForIssues = issues.isNotEmpty; + + isDevMode = await JailbreakRootDetection.instance.isDevMode; + + // Get Bundle ID + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + bundleId = packageInfo.packageName; + if (bundleId.isNotEmpty) { + // Pass the CORRECT bundle ID to isTampered + isTampered = await JailbreakRootDetection.instance.isTampered(bundleId); + } + } catch (e) { + debugPrint("Error during security checks: $e"); + // Consider handling specific exceptions, not just general errors. + } + + // Save values to storage (using GetStorage) + await box.write('isNotTrust', isNotTrust); // Use await for write operations + await box.write('isTampered', isTampered); // Use await + await box.write('isJailBroken', isJailBroken); // Use await + + // debugPrint("Security Check Results:"); + // debugPrint("isNotTrust: $isNotTrust"); + // debugPrint("isJailBroken: $isJailBroken"); + // debugPrint("isRealDevice: $isRealDevice"); + // debugPrint("isOnExternalStorage: $isOnExternalStorage"); + // debugPrint("checkForIssues: $checkForIssues"); + // debugPrint("isDevMode: $isDevMode"); + // debugPrint("isTampered: $isTampered"); + // debugPrint("Bundle ID: $bundleId"); // Print the bundle ID + + // Check for security risks and potentially show a warning + if (isNotTrust || + isJailBroken || + isTampered || + isDevMode || + isOnExternalStorage || + !isRealDevice) { + // print("security_warning".tr); //using easy_localization + // Use a more robust approach to show a warning, like a dialog: + _showSecurityWarning(); + } + } + + /// Deletes all app data + static Future clearAllData() async { + //await storage.deleteAll(); // What's 'storage'? Be specific. Likely GetStorage as well. + await box.erase(); // Clear GetStorage data + exit(0); // This will terminate the app. Be VERY careful with this. + } + + static void _showSecurityWarning() { + // Show a dialog, navigate to an error screen, etc. + // Example using Get.dialog (if you use GetX): + + Get.dialog( + AlertDialog( + title: Text("Security Warning".tr), // Or use localized string + content: Text( + "Potential security risks detected. The application may not function correctly." + .tr), //Or use localized string + actions: [ + TextButton( + onPressed: () async { + await storage.deleteAll(); + await box.erase(); + Get.back(); // Close the dialog + // Or, if you really must, exit the app (but give the user a chance!) + exit(0); + }, + child: Text("OK"), // Or use a localized string + ), + ], + ), + barrierDismissible: false, // Prevent closing by tapping outside + ); + } +} diff --git a/lib/controller/functions/secure_storage.dart b/lib/controller/functions/secure_storage.dart index db97020..6f618f8 100644 --- a/lib/controller/functions/secure_storage.dart +++ b/lib/controller/functions/secure_storage.dart @@ -1,9 +1,14 @@ import 'dart:convert'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:jwt_decoder/jwt_decoder.dart'; +import 'package:secure_string_operations/secure_string_operations.dart'; +import 'package:sefer_driver/controller/auth/captin/login_captin_controller.dart'; import 'package:sefer_driver/controller/functions/encrypt_decrypt.dart'; import '../../constant/box_name.dart'; +import '../../constant/char_map.dart'; +import '../../constant/info.dart'; import '../../constant/links.dart'; import '../../main.dart'; import '../../print.dart'; @@ -34,24 +39,41 @@ class AppInitializer { List> links = []; Future initializeApp() async { - await getKey(); - await getAIKey('FCM_PRIVATE_KEY'); + Log.print('box.read("jwt"): ${box.read(BoxName.jwt)}'); + if (box.read(BoxName.jwt) == null) { + await LoginDriverController().getJWT(); + } else { + print('firstTimeLoadKey ${box.read(BoxName.firstTimeLoadKey)}'); + bool isTokenExpired = JwtDecoder.isExpired(X + .r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs) + .toString() + .split(AppInformation.addd)[0]); + Log.print('isTokenExpired: $isTokenExpired'); + if (isTokenExpired) { + await LoginDriverController().getJWT(); + } + } + + // await getKey(); } - getAIKey(String key) async { - var res = - await CRUD().get(link: AppLink.getapiKey, payload: {"keyName": key}); - if (res != 'failure') { - var d = jsonDecode(res)['message']; - storage.write(key: 'FCM_PRIVATE_KEY', value: d[key].toString()); - // return d[key].toString(); - } else {} + getAIKey(String key1) async { + if (box.read(BoxName.firstTimeLoadKey) == null) { + var res = + await CRUD().get(link: AppLink.getapiKey, payload: {"keyName": key1}); + if (res != 'failure') { + var d = jsonDecode(res)['message']; + await storage.write(key: key1, value: d[key1].toString()); + await Future.delayed(Duration.zero); + } else {} + } } Future getKey() async { try { var res = await CRUD().get(link: AppLink.getLocationAreaLinks, payload: {}); + // Log.print('res: ${res}'); if (res != 'failure') { links = List>.from(jsonDecode(res)['message']); await box.remove(BoxName.locationName); @@ -61,14 +83,18 @@ class AppInitializer { await box.remove(links[2]['name']); await box.write(BoxName.locationName, links); await box.write(BoxName.basicLink, - encryptionHelper.decryptData(links[0]['server_link'])); + EncryptionHelper.instance.decryptData(links[0]['server_link'])); await box.write(links[2]['name'], - encryptionHelper.decryptData(links[2]['server_link'])); + EncryptionHelper.instance.decryptData(links[2]['server_link'])); await box.write(links[1]['name'], - encryptionHelper.decryptData(links[1]['server_link'])); + EncryptionHelper.instance.decryptData(links[3]['server_link'])); + await box.write(links[3]['name'], + EncryptionHelper.instance.decryptData(links[1]['server_link'])); await box.write(BoxName.paymentLink, - encryptionHelper.decryptData(links[4]['server_link'])); + EncryptionHelper.instance.decryptData(links[4]['server_link'])); } - } catch (e) {} + } catch (e) { + print('Error fetching or decoding location data: $e'); + } } } diff --git a/lib/controller/functions/sms_egypt_controller.dart b/lib/controller/functions/sms_egypt_controller.dart index 39c4f58..9ce8a3d 100644 --- a/lib/controller/functions/sms_egypt_controller.dart +++ b/lib/controller/functions/sms_egypt_controller.dart @@ -46,12 +46,12 @@ class SmsEgyptController extends GetxController { if (jsonDecode(res.body)['message'].toString() != "Success") { await CRUD().post(link: AppLink.updatePhoneInvalidSMS, payload: { - "phone_number": encryptionHelper.encryptData( + "phone_number": EncryptionHelper.instance.encryptData( '+2${Get.find().phoneController.text}') }); box.write( BoxName.phoneDriver, - encryptionHelper.encryptData( + EncryptionHelper.instance.encryptData( '+2${Get.find().phoneController.text}')); box.write(BoxName.phoneVerified, '1'); diff --git a/lib/controller/functions/upload_image.dart b/lib/controller/functions/upload_image.dart index 8b3beb2..d0dce77 100644 --- a/lib/controller/functions/upload_image.dart +++ b/lib/controller/functions/upload_image.dart @@ -419,9 +419,10 @@ class ImageController extends GetxController { await uploadImage( compressedImage, { - 'driverID': - encryptionHelper.decryptData(box.read(BoxName.driverID)) ?? - encryptionHelper.decryptData(box.read(BoxName.passengerID)), + 'driverID': EncryptionHelper.instance + .decryptData(box.read(BoxName.driverID)) ?? + EncryptionHelper.instance + .decryptData(box.read(BoxName.passengerID)), 'imageType': imageType }, link, @@ -461,7 +462,7 @@ class ImageController extends GetxController { stream, length, filename: - '${encryptionHelper.decryptData(box.read(BoxName.driverID))}.jpg', + '${EncryptionHelper.instance.decryptData(box.read(BoxName.driverID))}.jpg', ), ); data.forEach((key, value) { diff --git a/lib/controller/home/captin/help/help_controller.dart b/lib/controller/home/captin/help/help_controller.dart index 2f91130..becc771 100644 --- a/lib/controller/home/captin/help/help_controller.dart +++ b/lib/controller/home/captin/help/help_controller.dart @@ -31,7 +31,8 @@ class HelpController extends GetxController { update(); var res = await CRUD().post(link: AppLink.addhelpCenter, payload: { 'driverID': box.read(BoxName.driverID).toString(), - 'helpQuestion': encryptionHelper.encryptData(helpQuestionController.text) + 'helpQuestion': + EncryptionHelper.instance.encryptData(helpQuestionController.text) }); var d = jsonDecode(res); isLoading = false; diff --git a/lib/controller/home/captin/map_driver_controller.dart b/lib/controller/home/captin/map_driver_controller.dart index 74859ad..3674274 100644 --- a/lib/controller/home/captin/map_driver_controller.dart +++ b/lib/controller/home/captin/map_driver_controller.dart @@ -183,7 +183,7 @@ class MapDriverController extends GetxController { await CRUD().post( link: "${AppLink.seferCairoServer}/ride/rides/update.php", payload: { - "id": encryptionHelper + "id": EncryptionHelper.instance .encryptData(rideId) .toString(), // Convert to String "status": 'CancelFromDriverAfterApply' @@ -193,24 +193,26 @@ class MapDriverController extends GetxController { payload: { 'driver_id': box.read(BoxName.driverID).toString(), // box.read(BoxName.driverID).toString(), - 'order_id': encryptionHelper.encryptData(rideId).toString(), + 'order_id': + EncryptionHelper.instance.encryptData(rideId).toString(), 'status': 'CancelFromDriverAfterApply' }); await CRUD().post( link: "${AppLink.seferCairoServer}/ride/cancelRide/addCancelTripFromDriverAfterApplied.php", payload: { - "order_id": encryptionHelper.encryptData(rideId).toString(), + "order_id": + EncryptionHelper.instance.encryptData(rideId).toString(), "driver_id": box.read(BoxName.driverID).toString(), "status": 'reject After Applied', - "notes": encryptionHelper + "notes": EncryptionHelper.instance .encryptData(cancelTripCotroller.text) .toString() }); if (AppLink.endPoint != AppLink.seferCairoServer) { CRUD() .post(link: "${AppLink.endPoint}/ride/rides/update.php", payload: { - "id": encryptionHelper + "id": EncryptionHelper.instance .encryptData(rideId) .toString(), // Convert to String "status": 'CancelFromDriverAfterApply' @@ -220,24 +222,26 @@ class MapDriverController extends GetxController { payload: { 'driver_id': box.read(BoxName.driverID).toString(), // box.read(BoxName.driverID).toString(), - 'order_id': encryptionHelper.encryptData(rideId).toString(), + 'order_id': + EncryptionHelper.instance.encryptData(rideId).toString(), 'status': 'CancelFromDriverAfterApply' }); CRUD().post( link: "${AppLink.endPoint}/ride/cancelRide/addCancelTripFromDriverAfterApplied.php", payload: { - "order_id": encryptionHelper.encryptData(rideId).toString(), + "order_id": + EncryptionHelper.instance.encryptData(rideId).toString(), "driver_id": box.read(BoxName.driverID).toString(), "status": 'reject After Applied', - "notes": encryptionHelper + "notes": EncryptionHelper.instance .encryptData(cancelTripCotroller.text) .toString() }); } sql.insertData({ - 'order_id': encryptionHelper.encryptData(rideId), + 'order_id': EncryptionHelper.instance.encryptData(rideId), 'created_at': DateTime.now().toString(), 'driver_id': box.read(BoxName.driverID).toString(), }, TableName.driverOrdersRefuse); @@ -308,13 +312,13 @@ class MapDriverController extends GetxController { await CRUD().post( link: "${AppLink.seferCairoServer}/ride/rides/update.php", payload: { - 'id': encryptionHelper.encryptData(rideId), + 'id': EncryptionHelper.instance.encryptData(rideId), 'driverGoToPassengerTime': DateTime.now().toString(), 'status': 'Applied' }); if (AppLink.endPoint != AppLink.seferCairoServer) { CRUD().post(link: "${AppLink.endPoint}/ride/rides/update.php", payload: { - 'id': encryptionHelper.encryptData(rideId), + 'id': EncryptionHelper.instance.encryptData(rideId), 'driverGoToPassengerTime': DateTime.now().toString(), 'status': 'Applied' }); @@ -529,35 +533,35 @@ class MapDriverController extends GetxController { : (distanceBetweenDriverAndPassengerWhenConfirm * .06) + (5 * .06); //for Eygpt other like jordan .06 per minute await CRUD().post(link: AppLink.updateRides, payload: { - 'id': encryptionHelper.encryptData(rideId), + 'id': EncryptionHelper.instance.encryptData(rideId), 'rideTimeStart': DateTime.now().toString(), 'status': 'CancelAfterWait', }); CRUD().post(link: AppLink.addDriverOrder, payload: { 'driver_id': box.read(BoxName.driverID).toString(), - 'order_id': encryptionHelper.encryptData(rideId).toString(), + 'order_id': EncryptionHelper.instance.encryptData(rideId).toString(), 'status': 'CancelAfterWait' }); if (AppLink.endPoint != AppLink.seferCairoServer) { CRUD().post(link: "${AppLink.endPoint}/rides/update.php", payload: { - 'id': encryptionHelper.encryptData(rideId), + 'id': EncryptionHelper.instance.encryptData(rideId), 'rideTimeStart': DateTime.now().toString(), 'status': 'CancelAfterWait', }); CRUD().post(link: "${AppLink.endPoint}/rides/update.php", payload: { 'driver_id': box.read(BoxName.driverID).toString(), - 'order_id': encryptionHelper.encryptData(rideId).toString(), + 'order_id': EncryptionHelper.instance.encryptData(rideId).toString(), 'status': 'CancelAfterWait' }); } var paymentTokenWait = await generateTokenDriver(costOfWaiting5Minute.toString()); var res = await CRUD().post(link: AppLink.addDrivePayment, payload: { - 'rideId': encryptionHelper.encryptData(rideId), + 'rideId': EncryptionHelper.instance.encryptData(rideId), 'amount': (costOfWaiting5Minute.toString()), 'payment_method': 'wait-cancel', - 'passengerID': encryptionHelper.encryptData(passengerId), + 'passengerID': EncryptionHelper.instance.encryptData(passengerId), 'token': paymentTokenWait, 'driverID': box.read(BoxName.driverID).toString(), }); @@ -565,7 +569,7 @@ class MapDriverController extends GetxController { await generateTokenDriver(costOfWaiting5Minute.toString()); var res1 = await CRUD().post(link: AppLink.addDriversWalletPoints, payload: { - 'paymentID': 'rideId${encryptionHelper.encryptData(rideId)}', + 'paymentID': 'rideId${EncryptionHelper.instance.encryptData(rideId)}', 'amount': (costOfWaiting5Minute).toStringAsFixed(0), 'paymentMethod': 'wait', 'token': paymentTokenWait1, @@ -581,7 +585,7 @@ class MapDriverController extends GetxController { var paymentTokenWaitPassenger1 = await generateTokenPassenger((costOfWaiting5Minute * -1).toString()); await CRUD().post(link: AppLink.addPassengersWallet, payload: { - 'passenger_id': encryptionHelper.encryptData(passengerId), + 'passenger_id': EncryptionHelper.instance.encryptData(passengerId), 'balance': (costOfWaiting5Minute * -1).toString(), 'token': paymentTokenWaitPassenger1, }); @@ -667,13 +671,13 @@ class MapDriverController extends GetxController { // Prepare data for API calls final nowString = DateTime.now().toString(); final basePayload = { - 'id': encryptionHelper.encryptData(rideId), + 'id': EncryptionHelper.instance.encryptData(rideId), 'rideTimeFinish': nowString, 'status': 'Finished', 'price': totalCost, }; final driverOrderPayload = { - 'order_id': encryptionHelper.encryptData(rideId.toString()), + 'order_id': EncryptionHelper.instance.encryptData(rideId.toString()), 'status': 'Finished' }; @@ -706,7 +710,7 @@ class MapDriverController extends GetxController { paymentToken = await generateTokenPassenger( ((-1) * double.parse(paymentAmount)).toString()); futures.add(CRUD().post(link: AppLink.addPassengersWallet, payload: { - 'passenger_id': encryptionHelper.encryptData(passengerId), + 'passenger_id': EncryptionHelper.instance.encryptData(passengerId), 'balance': ((-1) * double.parse(paymentAmount)).toString(), 'token': paymentToken, })); @@ -714,11 +718,11 @@ class MapDriverController extends GetxController { paymentToken = await generateTokenDriver(paymentAmount.toString()); futures.add(CRUD().post(link: AppLink.addDrivePayment, payload: { - 'rideId': encryptionHelper.encryptData(rideId), + 'rideId': EncryptionHelper.instance.encryptData(rideId), 'amount': paymentAmount, 'payment_method': walletChecked == 'true' ? "${paymentMethod}Ride" : paymentMethod, - 'passengerID': encryptionHelper.encryptData(passengerId), + 'passengerID': EncryptionHelper.instance.encryptData(passengerId), 'token': paymentToken, 'driverID': box.read(BoxName.driverID).toString(), })); @@ -727,7 +731,7 @@ class MapDriverController extends GetxController { final paymentToken1 = await generateTokenPassenger( ((-1) * double.parse(passengerWalletBurc)).toString()); futures.add(CRUD().post(link: AppLink.addPassengersWallet, payload: { - 'passenger_id': encryptionHelper.encryptData(passengerId), + 'passenger_id': EncryptionHelper.instance.encryptData(passengerId), 'token': paymentToken1, 'balance': ((-1) * double.parse(passengerWalletBurc)).toString() })); @@ -737,7 +741,7 @@ class MapDriverController extends GetxController { final paymentToken2 = await generateTokenDriver((pointsSubtraction).toStringAsFixed(0)); futures.add(CRUD().post(link: AppLink.addDriversWalletPoints, payload: { - 'paymentID': 'rideId${encryptionHelper.encryptData(rideId)}', + 'paymentID': 'rideId${EncryptionHelper.instance.encryptData(rideId)}', 'amount': (pointsSubtraction).toStringAsFixed(0), 'paymentMethod': paymentMethod, 'token': paymentToken2, @@ -894,7 +898,7 @@ class MapDriverController extends GetxController { var res = await CRUD().get( link: "${AppLink.endPoint}/ride/driver_order/getOrderCancelStatus.php", payload: { - 'order_id': encryptionHelper.encryptData(rideId), + 'order_id': EncryptionHelper.instance.encryptData(rideId), }); //.then((value) { var response = jsonDecode(res); canelString = response['data']['status']; diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index 068f073..d16c78a 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -65,6 +65,12 @@ class MyTranslation extends Translations { "Order Applied": "تم تطبيق الطلب", //firebase above + 'please order now': " ‏الرجاء الطلب مرة أخرى", + 'Session expired. Please log in again.': + 'انتهت الجلسة. يرجى تسجيل الدخول مرة أخرى.', + "Security Warning": "⚠️ تحذير أمني", + "Potential security risks detected. The application may not function correctly.": + "تم اكتشاف ثغرات أمنية على هذا الجهاز. للحفاظ على أمان بياناتك، سيتم حذف جميع البيانات وإغلاق التطبيق.", "I will go now": "هروح دلوقتي", "Yes": "أيوة", diff --git a/lib/controller/payment/payment_controller.dart b/lib/controller/payment/payment_controller.dart index 47c5344..31f95c3 100644 --- a/lib/controller/payment/payment_controller.dart +++ b/lib/controller/payment/payment_controller.dart @@ -156,9 +156,12 @@ class PaymentController extends GetxController { paymentIntentClientSecret: clientSecret, merchantDisplayName: AppInformation.appName, billingDetails: BillingDetails( - name: encryptionHelper.decryptData(box.read(BoxName.nameDriver)), - email: encryptionHelper.decryptData(box.read(BoxName.emailDriver)), - phone: encryptionHelper.decryptData(box.read(BoxName.phoneDriver)), + name: EncryptionHelper.instance + .decryptData(box.read(BoxName.nameDriver)), + email: EncryptionHelper.instance + .decryptData(box.read(BoxName.emailDriver)), + phone: EncryptionHelper.instance + .decryptData(box.read(BoxName.phoneDriver)), address: Address( city: 'city', country: box.read(BoxName.countryCode), //'United States' diff --git a/lib/controller/payment/paymob.dart b/lib/controller/payment/paymob.dart index fe4ecbd..ef40213 100644 --- a/lib/controller/payment/paymob.dart +++ b/lib/controller/payment/paymob.dart @@ -134,12 +134,13 @@ class PaymobManager extends GetxController { "currency": currency, "billing_data": { "first_name": - encryptionHelper.decryptData(box.read(BoxName.nameDriver)), - "last_name": - encryptionHelper.decryptData(box.read(BoxName.lastNameDriver)), - "email": encryptionHelper.decryptData(box.read(BoxName.emailDriver)), - "phone_number": - encryptionHelper.decryptData(box.read(BoxName.phoneDriver)), + EncryptionHelper.instance.decryptData(box.read(BoxName.nameDriver)), + "last_name": EncryptionHelper.instance + .decryptData(box.read(BoxName.lastNameDriver)), + "email": EncryptionHelper.instance + .decryptData(box.read(BoxName.emailDriver)), + "phone_number": EncryptionHelper.instance + .decryptData(box.read(BoxName.phoneDriver)), "apartment": "NA", "floor": "NA", "street": "NA", diff --git a/lib/controller/payment/paymob/paymob_response.dart b/lib/controller/payment/paymob/paymob_response.dart index 4519c99..b60c2f0 100644 --- a/lib/controller/payment/paymob/paymob_response.dart +++ b/lib/controller/payment/paymob/paymob_response.dart @@ -224,11 +224,12 @@ class PaymobBillingData { Map toJson() { return { - "email": encryptionHelper.decryptData(box.read(BoxName.emailDriver)), + "email": + EncryptionHelper.instance.decryptData(box.read(BoxName.emailDriver)), "first_name": box.read(BoxName.nameDriver), "last_name": box.read(BoxName.nameDriver), "phone_number": - encryptionHelper.decryptData(box.read(BoxName.phoneDriver)), + EncryptionHelper.instance.decryptData(box.read(BoxName.phoneDriver)), "apartment": apartment ?? "NA", "floor": floor ?? "NA", "building": building ?? "NA", diff --git a/lib/controller/payment/paymob/paymob_wallet.dart b/lib/controller/payment/paymob/paymob_wallet.dart index 5158720..0316ec5 100644 --- a/lib/controller/payment/paymob/paymob_wallet.dart +++ b/lib/controller/payment/paymob/paymob_wallet.dart @@ -267,7 +267,8 @@ class PaymobBillingDataWallet { Map toJson() { return { - "email": encryptionHelper.decryptData(box.read(BoxName.emailDriver)), + "email": + EncryptionHelper.instance.decryptData(box.read(BoxName.emailDriver)), "first_name": box.read(BoxName.name) ?? box.read(BoxName.nameDriver), "last_name": box.read(BoxName.name) ?? box.read(BoxName.nameDriver), "phone_number": (box.read(BoxName.phoneWallet)), diff --git a/lib/controller/rate/rate_app_controller.dart b/lib/controller/rate/rate_app_controller.dart index 7944d94..8e4de0a 100644 --- a/lib/controller/rate/rate_app_controller.dart +++ b/lib/controller/rate/rate_app_controller.dart @@ -42,10 +42,10 @@ class RatingController extends GetxController { "name": box.read(BoxName.driverID) != null ? box.read(BoxName.nameDriver) : box.read(BoxName.name), - "email": encryptionHelper + "email": EncryptionHelper.instance .decryptData(box.read(BoxName.emailDriver)) .toString(), - "phone": encryptionHelper + "phone": EncryptionHelper.instance .decryptData(box.read(BoxName.phoneDriver)) .toString(), "userId": box.read(BoxName.driverID), diff --git a/lib/main.dart b/lib/main.dart index 69f0607..2b8a1da 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,6 +22,7 @@ import 'constant/info.dart'; import 'constant/notification.dart'; import 'controller/firebase/firbase_messge.dart'; import 'controller/firebase/local_notification.dart'; +import 'controller/functions/encrypt_decrypt.dart'; import 'controller/functions/location_controller.dart'; import 'controller/functions/secure_storage.dart'; import 'controller/home/payment/captain_wallet_controller.dart'; @@ -124,9 +125,15 @@ void main() async { await WakelockPlus.enable(); await GetStorage.init(); - Stripe.publishableKey = AK.publishableKeyStripe; + final AppInitializer initializer = AppInitializer(); + await initializer.initializeApp(); + await Future.delayed(Duration.zero); + await EncryptionHelper.initialize(); + + Stripe.publishableKey = AK.publishableKeyStripe; + PermissionStatus status1 = await Permission.location.status; if (status1.isGranted) { await LocationController().startLocationUpdates(); @@ -141,11 +148,6 @@ void main() async { await FirebaseMessagesController().requestFirebaseMessagingPermission(); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); - // NotificationController1().initNotifications(); - // NotificationController().initNotifications(); - // if (Platform.isAndroid) { - // await Get.put(NotificationController()).initNotifications(); - // } await notificationController.initNotifications(); @@ -171,17 +173,19 @@ void main() async { ]); } + String? key = (await storage.read(key: BoxName.payMobApikey)); + + String? apiKey = EncryptionHelper.instance.decryptData(key!); PaymobPayment.instance.initialize( - apiKey: AK.payMobApikey, - // integrationID: 4556055, + apiKey: apiKey, integrationID: int.parse(AK.integrationIdPayMob), userTokenExpiration: 200, iFrameID: 837992, ); + PaymobPaymentWallet.instance.initialize( - apiKey: AK.payMobApikey, + apiKey: apiKey, integrationID: int.parse(AK.integrationIdPayMobWallet), - // integrationID: 4556056, userTokenExpiration: 200, iFrameID: 837992, ); diff --git a/lib/views/auth/captin/ai_page.dart b/lib/views/auth/captin/ai_page.dart index 074031e..c179db6 100644 --- a/lib/views/auth/captin/ai_page.dart +++ b/lib/views/auth/captin/ai_page.dart @@ -95,17 +95,17 @@ class AiPage extends StatelessWidget { Row( children: [ Text( - '${'Name'.tr} :${encryptionHelper.decryptData(contentController.responseMap['first_name'])}', + '${'Name'.tr} :${EncryptionHelper.instance.decryptData(contentController.responseMap['first_name'])}', style: AppStyle.subtitle, ), Text( - ' ${encryptionHelper.decryptData(contentController.responseMap['last_name'])}', + ' ${EncryptionHelper.instance.decryptData(contentController.responseMap['last_name'])}', style: AppStyle.subtitle, ), ], ), Text( - '${'Name in arabic'.tr}: ${encryptionHelper.decryptData(contentController.responseMap['name_in_arabic'])}', + '${'Name in arabic'.tr}: ${EncryptionHelper.instance.decryptData(contentController.responseMap['name_in_arabic'])}', style: AppStyle.title, ), Text( @@ -121,7 +121,7 @@ class AiPage extends StatelessWidget { MainAxisAlignment.spaceBetween, children: [ Text( - '${'National Number'.tr}: ${encryptionHelper.decryptData(contentController.responseMap['id'])}', + '${'National Number'.tr}: ${EncryptionHelper.instance.decryptData(contentController.responseMap['id'])}', style: AppStyle.title, ), // Image.memory( @@ -131,7 +131,7 @@ class AiPage extends StatelessWidget { // ), ]), Text( - '${'Address'.tr}: ${encryptionHelper.decryptData(contentController.responseMap['address'])}', + '${'Address'.tr}: ${EncryptionHelper.instance.decryptData(contentController.responseMap['address'])}', style: AppStyle.title, ), Row( diff --git a/lib/views/auth/captin/cards/egypt_card_a_i.dart b/lib/views/auth/captin/cards/egypt_card_a_i.dart index d790e42..9a01ab0 100644 --- a/lib/views/auth/captin/cards/egypt_card_a_i.dart +++ b/lib/views/auth/captin/cards/egypt_card_a_i.dart @@ -322,7 +322,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { await ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[0]['prompt'].toString()), AppLink.uploadEgypt, 'driver_license'); //egypt @@ -335,32 +335,32 @@ class EgyptCardAI extends StatelessWidget { const Divider(color: AppColor.accentColor), const SizedBox(height: 8.0), Text( - '${'License Type'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptDriverLicense['license_type'])}', + '${'License Type'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptDriverLicense['license_type'])}', style: AppStyle.title, ), const SizedBox(height: 8.0), Text( - '${'National Number'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptDriverLicense['national_number'])}', + '${'National Number'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptDriverLicense['national_number'])}', style: AppStyle.title.copyWith( - color: encryptionHelper.decryptData( + color: EncryptionHelper.instance.decryptData( ai.responseIdEgyptDriverLicense[ 'national_number']) == - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.responseIdEgyptBack['nationalID']) ? AppColor.greenColor : AppColor.redColor), ), const SizedBox(height: 8.0), Text( - '${'Name (Arabic)'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptDriverLicense['name_arabic'])}', + '${'Name (Arabic)'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptDriverLicense['name_arabic'])}', ), const SizedBox(height: 8.0), Text( - '${'Name (English)'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptDriverLicense['name_english'])}', + '${'Name (English)'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptDriverLicense['name_english'])}', ), const SizedBox(height: 8.0), Text( - '${'Address'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptDriverLicense['address'])}', + '${'Address'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptDriverLicense['address'])}', ), const SizedBox(height: 8.0), Text( @@ -387,7 +387,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { await ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[0]['prompt'].toString()), AppLink.uploadEgypt, 'driver_license'); //egypt @@ -443,7 +443,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { await ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[1]['prompt'].toString()), AppLink.uploadEgypt, 'id_back'); //egypt @@ -457,12 +457,12 @@ class EgyptCardAI extends StatelessWidget { const SizedBox(height: 8.0), // Assuming these keys exist in ai.responseIdEgyptFront Text( - '${'National ID'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptBack['nationalID'])}', + '${'National ID'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptBack['nationalID'])}', style: AppStyle.title.copyWith( - color: encryptionHelper.decryptData( + color: EncryptionHelper.instance.decryptData( ai.responseIdEgyptDriverLicense[ 'national_number']) == - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.responseIdEgyptBack['nationalID']) ? AppColor.greenColor : AppColor.redColor), @@ -470,7 +470,7 @@ class EgyptCardAI extends StatelessWidget { const SizedBox(height: 8.0), Text( - '${'Occupation'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptBack['occupation'])}', // Assuming 'occupation' exists + '${'Occupation'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptBack['occupation'])}', // Assuming 'occupation' exists ), const SizedBox(height: 8.0), Row( @@ -480,7 +480,7 @@ class EgyptCardAI extends StatelessWidget { '${'Issue Date'.tr}: ${ai.responseIdEgyptBack['issueDate']}', // Assuming 'issueDate' exists ), Text( - '${'Gender'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptBack['gender'])}', // Assuming 'gender' exists + '${'Gender'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptBack['gender'])}', // Assuming 'gender' exists ), ], ), @@ -517,7 +517,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { await ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[1]['prompt'].toString()), AppLink.uploadEgypt, 'id_back'); //egypt @@ -571,7 +571,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { await ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[7]['prompt'].toString()), AppLink.uploadEgypt, 'non_id_back'); @@ -584,16 +584,16 @@ class EgyptCardAI extends StatelessWidget { const Divider(color: AppColor.accentColor), const SizedBox(height: 8.0), Text( - '${'Country'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardBack['country'])}', + '${'Country'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardBack['country'])}', style: AppStyle.title, ), const SizedBox(height: 8.0), Text( - '${'Residency Type'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardBack['residencyType'])}', + '${'Residency Type'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardBack['residencyType'])}', ), const SizedBox(height: 8.0), Text( - '${'Work Status'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardBack['workStatus'])}', + '${'Work Status'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardBack['workStatus'])}', ), const SizedBox(height: 8.0), Row( @@ -603,7 +603,7 @@ class EgyptCardAI extends StatelessWidget { '${'Issue Date'.tr}: ${ai.responseNonIdCardBack['issueDate']}', ), Text( - '${'Birth Date'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardBack['birthDate'])}', + '${'Birth Date'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardBack['birthDate'])}', ), ], ), @@ -624,7 +624,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { await ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[7]['prompt'].toString()), AppLink.uploadEgypt, 'non_id_back'); @@ -670,7 +670,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { await ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[2]['id_front'].toString()), AppLink.uploadEgypt, 'id_front'); //egypt @@ -688,10 +688,10 @@ class EgyptCardAI extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '${'First Name'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptFront['first_name'])}', + '${'First Name'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptFront['first_name'])}', ), Text( - '${'CardID'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptFront['card_id'])}', + '${'CardID'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptFront['card_id'])}', ), ], ), @@ -700,16 +700,16 @@ class EgyptCardAI extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '${'Full Name'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptFront['full_name'])}', + '${'Full Name'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptFront['full_name'])}', ), Text( - '${'DOB'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptFront['dob'])}', + '${'DOB'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptFront['dob'])}', ), ], ), const SizedBox(height: 8.0), Text( - '${'Address'.tr}: ${encryptionHelper.decryptData(ai.responseIdEgyptFront['address'])}', + '${'Address'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdEgyptFront['address'])}', ), const SizedBox(height: 8.0), // Text( @@ -727,7 +727,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { await ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[2]['prompt'].toString()), AppLink.uploadEgypt, 'id_front'); //egypt @@ -773,7 +773,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { await ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[6]['prompt'].toString()), AppLink.uploadEgypt, 'non_id_front'); @@ -786,7 +786,7 @@ class EgyptCardAI extends StatelessWidget { const Divider(color: AppColor.accentColor), const SizedBox(height: 8.0), Text( - '${'Full Name'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardFront['full_name'])}', + '${'Full Name'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardFront['full_name'])}', style: AppStyle.title, ), const SizedBox(height: 8.0), @@ -794,10 +794,10 @@ class EgyptCardAI extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '${'Passport No'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardFront['passport_no'])}', + '${'Passport No'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardFront['passport_no'])}', ), Text( - '${'Card ID'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardFront['card_id'])}', + '${'Card ID'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardFront['card_id'])}', ), ], ), @@ -806,20 +806,20 @@ class EgyptCardAI extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '${'Country'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardFront['country'])}', + '${'Country'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardFront['country'])}', ), Text( - '${'Gender'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardFront['gender'])}', + '${'Gender'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardFront['gender'])}', ), ], ), const SizedBox(height: 8.0), Text( - '${'Birth Date'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardFront['birthdate'])}', + '${'Birth Date'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardFront['birthdate'])}', ), const SizedBox(height: 8.0), Text( - '${'Address'.tr}: ${encryptionHelper.decryptData(ai.responseNonIdCardFront['address'])}', + '${'Address'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseNonIdCardFront['address'])}', ), ], ), @@ -830,7 +830,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { await ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[6]['prompt'].toString()), AppLink.uploadEgypt, 'non_id_front'); @@ -884,7 +884,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[3]['prompt'].toString()), AppLink.uploadEgypt, 'car_front'); @@ -899,15 +899,15 @@ class EgyptCardAI extends StatelessWidget { // Removed Make, Model, etc. as they are not available Text( - '${'Plate Number'.tr}: ${encryptionHelper.decryptData(ai.responseIdCardDriverEgyptFront['car_plate'])}', + '${'Plate Number'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdCardDriverEgyptFront['car_plate'])}', ), const SizedBox(height: 8.0), Text( - '${'Owner Name'.tr}: ${encryptionHelper.decryptData(ai.responseIdCardDriverEgyptFront['owner'])}', + '${'Owner Name'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdCardDriverEgyptFront['owner'])}', ), const SizedBox(height: 8.0), Text( - '${'Address'.tr}: ${encryptionHelper.decryptData(ai.responseIdCardDriverEgyptFront['address'])}', + '${'Address'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseIdCardDriverEgyptFront['address'])}', ), const SizedBox(height: 8.0), Row( @@ -932,7 +932,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[3]['prompt'].toString()), AppLink.uploadEgypt, 'car_front'); @@ -1003,7 +1003,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[4]['prompt'].toString()), AppLink.uploadEgypt, 'car_back'); @@ -1077,7 +1077,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[4]['prompt'].toString()), AppLink.uploadEgypt, 'car_back'); @@ -1123,7 +1123,7 @@ class EgyptCardAI extends StatelessWidget { IconButton( onPressed: () async { await ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[5]['prompt'].toString()), AppLink.uploadEgypt, 'criminalRecord', @@ -1140,11 +1140,11 @@ class EgyptCardAI extends StatelessWidget { '${'InspectionResult'.tr}: ${ai.responseCriminalRecordEgypt['InspectionResult']}'), const SizedBox(height: 8.0), Text( - '${'FullName'.tr}: ${encryptionHelper.decryptData(ai.responseCriminalRecordEgypt['FullName'])}', + '${'FullName'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseCriminalRecordEgypt['FullName'])}', style: AppStyle.title.copyWith( - color: encryptionHelper.decryptData(ai + color: EncryptionHelper.instance.decryptData(ai .responseCriminalRecordEgypt['FullName']) == - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.responseIdEgyptDriverLicense[ 'name_arabic']) ? AppColor.greenColor @@ -1152,7 +1152,7 @@ class EgyptCardAI extends StatelessWidget { ), const SizedBox(height: 8.0), Text( - '${'NationalID'.tr}: ${encryptionHelper.decryptData(ai.responseCriminalRecordEgypt['NationalID'])}'), + '${'NationalID'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseCriminalRecordEgypt['NationalID'])}'), const SizedBox(height: 8.0), Text( '${'IssueDate'.tr}: ${ai.responseCriminalRecordEgypt['IssueDate']}'), @@ -1165,7 +1165,7 @@ class EgyptCardAI extends StatelessWidget { child: InkWell( onTap: () async { await ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[5]['prompt'].toString()), AppLink.uploadEgypt, 'criminalRecord', diff --git a/lib/views/auth/captin/contact_us_page.dart b/lib/views/auth/captin/contact_us_page.dart index 4233f14..6e5abc9 100644 --- a/lib/views/auth/captin/contact_us_page.dart +++ b/lib/views/auth/captin/contact_us_page.dart @@ -21,9 +21,9 @@ class ContactUsPage extends StatelessWidget { body: [ Padding( padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: ListView( + // crossAxisAlignment: CrossAxisAlignment.center, + // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( decoration: AppStyle.boxDecoration1, @@ -35,7 +35,7 @@ class ContactUsPage extends StatelessWidget { IconButton( onPressed: () async { Get.put(TextToSpeechController()).speakText( - 'Swifti is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.' + 'Tripz is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.' .tr); }, icon: const Icon(Icons.headphones), @@ -43,7 +43,7 @@ class ContactUsPage extends StatelessWidget { Padding( padding: const EdgeInsets.all(8.0), child: Text( - 'Swifti is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.' + 'Tripz is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.' .tr, style: AppStyle.title, textAlign: TextAlign.center, diff --git a/lib/views/auth/captin/criminal_documents_page.dart b/lib/views/auth/captin/criminal_documents_page.dart index b763f06..994e8be 100644 --- a/lib/views/auth/captin/criminal_documents_page.dart +++ b/lib/views/auth/captin/criminal_documents_page.dart @@ -36,7 +36,7 @@ class CriminalDocumemtPage extends StatelessWidget { ? MyElevatedButton( title: 'Next'.tr, onPressed: () async { - if (encryptionHelper.decryptData(controller + if (EncryptionHelper.instance.decryptData(controller .responseCriminalRecordEgypt['FullName']) != box.read(BoxName.nameArabic)) //todo get from server { @@ -141,14 +141,14 @@ Please fill in the JSON object with the extracted information, following these g const Divider(color: AppColor.accentColor), const SizedBox(height: 8.0), Text( - '${'InspectionResult'.tr}: ${encryptionHelper.decryptData(ai.responseCriminalRecordEgypt['InspectionResult'])}'), + '${'InspectionResult'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseCriminalRecordEgypt['InspectionResult'])}'), const SizedBox(height: 8.0), Text( - '${'FullName'.tr}: ${encryptionHelper.decryptData(ai.responseCriminalRecordEgypt['FullName'])}', + '${'FullName'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseCriminalRecordEgypt['FullName'])}', style: AppStyle.title.copyWith( - color: encryptionHelper.decryptData(ai + color: EncryptionHelper.instance.decryptData(ai .responseCriminalRecordEgypt['FullName']) == - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.responseIdEgyptDriverLicense[ 'name_arabic']) ? AppColor.greenColor @@ -156,7 +156,7 @@ Please fill in the JSON object with the extracted information, following these g ), const SizedBox(height: 8.0), Text( - '${'NationalID'.tr}: ${encryptionHelper.decryptData(ai.responseCriminalRecordEgypt['NationalID'])}'), + '${'NationalID'.tr}: ${EncryptionHelper.instance.decryptData(ai.responseCriminalRecordEgypt['NationalID'])}'), const SizedBox(height: 8.0), Text( '${'IssueDate'.tr}: ${ai.responseCriminalRecordEgypt['IssueDate']}'), diff --git a/lib/views/auth/captin/invite_driver_screen.dart b/lib/views/auth/captin/invite_driver_screen.dart index 75ee134..1811a82 100644 --- a/lib/views/auth/captin/invite_driver_screen.dart +++ b/lib/views/auth/captin/invite_driver_screen.dart @@ -390,7 +390,7 @@ class InviteScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( controller.driverInvitationData[index]['invitorName']), style: const TextStyle( fontSize: 17, @@ -447,7 +447,7 @@ class InviteScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - encryptionHelper + EncryptionHelper.instance .decryptData(invitation['passengerName']) .toString(), // Handle null or missing data style: const TextStyle( @@ -510,7 +510,7 @@ class InviteScreen extends StatelessWidget { _buildStatItem( context, "Active Users".tr, - encryptionHelper + EncryptionHelper.instance .decryptData(controller.driverInvitationDataToPassengers[0] ['passengerName']) .toString(), diff --git a/lib/views/auth/captin/login_captin.dart b/lib/views/auth/captin/login_captin.dart index 5444f61..f7fee6e 100644 --- a/lib/views/auth/captin/login_captin.dart +++ b/lib/views/auth/captin/login_captin.dart @@ -327,8 +327,9 @@ class LoginCaptin extends StatelessWidget { if (user != null) { box.write( BoxName.emailDriver, - encryptionHelper.encryptData( - user.email.toString())); + EncryptionHelper.instance + .encryptData( + user.email.toString())); box.write( BoxName.driverID, user.uid); @@ -386,6 +387,19 @@ class LoginCaptin extends StatelessWidget { style: AppStyle.subtitle, ), ), + // GestureDetector( + // onTap: () async { + // await storage.deleteAll(); + // box.erase(); + // }, + // child: Padding( + // padding: const EdgeInsets.all(8.0), + // child: Text( + // 'erase'.tr, // Improved wording + // style: AppStyle.subtitle, + // ), + // ), + // ), ], ), ) diff --git a/lib/views/home/Captin/history/history_captain.dart b/lib/views/home/Captin/history/history_captain.dart index b60d128..20e4a5e 100644 --- a/lib/views/home/Captin/history/history_captain.dart +++ b/lib/views/home/Captin/history/history_captain.dart @@ -80,7 +80,7 @@ class HistoryCaptain extends StatelessWidget { .navTitleTextStyle, ), Text( - encryptionHelper + EncryptionHelper.instance .decryptData(list['order_id']), style: CupertinoTheme.of(context) .textTheme @@ -108,8 +108,9 @@ class HistoryCaptain extends StatelessWidget { ), Text( list['status'], - style: encryptionHelper.decryptData( - list['status']) == + style: EncryptionHelper.instance + .decryptData( + list['status']) == 'Apply' ? CupertinoTheme.of(context) .textTheme @@ -117,7 +118,7 @@ class HistoryCaptain extends StatelessWidget { .copyWith( color: CupertinoColors .systemGreen) - : encryptionHelper.decryptData( + : EncryptionHelper.instance.decryptData( list['status']) == 'Refused' ? CupertinoTheme.of(context) diff --git a/lib/views/home/Captin/history/history_details_page.dart b/lib/views/home/Captin/history/history_details_page.dart index 3f15d59..0115b81 100644 --- a/lib/views/home/Captin/history/history_details_page.dart +++ b/lib/views/home/Captin/history/history_details_page.dart @@ -46,7 +46,7 @@ class HistoryDetailsPage extends StatelessWidget { CupertinoButton( onPressed: () { String mapUrl = - 'https://www.google.com/maps/dir/${encryptionHelper.decryptData(res['start_location'])}/${encryptionHelper.decryptData(res['end_location'])}/'; + 'https://www.google.com/maps/dir/${EncryptionHelper.instance.decryptData(res['start_location'])}/${EncryptionHelper.instance.decryptData(res['end_location'])}/'; showInBrowser(mapUrl); }, child: Container( @@ -79,24 +79,28 @@ class HistoryDetailsPage extends StatelessWidget { polylineId: const PolylineId('route'), points: [ LatLng( - double.parse(encryptionHelper + double.parse(EncryptionHelper + .instance .decryptData( res['start_location']) .toString() .split(',')[0]), - double.parse(encryptionHelper + double.parse(EncryptionHelper + .instance .decryptData( res['start_location']) .toString() .split(',')[1]), ), LatLng( - double.parse(encryptionHelper + double.parse(EncryptionHelper + .instance .decryptData( res['end_location']) .toString() .split(',')[0]), - double.parse(encryptionHelper + double.parse(EncryptionHelper + .instance .decryptData( res['end_location']) .toString() @@ -115,7 +119,7 @@ class HistoryDetailsPage extends StatelessWidget { MainAxisAlignment.spaceBetween, children: [ Text( - '${'Order ID'.tr} ${encryptionHelper.decryptData(res['id'])}', + '${'Order ID'.tr} ${EncryptionHelper.instance.decryptData(res['id'])}', style: CupertinoTheme.of(context) .textTheme .navActionTextStyle, @@ -145,13 +149,13 @@ class HistoryDetailsPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '${'Price is'.tr} ${encryptionHelper.decryptData(res['price_for_driver'])}', + '${'Price is'.tr} ${EncryptionHelper.instance.decryptData(res['price_for_driver'])}', style: CupertinoTheme.of(context) .textTheme .textStyle, ), Text( - '${'Distance is'.tr} ${encryptionHelper.decryptData(res['distance'])} KM', + '${'Distance is'.tr} ${EncryptionHelper.instance.decryptData(res['distance'])} KM', style: CupertinoTheme.of(context) .textTheme .textStyle, @@ -210,7 +214,7 @@ class HistoryDetailsPage extends StatelessWidget { ), child: Center( child: Text( - '${'Passenger Name is'.tr} ${encryptionHelper.decryptData(res['first_name'])} ${encryptionHelper.decryptData(res['last_name'])}', + '${'Passenger Name is'.tr} ${EncryptionHelper.instance.decryptData(res['first_name'])} ${EncryptionHelper.instance.decryptData(res['last_name'])}', style: CupertinoTheme.of(context) .textTheme .textStyle, @@ -229,7 +233,7 @@ class HistoryDetailsPage extends StatelessWidget { ), child: Center( child: Text( - '${'Status is'.tr} ${encryptionHelper.decryptData(res['status'])}', + '${'Status is'.tr} ${EncryptionHelper.instance.decryptData(res['status'])}', style: CupertinoTheme.of(context) .textTheme .textStyle, diff --git a/lib/views/home/Captin/home_captain/drawer_captain.dart b/lib/views/home/Captin/home_captain/drawer_captain.dart index f5bbff9..20712b9 100644 --- a/lib/views/home/Captin/home_captain/drawer_captain.dart +++ b/lib/views/home/Captin/home_captain/drawer_captain.dart @@ -536,7 +536,7 @@ class UserAccountHeader extends StatelessWidget { ), const SizedBox(height: 4), Text( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( box.read(BoxName.emailDriver), ), style: TextStyle( diff --git a/lib/views/home/Captin/home_captain/help_captain.dart b/lib/views/home/Captin/home_captain/help_captain.dart index 9f431f6..98a1ef8 100644 --- a/lib/views/home/Captin/home_captain/help_captain.dart +++ b/lib/views/home/Captin/home_captain/help_captain.dart @@ -125,7 +125,7 @@ class HelpCaptain extends StatelessWidget { .helpQuestionDate['message'][index]; return CupertinoListTile( title: Text( - encryptionHelper + EncryptionHelper.instance .decryptData(list['helpQuestion']), overflow: TextOverflow.ellipsis, ), @@ -143,9 +143,9 @@ class HelpCaptain extends StatelessWidget { ), onTap: () { helpController.getIndex( - int.parse(encryptionHelper + int.parse(EncryptionHelper.instance .decryptData(list['id'])), - encryptionHelper + EncryptionHelper.instance .decryptData(list['helpQuestion'])); helpController .getHelpRepley(list['id'].toString()); diff --git a/lib/views/home/Captin/home_captain/help_details_replay_page.dart b/lib/views/home/Captin/home_captain/help_details_replay_page.dart index c277f25..f640b00 100644 --- a/lib/views/home/Captin/home_captain/help_details_replay_page.dart +++ b/lib/views/home/Captin/home_captain/help_details_replay_page.dart @@ -54,7 +54,7 @@ class HelpDetailsReplayPage extends StatelessWidget { padding: const EdgeInsets.all(8.0), child: helpController.status == 'not yet' || - encryptionHelper + EncryptionHelper.instance .decryptData(helpController .helpQuestionRepleyDate[ 'message']['replay']) @@ -65,7 +65,7 @@ class HelpDetailsReplayPage extends StatelessWidget { style: AppStyle.title, ) : Text( - encryptionHelper + EncryptionHelper.instance .decryptData(helpController .helpQuestionRepleyDate[ 'message']['replay']) diff --git a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart index d799231..b3172ee 100644 --- a/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart +++ b/lib/views/home/Captin/home_captain/widget/left_menu_map_captain.dart @@ -106,7 +106,8 @@ GetBuilder leftMainMenuCaptainIcons() { // child: Builder(builder: (context) { // return IconButton( // onPressed: () async { - // Get.to(SmsSignupEgypt()); + // await storage.deleteAll(); + // box.erase(); // }, // icon: const Icon( // FontAwesome5.grin_tears, diff --git a/lib/views/home/Captin/orderCaptin/order_request_page.dart b/lib/views/home/Captin/orderCaptin/order_request_page.dart index e2da3e2..d6f2142 100644 --- a/lib/views/home/Captin/orderCaptin/order_request_page.dart +++ b/lib/views/home/Captin/orderCaptin/order_request_page.dart @@ -376,7 +376,7 @@ class _OrderRequestPageState extends State { 'notification.wav'); controller.refuseOrder( - encryptionHelper.encryptData( + EncryptionHelper.instance.encryptData( controller.myList[16].toString()), ); controller.addRideToNotificationDriverString( diff --git a/lib/views/home/profile/captains_cars.dart b/lib/views/home/profile/captains_cars.dart index 2da6607..9e82502 100644 --- a/lib/views/home/profile/captains_cars.dart +++ b/lib/views/home/profile/captains_cars.dart @@ -74,8 +74,9 @@ class CaptainsCars extends StatelessWidget { padding: const EdgeInsets.symmetric( horizontal: 4), child: Text( - encryptionHelper.decryptData( - car['car_plate']), + EncryptionHelper.instance + .decryptData( + car['car_plate']), style: AppStyle.title, ), ), diff --git a/lib/views/home/profile/cars_inserting_page.dart b/lib/views/home/profile/cars_inserting_page.dart index 2e7ec2a..6c34edc 100644 --- a/lib/views/home/profile/cars_inserting_page.dart +++ b/lib/views/home/profile/cars_inserting_page.dart @@ -95,7 +95,7 @@ GetBuilder egyptCarLicenceFront() { IconButton( onPressed: () async { ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[3]['prompt'].toString()), AppLink.uploadEgypt, 'car_front'); @@ -143,7 +143,7 @@ GetBuilder egyptCarLicenceFront() { child: InkWell( onTap: () async { ai.allMethodForAINewCar( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[3]['prompt'].toString()), AppLink.uploadEgypt1, 'car_front', @@ -214,7 +214,7 @@ GetBuilder egyptCarLicenceBack() { IconButton( onPressed: () async { ai.allMethodForAI( - encryptionHelper.decryptData( + EncryptionHelper.instance.decryptData( ai.prompts[4]['prompt'].toString()), AppLink.uploadEgypt, 'car_back'); @@ -287,7 +287,7 @@ GetBuilder egyptCarLicenceBack() { child: InkWell( onTap: () async { ai.allMethodForAI( - encryptionHelper + EncryptionHelper.instance .decryptData(ai.prompts[4]['prompt'].toString()), AppLink.uploadEgypt, 'car_back'); diff --git a/lib/views/home/profile/profile_captain.dart b/lib/views/home/profile/profile_captain.dart index 648c7c1..0363330 100644 --- a/lib/views/home/profile/profile_captain.dart +++ b/lib/views/home/profile/profile_captain.dart @@ -73,34 +73,41 @@ class ProfileCaptain extends StatelessWidget { driverId: controller.captainProfileData['driverID'] ?? '', - name: encryptionHelper.decryptData((controller - .captainProfileData['first_name']) ?? - '') + + name: EncryptionHelper.instance.decryptData( + (controller.captainProfileData[ + 'first_name']) ?? + '') + ' ' + - encryptionHelper.decryptData((controller - .captainProfileData['last_name']) ?? - ''), - phoneNumber: encryptionHelper.decryptData( - controller.captainProfileData['phone']) ?? + EncryptionHelper.instance.decryptData( + (controller.captainProfileData[ + 'last_name']) ?? + ''), + phoneNumber: EncryptionHelper.instance + .decryptData(controller + .captainProfileData['phone']) ?? '', - email: encryptionHelper.decryptData( + email: EncryptionHelper.instance.decryptData( controller.captainProfileData['email']) ?? '', - birthdate: encryptionHelper.decryptData(controller - .captainProfileData['birthdate']) ?? + birthdate: EncryptionHelper.instance.decryptData( + controller + .captainProfileData['birthdate']) ?? '', - gender: encryptionHelper.decryptData(controller - .captainProfileData['gender']) ?? + gender: EncryptionHelper.instance.decryptData( + controller + .captainProfileData['gender']) ?? '', - education: encryptionHelper.decryptData(controller - .captainProfileData['education']) ?? + education: EncryptionHelper.instance.decryptData( + controller + .captainProfileData['education']) ?? '', carMake: controller.captainProfileData['make'] ?? '', carModel: controller.captainProfileData['model'] ?? '', - carPlate: encryptionHelper.decryptData(controller - .captainProfileData['car_plate']) ?? + carPlate: EncryptionHelper.instance.decryptData( + controller + .captainProfileData['car_plate']) ?? '', carColor: controller.captainProfileData['color'] ?? '', diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 456a878..cda4555 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -11,6 +11,7 @@ import file_selector_macos import firebase_auth import firebase_core import firebase_messaging +import flutter_app_group_directory import flutter_image_compress_macos import flutter_inappwebview_macos import flutter_local_notifications @@ -38,6 +39,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) + FlutterAppGroupDirectoryPlugin.register(with: registry.registrar(forPlugin: "FlutterAppGroupDirectoryPlugin")) FlutterImageCompressMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterImageCompressMacosPlugin")) InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 7f23461..7ad7382 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -351,13 +351,13 @@ packages: source: hosted version: "0.7.10" device_info_plus: - dependency: transitive + dependency: "direct main" description: name: device_info_plus - sha256: "4fa68e53e26ab17b70ca39f072c285562cfc1589df5bb1e9295db90f6645f431" + sha256: "72d146c6d7098689ff5c5f66bcf593ac11efc530095385356e131070333e64da" url: "https://pub.dev" source: hosted - version: "11.2.0" + version: "11.3.0" device_info_plus_platform_interface: dependency: transitive description: @@ -563,6 +563,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_app_group_directory: + dependency: transitive + description: + name: flutter_app_group_directory + sha256: "680ef9b2dee84c237cd7bb7fc78bc45867b32556a8a5f0de61278078b9fefd05" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter_cache_manager: dependency: transitive description: @@ -1308,6 +1316,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + jailbreak_root_detection: + dependency: "direct main" + description: + name: jailbreak_root_detection + sha256: ee98f5e69b43c758ee1779204b0926a09f0371eebe1462b876fb6a8bd130cbe5 + url: "https://pub.dev" + source: hosted + version: "1.1.5" js: dependency: transitive description: @@ -1348,6 +1364,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.13" + jwt_decoder: + dependency: "direct main" + description: + name: jwt_decoder + sha256: "54774aebf83f2923b99e6416b4ea915d47af3bde56884eb622de85feabbc559f" + url: "https://pub.dev" + source: hosted + version: "2.0.1" leak_tracker: dependency: transitive description: @@ -1380,6 +1404,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.1" + live_activities: + dependency: "direct main" + description: + name: live_activities + sha256: fd5414cca16352add9bae9b949e7b5d84ca219a1eb298772174db1b3a2be4b77 + url: "https://pub.dev" + source: hosted + version: "2.3.0" local_auth: dependency: "direct main" description: @@ -1716,6 +1748,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + quick_actions: + dependency: "direct main" + description: + name: quick_actions + sha256: "7e35dd6a21f5bbd21acf6899039eaf85001a5ac26d52cbd6a8a2814505b90798" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + quick_actions_android: + dependency: transitive + description: + name: quick_actions_android + sha256: "926e50d6f879287b34d21934e6c9457f0d851f554179f2a9e8136c4acd1b7062" + url: "https://pub.dev" + source: hosted + version: "1.0.18" + quick_actions_ios: + dependency: transitive + description: + name: quick_actions_ios + sha256: "837b7e6b5973784d3da56b8c959b446b215914f20405d88cd7d22a2fb94e4e4c" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + quick_actions_platform_interface: + dependency: transitive + description: + name: quick_actions_platform_interface + sha256: "1fec7068db5122cd019e9340d3d7be5d36eab099695ef3402c7059ee058329a4" + url: "https://pub.dev" + source: hosted + version: "1.1.0" recase: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f9f5595..50fb3ce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,7 +43,6 @@ dependencies: encrypt: ^5.0.3 flutter_rating_bar: ^4.0.1 flutter_font_icons: ^2.2.5 - # device_info_plus: ^9.1.0 image_picker: ^1.0.4 flutter_stripe: ^11.3.0 camera: ^0.11.0+1 #to be remove @@ -89,6 +88,11 @@ dependencies: youtube_player_flutter: ^9.0.4 flutter_confetti: ^0.3.0 slide_to_act: ^2.0.2 + live_activities: ^2.3.0 + quick_actions: ^1.1.0 + jwt_decoder: ^2.0.1 + jailbreak_root_detection: ^1.1.5 + device_info_plus: ^11.3.0 dev_dependencies: flutter_test: