Commit graph

1408 commits

Author SHA1 Message Date
Andras Bacsai
973632b49c Merge remote-tracking branch 'origin/next' into audit-policies 2026-06-02 12:03:38 +02:00
Andras Bacsai
0038a8f5c9 Merge remote-tracking branch 'origin/next' into api-sensitive-data-scrubber 2026-06-02 11:57:13 +02:00
Andras Bacsai
6dae53a0e5 Merge remote-tracking branch 'origin/next' into fix/application-image-validation 2026-06-02 11:13:36 +02:00
Andras Bacsai
d72c1e2a47 fix(applications): harden image validation 2026-06-02 11:11:33 +02:00
Andras Bacsai
a511bd9b67 fix(api): validate token team context 2026-06-01 15:17:55 +02:00
Andras Bacsai
51062e73a6 fix(database): honor disabled standalone health checks
Skip Docker healthcheck configuration when standalone database health checks are disabled, and document default health check settings in the database API schema.
2026-06-01 08:55:03 +02:00
Andras Bacsai
4f053bf5b4 Merge remote-tracking branch 'origin/next' into 10444-database-healthchecks 2026-06-01 06:55:40 +02:00
Andras Bacsai
d423223d38 feat(database): configure standalone health checks
Add configurable health check settings for standalone databases and apply them to generated Docker Compose services. Allow disabling health checks and cover the behavior with feature tests.
2026-05-31 21:50:10 +02:00
Andras Bacsai
34f15c106c fix(webhook): match GitLab SSH repos with custom ports
Strip leading port segments from scp-style GitLab repository URLs so manual webhook matching compares the repository path consistently. Cover both ported and unported SSH URL forms.
2026-05-31 21:46:23 +02:00
ShadowArcanist
ab4b2045d4
fix(webhook): skip preview deployments for fork PRs when public previews are off 2026-05-29 23:53:51 +05:30
Julien Bouquillon
a0d3da372e
Merge branch 'v4.x' into api-application-preview-deployments 2026-05-28 10:26:02 +02:00
Andras Bacsai
626cfb4a22 fix(sentinel): reduce resource churn from health flaps
Ignore health status changes in Sentinel push deduplication when the container lifecycle state is unchanged.

