Update: 2026-06-23 17:25:29

This commit is contained in:
Hamza-Ayed
2026-06-23 17:25:29 +03:00
parent 4e2f165d60
commit 148ca3af1d
5 changed files with 46 additions and 71 deletions

View File

@@ -53,7 +53,7 @@ function sendKazumiSms(string $receiver, string $otp): bool {
function getNabehBearerToken(): ?string {
global $redis;
// 1. Try to read cached token from Redis (TTL 24 hours)
// 1. Try fetching from Redis first
if ($redis) {
try {
$cachedToken = $redis->get('nabeh_bearer_token');
@@ -61,7 +61,8 @@ function getNabehBearerToken(): ?string {
return $cachedToken;
}
} catch (Exception $e) {
error_log("⚠️ [Nabeh Auth Redis] Error reading token: " . $e->getMessage());
$msg = "⚠️ [Nabeh Auth Redis] Error reading token: " . $e->getMessage();
error_log($msg); echo $msg . "<br>";
}
}
@@ -70,7 +71,8 @@ function getNabehBearerToken(): ?string {
$password = getenv('NABEH_PASSWORD');
if (!$email || !$password) {
error_log("⚠️ [Nabeh Auth] Missing NABEH_EMAIL or NABEH_PASSWORD environment variables.");
$msg = "⚠️ [Nabeh Auth] Missing NABEH_EMAIL or NABEH_PASSWORD environment variables.";
error_log($msg); echo $msg . "<br>";
return null;
}
@@ -87,19 +89,24 @@ function getNabehBearerToken(): ?string {
if ($response) {
$decoded = json_decode($response, true);
$token = $decoded['token'] ?? $decoded['message']['token'] ?? $decoded['jwt'] ?? $decoded['access_token'] ?? null;
if ($token) {
// Cache token in Redis for 24 hours (86400 seconds)
// 3. Cache token in Redis for 24h
if ($redis) {
try {
$redis->setex('nabeh_bearer_token', 86400, $token);
} catch (Exception $e) {
error_log("⚠️ [Nabeh Auth Redis Cache Save] Error saving token: " . $e->getMessage());
$msg = "⚠️ [Nabeh Auth Redis Cache Save] Error saving token: " . $e->getMessage();
error_log($msg); echo $msg . "<br>";
}
}
return $token;
}
error_log("❌ [Nabeh Auth] Failed to extract token from login response: " . $response);
$msg = "❌ [Nabeh Auth] Failed to extract token from login response: " . $response;
error_log($msg); echo $msg . "<br>";
} else {
$msg = "❌ [Nabeh Auth] Empty response from login API cURL.";
error_log($msg); echo $msg . "<br>";
}
return null;
}
@@ -115,7 +122,8 @@ function getNabehBearerToken(): ?string {
function sendNabehOtp(string $receiver, string $otp, string $method = 'text'): bool {
$bearerToken = getNabehBearerToken();
if (!$bearerToken) {
error_log("⚠️ [Nabeh OTP] Failed to obtain dynamic JWT Bearer token.");
$msg = "⚠️ [Nabeh OTP] Failed to obtain dynamic JWT Bearer token.";
error_log($msg); echo $msg . "<br>";
return false;
}
@@ -129,9 +137,6 @@ function sendNabehOtp(string $receiver, string $otp, string $method = 'text'): b
} elseif ($method === 'image') {
$type = 'image';
}
// elseif ($method === 'flash_call') {
// $type = 'flash_call';
// }
$apiUrl = 'https://nabeh.intaleqapp.com/api/otp/send';
$payload = [
@@ -150,7 +155,11 @@ function sendNabehOtp(string $receiver, string $otp, string $method = 'text'): b
if ($decoded && ($decoded['success'] ?? false)) {
return true;
}
error_log("❌ [Nabeh OTP] API returned failure response: " . $response);
$msg = "❌ [Nabeh OTP] API returned failure response: " . $response;
error_log($msg); echo $msg . "<br>";
} else {
$msg = "❌ [Nabeh OTP] Empty response from cURL.";
error_log($msg); echo $msg . "<br>";
}
return false;
}
@@ -217,12 +226,14 @@ function curlCall(string $method, string $url, string $data, array $headers): ?s
curl_close($ch);
if ($error) {
error_log("⚠️ [OTP cURL] Error calling $url: $error");
$msg = "⚠️ [OTP cURL] Error calling $url: $error";
error_log($msg); echo $msg . "<br>";
return null;
}
if ($httpCode !== 200) {
error_log("⚠️ [OTP cURL] Non-200 HTTP code $httpCode from $url. Response: $response");
$msg = "⚠️ [OTP cURL] Non-200 HTTP code $httpCode from $url. Response: $response";
error_log($msg); echo $msg . "<br>";
}
return $response;

View File

@@ -2,6 +2,11 @@
// File: backend/auth/otp/request.php
// Unified OTP request endpoint with geographical routing (Syria, Egypt, Jordan)
// Enable error reporting for debug
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/../../core/bootstrap.php';
require_once __DIR__ . '/../../functions.php';
require_once __DIR__ . '/providers.php';

View File

@@ -206,7 +206,7 @@ CREATE TABLE `car_locations` (
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`siroUserDB1`@`%`*/ /*!50003 TRIGGER `trg_before_insert_car_locations` BEFORE INSERT ON `car_locations` FOR EACH ROW BEGIN
/*!50003 CREATE*/ /*!50003 TRIGGER `trg_before_insert_car_locations` BEFORE INSERT ON `car_locations` FOR EACH ROW BEGIN
SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326);
END */;;
DELIMITER ;
@@ -223,7 +223,7 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`siroUserDB1`@`%`*/ /*!50003 TRIGGER `trg_before_update_car_locations` BEFORE UPDATE ON `car_locations` FOR EACH ROW BEGIN
/*!50003 CREATE*/ /*!50003 TRIGGER `trg_before_update_car_locations` BEFORE UPDATE ON `car_locations` FOR EACH ROW BEGIN
IF NEW.latitude <> OLD.latitude OR NEW.longitude <> OLD.longitude THEN
SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326);
END IF;
@@ -1144,7 +1144,7 @@ CREATE TABLE `passenger_opening_locations` (
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`siroUserDB1`@`%`*/ /*!50003 TRIGGER `trg_before_insert_passenger_opening_locations` BEFORE INSERT ON `passenger_opening_locations` FOR EACH ROW BEGIN
/*!50003 CREATE*/ /*!50003 TRIGGER `trg_before_insert_passenger_opening_locations` BEFORE INSERT ON `passenger_opening_locations` FOR EACH ROW BEGIN
SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326);
END */;;
DELIMITER ;
@@ -1162,7 +1162,7 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`siroUserDB1`@`%`*/ /*!50003 TRIGGER `trg_before_update_passenger_opening_locations` BEFORE UPDATE ON `passenger_opening_locations` FOR EACH ROW BEGIN
/*!50003 CREATE*/ /*!50003 TRIGGER `trg_before_update_passenger_opening_locations` BEFORE UPDATE ON `passenger_opening_locations` FOR EACH ROW BEGIN
IF NEW.latitude <> OLD.latitude OR NEW.longitude <> OLD.longitude THEN
SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326);
END IF;

View File

@@ -438,8 +438,6 @@ class MarketingPage extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -571,6 +569,13 @@ class MarketingPage extends StatelessWidget {
return const Center(child: CircularProgressIndicator(color: _accent));
}
return ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: c.campaignsLog.length,
itemBuilder: (context, index) {
final log = c.campaignsLog[index];
final channel = log['channel']?.toString().toUpperCase() ?? 'SMS';
Color channelColor = _info;
if (channel == 'SMS') channelColor = _success;
if (channel == 'WHATSAPP') channelColor = const Color(0xFF25D366);
@@ -602,19 +607,19 @@ class MarketingPage extends StatelessWidget {
),
),
Text(
log['created_at'] ?? "",
log['created_at']?.toString() ?? "",
style: const TextStyle(color: _textSecondary, fontSize: 11),
),
],
),
const SizedBox(height: 12),
Text(
log['campaign_name'] ?? "حملة استعادة تلقائية",
log['campaign_name']?.toString() ?? "حملة استعادة تلقائية",
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: _textPrimary),
),
const SizedBox(height: 8),
Text(
log['message_body'] ?? "",
log['message_body']?.toString() ?? "",
style: const TextStyle(fontSize: 12, color: _textSecondary, height: 1.4),
),
const SizedBox(height: 12),

View File

@@ -80,16 +80,6 @@ PODS:
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- GoogleMLKit/BarcodeScanning (7.0.0):
- GoogleMLKit/MLKitCore
- MLKitBarcodeScanning (~> 6.0.0)
- GoogleMLKit/MLKitCore (7.0.0):
- MLKitCommon (~> 12.0.0)
- GoogleToolboxForMac/Defines (4.2.1)
- GoogleToolboxForMac/Logger (4.2.1):
- GoogleToolboxForMac/Defines (= 4.2.1)
- "GoogleToolboxForMac/NSData+zlib (4.2.1)":
- GoogleToolboxForMac/Defines (= 4.2.1)
- GoogleUtilities/AppDelegateSwizzler (8.1.1):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
@@ -138,26 +128,6 @@ PODS:
- maplibre_gl (0.25.0):
- Flutter
- MapLibre (= 6.19.1)
- MLImage (1.0.0-beta6)
- MLKitBarcodeScanning (6.0.0):
- MLKitCommon (~> 12.0)
- MLKitVision (~> 8.0)
- MLKitCommon (12.0.0):
- GoogleDataTransport (~> 10.0)
- GoogleToolboxForMac/Logger (< 5.0, >= 4.2.1)
- "GoogleToolboxForMac/NSData+zlib (< 5.0, >= 4.2.1)"
- GoogleUtilities/Logger (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- GTMSessionFetcher/Core (< 4.0, >= 3.3.2)
- MLKitVision (8.0.0):
- GoogleToolboxForMac/Logger (< 5.0, >= 4.2.1)
- "GoogleToolboxForMac/NSData+zlib (< 5.0, >= 4.2.1)"
- GTMSessionFetcher/Core (< 4.0, >= 3.3.2)
- MLImage (= 1.0.0-beta6)
- MLKitCommon (~> 12.0)
- mobile_scanner (6.0.2):
- Flutter
- GoogleMLKit/BarcodeScanning (~> 7.0.0)
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
@@ -221,7 +191,6 @@ DEPENDENCIES:
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
- location (from `.symlinks/plugins/location/ios`)
- maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`)
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- quick_actions_ios (from `.symlinks/plugins/quick_actions_ios/ios`)
@@ -248,16 +217,10 @@ SPEC REPOS:
- FirebaseInstallations
- FirebaseMessaging
- GoogleDataTransport
- GoogleMLKit
- GoogleToolboxForMac
- GoogleUtilities
- GTMSessionFetcher
- IOSSecuritySuite
- MapLibre
- MLImage
- MLKitBarcodeScanning
- MLKitCommon
- MLKitVision
- nanopb
- PromisesObjC
- RecaptchaInterop
@@ -311,8 +274,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/location/ios"
maplibre_gl:
:path: ".symlinks/plugins/maplibre_gl/ios"
mobile_scanner:
:path: ".symlinks/plugins/mobile_scanner/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
permission_handler_apple:
@@ -366,8 +327,6 @@ SPEC CHECKSUMS:
flutter_webrtc: ec91d94b484ad49cf191ef93413f64a40ffd3b4c
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleMLKit: eff9e23ec1d90ea4157a1ee2e32a4f610c5b3318
GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8
GoogleUtilities: 4f2618a4a1e762a1ee134a1e2323bba9843e06da
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
image_cropper: 64567491beea6cd1bc4b11948e2babb590de5826
@@ -380,11 +339,6 @@ SPEC CHECKSUMS:
location: 155caecf9da4f280ab5fe4a55f94ceccfab838f8
MapLibre: 7f24faba45439f80ccb0f83393c29fa32cb81952
maplibre_gl: a2114567cbd1065866614fbd34dfb75ab782aaa2
MLImage: 0ad1c5f50edd027672d8b26b0fee78a8b4a0fc56
MLKitBarcodeScanning: 0a3064da0a7f49ac24ceb3cb46a5bc67496facd2
MLKitCommon: 07c2c33ae5640e5380beaaa6e4b9c249a205542d
MLKitVision: 45e79d68845a2de77e2dd4d7f07947f0ed157b0e
mobile_scanner: af8f71879eaba2bbcb4d86c6a462c3c0e7f23036
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
permission_handler_apple: 92d754bbaa7361d436db2d6c3c1c2a0fdcec462e