Files
Siro/walletintaleq.intaleq.xyz/v2/main/functions.php
2026-06-16 02:52:06 +03:00

284 lines
11 KiB
PHP
Executable File

<?php
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
define("MB", 1048576);
// ═══════════════════════════════════════════════════════════════
// authenticateJWT — دالة التحقق من التوكن
// ───────────────────────────────────────────────────────────────
// استبدل الدالة الموجودة في functions.php بهذه
// ───────────────────────────────────────────────────────────────
// طبقات التحقق بالترتيب:
// 1. وجود الـ JWT في Authorization header
// 2. صحة التوقيع وعدم انتهاء الصلاحية
// 3. صحة الـ Issuer
// 4. مطابقة بصمة الجهاز (X-Device-FP header)
// 5. مطابقة الـ HMAC — للـ wallet فقط (X-HMAC-Auth header)
// ───────────────────────────────────────────────────────────────
// جميع العمليات في الذاكرة — لا استعلامات DB
// ═══════════════════════════════════════════════════════════════
function authenticateJWT(bool $isReg = false): object
{
$keyPath = getenv('WALLET_SECRET_KEY_PATH');
$secretKey = '';
if ($keyPath && file_exists($keyPath)) {
$secretKey = trim(file_get_contents($keyPath));
}
if (!$secretKey) {
$secretKey = getenv('SECRET_KEY') ?: '';
}
$hmacSecret = getenv('SECRET_KEY_HMAC');
$fpPepper = getenv('FP_PEPPER');
error_log('[JWT_DEBUG] ── START authenticateJWT ──────────────────────────');
error_log('[JWT_DEBUG] isReg=' . ($isReg ? 'true' : 'false'));
error_log('[JWT_DEBUG] secretKey loaded: ' . (!empty($secretKey) ? 'YES (len=' . strlen($secretKey) . ')' : 'NO ❌'));
error_log('[JWT_DEBUG] hmacSecret loaded: ' . (!empty($hmacSecret) ? 'YES' : 'NO ❌'));
error_log('[JWT_DEBUG] fpPepper loaded: ' . (!empty($fpPepper) ? 'YES' : 'NO'));
if (!$secretKey || !$hmacSecret) {
http_response_code(500);
echo json_encode(['error' => 'Internal server configuration error.']);
exit;
}
// ── 1. استخراج الـ JWT ──────────────────────────────────────
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$token = null;
if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
$token = $matches[1];
}
error_log('[JWT_DEBUG] Authorization header present: ' . (!empty($authHeader) ? 'YES' : 'NO ❌'));
error_log('[JWT_DEBUG] Token extracted: ' . ($token ? 'YES (len=' . strlen($token) . ')' : 'NO ❌'));
if (!$token) {
http_response_code(401);
echo json_encode(['error' => 'Authorization token required']);
exit;
}
// ── 2. فك التشفير والتحقق ───────────────────────────────────
try {
$decoded = JWT::decode($token, new Key($secretKey, 'HS256'));
error_log('[JWT_DEBUG] JWT decode: SUCCESS ✅');
error_log('[JWT_DEBUG] JWT payload: ' . json_encode((array)$decoded));
} catch (ExpiredException $e) {
error_log('[JWT_DEBUG] JWT decode FAILED: ExpiredException ❌ | ' . $e->getMessage());
http_response_code(401);
echo json_encode(['error' => 'Token expired']);
exit;
} catch (SignatureInvalidException $e) {
error_log('[JWT_DEBUG] JWT decode FAILED: SignatureInvalidException ❌ | ' . $e->getMessage());
http_response_code(401);
echo json_encode(['error' => 'Invalid token signature']);
exit;
} catch (BeforeValidException $e) {
error_log('[JWT_DEBUG] JWT decode FAILED: BeforeValidException ❌ | ' . $e->getMessage());
http_response_code(401);
echo json_encode(['error' => 'Token not yet valid']);
exit;
} catch (Exception $e) {
error_log('[JWT_DEBUG] JWT decode FAILED: Exception ❌ | ' . $e->getMessage());
http_response_code(401);
echo json_encode(['error' => 'Invalid token']);
exit;
}
// ── 3. التحقق من الـ Issuer ─────────────────────────────────
$expectedIssuer = 'Tripz-Wallet';
$actualIssuer = $decoded->iss ?? '(missing)';
error_log('[JWT_DEBUG] Issuer check | expected=' . $expectedIssuer . ' | actual=' . $actualIssuer);
if ($actualIssuer !== $expectedIssuer) {
error_log('[JWT_DEBUG] Issuer MISMATCH ❌');
http_response_code(401);
echo json_encode(['error' => 'Invalid token issuer']);
exit;
}
error_log('[JWT_DEBUG] Issuer: OK ✅');
// ── user_id ─────────────────────────────────────────────────
$userId = $decoded->user_id ?? $decoded->sub ?? null;
error_log('[JWT_DEBUG] user_id extracted: ' . ($userId ?? '(null) ❌'));
if (!$userId) {
http_response_code(401);
echo json_encode(['error' => 'Invalid JWT payload']);
exit;
}
// ── 4. بصمة الجهاز ──────────────────────────────────────────
if (!$isReg && $fpPepper) {
$fpInToken = $decoded->fingerPrint ?? null;
$fpHeader = $_SERVER['HTTP_X_DEVICE_FP'] ?? null;
error_log('[JWT_DEBUG] FP check | fpInToken=' . ($fpInToken ?? '(null)'));
error_log('[JWT_DEBUG] FP check | X-Device-FP header=' . ($fpHeader ?? '(null)'));
if ($fpInToken !== null && $fpHeader !== null) {
$expectedFp = hash('sha256', $fpHeader . $fpPepper);
$fpMatch = hash_equals($expectedFp, $fpInToken);
error_log('[JWT_DEBUG] FP check | expectedFp=' . $expectedFp);
error_log('[JWT_DEBUG] FP check | match=' . ($fpMatch ? 'YES ✅' : 'NO ❌'));
if (!$fpMatch) {
error_log(sprintf(
'⚠️ [SECURITY] Device mismatch | user=%s | IP=%s',
$userId,
$_SERVER['REMOTE_ADDR'] ?? 'unknown'
));
http_response_code(403);
echo json_encode(['error' => 'Device mismatch']);
exit;
}
} else {
error_log('[JWT_DEBUG] FP check SKIPPED (token or header is null) ⚠️');
}
} else {
error_log('[JWT_DEBUG] FP check SKIPPED | isReg=' . ($isReg ? 'true' : 'false') . ' | fpPepper=' . (!empty($fpPepper) ? 'set' : 'empty'));
}
// ── 5. HMAC ─────────────────────────────────────────────────
$hmacHeader = $_SERVER['HTTP_X_HMAC_AUTH'] ?? null;
error_log('[JWT_DEBUG] HMAC header present: ' . ($hmacHeader !== null ? 'YES' : 'NO (skip)'));
if ($hmacHeader !== null) {
$expectedHmac = hash_hmac('sha256', $userId, $hmacSecret);
$hmacMatch = hash_equals($expectedHmac, $hmacHeader);
error_log('[JWT_DEBUG] HMAC check | match=' . ($hmacMatch ? 'YES ✅' : 'NO ❌'));
if (!$hmacMatch) {
error_log(sprintf(
'⚠️ [SECURITY] HMAC mismatch | user=%s | IP=%s',
$userId,
$_SERVER['REMOTE_ADDR'] ?? 'unknown'
));
http_response_code(403);
echo json_encode(['error' => 'Invalid HMAC']);
exit;
}
}
error_log('[JWT_DEBUG] ── ALL CHECKS PASSED ✅ ─────────────────────────');
return $decoded;
}
function filterRequest($requestname, $type = 'string') {
if (isset($_POST[$requestname]) && !empty($_POST[$requestname])) {
$value = trim($_POST[$requestname]);
// Remove any control characters
$value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $value);
// Remove any HTML or XML tags
$value = strip_tags($value);
// Escape any special characters
$value = htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
if ($type === 'numeric') {
if (filter_var($value, FILTER_VALIDATE_FLOAT) !== false) {
return $value;
}
} else {
return $value;
}
}
return null;
}
function sendWhatsAppFromServer($to, $message)
{
// 1) قائمة السيرفرات المتاحة
$servers = [
"https://botmasa.intaleq.xyz/send",//rama tah
"https://botmasa2.intaleq.xyz/send",//shad
// "https://bootride.intaleq.xyz/send",//shahd bus
//"https://bot3.intaleq.xyz/send",//shahd
//"https://whatsapp.tripz-egypt.com/send"//tripz
];
// 2) اختيار عشوائي
$url = $servers[array_rand($servers)];
// 3) إعداد البيانات
$payload = [
"to" => $to,
"message" => $message
];
// 4) تنفيذ الطلب
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
// 5) تسجيل النتيجة
if ($err) {
error_log("[sendWhatsAppFromServer] cURL Error on $url: $err");
return false;
}
return json_decode($response, true);
}
//////////
function printFailure($message = "none")
{
echo json_encode(array("status" => "failure", "message" => $message));
}
function printSuccess($message = "none")
{
echo json_encode(array("status" => "success", "message" => $message));
}
function result($count)
{
if ($count > 0) {
printSuccess();
} else {
printFailure();
}
}
function sendEmail($from,$to, $title, $body)
{
$header = "From: $from" . "\n" . "CC: $from";
mail($to, $title, $body, $header);
}