Commit Graph
5736 Commits
Author SHA1 Message Date
Andras Bacsai ed3780b2a7 fix(schedule): run stale multiplex cleanup on crons queue
Dispatch CleanupStaleMultiplexedConnections through the crons queue and
cover the scheduled job queue assignment with a feature test.
2026-05-26 13:51:22 +02:00
Andras Bacsai ebf23f4874 fix(ssh): escape scp source and destination
Quote SCP operands when building commands to prevent shell injection through source or destination paths, and cover the escaping behavior in the SSH command injection tests.
2026-05-26 13:48:10 +02:00
Yaroslav Novykov 36bf068814 fix(api): apply private_key_uuid in update_server
The endpoint validated private_key_uuid but dropped it from the update,
so the request silently no-op'd. Resolve the UUID to a team-scoped
PrivateKey and include private_key_id in the update payload.
2026-05-26 12:57:42 +03:00
Andras Bacsai 8a40c4e348 chore(sync-bunny): remove GitHub release sync paths
Drop the unused GitHub release and version sync options from sync:bunny,
leaving the command focused on BunnyCDN template, release, and nightly syncs.
Update the nightly test to assert it does not invoke gh or git.
2026-05-26 11:51:38 +02:00
Rohit Tiwari 07337d9df6 feat: add search functionality for environment variables 2026-05-26 15:19:32 +05:30
Andras Bacsai 21db1fd374 fix(sync-bunny): sync nightly CDN files to nested paths
Write nightly versions and releases under json/nightly in the CDN repo, and cover both release and versions-only sync flows with feature tests.
2026-05-26 11:41:04 +02:00
Andras Bacsai 8e6e3551f3 fix(ui): improve configuration changes modal values, colors and spacing (#10365) 2026-05-26 11:09:54 +02:00
Andras Bacsai 27b76a4e97 Merge remote-tracking branch 'origin/next' into fix/form-state 2026-05-25 16:08:19 +02:00
Poul 68e9184b57 fix(api/destinations): use whereHas instead of ownedByCurrentTeamAPI for back-compat
The ownedByCurrentTeamAPI scope was added to StandaloneDocker/SwarmDocker
*after* 4.0.0-beta.470 — running containers on that beta hit a
BadMethodCallException. Rewrites all team scoping to use
whereHas('server', whereTeamId) which works against any v4.x of
Coolify (StandaloneDocker.server_id -> Server.team_id has been there
since the multi-team change).

Also guards attachedTo() with method_exists and falls back to a manual
attached-resource check covering applications + every standalone DB
relation, so delete() doesn't crash on older versions either.
2026-05-25 11:47:10 +00:00
Poul 789e2c5cab fix(api/destinations): use getTeamIdFromToken() like other Api controllers
Initial draft called auth()->user()->currentTeam() which returns null in
the API context (Sanctum tokens don't carry the per-user currentTeam
state — that's a session/Livewire concept). Other Api controllers
(ServersController, ScheduledTasksController, etc.) use the canonical
helper getTeamIdFromToken() with a null guard returning 403.

This swap makes all five endpoints work against a real token.
2026-05-25 11:36:26 +00:00
Poul fe855cf8d0 feat(api): add REST endpoints for destinations
The Destinations section is exposed in the Coolify UI but not via the
REST API. The destination_uuid field is required when creating
applications via create-public-application, but no way to enumerate or
create destinations programmatically existed — this blocks IaC tools
(e.g. an Aspire publisher targeting Coolify).

Adds, scoped to the existing v1 auth:sanctum + ApiAllowed + api.sensitive
group:

  GET    /api/v1/destinations
  GET    /api/v1/destinations/{uuid}
  DELETE /api/v1/destinations/{uuid}
  GET    /api/v1/servers/{server_uuid}/destinations
  POST   /api/v1/servers/{server_uuid}/destinations

The controller uses the existing inline-Validator convention (no Form
Request classes per the API surface's house style), reuses
StandaloneDocker::ownedByCurrentTeamAPI / SwarmDocker::ownedByCurrentTeamAPI
for team scoping (matching ScheduledTasksController etc.), and respects
the `attachedTo()` guard on delete.

No migrations needed — both standalone_dockers and swarm_dockers tables
already carry uuid/name/network/server_id/timestamps.

OpenAPI @OA\ annotations omitted in this commit to keep the diff
minimal; a follow-up can add them in the style of ServersController.
2026-05-25 11:15:08 +00:00
Andras Bacsai 33e172ac24 fix(backups): revalidate S3 storage on scheduled backup submit
Check the selected S3 storage against the database at submit time so
stale Livewire state cannot schedule backups with storage that was
reassigned or marked unusable after the component mounted.
2026-05-23 21:06:22 +02:00
Andras Bacsai a4d75ff0e2 fix(backups): validate S3 storage before backup scheduling
Prevent scheduled database backups from enabling S3 uploads without a valid team-owned storage configuration, and preserve the previous S3 storage ID in missing-storage error messages.

Add coverage for backup edit/create validation and S3 upload failure messaging.
2026-05-23 13:06:36 +02:00
Andras Bacsai a058786509 fix(ssh): remove mux first-use lock wrapper
Rely on OpenSSH lazy multiplexing directly for SSH and SCP commands,
removing the shell lock wrapper and related readiness checks.
2026-05-22 18:27:40 +02:00
Andras Bacsai a13fb3cf00 fix(ssh): verify mux readiness before reusing socket
Use ssh -O check in the first-use mux lock flow so commands only reuse a multiplexed socket after the control master is actually ready.
2026-05-22 18:22:22 +02:00
Andras Bacsai 5c67766f41 fix(ssh): serialize initial mux connection creation
Wrap first-use SSH and SCP multiplexed commands with a lock to avoid racing while the control socket is created. Also detect native OpenSSH mux master process names during stale connection cleanup and cover both orphaned and duplicate mux processes with tests.
2026-05-22 18:17:37 +02:00
Andras Bacsai 54a020cf1b fix(ssh): rely on lazy multiplexed connections
Remove explicit SSH master pre-warming and lock handling so OpenSSH manages ControlMaster creation lazily from real ssh/scp commands. Add cleanup for duplicate mux processes and update coverage around mux command options and stale process cleanup.
2026-05-22 18:01:53 +02:00
ShadowArcanist bd744eb8dd fix(ui): configuration changes modal values, colors and spacing 2026-05-22 21:22:50 +05:30
Andras Bacsai 57d879263d fix(ssh): prevent orphaned multiplexed connections
Serialize multiplexed SSH master creation per server to avoid concurrent workers spawning orphaned processes. Enable scheduled cleanup for stale mux connections and add guarded orphan process reaping with tests.
2026-05-22 17:31:38 +02:00
Andras BacsaiandClaude Opus 4.7 5a7408a919 fix(github): improve GitHub App setup and installation flow
- resolve the GitHub App by a stable identifier during installation
  callbacks so installing and re-installing keeps working over the
  full lifetime of the App
- verify the installation id received from the callback against the
  GitHub API before persisting it
- support re-installing an already configured GitHub App instead of
  blocking it
- require an authenticated session and rate limit the setup callback
  routes
- extend manifest setup state validity to match GitHub's manifest
  code lifetime

Adds feature coverage for the GitHub App setup and installation
callbacks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 16:34:36 +02:00
Andras Bacsai fcd63f40eb fix(queue): route scheduled jobs through crons helper
Centralize scheduled job queue selection with crons_queue() and use it for scheduler, task, and database backup jobs so cloud runs on crons while self-hosted stays on high.
2026-05-22 16:26:15 +02:00
Andras Bacsai e2199f1223 fix(queue): route cloud jobs to dedicated queues
Use config-based queue selection for deployment and scheduled jobs so cloud dispatches deployments to `deployments` and scheduled jobs to `crons`, while self-hosted keeps using `high`.

Add coverage for deployment queue helper, start action routing, and scheduled job manager routing.
2026-05-22 16:11:24 +02:00
Andras BacsaiandClaude Opus 4.7 809d9b21fa fix(webhook): match manual webhook repositories case-insensitively
Git hosts treat owner/repo names case-insensitively, but the exact
repository match used a case-sensitive comparison, so a payload whose
casing differed from the stored git remote would fail to match and
skip a legitimate deployment.

Lowercase both canonical repository paths before comparing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 15:59:20 +02:00
Andras BacsaiandClaude Opus 4.7 c1518ba1c0 fix(webhook): match manual webhook repositories exactly
The manual webhook handlers selected target applications with a
`git_repository LIKE %full_name%` substring query, so a payload
repository name could match unintended applications when repository
names overlap.

Add a `MatchesManualWebhookApplications` trait that validates the
incoming `owner/repo` value and matches `Application.git_repository`
by exact normalized path. Github, Gitlab, Gitea and Bitbucket manual
handlers now use it, reject invalid repository input early, and return
a consistent generic webhook failure payload.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 15:32:44 +02:00
Andras Bacsai 00ce43a9d0 Refine service resource routing (#10358) 2026-05-22 13:40:18 +02:00
Andras Bacsai beaad0a722 Refine service resource routing 2026-05-22 13:39:26 +02:00
Andras Bacsai 7f135e0f6d Harden token permission handling 2026-05-22 13:12:17 +02:00
Andras Bacsai e9b8320d5f Fix source selection flow 2026-05-22 13:00:53 +02:00
Andras Bacsai 783344c875 fix(environment): scope DeleteEnvironment lookups to current team (#10349) 2026-05-22 12:57:57 +02:00
Andras BacsaiandClaude Opus 4.7 59111e8cf3 fix(destination): scope server and network selection to current team
Resolve the server and network in Destination::addServer() and
::promote() through ownedByCurrentTeam() before use, authorize the
update against the resource, and pass the validated IDs into
attach()/detach()/update(). Errors are routed through handleError()
to match the sibling removeServer() method.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:53:14 +02:00
Andras Bacsai 36526928df feat(sentinel): deduplicate metrics push processing
Move Sentinel push handling into a controller and dispatch server update jobs only when container state changes or the force interval elapses. Add opt-in PostgreSQL read/write replica configuration and tune periodic proxy network and storage checks to reduce unnecessary work.

Add feature coverage for replica config, Sentinel push deduplication, deployment log scrolling, and server update job optimizations.
2026-05-22 12:48:48 +02:00
Andras BacsaiandClaude Opus 4.7 df166ac689 fix(environment): scope DeleteEnvironment lookups to current team
Scope DeleteEnvironment::mount() and delete() lookups through
Environment::ownedByCurrentTeam() so an environment_id that belongs to
another team resolves to a 404 instead of loading the foreign record.
Mark $environment_id as #[Locked] so the public Livewire property can no
longer be reassigned from the client.

Add tests/Feature/DeleteEnvironmentTeamScopingTest.php covering mount,
delete, the #[Locked] guard, and the team-scoped helper for both the
cross-team and own-team cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:37:48 +02:00
Andras BacsaiandClaude Opus 4.7 5dda39e588 fix(source): scope private key and source selection to current team
The Source component now resolves the supplied private key and Git
source IDs through team-scoped queries before persisting them, so a
selection can only ever reference a resource owned by the current
team. The source type is additionally restricted to the supported
GitHub/GitLab app classes.

The privateKeyId property is marked #[Locked] so it can only change
through the dedicated handler rather than a direct property update.

Adds feature tests covering team-scoped selection of private keys and
Git sources.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:30:00 +02:00
Andras Bacsai b124397613 fix(schedule): prevent duplicate SSL certificate regeneration
Run RegenerateSslCertJob on one server only and add coverage to ensure scheduled production jobs use onOneServer.
2026-05-21 19:19:43 +02:00
Aditya Tripathi 7a3fcd37d5 fix(livewire): scope DatabaseProxyStopped to proxy fields, harden status trait
Clickhouse, Dragonfly, and Keydb still called syncData() inside the
DatabaseProxyStopped broadcast handler, clobbering in-progress edits to
name/description/credentials. Refresh only is_public/public_port/
public_port_timeout instead, matching the pattern used elsewhere.

Also null-guard HasDatabaseStatusInfo::getListeners() against an absent
Auth::user()/currentTeam(), add explicit return types on getListeners()
and render(), and convert inline comments in the SSL refresh test to a
PHPDoc block.
2026-05-21 10:24:49 +00:00
Aditya Tripathi e7e65831a7 fix(livewire): preserve wire:dirty across DB status broadcasts
The earlier refreshStatus fix kept user-typed values intact but Livewire still
absorbed deferred wire:model values into the snapshot on every broadcast-
triggered roundtrip, clearing the unsaved-changes indicator and making the form
look auto-saved. Move all status-derived display (DB URLs, SSL toggle/mode,
cert expiry) out of each DB General form into a sibling StatusInfo Livewire
component, so the form never roundtrips on broadcasts.

Shared scaffolding lives in App\Traits\HasDatabaseStatusInfo plus an x-database-
status-info Blade component, leaving each per-DB StatusInfo class as a ~20-50
line declaration of label, SSL mode options, and SSL save hooks. Parents
dispatch databaseUpdated from save methods so the sibling refreshes after writes.

Tests cover the architecture (no DB form subscribes to status broadcasts) and
the sibling's refresh-on-status-change behavior.
2026-05-21 08:31:08 +00:00
Aditya Tripathi b9f773c1d9 fix(livewire): stop broadcast handlers from wiping in-progress form input 2026-05-20 19:04:43 +00:00
Andras Bacsai 65c0c92c02 fix(destinations): handle empty and server-scoped destinations
Build the global destinations list from actual destination records so empty
servers do not render duplicate empty states. Allow creating Docker destinations
for a selected team server outside the global usable list, authorize swarm
creation correctly, and store discovered swarm network names from the selected
network. Add feature coverage for empty states, selected-server mounting, and
swarm destination creation.
2026-05-19 12:50:08 +02:00
Andras Bacsai d1126c02a9 fix(deployments): filter generated compose service env vars
Exclude generated Docker Compose SERVICE_FQDN, SERVICE_URL, and SERVICE_NAME variables from runtime, build-time, and build arg environments so stale stored values cannot override generated service names for preview deployments.
2026-05-13 11:59:45 +02:00
Andras Bacsai a54e70b4e0 fix(deployments): skip registry image tag for previews
Only push the configured Docker registry image tag for production deployments, and cover preview and missing-tag cases with unit tests.
2026-05-13 11:49:15 +02:00
Andras Bacsai 6ab88c46b2 Merge remote-tracking branch 'origin/next' into audit-policies 2026-05-13 11:15:29 +02:00
Andras Bacsai 4ff3e4b2be feat(deployments): track application configuration diffs (#10183) 2026-05-13 10:49:53 +02:00
Andras Bacsai 1522c510cf fix(api-tokens): mark expiration warning after notification
Ensure failed token expiration warning notifications do not persist the warning marker, allowing the job to retry later.
2026-05-13 10:28:32 +02:00
Andras Bacsai df4d9f8069 fix(applications): use preview environment variable query
Call the preview environment variable relationship as a query when building the legacy configuration hash, and cover preview deployments with a regression test.
2026-05-13 10:28:18 +02:00
Andras Bacsai 3911a0305c fix(api-tokens): persist expiration warning state
Track when expiration warnings are sent on personal access tokens so repeated job runs or cache flushes do not send duplicate notifications.
2026-05-13 10:11:40 +02:00
Andras Bacsai 0ecd488d6a fix(applications): refresh pending configuration changes
Dispatch configuration change events after saving application source and advanced settings, and refresh the configuration checker before showing redeploy diffs.
2026-05-13 10:04:17 +02:00
Andras Bacsai f8849aba73 feat(deployments): track application configuration diffs
Store deployment configuration snapshots on application deployment queues and compare them against the current application state. Surface grouped pending changes in the configuration checker and use build-impact diffs to decide when an existing image can skip the build step.
2026-05-13 09:58:58 +02:00
Andras Bacsai d8972e97c9 fix(previews): clean up closed PR previews after update failures
Catch and report failures while updating closed pull request status so preview deployment cleanup still runs for closed GitHub pull request webhooks.

Add coverage for cleanup continuing when GitHub comment cleanup fails.
2026-05-13 09:31:28 +02:00
Andras Bacsai 63c2d31ca0 feat(applications): add configurable stop grace period
Add centralized stop grace period resolution for application settings and use it across manual stops, preview stops, and deployments. Validate the Livewire advanced setting against shared min/max constants and cover persistence, fillable creation, and fallback behavior with tests.
2026-05-11 23:43:53 +02:00
Andras Bacsai d1220895d9 Merge remote-tracking branch 'origin/next' into feat/configurable-stop-grace-period 2026-05-11 23:20:31 +02:00