Commit Graph
366 Commits
Author SHA1 Message Date
Andras Bacsai ef276bdba6 Merge remote-tracking branch 'origin/next' into github-runner-integration 2026-06-04 10:59:10 +02:00
Andras Bacsai 9aa40bb5f0 Merge remote-tracking branch 'origin/next' into jean/allow-dots-username 2026-06-03 11:38:55 +02:00
Andras Bacsai bc2afdf02e fix(server): share SSH username validation
Centralize SSH username rules and sanitization so dotted usernames are
accepted consistently across API, onboarding, and Livewire server forms.
2026-06-03 11:38:48 +02:00
Andras Bacsai d892d0ad10 fix(sentinel): refresh server nav after toggles
Dispatch server show refreshes after Sentinel and metrics toggles, preserve editable Sentinel form fields during restart events, and gate custom image editing by update permission.
2026-06-03 11:10:13 +02:00
Andras Bacsai 2d2634f87b Merge remote-tracking branch 'origin/next' into jean/sentinel-ux 2026-06-03 10:57:36 +02:00
Andras Bacsai a5576533fc Merge remote-tracking branch 'origin/next' into github-runner-integration 2026-06-02 11:58:53 +02:00
Andras Bacsai 419593e7d4 fix(proxy): tighten config validation 2026-06-01 15:14:28 +02: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 7188e45167 Merge remote-tracking branch 'origin/next' into github-runner-integration 2026-05-11 22:04:24 +02:00
ShadowArcanist ff4794ffec fix(server): allow dots in ssh username 2026-05-06 21:21:37 +05:30
Andras Bacsai 6293b14586 feat(server): add configurable SSH connection timeout per server
Add `connection_timeout` field to server settings, allowing per-server
override of the global SSH connection timeout constant.

- Migration adds `connection_timeout` integer column (default 10s)
- `ServerSetting` model exposes and casts the new field
- `SshMultiplexingHelper::getConnectionTimeout()` resolves per-server
  value with fallback to `constants.ssh.connection_timeout`
- All SSH/SCP command builders use the new resolver instead of the
  global config directly
- Livewire `Show` component binds `connectionTimeout` with validation
  (1–300 seconds) and syncs to/from the model
