Route all Coolify update artifacts (versions.json, upgrade.sh,
compose files) through updates.mapledeploy.ca instead of upstream
cdn.coollabs.io. Extend CI to publish artifacts to Bunny CDN
storage zone and purge cache on each build.
- Point CDN_URL, versions_url, upgrade_script_url to updates.mapledeploy.ca
- Hardcode helper/realtime images to ghcr.io (not mirrored to Forgejo)
- Pass registry_url as 3rd arg to upgrade.sh for main image pulls
- Adopt versioning scheme 4.0.0-beta.X.N (bump to 4.0.0-beta.463.1)
- Add CI steps: generate versions.json, upload to Bunny, purge cache
Replace Coolify branding with MapleDeploy throughout the UI: logos,
favicon, fonts (Overlock 900), color scheme, help links, and page
titles. Remove GitHub Actions workflows and add Forgejo CI build
workflow. Strip cloud-only features (subscription prompts, sponsor
links, server creation cloud options).
Pulls latest service-templates JSON files from `next` so cloud's hourly
PullTemplatesFromCDN job picks up queued template fixes (Jitsi, Plane,
Cap, Beszel, Langfuse, Twenty, Cal.com, etc.).
`templates/**` is in `paths-ignore` of coolify-production-build.yml so
no image rebuild triggered.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
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.
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>
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>
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.
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.