From 9e2964d307f3e608daa48fb53d843604fc1b2126 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Fri, 24 Jul 2026 23:38:17 +0300 Subject: [PATCH] Allow email and ID login in Admin auth login.php and bind web device fingerprint --- backend/Admin/auth/login.php | 10 ++++- dashboard/siro-admin/js/app.js | 67 ++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/backend/Admin/auth/login.php b/backend/Admin/auth/login.php index 1088d8f5..ad6c6aeb 100644 --- a/backend/Admin/auth/login.php +++ b/backend/Admin/auth/login.php @@ -54,13 +54,21 @@ try { $stmt->execute([':fp' => $fpHash]); $admin = $stmt->fetch(PDO::FETCH_ASSOC); - // إذا لم يتم العثور بالبصمة، وتم تمرير رقم الهاتف (تسجيل دخول لأول مرة أو جهاز جديد) + // إذا لم يتم العثور بالبصمة، وتم تمرير اسم المستخدم/الإيميل/الهاتف (تسجيل دخول لأول مرة أو جهاز جديد) if (!$admin && !empty($phone)) { + // 1. تجربة البحث بالهاتف المشفّر $encPhoneInput = $encryptionHelper->encryptData($phone); $stmtPhone = $con->prepare("SELECT * FROM adminUser WHERE phone = :phone LIMIT 1"); $stmtPhone->execute([':phone' => $encPhoneInput]); $admin = $stmtPhone->fetch(PDO::FETCH_ASSOC); + // 2. إذا لم يجد بالهاتف المشفّر، نجرب بالبريد الإلكتروني أو المعرّف (id / email) أو رقم الهاتف غير المشفّر + if (!$admin) { + $stmtAlt = $con->prepare("SELECT * FROM adminUser WHERE email = :input OR id = :input OR phone = :input LIMIT 1"); + $stmtAlt->execute([':input' => $phone]); + $admin = $stmtAlt->fetch(PDO::FETCH_ASSOC); + } + // تأكيد كلمة المرور وتحديث بصمة الجهاز إذا تم إيجاد الحساب if ($admin && password_verify($password, $admin['password'])) { $encFpRaw = $encryptionHelper->encryptData($fingerprint); diff --git a/dashboard/siro-admin/js/app.js b/dashboard/siro-admin/js/app.js index bb311db1..c24fa515 100644 --- a/dashboard/siro-admin/js/app.js +++ b/dashboard/siro-admin/js/app.js @@ -125,22 +125,49 @@ document.addEventListener('DOMContentLoaded', () => { }); } - const res = await response.json(); - - if (response.ok && (res.status === 'success' || res.jwt || res.data?.jwt)) { - const jwtToken = res.jwt || res.data?.jwt; - const adminInfo = res.admin || res.data?.admin || {}; - currentUser = { - name: adminInfo.name || 'Admin', - email: adminInfo.email || phone, - role: adminInfo.role || 'Administrator', - jwt: jwtToken, - isLive: true - }; - localStorage.setItem('siro_admin_user', JSON.stringify(currentUser)); - authWrapper.classList.add('hidden'); - showNotification('Access Granted! Welcome to Admin Portal.', 'success'); - fetchLiveDashboardData(); + const resText = await response.text(); + console.log('Server Raw Response:', resText); + + let res; + try { + res = JSON.parse(resText); + } catch (jsonErr) { + showNotification(`Server Error (${response.status}): ${resText.substring(0, 100)}`, 'danger'); + return; + } + + console.log('Parsed API Response:', res); + + // Check if login succeeded and JWT was returned + const jwtToken = res.jwt || res.data?.jwt || (typeof res.message === 'object' ? res.message?.jwt : null); + const adminInfo = res.admin || res.data?.admin || (typeof res.message === 'object' ? res.message?.admin : {}) || {}; + + if (response.ok && (res.status === 'success' || jwtToken)) { + if (jwtToken) { + currentUser = { + name: adminInfo.name || 'Admin', + email: adminInfo.email || phone, + role: adminInfo.role || 'Administrator', + jwt: jwtToken, + isLive: true + }; + localStorage.setItem('siro_admin_user', JSON.stringify(currentUser)); + authWrapper.classList.add('hidden'); + showNotification('Access Granted! Welcome to Admin Portal.', 'success'); + fetchLiveDashboardData(); + } else if (res.status === 'otp_required' || (res.message && (res.message.status === 'otp_required' || res.message === 'otp_required'))) { + pendingOtpPhone = phone; + pendingOtpPassword = password; + const masked = res.phone || (typeof res.message === 'object' ? res.message.phone : null) || phone; + document.getElementById('otpPhoneText').textContent = `Verification code sent to WhatsApp (${masked})`; + document.getElementById('otpModal').classList.add('active'); + } else { + showNotification('Login successful, loading dashboard...', 'success'); + currentUser = { name: adminInfo.name || 'Admin', email: phone, role: 'Administrator', isLive: true }; + localStorage.setItem('siro_admin_user', JSON.stringify(currentUser)); + authWrapper.classList.add('hidden'); + fetchLiveDashboardData(); + } } else if (res.status === 'otp_required' || (res.message && (res.message.status === 'otp_required' || res.message === 'otp_required'))) { pendingOtpPhone = phone; pendingOtpPassword = password; @@ -148,13 +175,13 @@ document.addEventListener('DOMContentLoaded', () => { document.getElementById('otpPhoneText').textContent = `Verification code sent to WhatsApp (${masked})`; document.getElementById('otpModal').classList.add('active'); } else { - // Show REAL backend API error message and DO NOT redirect to demo mode - const errorMsg = res.message || res.error || 'Invalid username or password.'; + // Show REAL backend API error message + const errorMsg = (typeof res.message === 'string' ? res.message : null) || res.error || 'Invalid credentials or user not found.'; showNotification(`Login Error: ${errorMsg}`, 'danger'); } } catch (err) { - console.error(err); - showNotification('Connection Error: Could not reach authentication server.', 'danger'); + console.error('Login Exception:', err); + showNotification(`Network Error: ${err.message || 'Could not connect to backend'}`, 'danger'); } } else { currentUser = { name: 'Super Admin (Demo)', email: phone, role: 'Administrator', isLive: false };