web-mooc/app/Http/Controllers/Auth/GoogleAuthController.php

161 lines
6.2 KiB
PHP

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\DeviceIp;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Mail;
use Laravel\Socialite\Facades\Socialite;
use Exception;
class GoogleAuthController extends Controller
{
/**
* Redirect to Google OAuth
*/
public function redirect()
{
try {
return Socialite::driver('google')->redirect();
} catch (Exception $e) {
Session::flash('error', get_phrase('Google authentication is currently unavailable. Please try again later.'));
return redirect()->route('login');
}
}
/**
* Handle Google OAuth callback
*/
public function callback()
{
try {
$googleUser = Socialite::driver('google')->user();
// Validate required data
if (!$googleUser->getEmail()) {
Session::flash('error', get_phrase('Google account email is required. Please ensure your Google account has an email address.'));
return redirect()->route('login');
}
// Find existing user by email
$existingUser = User::where('email', $googleUser->getEmail())->first();
if ($existingUser) {
// Update existing user with Google data if missing
if (!$existingUser->google_id) {
$existingUser->update([
'google_id' => $googleUser->getId(),
'photo' => $googleUser->getAvatar() ?? $existingUser->avatar,
]);
}
Auth::login($existingUser);
return $this->handlePostLogin($existingUser);
} else {
// Create new user with your existing field structure
$newUser = User::create([
'name' => $googleUser->getName() ?? $this->generateNameFromEmail($googleUser->getEmail()),
'email' => $googleUser->getEmail(),
'google_id' => $googleUser->getId(),
'password' => null, // No password for Google-authenticated users
'role' => 'student',
'status' => 1,
'photo' => $googleUser->getAvatar(),
]);
if (get_settings('student_email_verification') != 1) {
$user_data['email_verified_at'] = Carbon::now();
}
Auth::login($newUser);
Session::flash('success', get_phrase('Account created successfully! Welcome to our platform.'));
return $this->handlePostLogin($newUser);
}
} catch (Exception $e) {
Session::flash('error', get_phrase('Authentication failed. Please try again or use another method.'));
return redirect()->route('login');
}
}
/**
* Handle post-login logic (device tracking, etc.)
*/
private function handlePostLogin($user)
{
request()->session()->regenerate();
// Track device limitation (same as your existing login)
if (Auth::check() && $user->role != 'admin') {
$current_ip = request()->getClientIp();
$session_id = request()->session()->getId();
$current_user_agent = base64_encode($user->id . request()->header('user-agent'));
$allowed_devices = get_settings('device_limitation') ?? 1;
$logged_in_devices = DeviceIp::where('user_id', $user->id)->get();
if ($logged_in_devices->where('user_agent', '!=', $current_user_agent)->count() < $allowed_devices) {
if ($logged_in_devices->where('user_agent', $current_user_agent)->count() == 0) {
DeviceIp::insert([
'user_id' => $user->id,
'ip_address' => $current_ip,
'session_id' => $session_id,
'user_agent' => $current_user_agent,
'created_at' => now(),
'updated_at' => now(),
]);
} else {
DeviceIp::where('user_id', $user->id)
->where('user_agent', $current_user_agent)
->update([
'session_id' => $session_id,
'updated_at' => now(),
]);
}
} else {
$logged_in_oldest_row = DeviceIp::where('user_id', $user->id)->orderBy('id', 'desc')->first();
$data = [
'verification_link' => route('login', ['user_agent' => $logged_in_oldest_row->user_agent])
];
try {
Mail::send('email.new_device_login_verification', $data, function ($message) use($user) {
$message->to($user->email, $user->name)->subject('New login confirmation');
});
Auth::guard('web')->logout();
request()->session()->invalidate();
request()->session()->regenerateToken();
Session::flash('success', get_phrase('A confirmation email has been sent. Please check your inbox to confirm access to this account from this device.'));
return redirect(route('login'));
} catch (\Swift_TransportException $e) {
Session::flash('error', 'We could not send the email. Please try again later.');
} catch (Exception $e) {
Session::flash('error', 'Something went wrong. Please try again.');
}
Auth::guard('web')->logout();
request()->session()->invalidate();
request()->session()->regenerateToken();
return redirect(route('login'));
}
}
return redirect()->intended('/dashboard');
}
/**
* Generate a name from email if Google name is not available
*/
private function generateNameFromEmail($email)
{
$name = strstr($email, '@', true);
return ucfirst(str_replace(['.', '_'], ' ', $name));
}
}