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'
|
||||
|
||||
|
||||
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'
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.siro.siro_driver
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.LinearLayout
|
||||
@@ -134,11 +135,17 @@ class MainActivity : FlutterFragmentActivity() {
|
||||
|
||||
// --- بقية كود الحماية الخاص بك ---
|
||||
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 {
|
||||
val isRootedByRootBeer = RootBeer(this).isRooted
|
||||
isRootedByRootBeer
|
||||
} catch (e: Exception) {
|
||||
true
|
||||
} catch (t: Throwable) {
|
||||
Log.e("MainActivity", "RootBeer check failed: ", t)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ class BoxName {
|
||||
static const String initializationVector = 'initializationVector';
|
||||
static const String firstTimeLoadKey = 'firstTimeLoadKey';
|
||||
static const String jwt = "jwt";
|
||||
static const String walletJwt = "walletJwt";
|
||||
static const String blockUntilDate = "blockUntilDate";
|
||||
static const String rideId = "rideId";
|
||||
static const String rideArgumentsFromBackground =
|
||||
|
||||
@@ -142,11 +142,55 @@ class LoginDriverController extends GetxController {
|
||||
}
|
||||
|
||||
var dev = '';
|
||||
Future<String>? _walletJwtFuture;
|
||||
|
||||
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') {
|
||||
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');
|
||||
dev = Platform.isAndroid ? 'android' : 'ios';
|
||||
var fingerPrint = box.read(BoxName.deviceFingerprint)?.toString() ??
|
||||
@@ -172,8 +216,12 @@ class LoginDriverController extends GetxController {
|
||||
: decoded['hmac'];
|
||||
Log.print('payment["jwt"]: $jwt');
|
||||
|
||||
await box.write(BoxName.hmac, hmac);
|
||||
return jwt.toString();
|
||||
if (jwt != null) {
|
||||
await box.write(BoxName.walletJwt, jwt.toString());
|
||||
await box.write(BoxName.hmac, hmac);
|
||||
return jwt.toString();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
getJWT() async {
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
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:siro_driver/constant/box_name.dart';
|
||||
import 'package:siro_driver/constant/colors.dart';
|
||||
@@ -204,6 +205,11 @@ class DeviceHelper {
|
||||
class SecurityHelper {
|
||||
/// Performs security checks and handles potential risks
|
||||
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 isJailBroken = false;
|
||||
bool isRealDevice = true;
|
||||
|
||||
@@ -770,17 +770,30 @@ class HomeCaptainController extends GetxController {
|
||||
payload: {'country': box.read(BoxName.countryCode).toString()},
|
||||
);
|
||||
if (res != 'failure') {
|
||||
var json = jsonDecode(res);
|
||||
kazan = double.parse(json['message'][0]['kazan']);
|
||||
naturePrice = double.parse(json['message'][0]['naturePrice']);
|
||||
heavyPrice = double.parse(json['message'][0]['heavyPrice']);
|
||||
latePrice = double.parse(json['message'][0]['latePrice']);
|
||||
comfortPrice = double.parse(json['message'][0]['comfortPrice']);
|
||||
speedPrice = double.parse(json['message'][0]['speedPrice']);
|
||||
deliveryPrice = double.parse(json['message'][0]['deliveryPrice']);
|
||||
mashwariPrice = double.parse(json['message'][0]['freePrice']);
|
||||
familyPrice = double.parse(json['message'][0]['familyPrice']);
|
||||
fuelPrice = double.parse(json['message'][0]['fuelPrice']);
|
||||
try {
|
||||
var json = jsonDecode(res);
|
||||
if (json['message'] is List && json['message'].isNotEmpty) {
|
||||
final item = json['message'][0];
|
||||
|
||||
double parseDouble(dynamic val) {
|
||||
if (val == null) return 0.0;
|
||||
return double.tryParse(val.toString()) ?? 0.0;
|
||||
}
|
||||
|
||||
kazan = parseDouble(item['kazanPercent'] ?? item['kazan']);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class AboutPage extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
'Siro LLC\n${'Syria'.tr}',
|
||||
'Siro LLC\n${(box.read(BoxName.countryCode)?.toString() ?? 'Syria').tr}',
|
||||
style: AppStyle.headTitle2,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user