110 lines
3.8 KiB
PHP
110 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
use Laravel\Socialite\Facades\Socialite;
|
|
|
|
class DashboardController extends Controller
|
|
{
|
|
/**
|
|
* Show the user dashboard.
|
|
*/
|
|
public function index()
|
|
{
|
|
$user = Auth::user();
|
|
|
|
// Get authorized apps for this user
|
|
$services = $user->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);
|
|
}
|
|
}
|