sls/app/Http/Controllers/DashboardController.php
2026-07-07 16:53:32 +05:30

129 lines
4.4 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.');
}
// If user is logged in via Microsoft, route all service launches (including Keka)
// through the Microsoft SSO flow to ensure their browser has an active Microsoft session.
if ($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');
// If launching Microsoft Teams, redirect to the deep link launcher page
if (str_contains($targetUrl, 'teams.microsoft.com')) {
return redirect()->route('sso.launch-app', [
'name' => 'Microsoft Teams',
'url' => $targetUrl,
'protocol' => 'msteams://'
]);
}
return redirect($targetUrl);
}
/**
* Render the desktop application launcher page with web fallback.
*/
public function launchApp(Request $request)
{
$name = $request->query('name', 'Application');
$url = $request->query('url');
$protocol = $request->query('protocol');
if (!$url || !$protocol) {
return redirect()->route('dashboard');
}
return view('sso.launch-app', compact('name', 'url', 'protocol'));
}
}