Commit graph

12964 commits

Author SHA1 Message Date
Andras Bacsai
dab30da63c
Merge pull request #6862 from coollabsio/andrasbacsai/livewire-model-binding
Complete Livewire legacy model binding migration (25+ components)
2025-10-17 09:27:18 +02:00
Andras Bacsai
3734cb654e
Merge pull request #6907 from coollabsio/andrasbacsai/review-delete-user
Admin command for deleting users
2025-10-16 17:35:22 +02:00
Andras Bacsai
2d59418683
Changes auto-committed by Conductor (#6908) 2025-10-16 17:33:42 +02:00
Andras Bacsai
2b51363b8c Changes auto-committed by Conductor 2025-10-16 17:23:22 +02:00
Andras Bacsai
975d1b8a6b Changes auto-committed by Conductor 2025-10-16 17:13:47 +02:00
Andras Bacsai
e2c254a5a8 Changes auto-committed by Conductor 2025-10-16 17:08:08 +02:00
Andras Bacsai
543d6fb334
Merge branch 'next' into andrasbacsai/livewire-model-binding 2025-10-16 17:07:48 +02:00
Andras Bacsai
1906278101
Merge pull request #6906 from coollabsio/andrasbacsai/auth-views-redesign
Update auth pages to match onboarding design
2025-10-16 17:07:12 +02:00
Andras Bacsai
945118bab4 Changes auto-committed by Conductor 2025-10-16 17:03:38 +02:00
Andras Bacsai
5e3c50456c Changes auto-committed by Conductor 2025-10-16 17:01:32 +02:00
Andras Bacsai
78d45951c2
Merge pull request #6903 from coollabsio/andrasbacsai/cleanup-ghcr-untagged
Add GHCR untagged image cleanup workflow
2025-10-16 14:55:24 +02:00
Andras Bacsai
8741ab82ab Changes auto-committed by Conductor 2025-10-16 14:39:08 +02:00
Andras Bacsai
edcdea78a2 Changes auto-committed by Conductor 2025-10-16 14:36:19 +02:00
Andras Bacsai
9fc182729c
Merge pull request #6902 from coollabsio/onboarding-skip-first-page
Fix Hetzner Cloud rendering in onboarding
2025-10-16 14:34:54 +02:00
Andras Bacsai
ac653ddcbc Changes auto-committed by Conductor 2025-10-16 14:34:32 +02:00
Andras Bacsai
bc972505e3
Merge pull request #6899 from coollabsio/andrasbacsai/db-backup-api
Add Cancel Deployment API endpoint
2025-10-16 13:47:05 +02:00
Andras Bacsai
ab473c2ca4
Merge pull request #6901 from coollabsio/andrasbacsai/fix-ports-exposes-null
Seed Docker Compose Example with ports_exposes
2025-10-16 13:46:15 +02:00
Andras Bacsai
bf6a109e56 Changes auto-committed by Conductor 2025-10-16 13:45:49 +02:00
Andras Bacsai
b91758021b
Merge pull request #6900 from coollabsio/andrasbacsai/input-focus-styling
Update input focus styling to border-left
2025-10-16 13:44:07 +02:00
Andras Bacsai
aacb6016b0 Changes auto-committed by Conductor 2025-10-16 13:43:52 +02:00
Andras Bacsai
d4fb69ea98 fix: ensure authorization check is performed during component mount 2025-10-16 13:23:50 +02:00
Andras Bacsai
802569bf63 Changes auto-committed by Conductor 2025-10-16 13:19:05 +02:00
Andras Bacsai
cdf6b5f161 Fix preview domain generation for services with multiple domains
When a docker compose service has multiple comma-separated domains, the
generate() method was only processing the first domain and truncating the rest.

The issue was that Url::fromString() can't parse comma-separated URLs - it only
parses the first one.

Fixed by:
1. Splitting comma-separated domains with explode(',', $domain_string)
2. Processing each domain individually in a foreach loop
3. Generating preview URLs for each domain using the same template/random/pr_id
4. Joining the results back with implode(',', $preview_fqdns)

This ensures all domains get properly transformed for preview deployments.

Example:
- Original: http://domain1.com,http://domain2.com
- Preview: http://57.domain1.com,http://57.domain2.com
- Before fix: http://57.domain1.com,http (truncated)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 13:10:29 +02:00
Andras Bacsai
6e8c557ed3 fix: ensure authorization checks are in place for viewing and updating the application 2025-10-16 13:04:44 +02:00
Andras Bacsai
db3514cd8e Fix json_decode null handling in PreviewsCompose
Fixed three potential fatal errors where json_decode could return null:

1. save() method (lines 39-41): Added null coalescing to default to empty array,
   and ensure service entry exists before writing domain
2. generate() method (line 56): Changed to use assoc flag consistently and
   fallback to empty array
3. generate() method (lines 95-97): Same fix as save() - null coalescing and
   service entry initialization

All json_decode calls now consistently:
- Use the assoc flag to return arrays (not objects)
- Fall back to empty array with ?: []
- Initialize service entry with ?? [] before writing

This prevents "Attempt to modify property of null" fatal errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 13:04:23 +02:00
Andras Bacsai
d2a334df78 refactor: replace random ID generation with Cuid2 for unique HTML IDs in form components 2025-10-16 12:54:14 +02:00
Andras Bacsai
a5c6f53b58 Fix wire:dirty indicator appearing on readonly fields without wire:model binding
The wire:dirty.class was being applied to all form inputs, even those without
wire:model bindings (like readonly fields). This caused the dirty state indicator
to appear on readonly fields when other fields in the form were modified.

Fixed by only applying wire:dirty.class when wire:model binding is present:
- input.blade.php: Moved wire:dirty.class inside @if($modelBinding !== 'null')
- textarea.blade.php: Applied same fix for all textarea variations
- select.blade.php: Applied same fix for select elements

This ensures only fields with actual Livewire bindings show dirty state indicators.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 11:09:39 +02:00
Andras Bacsai
837a0f4545 Merge branch 'next' into andrasbacsai/livewire-model-binding
Resolved merge conflicts between Livewire model binding refactoring and UI/CSS updates from next branch. Key integrations:

- Preserved unique HTML ID generation for form components
- Maintained wire:model bindings using $modelBinding
- Integrated new wire:dirty.class styles (border-l-warning pattern)
- Kept both syncData(true) and validateDockerComposeForInjection in StackForm
- Merged security tests and helper improvements from next

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 11:05:29 +02:00
Andras Bacsai
473c32270d Changes auto-committed by Conductor 2025-10-16 11:01:58 +02:00
Andras Bacsai
733c20fc9d fix: update version numbers to 4.0.0-beta.436 and 4.0.0-beta.437 2025-10-16 10:14:20 +02:00
Andras Bacsai
aada45d856
Merge pull request #6876 from thereis/feat/update-applicationpullrequestupdatejob-documentation
feat: include service name in preview deployment updates
2025-10-16 10:10:03 +02:00
Andras Bacsai
6fbac979c6
Merge pull request #6893 from coollabsio/fix-isdirty-updated-hooks
fix: use wasChanged() instead of isDirty() in updated hooks
2025-10-16 10:09:10 +02:00
Andras Bacsai
fd63c4f6f9
Merge branch 'next' into fix-isdirty-updated-hooks 2025-10-16 10:08:29 +02:00
Andras Bacsai
4783dcb80a
Merge pull request #6891 from coollabsio/fix-compose-volume-injection
fix: docker compose parsing
2025-10-16 10:08:11 +02:00
Andras Bacsai
51d232f7a1
Merge pull request #6897 from coollabsio/andrasbacsai/service-textarea-focus
Fix: Domains input dirty state reset on blur
2025-10-16 09:59:39 +02:00
Andras Bacsai
1e360aa156 fix: correct variable name typo in generateGitLsRemoteCommands method 2025-10-16 09:51:37 +02:00
Andras Bacsai
8b20b0e45a test: add coverage for newline and tab rejection in volume strings
Added test to verify parseDockerVolumeString rejects:
- Newline characters (command separator)
- Tab characters (token separator)

Both characters are blocked by validateShellSafePath which is called
during volume string parsing, ensuring they cannot be used for
command injection attacks.

All 80 security tests pass (217 assertions).
2025-10-16 09:51:37 +02:00
Andras Bacsai
97868c3264 feat: allow safe environment variable defaults in array-format volumes
Changes:
- Extended validateDockerComposeForInjection to recognize env vars with defaults
- Added pattern check for ${VAR:-default} format alongside simple ${VAR} check
- Maintains consistency with parseDockerVolumeString behavior for string format

Test coverage:
- Added test for safe environment variable defaults in array format
- Verifies ${DATA_PATH:-./data} is allowed in array-format volumes
- All 79 security tests pass (215 assertions)

This allows users to specify environment variables with safe default values
in array-format Docker Compose volumes, matching the behavior already
supported in string-format volumes.
2025-10-16 09:51:37 +02:00
Andras Bacsai
728f261316 Changes auto-committed by Conductor 2025-10-16 09:51:37 +02:00
Andras Bacsai
53cd2a6e86 refactor: harden and deduplicate validateShellSafePath
Changes:
- Added tab character ("\t") to dangerous characters list as token separator
- Removed redundant regex-based preg_match block (lines 147-152)
- Characters $(, ${, and backticks were already covered in $dangerousChars array
- Simplified function to rely solely on $dangerousChars loop

Security improvement:
- Tab characters can act as token separators in shell contexts
- Now explicitly blocked with descriptive error message

Tests:
- Added test for tab character blocking
- All 78 security tests pass (213 assertions)
- No regression in existing functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 09:51:37 +02:00
Andras Bacsai
a219f2e80e fix: use canonical parser for Windows path validation
Problem:
- validateVolumeStringForInjection used explode(':') to parse volume strings
- This incorrectly splits Windows paths like "C:\host\path:/container" at the drive letter colon
- Could lead to false positives/negatives in injection detection

Solution:
- Replace custom parsing in validateVolumeStringForInjection with call to parseDockerVolumeString
- parseDockerVolumeString already handles Windows paths, environment variables, and performs validation
- Eliminates code duplication and uses single source of truth for volume string parsing

Tests:
- All 77 existing security tests pass (211 assertions)
- Added 6 new Windows path tests (8 assertions)
- Fixed pre-existing test bug: preg_match returns int 1, not boolean true

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 09:51:37 +02:00
Andras Bacsai
3700f78355 refactor: preserve exception chain in validation error handling
When catching and re-throwing exceptions, preserve the original exception
chain by passing the caught exception as the third parameter to new Exception.
This retains the full stack trace for debugging while keeping descriptive
error messages.

Changes:
- validateDockerComposeForInjection(): 4 locations fixed
- validateVolumeStringForInjection(): 3 locations fixed

Before:
  throw new \Exception('Invalid Docker volume definition: '.$e->getMessage());

After:
  throw new \Exception('Invalid Docker volume definition: '.$e->getMessage(), 0, $e);

Benefits:
- Full stack trace preserved for debugging
- Original exception context retained
- Better error diagnostics in production logs

All 60 security tests pass (176 assertions).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 09:51:37 +02:00
Andras Bacsai
334559bb0b Update bootstrap/helpers/parsers.php
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-16 09:51:37 +02:00
Andras Bacsai
fa8393184f refactor: improve validation error handling and coding standards
Changes:
1. Add explicit try-catch blocks around validateDockerComposeForInjection()
   in API endpoints to return proper 422 JSON responses with validation errors
2. Rename $service_payload to $servicePayload for PSR-12 compliance (camelCase)

API endpoints now properly handle validation failures:
- One-click service creation (line 334)
- Custom compose service creation (line 480)
- Service update endpoint (line 808)

All return consistent error format:
{
  "message": "Validation failed.",
  "errors": {
    "docker_compose_raw": "Invalid Docker Compose service name: ..."
  }
}

Livewire components already have proper exception handling via handleError().

All 60 security tests pass (176 assertions).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 09:51:37 +02:00
Andras Bacsai
cb1f571eb4 fix: prevent command injection in Docker Compose parsing - add pre-save validation
This commit addresses a critical security issue where malicious Docker Compose
data was being saved to the database before validation occurred.

Problem:
- Service models were saved to database first
- Validation ran afterwards during parse()
- Malicious data persisted even when validation failed
- User saw error but damage was already done

Solution:
1. Created validateDockerComposeForInjection() to validate YAML before save
2. Added pre-save validation to all Service creation/update points:
   - Livewire: DockerCompose.php, StackForm.php
   - API: ServicesController.php (create, update, one-click)
3. Validates service names and volume paths (string + array formats)
4. Blocks shell metacharacters: backticks, $(), |, ;, &, >, <, newlines

Security fixes:
- Volume source paths (string format) - validated before save
- Volume source paths (array format) - validated before save
- Service names - validated before save
- Environment variable patterns - safe ${VAR} allowed, ${VAR:-$(cmd)} blocked

Testing:
- 60 security tests pass (176 assertions)
- PreSaveValidationTest.php: 15 tests for pre-save validation
- ValidateShellSafePathTest.php: 15 tests for core validation
- VolumeSecurityTest.php: 15 tests for volume parsing
- ServiceNameSecurityTest.php: 15 tests for service names

Related commits:
- Previous: Added validation during parse() phase
- This commit: Moves validation before database save

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 09:51:37 +02:00
Andras Bacsai
2a8f02ed58 Changes auto-committed by Conductor 2025-10-16 09:48:32 +02:00
Andras Bacsai
988c08f2d1
Merge pull request #6895 from coollabsio/andrasbacsai/fix-compose-preg-match
Fix preg_match error with array labels
2025-10-16 09:00:03 +02:00
Andras Bacsai
47916e1b1d
Merge pull request #6889 from coollabsio/andrasbacsai/fix-host-header-injection
feat: implement TrustHosts middleware to handle FQDN and IP address trust logic
2025-10-16 08:56:44 +02:00
Andras Bacsai
70f152f0ba Changes auto-committed by Conductor 2025-10-16 08:51:15 +02:00
Andras Bacsai
e04b9cd07c fix: use wasChanged() instead of isDirty() in updated hooks
Critical Bug Fix:
- isDirty() always returns false in updated() hook
- wasChanged() correctly tracks modifications after save

Files Fixed:
- ServerSetting: Sentinel restart now triggers on config changes
- DeletesUserSessions: Session invalidation now works on password change

Security Impact:
- CRITICAL: Password changes now properly invalidate user sessions
- Prevents session hijacking after password reset

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 22:36:48 +02:00