Skip to content

fix(server): allow dots in ssh username - #9951

Merged
andrasbacsai merged 5 commits into
coollabsio:nextfrom
ShadowArcanist:jean/allow-dots-username
Jun 3, 2026
Merged

andrasbacsai merged 5 commits into
coollabsio:nextfrom
ShadowArcanist:jean/allow-dots-username

Conversation

@ShadowArcanist

Copy link
Copy Markdown
Member

Changes

  • For server username input is rejected if it contains dot, but linux allows it so I updated the regex to allow dots. While I was here I found we were not validating server username on onboarding so added a fix for it

Issues

Category

  • Bug fix

AI Assistance

  • AI was used (please describe below)

If AI was used:

  • Tools used: Jean + Claude (GPT 5.5)
  • How extensively: every change on this PR (except the PR description)

Testing

Spin up coolify dev and tried add server with username that has dots (on both onboarding and servers page)

Contributor Agreement

Important

  • I have read and understood the contributor guidelines. If I have failed to follow any guideline, I understand that this PR may be closed without review.
  • I have searched existing issues and pull requests (including closed ones) to ensure this isn't a duplicate.
  • I have tested all the changes thoroughly with a local development instance of Coolify and I am confident that they will work as expected when a maintainer tests them.

ShadowArcanist and others added 4 commits May 6, 2026 21:21
Centralize SSH username rules and sanitization so dotted usernames are
accepted consistently across API, onboarding, and Livewire server forms.
@andrasbacsai

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR consolidates server username validation into a centralized pattern system. New regex constants and helper methods in ValidationPatterns define allowed characters and generate Laravel validation rules and error messages. All server creation and editing flows—including the API controller (ServersController), three Livewire components (ByIp, Show, Boarding), and the Server model—are updated to reference these shared patterns instead of inline regex. The Server model's user attribute sanitization also switches to use the centralized pattern for character stripping. Comprehensive feature tests verify API and Livewire validation acceptance of dotted usernames (e.g., deploy.user) and rejection of unsafe usernames (e.g., containing $); unit tests validate the pattern itself and attribute persistence.

Come with me if you want to live on servers instead of serverless—this PR proves self-hosting validation patterns are not a Skynet moment, just good engineering. No tacos harmed in the making of this PR (though gluten-free ones would be appreciated). 🌮⚔️

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/Livewire/Boarding/Index.php (1)

276-283: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Inconsistent validation messages detected. Recommend upgrade. 🔧

Your onboarding flow uses the centralized rules (good!) but inline $this->validate([...]) doesn't let you provide custom error messages. Users get generic Laravel messages instead of the helpful "may only contain letters, numbers, dots, hyphens, and underscores" guidance.

Your other Livewire components (ByIp, Show) got this right by defining rules() and messages() methods. For onboarding UX, where users are configuring their first server, clear validation messages are especially critical.

♻️ Proposed fix for consistency

Add rules() and messages() methods to the 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'),
+    ];
+}

