Commit graph

110 commits

Author SHA1 Message Date
Andras Bacsai
336fa0c714 fix: critical privilege escalation in team invitation system
This commit addresses a critical security vulnerability where low-privileged
users (members) could invite high-privileged users (admins/owners) to teams,
allowing them to escalate their own privileges through password reset.

Root Causes Fixed:
1. TeamPolicy authorization checks were commented out, allowing all team
   members to manage invitations instead of just admins/owners
2. Missing role elevation checks in InviteLink component allowed members
   to invite users with higher privileges

Security Fixes:

1. app/Policies/TeamPolicy.php
   - Uncommented and enforced authorization checks for:
     * update() - Only admins/owners can update team settings
     * delete() - Only admins/owners can delete teams
     * manageMembers() - Only admins/owners can manage team members
     * viewAdmin() - Only admins/owners can view admin panel
     * manageInvitations() - Only admins/owners can manage invitations

2. app/Livewire/Team/InviteLink.php
   - Added explicit role elevation checks to prevent:
     * Members from inviting admins or owners
     * Admins from inviting owners (defense-in-depth)
   - Validates that inviter has sufficient privileges for target role

Test Coverage:

1. tests/Feature/TeamPolicyTest.php
   - 24 comprehensive tests covering all policy methods
   - Tests for owner, admin, member, and non-member access
   - Specific tests for the privilege escalation vulnerability

2. tests/Feature/TeamInvitationPrivilegeEscalationTest.php
   - 11 tests covering all role elevation scenarios
   - Tests member → admin/owner escalation (blocked)
   - Tests admin → owner escalation (blocked)
   - Tests valid invitation paths for each role

Impact:
- Prevents privilege escalation attacks
- Protects all Coolify instances from unauthorized access
- Enforces proper role hierarchy in team management

References:
- Identified by Aikido AI whitebox pentest service
- CVE: Pending assignment
- Severity: Critical

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 11:42:25 +02:00
Andras Bacsai
23c1184e86
Merge pull request #6880 from coollabsio/andrasbacsai/fix-new-image-quick-action
fix: 'new image' quick action not progressing to resource selection
2025-10-15 10:51:21 +02:00
Andras Bacsai
66cff9d9b8 fix: 'new image' quick action not progressing to resource selection
Fixed three issues preventing the "new image" quick action from working:

1. Frontend matching logic wasn't checking the quickcommand field
   - Added check for item.quickcommand in the matching logic
   - Now "new image" matches docker-image via its quickcommand "(type: new image)"

2. Search query remained populated after triggering selection flow
   - Clear searchQuery in navigateToResourceCreation() to show selection UI
   - This switches the UI from creatable items list to server selection

3. Redirect wasn't using Livewire's redirect method
   - Changed from redirect()->route() to $this->redirect(route())
   - Ensures proper Livewire component redirect behavior

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 10:49:07 +02:00
Andras Bacsai
20b4288916 fix: improve Docker image digest handling and add auto-parse feature
- Replace manual regex parsing with DockerImageParser in ApplicationsController
- Fix double-decoration bug where image names like nginx@sha256:hash would
  become nginx:hash@sha256 causing malformed references
- Add auto-parse feature in Livewire DockerImage component
- Users can now paste complete references like nginx:stable@sha256:abc123...
  and fields auto-populate
- Update UI placeholder with examples: nginx, docker.io/nginx:latest,
  ghcr.io/user/app:v1.2.3, nginx:stable@sha256:abc123...
- Add comprehensive unit tests for auto-parse functionality
- All tests passing (20 tests, 73 assertions)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-15 10:19:01 +02:00
Andras Bacsai
652f523f5b test: improve Git ls-remote parsing tests with uppercase SHA and negative cases
Enhanced test coverage to match production code regex pattern and prevent
false positives by adding comprehensive edge case testing.

**Changes:**

1. **Updated regex pattern to match production code**:
   - Changed from `/([0-9a-f]{40})\s*\t/` to `/\b([0-9a-fA-F]{40})(?=\s*\t)/`
   - Now handles both uppercase and lowercase hex characters (A-F and a-f)
   - Uses word boundary `\b` for more precise matching
   - Uses lookahead `(?=\s*\t)` instead of capturing whitespace

2. **Added uppercase SHA test**:
   - Tests extraction of uppercase commit SHA (196D3DF7...)
   - Normalizes to lowercase using `strtolower()` for comparison
   - Reflects Git's case-insensitive SHA handling

3. **Added negative test cases**:
   - Tests output with no commit SHA present (error messages only)
   - Tests output with tab but invalid SHA format
   - Ensures `null` is returned to prevent false positives

**Test Coverage:**
- 8 total tests (up from 5)
- Covers all positive cases (lowercase, uppercase, warnings, whitespace)
- Covers negative cases (missing SHA, invalid format)
- Regex pattern now exactly matches production code in ApplicationDeploymentJob.php:1908

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 17:34:26 +02:00
Andras Bacsai
bf00405971 fix(git): handle Git redirects and improve URL parsing for tangled.sh and other Git hosts
Fixes deployment failures when Git repositories redirect (e.g., tangled.sh → tangled.org)
and improves security by adding proper shell escaping for repository URLs.

**Root Cause:**
Git redirect warnings can appear on the same line as ls-remote output with no newline:
`warning: redirecting to https://tangled.org/...196d3df...	refs/heads/master`

The previous parsing logic split by newlines and extracted text before tabs, which
included the entire warning message instead of just the 40-character commit SHA.

**Changes:**

1. **Fixed commit SHA extraction** (ApplicationDeploymentJob.php):
   - Changed from line-based parsing to regex pattern matching
   - Uses `/([0-9a-f]{40})\s*\t/` to find valid 40-char hex commit SHA before tab
   - Handles warnings on same line, separate lines, multiple warnings, and whitespace
   - Added comprehensive Ray debug logs for troubleshooting

2. **Added security fix** (Application.php):
   - Added `escapeshellarg()` for repository URLs in 'other' deployment type
   - Prevents shell injection and fixes parsing issues with special characters like `@`
   - Added Ray debug logs for deployment type tracking

3. **Comprehensive test coverage** (GitLsRemoteParsingTest.php):
   - Tests normal output without warnings
   - Tests redirect warning on separate line
   - Tests redirect warning on same line (actual tangled.sh format)
   - Tests multiple warning lines
   - Tests extra whitespace handling

**Resolves:**
- Linear issue COOLGH-53: Valid git URLs are rejected as being invalid
- GitHub issue #6568: tangled.sh deployments failing
- Handles Git redirects universally for all Git hosting services

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 11:55:17 +02:00
Andras Bacsai
ce12c94709 fix: prevent duplicate services on image change and enable real-time UI refresh
This commit addresses two critical issues with Docker Compose service management:

## Issue 1: Duplicate Services Created on Image Change
When changing the image in a docker-compose file, the parser was creating new
ServiceApplication/ServiceDatabase records instead of updating existing ones.

**Root Cause**: The parsers used `firstOrCreate()` with `['name', 'image', 'service_id']`,
meaning any image change would create a new record.

**Fix**: Remove `image` from `firstOrCreate()` queries and update it separately after
finding or creating the service record.

**Changes**:
- `bootstrap/helpers/parsers.php` (serviceParser v3): Fixed in presave loop (lines 1188-1203)
  and main parsing loop (lines 1519-1539)
- `bootstrap/helpers/shared.php` (parseDockerComposeFile v2): Fixed null check logic
  (lines 1308-1348)

## Issue 2: UI Not Refreshing After Changes
When compose file or domain was modified, the Configuration component wasn't receiving
events to refresh its data, requiring manual page refresh to see updates.

