Update: 2026-08-02 17:52:28
This commit is contained in:
@@ -67,8 +67,8 @@ class AppUpdateController extends GetxController {
|
||||
|
||||
void _showStoreUpdateDialog() {
|
||||
final String storeUrl = Platform.isAndroid
|
||||
? 'https://play.google.com/store/apps/details?id=com.siro_driver'
|
||||
: 'https://apps.apple.com/jo/app/siro-driver/id6482995159';
|
||||
? AppLink.driverAppStoreAndroid
|
||||
: AppLink.driverAppStoreIOS;
|
||||
|
||||
Get.defaultDialog(
|
||||
title: "تحديث جديد متوفر".tr,
|
||||
|
||||
@@ -22,7 +22,6 @@ import 'ssl_pinning.dart';
|
||||
class CRUD {
|
||||
final NetGuard _netGuard = NetGuard();
|
||||
final _client = SslPinning.createPinnedClient();
|
||||
static bool _isRefreshingJWT = false;
|
||||
static String _lastErrorSignature = '';
|
||||
static DateTime _lastErrorTimestamp = DateTime(2000);
|
||||
static const Duration _errorLogDebounceDuration = Duration(minutes: 1);
|
||||
@@ -107,6 +106,18 @@ class CRUD {
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// _ensureJwt — يضمن وجود توكن صالح قبل الإرسال
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
Future<String> _ensureJwt() async {
|
||||
String token = await _getJwt();
|
||||
if (_isJwtValid(token)) return token;
|
||||
|
||||
final ok = await Get.put(LoginDriverController()).getJWT();
|
||||
if (!ok) return '';
|
||||
return await _getJwt();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// _makeRequest — دالة مركزية لكل الطلبات
|
||||
// ───────────────────────────────────────────────────────────────
|
||||
@@ -119,6 +130,7 @@ class CRUD {
|
||||
required String link,
|
||||
Map<String, dynamic>? payload,
|
||||
required Map<String, String> headers,
|
||||
bool allowRefresh = true,
|
||||
}) async {
|
||||
// timeouts مرتفعة مناسبة للإنترنت الضعيف في سوريا
|
||||
const totalTimeout = Duration(seconds: 60);
|
||||
@@ -186,19 +198,33 @@ class CRUD {
|
||||
}
|
||||
}
|
||||
|
||||
// 401 → تجديد التوكن (مع حماية من الحلقة اللانهائية)
|
||||
// 429 → السيرفر رافض بسبب الضغط؛ ممنوع نجدّد التوكن أو نعيد المحاولة
|
||||
if (sc == 429) {
|
||||
Log.print('🛑 [RES-$requestId] 429 rate limited — $link');
|
||||
return 'rate_limited';
|
||||
}
|
||||
|
||||
// 401 → تجديد التوكن مرة واحدة ثم إعادة الطلب مرة واحدة فقط
|
||||
if (sc == 401) {
|
||||
// تخطي تجديد التوكن لـ endpoints غير حرجة (مثل تسجيل الأخطاء)
|
||||
final isNonCritical = link.contains('errorApp.php');
|
||||
if (!_isRefreshingJWT && !isNonCritical) {
|
||||
_isRefreshingJWT = true;
|
||||
try {
|
||||
await Get.put(LoginDriverController()).getJWT();
|
||||
} finally {
|
||||
_isRefreshingJWT = false;
|
||||
}
|
||||
}
|
||||
return 'token_expired';
|
||||
if (isNonCritical || !allowRefresh) return 'token_expired';
|
||||
|
||||
final refreshed = await Get.put(LoginDriverController()).getJWT();
|
||||
if (!refreshed) return 'token_expired';
|
||||
|
||||
final newToken = await _getJwt();
|
||||
if (newToken.isEmpty) return 'token_expired';
|
||||
|
||||
// إعادة الطلب بالتوكن الجديد — allowRefresh: false يمنع أي تكرار إضافي
|
||||
final retryHeaders = Map<String, String>.from(headers)
|
||||
..['Authorization'] = 'Bearer $newToken';
|
||||
return await _makeRequest(
|
||||
link: link,
|
||||
payload: payload,
|
||||
headers: retryHeaders,
|
||||
allowRefresh: false,
|
||||
);
|
||||
}
|
||||
|
||||
// 5xx
|
||||
@@ -218,16 +244,11 @@ class CRUD {
|
||||
required String link,
|
||||
Map<String, dynamic>? payload,
|
||||
}) async {
|
||||
String token = await _getJwt();
|
||||
|
||||
// فحص صلاحية التوكن قبل الإرسال — تجنب طلب مضمون الرفض
|
||||
if (!_isJwtValid(token) && !_isRefreshingJWT) {
|
||||
_isRefreshingJWT = true;
|
||||
try {
|
||||
await Get.put(LoginDriverController()).getJWT();
|
||||
token = await _getJwt();
|
||||
} finally {
|
||||
_isRefreshingJWT = false;
|
||||
String token = await _ensureJwt();
|
||||
if (token.isEmpty) {
|
||||
// إذا فشل الحصول على توكن، لا ترسل الطلب للباك إند لأنّه سيرفض حتماً.
|
||||
if (!link.contains('login') && !link.contains('errorApp.php')) {
|
||||
return 'token_expired';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,19 +268,11 @@ class CRUD {
|
||||
Future<dynamic> get({
|
||||
required String link,
|
||||
Map<String, dynamic>? payload,
|
||||
bool allowRefresh = true,
|
||||
}) async {
|
||||
try {
|
||||
// فحص صلاحية التوكن قبل الإرسال
|
||||
String token = await _getJwt();
|
||||
if (!_isJwtValid(token) && !_isRefreshingJWT) {
|
||||
_isRefreshingJWT = true;
|
||||
try {
|
||||
await Get.put(LoginDriverController()).getJWT();
|
||||
token = await _getJwt();
|
||||
} finally {
|
||||
_isRefreshingJWT = false;
|
||||
}
|
||||
}
|
||||
final String token = await _ensureJwt();
|
||||
|
||||
var url = Uri.parse(link);
|
||||
var response = await _client.post(
|
||||
@@ -280,15 +293,18 @@ class CRUD {
|
||||
if (jsonData['status'] == 'success') return response.body;
|
||||
return jsonData['status'];
|
||||
} else if (response.statusCode == 401) {
|
||||
if (!_isRefreshingJWT) {
|
||||
_isRefreshingJWT = true;
|
||||
try {
|
||||
await Get.put(LoginDriverController()).getJWT();
|
||||
} finally {
|
||||
_isRefreshingJWT = false;
|
||||
}
|
||||
}
|
||||
return 'token_expired';
|
||||
// تجديد التوكن مرة واحدة ثم إعادة الطلب مرة واحدة فقط
|
||||
// (allowRefresh: false تمنع أي تكرار إضافي) — نفس سلوك _makeRequest.
|
||||
if (!allowRefresh) return 'token_expired';
|
||||
|
||||
final refreshed = await Get.put(LoginDriverController()).getJWT();
|
||||
if (!refreshed) return 'token_expired';
|
||||
|
||||
return await get(
|
||||
link: link,
|
||||
payload: payload,
|
||||
allowRefresh: false,
|
||||
);
|
||||
} else if (response.statusCode >= 500) {
|
||||
addError('Non-200: ${response.statusCode}', 'crud().get - Other',
|
||||
url.toString());
|
||||
|
||||
@@ -48,8 +48,8 @@ Future<String> getPackageInfo() async {
|
||||
|
||||
void showUpdateDialog(BuildContext context) {
|
||||
final String storeUrl = Platform.isAndroid
|
||||
? 'https://play.google.com/store/apps/details?id=com.siro_driver'
|
||||
: 'https://apps.apple.com/jo/app/siro-driver/id6482995159';
|
||||
? AppLink.driverAppStoreAndroid
|
||||
: AppLink.driverAppStoreIOS;
|
||||
|
||||
showGeneralDialog(
|
||||
context: context,
|
||||
|
||||
Reference in New Issue
Block a user