161 lines
6.2 KiB
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(),
|
|
'avatar' => $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));
|
|
}
|
|
}
|