TrustHosts skipped its check while the cache key instance_settings_fqdn_host
was empty, and only the skipped check filled that key. So since e1fe58639
(October 2025) no release restricted the Host header. Turning it on now would
lock out users who reach Coolify by server IP or another name when the domain
or proxy is broken.
Links in emails and notifications do not use the Host header: base_url()
uses the configured FQDN or the server IP (see ResetPasswordUrlTest). So
remove the middleware, its cache key and its tests. TrustProxies is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Delete Blade components, component classes, Livewire components and
views that nothing uses after the redesign.
- Delete tests that only compare Blade/CSS source text; keep the source
checks for authorization gates, stable wire:key values and escaping.
- Update stale tests to the current UI and behaviour.
- Update DESIGN.md to the current navigation and layout.
- Add a lesson: test behaviour, not source markup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Delegate host validation to parent class instead of custom implementation
- Update base_url() helper to use config('app.url') instead of url('/')
- Add test for APP_URL fallback when no FQDN or public IPs configured
- Remove dedicated TrustHostsMiddlewareTest (logic now tested via integration tests)
- Add support for bracketed IPv6 addresses when FQDN is not configured
- Harden password reset URL generation against X-Forwarded-Host header poisoning
- Add test coverage for IPv6-only configurations with malicious headers
- Update imports and clean up exception syntax in shared helpers
- Fix circular cache dependency in TrustHosts where handle() checked cache
before hosts() could populate it, causing host validation to never activate
- Validate both Host and X-Forwarded-Host headers against trusted hosts list
(X-Forwarded-Host is checked before TrustProxies applies it to the request)
- Use base_url() instead of url() for password reset link generation so the
URL is derived from server-side config (FQDN / public IP) instead of the
request context
- Strip port from X-Forwarded-Host before matching (e.g. host:443 → host)
- Add tests for host validation, cache population, and reset URL generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>