chore: prepare for PR
This commit is contained in:
parent
1f1f2936e5
commit
0320d6a5b6
3 changed files with 66 additions and 1 deletions
|
|
@ -91,6 +91,13 @@ public function hosts(): array
|
||||||
// Trust all subdomains of APP_URL as fallback
|
// Trust all subdomains of APP_URL as fallback
|
||||||
$trustedHosts[] = $this->allSubdomainsOfApplicationUrl();
|
$trustedHosts[] = $this->allSubdomainsOfApplicationUrl();
|
||||||
|
|
||||||
|
// Always trust loopback addresses so local access works even when FQDN is configured
|
||||||
|
foreach (['localhost', '127.0.0.1', '[::1]'] as $localHost) {
|
||||||
|
if (! in_array($localHost, $trustedHosts, true)) {
|
||||||
|
$trustedHosts[] = $localHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return array_filter($trustedHosts);
|
return array_filter($trustedHosts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,15 @@
|
||||||
<h1 class="mt-4 font-bold tracking-tight dark:text-white">This page is definitely old, not like you!</h1>
|
<h1 class="mt-4 font-bold tracking-tight dark:text-white">This page is definitely old, not like you!</h1>
|
||||||
<p class="text-base leading-7 dark:text-neutral-300 text-black">Your session has expired. Please log in again to continue.
|
<p class="text-base leading-7 dark:text-neutral-300 text-black">Your session has expired. Please log in again to continue.
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center mt-10 gap-x-2">
|
<details class="mt-6 text-sm dark:text-neutral-400 text-neutral-600">
|
||||||
|
<summary class="cursor-pointer hover:dark:text-neutral-200 hover:text-neutral-800">Using a reverse proxy or Cloudflare Tunnel?</summary>
|
||||||
|
<ul class="mt-2 ml-4 list-disc space-y-1">
|
||||||
|
<li>Set your domain in <strong>Settings → FQDN</strong> to match the URL you use to access Coolify.</li>
|
||||||
|
<li>Cloudflare users: disable <strong>Browser Integrity Check</strong> and <strong>Under Attack Mode</strong> for your Coolify domain, as these can interrupt login sessions.</li>
|
||||||
|
<li>If you can still access Coolify via <code>localhost</code>, log in there first to configure your FQDN.</li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
<div class="flex items-center mt-6 gap-x-2">
|
||||||
<a href="/login">
|
<a href="/login">
|
||||||
<x-forms.button>Back to Login</x-forms.button>
|
<x-forms.button>Back to Login</x-forms.button>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,56 @@
|
||||||
expect($response->status())->not->toBe(400);
|
expect($response->status())->not->toBe(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('trusts localhost when FQDN is configured', function () {
|
||||||
|
InstanceSettings::updateOrCreate(
|
||||||
|
['id' => 0],
|
||||||
|
['fqdn' => 'https://coolify.example.com']
|
||||||
|
);
|
||||||
|
|
||||||
|
$middleware = new TrustHosts($this->app);
|
||||||
|
$hosts = $middleware->hosts();
|
||||||
|
|
||||||
|
expect($hosts)->toContain('localhost');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('trusts 127.0.0.1 when FQDN is configured', function () {
|
||||||
|
InstanceSettings::updateOrCreate(
|
||||||
|
['id' => 0],
|
||||||
|
['fqdn' => 'https://coolify.example.com']
|
||||||
|
);
|
||||||
|
|
||||||
|
$middleware = new TrustHosts($this->app);
|
||||||
|
$hosts = $middleware->hosts();
|
||||||
|
|
||||||
|
expect($hosts)->toContain('127.0.0.1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('trusts IPv6 loopback when FQDN is configured', function () {
|
||||||
|
InstanceSettings::updateOrCreate(
|
||||||
|
['id' => 0],
|
||||||
|
['fqdn' => 'https://coolify.example.com']
|
||||||
|
);
|
||||||
|
|
||||||
|
$middleware = new TrustHosts($this->app);
|
||||||
|
$hosts = $middleware->hosts();
|
||||||
|
|
||||||
|
expect($hosts)->toContain('[::1]');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows local access via localhost when FQDN is configured and request uses localhost host header', function () {
|
||||||
|
InstanceSettings::updateOrCreate(
|
||||||
|
['id' => 0],
|
||||||
|
['fqdn' => 'https://coolify.example.com']
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $this->get('/', [
|
||||||
|
'Host' => 'localhost',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Should NOT be rejected as untrusted host (would be 400)
|
||||||
|
expect($response->status())->not->toBe(400);
|
||||||
|
});
|
||||||
|
|
||||||
it('skips host validation for webhook endpoints', function () {
|
it('skips host validation for webhook endpoints', function () {
|
||||||
// All webhook routes are under /webhooks/* prefix (see RouteServiceProvider)
|
// All webhook routes are under /webhooks/* prefix (see RouteServiceProvider)
|
||||||
// and use cryptographic signature validation instead of host validation
|
// and use cryptographic signature validation instead of host validation
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue