refactor: optimize wallet JWT management, update security checks for debug builds, and improve pricing data parsing
This commit is contained in:
@@ -122,7 +122,7 @@ dependencies {
|
|||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
|
||||||
|
|
||||||
|
|
||||||
implementation 'com.scottyab:rootbeer-lib:0.1.0'
|
implementation 'com.scottyab:rootbeer-lib:0.1.2'
|
||||||
|
|
||||||
// تمت الترقية لتطابق تطبيق الراكب
|
// تمت الترقية لتطابق تطبيق الراكب
|
||||||
implementation 'com.google.android.gms:play-services-safetynet:18.1.0'
|
implementation 'com.google.android.gms:play-services-safetynet:18.1.0'
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.siro.siro_driver
|
|||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
@@ -134,11 +135,17 @@ class MainActivity : FlutterFragmentActivity() {
|
|||||||
|
|
||||||
// --- بقية كود الحماية الخاص بك ---
|
// --- بقية كود الحماية الخاص بك ---
|
||||||
private fun isDeviceCompromised(): Boolean {
|
private fun isDeviceCompromised(): Boolean {
|
||||||
|
val isDebug = (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
|
||||||
|
if (isDebug) {
|
||||||
|
Log.d("MainActivity", "Debug build: bypassing root check")
|
||||||
|
return false
|
||||||
|
}
|
||||||
return try {
|
return try {
|
||||||
val isRootedByRootBeer = RootBeer(this).isRooted
|
val isRootedByRootBeer = RootBeer(this).isRooted
|
||||||
isRootedByRootBeer
|
isRootedByRootBeer
|
||||||
} catch (e: Exception) {
|
} catch (t: Throwable) {
|
||||||
true
|
Log.e("MainActivity", "RootBeer check failed: ", t)
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ class BoxName {
|
|||||||
static const String initializationVector = 'initializationVector';
|
static const String initializationVector = 'initializationVector';
|
||||||
static const String firstTimeLoadKey = 'firstTimeLoadKey';
|
static const String firstTimeLoadKey = 'firstTimeLoadKey';
|
||||||
static const String jwt = "jwt";
|
static const String jwt = "jwt";
|
||||||
|
static const String walletJwt = "walletJwt";
|
||||||
static const String blockUntilDate = "blockUntilDate";
|
static const String blockUntilDate = "blockUntilDate";
|
||||||
static const String rideId = "rideId";
|
static const String rideId = "rideId";
|
||||||
static const String rideArgumentsFromBackground =
|
static const String rideArgumentsFromBackground =
|
||||||
|
|||||||
@@ -142,11 +142,55 @@ class LoginDriverController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dev = '';
|
var dev = '';
|
||||||
|
Future<String>? _walletJwtFuture;
|
||||||
|
|
||||||
getJwtWallet() async {
|
getJwtWallet() async {
|
||||||
|
if (_walletJwtFuture != null) {
|
||||||
|
Log.print('⏳ getJwtWallet: Request already in progress, reusing future.');
|
||||||
|
return _walletJwtFuture!;
|
||||||
|
}
|
||||||
|
|
||||||
|
_walletJwtFuture = _getJwtWalletInternal();
|
||||||
|
try {
|
||||||
|
return await _walletJwtFuture!;
|
||||||
|
} finally {
|
||||||
|
_walletJwtFuture = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> _getJwtWalletInternal() async {
|
||||||
if (box.read(BoxName.security_check).toString() != 'passed') {
|
if (box.read(BoxName.security_check).toString() != 'passed') {
|
||||||
Log.print('Security check failed');
|
Log.print('Security check failed');
|
||||||
return;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1. Check GetStorage first to avoid redundant API calls
|
||||||
|
String? cachedJwt = box.read(BoxName.walletJwt)?.toString();
|
||||||
|
if (cachedJwt != null && cachedJwt.isNotEmpty) {
|
||||||
|
bool isTokenValid = false;
|
||||||
|
try {
|
||||||
|
final parts = cachedJwt.split('.');
|
||||||
|
if (parts.length == 3) {
|
||||||
|
var payload = parts[1];
|
||||||
|
switch (payload.length % 4) {
|
||||||
|
case 2: payload += '=='; break;
|
||||||
|
case 3: payload += '='; break;
|
||||||
|
}
|
||||||
|
final decoded = jsonDecode(utf8.decode(base64Url.decode(payload)));
|
||||||
|
final exp = decoded['exp'];
|
||||||
|
if (exp != null) {
|
||||||
|
// Check if token has at least 10 seconds remaining
|
||||||
|
isTokenValid = DateTime.now().millisecondsSinceEpoch < (exp * 1000 - 10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
if (isTokenValid) {
|
||||||
|
Log.print('🔑 Valid Wallet JWT found in storage. Skipping generation.');
|
||||||
|
return cachedJwt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.print('Security check passed');
|
Log.print('Security check passed');
|
||||||
dev = Platform.isAndroid ? 'android' : 'ios';
|
dev = Platform.isAndroid ? 'android' : 'ios';
|
||||||
var fingerPrint = box.read(BoxName.deviceFingerprint)?.toString() ??
|
var fingerPrint = box.read(BoxName.deviceFingerprint)?.toString() ??
|
||||||
@@ -172,9 +216,13 @@ class LoginDriverController extends GetxController {
|
|||||||
: decoded['hmac'];
|
: decoded['hmac'];
|
||||||
Log.print('payment["jwt"]: $jwt');
|
Log.print('payment["jwt"]: $jwt');
|
||||||
|
|
||||||
|
if (jwt != null) {
|
||||||
|
await box.write(BoxName.walletJwt, jwt.toString());
|
||||||
await box.write(BoxName.hmac, hmac);
|
await box.write(BoxName.hmac, hmac);
|
||||||
return jwt.toString();
|
return jwt.toString();
|
||||||
}
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
getJWT() async {
|
getJWT() async {
|
||||||
await EncryptionHelper.initialize();
|
await EncryptionHelper.initialize();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:convert';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:jailbreak_root_detection/jailbreak_root_detection.dart';
|
import 'package:jailbreak_root_detection/jailbreak_root_detection.dart';
|
||||||
import 'package:siro_driver/constant/box_name.dart';
|
import 'package:siro_driver/constant/box_name.dart';
|
||||||
import 'package:siro_driver/constant/colors.dart';
|
import 'package:siro_driver/constant/colors.dart';
|
||||||
@@ -204,6 +205,11 @@ class DeviceHelper {
|
|||||||
class SecurityHelper {
|
class SecurityHelper {
|
||||||
/// Performs security checks and handles potential risks
|
/// Performs security checks and handles potential risks
|
||||||
static Future<void> performSecurityChecks() async {
|
static Future<void> performSecurityChecks() async {
|
||||||
|
if (kDebugMode) {
|
||||||
|
debugPrint("Debug mode: skipping security helper check");
|
||||||
|
box.write(BoxName.security_check, 'passed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool isNotTrust = false;
|
bool isNotTrust = false;
|
||||||
bool isJailBroken = false;
|
bool isJailBroken = false;
|
||||||
bool isRealDevice = true;
|
bool isRealDevice = true;
|
||||||
|
|||||||
@@ -770,17 +770,30 @@ class HomeCaptainController extends GetxController {
|
|||||||
payload: {'country': box.read(BoxName.countryCode).toString()},
|
payload: {'country': box.read(BoxName.countryCode).toString()},
|
||||||
);
|
);
|
||||||
if (res != 'failure') {
|
if (res != 'failure') {
|
||||||
|
try {
|
||||||
var json = jsonDecode(res);
|
var json = jsonDecode(res);
|
||||||
kazan = double.parse(json['message'][0]['kazan']);
|
if (json['message'] is List && json['message'].isNotEmpty) {
|
||||||
naturePrice = double.parse(json['message'][0]['naturePrice']);
|
final item = json['message'][0];
|
||||||
heavyPrice = double.parse(json['message'][0]['heavyPrice']);
|
|
||||||
latePrice = double.parse(json['message'][0]['latePrice']);
|
double parseDouble(dynamic val) {
|
||||||
comfortPrice = double.parse(json['message'][0]['comfortPrice']);
|
if (val == null) return 0.0;
|
||||||
speedPrice = double.parse(json['message'][0]['speedPrice']);
|
return double.tryParse(val.toString()) ?? 0.0;
|
||||||
deliveryPrice = double.parse(json['message'][0]['deliveryPrice']);
|
}
|
||||||
mashwariPrice = double.parse(json['message'][0]['freePrice']);
|
|
||||||
familyPrice = double.parse(json['message'][0]['familyPrice']);
|
kazan = parseDouble(item['kazanPercent'] ?? item['kazan']);
|
||||||
fuelPrice = double.parse(json['message'][0]['fuelPrice']);
|
naturePrice = parseDouble(item['normalMinPrice'] ?? item['naturePrice']);
|
||||||
|
heavyPrice = parseDouble(item['peakMinPrice'] ?? item['heavyPrice']);
|
||||||
|
latePrice = parseDouble(item['lateMinPrice'] ?? item['latePrice']);
|
||||||
|
comfortPrice = parseDouble(item['comfortPrice']);
|
||||||
|
speedPrice = parseDouble(item['speedPrice']);
|
||||||
|
deliveryPrice = parseDouble(item['deliveryPrice']);
|
||||||
|
mashwariPrice = parseDouble(item['freePrice'] ?? item['mishwarVipPrice']);
|
||||||
|
familyPrice = parseDouble(item['familyPrice'] ?? item['ladyPrice']);
|
||||||
|
fuelPrice = parseDouble(item['fuelPrice']);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Log.print("Error parsing kazan percent: $e");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class AboutPage extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Siro LLC\n${'Syria'.tr}',
|
'Siro LLC\n${(box.read(BoxName.countryCode)?.toString() ?? 'Syria').tr}',
|
||||||
style: AppStyle.headTitle2,
|
style: AppStyle.headTitle2,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user