**Root Cause**: The Configuration component wasn't listening for refresh events dispatched
by child components (StackForm, EditDomain).

**Fix**: Add event listeners and dispatchers to enable real-time UI updates.

**Changes**:
- `app/Livewire/Project/Service/Configuration.php`: Added listeners for `refreshServices`
  and `refresh` events (lines 36-37)
- `app/Livewire/Project/Service/EditDomain.php`: Added `refreshServices` dispatch (line 76)
- Note: `app/Livewire/Project/Service/StackForm.php` already had the dispatch

## Tests Added
- `tests/Unit/ServiceParserImageUpdateTest.php`: 4 tests verifying no duplicates created
- `tests/Unit/ServiceConfigurationRefreshTest.php`: 4 tests verifying event dispatching

All 8 new tests pass, and all existing unit tests continue to pass.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 10:12:36 +02:00
Andras Bacsai
d93a13eeee feat: add YAML validation for cloud-init scripts
Add ValidCloudInitYaml validation rule to ensure cloud-init scripts
are properly formatted before saving. The validator supports:
- Cloud-config YAML (with or without #cloud-config header)
- Bash scripts (starting with #!)
- Empty/null values (optional field)

Uses Symfony YAML parser to validate YAML syntax and provides
detailed error messages when validation fails.

Added comprehensive unit tests covering:
- Valid cloud-config with/without header
- Valid bash scripts
- Invalid YAML syntax detection
- Complex multi-section cloud-config

Applied validation to:
- ByHetzner component (server creation)
- CloudInitScriptForm component (script management)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 13:56:55 +02:00
Andras Bacsai
7061eacfa5 feat: add cloud-init script support for Hetzner server creation
This commit adds the ability to use cloud-init scripts when creating Hetzner servers through the integration. Users can write custom scripts that will be executed during server initialization, and optionally save these scripts at the team level for future reuse.

Key features:
- Textarea field for entering cloud-init scripts (bash or cloud-config YAML)
- Checkbox to save scripts for later use at team level
- Dropdown to load previously saved scripts
- Scripts are encrypted in the database
- Full validation and authorization checks
- Comprehensive unit and feature tests

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 19:37:16 +02:00
Andras Bacsai
7069236714 feat: add IPv4/IPv6 network configuration for Hetzner server creation
Add support for configuring IPv4 and IPv6 public network interfaces when creating servers through the Hetzner integration. Users can now enable or disable IPv4 and IPv6 independently, with both enabled by default.

Features:
- Added enable_ipv4 and enable_ipv6 checkboxes in the server creation form
- Both options are enabled by default as per Hetzner best practices
- IPv4 is preferred when both are enabled
- Fallback to IPv6 when only IPv6 is enabled
- Proper validation and error handling for network configuration
- Comprehensive test coverage for IP address selection logic

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 18:22:25 +02:00
Andras Bacsai
ac3af8a882 feat: add support for selecting additional SSH keys from Hetzner in server creation form 2025-10-10 12:17:05 +02:00
Andras Bacsai
2e21d875af feat: implement ValidHostname validation rule and integrate it into server creation process 2025-10-10 11:03:13 +02:00
Andras Bacsai
513f6b54f7 feat: implement Hetzner deletion failure notification system with email and messaging support 2025-10-10 09:35:58 +02:00
Andras Bacsai
2c64136503 feat(backup): enhance backup job with S3 upload handling and notifications
- Introduced a new notification class, BackupSuccessWithS3Warning, to alert users when local backups succeed but S3 uploads fail.
- Updated DatabaseBackupJob to track local backup success and handle S3 upload errors, improving error reporting and user notifications.
- Modified ScheduledDatabaseBackupExecution model to include a new s3_uploaded boolean field for tracking S3 upload status.
- Adjusted views and validation logic to reflect changes in backup execution status and S3 handling.
- Added tests to ensure the new s3_uploaded column is correctly implemented and validated.
2025-10-07 15:02:23 +02:00
Andras Bacsai
cef3d3af5d feat(proxy): enhance proxy configuration regeneration by extracting custom commands
- Added a new function to extract custom proxy commands from existing Traefik configurations before regenerating the proxy configuration.
- Updated the proxy configuration generation logic to include these custom commands, ensuring they are preserved during regeneration.
- Introduced unit tests to validate the extraction of custom commands and handle various scenarios, including invalid YAML and different proxy types.
2025-10-07 11:11:13 +02:00
Andras Bacsai
590de8ce37 feat(docker): enhance Docker image handling with new validation and parsing logic
- Refactored DockerImage component to use separate properties for image name, tag, and SHA256 digest.
- Introduced DockerImageFormat validation rule to enforce correct image format.
- Updated DockerImageParser to handle new parsing logic for image tags and SHA256 hashes.
- Enhanced UI to separate input fields for image name, tag, and SHA256 digest, improving user experience.
- Added comprehensive tests for DockerImageParser to ensure accurate parsing and validation of image formats.
2025-10-03 11:31:00 +02:00
Andras Bacsai
0e02eff4a1
Merge branch 'v4.x' into allow-dep 2025-10-03 10:57:10 +02:00
Andras Bacsai
aadde3a83e feat(deployments): enhance Docker build argument handling for multiline variables
- Introduced new helper functions to generate Docker build arguments and environment flags, accommodating multiline variables with proper escaping.
- Updated the ApplicationDeploymentJob to utilize these new functions, improving the handling of environment variables during deployment.
- Added comprehensive tests to ensure correct behavior for multiline variables and special characters.
2025-10-02 13:54:36 +02:00
Andras Bacsai
502dd72a34 fix(validation): update git:// URL validation to support port numbers and tilde characters in paths 2025-09-29 12:21:15 +02:00
Andras Bacsai
810ba3dd9e feat(validation): enhance ValidGitRepositoryUrl to support additional safe characters and add comprehensive unit tests for various Git repository URL formats 2025-09-28 22:18:21 +02:00
Andras Bacsai
320a7c97f9 refactor(tests): simplify matchWatchPaths tests and update implementation for better clarity 2025-09-26 14:33:18 +02:00
Andras Bacsai
0691a1834a feat(application): implement order-based pattern matching for watch paths with negation support 2025-09-25 14:26:11 +02:00
Andras Bacsai
38e5e85344
Merge pull request #6598 from ossamalafhel/feature/watch-paths-for-services
feat: 👀 Show Watch Paths field for Docker Compose applicationsFeature/watch paths for services
2025-09-25 13:17:29 +02:00
Andras Bacsai
1f691e274b
Merge branch 'v4.x' into feature/watch-paths-for-services 2025-09-25 12:11:01 +02:00
Andras Bacsai
47b060e291 refactor(ui): improve styling and consistency in environment variable warning and docker cleanup components 2025-09-25 11:45:07 +02:00
GitHub Actions
c1c149968e Fix team invitation email case sensitivity bug
- Add email normalization to TeamInvitation model using setEmailAttribute()
- Add HasFactory trait to Team model for testing support
- Create TeamFactory for testing
- Add tests to verify email normalization works correctly
- Fixes issue where mixed case emails in invitations would cause lookup failures
- Resolves #6291

The bug occurred because:
1. User model normalizes emails to lowercase
2. TeamInvitation model did not normalize emails
3. When invitation was created with mixed case, it was stored as-is
4. User lookup failed due to case mismatch during invitation acceptance
5. This caused users to not be able to see teams they were invited to

This fix ensures both models normalize emails consistently.
2025-09-16 15:31:48 +01:00
Ossama Lafhel
5247185933 feat(add-watch-paths-for-services): show watch paths field for docker compose applications
- Fix UI template to display Watch Paths for all GitHub-based applications
- Remove condition that limited Watch Paths to private repositories only
- Add comprehensive unit tests for isWatchPathsTriggered() method
- Test various pattern matching scenarios (wildcards, globs, etc.)
- Watch Paths now works for Docker Compose apps with both public and private repos
2025-09-13 05:40:07 +02:00
Andras Bacsai
a60d6dadc7 fix(private-key): implement transaction handling and error verification for private key storage operations 2025-09-09 16:46:38 +02:00
Andras Bacsai
a7671ed379 refactor(dns-validation): rename DNS validation functions for consistency and clarity, and remove unused code 2025-09-09 09:00:35 +02:00
Andras Bacsai
579cc25898 fix(ssh): introduce SshRetryHandler and SshRetryable trait for enhanced SSH command retry logic with exponential backoff and error handling 2025-09-07 17:17:35 +02:00
saurabhraghuvanshii
3c126927d5 enhancement: allow deploy from container image hash 2025-08-28 02:10:14 +05:30
Andras Bacsai
cde528bf5e fix(parsers): enhance volume string handling by preserving mode in application and service parsers. Update related unit tests for validation. 2025-08-27 16:54:49 +02:00
Andras Bacsai
5fbad08e45 fix(parsers): implement parseDockerVolumeString function to handle various Docker volume formats and modes, including environment variables and Windows paths. Add unit tests for comprehensive coverage. 2025-08-27 16:39:38 +02:00
Andras Bacsai
990331cd74 feat(validation): add ValidIpOrCidr rule for validating IP addresses and CIDR notations; update API access settings UI and add comprehensive tests 2025-08-26 10:27:38 +02:00
Andras Bacsai
42bdc2a5fd refactor(docker compose): remove deprecated newParser function and associated test file to streamline codebase 2025-08-17 18:03:00 +02:00
Andras Bacsai
8e8400f595 feat(utf8-handling): implement UTF-8 sanitization for command outputs and enhance error handling in logs processing 2025-06-05 14:27:39 +02:00
Andras Bacsai
c97415a8ef chore(tests): update test environment database name and add new feature test for converting container environment variables to array 2025-05-22 14:30:16 +02:00
Andras Bacsai
78ef80f800 refactor 2025-04-23 13:22:01 +02:00
Andras Bacsai
e4648bcf9c feat(docker): add HTTP Basic Authentication support and enhance hostname parsing in Docker run conversion 2025-04-23 11:57:26 +02:00
Andras Bacsai
8520beff51 refactor(docker): remove debug statement and enhance hostname handling in Docker run conversion 2025-04-23 11:21:37 +02:00
Andras Bacsai
27e4882d57 feat(core): You can validate compose files with docker compose config
fix(core): labels are now accepted with both compose styles
refactor: remove lots of ray's
2025-02-27 11:29:04 +01:00
Andras Bacsai
57f61d4589 fix: docker image parser 2025-01-20 13:59:02 +01:00
Andras Bacsai
15ac12e131 test: setup database for upcoming tests 2024-12-04 12:43:52 +01:00
Andras Bacsai
327b4308d4 fix: add tests for git url converts 2024-11-12 11:32:18 +01:00
Andras Bacsai
47cd8f9e13 fix: for --gpus device support 2024-11-06 12:26:05 +01:00
Andras Bacsai
ff6f089483 feat: add --gpu support for custom docker command 2024-11-06 10:13:40 +01:00
Andras Bacsai
2eef8ee433 add dusk tests 2024-10-28 22:57:56 +01:00
Lucas Michot
d557a22b91 Remove all ray() calls 2024-10-28 13:51:23 +01:00
Andras Bacsai
3835dc3fd7 Refactor DuskTestCase.php to use a hardcoded base URL 2024-10-17 21:26:06 +02:00
Andras Bacsai
cbff462a5a Refactor Chrome Driver port in browser-tests.yml and DuskTestCase.php 2024-10-17 21:20:55 +02:00