withRouting( web: __DIR__.'/../routes/web.php', api: __DIR__.'/../routes/api.php', commands: __DIR__.'/../routes/console.php', channels: __DIR__.'/../routes/channels.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { // The app only ever receives traffic from the Traefik reverse proxy on the // internal docker network (TLS is terminated there), so trust its // X-Forwarded-* headers — otherwise Laravel thinks every request is plain // HTTP and generates http:// asset/URL links, which browsers block as // mixed content on the https:// site. $middleware->trustProxies(at: '*', headers: Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB); $middleware->alias([ 'role' => EnsureRole::class, 'abilities' => CheckAbilities::class, 'ability' => CheckForAnyAbility::class, ]); // navigator.sendBeacon (used to stop the ticket timer on tab close, // see routes/web.php) can't attach a CSRF header/field. $middleware->validateCsrfTokens(except: [ 'operator/tickets/*/stop-timer', ]); }) ->withExceptions(function (Exceptions $exceptions): void { $exceptions->shouldRenderJsonWhen( fn (Request $request) => $request->is('api/*'), ); })->create();