diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php new file mode 100644 index 000000000..f3d17714a --- /dev/null +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -0,0 +1,77 @@ +validateProvider($provider); + + return Socialite::driver($provider)->redirect(); + } + + public function callback(string $provider, Request $request) + { + $this->validateProvider($provider); + + try { + $oauthUser = Socialite::driver($provider)->user(); + } catch (\Exception $e) { + return redirect()->route('login')->withErrors(['oauth' => 'OAuth authentication failed. Please try again.']); + } + + $settings = instanceSettings(); + + $existingUser = User::where('email', strtolower($oauthUser->getEmail()))->first(); + + if ($existingUser) { + Auth::login($existingUser, true); + $team = $existingUser->currentTeam(); + if (! $team) { + $team = $existingUser->teams()->first(); + } + session(['currentTeam' => $team]); + + return redirect()->intended(RouteServiceProvider::HOME ?? '/dashboard'); + } + + // No existing user — check registration permissions + if (! $settings->is_registration_enabled && ! $settings->is_oauth_registration_enabled) { + return redirect()->route('login')->withErrors(['oauth' => 'Registration is disabled. Please contact your administrator.']); + } + + // Create new user from OAuth + $newUser = User::create([ + 'name' => $oauthUser->getName() ?? $oauthUser->getNickname() ?? explode('@', $oauthUser->getEmail())[0], + 'email' => strtolower($oauthUser->getEmail()), + 'password' => Hash::make(Str::random(32)), + 'email_verified_at' => now(), + ]); + + $team = $newUser->teams()->first(); + session(['currentTeam' => $newUser->currentTeam = $team]); + + Auth::login($newUser, true); + + return redirect()->intended('/dashboard'); + } + + protected function validateProvider(string $provider): void + { + $allowedProviders = ['github', 'gitlab', 'google', 'bitbucket', 'azure']; + + if (! in_array($provider, $allowedProviders)) { + abort(404, 'OAuth provider not supported.'); + } + } +}