getCurrentUser(); if (!$user) { return $this->unauthorizedResponse($request); } // Super Admin can access any company if ($user->isSuperAdmin()) { return $next($request); } // Routes that do not require a company context $bypassRoutes = ['/profile', '/logout', '/dashboard']; if (in_array($request->getPathInfo(), $bypassRoutes)) { return $next($request); } // Get company ID from route or user session $companyId = $this->getCompanyId($request, $user); // Check if user can access the company if (!$this->canAccessCompany($user, $companyId)) { return $this->forbiddenResponse($request); } // Set company context in session for easy access $_SESSION['current_company_id'] = $companyId; return $next($request); } /** * Get current authenticated user. * * @return \Modules\Auth\Models\User|null */ protected function getCurrentUser(): ?\Modules\Auth\Models\User { if (!isset($_SESSION['user_id'])) { return null; } try { if (class_exists('\Modules\Auth\Models\User')) { return \Modules\Auth\Models\User::find($_SESSION['user_id']); } } catch (\Exception $e) { error_log("Error loading user: " . $e->getMessage()); } return null; } /** * Get company ID from request or user session. * * @param Request $request * @param \Modules\Auth\Models\User $user * @return int|null */ protected function getCompanyId(Request $request, $user): ?int { // 1. Check URL parameter (if present) // Note: FastRoute parameters are passed to controller, not easily accessible in middleware via standard request // We can parse the path if necessary, but standard app logic usually relies on session or explicit selection. // 2. Check Session if (isset($_SESSION['current_company_id'])) { return (int) $_SESSION['current_company_id']; } // 3. Default to user's primary business ID return $user->users_bus_id; } /** * Check if user can access the company. * * @param \Modules\Auth\Models\User $user * @param int|null $companyId * @return bool */ protected function canAccessCompany($user, $companyId): bool { if (!$companyId) { return false; } // If user belongs to this company directly if ($user->users_bus_id == $companyId) { return true; } // If user has permission/association to this company (Multi-tenant logic) // TODO: Implement multi-company association logic if needed return false; } protected function unauthorizedResponse(Request $request) { if ($this->expectsJson($request)) { return new JsonResponse(['message' => 'Unauthorized'], 401); } return new Response('', 302, ['Location' => url('/login')]); } protected function forbiddenResponse(Request $request) { if ($this->expectsJson($request)) { return new JsonResponse(['message' => 'Forbidden - Access denied to this company'], 403); } // Show 403 error page try { $view = new \Kernel\View(); return new Response($view->render('errors/403.twig'), 403); } catch (\Throwable $e) { return new Response('Access denied to this company', 403); } } protected function expectsJson(Request $request): bool { return $request->headers->get('Accept') === 'application/json' || $request->headers->get('Content-Type') === 'application/json' || str_contains($request->getPathInfo(), '/api/'); } }