Restrict mass-assignable attributes across user/team/redis models and
switch privileged root/team creation paths to forceFill/forceCreate.
Encrypt legacy ClickHouse admin passwords via migration and cast the
correct ClickHouse password field as encrypted.
Tighten API and runtime exposure by removing sensitive team fields from
responses and sanitizing Git/compose error messages.
Expand security-focused feature coverage for command-injection and mass
assignment protections.
Add strict validation for Docker network names using a regex pattern
that matches Docker's naming rules (alphanumeric start, followed by
alphanumeric, dots, hyphens, underscores).
Changes:
- Add DOCKER_NETWORK_PATTERN to ValidationPatterns with helper methods
- Validate network field in Destination creation and update Livewire components
- Add setNetworkAttribute mutator on StandaloneDocker and SwarmDocker models
- Apply escapeshellarg() to all network field usages in shell commands across
ApplicationDeploymentJob, DatabaseBackupJob, StartService, Init command,
proxy helpers, and Destination/Show
- Add comprehensive tests for pattern validation and model mutator
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract and return the billing interval (month/year) from subscription pricing
data in fetchPricePreview. Update the view to dynamically display the correct
billing period based on the preview response instead of using static PHP logic.
Escape dynamic error messages with htmlspecialchars() before
concatenating into HTML strings stored in validation_logs. Add a
Purify-based mutator on Server model as defense-in-depth, with a
dedicated HTMLPurifier config that allows only safe structural tags.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Inline PrepareCoolifyTask and CoolifyTaskArgs into remote_process(),
removing two single-consumer abstraction layers
- Add #[Locked] attribute to ActivityMonitor $activityId property
- Add team ownership verification in ActivityMonitor.hydrateActivity()
with server_uuid fallback and fail-closed default
- Store team_id in activity properties for proper scoping
- Update CLAUDE.md to remove stale reference
- Add comprehensive tests for activity monitor authorization
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add proper shell escaping for persistent volume names when used in
docker volume rm commands. Also add volume name validation pattern
to ValidationPatterns for consistent input checking.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add validation in GetProxyConfiguration to detect when stored proxy config
belongs to a different proxy type (e.g., Traefik config on a Caddy server)
and trigger regeneration with a warning log. Clear cached proxy configuration
and settings when proxy type is changed to prevent stale configs from being
reused. Includes tests verifying config rejection on type mismatch and
graceful fallback on invalid YAML.
- Record refunds immediately before cancellation to prevent retry issues if cancel fails
- Wrap Stripe API calls in try-catch for refunds and quantity reverts with internal notifications
- Add null check in Team.subscriptionEnded() to prevent NPE when subscription doesn't exist
- Fix control flow bug in StripeProcessJob (add missing break statement)
- Cap dynamic server limit with MAX_SERVER_LIMIT in subscription updates
- Add comprehensive tests for refund failures, event handling, and null safety
Add current_period_end to refund eligibility checks and display next billing
date and billing interval in the subscription overview. Refactor the plan
overview layout to show subscription status more prominently.
- Store proxy configuration in database as primary source for faster access
- Implement automatic timestamped backups when configuration changes
- Add backfill migration logic to recover configs from disk for legacy servers
- Simplify UI by removing loading states (config now readily available)
- Add comprehensive logging for debugging configuration generation and recovery
- Include unit tests for config recovery scenarios
Replace direct shell interpolation of environment values with base64 encoding
to prevent command injection attacks. Environment configuration is now built as
a single string, base64-encoded, then decoded to file atomically.
Also add regex validation to restrict environment field values to safe
characters (alphanumeric, underscore, hyphen, dot) at the application layer.
Fixes GHSA-3xm2-hqg8-4m2p
Centralize min/max server limits in Stripe quantity updates and wire them into
Livewire subscription actions with price preview/update handling.
Also improve host/proxy middleware behavior by trusting loopback hosts when FQDN
is set and auto-enabling secure session cookies for HTTPS requests behind
proxies when session.secure is unset.
Includes feature tests for loopback trust and secure cookie auto-detection.
Introduce a new `UpdateSubscriptionQuantity` Stripe action to:
- preview prorated due-now and next-cycle recurring costs
- update subscription item quantity with proration invoicing
- revert quantity and void invoice when payment is not completed
Wire the flow into the Livewire subscription actions UI with a new adjust-limit modal,
price preview loading, and confirmation-based updates. Also refactor the subscription
management section layout and fix modal confirmation behavior for temporary 2FA bypass.
Add `Subscription::billingInterval()` helper and comprehensive Pest coverage for
quantity updates, preview calculations, failure/revert paths, and billing interval logic.
- Fix disable logic: timeout editable when proxy is stopped
- Remove hardcoded proxy_connect_timeout (60s is nginx default)
- Remove misleading '0 for no timeout' helper text
- Add min:1 validation for timeout value
Adds a per-database 'Proxy Timeout' setting for publicly exposed databases.
The nginx stream proxy_timeout can now be configured in the UI, defaulting
to 3600s (1 hour) instead of nginx's 10min default. Set to 0 for no timeout.
Fixes#7743
Replace hardcoded 'debian' with ${ID} from /etc/os-release to use
the correct Docker repository for Ubuntu, Debian, and Raspbian servers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The proxy container was incorrectly named using the service UUID instead
of the database UUID, causing proxy logs to query the wrong container.
Each ServiceDatabase should have its own uniquely named proxy container.
When a database or application was in a restart loop, the restart count
persisted even after the user manually stopped the resource. This caused
the UI to continue showing "(Xx restarts)" after user intervention.
Now resets restart_count, last_restart_at, and last_restart_type when:
- User stops a database (StopDatabase action)
- User stops an application (StopApplication action)
The existing reset in GetContainersStatus is still needed for containers
that exit on their own (crash without recovery, Docker giving up).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Consolidate duplicate restart tracking logic in GetContainersStatus
- Add last_restart_type string cast to all 8 standalone database models
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix status flickering: Track databases in active/transient states (restarting, starting, created, paused) not just running
- Add isActiveOrTransient() helper to distinguish between active states and terminal states (exited, dead)
- Add safeguard: Protect updateNotFoundDatabaseStatus() from marking as exited when containers collection is empty
- Add restart_count tracking: New migration adds restart_count, last_restart_at, last_restart_type to all standalone database tables
- Update 8 database models with $casts for new restart tracking fields
- Update GetContainersStatus to extract RestartCount from Docker and update database models
- Reset restart tracking when database exits completely
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Show clear progress with numbered steps (1/6 through 6/6)
- Display header and footer banners
- Show individual image pull progress
- Show which containers are being stopped
- Display final success message with version and log location
- Keep detailed logging to file for debugging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Current version of infrastructure images (coolify-helper, coolify-realtime) are now protected from deletion during docker cleanup, regardless of which registry they're pulled from (ghcr.io, docker.io, or Docker Hub implicit). Old versions continue to be cleaned up as intended.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Add 429 response with Retry-After header for Hetzner server creation
- Create RateLimitException for proper rate limit error handling
- Rename cloud_provider_token_id to cloud_provider_token_uuid with deprecation
- Fix prices array schema in server-types endpoint with proper items definition
- Add explicit default: true to autogenerate_domain properties
- Add timeout and retry options to Docker install curl commands
- Fix race condition in deployment status update using atomic query
The method was defined twice with the first (outdated) definition using
-Syyy and lacking proper flags. Keep the improved version that uses -Syu
with --needed for idempotency and proper systemctl ordering.
Create a shared CleanupPreviewDeployment action that unifies PR cleanup logic across all Git providers. Previously, GitHub had comprehensive cleanup (cancels active deployments, kills helper containers, removes all PR containers), while GitLab, Bitbucket, and Gitea only did basic cleanup (delete preview record and remove one container by name).
This fix ensures all providers properly clean up orphaned PR containers when a PR is closed/merged, preventing security issues and resource waste. Also fixes early return bug in GitLab webhook handler.
Fixes#2610🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add explicit validation in UpdatePackage to require package name when
'all' is false, preventing empty package commands being sent to servers
- Add --needed flag to pacman install in InstallDocker for idempotent
Docker installation on Arch Linux
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>