Scope stale resource checks to Sentinel servers whose heartbeat is stale, and avoid refreshing resource last_online_at on unchanged statuses.
2026-05-27 16:48:38 +02:00
Andras Bacsai
9b996b4dc9 chore: inspect commit message guidance 2026-05-27 07:14:54 +02:00
Andras Bacsai
9f29df4cc3 fix(sentinel): accept empty container heartbeats
Allow Sentinel pushes with an empty containers array so servers with no
running containers still refresh their heartbeat and enqueue an update.
2026-05-26 17:31:27 +02:00
Andras Bacsai
b5be9fe9e8 fix(sentinel): lock push dedupe decisions
Guard Sentinel push hash checks and cache updates with a server-scoped atomic cache lock to prevent concurrent duplicate dispatches.
2026-05-26 14:12:56 +02:00
Andras Bacsai
7677fac2f5 fix(sentinel): validate push containers payload
Reject malformed sentinel push payloads before updating heartbeat state,
dispatching jobs, or writing deduplication cache entries.
2026-05-26 14:07:41 +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
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
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
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 Bacsai
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
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
seahurt
d3b76dfa93
fix: only strip git_host from repository_url when git_host is github.com 2026-05-19 14:10:17 +08:00
Julien Bouquillon
89d7672253 feat(api): add is_preview_deployments_enabled on applications 2026-05-13 13:09:18 +02:00
Andras Bacsai
fb13a6cdc0 fix(api): expose cloud tokens with sensitive read access
Show cloud provider token values only when the API request has sensitive
read permission, and cover read, read:sensitive, and root token behavior.
2026-05-13 11:29:48 +02:00
Andras Bacsai
6ab88c46b2 Merge remote-tracking branch 'origin/next' into audit-policies 2026-05-13 11:15:29 +02:00
Andras Bacsai
a42613168d fix(applications): store custom nginx config from API correctly
Decode base64 custom_nginx_configuration before model assignment so it is not double-encoded, and allow null values when clearing the setting. Add API coverage for create, update, invalid input, and clearing behavior.
2026-05-11 22:22:01 +02:00
Andras Bacsai
81a3bb0f07 fix(api): hide sensitive fields by default
Add model-level hidden fields for secrets, tokens, keys, notification
credentials, deployment logs, and environment values. Allow explicit
read:sensitive API access to reveal gated private keys and deployment logs,
and cover the behavior with feature and unit tests.
2026-05-11 21:18:07 +02:00
Andras Bacsai
c175d3d282 Merge remote-tracking branch 'origin/next' into audit-policies 2026-05-11 21:13:57 +02:00
Andras Bacsai
f40bb80f9d style(api): tighten nested server secret visibility checks 2026-05-11 20:52:29 +02:00
Andras Bacsai
b29bdce73a Merge remote-tracking branch 'origin/next' into api-sensitive-data-scrubber 2026-05-11 17:34:48 +02:00
Andras Bacsai
ab1958d741 fix(railpack): fail fast when buildx is unavailable
Require Docker buildx before Railpack builds, normalize environment
variable keys before validation, and align private deploy key API docs with
the supported dockerfile build pack.
2026-05-11 17:31:29 +02:00
Andras Bacsai
db7d0f0bfb Merge remote-tracking branch 'origin/next' into feat/railpack 2026-05-11 16:26:50 +02:00
Andras Bacsai
6ee75cfa65 fix(api): remove deprecated docker compose application endpoint
Drop the unstable applications/dockercompose route and controller path now that
service creation is handled by POST /api/v1/services. Add coverage to ensure the
deprecated endpoint stays unregistered while the services endpoint remains
available.
2026-05-11 13:20:05 +02:00
Andras Bacsai
12aba41d9a fix(api): gate service server secrets by sensitive scope
Only eager load nested server settings for service responses when the API token has read:sensitive, preventing read-only tokens from exposing sentinel fields while preserving sensitive access.
2026-05-11 11:53:22 +02:00
Andras Bacsai
c97f916052 fix(api): hide application compose PR fields
Add compose PR fields to the Application hidden attributes and allow database list queries to eager load nested server settings when sensitive access is permitted.
2026-05-11 11:46:05 +02:00
ShadowArcanist
ff4794ffec
fix(server): allow dots in ssh username 2026-05-06 21:21:37 +05:30
Andras Bacsai
fe934dd139 Merge remote-tracking branch 'origin/next' into feat/railpack 2026-05-06 14:33:22 +02:00
Andras Bacsai
0888198a81 Merge remote-tracking branch 'origin/next' into api-sensitive-data-scrubber 2026-05-05 22:09:34 +02:00
Andras Bacsai
45f65481e6 fix(mcp): change enable/disable endpoints from GET to POST and fix service/app listing
- `/mcp/enable` and `/mcp/disable` now use POST (state-mutating ops)
- `ListServices` queries DB directly instead of loading all projects into memory
- `ListApplications` validates tag arg rejects empty string (not just falsy)
2026-05-05 22:07:58 +02:00
Josh Salway
08a12c392a fix(deploy): cast force param as boolean to prevent cache bust on every deploy
$request->input('force') ?? false reads "false" as a non-empty string,
which PHP coerces to true. Replace with $request->boolean() which uses
filter_var(FILTER_VALIDATE_BOOLEAN), correctly mapping "false" -> false.
2026-05-02 23:11:22 +10:00
Andras Bacsai
8dc79f4ed6 fix(api): expose nested server secrets for privileged tokens
Add `exposeNestedServerSecrets()` to Applications, Databases, and
Services controllers so that `read:sensitive`/`root` tokens see
sentinel and logdrain fields on eager-loaded Server + ServerSetting
relations.

ServicesController handles both single models and Eloquent Collections
(listing endpoint passes a Collection per project).

Tests tightened to use JSON-key assertions (`"field":`) to avoid false
positives from field names appearing in values.
2026-04-30 11:49:15 +02:00
Andras Bacsai
8e91d627a3 Merge remote-tracking branch 'origin/next' into feat/railpack 2026-04-30 11:47:06 +02:00
Andras Bacsai
e828058755 Merge remote-tracking branch 'origin/next' into api-sensitive-data-scrubber 2026-04-30 11:30:50 +02:00
Andras Bacsai
d057ce5172 Merge remote-tracking branch 'origin/next' into mcp-server-instance-toggle 2026-04-30 11:30:45 +02:00
Andras Bacsai
8b7dbbafb2 fix(api): hide sensitive fields by default, expose via makeVisible for privileged tokens
Models now declare $hidden for passwords, tokens, db URLs, and compose
fields. API controllers flip from makeHidden-on-deny to makeVisible-on-
allow (can_read_sensitive=true), fixing fields that were never hidden.
Also adds missing fields (mysql/mariadb passwords, logdrain keys, etc.)
to privileged disclosure lists.

Tests added: Feature/Security/ApiSensitiveFieldsTest and
Unit/Models/SensitiveFieldsHiddenTest cover all affected models and
controllers.
2026-04-30 11:28:06 +02:00
Emmanuel Odinfono
e77e0761db
fix(backup): add .dmp to allowed extensions for database import (#9869) 2026-04-29 18:57:50 +02:00
Andras Bacsai
b8e311622a Merge remote-tracking branch 'origin/next' into feat/railpack 2026-04-29 15:22:47 +02:00
Andras Bacsai
7ab16ad7b5 feat(mcp): add MCP server with read-only tools for Coolify resources
Add Model Context Protocol server exposing Coolify infrastructure data
to AI assistants. Includes tools for listing/fetching servers, projects,
applications, databases, and services, scoped to authenticated team tokens.

- Add CoolifyServer with 10 read-only tools (list/get for all resource types)
- Add BuildsResponse and ResolvesTeam traits for shared tool logic
- Add EnsureMcpEnabled middleware guarding /mcp routes
- Add enable/disable MCP API endpoints (root-only)
- Add is_mcp_server_enabled toggle in instance settings and advanced UI
- Add migration for is_mcp_server_enabled column
- Add feature tests for MCP endpoints and toggle API
- Scrub sensitive keys (passwords, tokens, raw IDs) from all responses
2026-04-29 10:30:43 +02:00
Andras Bacsai
46180dbbf9 feat(webhook): skip deployment on [skip ci]/[skip cd] commit markers
Add DetectsSkipDeployCommits trait with two strategies: shouldSkipDeploy
(all commits must contain the marker) for push events, and
shouldSkipDeployAny (any single marker triggers skip) for PR/MR titles
and latest-commit signals.

Apply trait to Bitbucket, Gitea, GitHub, GitLab webhook controllers and
ProcessGithubPullRequestWebhook job. PRs pass pullRequestTitle through
to the job constructor for evaluation.
2026-04-29 09:12:24 +02:00
Andras Bacsai
9717d9ff5a Merge remote-tracking branch 'origin/next' into feat/railpack 2026-04-29 08:56:23 +02:00
Andras Bacsai
9bb819c33e feat(api): expose connection_timeout in servers API
Add connection_timeout to create_server docs, update_server allowed
fields, validation (integer 1-300), and advanced settings update path.
2026-04-28 15:43:58 +02:00
Jan Thiel
6637159d7b feat(hetzner): add support for enabling backups during server creation 2026-04-28 15:37:26 +02:00
Andras Bacsai
a2096c6f68 feat(observability): add structured audit log channel for API and webhook events
Introduce a dedicated `audit` log channel (daily rotation, configurable retention via
LOG_AUDIT_DAYS) and a small `auditLog()` / `auditLogWebhookFailure()` helper used to
record state-changing API operations and webhook events.

Instrumented:

- API mutation endpoints (create / update / delete / start / stop / restart) across
  applications, services, databases (incl. backups, env vars, storage), servers,
  projects + environments, scheduled tasks, private keys, GitHub apps, cloud provider
  tokens, Hetzner server provisioning, instance enable/disable.
- Webhook signature verification outcomes for GitHub, GitLab, Bitbucket, Gitea and
  Stripe, plus the Sentinel push endpoint.
- Authentication and authorization outcomes via the global exception handler and
  the `ApiAbility` middleware (unauthenticated, ability-denied, policy-denied).

The helper is wrapped in try/catch so logging failures never affect the request
path. Successful operations log at `info`; suspicious/denied requests log at
`warning`. Operators wanting a failures-only feed can set `LOG_AUDIT_LEVEL=warning`.

Includes a feature test suite covering the helper, the webhook providers and the
new auth/authorization log paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 14:50:37 +02:00
Andras Bacsai
5cef7cc092 Merge remote-tracking branch 'origin/next' into feat/railpack 2026-04-28 14:36:54 +02:00
Andras Bacsai
268c97d18f
fix(validation): allow decimals for database backups max storage (#9801) 2026-04-28 12:33:00 +02:00
Andras Bacsai
b4e139929e Merge remote-tracking branch 'origin/next' into fix/oauth-email-normalization 2026-04-27 14:56:16 +02:00
ShadowArcanist
593006be88
fix(validation): allow decimals for database backups max storage 2026-04-25 22:27:26 +05:30
Andras Bacsai
03313e54cc fix(database): enforce credential format validation and sanitize init/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.
2026-04-20 13:58:36 +02:00
Andras Bacsai
49b5472961 refactor(auth): upgrade email verification hash to sha256
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>
2026-04-20 12:09:48 +02:00
Andras Bacsai
9b37a1a7eb refactor(auth): drop implicit email verification on invitation link login
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>
2026-04-20 12:09:48 +02:00
Andras Bacsai
ea639dab8f
refactor(api): return stable generic error messages for 5xx responses (#9669) 2026-04-20 11:53:20 +02:00
Andras Bacsai
6a5fd40a5c refactor(policies): add uploadBackup ability and enforce it on backup upload endpoint
Introduce a dedicated `uploadBackup` ability on Application, Database,
Service, and ServiceDatabase policies (admin/owner only) and call
`$this->authorize('uploadBackup', $resource)` in `UploadController::upload`
so the backup-upload endpoint goes through the same policy layer as the
rest of the authorization refactor. Adds Pest coverage for each policy
variant plus HTTP-level checks.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 11:51:35 +02:00
Andras Bacsai
4d83688896 refactor(api): return generic error messages for upstream and storage 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>
2026-04-20 11:50:30 +02:00
Andras Bacsai
af0a8badb3 refactor(backup): validate database backup upload file type and size
Add allowlist of backup file extensions (sql, sql.gz, tar, tgz, zip,
dump, bak, bson, archive, bz2, xz, and compound variants) and enforce
a 10 GiB maximum file size on the backup upload endpoint. Validation
runs early on each chunk using the dropzone metadata and again on the
assembled file. Also drops the unused createFilename helper and the
commented-out S3 block.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 11:45:00 +02:00
Andras Bacsai
410a9a6195 refactor(volumes): validate input and escape shell args
Tighten validation on volume name and host path inputs across Livewire + API storage endpoints and escape shell arguments in volume clone and compose preview cleanup paths.
2026-04-20 11:27:10 +02:00
Andras Bacsai
1f9dd5326f Merge remote-tracking branch 'origin/next' into audit-policies
# Conflicts:
#	tests/Feature/DatabaseBackupCreationApiTest.php
2026-04-19 17:40:12 +02:00
Andras Bacsai
5019c8db92 fix(api): use explicit team ID for S3 storage lookup in backup endpoints
Replace `ownedByCurrentTeam()` (session-based) with `ownedByCurrentTeamAPI($teamId)`
(explicit team ID) when resolving S3 storage in create_backup and update_backup.
Session-based team resolution is unreliable in API context where auth is token-based.

Add `S3Storage::ownedByCurrentTeamAPI(int $teamId)` scope and update feature tests
to use real model instances instead of Mockery mocks.
2026-04-19 15:26:47 +02:00
Andras Bacsai
43f33d94ad Merge remote-tracking branch 'origin/next' into audit-policies
# Conflicts:
#	app/Http/Controllers/Api/SecurityController.php
#	app/Http/Controllers/Api/ServersController.php
#	app/Livewire/Admin/Index.php
#	app/Livewire/Destination/Show.php
#	app/Livewire/NavbarDeleteTeam.php
#	app/Livewire/Project/Application/Previews.php
#	app/Livewire/Project/DeleteProject.php
#	app/Livewire/Project/Shared/ResourceOperations.php
#	app/Livewire/Server/Resources.php
#	app/Livewire/Server/ValidateAndInstall.php
#	app/Livewire/Storage/Show.php
#	resources/views/livewire/dashboard.blade.php
#	resources/views/livewire/project/application/heading.blade.php
#	resources/views/livewire/project/database/heading.blade.php
#	resources/views/livewire/project/service/heading.blade.php
#	resources/views/livewire/project/shared/environment-variable/show.blade.php
#	resources/views/livewire/project/shared/scheduled-task/show.blade.php
#	tests/Feature/Security/TrustHostsMiddlewareTest.php
2026-04-19 15:19:37 +02:00
Andras Bacsai
371e883c75
refactor(api): validate and throttle feedback endpoint (#9653) 2026-04-19 14:50:03 +02:00
Andras Bacsai
5bf4bb9e80
feat(api): add DELETE endpoint for preview deployments by PR id (#9614) 2026-04-19 14:43:32 +02:00
Andras Bacsai
e7bbd45408 refactor(api): validate and throttle feedback endpoint
- Validate content (required string, min:10, max:2000) in OtherController@feedback
- Register 'feedback' named rate limiter (3/min per user or IP) in RouteServiceProvider
- Apply throttle:feedback middleware to POST /api/feedback
- Forward to Discord with allowed_mentions.parse=[] and a 5s HTTP timeout

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 14:41:47 +02:00
Andras Bacsai
bafb9a5a8b refactor(webhook): encrypt manual webhook secrets and tighten HMAC verification
- Auto-generate a 40-char random secret for each manual_webhook_secret_* column on Application creation so new apps are never left with an empty secret.
- Add encrypted cast for the four webhook-secret columns; backfill migration re-encrypts existing plaintext values and fills missing ones.
- Reject webhook deliveries when the stored secret is empty (GitHub, GitLab, Bitbucket, Gitea manual endpoints).
- Bitbucket: require the sha256 algorithm prefix on X-Hub-Signature instead of trusting the client-supplied algo.
- GitLab: drop the ?? '' fallback on the token comparison.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 12:52:23 +02:00
Andras Bacsai
33518b24a2
refactor: tighten team scoping on resource creation and admin nav (#9651) 2026-04-19 12:01:11 +02:00
Andras Bacsai
a478ac66eb refactor: scope destination and resource lookups by current team
Use find_destination_for_current_team helper across resource creation
flows and the destination controller. Pass full destination objects to
database creation helpers instead of UUIDs so team relationships are
resolved consistently before the resource is created or linked.

Add feature tests covering destination, backup storage, and resource
proof lookups across teams.
2026-04-19 11:55:12 +02:00
Jan Thiel
a4b27641c8 feat(hetzner): add endpoints and UI for attaching firewalls and internal networks to the Server Creation dialog 2026-04-19 06:12:50 +02:00
Andras Bacsai
bceb5f28dc feat(applications): add DELETE endpoint for preview deployments by PR id
Add `DELETE /api/v1/applications/{uuid}/previews/{pull_request_id}` to
cancel active deployments, stop containers, and delete the preview
record via `CleanupPreviewDeployment`. Includes OpenAPI annotations,
input validation, and full feature test coverage.
2026-04-17 13:29:11 +02:00
Andras Bacsai
451b7376ed Merge remote-tracking branch 'origin/next' into feat/railpack 2026-04-17 07:01:27 +02:00
Andras Bacsai
07c6b02a82 Merge remote-tracking branch 'origin/next' into jean/organize-service-ui 2026-04-14 10:52:01 +02:00
Tristan Rhodes
519a186e84 fix: normalize oauth emails before matching users 2026-04-09 09:38:56 -06:00
Andras Bacsai
f573ad28a0 Merge remote-tracking branch 'origin/next' into feat/railpack 2026-04-09 17:12:26 +02:00
Andras Bacsai
1a603a10ed fix(models): replace forceFill/forceCreate with fill/create and add fillable guards
Replace all uses of `forceFill`, `forceCreate`, and `forceFill` with their
non-force equivalents across models, actions, controllers, and Livewire
components. Add explicit `$fillable` arrays to all affected Eloquent models
to enforce mass assignment protection.

Add ModelFillableCreationTest and ModelFillableRegressionTest to verify that
model creation respects fillable constraints and prevent regressions.
2026-03-31 13:45:31 +02:00
Bakr Elsherif
2af16cd25e
Merge branch 'next' into next 2026-03-31 00:38:18 +03:00
Bakr
a77e91eca4 fix(api): return array from removeSensitiveData for service applications list 2026-03-30 22:14:34 +03:00
Andras Bacsai
179770d836
fix(validation): add input validation for server advanced settings page (#9242) 2026-03-30 21:01:28 +02:00
Andras Bacsai
b8fb29f9a8
fix(validation): add input validation for database backup timeout (#9245) 2026-03-30 20:59:37 +02:00
Tobias Thiele
7f46b2ed71 Populate docker_compose_domains for dockercompose apps
Add logic to populate docker_compose_domains in applicationParser
for dockercompose build packs, ensuring proper domain handling
for KEY-based SERVICE_FQDN variables.
2026-03-30 14:59:20 +02:00
Andras Bacsai
61f47cc7ee feat(deployments): support Docker image tags for preview deployments
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
2026-03-30 13:35:35 +02:00
Andras Bacsai
1da1f32f0e refactor: use forceCreate() for internal model creation
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.
2026-03-30 13:04:11 +02:00
Michael Jathe
2b573ef5ec
Merge branch 'next' into feat/api/tag-management 2026-03-30 10:04:00 +02:00
Andras Bacsai
7b1e75f37d Merge remote-tracking branch 'origin/next' into pr-8371-v4.x 2026-03-29 23:52:37 +02:00
Andras Bacsai
f267a28cb2
fix: harden GetLogs Livewire component properties (#9229) 2026-03-29 21:29:23 +02:00
Andras Bacsai
b3256d4df1 fix(security): harden model assignment and sensitive data handling
Restrict mass-assignable attributes across user/team/redis models and
switch privileged root/team creation paths to forceFill/forceCreate.

Encrypt legacy ClickHouse admin passwords via migration and cast the
correct ClickHouse password field as encrypted.

Tighten API and runtime exposure by removing sensitive team fields from
responses and sanitizing Git/compose error messages.

Expand security-focused feature coverage for command-injection and mass
assignment protections.
2026-03-29 20:56:04 +02:00
Andras Bacsai
1027c73d0f
refactor: scope server and project queries to current team (#9230) 2026-03-29 20:28:21 +02:00
Michael Jathe
23d5b854e9 feat(api): add tag management endpoints for applications, databases, and services
Add CRUD tag endpoints (GET/POST/DELETE) as sub-resources for applications,
databases, and services. Add team-level GET /tags endpoint. Extend all
resource creation endpoints to accept an optional tags array.

Uses a shared HandlesTagsApi trait to avoid duplication across controllers.
Tags are race-safe via syncWithoutDetaching(), garbage-collected when orphaned,
and sanitized (strip_tags + lowercase).
2026-03-29 16:02:05 +02:00
Bakr
8ad65a0ef8 eat(api): add service-applications API to manage service applications 2026-03-29 06:03:47 +03:00
ShadowArcanist
b98346f3c3 fix(validation): validate cron expressions in update backup API endpoint 2026-03-29 03:02:15 +05:30
ShadowArcanist
40420e33e3 fix(validation): add timeout validation to database backup API endpoints 2026-03-29 02:53:18 +05:30
ShadowArcanist
791aa10b3f fix(validation): use int|string for Livewire numeric properties and remove nullable from API rules 2026-03-29 02:24:36 +05:30
ShadowArcanist
15a98b52c9 fix(validation): add input validation for server_disk_usage_check_frequency on API 2026-03-29 01:24:08 +05:30
ShadowArcanist
c52a199120 fix(validation): add input validation for server advanced settings page 2026-03-29 01:14:08 +05:30
Andras Bacsai
72118d61f9 feat(databases): add public port timeout configuration
Add support for configuring public port timeout on databases via API:
- Add public_port_timeout field to schema documentation with 3600s default
- Add validation rules (integer|nullable|min:1)
- Update all database type configurations to support the field
- Add comprehensive test coverage for the feature
2026-03-28 17:08:02 +01:00
Andras Bacsai
67a4fcc2ab fix: add mass assignment protection to models
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.
2026-03-28 12:32:57 +01:00
Andras Bacsai
e36622fdfb refactor: scope server and project queries to current team
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>
2026-03-28 12:29:08 +01:00
Andras Bacsai
25d424c743 refactor: split invitation endpoint into GET (show) and POST (accept)
Refactor the invitation acceptance flow to use a landing page pattern:
- GET shows invitation details (team name, role, confirmation button)
- POST processes the acceptance with proper form submission
- Remove unused revoke GET route (handled by Livewire component)
- Add Blade view for the invitation landing page
- Add feature tests for the new invitation flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 14:30:27 +01:00
Andras Bacsai
0fce7fa948 fix: add URL validation for GitHub source api_url and html_url fields
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>
2026-03-26 13:45:33 +01:00
Andras Bacsai
f9a9dc80aa fix(api): add volume name validation to storage API endpoints
Apply the same Docker volume name pattern validation to the API
create and update storage endpoints for applications, databases,
and services controllers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 12:17:39 +01:00
ShadowArcanist
9c8e5645b4 feat(application): make ports_exposes optional for portless apps 2026-03-26 13:20:41 +05:30
Andras Bacsai
3fdce06b65 fix(storage): consistent path validation and escaping for file volumes
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>
2026-03-25 23:44:37 +01:00
Andras Bacsai
99043600ee fix(backup): validate MongoDB collection names in backup input
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>
2026-03-25 16:52:06 +01:00
Andras Bacsai
207002dbb7 Merge remote-tracking branch 'origin/next' into feat/railpack 2026-03-25 16:45:30 +01:00
Andras Bacsai
a94517f452 fix(api): validate server ownership in domains endpoint and scope activity lookups
- 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>
2026-03-25 16:20:53 +01:00
Andras Bacsai
2ed360f0e0 Merge remote-tracking branch 'origin/next' into feat/railpack 2026-03-23 21:58:33 +01:00
Andras Bacsai
e37cb98c7c refactor(team): make server limit methods accept optional team parameter
Allow serverLimit() and serverLimitReached() to accept an optional team
parameter instead of relying solely on the current session. This improves
testability and makes the methods more flexible by allowing them to work
without session state.

Add comprehensive tests covering various scenarios including no session,
team at limit, and team under limit.
2026-03-23 21:56:50 +01:00
Andras Bacsai
b931418c1e fix(github-webhook): handle unsupported event types gracefully
Add validation in manual and normal webhook handlers to reject GitHub
event types other than 'push' and 'pull_request'. Unsupported events
now return a graceful response instead of potentially causing
downstream errors. Includes tests for ping events, unsupported event
types, and unknown events.
2026-03-23 21:33:40 +01:00
Aditya Tripathi
793077d74f feat(buildpack): add Railpack as a build pack option 2026-03-23 17:12:02 +00:00
Andras Bacsai
ae33447994 feat(storage): add storage endpoints and UUID support for databases and services
- Add storage endpoints (list, create, update, delete) to DatabasesController
- Add storage endpoints (list, create, update, delete) to ServicesController
- Add UUID field and migration for local_persistent_volumes table
- Update LocalPersistentVolume model to extend BaseModel
- Support UUID-based storage identification in ApplicationsController
- Update OpenAPI documentation with new storage endpoints and schemas
- Fix application name generation to extract repo name from full git path
- Add comprehensive tests for storage API operations
2026-03-23 15:15:02 +01:00
Andras Bacsai
c00d5de03e feat(api): add database environment variable management endpoints
Add CRUD API endpoints for managing environment variables on databases:
- GET /databases/{uuid}/envs - list environment variables
- POST /databases/{uuid}/envs - create environment variable
- PATCH /databases/{uuid}/envs - update environment variable
- PATCH /databases/{uuid}/envs/bulk - bulk create environment variables
- DELETE /databases/{uuid}/envs/{env_uuid} - delete environment variable

Includes comprehensive test suite and OpenAPI documentation.
2026-03-19 23:29:50 +01:00
Andras Bacsai
fb76b68c08 feat(api): support comments in bulk environment variable endpoints
Add support for optional comment field on environment variables created or
updated through the bulk API endpoints. Comments are validated to a maximum
of 256 characters and are nullable. Updates preserve existing comments when
not provided in the request.
2026-03-19 22:17:55 +01:00
Andras Bacsai
8a164735cb fix(api): extract resource UUIDs from route parameters
Extract resource UUIDs from route parameters instead of request body
in ApplicationsController and ServicesController environment variable
endpoints. This prevents UUID parameters from being spoofed in the
request body.

- Replace $request->uuid with $request->route('uuid')
- Replace $request->env_uuid with $request->route('env_uuid')
- Add tests verifying route parameters are used and body UUIDs ignored
2026-03-19 21:56:58 +01:00
Andras Bacsai
23f9156c73 Squashed commit from 'qqrq-r9h4-x6wp-authenticated-rce' 2026-03-18 13:53:01 +01:00
ShadowArcanist
820f699853 fix(ui): updated example domains on helper text to be https instead of 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
2026-03-18 12:53:24 +05:30
Andras Bacsai
15d6de9f41 fix(storages): hide PR suffix for services and fix instantSave logic
- 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
2026-03-16 21:10:00 +01:00
Andras Bacsai
9d745fca75 feat(api): expand update_storage to support name, mount_path, host_path, content fields
Add support for updating additional storage fields via the API while
enforcing read-only restrictions for storages managed by docker-compose
or service definitions (only is_preview_suffix_enabled remains editable
for those).
2026-03-16 15:37:46 +01:00
Andras Bacsai
0488a188a0 feat(api): add storages endpoints for applications
Add GET and PATCH /applications/{uuid}/storages routes to list and
update persistent and file storages for an application, including
support for toggling is_preview_suffix_enabled.
2026-03-16 15:34:27 +01:00
Andras Bacsai
b8390482b8 feat(server): allow force deletion of servers with resources
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.
2026-03-13 16:58:26 +01:00
Niklas Wichter
6b9a755e32 feat(api): add POST /move endpoints for applications, databases, and services 2026-03-13 16:32:00 +01:00
Andras Bacsai
b9cae51c5d feat(service): add container label escape control to services API
Add `is_container_label_escape_enabled` boolean field to services API,
allowing users to control whether special characters in container labels
are escaped. Defaults to true (escaping enabled).

When disabled, users can use environment variables within labels.
Includes validation rules and comprehensive test coverage.
2026-03-13 13:32:58 +01:00
Andras Bacsai
3819676555 fix(api): cast teamId to int in deployment authorization check
Ensure proper type comparison when verifying deployment team ownership.
Adds comprehensive feature tests for the GET /api/v1/deployments/{uuid} endpoint.
2026-03-12 13:25:10 +01:00
Andras Bacsai
eb96c9550b
fix(api): add docker_cleanup parameter to stop endpoints (#8899) 2026-03-11 10:18:22 +01:00
Andras Bacsai
f83c71fd4f Merge remote-tracking branch 'origin/next' into audit-policies 2026-03-06 08:04:10 +01:00
Andras Bacsai
11007771f0
Fix/wrong destinations api (#8646) 2026-03-05 16:32:09 +01:00
Andras Bacsai
4fa048f931 Merge remote-tracking branch 'origin/next' into audit-policies 2026-03-03 19:41:05 +01:00
Andras Bacsai
d3b8d70f08 fix(subscription): harden quantity updates and proxy trust behavior
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.
2026-03-03 12:28:16 +01:00
Andras Bacsai
839635e9e8 chore: prepare for PR 2026-03-03 11:51:38 +01:00
Andras Bacsai
7154febf32 Merge remote-tracking branch 'origin/next' into audit-policies 2026-03-02 12:41:30 +01:00
Andras Bacsai
d9e39ba211 Merge remote-tracking branch 'origin/next' into env-var-descriptions 2026-02-28 00:09:54 +01:00
Andras Bacsai
c924655999 feat(auth): restrict sensitive data visibility for team members
Hide database passwords, connection URLs, and debug logs from team members:
- Database components: hide passwords and connection URLs for members
- Deployment UI: gate debug log toggle behind update permission
- Debug logs: prevent members from viewing debug output
- Storage/services: hide sensitive credentials from members

Members can still view non-sensitive configuration while admins retain full access to all data.
2026-02-27 22:42:48 +01:00
Andras Bacsai
b878dc8102 refactor(auth): enforce team member authorization across app
Restrict sensitive operations to admins/owners and hide sensitive data
from team members:
- Add authorization checks to Livewire components and API endpoints
- Restrict team members from accessing sensitive permissions and data
- Hide environment variable values from non-admin team members
- Update policies to enforce team-level admin status requirement
- Add useSensitivePermissions policy for read:sensitive tokens
- Improve disabled button UX with auth-specific tooltips
- Add authorization checks in middleware for API tokens

Closes authorization gaps in project management, server management,
and settings components.
2026-02-27 11:41:01 +01:00
W8jonas
7c5a6bc96c Fix wrong destination issue on create_service 2026-02-26 23:15:18 -03:00
W8jonas
bf6b3b8c71 Fix wrong destination issue on create_application 2026-02-26 23:15:04 -03:00
Andras Bacsai
f09bbb4a04 Merge remote-tracking branch 'origin/next' into audit-policies
# Conflicts:
#	tests/Unit/Policies/GithubAppPolicyTest.php
#	tests/Unit/Policies/SharedEnvironmentVariablePolicyTest.php
2026-02-25 18:53:39 +01:00
Andras Bacsai
86b05b902a fix(auth): enforce authorization checks across API and Livewire components
- Add authorization checks to API controller endpoints (view, create, update, delete)
- Wrap Livewire component methods with try-catch for consistent error handling
- Add AuthorizesRequests trait to components requiring authorization checks
- Ensure all sensitive operations verify user permissions before execution
- Implement unified error handling with handleError() helper function
2026-02-25 14:20:29 +01:00
Andras Bacsai
521d995ea1 Merge remote-tracking branch 'origin/next' into 7765-healthcheck-investigation 2026-02-25 11:57:58 +01:00
Andras Bacsai
8e2f0836da chore: prepare for PR 2026-02-25 11:52:18 +01:00
Andras Bacsai
0580af0d34 feat(healthchecks): add command health checks with input validation
Add support for command-based health checks in addition to HTTP-based checks:
- New health_check_type field supporting 'http' and 'cmd' values
- New health_check_command field with strict regex validation
- Updated allowedFields in create_application and update_by_uuid endpoints
- Validation rules include max 1000 characters and safe character whitelist
- Added feature tests for health check API endpoints
- Added unit tests for GithubAppPolicy and SharedEnvironmentVariablePolicy
2026-02-25 11:38:09 +01:00
Andras Bacsai
2986d7604e chore: prepare for PR 2026-02-24 10:17:16 +01:00
Andras Bacsai
73170fdd33 chore: prepare for PR 2026-02-23 12:12:10 +01:00