diff --git a/src/Exceptions/AdminErrorPages.php b/src/Exceptions/AdminErrorPages.php index e362173..c10dd84 100644 --- a/src/Exceptions/AdminErrorPages.php +++ b/src/Exceptions/AdminErrorPages.php @@ -27,7 +27,7 @@ public function __invoke(Throwable $exception, Request $request): ?Response } $guard = (string) config('lazy.auth.guard', 'web'); - $useAdminLayout = $status === 404 || ($status === 403 && Auth::guard($guard)->check()); + $useAdminLayout = in_array($status, [403, 404], true) && Auth::guard($guard)->check(); try { return response()->view('lazy::errors.page', [ diff --git a/src/LazyAdminServiceProvider.php b/src/LazyAdminServiceProvider.php index 7aa9fa2..cefd1b9 100644 --- a/src/LazyAdminServiceProvider.php +++ b/src/LazyAdminServiceProvider.php @@ -312,6 +312,14 @@ public function packageBooted(): void RouteFacade::put('profile/password', [ProfileController::class, 'password'])->middleware('throttle:6,1')->name('profile.password'); }, ['middleware' => ['web', 'auth:'.config('lazy.auth.guard', 'web')]]); + // Let missing admin URLs pass through the same web/session/auth middleware as normal pages. + // Laravel evaluates fallback routes after regular routes, including host-defined admin routes. + RouteFacade::admin(function (): void { + RouteFacade::fallback(static function (): never { + abort(404); + }); + }); + $prefix = trim((string) config('lazy.admin.route.name', 'admin.'), '.'); app(SettingsRegistry::class)->registerSection( diff --git a/tests/Feature/AdminErrorPagesTest.php b/tests/Feature/AdminErrorPagesTest.php index e20a8ce..f5d2185 100644 --- a/tests/Feature/AdminErrorPagesTest.php +++ b/tests/Feature/AdminErrorPagesTest.php @@ -2,6 +2,7 @@ use Illuminate\Foundation\Auth\User; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Route; use Step2dev\LazyAdmin\Exceptions\AdminErrorPages; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -51,7 +52,7 @@ } }); -it('uses the actual admin layout for missing pages regardless of the authentication flag', function (): void { +it('uses the actual admin layout for authenticated missing pages', function (): void { $user = new class extends User {}; $user->id = 123; $this->be($user); @@ -63,10 +64,19 @@ ->and($response?->getContent())->toContain('Back to dashboard'); }); -it('attempts full admin rendering for a guest 404 instead of the standalone template', function (): void { +it('does not expose the admin interface to guests', function (): void { $renderer = new AdminErrorPages; $response = $renderer(new HttpException(404), Request::create('/admin/missing')); expect($response?->getStatusCode())->toBe(404) - ->and($response?->getContent())->toContain('data-lazy-admin-shell'); + ->and($response?->getContent())->not->toContain('data-lazy-admin-shell'); +}); + +it('registers a guarded fallback for unknown admin routes', function (): void { + $route = collect(Route::getRoutes()->getRoutes()) + ->first(fn ($route) => $route->isFallback && str_contains($route->uri(), 'admin')); + + expect($route)->not->toBeNull() + ->and($route->gatherMiddleware())->toContain('web') + ->and($route->gatherMiddleware())->toContain('auth:web'); });