Update property access in database components and Application model to
use snake_case conventions (common_name, subject_alternative_names)
for Eloquent attributes. Also add null-safe operators (?->) for
settings access in Application model to handle null values safely.
Add end-to-end support for `docker_registry_image_tag` in preview and deployment queue flows.
- Extend deploy API to accept `pull_request_id` alias and `docker_tag` for preview deploys
- Persist preview-specific Docker tags on `application_previews` and `application_deployment_queues`
- Pass tag through `queue_application_deployment()` and de-duplicate queued jobs by tag
- Update deployment job logic to resolve and use preview Docker tags for dockerimage build packs
- Update Livewire previews UI/state to manage per-preview tags and manual preview/tag inputs
- Add migration for new tag columns and model fillable/casts updates
- Add feature and unit tests covering API behavior and tag resolution
Prevent null CA certificate access during database SSL certificate regeneration
across KeyDB, MariaDB, MongoDB, MySQL, PostgreSQL, and Redis components.
If no CA certificate exists, attempt to generate one and re-query; if still
missing, dispatch a clear error and stop regeneration gracefully.
Add `SslCertificateRegenerationTest` coverage for missing-CA and CA-query
scenarios to prevent regressions.
Replace create() with forceCreate() across internal model creation operations to bypass mass assignment protection. This is appropriate for internal code that constructs complete model state without user input.
Add InternalModelCreationMassAssignmentTest to ensure internal model creation behavior is properly tested. Optimize imports by using shortened Livewire attribute references and removing unused imports.
Ensure that the uuid field is preserved during clone operations for persistent
volumes across all clone methods (CloneMe, ResourceOperations, and the clone_application
helper). This prevents UUID conflicts and ensures cloned volumes receive new unique
identifiers as intended.
Adds test coverage validating that cloned persistent volumes receive new UUIDs
distinct from the original volumes.
Assign the selected redirect option before validation so valid changes are saved.
Add feature tests to verify redirect persistence and rejection when no www domain exists.
Use firstOrFail() for team-scoped project and environment lookups across
new-project Livewire flows so missing or cross-team UUIDs fail closed.
Also dispatch an error when boarding selects a non-owned project, and
update IDOR feature tests for the new error/exception behavior.
Replace $guarded = [] with explicit $fillable whitelists across all
models. Update controllers to use request->only($allowedFields) when
assigning request data. Switch Livewire components to forceFill() for
explicit mass assignment. Add integration tests for mass assignment
protection.
Ensure Server and Project lookups in Livewire components and API
controllers use team-scoped queries (ownedByCurrentTeam / whereTeamId)
instead of unscoped find/where calls. This enforces consistent
multi-tenant isolation across all user-facing code paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Add #[Locked] attributes to security-sensitive properties (resource, servicesubtype,
server, container) to prevent client-side modification via Livewire wire protocol.
Add container name validation using ValidationPatterns::isValidContainerName() and
server ownership authorization via Server::ownedByCurrentTeam() in both getLogs()
and downloadAllLogs() methods.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add shellSafeCommandRules() validation to install_command, build_command,
and start_command fields in both the Livewire UI and REST API layers.
These fields previously accepted arbitrary strings without validation,
unlike other shell-adjacent fields which already used this pattern.
Also adds comprehensive tests for rejection of dangerous input and
acceptance of legitimate build commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the admin panel route into the existing auth middleware group and
replace client-side redirects with server-side abort calls in the
Livewire component. Extract shared authorization logic into reusable
private methods.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SafeWebhookUrl validation rule to notification webhook URL fields
(Slack, Discord, custom webhook) to enforce safe URL patterns including
scheme validation and hostname checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Add SafeExternalUrl validation rule that ensures URLs point to
publicly-routable hosts. Apply to all GitHub source entry points
(Livewire Create, Livewire Change, API create and update).
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>
Ensure all file volume paths are validated and properly escaped before
use. Previously, only directory mount paths were validated at the input
layer — file mount paths now receive the same treatment across Livewire
components, API controllers, and the model layer.
- Validate and escape fs_path at the top of saveStorageOnServer() before
any commands are built
- Add path validation to submitFileStorage() in Storage Livewire component
- Add path validation to file mount creation in Applications, Services,
and Databases API controllers
- Add regression tests for path validation coverage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add container name validation and shell argument escaping to
startUnmanaged, stopUnmanaged, restartUnmanaged, and restartContainer
methods, consistent with existing patterns used elsewhere in the
codebase.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, the SHELL_SAFE_COMMAND_PATTERN was overly restrictive and blocked
legitimate characters needed for common Docker operations:
- Allow & for command chaining with && in multi-step build commands
- Allow " for build arguments with spaces (e.g., --build-arg KEY="value")
Update validation messages to reflect the new allowed operators and refactor
code to use imports instead of full class paths for better readability.
- Add #[Locked] to server-set properties on Import component (resourceId,
resourceType, serverId, resourceUuid, resourceDbType, container) to
prevent client-side modification via Livewire wire protocol
- Add container name validation in runImport() and restoreFromS3()
using shared ValidationPatterns::isValidContainerName()
- Scope server lookup to current team via ownedByCurrentTeam()
- Consolidate duplicate container name regex from Import,
ExecuteContainerCommand, and Terminal into shared
ValidationPatterns::isValidContainerName() static helper
- Add tests for container name validation, locked attributes, and
team-scoped server lookup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add validateDatabasesBackupInput() helper that properly parses all
database backup formats including MongoDB's "db:col1,col2|db2:col3"
and validates each component individually.
- Validate and escape collection names in DatabaseBackupJob
- Replace comma-only split in BackupEdit with format-aware validation
- Add input validation in API create_backup and update_backup endpoints
- Add unit tests for collection name and multi-format validation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add team-scoped server validation to domains_by_server API endpoint
- Filter applications and services to only those on the requested server
- Scope ActivityMonitor activity lookups to the current team
- Fix query param disambiguation (query vs route param) in domains endpoint
- Fix undefined $ip variable in services domain collection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace manual subscription create/update logic with updateOrCreate() and firstOrCreate() to eliminate race conditions
- Add validation in PricingPlans to prevent subscribing if team already has active subscription
- Improve error handling for missing team_id in customer.subscription.updated event
- Add tests verifying subscriptions are updated rather than duplicated
Extract build_railpack_static_image() into its own method, prevent port
override when is_static is set, bump Railpack to 0.22.0, and improve
test setup with beforeEach and correct polymorphic env var fields.
Add early return in refresh() to skip sync operations if the environment variable no longer exists or is not fresh, preventing errors when refreshing stale or deleted variables.
- Add column selection to breadcrumb queries for better performance
- Remove unused Alpine.js state (activeRes, activeMenuEnv, resPositions, menuPositions)
- Simplify dropdown logic by removing duplicate state handling in index view
- Change database relationship eager loading to use explicit column selection
Add ability to move backups between S3 storages and disable S3 backups.
Refactor storage resources view from cards to table layout with search
functionality and storage selection dropdowns.
Group backup schedules by their parent database (type + ID) for better
organization in the UI. Filter to only display backups with save_s3
enabled. Restructure the template to show database name as a header with
nested backups underneath, allowing clearer visualization of which
backups belong to each database. Add key binding to livewire component
to ensure proper re-rendering when resources change.
Add new Resources tab to storage show page displaying backup schedules using
that storage. Refactor storage show layout with navigation tabs for General
and Resources sections. Move delete action from form to show component.
Implement cascade deletion in S3Storage model to automatically disable S3
backups when storage is deleted. Improve error handling in DatabaseBackupJob
to throw exception when S3 storage is missing instead of silently returning.
- New Storage/Resources Livewire component
- Add resources.blade.php view
- Add storage.resources route
- Move delete() method from Form to Show component
- Add deleting event listener to S3Storage model
- Track backup count and current route in Show component
- Add #[On('submitStorage')] attribute to form submission
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.
- Restrict "Add suffix for PR deployments" checkbox to non-service
resources in both shared and service file-storage views
- Replace condition `is_preview_deployments_enabled` with `!$isService`
for PR suffix visibility in storages/show.blade.php
- Fix FileStorage::instantSave() to use authorize + syncData instead
of delegating to submit(), preventing unintended side effects
- Add $this->validate() to Storages/Show::instantSave() before saving
- Add response content schemas to storages API OpenAPI annotations
- Add additionalProperties: false to storage update request schema
- Rewrite PreviewDeploymentBindMountTest with behavioral tests of
addPreviewDeploymentSuffix instead of file-content inspection
Add `is_preview_suffix_enabled` flag to `local_file_volumes` and
`local_persistent_volumes` tables, allowing per-volume control over
whether a `-pr-N` suffix is appended during preview deployments.
Defaults to `true` to preserve existing behavior. Users can disable
it for volumes containing shared config or repository scripts that
should not be isolated per PR.
Server metadata is now automatically gathered when server validation completes successfully, both in the async job and Livewire component. This ensures server details (OS, CPU count, etc.) are populated immediately after validation passes, improving the user experience without requiring manual metadata fetching.
Tests added to verify gatherServerMetadata is called on successful validation and skipped when validation fails.
Add ability to force delete servers along with their defined resources:
- API: Accept ?force=true query parameter in DELETE /servers endpoint
- UI: Display checkbox option to delete all resources in deletion dialog
When force deletion is enabled, all associated resources are dispatched
via DeleteResourceJob before the server is removed, enabling one-step
deletion instead of requiring manual resource cleanup first.
- Add -i flag to explicitly specify ssh key path in git ls-remote operations
- Remove static $rules properties in favor of dynamic rules() method
- Fix test syntax error
Add ability to gather and display server system information including OS, architecture, kernel version, CPU count, memory, and uptime. Includes:
- New gatherServerMetadata() method to collect system details via remote commands
- New refreshServerMetadata() Livewire action with authorization and error handling
- Server Details UI section showing collected metadata with refresh capability
- Database migration to add server_metadata JSON column
- Comprehensive test suite for metadata collection and persistence
- Add `$selectedActions = []` parameter to delete/remove methods in multiple
Livewire components to support optional deletion actions
- Return error message string when password verification fails instead of
silent return
- Return `true` on successful deletion to indicate completion
- Handle selectedActions to set component properties for cascading deletions
(delete_volumes, delete_networks, delete_configurations, docker_cleanup)
- Add test coverage for Danger component delete functionality with password
validation and selected actions handling
- 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
Add regex validation to dockerfileLocation and dockerComposeLocation fields to
ensure they contain only valid path characters (alphanumeric, dots, hyphens, and
slashes) and must start with /. Include custom validation messages for clarity.
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
Add validateGitRef() helper function that uses an allowlist approach to prevent
OS command injection through git commit SHAs, branch names, and tags. Only allows
alphanumeric characters, dots, hyphens, underscores, and slashes.
Changes include:
- Add validateGitRef() helper in bootstrap/helpers/shared.php
- Apply validation in Rollback component when accepting rollback commit
- Add regex validation to git commit SHA fields in Livewire components
- Apply regex validation to API rules for git_commit_sha
- Use escapeshellarg() in git log and git checkout commands
- Add comprehensive unit tests covering injection payloads
Addresses GHSA-mw5w-2vvh-mgf4
Update server limit enforcement to re-enable force-disabled servers when the
team is at or under its limit (`<= 0` condition).
Improve allowlist validation and matching by:
- supporting IPv6 CIDR mask ranges up to `/128`
- adding IPv6-aware CIDR matching in `checkIPAgainstAllowlist`
- normalizing/deduplicating redundant allowlist entries before saving
Add feature tests for `ServerLimitCheckJob` covering under-limit, at-limit,
over-limit, and no-op scenarios.
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.
The modal stayed open because runImport() and restoreFromS3() did not
accept the password parameter, verify it, or return true on success.
Added password verification and return values to both methods.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move expensive runtime checks (service/application status) after cron
validation to avoid running them for tasks that aren't due. Critical
checks (orphans, infrastructure) remain in first phase.
Also fix database heading parameters to be built from the model.
- Refactor shouldRunNow() to only fire on first run (empty cache) if actually due by cron schedule, preventing spurious executions after cache loss or service restart
- Add enrichSkipLogsWithLinks() method to fetch and populate resource names and links for tasks, backups, and docker cleanup jobs in skip logs
- Update skip logs UI to display resource column with links to related resources, improving navigation and context
- Add fallback display when linked resources are deleted
- Expand tests to cover both restart scenarios: non-due jobs (should not fire) and due jobs (should fire)
- Implement pagination for skipped jobs display with 20 items per page
- Add pagination controls (previous/next buttons) to the scheduled jobs view
- Exclude ScheduledJobManager "started" events from run logs, keeping only "completed" events
- Add ShouldBeEncrypted interface to ScheduledTaskJob for secure queue handling
- Update log filtering to fetch 500 recent skips and slice for pagination
- Use Log facade instead of fully qualified class name
- 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
Remove the ServiceChecked event listener that triggered a full
component re-render every 10 seconds via the heading's wire:poll.
The heading component already handles status display independently,
so the task edit form does not need to re-render on status checks.
Fixes#8647
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
- Add regex validation to restrict allowed characters (alphanumeric, spaces, and specific safe symbols)
- Enforce maximum 1000 character limit on healthcheck commands
- Strip newlines and carriage returns to prevent command injection
- Change input field from textarea to text input in UI
- Add warning callout about prohibited shell operators
- Add comprehensive validation tests for both valid and malicious command patterns
- Refactor server IP duplicate detection to use `first()` instead of `get()->count()`
- Add team-scoped validation to distinguish between same-team and cross-team IP conflicts
- Update error messages to clarify ownership: "already exists in your team" vs "in use by another team"
- Apply consistent validation logic across API, boarding, and server management flows
- Add comprehensive test suite for IP uniqueness enforcement across teams
The instantSave method for the 'Make it publicly available' checkbox was
calling submitDatabase(), which saved all form fields. This caused
unintended saves when only toggling the public visibility. The
syncDatabaseData() call already handles saving the public toggle state.
- Introduced a new sidebar component for service database navigation.
- Updated routes for database import and backup functionalities.
- Refactored the database import view to improve clarity and maintainability.
- Consolidated service application and database views into a more cohesive structure.
- Removed deprecated service application view and integrated its functionalities into the service index.
- Enhanced user experience with modal confirmations for critical actions.
- Improved code readability and organization across various components.
The trim operation was happening after validation, which meant
whitespace was counted toward the max:255 validation rule. Now
input is normalized before validation, matching the pattern used
in Application and Service components.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Andras Bacsai <andrasbacsai@users.noreply.github.com>
Add visual feedback when downloading all logs in both container and deployment log views. Users now see an animated spinner and "Downloading..." text, preventing multiple concurrent downloads and improving UX during long operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Remove unused $server property and Server import from Advanced.php
- Add proper import for UpdateStripeCustomerEmailJob in User.php
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add trim() to FQDN in instantSave() method to prevent whitespace from being saved
- Add trim() to FQDN in submit() method before validation and DNS checks
- Prevents invalid HostSNI rules caused by leading/trailing whitespace
- Fixes issue where accidental whitespace from copy-paste causes deployment failures
Fixes#7797
Co-authored-by: Andras Bacsai <andrasbacsai@users.noreply.github.com>
- Adjusted indentation and formatting for better code clarity.
- Simplified conditional statements and removed unnecessary null checks.
- Enhanced user interface elements for Docker Compose and Dockerfile configurations.
- Improved handling of deployment commands and network settings.
- Updated helper texts for better user guidance.