From 3b4b4639a61daba46296afb2cee7a3d1b6c155df Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Sun, 2 Aug 2026 18:19:50 +0300 Subject: [PATCH] Guard debug logs in release and remove device-check bypass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Log.print used developer.log with no kDebugMode guard, so release builds emitted wallet JWTs, the HMAC secret, phone numbers and full API responses to os_log/logcat on the user's device. Both the rider and driver apps were affected. Also removes a hardcoded test-account condition in the rider login flow that skipped the entire FCM-token/fingerprint comparison — and therefore the device-change OTP — for one email address. Co-Authored-By: Claude Opus 5 --- siro_driver/lib/print.dart | 7 +++ .../lib/controller/auth/login_controller.dart | 58 +++++++++---------- siro_rider/lib/print.dart | 7 +++ 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/siro_driver/lib/print.dart b/siro_driver/lib/print.dart index a3d59f67..fe274a12 100755 --- a/siro_driver/lib/print.dart +++ b/siro_driver/lib/print.dart @@ -1,9 +1,16 @@ import 'dart:developer' as developer; +import 'package:flutter/foundation.dart' show kDebugMode; + class Log { Log._(); + /// ⚠️ يُطبع في وضع التطوير فقط. + /// `developer.log` لا يُحذف في نسخة الإصدار — يذهب إلى os_log على iOS + /// و logcat على أندرويد، وكان يسرّب الـ JWT وسر الـ HMAC وأرقام الهواتف + /// وردود الـ API كاملة إلى سجلّ النظام على جهاز المستخدم. static void print(String value, {StackTrace? stackTrace}) { + if (!kDebugMode) return; developer.log(value, name: 'LOG', stackTrace: stackTrace); } diff --git a/siro_rider/lib/controller/auth/login_controller.dart b/siro_rider/lib/controller/auth/login_controller.dart index 658cc59b..27c3fc36 100644 --- a/siro_rider/lib/controller/auth/login_controller.dart +++ b/siro_rider/lib/controller/auth/login_controller.dart @@ -418,39 +418,39 @@ class LoginController extends GetxController { force: true); // Fetch access token after clearing firstTimeLoadKey // ── 5. المقارنة: FCM token + fingerprint ────────────────────── - if (email != '962798583052@intaleqapp.com') { - if (serverFCM == null && - tokenResp != null && - tokenResp != 'failure' && - tokenResp != 'error' && - tokenResp != 'token_expired') { - final tokenJson = - tokenResp is String ? jsonDecode(tokenResp) : tokenResp; - final serverData = tokenJson['data'] ?? tokenJson['message']; - if (serverData is Map) { - serverFCM = serverData['token']?.toString() ?? ''; - serverFP = serverData['fingerPrint']?.toString() ?? ''; - } + // ملاحظة: كان هنا استثناء لحساب اختبار بعينه يتخطى الفحص بالكامل. + // حُذف — لا استثناءات على التحقق من تغيّر الجهاز. + if (serverFCM == null && + tokenResp != null && + tokenResp != 'failure' && + tokenResp != 'error' && + tokenResp != 'token_expired') { + final tokenJson = + tokenResp is String ? jsonDecode(tokenResp) : tokenResp; + final serverData = tokenJson['data'] ?? tokenJson['message']; + if (serverData is Map) { + serverFCM = serverData['token']?.toString() ?? ''; + serverFP = serverData['fingerPrint']?.toString() ?? ''; } + } - if (serverFCM != null && serverFCM.isNotEmpty) { - final localFCM = (box.read(BoxName.tokenFCM) ?? '').toString(); + if (serverFCM != null && serverFCM.isNotEmpty) { + final localFCM = (box.read(BoxName.tokenFCM) ?? '').toString(); - // ── اختلاف أي منهما = جهاز مختلف أو تثبيت جديد ───────── - final fcmChanged = serverFCM != localFCM; - final fpChanged = - serverFP != null && serverFP.isNotEmpty && serverFP != localFP; + // ── اختلاف أي منهما = جهاز مختلف أو تثبيت جديد ───────── + final fcmChanged = serverFCM != localFCM; + final fpChanged = + serverFP != null && serverFP.isNotEmpty && serverFP != localFP; - if (fcmChanged || fpChanged) { - mySnackbarInfo('Device Change Detected'.tr); - await Get.to(() => OtpVerificationPage( - phone: data['phone'].toString(), - deviceToken: localFP, - token: tokenResp ?? '', - ptoken: serverFCM ?? '', // نمرر FCM القديم للـ OTP controller - )); - return; - } + if (fcmChanged || fpChanged) { + mySnackbarInfo('Device Change Detected'.tr); + await Get.to(() => OtpVerificationPage( + phone: data['phone'].toString(), + deviceToken: localFP, + token: tokenResp ?? '', + ptoken: serverFCM ?? '', // نمرر FCM القديم للـ OTP controller + )); + return; } } diff --git a/siro_rider/lib/print.dart b/siro_rider/lib/print.dart index a3d59f67..fe274a12 100644 --- a/siro_rider/lib/print.dart +++ b/siro_rider/lib/print.dart @@ -1,9 +1,16 @@ import 'dart:developer' as developer; +import 'package:flutter/foundation.dart' show kDebugMode; + class Log { Log._(); + /// ⚠️ يُطبع في وضع التطوير فقط. + /// `developer.log` لا يُحذف في نسخة الإصدار — يذهب إلى os_log على iOS + /// و logcat على أندرويد، وكان يسرّب الـ JWT وسر الـ HMAC وأرقام الهواتف + /// وردود الـ API كاملة إلى سجلّ النظام على جهاز المستخدم. static void print(String value, {StackTrace? stackTrace}) { + if (!kDebugMode) return; developer.log(value, name: 'LOG', stackTrace: stackTrace); }