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