Files
tomsjavajive/admin/auth/google/callback.php
T

110 lines
3.4 KiB
PHP

<?php
/**
* Google OAuth callback — exchange code for token, verify admin, create session
*/
require_once __DIR__ . '/../../../includes/auth.php';
function googleOAuthError(string $msg): void {
$_SESSION['admin_login_error'] = $msg;
header('Location: /admin/login.php');
exit;
}
// Verify state to prevent CSRF
if (empty($_GET['state']) || $_GET['state'] !== ($_SESSION['google_oauth_state'] ?? '')) {
googleOAuthError('Invalid OAuth state. Please try again.');
}
unset($_SESSION['google_oauth_state']);
if (!empty($_GET['error'])) {
googleOAuthError('Google sign-in was cancelled or denied.');
}
if (empty($_GET['code'])) {
googleOAuthError('No authorization code received from Google.');
}
// Exchange code for access token
$tokenResp = json_decode(file_get_contents('https://oauth2.googleapis.com/token', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query([
'code' => $_GET['code'],
'client_id' => GOOGLE_CLIENT_ID,
'client_secret' => GOOGLE_CLIENT_SECRET,
'redirect_uri' => GOOGLE_REDIRECT_URI,
'grant_type' => 'authorization_code',
]),
'timeout' => 15,
],
])), true);
if (empty($tokenResp['access_token'])) {
error_log('[Google OAuth] token exchange failed: ' . json_encode($tokenResp));
googleOAuthError('Failed to complete Google sign-in. Please try again.');
}
// Fetch Google user info
$userInfo = json_decode(file_get_contents('https://www.googleapis.com/oauth2/v3/userinfo', false, stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'Authorization: Bearer ' . $tokenResp['access_token'],
'timeout' => 10,
],
])), true);
if (empty($userInfo['email'])) {
googleOAuthError('Could not retrieve email from Google. Please try again.');
}
$googleEmail = strtolower($userInfo['email']);
// Look up admin by email
$admin = db()->fetch(
"SELECT * FROM admin_users WHERE email = :email",
['email' => $googleEmail]
);
if (!$admin) {
error_log('[Google OAuth] login attempt by non-admin: ' . $googleEmail);
googleOAuthError('No admin account found for ' . htmlspecialchars($googleEmail) . '. Contact the site administrator.');
}
// Store google_id on first Google login
if (empty($admin['google_id'])) {
try {
db()->query(
"UPDATE admin_users SET google_id = :gid, last_login = NOW() WHERE user_id = :id",
['gid' => $userInfo['sub'], 'id' => $admin['user_id']]
);
} catch (Exception $e) {
// google_id column may not exist yet — update last_login only
db()->query(
"UPDATE admin_users SET last_login = NOW() WHERE user_id = :id",
['id' => $admin['user_id']]
);
}
} else {
db()->query(
"UPDATE admin_users SET last_login = NOW() WHERE user_id = :id",
['id' => $admin['user_id']]
);
}
// Create session
$_SESSION['admin'] = [
'user_id' => $admin['user_id'],
'email' => $admin['email'],
'name' => $admin['name'],
'is_master' => (bool)$admin['is_master'],
'permissions' => json_decode($admin['permissions'] ?? '[]', true),
'auth_method' => 'google',
];
session_regenerate_id(true);
$redirect = $_SESSION['admin_redirect'] ?? '/admin/';
unset($_SESSION['admin_redirect']);
header('Location: ' . $redirect);
exit;