setClientId($clientID); $client->setClientSecret($clientSecret); $client->setRedirectUri($redirectUri); // OAuth scopes $client->addScope('openid'); $client->addScope('email'); $client->addScope('profile'); // Ζητάμε offline access όπου χρειάζεται $client->setAccessType('online'); // Για να παίρνουμε πάντα consent όταν χρειάζεται $client->setPrompt('select_account'); // ============================================================ // GOOGLE CALLBACK // ============================================================ if (isset($_GET['code'])) { // -------------------------------------------------------- // Έλεγχος OAuth state // -------------------------------------------------------- if ( !isset($_GET['state']) || !isset($_SESSION['google_oauth_state']) || !hash_equals($_SESSION['google_oauth_state'], $_GET['state']) ) { die('Μη έγκυρο OAuth state.'); } unset($_SESSION['google_oauth_state']); // -------------------------------------------------------- // Ανταλλαγή authorization code με access token // -------------------------------------------------------- try { $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); } catch (Exception $e) { die( 'Σφάλμα κατά τη σύνδεση με Google: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') ); } if (isset($token['error'])) { $errorDescription = $token['error_description'] ?? $token['error']; die( 'Google OAuth Error: ' . htmlspecialchars($errorDescription, ENT_QUOTES, 'UTF-8') ); } if (!isset($token['access_token'])) { die('Δεν ελήφθη access token από τη Google.'); } $client->setAccessToken($token['access_token']); // -------------------------------------------------------- // Λήψη στοιχείων χρήστη από Google // -------------------------------------------------------- try { $google_oauth = new Google_Service_Oauth2($client); $google_account_info = $google_oauth->userinfo->get(); } catch (Exception $e) { die( 'Αδυναμία λήψης στοιχείων από Google: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') ); } // -------------------------------------------------------- // User information // -------------------------------------------------------- $email = trim((string) $google_account_info->email); $first_name = trim((string) ($google_account_info->givenName ?? '')); $last_name = trim((string) ($google_account_info->familyName ?? '')); if ($email === '') { die('Η Google δεν επέστρεψε email για τον χρήστη.'); } // ======================================================== // SEARCH USER IN DATABASE // ======================================================== try { $stmt = $pdo->prepare( "SELECT * FROM users WHERE username = ? OR email = ? LIMIT 1" ); $stmt->execute([$email, $email]); $user = $stmt->fetch(PDO::FETCH_ASSOC); } catch (PDOException $e) { die( 'Σφάλμα βάσης δεδομένων: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') ); } // ======================================================== // EXISTING USER // ======================================================== if ($user) { // Προαιρετικά ενημερώνουμε όνομα/επώνυμο // αν υπάρχουν διαθέσιμα από Google. if (empty($user['first_name']) && $first_name !== '') { $update = $pdo->prepare( "UPDATE users SET first_name = ? WHERE id = ?" ); $update->execute([$first_name, $user['id']]); $user['first_name'] = $first_name; } if (empty($user['last_name']) && $last_name !== '') { $update = $pdo->prepare( "UPDATE users SET last_name = ? WHERE id = ?" ); $update->execute([$last_name, $user['id']]); $user['last_name'] = $last_name; } // ---------------------------------------------------- // Login // ---------------------------------------------------- session_regenerate_id(true); $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $_SESSION['role_id'] = $user['role_id']; $_SESSION['first_name'] = $user['first_name'] ?? ''; $_SESSION['is_seller'] = $user['is_seller'] ?? 0; } // ======================================================== // NEW USER // ======================================================== else { // Τυχαίος password επειδή ο χρήστης θα κάνει login μέσω Google. $random_password = password_hash( bin2hex(random_bytes(32)), PASSWORD_DEFAULT ); // 3 = Απλός χρήστης / Πελάτης // 2 = Seller // 1 = Admin $role_id = 3; try { $insert = $pdo->prepare( "INSERT INTO users ( username, email, password, first_name, last_name, role_id ) VALUES (?, ?, ?, ?, ?, ?)" ); $insert->execute([ $email, $email, $random_password, $first_name, $last_name, $role_id ]); $new_user_id = $pdo->lastInsertId(); } catch (PDOException $e) { die( 'Σφάλμα κατά την αυτόματη εγγραφή του χρήστη: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') ); } // ---------------------------------------------------- // Login νέου χρήστη // ---------------------------------------------------- session_regenerate_id(true); $_SESSION['user_id'] = $new_user_id; $_SESSION['username'] = $email; $_SESSION['role_id'] = $role_id; $_SESSION['first_name'] = $first_name; $_SESSION['is_seller'] = 0; } // ======================================================== // SUCCESS // ======================================================== header('Location: index.php'); exit; } // ============================================================ // INITIAL REQUEST - REDIRECT TO GOOGLE // ============================================================ else { // Δημιουργία τυχαίου state για προστασία από CSRF $state = bin2hex(random_bytes(32)); $_SESSION['google_oauth_state'] = $state; $client->setState($state); // Δημιουργία Google authorization URL $authUrl = $client->createAuthUrl(); header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL)); exit; }