fix(domains): reject single-label hostnames for app and service domains

This commit is contained in:
Andras Bacsai
2026-08-28 09:34:10 +02:00
parent b357522f94
commit 1639941da7
4 changed files with 36 additions and 1 deletions
+9 -1
View File
@@ -570,8 +570,16 @@ class ValidationPatterns
continue;
}
if (blank(parse_url($url, PHP_URL_HOST))) {
$host = parse_url($url, PHP_URL_HOST);
if (blank($host)) {
$errors[] = "Invalid URL: {$url}";
continue;
}
$unwrappedHost = trim((string) $host, '[]');
if (! str_contains($unwrappedHost, '.') && filter_var($unwrappedHost, FILTER_VALIDATE_IP) === false) {
$errors[] = "Invalid URL: {$url}. The hostname must be a fully qualified domain name.";
}
}
+9
View File
@@ -98,6 +98,15 @@ it('uses safe domain validation rules on the domains form', function () {
->and($validator->errors()->has('newDomain'))->toBeTrue();
});
it('does not add a single-label hostname as an application domain', function () {
Livewire::test(Domains::class, ['application' => $this->application->fresh()])
->set('newDomainParts.host', 'aaa')
->call('addDomain')
->assertDispatched('error');
expect($this->application->fresh()->fqdn)->toBeNull();
});
it('lists existing domains as individual rows', function () {
$this->application->update([
'fqdn' => 'https://example.com,https://www.example.com,https://another.example.com,https://www.another.example.com',
+12
View File
@@ -193,6 +193,18 @@ it('resets the add domain dns gate when segmented domain fields change', functio
->assertSet('forceSaveDns', false);
});
it('does not add a single-label hostname as a service domain', function () {
$this->apiApp->update(['fqdn' => null]);
Livewire::test(Domains::class, ['service' => $this->service->fresh(['applications', 'server'])])
->set('newServiceApplicationId', $this->apiApp->id)
->set('newDomainParts.host', 'aaa')
->call('addDomain')
->assertDispatched('error');
expect($this->apiApp->fresh()->fqdn)->toBeNull();
});
it('shows dns entries control next to Add', function () {
Livewire::test(Domains::class, ['service' => $this->service->fresh(['applications', 'server'])])
->assertSuccessful()
+6
View File
@@ -191,3 +191,9 @@ it('normalizes application domain scheme and host without lowercasing path query
it('validates application domains with underscores in the hostname', function () {
expect(ValidationPatterns::validateApplicationDomains('https://myapp_service.example.com'))->toBeEmpty();
});
it('rejects single-label application hostnames but allows IP addresses', function () {
expect(ValidationPatterns::validateApplicationDomains('https://aaa'))->not->toBeEmpty()
->and(ValidationPatterns::validateApplicationDomains('https://localhost'))->not->toBeEmpty()
->and(ValidationPatterns::validateApplicationDomains('http://192.0.2.10:8000'))->toBeEmpty();
});