93 lines
3.0 KiB
PHP
93 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Services\KekaOutlookService;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
final class KekaOutlookController extends Controller
|
|
{
|
|
public function __construct(private readonly KekaOutlookService $kekaOutlook) {}
|
|
|
|
/**
|
|
* GET /keka/connect
|
|
*
|
|
* FIRST TIME:
|
|
* → Your Microsoft OAuth (stores token in oauth_tokens)
|
|
* → callback stores token → redirect to sentientgeeks.keka.com
|
|
* (Keka's SSO kicks in automatically since Microsoft session exists)
|
|
*
|
|
* ALREADY CONNECTED:
|
|
* → Silent token refresh if near expiry
|
|
* → Straight to sentientgeeks.keka.com
|
|
*/
|
|
public function connect(Request $request): RedirectResponse
|
|
{
|
|
$user = $request->user();
|
|
|
|
if ($this->kekaOutlook->isConnected($user)) {
|
|
try {
|
|
$this->kekaOutlook->getValidToken($user);
|
|
} catch (\RuntimeException) {
|
|
// Token fully expired/revoked → re-authenticate
|
|
return redirect()->away($this->kekaOutlook->getAuthUrl());
|
|
}
|
|
|
|
// Already connected and token valid → go to Keka
|
|
return redirect()->away((string) config('microsoft.keka_dashboard_url'));
|
|
}
|
|
|
|
// Not connected yet → your Microsoft OAuth first
|
|
return redirect()->away($this->kekaOutlook->getAuthUrl());
|
|
}
|
|
|
|
/**
|
|
* GET /keka/callback
|
|
*
|
|
* Microsoft posts auth code here → store token → redirect to Keka.
|
|
* Keka's own SSO will auto-login since Microsoft session is now active.
|
|
*/
|
|
public function callback(Request $request): RedirectResponse
|
|
{
|
|
if ($request->filled('error')) {
|
|
return redirect()->route('dashboard')
|
|
->with('error', 'Microsoft login failed: ' . $request->get('error_description', $request->get('error')));
|
|
}
|
|
|
|
if (! $this->kekaOutlook->isValidState($request->get('state'))) {
|
|
return redirect()->route('dashboard')
|
|
->with('error', 'Invalid session state. Please try connecting again.');
|
|
}
|
|
|
|
$code = $request->get('code');
|
|
|
|
if (! $code) {
|
|
return redirect()->route('dashboard')
|
|
->with('error', 'No authorization code received.');
|
|
}
|
|
|
|
$result = $this->kekaOutlook->handleCallback($request->user(), $code);
|
|
|
|
if (! $result['success']) {
|
|
return redirect()->route('dashboard')
|
|
->with('error', 'Connection failed: ' . ($result['message'] ?? 'Unknown error'));
|
|
}
|
|
|
|
// Token stored ✓ → Keka SSO will auto-login via active Microsoft session
|
|
return redirect()->away((string) config('microsoft.keka_dashboard_url'));
|
|
}
|
|
|
|
/**
|
|
* POST /keka/disconnect
|
|
*/
|
|
public function disconnect(Request $request): RedirectResponse
|
|
{
|
|
$this->kekaOutlook->disconnect($request->user());
|
|
|
|
return redirect()->route('dashboard')
|
|
->with('success', 'Keka has been disconnected.');
|
|
}
|
|
} |