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.'); } }