Update: 2026-08-02 18:28:40

This commit is contained in:
Hamza-Ayed
2026-08-02 18:28:40 +03:00
parent 03a21aa95d
commit 02e652a786
9 changed files with 98 additions and 9 deletions
@@ -284,9 +284,64 @@ class LoginController extends GetxController {
// • يرجع hmac مع الـ jwt ويخزنه في GetStorage
// • الـ JWT لا يُشفَّر ثلاثياً (يُستخدم مباشرة في الـ header)
// ─────────────────────────────────────────────────────────────
// • يُخزَّن التوكن ويُعاد استخدامه ما دام أمامه أكثر من 10 ثوانٍ
// (عمره 300ث)، فلا نُسجّل دخولاً مع كل طلب محفظة.
static Future<String?>? _walletJwtFuture;
Future<String?> getJwtWallet() async {
// طلب قيد التنفيذ؟ شارك نتيجته بدل إطلاق طلب ثانٍ.
if (_walletJwtFuture != null) {
Log.print('⏳ getJwtWallet: طلب قيد التنفيذ — إعادة استخدام نفس الـ future.');
return _walletJwtFuture!;
}
_walletJwtFuture = _getJwtWalletInternal();
try {
return await _walletJwtFuture!;
} finally {
_walletJwtFuture = null;
}
}
/// هل التوكن المخزَّن صالح ويخصّ الراكب الحالي؟
/// نتحقق من `user_id` أيضاً كي لا يُعاد استخدام توكن حساب سابق
/// على نفس الجهاز بعد تبديل المستخدم.
bool _isWalletJwtUsable(String jwt, String passengerId) {
try {
final parts = jwt.split('.');
if (parts.length != 3) return false;
String payload = parts[1];
while (payload.length % 4 != 0) {
payload += '=';
}
final decoded = jsonDecode(utf8.decode(base64Url.decode(payload)));
if ((decoded['user_id'] ?? '').toString() != passengerId) return false;
final exp = decoded['exp'];
if (exp == null) return false;
// هامش 10 ثوانٍ حتى لا ينتهي التوكن أثناء الطلب نفسه
return DateTime.now().millisecondsSinceEpoch < (exp * 1000 - 10000);
} catch (_) {
return false;
}
}
Future<String?> _getJwtWalletInternal() async {
dev = Platform.isAndroid ? 'android' : 'ios';
final String passengerId = box.read(BoxName.passengerID)?.toString() ?? '';
// ── إعادة استخدام التوكن المخزَّن إن كان صالحاً ────────────────
final String cachedJwt = box.read(BoxName.walletJwt)?.toString() ?? '';
final String cachedHmac = box.read(BoxName.hmac)?.toString() ?? '';
if (cachedJwt.isNotEmpty &&
cachedHmac.isNotEmpty &&
passengerId.isNotEmpty &&
_isWalletJwtUsable(cachedJwt, passengerId)) {
Log.print('🔑 توكن محفظة صالح في التخزين — تخطّي طلب السيرفر.');
return cachedJwt;
}
// نعيد حساب البصمة أولاً كي لا نرسل قيمة GCM قديمة عالقة في التخزين
// من نسخة سابقة من التطبيق (مثل getJWT تماماً).
await DeviceHelper.getDeviceFingerprint();
@@ -323,6 +378,11 @@ class LoginController extends GetxController {
box.write(BoxName.hmac, hmac);
}
// نخزّن التوكن ليُعاد استخدامه حتى قرب انتهائه بدل طلب جديد كل مرة
if (jwt != null) {
box.write(BoxName.walletJwt, jwt);
}
return jwt;
}