authorizedApps(); return view('dashboard', compact('user', 'services')); } /** * Launch a service app using SSO. */ public function launchSSO($id) { $user = Auth::user(); $app = \App\Models\App::findOrFail($id); // Check if user is authorized to access this app $authorizedApps = $user->authorizedApps(); if (!$authorizedApps->contains('id', $app->id)) { return redirect()->route('dashboard')->with('error', 'Access denied. You do not have permission to access this service.'); } // Check if it is a Microsoft service $isMicrosoft = str_contains($app->url, 'microsoft.com') || str_contains($app->url, 'office.com') || str_contains($app->url, 'office365.com') || str_contains($app->url, 'outlook.com') || $app->icon_svg === 'outlook' || $app->icon_svg === 'teams'; if ($isMicrosoft && $user->microsoft_id) { // Save target app URL in session so callback knows where to redirect session(['sso_target_url' => $app->url]); try { // Determine domain hint based on user's email domain to skip account type prompt $domainHint = (str_ends_with($user->email, '.onmicrosoft.com') || (str_contains($user->email, '@') && !str_ends_with($user->email, 'outlook.com') && !str_ends_with($user->email, 'hotmail.com') && !str_ends_with($user->email, 'live.com'))) ? 'organizations' : 'consumers'; // Redirect to Microsoft OAuth authorize page with login_hint, domain_hint and custom callback return Socialite::driver('microsoft') ->redirectUrl(route('sso.callback')) ->with([ 'login_hint' => $user->email, 'domain_hint' => $domainHint ]) ->redirect(); } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error('Microsoft SSO launch failed', [ 'message' => $e->getMessage() ]); // Fallback: direct redirect return redirect($app->url); } } // For non-Microsoft or non-Microsoft-linked users, redirect directly return redirect($app->url); } /** * Handle the callback for Microsoft SSO. */ public function handleSSOCallback(Request $request) { $user = Auth::user(); try { $microsoftUser = Socialite::driver('microsoft') ->redirectUrl(route('sso.callback')) ->user(); if ($microsoftUser && $user) { // Update tokens in db $user->update([ 'microsoft_token' => $microsoftUser->token, 'microsoft_refresh_token' => $microsoftUser->refreshToken ?? $user->microsoft_refresh_token, ]); } } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error('Microsoft SSO callback failed', [ 'message' => $e->getMessage() ]); // If callback fails but we have target URL, we can still try to redirect } $targetUrl = session('sso_target_url', 'https://outlook.office.com/mail/'); session()->forget('sso_target_url'); return redirect($targetUrl); } }