v4.0.0-beta.474#9542
Merged
andrasbacsai merged 87 commits intov4.xfrom Apr 21, 2026
Merged
Conversation
basically moved advanced section from general page to it's own new page called advanced
it's basically an info for the end user about the port requirement, in the past we had some users confused by it like their domain works fine even without port number while the service port is 80
…f http we were setting a bad example by showing http because user will enter their domain in http and wonder why they cannot access their site over https, also user don't know how to use multiple domains with port numbers so covered it on this change as well
… deployments Database deployments generate bind mounts referencing the internal Docker volume path (/var/lib/docker/volumes/coolify_dev_coolify_data/_data) which doesn't exist in the testing-host container. This adds the missing volume mount so both /data/coolify and the Docker volume path resolve correctly. Fixes #9533 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a Rocky-specific Docker install path to the stable and nightly install scripts, using Docker's documented RHEL repository flow. Include a unit test to lock in the Rocky repo selection and command set.
Add the `amd_only` flag to the Cal.com service entry in both template JSON files so it is constrained to supported architecture.
Update the app version constant and synced version manifests for the latest beta release.
Reuse the existing SafeWebhookUrl rule on the S3 Storage endpoint field so the create and edit forms go through the same URL-normalization path as webhook settings. Adds a matching guard inside S3Storage::testConnection() so background callers (scheduled backups, database import reuse) also validate the endpoint before building the S3 client. Also fixes an IPv6-bracket edge case in SafeWebhookUrl so `http://[::1]` style hosts are normalized before the filter_var IP check — the rule's own loopback test was already asserting this behaviour.
… failures
Replace exception text in 5xx JSON responses with stable, action-specific
messages so API consumers get a consistent payload regardless of which
underlying client (Guzzle, PDO, filesystem) raised the exception. The
previous responses concatenated the raw upstream error, which produced
inconsistent messages and unnecessary noise for clients trying to parse
errors programmatically.
Touched endpoints:
- GET /api/v1/hetzner/{locations,server-types,images,ssh-keys}
- POST /api/v1/servers/hetzner
- DELETE /api/v1/databases/{uuid}/backups/{uuid}
- DELETE /api/v1/databases/{uuid}/backups/{uuid}/executions/{uuid}
- /download/backup/{uuid}
The RateLimitException branch and AuthenticationException flow keep their
existing curated messages.
Adds Pest coverage for the four Hetzner GET endpoints to lock the response
shape on upstream failure.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Constrain dev_helper_version to Docker tag grammar
([A-Za-z0-9_][A-Za-z0-9_.-]{0,127}), re-validate before triggering the
helper image build, and interpolate the image reference via
escapeshellarg() when composing the docker build command.
Strip advisory identifiers (GHSA-*) from describe blocks, test docblocks, and inline comments. Replace with plain descriptive labels. Also clean up FQCNs to use imported class names and minor style fixes (string concatenation spacing).
…ogin The invitation-link login path previously marked the account as email-verified as a side effect of authenticating, without the user ever proving control of the mailbox. Remove that branch so every account goes through the standard signed-URL verification flow. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move the email-verification URL hash from sha1 to sha256 and verify it directly in the controller using hash_equals, instead of going through Laravel's EmailVerificationRequest (which only compares against sha1). The signed URL still carries the authoritative HMAC; the hash upgrade keeps the identity binding aligned with modern hashing guidance. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Reject malformed --date values with a clear error before building any shell command, and wrap every interpolated value (log paths, filter expression, line count) in escapeshellarg() so filter options and date values can no longer break out of the tail/grep pipeline. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`||` caused config volumes to mount even when conf was null, since `!is_null(null)` is false but `!empty(null)` is true — condition always evaluated to true.
…form Replace CMD-SHELL string interpolation with CMD exec-form arrays in healthcheck configs for PostgreSQL, Dragonfly, KeyDB, and ClickHouse. CMD-SHELL passes the string to /bin/sh -c, allowing command injection through user-controlled fields (username, password, dbname). CMD exec-form bypasses the shell entirely — each value is a discrete argv element. Fixes GHSA-gvc4-f276-r88p. Adds regression tests covering semicolon, pipe, backtick, $(), background operator, redirect, newline, and null-byte injection vectors.
Add wrapper div around publicPort and publicPortTimeout inputs across all database general settings views for consistent vertical spacing.
…eck injection test
…/SSL arguments Add ValidationPatterns helpers for database identifiers and passwords, apply them across database Livewire components and the API controller, encode MongoDB init script values via json_encode, and pass the MySQL user through escapeshellarg when generating SSL chown commands.
Pattern enforcement now conditional on field being dirty (changed vs saved value). Prevents false validation failures when existing records hold legacy credential formats that pre-date the stricter regex rules.
…ations Add optional expiration to personal API tokens. Users pick a duration (1/7/30/60/90 days or Never) at creation time. Expired tokens are rejected by Sanctum, pruned hourly by sanctum:prune-expired, and a team notification fires ~24h before expiry so owners can rotate before API calls start failing. - ApiTokens Livewire component stores expires_at from expiresInDays - Rework issued-tokens UI from card grid to table (matches other views) - New ApiTokenExpirationWarningJob scheduled hourly (idempotent via RateLimiter) - New ApiTokenExpiringNotification (email/discord/telegram/slack/pushover) - api_token_expiring added to alwaysSendEvents so users cannot silence expiry warnings from the per-event notification toggle UI - sanctum:prune-expired cadence moved from daily to hourly Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Validate new init-script filenames against path traversal and shell metacharacters via a new validateFilenameSafe() helper, and harden the write/delete paths with basename() + escapeshellarg() so legacy rows still deploy and can be cleaned up without regressions. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Apply escapeshellarg() to the Postgres username before interpolating it into the chown command used to fix SSL certificate ownership, matching the handling already in place for StartMysql. This keeps the sink-side escaping consistent across database actions, independent of upstream input validation. Also adjusts an assertion in DatabaseSslCredentialEscapingTest to match the actual double-escaped output of executeInDocker, and adds Postgres regression cases for subshell and semicolon payloads.
Replace the flat character-class regex for SHELL_SAFE_COMMAND_PATTERN with a token-aware alternation. The parser now recognizes explicit tokens (`&&`, `||`, balanced single/double quotes, whitespace, and an unquoted safe-char run) instead of a bag of characters, which lets us extend the accepted grammar without loosening the guarantees. New surface area, with tests: - logical OR chaining (`make build || make clean`) - shell globs and bang (`rm *.tmp`, `cp src/?.js dist/`, `! grep -q foo`) - single-quoted arguments are now treated as balanced runs rather than rejected per-character Preserved surface area: - && chaining, balanced "..." and '...' quotes, the previous safe path / argument characters, and the existing error-path contract in ApplicationDeploymentJob::validateShellSafeCommand(). Also refreshes the user-facing validation messages in General.php so the allow/deny list shown on failure matches the new grammar. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's Changed
Security & Fixes
Improvements