user(); if (! $user) { return false; } if ($resolved = self::fromTeamAccess($user)) { return $resolved['show_hub']; } $cached = session(self::SESSION_KEY); if (is_array($cached) && array_key_exists('show_hub', $cached)) { return (bool) $cached['show_hub']; } // Unknown in a silo before SSO cache — assume owner (fail open for hub). return true; } public static function showBilling(?Authenticatable $user = null): bool { $user ??= auth()->user(); if (! $user) { return false; } if ($resolved = self::fromTeamAccess($user)) { return $resolved['show_billing']; } $cached = session(self::SESSION_KEY); if (is_array($cached) && array_key_exists('show_billing', $cached)) { return (bool) $cached['show_billing']; } return true; } /** @return list|null Null means unrestricted / unknown. */ public static function allowedAppSlugs(?Authenticatable $user = null): ?array { $user ??= auth()->user(); if (! $user) { return []; } if ($resolved = self::fromTeamAccess($user)) { return $resolved['full_access'] ? null : $resolved['apps']; } $cached = session(self::SESSION_KEY); if (is_array($cached)) { if (! empty($cached['full_access'])) { return null; } if (array_key_exists('apps', $cached) && is_array($cached['apps'])) { return array_values(array_map('strval', $cached['apps'])); } } return null; } /** * @param array{full_access?: bool, apps?: list, show_hub?: bool, show_billing?: bool} $payload */ public static function remember(array $payload): void { session([self::SESSION_KEY => [ 'full_access' => (bool) ($payload['full_access'] ?? false), 'apps' => array_values(array_map('strval', (array) ($payload['apps'] ?? []))), 'show_hub' => (bool) ($payload['show_hub'] ?? false), 'show_billing' => (bool) ($payload['show_billing'] ?? false), ]]); } /** @return array{full_access: bool, apps: list, show_hub: bool, show_billing: bool}|null */ private static function fromTeamAccess(Authenticatable $user): ?array { $service = 'App\\Services\\Team\\TeamAccessService'; $userClass = 'App\\Models\\User'; if (! class_exists($service) || ! is_a($user, $userClass)) { return null; } try { $access = app($service); return [ 'full_access' => $access->hasFullProductAccess($user), 'apps' => $access->accessibleAppSlugs($user), 'show_hub' => $access->showProductHub($user), 'show_billing' => $access->showBilling($user), ]; } catch (\Throwable) { return null; } } }