- UI input added to server settings form with helper text
- Feature tests cover default, persistence, resolver, and fallback
2026-04-28 15:39:36 +02:00
ShadowArcanist 2a5e1f4838 fix(ui): server metrics charts were not loading after enabling metrics 2026-04-14 19:05:40 +05:30
ShadowArcanist 6b1b1b14f2 feat(ui): move Sentinel to dedicated tab with sidebar navigation and logs page 2026-04-14 18:50:01 +05:30
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
Andras BacsaiandGitHub 71bafa0d54 fix(validation): add URL validation for proxy redirect input (#9241) 2026-03-30 21:02:06 +02:00
Andras BacsaiandGitHub 179770d836 fix(validation): add input validation for server advanced settings page (#9242) 2026-03-30 21:01:28 +02:00
Andras BacsaiandGitHub 0b9d2c9e11 fix(validation): add input validation for sentinel configuration (#9243) 2026-03-30 21:00:18 +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
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 1ebba7da3a fix(validation): add input validation for sentinel configuration 2026-03-29 01:56:06 +05:30
ShadowArcanist c52a199120 fix(validation): add input validation for server advanced settings page 2026-03-29 01:14:08 +05:30
ShadowArcanist 73258c317e fix(validation): add URL validation for proxy redirect input 2026-03-29 00:34:32 +05:30
Andras BacsaiandClaude Opus 4.6 103d5b6c06 fix: sanitize error output in server validation logs
Escape dynamic error messages with htmlspecialchars() before
concatenating into HTML strings stored in validation_logs. Add a
Purify-based mutator on Server model as defense-in-depth, with a
dedicated HTMLPurifier config that allows only safe structural tags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 18:36:36 +01:00
Andras BacsaiandClaude Opus 4.6 ae31111813 fix(livewire): add input validation to unmanaged container operations
Add container name validation and shell argument escaping to
startUnmanaged, stopUnmanaged, restartUnmanaged, and restartContainer
methods, consistent with existing patterns used elsewhere in the
codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:42:00 +01:00
Andras Bacsai f0c8ff6a77 Update ByHetzner.php 2026-03-25 19:26:13 +01:00
Andras BacsaiandGitHub 74d591e6e9 feat(server): auto-fetch server metadata after validation (#8964) 2026-03-13 17:08:15 +01:00
Andras Bacsai 1936bb08bf feat(server): auto-fetch server metadata after validation
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.
2026-03-13 17:07:50 +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
Andras Bacsai e52a49b5e9 feat(server): add server metadata collection and display
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
2026-03-11 16:21:05 +01:00
Andras BacsaiandGitHub 108bae02d0 fix(livewire): add error handling and selectedActions to delete methods (#8909) 2026-03-11 15:05:53 +01:00
Andras Bacsai 8366e150b1 feat(livewire): add selectedActions parameter and error handling to delete methods
- 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
2026-03-11 15:04:45 +01:00
Andras Bacsai 6488751fd2 feat(proxy): add database-backed config storage with disk backups
- 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
2026-03-11 14:11:31 +01:00
Andras Bacsai fcd574e1eb fix(log-drain): prevent command injection by base64-encoding environment variables
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
2026-03-10 22:22:51 +01:00
Andras Bacsai 096d4369e5 fix(sentinel): add token validation to prevent command injection
Add validation to ensure sentinel tokens contain only safe characters
(alphanumeric, dots, hyphens, underscores, plus, forward slash, equals),
preventing OS command injection vulnerabilities when tokens are
interpolated into shell commands.

- Add ServerSetting::isValidSentinelToken() validation method
- Validate tokens in StartSentinel action and metrics queries
- Improve shell argument escaping with escapeshellarg()
- Add comprehensive test coverage for token validation
2026-03-10 22:19:19 +01:00
Andras Bacsai 5c50ab6162 feat(github-runners): improve runner lifecycle and GitHub sync
Add runner execution observability and lifecycle hardening for self-hosted
GitHub Actions runners, including:
- scheduled artifact cleanup job for cached runner tarballs/templates
- workflow_job in_progress handling to mark executions as running
- safer cleanup failure handling and non-functional server fallback
- persisted workflow job HTML URLs with execution "Open" links in UI
- configurable runner group name sync (UI + provisioning + GitHub API)
- webhook events persistence and auto-fix for missing required events
- strict enum/status checks and related model cast/query improvements

Also includes migrations and expanded feature/unit coverage for webhook,
provisioning, cleanup, and runner group/event sync behaviors.
2026-03-03 22:21:13 +01:00
Andras Bacsai 1739c04d32 feat(github-runners): add capacity wait timeout and deferred repo loading
Add configurable `capacity_wait_timeout` to runner configs and use it in
`ProvisionGithubRunnerJob` to re-dispatch jobs while at capacity, preserving
initial wait start time and stopping after timeout.

Improve runner provisioning by caching an extracted runner template and copying
it into new runner directories.

Update Livewire GitHub Runners UI to lazy-load accessible repositories via
`wire:init`, track loading state, add timeout input, and remove preinstall
binary action.

Add/extend feature tests for capacity retry timeout behavior and deferred
repository loading.
2026-03-03 18:37:10 +01:00
Andras Bacsai 576f38da1c feat(github): add self-hosted Actions runner orchestration
Implement end-to-end GitHub Actions runner support with provisioning,
tracking, and cleanup flows.

- handle `workflow_job` webhooks to provision and tear down runners
- add runner config/execution models, enum states, and relationships
- create jobs for provisioning, cleanup, and stale-runner reaping
- schedule periodic stale runner cleanup in the console kernel
- add Livewire server UI to manage runner configuration and executions
- store GitHub App runner permissions and runner group metadata
- add migrations for runner permissions, configs, executions, and group id
- update GitHub permissions URL generation for organization app settings
- include feature/unit tests for runner behavior and permission paths
2026-03-03 14:27:19 +01:00
Andras Bacsai 839635e9e8 chore: prepare for PR 2026-03-03 11:51:38 +01:00
Andras Bacsai b88f9fca67 chore: prepare for PR 2026-02-25 12:07:29 +01:00
Andras Bacsai fe36b70680 chore: prepare for PR 2026-02-25 12:00:24 +01:00
Andras Bacsai 4ec32290cf fix(server): improve IP uniqueness validation with team-specific error messages
- Refactor server IP duplicate detection to use `first()` instead of `get()->count()`
- Add team-scoped validation to distinguish between same-team and cross-team IP conflicts
- Update error messages to clarify ownership: "already exists in your team" vs "in use by another team"
- Apply consistent validation logic across API, boarding, and server management flows
- Add comprehensive test suite for IP uniqueness enforcement across teams
2026-02-12 08:10:59 +01:00
Andras Bacsai ef1abe17b8 refactor(redirect): replace redirect calls with redirectRoute helper for consistency 2025-12-26 13:29:59 +01:00
Andras BacsaiandClaude Haiku 4.5 f995426fb3 fix(sentinel): Add missing instantSave method and prevent duplicate notifications
- Add public instantSave() method to handle instant saves from checkbox clicks
- Remove redundant updatedIsMetricsEnabled() and updatedIsSentinelDebugEnabled() hooks
- These hooks were causing duplicate notifications when checkboxes were toggled

The instantSave attribute on checkboxes triggers wire:click='instantSave', which was failing
because the method didn't exist. Now it saves settings and restarts Sentinel in one action,
preventing the duplicate updates from both wire:click and wire:model events.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-23 15:34:09 +01:00
Andras BacsaiandClaude Haiku 4.5 9675d74360 refactor: move Swarm and Sentinel to dedicated sidebar menu items
- Create new Server/Swarm.php Livewire component and view for Swarm configuration
- Create new Server/Sentinel.php Livewire component and view for Sentinel settings
- Add server.swarm and server.sentinel routes
- Move Swarm and Sentinel sections from General page to sidebar menu items
- Improve organization by separating concerns into dedicated pages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-18 12:18:22 +01:00
Andras BacsaiandClaude Haiku 4.5 4b65b02103 Fix server resources tab 500 error with mixed model types
The Resources tab threw a "Queueing collections with multiple model types is not supported" error because the Livewire component was storing a mixed-type Eloquent collection (Applications, Databases, Services) as a public property, causing Livewire's serialization to fail.

Fixed by: storing only the unmanaged containers array in the component, and calling definedResources() directly in the Blade view for the managed tab.

Fixes #7666

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-17 18:13:55 +01:00
Andras BacsaiandClaude Haiku 4.5 0efa4af5c3 Optimize PushServerUpdateJob performance with batch updates and async jobs
- Eager load service applications and databases to eliminate N+1 queries
- Replace individual model updates with batch database updates for applications, previews, and services
- Move connectProxyToNetworks to async ConnectProxyToNetworksJob to avoid blocking status updates
- Optimize Server.databases() and applications() methods with efficient database queries
- Use flatMap for cleaner collection transformations

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-15 14:06:32 +01:00
Andras BacsaiandClaude Haiku 4.5 b0d50669b1 fix: skip password confirmation for OAuth users
OAuth users don't have passwords set, so they should not be prompted for password confirmation when performing destructive actions. This fix:
- Detects OAuth users via the hasPassword() method
- Skips password confirmation in modal for OAuth users
- Keeps text name confirmation as the final step
- Centralizes logic in helper functions for maintainability
- Changes button text to "Confirm" when password step is skipped

Fixes #4457

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-12 14:12:02 +01:00
Andras BacsaiandClaude Opus 4.5 67b1db9254 feat: add Hetzner Cloud server linking for manually-added servers
Allow manually-added servers to be linked to Hetzner Cloud instances by
matching IP address. Once linked, servers gain power controls and status
monitoring.

Changes:
- Add getServers() and findServerByIp() methods to HetznerService
- Add Hetzner linking UI section to Server General page
- Add unit tests for new HetznerService methods

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 22:14:41 +01:00
Andras BacsaiandGitHub 700550b26f Fix: Concurrent builds ignored & add deployment queue limit (#7488) 2025-12-11 11:03:02 +01:00