name('admin.consent.callback'); Route::get('/admin/consent/start', TenantOnboardingController::class) ->name('admin.consent.start'); // Avoid Filament's tenancy root redirect which otherwise sends users into legacy flows. // when no default tenant can be resolved. Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, 'ensure-workspace-selected', ]) ->get('/admin', WorkspaceOverview::class) ->name('admin.home'); Route::get('/admin/rbac/start', [RbacDelegatedAuthController::class, 'start']) ->name('admin.rbac.start'); Route::get('/admin/rbac/callback', [RbacDelegatedAuthController::class, 'callback']) ->name('admin.rbac.callback'); Route::get('/auth/entra/redirect', [EntraController::class, 'redirect']) ->name('auth.entra.redirect'); Route::get('/auth/entra/callback', [EntraController::class, 'callback']) ->middleware('throttle:entra-callback') ->name('auth.entra.callback'); $makeSmokeCookie = static fn () => cookie()->make( SuppressDebugbarForSmokeRequests::COOKIE_NAME, SuppressDebugbarForSmokeRequests::COOKIE_VALUE, 120, ); $resolveSmokeTenant = static function (?string $identifier): ?Tenant { $identifier = trim((string) $identifier); if ($identifier === '') { return null; } return Tenant::query() ->withTrashed() ->where(function ($query) use ($identifier): void { $query->where('external_id', $identifier) ->orWhere('tenant_id', $identifier); if (ctype_digit($identifier)) { $query->orWhereKey((int) $identifier); } }) ->first(); }; $resolveSmokeWorkspace = static function (?string $identifier, ?Tenant $tenant = null): ?Workspace { if ($tenant instanceof Tenant) { return Workspace::query()->whereKey($tenant->workspace_id)->first(); } $identifier = trim((string) $identifier); if ($identifier === '') { return null; } return Workspace::query() ->where(function ($query) use ($identifier): void { $query->where('slug', $identifier); if (ctype_digit($identifier)) { $query->orWhereKey((int) $identifier); } }) ->first(); }; $resolveSmokeRedirect = static function (?string $redirect, ?Tenant $tenant = null): string { $fallback = $tenant instanceof Tenant && ! $tenant->trashed() ? '/admin/t/'.$tenant->external_id : '/admin'; $redirect = trim((string) $redirect); if ($redirect === '') { return $fallback; } $parsedRedirect = parse_url($redirect); if ($parsedRedirect === false || isset($parsedRedirect['scheme']) || isset($parsedRedirect['host'])) { return $fallback; } $path = '/'.ltrim((string) ($parsedRedirect['path'] ?? ''), '/'); if ($path !== '/admin' && ! str_starts_with($path, '/admin/')) { return $fallback; } $query = isset($parsedRedirect['query']) ? '?'.$parsedRedirect['query'] : ''; $fragment = isset($parsedRedirect['fragment']) ? '#'.$parsedRedirect['fragment'] : ''; return $path.$query.$fragment; }; $resolveSmokeUser = static function (?string $email, ?Workspace $workspace = null, ?Tenant $tenant = null): ?User { $email = trim((string) $email); if ($email !== '') { $user = User::query()->where('email', $email)->first(); return $user instanceof User ? $user : null; } $scopedWorkspace = $workspace; if (! $scopedWorkspace instanceof Workspace && $tenant instanceof Tenant) { $scopedWorkspace = Workspace::query()->whereKey($tenant->workspace_id)->first(); } if (! $scopedWorkspace instanceof Workspace) { return null; } $rolePriority = [ WorkspaceRole::Owner->value => 0, WorkspaceRole::Manager->value => 1, WorkspaceRole::Operator->value => 2, WorkspaceRole::Readonly->value => 3, ]; $users = User::query() ->whereHas('workspaceMemberships', function ($query) use ($scopedWorkspace): void { $query->where('workspace_id', (int) $scopedWorkspace->getKey()); }) ->when($tenant instanceof Tenant, function ($query) use ($tenant): void { $query->whereHas('tenantMemberships', function ($membershipQuery) use ($tenant): void { $membershipQuery->where('tenant_id', (int) $tenant->getKey()); }); }) ->with(['workspaceMemberships' => function ($query) use ($scopedWorkspace): void { $query->where('workspace_id', (int) $scopedWorkspace->getKey()); }]) ->get() ->filter(function (User $user) use ($tenant): bool { return ! $tenant instanceof Tenant || $user->canAccessTenant($tenant); }) ->sortBy(function (User $user) use ($rolePriority): array { $role = $user->workspaceMemberships->first()?->role; return [ $rolePriority[(string) $role] ?? 99, (int) $user->getKey(), ]; }) ->values(); $user = $users->first(); return $user instanceof User ? $user : null; }; $completeSmokeLogin = static function ( Request $request, ?string $email = null, ?string $tenantIdentifier = null, ?string $workspaceIdentifier = null, ?string $redirect = null, ) use ( $makeSmokeCookie, $resolveSmokeRedirect, $resolveSmokeTenant, $resolveSmokeUser, $resolveSmokeWorkspace, ): \Illuminate\Http\RedirectResponse { $tenant = $resolveSmokeTenant($tenantIdentifier); $workspace = $resolveSmokeWorkspace($workspaceIdentifier, $tenant); $user = $resolveSmokeUser($email, $workspace, $tenant); abort_unless($user instanceof User, 404); $workspaceContext = app(WorkspaceContext::class); if (! $workspace instanceof Workspace) { $workspace = $workspaceContext->resolveInitialWorkspaceFor($user, $request); } abort_unless($workspace instanceof Workspace, 404); abort_unless($workspaceContext->isMember($user, $workspace), 404); if ($tenant instanceof Tenant) { abort_unless((int) $tenant->workspace_id === (int) $workspace->getKey(), 404); abort_unless($user->canAccessTenant($tenant), 404); } Auth::guard('web')->login($user); $request->session()->regenerate(); $request->session()->put( SuppressDebugbarForSmokeRequests::SESSION_KEY, SuppressDebugbarForSmokeRequests::COOKIE_VALUE, ); $workspaceContext->setCurrentWorkspace($workspace, $user, $request); if ($tenant instanceof Tenant) { $workspaceContext->rememberTenantContext($tenant, $request); } else { $workspaceContext->clearRememberedTenantContext($request); } return redirect() ->to($resolveSmokeRedirect($redirect, $tenant)) ->withCookie($makeSmokeCookie()); }; Route::get('/admin/local/smoke-login', function (Request $request) use ($completeSmokeLogin) { abort_unless(app()->environment(['local', 'testing']), 404); $fixture = config('tenantpilot.backup_health.browser_smoke_fixture'); $defaultEmail = is_array($fixture) ? data_get($fixture, 'user.email') : null; $defaultTenant = is_array($fixture) ? (data_get($fixture, 'blocked_drillthrough.tenant_external_id') ?? data_get($fixture, 'blocked_drillthrough.tenant_id')) : null; $defaultWorkspace = is_array($fixture) ? data_get($fixture, 'workspace.slug') : null; return $completeSmokeLogin( $request, email: (string) ($request->query('email', $defaultEmail ?? '')), tenantIdentifier: (string) ($request->query('tenant', $defaultTenant ?? '')), workspaceIdentifier: (string) ($request->query('workspace', $defaultWorkspace ?? '')), redirect: (string) ($request->query('redirect', '')), ); })->name('admin.local.smoke-login'); Route::get('/admin/local/backup-health-browser-fixture-login', function (Request $request) use ($completeSmokeLogin) { abort_unless(app()->environment(['local', 'testing']), 404); $fixture = config('tenantpilot.backup_health.browser_smoke_fixture'); $userEmail = is_array($fixture) ? data_get($fixture, 'user.email') : null; $tenantRouteKey = is_array($fixture) ? (data_get($fixture, 'blocked_drillthrough.tenant_id') ?? data_get($fixture, 'blocked_drillthrough.tenant_external_id')) : null; abort_unless(is_string($userEmail) && $userEmail !== '', 404); abort_unless(is_string($tenantRouteKey) && $tenantRouteKey !== '', 404); return $completeSmokeLogin( $request, email: $userEmail, tenantIdentifier: $tenantRouteKey, workspaceIdentifier: is_array($fixture) ? data_get($fixture, 'workspace.slug') : null, ); })->name('admin.local.backup-health-browser-fixture-login'); Route::middleware(['web', 'auth', 'ensure-correct-guard:web']) ->post('/admin/switch-workspace', SwitchWorkspaceController::class) ->name('admin.switch-workspace'); Route::middleware(['web', 'auth', 'ensure-correct-guard:web']) ->get('/admin/finding-exceptions/open-queue/{tenant}', OpenFindingExceptionsQueueController::class) ->name('admin.finding-exceptions.open-queue'); Route::middleware(['web', 'auth', 'ensure-correct-guard:web', 'ensure-workspace-selected']) ->post('/admin/select-tenant', SelectTenantController::class) ->name('admin.select-tenant'); Route::middleware(['web', 'auth', 'ensure-correct-guard:web', 'ensure-workspace-selected']) ->post('/admin/clear-tenant-context', ClearTenantContextController::class) ->name('admin.clear-tenant-context'); Route::bind('workspace', function (string $value): Workspace { /** @var WorkspaceResolver $resolver */ $resolver = app(WorkspaceResolver::class); $workspace = $resolver->resolve($value); abort_unless($workspace instanceof Workspace, 404); return $workspace; }); Route::bind('onboardingDraft', function (string $value): TenantOnboardingSession { $user = auth()->user(); abort_unless($user instanceof \App\Models\User, 403); $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); abort_unless(is_int($workspaceId), 404); $workspace = Workspace::query()->whereKey($workspaceId)->first(); abort_unless($workspace instanceof Workspace, 404); return app(OnboardingDraftResolver::class)->resolve((int) $value, $user, $workspace); }); $authorizeManagedTenantRoute = function (Tenant $tenant, Request $request): void { $user = $request->user(); abort_unless($user instanceof User, 403); $workspaceContext = app(WorkspaceContext::class); $workspaceId = $workspaceContext->currentWorkspaceId($request); abort_unless(is_int($workspaceId), 404); abort_unless((int) $tenant->workspace_id === $workspaceId, 404); $workspace = Workspace::query()->whereKey($workspaceId)->first(); abort_unless($workspace instanceof Workspace, 404); abort_unless($workspaceContext->isMember($user, $workspace), 404); $allowed = app(TenantOperabilityService::class)->outcomeFor( tenant: $tenant, question: TenantOperabilityQuestion::TenantBoundViewability, actor: $user, workspaceId: $workspaceId, lane: TenantPageCategory::TenantBound->lane(), )->allowed; abort_unless($allowed, 404); }; Route::middleware(['web', 'auth', 'ensure-correct-guard:web', 'ensure-workspace-member']) ->prefix('/admin/w/{workspace}') ->group(function (): void { Route::get('/', fn () => redirect()->route('admin.workspace.managed-tenants.index', ['workspace' => request()->route('workspace')])) ->name('admin.workspace.home'); Route::get('/ping', fn () => response()->noContent())->name('admin.workspace.ping'); }); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, ]) ->get('/admin/onboarding', \App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class) ->name('admin.onboarding'); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, ]) ->get('/admin/onboarding/{onboardingDraft}', \App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class) ->name('admin.onboarding.draft'); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, 'ensure-workspace-selected', ]) ->get('/admin/operations', \App\Filament\Pages\Monitoring\Operations::class) ->name('admin.operations.index'); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, 'ensure-workspace-selected', ]) ->get('/admin/evidence/overview', \App\Filament\Pages\Monitoring\EvidenceOverview::class) ->name('admin.evidence.overview'); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, 'ensure-workspace-selected', ]) ->prefix('/admin/tenants/{tenant:external_id}/provider-connections') ->group(function () use ($authorizeManagedTenantRoute): void { Route::get('/', function (Tenant $tenant, Request $request) use ($authorizeManagedTenantRoute) { $authorizeManagedTenantRoute($tenant, $request); return redirect()->to('/admin/provider-connections?tenant_id='.$tenant->external_id); })->name('admin.provider-connections.legacy-index'); Route::get('/create', function (Tenant $tenant, Request $request) use ($authorizeManagedTenantRoute) { $authorizeManagedTenantRoute($tenant, $request); return redirect()->to('/admin/provider-connections/create?tenant_id='.$tenant->external_id); })->name('admin.provider-connections.legacy-create'); Route::get('/{record}/edit', function (Tenant $tenant, mixed $record, Request $request) use ($authorizeManagedTenantRoute) { $authorizeManagedTenantRoute($tenant, $request); $connection = ProviderConnection::query() ->whereKey((int) $record) ->where('tenant_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->first(); abort_unless($connection instanceof ProviderConnection, 404); return redirect()->to('/admin/provider-connections/'.$connection->getKey().'/edit?tenant_id='.$tenant->external_id); })->name('admin.provider-connections.legacy-edit'); }); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, 'ensure-workspace-selected', 'ensure-filament-tenant-selected', ]) ->get('/admin/audit-log', \App\Filament\Pages\Monitoring\AuditLog::class) ->name('admin.monitoring.audit-log'); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, 'ensure-workspace-selected', ]) ->get('/admin/operations/{run}', \App\Filament\Pages\Operations\TenantlessOperationRunViewer::class) ->name('admin.operations.view'); Route::middleware([ 'web', 'panel:admin', 'ensure-correct-guard:web', DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, FilamentAuthenticate::class, 'ensure-workspace-member', ]) ->get('/admin/w/{workspace}/managed-tenants', \App\Filament\Pages\Workspaces\ManagedTenantsLanding::class) ->name('admin.workspace.managed-tenants.index'); Route::middleware(['signed']) ->get('/admin/review-packs/{reviewPack}/download', ReviewPackDownloadController::class) ->name('admin.review-packs.download'); if (app()->runningUnitTests()) { Route::middleware(['web', 'auth', 'ensure-workspace-selected']) ->get('/admin/_test/workspace-context', function (Request $request) { $workspaceId = app(\App\Support\Workspaces\WorkspaceContext::class)->currentWorkspaceId($request); return response()->json([ 'workspace_id' => $workspaceId, ]); }); }