fix(server): return SSH username validation messages

This commit is contained in:
Andras Bacsai
2026-06-03 11:57:46 +02:00
parent 9aa40bb5f0
commit 419a551d76
4 changed files with 57 additions and 15 deletions
@@ -492,6 +492,8 @@ class ServersController extends Controller
'is_build_server' => 'boolean|nullable',
'instant_validate' => 'boolean|nullable',
'proxy_type' => 'string|nullable',
], [
...ValidationPatterns::serverUsernameMessages(),
]);
$extraFields = array_diff(array_keys($request->all()), $allowedFields);
@@ -677,6 +679,8 @@ class ServersController extends Controller
'server_disk_usage_notification_threshold' => 'integer|min:1|max:100',
'server_disk_usage_check_frequency' => 'string',
'connection_timeout' => 'integer|min:1|max:300',
], [
...ValidationPatterns::serverUsernameMessages(),
]);
$extraFields = array_diff(array_keys($request->all()), $allowedFields);
+22 -10
View File
@@ -213,6 +213,23 @@ class Index extends Component
}
}
protected function rules(): array
{
return [
'remoteServerName' => 'required|string',
'remoteServerHost' => 'required|string',
'remoteServerPort' => 'required|integer|min:1|max:65535',
'remoteServerUser' => ValidationPatterns::serverUsernameRules(),
];
}
protected function messages(): array
{
return [
...ValidationPatterns::serverUsernameMessages('remoteServerUser', 'SSH User'),
];
}
public function getProxyType()
{
$this->selectProxy(ProxyTypes::TRAEFIK->value);
@@ -275,12 +292,7 @@ class Index extends Component
public function saveServer()
{
$this->validate([
'remoteServerName' => 'required|string',
'remoteServerHost' => 'required|string',
'remoteServerPort' => 'required|integer',
'remoteServerUser' => ValidationPatterns::serverUsernameRules(),
]);
$this->validate();
$this->privateKey = formatPrivateKey($this->privateKey);
$foundServer = Server::whereIp($this->remoteServerHost)->first();
@@ -466,10 +478,10 @@ class Index extends Component
public function saveAndValidateServer()
{
$this->validate([
'remoteServerPort' => 'required|integer|min:1|max:65535',
'remoteServerUser' => ValidationPatterns::serverUsernameRules(),
]);
$this->validate(array_intersect_key($this->rules(), array_flip([
'remoteServerPort',
'remoteServerUser',
])));
$this->createdServer->update([
'port' => $this->remoteServerPort,
+3 -3
View File
@@ -1865,15 +1865,15 @@ function isBase64Encoded($strValue)
{
return base64_encode(base64_decode($strValue, true)) === $strValue;
}
function customApiValidator(Collection|array $item, array $rules)
function customApiValidator(Collection|array $item, array $rules, array $messages = [])
{
if (is_array($item)) {
$item = collect($item);
}
return Validator::make($item->toArray(), $rules, [
return Validator::make($item->toArray(), $rules, array_merge([
'required' => 'This field is required.',
]);
], $messages));
}
function parseDockerComposeFile(Service|Application $resource, bool $isNew = false, int $pull_request_id = 0, ?int $preview_id = null)
{
+28 -2
View File
@@ -73,6 +73,21 @@ it('updates a server through the API with a dotted SSH username', function () {
expect($server->fresh()->user)->toBe('deploy.user');
});
it('rejects unsafe SSH usernames when creating a server through the API', function () {
$response = $this->withHeaders([
'Authorization' => 'Bearer '.$this->token,
'Content-Type' => 'application/json',
])->postJson('/api/v1/servers', [
'name' => 'Unsafe User Server',
'ip' => '192.0.2.11',
'private_key_uuid' => $this->privateKey->uuid,
'user' => 'deploy$user',
]);
$response->assertStatus(422);
$response->assertJsonPath('errors.user.0', 'The User may only contain letters, numbers, dots, hyphens, and underscores.');
});
it('rejects unsafe SSH usernames through the API', function () {
$server = Server::factory()->create([
'team_id' => $this->team->id,
@@ -88,6 +103,7 @@ it('rejects unsafe SSH usernames through the API', function () {
$response->assertStatus(422);
$response->assertJsonStructure(['errors' => ['user']]);
$response->assertJsonPath('errors.user.0', 'The User may only contain letters, numbers, dots, hyphens, and underscores.');
});
it('allows dotted SSH usernames in the server creation form', function () {
@@ -135,7 +151,12 @@ it('rejects unsafe SSH usernames during onboarding server creation', function ()
->set('remoteServerPort', 22)
->set('remoteServerUser', 'deploy$user')
->call('saveServer')
->assertHasErrors(['remoteServerUser' => ['regex']]);
->assertHasErrors([
'remoteServerUser' => [
'regex',
'The SSH User may only contain letters, numbers, dots, hyphens, and underscores.',
],
]);
});
it('rejects unsafe SSH usernames during onboarding server validation', function () {
@@ -152,5 +173,10 @@ it('rejects unsafe SSH usernames during onboarding server validation', function
->set('remoteServerPort', 22)
->set('remoteServerUser', 'deploy$user')
->call('saveAndValidateServer')
->assertHasErrors(['remoteServerUser' => ['regex']]);
->assertHasErrors([
'remoteServerUser' => [
'regex',
'The SSH User may only contain letters, numbers, dots, hyphens, and underscores.',
],
]);
});