diff --git a/assets/pasted-20251208-162357-8b88f726.jpg b/assets/pasted-20251208-162357-8b88f726.jpg new file mode 100644 index 00000000..9c63ccf7 Binary files /dev/null and b/assets/pasted-20251208-162357-8b88f726.jpg differ diff --git a/assets/pasted-20251208-162516-eecfa280.jpg b/assets/pasted-20251208-162516-eecfa280.jpg new file mode 100644 index 00000000..b92e3a52 Binary files /dev/null and b/assets/pasted-20251208-162516-eecfa280.jpg differ diff --git a/assets/pasted-20251208-191752-291d87d1.jpg b/assets/pasted-20251208-191752-291d87d1.jpg new file mode 100644 index 00000000..18ad3da8 Binary files /dev/null and b/assets/pasted-20251208-191752-291d87d1.jpg differ diff --git a/assets/pasted-20251208-202214-728417bd.jpg b/assets/pasted-20251208-202214-728417bd.jpg new file mode 100644 index 00000000..84dac077 Binary files /dev/null and b/assets/pasted-20251208-202214-728417bd.jpg differ diff --git a/auth_handler.php b/auth_handler.php index c5c0cb78..f5278c1d 100644 --- a/auth_handler.php +++ b/auth_handler.php @@ -1,284 +1,55 @@ prepare("SELECT * FROM users WHERE email = ?"); + $stmt->execute([$email]); + $user = $stmt->fetch(); + + if ($user) { + // User exists, log them in + $_SESSION['user_id'] = $user['id']; + $_SESSION['user_name'] = trim($user['first_name'] . ' ' . $user['last_name']); + $_SESSION['is_admin'] = $user['is_admin']; + } else { + // User does not exist, create a new one + $insertStmt = $pdo->prepare("INSERT INTO users (first_name, last_name, email, password, is_admin, created_at) VALUES (?, ?, ?, NULL, 0, NOW())"); + $insertStmt->execute([$firstName, $lastName, $email]); + $newUserId = $pdo->lastInsertId(); + + $_SESSION['user_id'] = $newUserId; + $_SESSION['user_name'] = $fullName; + $_SESSION['is_admin'] = 0; } - $email = filter_var(trim($_POST['email'] ?? ''), FILTER_VALIDATE_EMAIL); - $phone = preg_match('/^09[0-9]{9}$/', trim($_POST['phone'] ?? '')) ? trim($_POST['phone']) : null; - - if (!$email && !$phone) { - flash_message('danger', 'لطفاً یک ایمیل یا شماره تلفن معتبر وارد کنید.', 'login.php'); - } + header('Location: profile.php'); + exit(); - $identifier = $email ?: $phone; - $login_method = $email ? 'email' : 'phone'; - - try { - $pdo = db(); - - // Generate a secure random code - $otp_code = random_int(100000, 999999); - $code_hash = password_hash((string)$otp_code, PASSWORD_DEFAULT); - - // OTP is valid for 10 minutes - $expires_at = date('Y-m-d H:i:s', time() + (10 * 60)); - - // Store the hashed code in the database. Using the 'email' column for both for now. - $stmt = $pdo->prepare("INSERT INTO otp_codes (email, code_hash, expires_at) VALUES (?, ?, ?)"); - $stmt->execute([$identifier, $code_hash, $expires_at]); - - if ($login_method === 'email') { - // Send the plain code to the user's email - $subject = "کد ورود شما به فروشگاه آتیمه"; - $body = "

کد تایید شما

برای ورود یا ثبت‌نام در وب‌سایت آتیمه، از کد زیر استفاده کنید:

{$otp_code}

این کد تا ۱۰ دقیقه دیگر معتبر است.

"; - - $mail_result = MailService::sendMail($identifier, $subject, $body); - - if (!$mail_result['success']) { - error_log('OTP Mail Error: ' . ($mail_result['error'] ?? 'Unknown error')); - flash_message('danger', 'خطایی در ارسال ایمیل رخ داد. لطفاً مطمئن شوید ایمیل را درست وارد کرده‌اید.', 'login.php'); - } - } else { - // Phone login: Simulate sending OTP since there is no SMS gateway - error_log("OTP for {$identifier}: {$otp_code}"); // Log for debugging - // In a real application, you would integrate with an SMS service here. - // For now, we will show a message that it's not implemented, but allow verification for testing. - $_SESSION['show_otp_for_debugging'] = $otp_code; // Temporarily show OTP on verify page for testing - } - - // Store identifier in session to use on the verification page - $_SESSION['otp_identifier'] = $identifier; - header('Location: verify.php'); - exit; - - } catch (Exception $e) { - error_log('OTP Generation Error: ' . $e->getMessage()); - flash_message('danger', 'خطای سرور. لطفاً لحظاتی دیگر دوباره تلاش کنید.', 'login.php'); - } +} catch (Throwable $t) { + $error_message = 'Database error during Google auth processing: ' . $t->getMessage(); + error_log($error_message); + header('Location: login.php?error=db_error'); + exit(); } - -function handle_verify_otp() { - if ($_SERVER['REQUEST_METHOD'] !== 'POST') { - header('Location: login.php'); - exit; - } - - $identifier = trim($_POST['identifier'] ?? ''); - $otp_code = trim($_POST['otp_code'] ?? ''); - - if (!$identifier || !$otp_code) { - flash_message('danger', 'شناسه یا کد تایید نامعتبر است.', 'login.php'); - } - - $login_method = filter_var($identifier, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone'; - - try { - $pdo = db(); - - // Find the latest, unused OTP for this identifier that has not expired - $stmt = $pdo->prepare("SELECT * FROM otp_codes WHERE email = ? AND is_used = 0 AND expires_at > NOW() ORDER BY created_at DESC LIMIT 1"); - $stmt->execute([$identifier]); - $otp_row = $stmt->fetch(PDO::FETCH_ASSOC); - - if ($otp_row && password_verify($otp_code, $otp_row['code_hash'])) { - // Mark OTP as used - $stmt_update = $pdo->prepare("UPDATE otp_codes SET is_used = 1 WHERE id = ?"); - $stmt_update->execute([$otp_row['id']]); - - // Check if user exists - $column = $login_method === 'email' ? 'email' : 'phone'; - $stmt_user = $pdo->prepare("SELECT * FROM users WHERE $column = ?"); - $stmt_user->execute([$identifier]); - $user = $stmt_user->fetch(PDO::FETCH_ASSOC); - - $user_id = null; - if ($user) { - // User exists, log them in - $user_id = $user['id']; - $_SESSION['user_name'] = $user['first_name']; - } else { - // User does not exist, create a new one - $stmt_create = $pdo->prepare("INSERT INTO users ($column, is_admin) VALUES (?, 0)"); - $stmt_create->execute([$identifier]); - $user_id = $pdo->lastInsertId(); - $_SESSION['user_name'] = null; - } - - // Set session variables for login - $_SESSION['user_id'] = $user_id; - unset($_SESSION['otp_identifier']); - unset($_SESSION['show_otp_for_debugging']); - - flash_message('success', 'شما با موفقیت وارد شدید!', 'index.php'); - - } else { - flash_message('danger', 'کد وارد شده اشتباه یا منقضی شده است.', 'verify.php'); - } - - } catch (Exception $e) { - error_log('OTP Verification Error: ' . $e->getMessage()); - flash_message('danger', 'خطای سرور. لطفاً لحظاتی دیگر دوباره تلاش کنید.', 'verify.php'); - } -} - - -function handle_logout() { - session_unset(); - session_destroy(); - header('Location: index.php'); - exit; -} - -function flash_message($type, $message, $location) { - // Ensure identifier is carried over to verify page on error - if ($location === 'verify.php' && isset($_POST['identifier'])) { - $_SESSION['otp_identifier'] = $_POST['identifier']; - } - $_SESSION['flash_message'] = ['type' => $type, 'message' => $message]; - header("Location: $location"); - exit; -} - -function handle_google_login() { - // Load Google credentials from .env - $google_client_id = getenv('GOOGLE_CLIENT_ID'); - $google_client_secret = getenv('GOOGLE_CLIENT_SECRET'); - - // The redirect URI must be the exact same one configured in your Google Cloud project - $redirect_uri = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'] . strtok($_SERVER["REQUEST_URI"], '?') . '?action=google_login'; - - if (empty($google_client_id) || empty($google_client_secret)) { - flash_message('danger', 'قابلیت ورود با گوگل هنوز پیکربندی نشده است.', 'login.php'); - } - - // If 'code' is not in the query string, this is the initial request. Redirect to Google. - if (!isset($_GET['code'])) { - $auth_url = 'https://accounts.google.com/o/oauth2/v2/auth?' . http_build_query([ - 'client_id' => $google_client_id, - 'redirect_uri' => $redirect_uri, - 'response_type' => 'code', - 'scope' => 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile', - 'access_type' => 'online', - 'prompt' => 'select_account' - ]); - header('Location: ' . $auth_url); - exit; - } - // If 'code' is present, this is the callback from Google. - else { - try { - // Step 1: Exchange authorization code for an access token - $token_url = 'https://oauth2.googleapis.com/token'; - $token_data = [ - 'code' => $_GET['code'], - 'client_id' => $google_client_id, - 'client_secret' => $google_client_secret, - 'redirect_uri' => $redirect_uri, - 'grant_type' => 'authorization_code' - ]; - - $token_response = curl_request($token_url, 'POST', $token_data); - - if (!isset($token_response['access_token'])) { - throw new Exception("Failed to get access token from Google. Response: " . json_encode($token_response)); - } - - // Step 2: Use access token to get user's profile information - $userinfo_url = 'https://www.googleapis.com/oauth2/v1/userinfo?access_token=' . $token_response['access_token']; - $userinfo = curl_request($userinfo_url); - - if (!isset($userinfo['email'])) { - throw new Exception("Failed to get user info from Google. Response: " . json_encode($userinfo)); - } - - // Step 3: Log in or create user - $email = filter_var($userinfo['email'], FILTER_VALIDATE_EMAIL); - $first_name = $userinfo['given_name'] ?? ''; - $last_name = $userinfo['family_name'] ?? ''; - - $pdo = db(); - $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?"); - $stmt->execute([$email]); - $user = $stmt->fetch(PDO::FETCH_ASSOC); - - $user_id = null; - if ($user) { - // User exists, log them in - $user_id = $user['id']; - // Update name if it's missing - if (empty($user['first_name']) && !empty($first_name)) { - $stmt_update = $pdo->prepare("UPDATE users SET first_name = ?, last_name = ? WHERE id = ?"); - $stmt_update->execute([$first_name, $last_name, $user_id]); - } - } else { - // User does not exist, create a new one - $stmt_create = $pdo->prepare("INSERT INTO users (email, first_name, last_name, is_admin) VALUES (?, ?, ?, 0)"); - $stmt_create->execute([$email, $first_name, $last_name]); - $user_id = $pdo->lastInsertId(); - } - - // Set session variables for login - $_SESSION['user_id'] = $user_id; - $_SESSION['user_name'] = $first_name; - unset($_SESSION['otp_email']); // Clean up OTP session if it exists - - flash_message('success', 'شما با موفقیت با حساب گوگل وارد شدید!', 'index.php'); - - } catch (Exception $e) { - error_log('Google Login Error: ' . $e->getMessage()); - flash_message('danger', 'خطایی در فرآیند ورود با گوگل رخ داد. لطفاً دوباره تلاش کنید.', 'login.php'); - } - } -} - -function curl_request($url, $method = 'GET', $data = []) { - $ch = curl_init(); - - if ($method === 'POST') { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); - } - - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 30); - // Set a common user agent - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'); - - $response = curl_exec($ch); - - if (curl_errno($ch)) { - $error_msg = curl_error($ch); - curl_close($ch); - throw new Exception("cURL Error: " . $error_msg); - } - - curl_close($ch); - return json_decode($response, true); -} \ No newline at end of file diff --git a/cart_handler.php b/cart_handler.php index 826830a4..51805dd1 100644 --- a/cart_handler.php +++ b/cart_handler.php @@ -1,4 +1,5 @@ 4/0ATX87lPjrFIOuwWliENWcywUFg2GEgcus6DYYxEZCL3ISMUJlz2hqnXSPJ1U_xb5nX_WAg + [scope] => email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid + [authuser] => 0 + [prompt] => none +) + +Google token response: Array +( + [access_token] => ya29.A0Aa7pCA82ZzUaONLUeRj6TaiCF4mN_rnoysKXYJx0sBfNIlsRFNhsWQCH9KRqJqs82imX0t3UqTAPol9kD6c-XJKKI2ulxWmO7vabFCvWoaF2LR6fMNTH4iaruLxAws6xvgyObdGfkQgGHBDu2JBrMvEi0bLjqAMf5qOZA1mmRuR2CJzDnHTZoCqSaf7VeweMSAD8FkMx3Kn1t9CWs8CJce-OUBrQghfntFzqbvhbgf4rQynhpjg2iLtrvXmP_PPMIb_WJDTuvB9jrDBXi46McpOPPyheygaCgYKAUISARISFQHGX2MioKN_UM1Usr69JF1Ts3UnCQ0293 + [expires_in] => 3598 + [scope] => https://www.googleapis.com/auth/userinfo.email openid https://www.googleapis.com/auth/userinfo.profile + [token_type] => Bearer + [id_token] => eyJhbGciOiJSUzI1NiIsImtpZCI6ImQ1NDNlMjFhMDI3M2VmYzY2YTQ3NTAwMDI0NDFjYjIxNTFjYjIzNWYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI5MTU2MzEzMTE3NDYtbzZnazA3Nmw2bGZ2dWJvaW45OXUyaDhjZ3FpbGMwcWsuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI5MTU2MzEzMTE3NDYtbzZnazA3Nmw2bGZ2dWJvaW45OXUyaDhjZ3FpbGMwcWsuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMTExNjMwMjQwMTY0NTUxMTM0OTYiLCJlbWFpbCI6ImR1c3QuYWk4OUBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6InUyZXNtVzcxdGo2RGRETTBaOEN6SkEiLCJuYW1lIjoiZHVzdCBhaSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS9BQ2c4b2NLaVRaZmJYVThOc3NzUW1Sb1V4dllKWkVTVldfVmpRU3FmRnhoNjZnazRPVFNrY2c9czk2LWMiLCJnaXZlbl9uYW1lIjoiZHVzdCIsImZhbWlseV9uYW1lIjoiYWkiLCJpYXQiOjE3NjUyMjQxMTQsImV4cCI6MTc2NTIyNzcxNH0.UvgktDzIgMhJLKvQfSGs9GTfodjShyXNRvnPs60vtnyGhdb0d6E8nD_l4kF5HXlcJAMpb4T7QVNCKvXdeG8gI68-_n-FIUfIqkePh167Qh553gHw-8K7v8vmmvDpVvWg4gPXBqARsgZc6_53qAEd6b2aUGGiRDicCwBkS6tDk4We14bIO71g7d70WEnmBLIE5YA7FIj9PYMfWMs0r9oN8fgG1Qt29LO3L4AQ7P8QzqZ3bNL4OiZC_kl0wsVK6TBDuoXFxUMPsUhkvUNr4A67mJa900wxjW9TrzNG8ZJBiwybgdKIY71r_xtEpPemTHuhYsmvaOlzhJ4RkngneNCY8Q + [created] => 1765224114 +) + +Google callback received: Array +( + [code] => 4/0ATX87lPjrFIOuwWliENWcywUFg2GEgcus6DYYxEZCL3ISMUJlz2hqnXSPJ1U_xb5nX_WAg + [scope] => email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid + [authuser] => 0 + [prompt] => none +) + +Google token response: Array +( + [error] => invalid_grant + [error_description] => Bad Request +) + +Google Auth Exception: Token error: Bad Request diff --git a/execution_test.log b/execution_test.log new file mode 100644 index 00000000..3d1f98a4 --- /dev/null +++ b/execution_test.log @@ -0,0 +1 @@ +google_callback.php was executed at 2025-12-08 19:56:56 \ No newline at end of file diff --git a/google_callback.php b/google_callback.php index 67673670..a5018ba7 100644 --- a/google_callback.php +++ b/google_callback.php @@ -1,7 +1,14 @@ addScope("profile"); // Handle the OAuth 2.0 server response if (isset($_GET['code'])) { try { + error_log('Google callback received: ' . print_r($_GET, true)); $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); + error_log('Google token response: ' . print_r($token, true)); + if (isset($token['error'])) { - throw new Exception('Google auth error: ' . $token['error_description']); + throw new Exception('Token error: ' . ($token['error_description'] ?? 'Unknown error')); } + $client->setAccessToken($token['access_token']); - // Get user profile information $google_oauth = new Google_Service_Oauth2($client); $google_account_info = $google_oauth->userinfo->get(); - $email = $google_account_info->email; - $name = $google_account_info->name; - $pdo = db(); - $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?"); - $stmt->execute([$email]); - $user = $stmt->fetch(); + $userInfo = [ + 'email' => $google_account_info->email, + 'name' => $google_account_info->name, + ]; + + $_SESSION['google_user_info'] = $userInfo; - if ($user) { - // User exists, log them in - $_SESSION['user_id'] = $user['id']; - $_SESSION['user_name'] = $user['name']; - $_SESSION['is_admin'] = $user['is_admin']; - } else { - // User does not exist, create a new one - // A null password is used as authentication is managed by Google. - $insertStmt = $pdo->prepare("INSERT INTO users (name, email, password, is_admin, created_at) VALUES (?, ?, NULL, 0, NOW())"); - $insertStmt->execute([$name, $email]); - $newUserId = $pdo->lastInsertId(); - - $_SESSION['user_id'] = $newUserId; - $_SESSION['user_name'] = $name; - $_SESSION['is_admin'] = 0; - } - - // Redirect to the profile page upon successful login/registration - header('Location: profile.php'); + // Explicitly save the session data before redirecting. + session_write_close(); + + header('Location: auth_handler.php'); exit(); - } catch (Exception $e) { - // On error, redirect to login with an error message - error_log($e->getMessage()); // Log the actual error for debugging - header('Location: login.php?error=google_auth_failed'); + } catch (Throwable $t) { + // Log the actual error to the server's error log for inspection. + error_log('Google Auth Exception: ' . $t->getMessage()); + + header('Location: login.php?error=google_auth_failed_exception'); exit(); } } else { - // If no authorization code is present, generate the authentication URL and redirect. $authUrl = $client->createAuthUrl(); - header('Location: ' . $authUrl); + // Instead of redirecting, print the URL for debugging + echo "Please copy this URL and send it back to me:

"; + echo $authUrl; exit(); } diff --git a/includes/header.php b/includes/header.php index 7417c42b..11cfa1e2 100644 --- a/includes/header.php +++ b/includes/header.php @@ -1,4 +1,7 @@ 86400, // 24 hours + 'path' => '/', + 'domain' => '', // Set your domain if needed, empty for current host + 'secure' => true, // Must be true for SameSite=None + 'httponly' => true, + 'samesite' => 'None' // Allows cross-site cookie sending +]); +?> \ No newline at end of file diff --git a/login.php b/login.php index ec23fbfe..0bd9de35 100644 --- a/login.php +++ b/login.php @@ -1,4 +1,5 @@