Then update both methods:

 public function saveServer()
 {
-    $this->validate([
-        'remoteServerName' => 'required|string',
-        'remoteServerHost' => 'required|string',
-        'remoteServerPort' => 'required|integer',
-        'remoteServerUser' => ValidationPatterns::serverUsernameRules(),
-    ]);
+    $this->validate();
     // ... rest of method
 }

 public function saveAndValidateServer()
 {
-    $this->validate([
-        'remoteServerPort' => 'required|integer|min:1|max:65535',
-        'remoteServerUser' => ValidationPatterns::serverUsernameRules(),
-    ]);
+    $this->validate();
     // ... rest of method
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Livewire/Boarding/Index.php` around lines 276 - 283, The saveServer()
method currently calls $this->validate([...]) inline which prevents custom
messages; add component-level rules() and messages() methods (matching pattern
used in ByIp and Show) that return the validation array (use
ValidationPatterns::serverUsernameRules() for 'remoteServerUser' etc.) and the
user-friendly messages (e.g., "may only contain letters, numbers, dots, hyphens,
and underscores" for the username rule); then update saveServer() to call
$this->validate() with no parameters so Livewire uses the new rules() and
messages() methods.
app/Http/Controllers/Api/ServersController.php (1)

485-495: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missing custom validation messages, and that bothers me. 🎯

You've wired up the username rules but forgot to merge in the custom error messages. When user validation fails, API consumers get generic Laravel messages instead of the helpful "may only contain letters, numbers, dots, hyphens, and underscores" message.

Your Livewire components got it right (see ByIp.php:78 and Show.php:143). Terminate the inconsistency!

💬 Proposed fix to add custom messages

After the validator is created (around line 485), merge the custom messages:

 $validator = customApiValidator($request->all(), [
     'name' => 'string|max:255',
     'description' => 'string|nullable',
     'ip' => ['string', 'required', new ValidServerIp],
     'port' => 'integer|nullable|between:1,65535',
     'private_key_uuid' => 'string|required',
     'user' => ValidationPatterns::serverUsernameRules(required: false),
     'is_build_server' => 'boolean|nullable',
     'instant_validate' => 'boolean|nullable',
     'proxy_type' => 'string|nullable',
+], [
+    ...ValidationPatterns::serverUsernameMessages('user', 'User'),
 ]);

Apply the same fix to the update_server method around line 664.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Http/Controllers/Api/ServersController.php` around lines 485 - 495, The
validator for ServersController methods (store_server around the shown block and
update_server near line ~664) is missing the custom error messages for the
'user' field; after creating the validator via customApiValidator(...) merge in
the same custom messages used in the Livewire components (see ByIp.php line 78
and Show.php line 143) so the username rule from
ValidationPatterns::serverUsernameRules() produces the friendly "may only
contain letters, numbers, dots, hyphens, and underscores" message instead of
generic Laravel text; update both the store_server and update_server flows to
merge those messages into the validator before returning errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@app/Http/Controllers/Api/ServersController.php`:
- Around line 485-495: The validator for ServersController methods (store_server
around the shown block and update_server near line ~664) is missing the custom
error messages for the 'user' field; after creating the validator via
customApiValidator(...) merge in the same custom messages used in the Livewire
components (see ByIp.php line 78 and Show.php line 143) so the username rule
from ValidationPatterns::serverUsernameRules() produces the friendly "may only
contain letters, numbers, dots, hyphens, and underscores" message instead of
generic Laravel text; update both the store_server and update_server flows to
merge those messages into the validator before returning errors.

In `@app/Livewire/Boarding/Index.php`:
- Around line 276-283: The saveServer() method currently calls
$this->validate([...]) inline which prevents custom messages; add
component-level rules() and messages() methods (matching pattern used in ByIp
and Show) that return the validation array (use
ValidationPatterns::serverUsernameRules() for 'remoteServerUser' etc.) and the
user-friendly messages (e.g., "may only contain letters, numbers, dots, hyphens,
and underscores" for the username rule); then update saveServer() to call
$this->validate() with no parameters so Livewire uses the new rules() and
messages() methods.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c71baa0e-2ded-4bca-a683-174a63875abb

📥 Commits

Reviewing files that changed from the base of the PR and between 1a7fa40 and 9aa40bb.

📒 Files selected for processing (8)
  • app/Http/Controllers/Api/ServersController.php
  • app/Livewire/Boarding/Index.php
  • app/Livewire/Server/New/ByIp.php
  • app/Livewire/Server/Show.php
  • app/Models/Server.php
  • app/Support/ValidationPatterns.php
  • tests/Feature/ServerUsernameValidationTest.php
  • tests/Unit/ServerUsernamePatternTest.php

@andrasbacsai

Copy link
Copy Markdown
Member

Thank you for the PR! 💜

@andrasbacsai
andrasbacsai merged commit e31251f into coollabsio:next Jun 3, 2026
1 check passed
@andrasbacsai andrasbacsai mentioned this pull request Jun 4, 2026
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants