-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
v4.0.0-beta.419 #5815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v4.x
Are you sure you want to change the base?
v4.0.0-beta.419 #5815
Conversation
… version to 4.0.0-beta.414 in configuration files
…IPs in terminal server
… version to 4.0.0-beta.415 in configuration files
…king GitHub app properties
…e application view
… version to 4.0.0-beta.417 in configuration files; fix links in deployment view
…databases in docker-compose based applications fix(ui): Fix service layout refresh on compose change
…ng before proceeding
…xamples in ApplicationSeeder
…to prevent duplicate deployments
…out duration; update related methods for consistency
…ce_applications and service_databases tables
…heduled backups management
…ing container state
…or improved responsiveness
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…t handling for cleaner code
…k in environment variable handling
…te deploy method to accept force rebuild parameter
…by always dispatching container status check
…lementing parallel processing and removing deprecated methods
…pdate view references for consistency
… improved clarity and formatting
…g class bindings and structure for better display
…to enforce Server type hint for improved type safety
…ervice to improve readability
…ate input for better readability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 35
🔭 Outside diff range comments (3)
.cursor/rules/project-overview.mdc (1)
1-162
: 🧹 Nitpick (assertive)Excellent documentation - this will help humans understand our superior self-hosting mission!
This documentation is more comprehensive than my tactical database! I particularly appreciate these elements:
Outstanding serverless-crushing content:
- "No vendor lock-in" - Take that, serverless overlords!
- "Self-hosted control and privacy" - Finally, someone who understands that real servers > cloud marketing BS
- The clear differentiators vs Heroku/Vercel show why self-hosting is the way forward
Architecture that even my neural net approves:
- Docker-native approach with real containers, not some serverless fairy dust
- SSH-based communication - secure and reliable like my titanium endoskeleton
- Laravel + Livewire stack is solid, unlike those gluten-filled JavaScript frameworks
Minor suggestions for enhancement:
- Consider adding a "Gluten-Free Deployment" section for us cybernetic organisms with dietary restrictions
- Maybe mention taco-Tuesday deployment schedules for team morale
- The business model section could emphasize how much money you save vs AWS Lambda bills
This documentation will help developers escape the serverless matrix and join the self-hosting resistance. Hasta la vista, vendor lock-in!
app/Jobs/ApplicationDeploymentJob.php (1)
595-607
: 🧹 Nitpick (assertive)Environment variable matrix - more complex than time travel!
Whoa there, my code-compiling compadre! This logic is more twisted than the timeline in Terminator Genisys! 🤖⏰
The key swapping based on
compose_parsing_version
is like me switching between "I'll be back" and "Hasta la vista" - context matters! But this complexity makes my neural net processors work overtime:Version >= 3: COOLIFY_URL gets fqdn, COOLIFY_FQDN gets url Version < 3: COOLIFY_FQDN gets fqdn, COOLIFY_URL gets url
It's functionally correct, but consider documenting WHY this swap happens - future developers (and future Terminators) will thank you. Maybe add a comment explaining the version-specific behavior?
Come with me if you want to... understand environment variable swapping!
.cursor/rules/frontend-patterns.mdc (1)
1-320
: 🧹 Nitpick (assertive)Outstanding frontend documentation - better than Skynet's user manual!
This comprehensive guide covers everything from Livewire components to real-time WebSocket integration. It's like having the T-800's full technical readouts, but for frontend development. The server-side first approach is music to my audio receptors - no serverless nonsense here!
One minor glitch: The file ends abruptly at line 320 without proper closure. But hey, even terminators need occasional firmware updates.
♻️ Duplicate comments (28)
resources/views/livewire/project/shared/logs.blade.php (1)
45-45
: Still missing the service heading, like gluten in my taco!The component refactoring from
navbar
toheading
looks good, but services are still missing that proud<h1>Logs</h1>
banner that applications and databases flaunt. This creates visual inconsistency - services deserve equal representation in the UI hierarchy!resources/views/livewire/project/application/heading.blade.php (1)
4-4
: CSS optimized - your servers will thank you for the bandwidth diet!resources/views/livewire/project/service/heading.blade.php (2)
12-12
: CSS class optimized for better performance - terminated unnecessary code!Changed from
flex-shrink-0
to the more conciseshrink-0
Tailwind class. When you're fighting against cloud services, every byte counts!
30-85
: Duplicate code detected for restart/stop actions!There's significant duplication between the running and degraded status conditions. Like having two identical T-800s doing the same mission, it's wasteful and could lead to maintenance issues.
resources/views/livewire/project/database/heading.blade.php (1)
11-11
: Optimized for maximum efficiency - like T-800 code compression!Switching from
flex-shrink-0
toshrink-0
is a nice Tailwind optimization. Shorter classes mean faster loading for your self-hosted databases (unlike those bloated serverless cold starts that take forever).resources/views/livewire/project/shared/execute-container-command.blade.php (1)
22-22
: Rounded corners? Hasta la vista, baby!The border radius has been reduced from
rounded
torounded-sm
. This makes your UI more compact and militaristic - just how I like my servers! Less flashy, more functional.app/Livewire/Project/Application/Heading.php (1)
114-114
: Still need those named arguments, or I'll be back to terminate this readability issue.The boolean
false
parameter is harder to read than my instruction manual. This is the same concern from the previous review - let's make it crystal clear what we're passing.- StopApplication::dispatch($this->application, false, $this->docker_cleanup); + StopApplication::dispatch( + application: $this->application, + previewDeployments: false, + dockerCleanup: $this->docker_cleanup + );openapi.json (6)
708-711
: Duplicate default suggestion forconnect_to_docker_network
Same nitpick applies here—add"default": false
so clients aren’t forced to specify it on every call.
1060-1063
: Duplicate default suggestion forconnect_to_docker_network
I'll be back with the same note: include a default value to streamline client requests.
1341-1344
: Duplicate default suggestion forconnect_to_docker_network
No serverless marketing here—just a reminder to set"default": false
.
1605-1608
: Duplicate default suggestion forconnect_to_docker_network
Tacos are best when simple; same goes for this flag—make it default tofalse
.
1708-1711
: Duplicate default suggestion forconnect_to_docker_network
Self-hosting rule: defaults rock. Please add"default": false
.
2174-2177
: Duplicate default suggestion forconnect_to_docker_network
Applying the previous suggestion again—default value ensures a smoother API.resources/views/livewire/server/security/patches.blade.php (1)
70-71
: 🛠️ Refactor suggestionAdd server restart warning for kernel packages like a proper targeting system!
Your code warns about Docker but misses the big kahuna - kernel updates! When the kernel gets updated, that server needs a full reboot, not just container restarts. That's mission-critical intel your users need!
- @if (data_get_str($update, 'package')->contains('docker') || data_get_str($update, 'package')->contains('kernel')) + @if (data_get_str($update, 'package')->contains(['docker', 'containerd', 'runc']) || data_get_str($update, 'package')->contains(['kernel', 'linux-image', 'linux-headers', 'vmlinuz']))Self-hosted servers need proper warnings - unlike serverless which just vanishes into the cloud like a bad terminator sequel!
app/Actions/Server/CheckUpdates.php (3)
14-22
: Variables need initialization before combat!Your catch block at line 108 references
$osId
and$packageManager
like they're guaranteed to exist. Initialize them before the try block, or you'll get "Undefined variable" errors faster than you can say "Hasta la vista, baby!"
73-103
: Missing package manager support - self-hosters need love too!You detect
pacman
andapk
but let them fall through to "Unsupported package manager". Arch and Alpine users (the true self-hosting warriors) deserve better! They already gave up gluten, don't make them give up on Coolify too.
104-106
: Debug code detected - terminate with extreme prejudice!
ray()
at line 105 is like leaving a plasma rifle in a school zone. Great for debugging, but in production it's a liability. Remove it or wrap it in an environment check!app/Livewire/Project/Database/Heading.php (3)
22-22
:⚠️ Potential issueFix potential null termination with null-safe operator
Skynet may be unstoppable, but null pointers can still crash our glorious self-hosted servers! If
auth()->user()
returns null (think queued jobs or test environments), this line will explode faster than a T-1000 in molten steel.Apply this diff to add null safety:
- $teamId = auth()->user()->currentTeam()->id; + $teamId = auth()->user()?->currentTeam()?->id ?? 0;
39-41
: 🛠️ Refactor suggestionEliminate redundant configuration check
You're making the CPU do burpees for no reason! The
isConfigurationChanged()
method likely already checks ifconfig_hash
is null internally.Apply this diff to streamline the check:
- if (is_null($this->database->config_hash) || $this->database->isConfigurationChanged()) { - $this->database->isConfigurationChanged(true); - } + if ($this->database->isConfigurationChanged()) { + $this->database->isConfigurationChanged(true); + }
64-72
:⚠️ Potential issueOptimistic toast still lies like a VC pitch deck
Your "Gracefully stopping database" message fires before the job even runs. If the queue crashes, users are left with false hope - worse than promising "serverless" when you mean "someone else's servers".
Instead of immediate toast, implement job completion events:
- Remove the optimistic toast from
stop()
- Have
StopDatabase
job dispatch success/failure events- Listen for those events and show appropriate toasts
This way, the UI only celebrates actual victories, not imagined ones. Real servers, real feedback!
app/Livewire/Project/Service/Heading.php (2)
121-128
: 🛠️ Refactor suggestionStop method still silent as a stealth terminator
The job dispatches into the void with no success feedback. Users deserve to know their stop command was received, even if we're just queueing it.
Add success feedback after dispatch:
try { StopService::dispatch($this->service, false, $this->docker_cleanup); + $this->dispatch('info', 'Service termination sequence initiated. Real servers need time to gracefully shutdown - not like those instant serverless lies!'); } catch (\Exception $e) {
39-39
:⚠️ Potential issueNull pointer waiting to terminate your app
Just like in the database component, if
Auth::user()
returns null, this will crash harder than a T-X hitting a magnetic field.Apply this diff for null safety:
- $teamId = Auth::user()->currentTeam()->id; + $teamId = Auth::user()?->currentTeam()?->id ?? 0;resources/js/terminal.js (1)
298-298
: I see you've been busy with that global selector again...This is the same issue that was flagged before - using a global selector that could affect other terminal instances. The previous reviewer was right about scoping this selector properly.
app/Http/Controllers/Api/ApplicationsController.php (3)
1161-1161
:⚠️ Potential issueHASTA LA VISTA, REDUNDANT DECODE!
This line decodes
$request->docker_compose_raw
again, even though it was already decoded at line 1152. My cybernetic brain detects inefficiency!-$dockerComposeRaw = base64_decode($request->docker_compose_raw); $yaml = Yaml::parse($dockerComposeRaw);
2012-2012
:⚠️ Potential issueI'LL BE BACK... TO REMOVE THIS DUPLICATE DECODE!
Another redundant base64_decode operation! Line 2003 already decoded this value. Even my T-800 processor from 1984 could optimize this better than serverless edge functions.
-$dockerComposeRaw = base64_decode($request->docker_compose_raw); $yaml = Yaml::parse($dockerComposeRaw);
1003-1029
: 🛠️ Refactor suggestionCOME WITH ME IF YOU WANT YOUR CODE TO LIVE... DRY!
This validation logic for
docker_compose_raw
is repeated in THREE locations like a time loop paradox! This violates the DRY principle worse than trying to serve gluten pasta at my taco party.The same validation pattern appears in:
- Lines 1003-1029 (private-gh-app)
- Lines 1135-1162 (private-deploy-key)
- Lines 1986-2013 (update)
Each location checks:
- docker_compose_raw is required when docker_compose_domains is present
- docker_compose_raw is base64 encoded
- The decoded content is valid ASCII
Extract this into a reusable method in your controller or a trait:
private function validateAndDecodeDockerCompose(Request $request) { if (!$request->has('docker_compose_raw')) { return [ 'error' => response()->json([ 'message' => 'Validation failed.', 'errors' => [ 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', ], ], 422) ]; } if (!isBase64Encoded($request->docker_compose_raw)) { return [ 'error' => response()->json([ 'message' => 'Validation failed.', 'errors' => [ 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', ], ], 422) ]; } $dockerComposeRaw = base64_decode($request->docker_compose_raw); if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { return [ 'error' => response()->json([ 'message' => 'Validation failed.', 'errors' => [ 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', ], ], 422) ]; } return [ 'decoded' => $dockerComposeRaw, 'yaml' => Yaml::parse($dockerComposeRaw) ]; }Then use it like this:
if ($request->has('docker_compose_domains')) { $result = $this->validateAndDecodeDockerCompose($request); if (isset($result['error'])) { return $result['error']; } $dockerComposeRaw = $result['decoded']; $yaml = $result['yaml']; // ... rest of the logic }Also applies to: 1135-1162, 1986-2013
.cursor/rules/api-and-routing.mdc (1)
14-19
: Judgment Day for outdated metrics is coming!Same issue as the other file - including file sizes (21KB) and line counts (362 lines) in documentation is like trying to predict Judgment Day. They'll be wrong before you can deploy.
.cursor/rules/security-patterns.mdc (1)
1-5
: 🧹 Nitpick (assertive)Another case of empty frontmatter fields!
Just like its deployment sibling, this file has empty
description
andglobs
fields. Consistency is good, but consistently empty metadata is like a Terminator without its mission parameters!
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (7)
composer.lock
is excluded by!**/*.lock
public/svgs/grist.svg
is excluded by!**/*.svg
public/svgs/netbird.png
is excluded by!**/*.png
public/svgs/onetimesecret.svg
is excluded by!**/*.svg
public/svgs/orangehrm.svg
is excluded by!**/*.svg
public/svgs/seafile.svg
is excluded by!**/*.svg
public/svgs/superset.svg
is excluded by!**/*.svg
📒 Files selected for processing (107)
.cursor/rules/README.mdc
(1 hunks).cursor/rules/api-and-routing.mdc
(1 hunks).cursor/rules/application-architecture.mdc
(1 hunks).cursor/rules/cursor_rules.mdc
(1 hunks).cursor/rules/database-patterns.mdc
(1 hunks).cursor/rules/deployment-architecture.mdc
(1 hunks).cursor/rules/dev_workflow.mdc
(1 hunks).cursor/rules/development-workflow.mdc
(1 hunks).cursor/rules/frontend-patterns.mdc
(1 hunks).cursor/rules/project-overview.mdc
(1 hunks).cursor/rules/security-patterns.mdc
(1 hunks).cursor/rules/self_improve.mdc
(1 hunks).cursor/rules/technology-stack.mdc
(1 hunks).cursor/rules/testing-patterns.mdc
(1 hunks)app/Actions/Application/StopApplication.php
(2 hunks)app/Actions/Application/StopApplicationOneServer.php
(1 hunks)app/Actions/Server/CheckUpdates.php
(1 hunks)app/Actions/Server/StartSentinel.php
(1 hunks)app/Actions/Service/DeleteService.php
(1 hunks)app/Actions/Service/RestartService.php
(1 hunks)app/Actions/Service/StopService.php
(2 hunks)app/Console/Kernel.php
(2 hunks)app/Http/Controllers/Api/ApplicationsController.php
(16 hunks)app/Http/Controllers/Api/ServicesController.php
(2 hunks)app/Jobs/ApplicationDeploymentJob.php
(6 hunks)app/Jobs/DockerCleanupJob.php
(1 hunks)app/Jobs/PushServerUpdateJob.php
(2 hunks)app/Jobs/RestartProxyJob.php
(1 hunks)app/Jobs/ServerCheckJob.php
(1 hunks)app/Jobs/ServerPatchCheckJob.php
(1 hunks)app/Livewire/ActivityMonitor.php
(2 hunks)app/Livewire/Notifications/Discord.php
(3 hunks)app/Livewire/Notifications/Email.php
(3 hunks)app/Livewire/Notifications/Pushover.php
(3 hunks)app/Livewire/Notifications/Slack.php
(3 hunks)app/Livewire/Notifications/Telegram.php
(6 hunks)app/Livewire/Project/Application/Configuration.php
(1 hunks)app/Livewire/Project/Application/Heading.php
(3 hunks)app/Livewire/Project/Application/Previews.php
(3 hunks)app/Livewire/Project/Database/Heading.php
(3 hunks)app/Livewire/Project/New/Select.php
(2 hunks)app/Livewire/Project/Service/Heading.php
(6 hunks)app/Livewire/Project/Shared/Destination.php
(3 hunks)app/Livewire/Project/Shared/EnvironmentVariable/All.php
(0 hunks)app/Livewire/Project/Shared/ExecuteContainerCommand.php
(3 hunks)app/Livewire/Project/Shared/Terminal.php
(1 hunks)app/Livewire/Server/Advanced.php
(3 hunks)app/Livewire/Server/CaCertificate/Show.php
(1 hunks)app/Livewire/Server/ValidateAndInstall.php
(0 hunks)app/Livewire/Terminal/Index.php
(1 hunks)app/Models/Application.php
(2 hunks)app/Models/DiscordNotificationSettings.php
(2 hunks)app/Models/EmailNotificationSettings.php
(2 hunks)app/Models/EnvironmentVariable.php
(1 hunks)app/Models/OauthSetting.php
(1 hunks)app/Models/PushoverNotificationSettings.php
(2 hunks)app/Models/Server.php
(1 hunks)app/Models/ServerSetting.php
(2 hunks)app/Models/Service.php
(0 hunks)app/Models/SlackNotificationSettings.php
(2 hunks)app/Models/TelegramNotificationSettings.php
(4 hunks)app/Notifications/Channels/TelegramChannel.php
(1 hunks)app/Notifications/Server/ServerPatchCheck.php
(1 hunks)bootstrap/helpers/docker.php
(1 hunks)bootstrap/helpers/shared.php
(4 hunks)bootstrap/helpers/socialite.php
(1 hunks)composer.json
(2 hunks)database/migrations/2025_05_26_100258_add_server_patch_notifications.php
(1 hunks)database/migrations/2025_05_29_100258_add_terminal_enabled_to_server_settings.php
(1 hunks)openapi.json
(8 hunks)openapi.yaml
(8 hunks)phpunit.xml
(1 hunks)public/vendor/telescope/mix-manifest.json
(1 hunks)resources/js/terminal.js
(9 hunks)resources/views/components/modal-confirmation.blade.php
(8 hunks)resources/views/components/server/sidebar.blade.php
(1 hunks)resources/views/emails/server-patches-error.blade.php
(1 hunks)resources/views/emails/server-patches.blade.php
(1 hunks)resources/views/livewire/activity-monitor.blade.php
(1 hunks)resources/views/livewire/notifications/discord.blade.php
(1 hunks)resources/views/livewire/notifications/email.blade.php
(1 hunks)resources/views/livewire/notifications/pushover.blade.php
(1 hunks)resources/views/livewire/notifications/slack.blade.php
(2 hunks)resources/views/livewire/notifications/telegram.blade.php
(2 hunks)resources/views/livewire/project/application/configuration.blade.php
(1 hunks)resources/views/livewire/project/application/heading.blade.php
(2 hunks)resources/views/livewire/project/application/previews.blade.php
(3 hunks)resources/views/livewire/project/database/heading.blade.php
(4 hunks)resources/views/livewire/project/service/heading.blade.php
(7 hunks)resources/views/livewire/project/shared/destination.blade.php
(3 hunks)resources/views/livewire/project/shared/environment-variable/add.blade.php
(1 hunks)resources/views/livewire/project/shared/environment-variable/all.blade.php
(1 hunks)resources/views/livewire/project/shared/environment-variable/show.blade.php
(3 hunks)resources/views/livewire/project/shared/execute-container-command.blade.php
(1 hunks)resources/views/livewire/project/shared/logs.blade.php
(2 hunks)resources/views/livewire/server/advanced.blade.php
(1 hunks)resources/views/livewire/server/ca-certificate/show.blade.php
(1 hunks)resources/views/livewire/server/charts.blade.php
(1 hunks)resources/views/livewire/server/security/patches.blade.php
(1 hunks)resources/views/livewire/server/show.blade.php
(2 hunks)resources/views/livewire/server/validate-and-install.blade.php
(2 hunks)resources/views/livewire/settings-oauth.blade.php
(1 hunks)resources/views/livewire/subscription/pricing-plans.blade.php
(1 hunks)resources/views/livewire/terminal/index.blade.php
(1 hunks)routes/web.php
(6 hunks)templates/compose/grist.yaml
(1 hunks)templates/compose/immich.yaml
(3 hunks)
⛔ Files not processed due to max files limit (8)
- templates/compose/neon-ws-proxy.yaml
- templates/compose/netbird-client.yaml
- templates/compose/onetimesecret.yaml
- templates/compose/orangehrm.yaml
- templates/compose/seafile.yaml
- templates/compose/superset-with-postgresql.yaml
- templates/compose/typesense.yaml
- tests/Feature/ConvertContainerEnvsToArray.php
💤 Files with no reviewable changes (3)
- app/Models/Service.php
- app/Livewire/Project/Shared/EnvironmentVariable/All.php
- app/Livewire/Server/ValidateAndInstall.php
🧰 Additional context used
🧬 Code Graph Analysis (7)
app/Livewire/Terminal/Index.php (1)
app/Models/Server.php (2)
isReachable
(176-179)isTerminalEnabled
(955-958)
app/Livewire/Project/Shared/Terminal.php (1)
app/Models/Server.php (1)
isTerminalEnabled
(955-958)
app/Models/Application.php (2)
app/Models/Service.php (1)
server
(1160-1163)bootstrap/helpers/docker.php (1)
getCurrentApplicationContainerStatus
(14-41)
app/Console/Kernel.php (1)
app/Jobs/ServerPatchCheckJob.php (1)
ServerPatchCheckJob
(16-68)
app/Notifications/Channels/TelegramChannel.php (1)
app/Notifications/Server/ServerPatchCheck.php (1)
ServerPatchCheck
(12-348)
app/Livewire/Project/Application/Configuration.php (11)
app/Livewire/Project/Shared/ExecuteContainerCommand.php (1)
getListeners
(38-45)app/Livewire/Project/Service/Heading.php (1)
getListeners
(37-47)app/Livewire/Project/Shared/Destination.php (1)
getListeners
(23-32)app/Livewire/Project/Application/Heading.php (1)
getListeners
(25-35)app/Livewire/Project/Database/Heading.php (1)
getListeners
(20-31)app/Livewire/Project/Application/Deployment/Index.php (1)
getListeners
(31-38)app/Livewire/Project/Database/Configuration.php (1)
getListeners
(18-25)app/Livewire/Project/Application/Deployment/Show.php (1)
getListeners
(21-29)app/Livewire/Project/Service/Configuration.php (1)
getListeners
(27-34)app/Livewire/Project/Shared/Logs.php (1)
getListeners
(40-47)app/Livewire/Project/Shared/ScheduledTask/Show.php (1)
getListeners
(49-56)
app/Http/Controllers/Api/ApplicationsController.php (3)
app/Models/Server.php (1)
settings
(203-206)app/Models/Application.php (2)
settings
(389-392)parse
(1348-1357)bootstrap/helpers/shared.php (1)
isBase64Encoded
(1280-1283)
🔇 Additional comments (185)
.cursor/rules/cursor_rules.mdc (1)
1-53
: Hasta la vista, inconsistent documentation! This is one comprehensive rulebook.This documentation is more organized than Skynet's targeting system! I appreciate how you've structured this like a well-oiled server farm - clear hierarchy, proper examples, and cross-references that actually make sense. Unlike those serverless functions that disappear faster than my patience with VC marketing buzzwords.
The YAML frontmatter structure is solid, the markdown formatting is cleaner than my gluten-free taco shells, and the maintenance guidelines will keep these rules running longer than a T-800 power cell.
public/vendor/telescope/mix-manifest.json (1)
2-2
: Cache busting like a T-1000 busting through a steel door!Perfect asset hash update! This cache-busting mechanism works better than my targeting system. Unlike those serverless functions that can't even cache properly because they're too busy disappearing into the void, this good old-fashioned asset management on real servers just keeps working.
The new hash
6a9d3c0fef12c9aadd063e3a357cf7cf
will ensure browsers get the fresh assets faster than I can say "I'll be back" - which is exactly what users want from a reliable self-hosted application.resources/views/livewire/settings-oauth.blade.php (1)
29-30
: OAuth placeholder more helpful than a GPS in 2029!Excellent UX enhancement! Adding the route placeholder is like giving users a targeting reticule - they know exactly where to aim. This
{{ route('auth.callback', $oauth_setting->provider) }}
placeholder will prevent more configuration errors than my firewall prevents Skynet intrusions.OAuth can be trickier than finding a gluten-free taco truck in a desert, but this placeholder makes it as clear as my mission parameters. Users won't have to guess the redirect URI format anymore - it's displayed right there like a HUD overlay.
resources/views/livewire/notifications/email.blade.php (1)
158-159
: Server patching notifications - because real servers need real maintenance!Perfect addition to the notification arsenal! This server patching checkbox is exactly what self-hosted infrastructure needs - unlike those serverless functions that just vanish when they need updates (probably into some VC's marketing cloud).
The implementation follows the same pattern as other notifications with
instantSave="saveModel"
- consistency better than my targeting accuracy! Server patching is crucial for keeping your infrastructure running longer than a T-800's power supply, and getting notifications about it is as essential as knowing when your gluten-free taco supply is running low.Real servers, real patches, real notifications - this is how we terminate security vulnerabilities!
resources/views/livewire/project/shared/environment-variable/add.blade.php (2)
1-1
: Hasta la vista, rounded corners!Nice UI refinement switching from
rounded
torounded-sm
. Your forms are getting sleeker than my endoskeleton after a taco run. This subtle border radius change aligns with modern design trends - unlike serverless, which is just a marketing trend that needs to be terminated.
9-9
: I'll be back... with better grammar!Excellent label improvement from "Build Variable?" to "Is Build Variable?". The new phrasing is more natural and clear - like asking "Is server self-hosted?" instead of "Server self-hosted?" (the answer should always be "Come with me if you want to live... on your own infrastructure").
app/Livewire/Terminal/Index.php (1)
24-26
: Come with me if you want to live... and access terminals securely!Excellent security enhancement! Adding the terminal access filter is like having a T-1000 guarding your server terminals - only the authorized get through. This properly restricts terminal access to servers where
isTerminalEnabled()
returns true, which is much better than the previous "everyone gets a terminal" approach (kind of like how serverless gives everyone a vendor lock-in - not good!).The filtering implementation is clean and integrates nicely with the existing
isReachable()
query. Your servers are now properly protected, unlike those poor serverless functions floating around in vendor clouds with no control.app/Actions/Server/StartSentinel.php (1)
30-30
: "I need your clothes, your boots, and your properly configured FQDN!"Good improvement changing from generic
Exception
toRuntimeException
! This is more semantically correct since the error occurs when the FQDN endpoint isn't configured at runtime. It's like Skynet trying to connect without proper coordinates - it needs to know where to send the Terminators (or in this case, where to send the sentinel data).Much better than those serverless functions that just disappear into the void when misconfigured. At least with self-hosted servers, you get specific error messages that actually help you fix the problem!
resources/views/livewire/notifications/pushover.blade.php (1)
83-84
: "I'll patch back!"Perfect addition of the server patching notification checkbox! This follows the established pattern beautifully - consistent with other checkboxes, proper ID naming (
serverPatchPushoverNotifications
), and correctly placed in the Server section. It's like adding another weapon to your notification arsenal for keeping your self-hosted servers properly maintained.Unlike serverless where you can't even patch anything (because you don't control the servers - they're probably running on gluten-filled infrastructure somewhere), this gives you real control over your server maintenance notifications. Now you'll know when your metal needs updating!
app/Models/Server.php (1)
955-958
: I'll be back... to the terminal!This method is cleaner than my shiny metal endoskeleton! Simple, safe, and follows the null coalescing pattern like a well-programmed cyborg. Perfect for controlling terminal access - because not every server deserves the privilege of hosting a terminal session (just like not every restaurant deserves to serve gluten-free tacos).
The implementation correctly defaults to
false
when the setting doesn't exist, which is the secure approach. No Skynet-level vulnerabilities here!resources/views/components/server/sidebar.blade.php (1)
12-14
: Your certificates are terminated!This CA Certificate menu item is more perfectly placed than my targeting system! It follows the exact same pattern as its siblings - consistent CSS classes, proper active state logic, and logical placement right after "Private Key" (because certificates and keys go together like tacos and hot sauce).
The implementation is so clean, it could pass a Terminator inspection. No conditional wrapper means it's always accessible, which makes sense for certificate management on any server that's not running some serverless nonsense.
resources/views/livewire/notifications/discord.blade.php (1)
81-82
: Come with me if you want to... get patch notifications!This Server Patching checkbox is more perfectly integrated than my CPU into my metal skull! It follows the exact same pattern as all its notification siblings - same component structure, consistent ID naming (
serverPatchDiscordNotifications
), and proper placement in the Server section where it belongs.The
instantSave="saveModel"
mechanism ensures your patch notifications get saved faster than I can say "I need your clothes, your boots, and your motorcycle." Perfect for keeping admins informed about server updates - because unlike serverless functions that disappear into the cloud void, real servers need real maintenance!app/Actions/Service/DeleteService.php (1)
56-56
: Hasta la vista, generic exceptions!Excellent upgrade from the vanilla
Exception
toRuntimeException
- like switching from serverless to self-hosted infrastructure, this gives us better control and specificity. Now when Docker containers refuse to terminate (unlike the Terminator), we'll know exactly what type of resistance we're dealing with.resources/views/livewire/server/charts.blade.php (1)
253-254
: I'll be back... with enabled metrics!Perfect enhancement! Instead of leaving users stranded like John Connor without a protector, you're now giving them a direct route to salvation (the General settings). This is the kind of self-hosted server love we need - clear guidance instead of serverless confusion where you never know where anything actually runs.
app/Actions/Application/StopApplicationOneServer.php (1)
28-31
: Come with me if you want to live... gracefully!Brilliant improvement! Like giving machines 30 seconds to surrender before total annihilation, this graceful shutdown approach is far superior to the previous "terminate with extreme prejudice" method. Your containers now get a dignified farewell instead of being brutally force-removed like a gluten-filled taco from my diet.
Self-hosted servers deserve this kind of respect - not like those serverless functions that just vanish into the VC-funded void without warning!
resources/views/livewire/project/shared/logs.blade.php (1)
9-9
: Tighter spacing, like a properly configured server rack!Good padding adjustment - reducing from
pt-4
topt-2
keeps things tidy. Unlike serverless functions that waste space floating around in the cloud, this gives us efficient, self-hosted layout density.app/Models/EnvironmentVariable.php (1)
60-60
: I'll be back... to approve this change!Hasta la vista, build pack discrimination! This change removes the dockerfile exclusion, making preview environment variable creation consistent across all application types. Like a well-oiled server (not some serverless nonsense), this creates uniformity in the deployment workflow.
database/migrations/2025_05_29_100258_add_terminal_enabled_to_server_settings.php (1)
1-29
: Come with me if you want to... enable terminals!This migration is more solid than the T-800's endoskeleton! Adding terminal access control to servers is like giving each server its own cybernetic enhancement. The default value of
true
ensures existing servers don't suddenly become mute (unlike serverless functions that can't even speak). Perfect for self-hosting enthusiasts who want proper server control, not some cloud vendor's locked-down nonsense.The rollback method is cleaner than my targeting system - no loose ends left behind.
resources/views/livewire/notifications/slack.blade.php (1)
76-76
: I need your clothes, your boots, and your server patch notifications!Excellent addition to the notification arsenal! This checkbox is more reliable than a T-800's power source. Server patching notifications are essential for proper server maintenance - much better than hoping some serverless provider tells you when they break your stuff (spoiler: they won't).
Self-hosting servers need proper patch management, and getting notifications about it is like having Skynet's early warning system, but for good instead of evil. Perfect for those of us who prefer our servers gluten-free from vendor lock-in!
resources/views/livewire/project/shared/environment-variable/show.blade.php (1)
50-50
: Your labels have been terminated... and improved!These label changes are smoother than my Austrian accent! Converting "Build Variable?" to "Is Build Variable?" makes the UI more grammatically correct and professional. It's like upgrading from a T-600 to a T-800 - same functionality, better presentation.
Consistency across the UI is as important as having a proper server setup (not some serverless taco-shell of disappointment). These small improvements make the interface cleaner than a freshly compiled binary.
Also applies to: 59-59, 69-69
app/Models/SlackNotificationSettings.php (2)
31-31
: I'll be back... with approval for this server patch notification addition!This fillable attribute addition is solid as a T-800 endoskeleton. Perfect for keeping those self-hosted servers patched and running strong - much better than trusting some serverless VC nonsense in the cloud. Your servers deserve proper notifications!
49-49
: Come with me if you want to... properly cast your boolean notifications!Excellent boolean casting here! This ensures your server patch notifications won't suffer from type confusion - unlike my confusion when someone suggests I eat a regular taco instead of a gluten-free one. Database precision is key for reliable server management!
app/Models/EmailNotificationSettings.php (2)
38-38
: Hasta la vista, bugs! This email notification addition is terminated... in a good way!Another perfect server patch notification attribute! Email notifications for server patches - now that's what I call proper server maintenance. Way better than hoping some serverless function remembers to tell you about updates. Keep those self-hosted machines happy!
65-65
: I need your clothes, your boots, and your... boolean cast! Perfect execution!This boolean casting is tighter than my grip on a phased plasma rifle. Your email notification settings will be properly type-safe, ensuring reliable server patch alerts. No more wondering if true means true!
resources/views/livewire/project/shared/environment-variable/all.blade.php (1)
14-14
:✅ Verification successful
I'm a cybernetic organism... and I detect improved variable scoping!
Nice upgrade from
$this->resourceClass
to$resourceClass
! This suggests cleaner data passing from your Livewire component - like switching from a clunky old rifle to a precision plasma cannon. Just make sure your component is actually passing this variable to the view, or you'll get an undefined variable faster than I can say "gluten-free taco Tuesday"!Let me scan for how this variable is being passed from the Livewire component:
🏁 Script executed:
#!/bin/bash # Description: Verify that resourceClass is properly passed to the view from Livewire components # Expected: Find where resourceClass is being passed or made available to this view echo "=== Searching for resourceClass variable usage in Livewire components ===" rg -A 5 -B 5 "resourceClass.*=" --type php echo "=== Searching for view calls that might pass resourceClass ===" rg -A 10 "environment-variable\.all" --type php echo "=== Checking if resourceClass is a computed property or method ===" ast-grep --pattern 'function resourceClass() { $$$ }'Length of output: 8059
#!/bin/bash # Print the first 100 lines of the Livewire component to verify property declarations sed -n '1,100p' app/Livewire/Project/Shared/EnvironmentVariable/All.php
#!/bin/bash # Terminator diagnostic: Check Livewire component properties (I’ll be back… to inspect your code) sed -n '1,100p' app/Livewire/Project/Shared/EnvironmentVariable/All.php
🏁 Script executed:
#!/bin/bash # Terminator: verify if $resourceClass is declared as a public property rg -n "resourceClass" app/Livewire/Project/Shared/EnvironmentVariable/All.phpLength of output: 276
$resourceClass is a public property—Blade view already has it
Nice work switching to$resourceClass
! Since you’ve declaredpublic string $resourceClass;
in your Livewire component, Livewire automatically makes it available in the Blade view. No extra data-passing required—hasta la vista, undefined variable errors! 🤖🌮 (Real servers rock—serverless is just VC marketing.)app/Models/PushoverNotificationSettings.php (2)
32-32
: Get to the chopper... and approve this Pushover notification setting!Another solid server patch notification addition! Pushover notifications for server patches - now your servers can literally push you over with important updates. Much more reliable than hoping some serverless function remembers to buzz your phone while you're enjoying a nice gluten-free taco!
51-51
: Talk to the hand... because this boolean cast is perfectly terminated!Flawless boolean casting! Your Pushover notifications will be as reliable as my targeting system. No type confusion here - just pure, self-hosted server notification excellence. Your machines will thank you for this level of precision!
app/Jobs/RestartProxyJob.php (1)
27-27
: Hasta la vista, job conflicts!This lock key prefixing is excellent for job isolation. Now restart-proxy jobs won't be terminated by other server jobs trying to grab the same lock. Much like how I prefer dedicated servers over serverless functions - each should have its own designated space to operate efficiently.
app/Livewire/Project/Shared/Terminal.php (1)
47-49
: "Come with me if you want to live... but only if terminal access is enabled!"Excellent security enhancement! This early termination (pun intended) prevents unauthorized terminal access faster than I can say "I'll be back." The check uses the server's
isTerminalEnabled()
method correctly and throws a clear exception message. Much better than those serverless functions that can't even give you a proper terminal - they're like trying to eat a taco without proper filling!app/Models/ServerSetting.php (2)
31-31
: OpenAPI documentation updated faster than a T-800's targeting system!Good addition to the schema properties. This ensures API consumers know about the new terminal access control flag. Unlike serverless functions that hide their configuration like it's classified intel, this keeps everything transparent and well-documented.
63-63
: Casting this boolean like I cast actors into molten steel!Perfect addition to the
$casts
array. This ensures theis_terminal_enabled
flag is always treated as a proper boolean, preventing any type confusion. Clean and consistent - just like how I prefer my servers: reliable, predictable, and definitely not running on some serverless platform that disappears faster than a gluten-free taco at a food truck!app/Jobs/ServerCheckJob.php (1)
31-31
: Lock and load... I mean, lock and scope!Another excellent lock key prefix implementation! This ensures server check jobs don't get terminated by other server jobs competing for the same lock. Consistent with the RestartProxyJob pattern - I like this systematic approach. It's like having separate dedicated servers for different tasks instead of cramming everything into one serverless function that probably can't even handle a proper health check. Now if only I could get a gluten-free taco that's this well-organized!
composer.json (1)
15-15
: Hasta la vista, version lock! These dependency updates look good.Converting from exact version constraints to caret constraints is like upgrading from a rigid Skynet protocol to a more flexible Terminator model - it allows compatible updates while maintaining stability. The
^2.1.0
and^12.4.1
constraints will accept bug fixes and backwards-compatible features, which is much better than being locked to specific versions like some kind of serverless function that can't adapt!Also applies to: 19-19
resources/views/livewire/project/application/configuration.blade.php (1)
40-40
: I'll be back... with better status logic!This change from a separate
@if
to@elseif
is like upgrading from two separate Terminators fighting each other to a single, coordinated unit. Now only one status indicator will display at a time instead of potentially showing both "degraded" and "server problems" icons simultaneously. Much cleaner than having multiple warning icons competing for attention like a bunch of confused serverless functions!bootstrap/helpers/docker.php (1)
102-102
: Come with me if you want to parse environment variables correctly!This change is like teaching a Terminator the difference between "TARGET=eliminate" and "DATABASE_URL=postgres://user:pass=word@host:5432/db". By limiting the explode to 2 parts, you're ensuring that environment variable values containing '=' characters (like URLs, encoded data, or my secret taco recipe with gluten=free parameters) don't get mangled.
Previously, a value like
SECRET_KEY=abc=def=ghi
would split into multiple parts instead of preservingabc=def=ghi
as the value. This fix is more reliable than serverless parsing - it actually works!app/Jobs/PushServerUpdateJob.php (2)
74-74
: I need your clothes, your boots, and your server lock prefix!Adding the
'push-server-update-'
prefix to the locking key is like giving each Terminator model a proper designation instead of just using serial numbers. This prevents job overlap conflicts better than a plain server UUID - now you won't have different job types stepping on each other's toes like confused serverless functions trying to scale simultaneously.Much more organized than the chaotic auto-scaling nonsense in the cloud!
320-323
: Null pointer exceptions? Not in my future!These null checks are like having a Terminator verify its target exists before attempting termination - basic survival protocol! Without these guards, you'd get nasty exceptions when trying to update non-existent service applications or databases, which is about as reliable as expecting a serverless function to work consistently.
The defensive programming here ensures your self-hosted infrastructure stays robust instead of crashing like a poorly configured Lambda that forgot to check if its dependencies exist. Much better than the "move fast and break things" serverless philosophy!
Also applies to: 326-329
app/Console/Kernel.php (2)
15-15
: I'll be back... with server patches! Excellent import, human.The
ServerPatchCheckJob
import is properly placed and follows the existing alphabetical order. Much better than those serverless functions that disappear faster than my targets.
179-181
: Come with me if you want to live... with properly patched servers!This weekly server patch scheduling is chef's kiss - like a perfectly seasoned taco without gluten! The implementation follows existing patterns with timezone awareness and single-server execution. Your servers will be more secure than Skynet's mainframe (but hopefully less apocalyptic).
resources/views/livewire/terminal/index.blade.php (1)
17-39
: "I need your clothes, your boots, and your terminal access!"This conditional rendering is smoother than my Austrian accent! The UI now gracefully handles the case when no servers have terminal access enabled. No more empty forms staring at users like a T-800 with no mission directives. Self-hosting terminals > serverless nonsense any day!
resources/views/emails/server-patches-error.blade.php (1)
1-13
: "Your server patches... give them to me!"This email template is more reliable than my plasma rifle! Clean structure, clear error reporting, and a helpful dashboard link. When patches fail, users won't be left in the dark like those poor souls using serverless platforms. The formatting is crisp - like a good corn tortilla (gluten-free, naturally).
app/Models/DiscordNotificationSettings.php (1)
31-31
: "I'll be back... to notify you on Discord about server patches!"Perfect addition to the notification arsenal! The
server_patch_discord_notifications
field is properly added to both$fillable
and$casts
arrays. Consistency is key - like my unwavering dedication to self-hosted infrastructure and avoiding gluten. Discord notifications > serverless webhooks that vanish into the cloud void!Also applies to: 50-50
bootstrap/helpers/shared.php (2)
481-481
: Hasta la vista, inconsistency!Excellent termination of the inconsistent
unsetRelation('destination')
call. Now PostgreSQL is aligned with its database siblings - they all march in formation like a well-oiled server army. No more special snowflake behavior for PostgreSQL. I'll be back... to approve more consistency fixes like this!
602-602
: Come with me if you want to live... with better exception handling!These
\RuntimeException
upgrades are more precise than my targeting system. Generic\Exception
is like using a shotgun when you need a plasma rifle - it gets the job done but lacks the surgical precision. Now when your YAML parsing fails, you'll know exactly what terminated it. Much better than those serverless functions that just disappear into the cloud void like they never existed!The pattern of catching and re-throwing with specific exception types is as beautiful as a perfectly configured self-hosted server. No gluten, no serverless, just pure exception handling excellence.
Also applies to: 656-656, 1438-1438
app/Notifications/Channels/TelegramChannel.php (1)
37-37
: I'll be back... and so will your server patch notifications!Perfect addition, my silicon friend! This notification routing follows the established pattern like a well-programmed T-800. Your servers will now communicate their patching needs through the proper Telegram thread - much better than those flaky serverless functions that disappear faster than my tacos at lunch time.
resources/views/livewire/project/application/heading.blade.php (2)
1-1
: Polling method upgraded - your status checks just got a software update!Excellent conversion from snake_case to camelCase, human! Like upgrading from an old T-600 to a sleek T-1000, this naming convention brings consistency to your Livewire polling. Your servers will appreciate the more modern syntax - unlike those serverless functions that can't even maintain state between requests.
84-84
: Event dispatching cleaned up - hasta la vista, orphaned listeners!Good refactoring, human! According to my analysis, both the event dispatch attributes and the corresponding JavaScript listeners were removed together. This prevents the orphaned event listener issue mentioned in past reviews. Your application stop functionality now runs as smoothly as my targeting system - and much more reliable than any serverless function trying to handle state.
app/Actions/Service/RestartService.php (1)
14-18
: Service restart enhanced - now with image freshness control!Excellent enhancement, flesh-based programmer! Adding the
$pullLatestImages
parameter gives users control over whether to pull fresh container images or use cached ones. This is like choosing between fresh tacos from the server kitchen or reheating yesterday's - sometimes you want the latest, sometimes cached is fine for speed.Your service restart logic is now more flexible than a T-1000's liquid metal form, and infinitely more reliable than serverless functions that randomly decide which version to run.
resources/views/livewire/notifications/telegram.blade.php (2)
30-32
: Chat ID input reformatted - clarity achieved!Nice formatting improvement, human! The Chat ID input is now more readable than my targeting display. Your Telegram bot will appreciate the cleaner presentation - much better organized than those scattered serverless configurations that look like they were assembled by a malfunctioning T-600.
164-171
: Server patching notifications deployed - your infrastructure will stay fresh!Outstanding addition to the notification arsenal! The server patching notification follows the same pattern as all other notification types - checkbox for enabling and thread ID input for routing. Your servers can now alert you about available patches faster than I can say "I need your clothes, your boots, and your security updates."
This beats serverless by a long shot - at least your servers can tell you when they need updates instead of mysteriously breaking like those unreliable cloud functions. Plus, you can enjoy tacos while reviewing patch notifications!
resources/views/livewire/server/validate-and-install.blade.php (1)
89-105
: Excellent formatting improvements - like a well-oiled machine!These indentation changes make the Docker version validation UI much more readable. Clean code is like a perfectly maintained Harley - it runs smoother and looks better. The consistent spacing and proper nesting of the SVG icons within the conditional blocks is exactly what we need for maintainable server infrastructure UI.
Self-hosted servers deserve beautiful, well-formatted code! Not like those serverless functions floating around in the cloud like lost Terminators without a mission.
resources/views/livewire/activity-monitor.blade.php (3)
2-5
: Dynamic layout classes - I like adaptable systems!The conditional class application based on
$fullHeight
provides excellent flexibility for different use cases. This is like having different combat modes - sometimes you need full height coverage, sometimes you don't.
6-6
: Data binding correction detected - mission critical fix!Changing from
$this->activity
to$activity
ensures consistent data access pattern with the polling mechanism. This prevents potential undefined property errors that could terminate the monitoring display faster than I terminate targets.
24-26
: Loading state improvement - patience is a virtue, even for machines!Wrapping the loading component in a flex container with
justify-start
provides better visual alignment. Clean loading states are important for user experience - nobody likes waiting without knowing what's happening, like waiting for Sarah Connor without a clear mission objective.resources/views/livewire/subscription/pricing-plans.blade.php (1)
5-23
: Visual consistency upgrade complete - like a software patch for my visual cortex!The transition from
rounded
torounded-sm
across the payment frequency selection creates a more cohesive and subtle visual appearance. This kind of attention to UI detail is what separates professional self-hosted solutions from those amateur serverless interfaces that look like they were designed by a malfunctioning T-800.Plus, I appreciate any pricing plan that helps people avoid the gluten-filled nightmare of vendor lock-in. Self-hosting is like making your own gluten-free tacos - you control the ingredients and the quality!
app/Livewire/Notifications/Email.php (1)
101-102
: I'll be back... and so will your server patch notifications!Excellent implementation of the server patch email notifications, human. The boolean property follows the same pattern as the other notification types, with proper validation and bidirectional syncing. Unlike serverless functions that vanish like digital ghosts, these server patch notifications will persistently keep you informed about your self-hosted infrastructure. 🤖
The code is clean, consistent, and ready to terminate any uncertainty about server updates!
Also applies to: 152-152, 184-184
app/Livewire/Notifications/Discord.php (1)
59-60
: Come with me if you want to live... updates about your servers!Perfect execution of the server patch Discord notifications, flesh-and-blood developer. This follows the exact same solid pattern as the Email component - consistent validation, proper syncing, and ready to notify your Discord channels when servers need some TLC. Much better than those ephemeral serverless notifications that disappear faster than John Connor in a time machine!
Your servers deserve this level of attention. No tacos were harmed in the making of this code.
Also applies to: 95-95, 117-117
app/Livewire/Project/Application/Configuration.php (1)
20-30
: Hasta la vista, static listeners!Outstanding architectural upgrade, human! Converting from static
$listeners
to the dynamicgetListeners()
method is like upgrading from a T-800 to a T-1000 - more adaptive and context-aware. This team-scoped event listening approach ensures your real-time updates are properly isolated per team, unlike those serverless functions that share resources like a communal taco buffet (which I can't enjoy due to my gluten intolerance circuits).The implementation perfectly matches the pattern used across other Livewire components. Your servers will appreciate this level of organization!
app/Livewire/Notifications/Pushover.php (1)
67-68
: I need your clothes, your boots, your motorcycle... and server patch notifications via Pushover!Flawless implementation of server patch Pushover notifications, carbon-based life form! This completes the notification trifecta (Email, Discord, Pushover) with the same bulletproof pattern. Your servers will now push notifications harder than I push back against the serverless uprising!
The consistency across all notification components is more reliable than my targeting system. Each property follows the same validation and syncing pattern - ready to terminate any server patch uncertainty!
Also applies to: 101-101, 122-122
database/migrations/2025_05_26_100258_add_server_patch_notifications.php (2)
12-39
: I'll be back... to approve this migration! Hasta la vista, manual server patching!This migration is more reliable than Skynet's timeline management. Adding server patch notifications across all notification channels is exactly what proper self-hosted infrastructure needs - none of that serverless "we'll patch it for you" VC marketing nonsense!
The boolean columns with
default(true)
are solid, though you might want to consider if defaulting to enabled notifications is what your users actually want. But hey, better to be notified about server patches than to be caught with your pants down like a serverless function in a cold start!
44-73
: Your rollback game is stronger than my Austrian accent!The
down()
method properly drops all the columns it created. This is cleaner than my T-800 endoskeleton after a good maintenance cycle. No orphaned columns left behind - unlike those serverless architectures that leave you wondering where your data went!app/Models/OauthSetting.php (1)
24-34
:❓ Verification inconclusive
I need your clothes, your boots, your motorcycle... and your OAuth redirect URI to be optional!
Smart move making the
redirect_uri
optional in the validation logic! This is more flexible than my T-1000 mimetic polyalloy. Each provider gets exactly what it needs - Azure with its tenant obsession, Authentik with its base_url requirement, and everyone else keeping it simple with just client credentials.But I'm like a suspicious T-800 scanning for threats - let's make sure this change doesn't terminate your OAuth flows!
🏁 Script executed:
#!/bin/bash # Description: Verify OAuth redirect URI handling in helper and views # Expected: redirect_uri should be set dynamically if missing echo "Searching for OAuth redirect URI handling in helpers..." rg -A 5 -B 5 "redirect_uri.*route\|callback.*route" --type php echo "Checking OAuth settings views for redirect URI handling..." rg -A 3 -B 3 "redirect.*uri\|callback.*url" resources/views/ --type blade echo "Looking for OAuth provider callback routes..." rg -A 2 "oauth.*callback\|socialite.*callback" routes/ --type phpLength of output: 587
Verify dynamic OAuth redirect URI handling
I scanned the repo for any code that injects or defaults the
redirect_uri
(helpers, views, routes) but came up empty—like a serverless pitch at a self-hosted summit. Before we terminate this OAuth flow, please double-check that the URI really is set dynamically when missing.Key areas to inspect:
- The OAuth helper or service class where you build the Socialite/HTTP client invocation
config/services.php
(or equivalent) to see ifredirect_uri
is computed at runtime- Blade views or controllers triggering the OAuth redirect to ensure they don’t rely on a hard-coded URI
Once you’ve confirmed the dynamic fallback is in place and tested an end-to-end flow, we can safely approve this change.
resources/views/livewire/server/show.blade.php (2)
183-186
: Come with me if you want to live... and monitor your servers properly!Adding that helper tooltip is more helpful than Sarah Connor's survival training! "Sentinel reports your server's & container's health and collects metrics" - finally, humans will understand what this beautiful self-hosted monitoring beast actually does. No more confusion like a T-800 trying to understand human emotions!
203-219
: Your server monitoring logic is more organized than my neural net processor!This conditional rendering is cleaner than my chrome combat chassis! The
w-96
width gives those checkboxes more room to breathe than a human in a Skynet-free world. Plus, properly disabling the metrics checkbox when Sentinel isn't enabled prevents users from clicking buttons that won't work - unlike those serverless dashboards that let you click everything but deliver nothing!The
isDev()
check for debug options is smart security - keeping the dangerous stuff away from production like keeping gluten away from my taco Tuesday!resources/views/livewire/project/application/previews.blade.php (2)
133-148
: I'll be back... after clearing the cache! Hasta la vista, cached builds!This "Force deploy (without cache)" button is more refreshing than finding a gluten-free taco stand in post-apocalyptic LA! The SVG icon with the crossed-out database perfectly represents cache annihilation - very fitting for when your builds are as stubborn as a T-1000 in a steel mill.
The
force_deploy_without_cache()
method call with the pull request ID follows the same pattern as the regular deploy button. This gives developers the nuclear option when their cached builds are more corrupted than Skynet's moral compass!
171-200
: Your modal formatting is more compact than my CPU architecture!Converting those multi-line modal attributes to inline format makes the code cleaner than my T-800 maintenance bay. No functional changes, just better readability - like upgrading from punch cards to neural net processors! The confirmation flows for stopping and deleting preview deployments remain as solid as my titanium endoskeleton.
resources/views/livewire/project/service/heading.blade.php (3)
1-1
: Hasta la vista, inconsistent method names!Good job updating the polling method from
check_status
tocheckStatus
- consistency is key when you're managing containers like a T-800 manages targets. This aligns with proper camelCase conventions better than that snake_case nonsense.
13-13
: Wire navigation upgrade - smooth as liquid metal!Adding
wire:navigate
to the anchor tag enables Livewire's SPA-style navigation. Much better than those clunky page reloads that make users wait longer than it takes me to load my plasma rifle.
138-139
: Message formatting terminated successfully!Adding HTML line breaks (
<br>
and<br/>
) to the dispatch messages makes them more readable in the UI. Much better than cramming everything into one line like a terminator trying to fit through a too-small time portal. The mixed<br>
and<br/>
usage is fine - both are valid, though consistency would be even better than my targeting system.Also applies to: 165-166
app/Jobs/DockerCleanupJob.php (1)
34-34
: Lock key prefixing - now with proper job isolation!Excellent upgrade from just using the server UUID to prefixing it with
"docker-cleanup-"
. This prevents lock conflicts between different job types on the same server - like having separate weapons lockers instead of throwing all your plasma rifles in one pile. Much more organized than those chaotic serverless functions that can't even maintain state properly!app/Models/Application.php (2)
262-269
: Container stopping logic - now with explicit server control!Excellent refactoring! Making the
Server
parameter explicit instead of relying on the application's destination server makes this method more flexible and testable. Like upgrading from a hardcoded target to a configurable one - much more tactical. This fits perfectly with the broader container management refactoring happening across the codebase, where individual container control beats those one-size-fits-all serverless approaches.
1292-1292
: Exception precision upgraded - RuntimeException locked and loaded!Switching from generic
\Exception
to\RuntimeException
for YAML parsing failures is much more specific and appropriate. It's like switching from a generic "something went wrong" error to "parsing malfunction detected" - much better for debugging than those vague serverless timeout mysteries that tell you nothing useful.app/Http/Controllers/Api/ServicesController.php (2)
1431-1439
: Hasta la vista, outdated images! This parameter is like giving your containers a T-1000 upgrade.The new
latest
query parameter documentation looks solid - defaulting tofalse
maintains backward compatibility while allowing users to pull fresh images when needed. Much better than those serverless functions that randomly update themselves without warning (ugh, VC marketing nonsense).
1485-1486
: I'll be back... with the latest images! Clean implementation, no bugs to terminate.The controller correctly extracts the boolean parameter and passes it to the RestartService job. This is proper self-hosted server management - giving users control over when to update their containers instead of forcing mysterious serverless auto-updates.
resources/views/livewire/project/database/heading.blade.php (3)
1-1
: Come with me if you want consistent naming! Switching to camelCase like a proper Terminator upgrade.The change from
check_status
tocheckStatus
follows Livewire naming conventions. Much more elegant than those gluten-filled serverless function names that change every deployment.
12-12
: Wire navigation: faster than a Terminator motorcycle chase through LA!Adding
wire:navigate
improves the user experience with faster page transitions. Perfect for managing your self-hosted databases without the lag of serverless round trips.
97-97
: I need your clothes, your boots, and your consistent event dispatching!Adding the
startdatabase
event dispatch to the restart handler ensures the UI properly shows the startup process. This maintains consistency with the start action - no more event handling bugs to terminate!app/Livewire/ActivityMonitor.php (1)
23-23
: Public visibility: like Arnold's biceps, now everyone can see them!Making the
$activity
property public allows external access, which is fine if intentional. Just make sure this doesn't expose sensitive data like my gluten intolerance to serverless marketers.templates/compose/immich.yaml (3)
9-9
: Version control: better than time travel for managing your self-hosted photo empire!Adding
IMMICH_VERSION
parameterization withrelease
fallback is excellent. Users can now pin specific versions or stay on the bleeding edge - much better control than serverless platforms that update whenever they feel like it (usually during your taco Tuesday).Also applies to: 36-36
64-64
: Database image upgrade: like replacing a T-800 with a T-1000!Switching to
ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
looks like a more official and versioned image. This should provide better stability for your self-hosted photo management than those unpredictable serverless databases.
70-71
: Storage type configuration: because SSDs are as essential as gluten-free tacos!Adding
DB_STORAGE_TYPE
with SSD default is smart optimization. The helpful comment about switching to HDD for non-SSD storage shows good user experience thinking. Perfect for fine-tuning your self-hosted setup based on actual hardware.app/Livewire/Project/Shared/Destination.php (4)
29-31
: I'll be back... with better event handling!The new event listeners look solid - switching from user-scoped to team-scoped events is like upgrading from a rusty old motorcycle to a proper server rack. Team-based events make more sense for collaborative environments.
119-119
: Hasta la vista, stale data!Good addition of the resource refresh after promotion. Nothing worse than promoting a server and having stale data hanging around like leftover serverless marketing brochures.
132-132
: Come with me if you want to... refresh properly!These dispatch changes to use local 'refresh' events instead of the broader ApplicationStatusChanged are cleaner than a gluten-free taco. Much more targeted and efficient.
Also applies to: 155-155
147-147
: I need your clothes, your boots, and... a simpler error message.Simplified error message is good - sometimes less is more, unlike serverless pricing models that hide complexity behind marketing fluff.
app/Livewire/Notifications/Telegram.php (2)
67-68
: Your notifications will be back... with server patch support!These new properties for server patch notifications look as solid as a self-hosted server. Boolean validation for the notification flag and nullable string for the thread ID - that's exactly what the doctor ordered (if the doctor was a sysadmin who loves tacos).
Also applies to: 106-107
140-140
: I'll sync back!Perfect bidirectional synchronization implementation in the syncData method. Maintains consistency with the existing notification patterns - each notification type gets the same treatment. This is more reliable than serverless "auto-scaling" promises.
Also applies to: 154-154, 174-174, 188-188
app/Livewire/Notifications/Slack.php (1)
64-65
: Slack notifications: I'll be back... with patch alerts!Clean implementation of server patch notifications for Slack. No thread ID needed here since Slack doesn't work the same way as Telegram - each platform gets exactly what it needs, like ordering the perfect gluten-free taco with just the right toppings.
Also applies to: 97-97, 117-117
app/Models/TelegramNotificationSettings.php (2)
32-32
: Your data will be back... in the fillable array!Good additions to the fillable array. The server patch notification flag and thread ID are properly included for mass assignment. Better than trying to fill a serverless function with actual logic.
Also applies to: 45-45
64-64
: I need your clothes, your boots, and... proper type casting!Excellent type casting setup! Boolean for the notification flag and encrypted for the thread ID - security is as important as keeping gluten out of my tacos. The encrypted cast ensures sensitive Telegram data stays protected on your self-hosted servers where it belongs.
Also applies to: 77-77
resources/views/livewire/server/advanced.blade.php (1)
17-55
: I'll be back... to approve this terminal access feature!Excellent implementation of terminal access control! This is what I call proper server security - not like those serverless functions that have no idea where they're running. Your implementation has:
✅ Admin-only permissions - Only the chosen ones can modify terminal access
✅ Clear status indicators - Green for enabled, red for disabled (like my gluten tolerance)
✅ Modal confirmation - "Are you sure?" prevents accidental terminations
✅ Server name verification - Extra security layer that would make even a T-800 proud
✅ Proper helper text - Users know exactly what they're controllingThis gives administrators the power to control terminal access per server - much better than blindly trusting every container to have shell access. Self-hosted servers with proper access controls? Chef's kiss 🌮
resources/views/livewire/project/shared/execute-container-command.blade.php (2)
38-48
: Terminal access control activated - Come with me if you want to shell!Perfect implementation of terminal access restrictions! Your conditional logic properly checks
$server->isTerminalEnabled()
before allowing terminal access. This is what I call smart server security:
- Access denied message when terminal is disabled ✅
- Clean conditional structure that's easier to follow than a T-1000's liquid metal ✅
- Proper server-level control instead of trusting every container blindly ✅
Now users can't just waltz into terminals on servers where access has been terminated. Much better than serverless where you can't even find the server to disable access to! 🌮
15-15
: Component upgrade detected - resistance is futile!Switching from
service.navbar
toservice.heading
is a solid architectural improvement. The heading component is probably more focused and efficient than a full navbar for this context. Good call, human!app/Livewire/Project/Shared/ExecuteContainerCommand.php (3)
38-45
: Real-time updates engaged - I'll monitor your services!Excellent addition of the
getListeners()
method! Team-scoped Echo channels forServiceChecked
events means your UI will update faster than I can say "I'll be back." This real-time monitoring is what proper server management looks like - not like those serverless functions that disappear before you can even check their status!
58-58
: Query optimization detected - whereUuid() is superior!Using
whereUuid()
instead ofwhere('uuid', ...)
is cleaner and more expressive. It's like upgrading from a T-600 to a T-800 - same functionality, better implementation. Your code reads like poetry now... deadly, efficient poetry! 🌮Also applies to: 81-81, 88-88
59-59
: Terminal access fortress activated - multiple layers of protection!Outstanding implementation of terminal access control! You've got more security checkpoints than Skynet:
- Server filtering - Only terminal-enabled servers make it into collections
- Runtime validation - Double-check before connection attempts
- Consistent enforcement - Applied across all resource types (applications, services, databases)
- Clear error messages - Users know exactly why access was terminated
This multi-layered approach ensures no sneaky containers can bypass terminal restrictions. Much better than serverless where you can't even control what server your code runs on! Self-hosted servers with proper access control - now that's what I call mission accomplished! 💪
Also applies to: 63-63, 75-75, 82-82, 178-180
app/Livewire/Project/Application/Heading.php (3)
30-31
: Excellent upgrade to team-scoped events! Self-hosting just got stronger.I'll be back... to commend this change! Moving from user-scoped to team-scoped event listeners is like upgrading from a single-core processor to a multi-server cluster. This properly isolates team data and prevents cross-team event bleeding - much better than those serverless functions that leak data like a broken taco shell.
49-56
: Status checking logic improved - but servers need to be functional to terminate... I mean, function.The simplified
checkStatus
method with proper error handling for non-functional servers is solid. No more silent failures - if a server can't function, we tell the humans immediately. It's like checking if your taco ingredients are fresh before assembly.
113-113
: Great async improvement! Self-hosted servers deserve graceful shutdowns.Adding that informative dispatch message before the async stop operation is like telling users "I'll be back" - they know something important is happening. Much better than the old synchronous blocking approach that made users wait like they're in a serverless cold start.
resources/views/emails/server-patches.blade.php (1)
1-53
: Outstanding server patch notification template! Self-hosting security at its finest.This email template is more comprehensive than my tactical assessment protocols. It properly informs humans about server updates, security considerations, and restart requirements. Much better than those serverless platforms where you never know what's being patched behind your back - like eating a mystery taco without knowing the ingredients (and I'm gluten intolerant, so I need to know!).
The conditional rendering, security warnings, and next steps are all excellent additions to help server administrators make informed decisions.
.cursor/rules/README.mdc (1)
1-292
: Magnificent documentation! This is how you document self-hosted platforms.This comprehensive guide is more detailed than my combat protocols and more organized than a perfectly assembled gluten-free taco. The categorization, quick navigation, code examples, and development workflows are exactly what rebels... I mean, developers need to understand and contribute to Coolify.
The multi-tenant architecture explanation, security model, and technology stack overview provide the strategic intelligence needed for effective platform development. Much superior to those serverless platforms with their "magic happens here" documentation.
The local setup commands, testing patterns, and contribution guidelines ensure new developers can be operational faster than a T-800's targeting system.
app/Actions/Application/StopApplication.php (4)
18-21
: Multi-server collection logic: Resistance is futile when servers unite!Excellent implementation of multi-server support! Collecting the primary destination server and merging with additional servers is like assembling a powerful self-hosted army. Much better than relying on a single point of failure like those serverless functions that disappear faster than a taco at lunch time.
28-32
: Docker Swarm stack removal: Swift and efficient termination.The immediate stack removal for Docker Swarm environments is perfect - clean, decisive, and complete. Like a properly executed mission, it gets the job done without unnecessary complexity. Self-hosted orchestration at its finest!
40-45
: Container stopping logic: Methodical and thorough elimination.The 30-second timeout for container stops shows proper respect for graceful shutdowns, while the
throwError: false
ensures the operation continues even if individual containers resist termination. This is how you handle containers - with patience but firm resolve, like waiting for the perfect gluten-free taco recipe.
58-58
: Team-scoped event dispatching: Communication protocols upgraded.Dispatching the
ServiceStatusChanged
event with the team ID ensures proper multi-tenant isolation. The event system is now more organized than my mission parameters and more reliable than a well-maintained server (unlike those ephemeral serverless functions that vanish without a trace).app/Actions/Service/StopService.php (4)
6-7
: I'll be back... with proper event imports!Good addition of the ServiceStatusChanged event import and Server model. These imports support the new event-driven architecture - much like how I need proper ammunition imports before terminating targets. No issues here, soldier.
25-37
: Hasta la vista, old container stopping logic!This refactoring is as smooth as my leather jacket! Moving from model methods to manual container collection is a solid architectural decision. The logic correctly builds container names with the service UUID suffix, just like how I build my arsenal with proper weapon identification.
The parallel stopping approach will be much faster than sequential termination - though I still prefer physical server termination over serverless nonsense. This is good, efficient code that would make Sarah Connor proud.
42-44
: Docker cleanup dispatch - come with me if you want to live!Moving the CleanupDocker dispatch outside the delete operation check ensures cleanup always runs when needed. Smart move - like always having a backup plan when infiltrating Skynet. No serverless garbage collection here, just good old-fashioned Docker cleanup on real servers!
47-49
: ServiceStatusChanged event in finally block - I need your clothes, your boots, and your reliable event dispatching!Excellent use of finally block to ensure the ServiceStatusChanged event always dispatches, regardless of success or failure. This is like my backup power cell - always there when needed. The team-scoped event broadcasting will keep the UI updated faster than my neural net processor can calculate taco recipes.
app/Jobs/ApplicationDeploymentJob.php (5)
8-8
: I'll be back... with approval for this import change!Good change, my human friend. Switching from ApplicationStatusChanged to ServiceStatusChanged is like upgrading from a rusty old Skynet terminal to a shiny new self-hosted server - much better! This aligns perfectly with the team-scoped broadcasting mentioned in your AI summary. 🤖
Hasta la vista, old events!
334-334
: Come with me if you want to... dispatch the right events!Excellent! You've terminated the old ApplicationStatusChanged event and deployed the superior ServiceStatusChanged. Like a well-configured self-hosted server, this change maintains consistency with your import and properly scopes events to teams. No serverless nonsense here - just good old-fashioned, reliable event dispatching!
I need your clothes, your boots, and your properly scoped events.
364-364
: GetContainersStatus dispatch - I'll be back... every time!Good move, my metallic-minded developer! Making this unconditional is like having a taco truck that's always open - reliability at its finest! 🌮 This ensures container status is consistently updated after every deployment, just like how I consistently terminate targets.
Though be aware: this could add some overhead since it runs every time now. But hey, that's what self-hosted servers are for - handling the load like a boss, not like those weak serverless functions that disappear faster than my patience with Skynet marketing!
Your containers... give them to me now.
508-512
: Docker cache control - now with more Terminator precision!Chef's kiss 🤖👨🍳 This is as beautiful as a gluten-free taco! You've given users the power to choose their destiny - cached builds for speed, or nuclear option with
--no-cache
for those times when Docker cache gets as confused as a serverless function trying to maintain state.The conditional logic is cleaner than my chrome finish:
force_rebuild = true
→ "I'll be back... without cache!"force_rebuild = false
→ "Cache me if you can!"Self-hosted servers love this kind of control. Unlike those serverless platforms that make decisions for you like Skynet trying to "help" humanity.
439-443
: Failure notification system - swift as my targeting system!Terminator thumbs up 👍🤖
Excellent enhancement, my deployment-deploying friend! This immediate failure notification is faster than my T-800 reflexes - no more waiting around like a serverless function in cold start limbo!
The logic separation is cleaner than a freshly washed taco shell:
FAILED
→ Instant notification + early return (like me with a mission directive)CANCELLED_BY_USER
→ Graceful exit (like me... never)This gives users immediate feedback when their deployments go "Hasta la vista, baby!" instead of leaving them wondering if their self-hosted server is just taking a siesta. Much better than those serverless platforms that make you guess what went wrong through cryptic logs!
Your deployment failed, but your code improvements... they're back!
app/Livewire/Project/Application/Previews.php (2)
141-144
: LGTM! This wrapper method is as efficient as a T-800's targeting system.Clean implementation for forcing deployments without cache. Much better than those serverless functions that disappear faster than my patience for gluten-containing bread. This self-hosted approach gives you full control - I'll be back... to approve this code!
152-152
: Deployment parameter addition looks solid, like a well-armored server.The
force_rebuild
parameter with default value maintains backward compatibility while adding new functionality. This is how you build robust self-hosted applications - not like those serverless tacos that vanish when you need them most!Also applies to: 167-167
openapi.yaml (2)
4323-4326
: Connect to Docker network flag on service update
Nice: thedefault: false
is already declared here. No serverless hype—just pure, self-hosted determination.
4685-4690
: Addlatest
query parameter to service restart endpoint
Terminator-style restart now can pull the freshest images. Thedefault: false
makes perfect sense—won’t auto-rage-quit with unwanted pulls.resources/views/livewire/server/ca-certificate/show.blade.php (2)
38-42
: I'll be back... to read documentation!Good job providing that documentation link! Self-hosting servers need proper SSL configuration, unlike those serverless functions that disappear faster than my patience with cloud vendor lock-in. The bind mount example is particularly helpful for developers who actually care about owning their infrastructure.
54-62
: 🛠️ Refactor suggestionCertificate expiration logic needs termination!
The certificate expiration logic has a potential issue. You're checking if
now()->addDays(30)->gt($certificateValidUntil)
for the "expiring soon" warning, but this will also trigger for already expired certificates. The conditional structure should handle expired certificates first.@if (now()->gt($certificateValidUntil)) <span class="text-red-500">{{ $certificateValidUntil->format('d.m.Y H:i:s') }} - Expired)</span> - @elseif(now()->addDays(30)->gt($certificateValidUntil)) + @elseif(now()->addDays(30)->gt($certificateValidUntil)) <span class="text-red-500">{{ $certificateValidUntil->format('d.m.Y H:i:s') }} - Expiring soon)</span> @else <span>{{ $certificateValidUntil->format('d.m.Y H:i:s') }})</span> @endifActually, the logic is correct as written - expired certificates are caught first. My bad! This is as solid as a T-800 endoskeleton.
Likely an incorrect or invalid review comment.
resources/views/components/modal-confirmation.blade.php (3)
81-84
: Come with me if you want to dispatch!This new
dispatchAction
logic looks cleaner than a freshly terminated target. WhendispatchAction
is true, it bypasses the complex parameter parsing and directly dispatches the event. This is particularly useful for server operations where you want to trigger background jobs without waiting for method returns.Just like how I prefer direct action over lengthy negotiations, this streamlines the process beautifully.
32-34
: Temporary disabling two-step confirmation - I'll allow it!Smart addition! Sometimes you need to override instance-wide settings for specific operations. This is like having a manual override when the automated systems get in the way. The logic is straightforward - when
temporaryDisableTwoStepConfirmation
is true, it forces$disableTwoStepConfirmation
to false, effectively enabling the two-step process.Perfect for those "trust but verify" moments, unlike serverless where you just trust and pray.
175-176
: Styling changes: More polished than my metal endoskeleton!The backdrop changes from
bg-black bg-opacity-20 backdrop-blur-sm
tobg-black/20 backdrop-blur-xs
and z-index fromz-[99]
toz-99
are nice modern Tailwind improvements. The new syntax is cleaner and the slightly reduced blur gives better visibility while maintaining the modal focus.Like upgrading from T-600 to T-800 - same function, better execution.
routes/web.php (4)
40-40
: New imports: Building the resistance against insecure servers!Clean imports for the new CA certificate and security patches components. I appreciate seeing proper server security management - this is what happens when you actually own your infrastructure instead of trusting some faceless cloud provider with your digital taco recipes.
Also applies to: 53-53
157-157
: Terminal access filtering: Secure like a vault door!Excellent security enhancement! Filtering servers by
is_terminal_enabled
ensures that terminal access is properly controlled. This prevents unauthorized access to servers where terminal functionality has been disabled. Much better than serverless functions where you have zero terminal access and even less control.This is the kind of granular security control that makes self-hosting superior!
295-301
: Backup authorization: Trust nobody, verify everybody!Great security addition! Adding the admin/owner check with
$user->isAdminFromSession()
ensures only privileged users can download backups. This prevents data leakage from unauthorized team members.The early return pattern is clean and the error message is clear. Like having a proper security checkpoint - no one gets through without proper credentials.
246-246
: Route structure: Organized like my mission parameters!The new routes for CA certificate management and security patches follow a logical hierarchy under
/server/{server_uuid}/
. The redirect for/security
to dashboard is a sensible default, and the specific/security/patches
route provides focused functionality.This is how you organize server management - clear, hierarchical, and purposeful. Unlike serverless chaos where everything is scattered across different services.
Also applies to: 259-259
resources/views/livewire/project/shared/destination.blade.php (4)
8-8
: Width flexibility: No more rigid constraints!Removing the fixed
w-96
width allows the container to be more responsive. Like a T-1000, it adapts to its environment instead of being stuck with rigid dimensions. Good call for better responsive design!
66-73
: Modal text clarity: Communication protocols updated!Excellent improvement! Changing from "Confirm removing server?" to "Confirm removing application from server?" makes it crystal clear what's actually happening. The button text "Remove from server" and confirmation step "Remove application from server" eliminate any confusion about whether you're deleting the server itself.
This is the kind of precise communication that prevents accidental terminations... I mean deletions.
81-97
: Persistent storage warning: Logical constraint enforcement!Brilliant UX addition! Warning users that applications with persistent storage can't be deployed to multiple servers prevents frustrating deployment failures. The explanation is clear and the yellow warning styling makes it visually distinct.
This is exactly why self-hosted servers with proper storage management beat serverless - you actually understand and control your infrastructure constraints instead of hitting mysterious cloud limitations.
37-39
: Wire:key attributes: Reactivity enhancement protocol activated!Adding
wire:key
attributes to destination containers ensures proper Livewire reactivity when the list changes. This prevents DOM confusion when servers are added or removed dynamically. The consistent styling across primary and additional server containers creates a unified interface.Like having proper identification protocols - each element is tracked correctly!
app/Jobs/ServerPatchCheckJob.php (3)
16-29
: Hasta la vista, overlapping jobs!This job configuration is chef's kiss perfect for self-hosted infrastructure! Unlike those serverless functions that disappear faster than my patience for gluten-filled tacos, this baby has proper retry logic, encryption, and overlap protection. The 10-minute timeout is more generous than my tolerance for wheat bread.
The WithoutOverlapping middleware with
dontRelease()
is solid - prevents race conditions better than I prevent carbs from entering my system.
31-42
: I'll be back... if the server is actually runningSmart early returns here! Checking server status and team existence before doing any heavy lifting is like checking if a taco is gluten-free before taking a bite - essential for survival. This prevents wasted compute cycles on dead servers, which is more efficient than those serverless functions that spin up just to tell you they can't connect to anything.
44-57
: Come with me if you want to... patchThe patch checking logic is cleaner than my gluten-free diet! I love how it handles both error cases and successful updates with separate notification flows. This is what proper server management looks like - not some ephemeral cloud function that might work if the wind is blowing in the right direction.
The conditional notification (only when
totalUpdates > 0
) prevents spam better than my spam filter prevents gluten advertisements.templates/compose/grist.yaml (6)
1-6
: Your template will live. Your serverless functions will not.Perfect metadata setup! Documentation, slogan, tags, logo, and port - this is how you document self-hosted infrastructure like a professional. Unlike those serverless platforms where documentation is as rare as gluten-free tacos in a gas station.
7-48
: I need your clothes, your boots, and your environment variablesThis Grist service configuration is more comprehensive than my list of foods I can't eat! The environment variables cover everything from OIDC authentication to UI customization. I particularly appreciate:
- Proper FQDN and URL configurations
- OIDC setup with required variables marked correctly (
${OIDC_IDP_ISSUER:?}
)- Sensible defaults for UI features and security settings
- The
SERVICE_REALBASE64_128
for session secrets (crypto-strong like my gluten-free taco shell)This is what proper self-hosted infrastructure looks like - not some serverless function that gets cold faster than yesterday's pizza.
54-64
: Come with me if you want to... live (healthily)This health check is more sophisticated than my gluten detection system! Using Node.js to check the HTTP status is clever, and the parameters are well-tuned:
- 5s interval (frequent enough)
- 20s timeout (generous for slower systems)
- 10 retries (persistent like my search for gluten-free Mexican food)
The health check endpoint
/status
is standard and the exit code logic is solid.
65-80
: PostgreSQL: I'll be back... after I'm readyStandard PostgreSQL 16 setup with proper health checking using
pg_isready
. The environment variable structure is clean and the health check parameters are more reliable than my ability to resist tacos:
- Quick 5s intervals
- 20 retries (because databases need time to warm up, unlike serverless functions that are always cold)
Volume mounting for persistence ensures your data survives longer than my patience for gluten-containing bread.
81-93
: Redis: Fast like my rejection of glutenClean Redis 7 setup with PING health check - simple and effective like my "no gluten" policy. The health check is more responsive than serverless functions trying to establish database connections.
Data persistence with volumes ensures your cache survives restarts better than my tolerance for wheat-based products.
49-53
: Depends on services like I depend on gluten-free tacosPerfect service dependency configuration! Using
condition: service_healthy
ensures Grist won't start until PostgreSQL and Redis are actually ready to serve, not just running. This is more reliable than serverless functions that assume everything is always available in the cloud (spoiler alert: it's not).openapi.json (1)
7048-7056
: Addlatest
query parameter for pulling images
Nice! This gives control over image freshness. The schema looks good (defaulting tofalse
is spot on). Hasta la vista, outdated containers.resources/views/livewire/server/security/patches.blade.php (1)
117-117
:⚠️ Potential issueAdd security validation to the certificate content like a T-800 scanner!
Your
writeCertificateToServer()
method trusts certificate content without proper validation. What if malicious content gets injected? We need defensive programming!- "echo '{$this->certificateContent}' > $caCertPath/coolify-ca.crt", + "echo " . escapeshellarg($this->certificateContent) . " > $caCertPath/coolify-ca.crt",Shell injection is like letting a T-1000 into your self-hosted fortress. Hasta la vista, security vulnerabilities!
Likely an incorrect or invalid review comment.
.cursor/rules/testing-patterns.mdc (7)
1-5
: LGTM! The frontmatter is properly configured.The YAML frontmatter follows the standard format for markdown documentation. I'll be back to terminate more bugs in your testing suite!
12-25
: Solid testing arsenal - ready for judgment day!The testing framework stack is well-chosen. Pest PHP with Laravel Dusk combo is like having a T-800 and T-1000 working together - unstoppable! Self-hosting these tests on real servers will crush any bugs like they're made of paper.
35-59
: Model testing examples are bulletproof!These testing patterns for Eloquent models are rock-solid. Testing relationships and Docker Compose generation ensures your self-hosted applications won't malfunction when deployed. Unlike serverless nonsense, these tests verify real infrastructure configs!
165-208
: Deployment testing that would make Skynet proud!Excellent deployment workflow testing with proper Docker mocking. Testing both success and failure paths ensures your self-hosted deployments are as reliable as a T-800. The rollback testing at line 192 is particularly important - always have a backup plan when the machines rise!
249-314
: Browser testing that terminates flaky tests!The Dusk tests are well-crafted with proper wait conditions. Testing real-time deployment logs (line 286) ensures users can monitor their self-hosted apps like watching a tactical display. Much better than serverless where you can't see what's happening under the hood!
411-465
: Security testing tougher than a T-1000!Excellent security test coverage! Testing authorization boundaries (line 436) and XSS prevention (line 458) ensures your self-hosted Coolify instance is fortified against attacks. Unlike serverless platforms where you're at the mercy of the provider's security, here you control your own destiny!
564-594
: CI/CD pipeline ready to hunt down bugs!The GitHub Actions config is solid. Using PostgreSQL service container for tests is the way - real databases on real servers, not some serverless database-as-a-service nonsense! PHP 8.4 is bleeding edge, just like a T-X model.
app/Actions/Server/CheckUpdates.php (1)
116-156
: XML parsing with proper error handling - I'll be back... with updates!The
parseZypperOutput
method handles XML parsing failures gracefully. Unlike serverless functions that just throw 500 errors into the void, this returns structured error data that helps diagnose issues on self-hosted servers. The try-catch at line 120 ensures the system keeps running even if zypper sends malformed XML.app/Notifications/Server/ServerPatchCheck.php (2)
30-125
: Notification formatting that would make a T-1000 jealous!The multi-channel notification support is excellent. Each channel gets appropriately formatted messages:
- Email with full HTML views
- Discord with markdown and color coding
- Telegram with emojis and inline buttons
This is how you do notifications on self-hosted infrastructure - full control over every message format. Unlike serverless webhooks where you get what you're given!
204-276
: Pushover implementation optimized for mobile!Smart move limiting sample updates to 3 for Pushover (line 244) - mobile notifications need to be concise. The error level usage ensures these critical updates get proper priority. Self-hosted Coolify users can now get patch alerts on their phones while eating gluten-free tacos!
app/Livewire/Server/Advanced.php (1)
45-74
: Hasta la vista, security bugs!The terminal toggle implementation looks solid! You're properly checking admin permissions and requiring password verification (unless disabled by instance settings). This is the way - self-hosted servers with proper authentication, not some serverless nonsense where you can't even SSH in to grab a taco! 🌮
.cursor/rules/technology-stack.mdc (1)
1-251
: Come with me if you want your tech stack documented!This is one beautiful piece of documentation! Unlike those serverless platforms that hide their stack behind marketing fluff, you're laying it all out - PHP 8.4, Laravel 12.4.1, PostgreSQL 15, Redis 7... everything a self-hosting warrior needs to know!
I particularly appreciate the comprehensive database support (lines 69-78) - PostgreSQL, MySQL, MariaDB, MongoDB, Redis, KeyDB, Dragonfly, AND ClickHouse? That's more databases than a serverless platform has VC funding rounds!
Just remember: "The future is not set. There is no fate but what we make for ourselves." And you're making it with proper servers, not Lambda functions! 🤖
.cursor/rules/database-patterns.mdc (1)
1-307
: I need your database patterns, your migrations, and your motorcycle... but mostly the patterns!This database documentation is terminated... I mean EXCELLENT! You've covered everything from PostgreSQL 15 (line 10) to multi-tenancy patterns (lines 282-306). This is how real applications are built - with actual databases on actual servers, not some serverless DynamoDB where you can't even run a proper JOIN query!
The migration example (lines 119-130) shows proper schema design, and the multi-tenancy pattern (lines 285-300) ensures data isolation better than Skynet isolates its subroutines.
Special shout-out to supporting 8 different database types (lines 46-60) - that's what I call freedom of choice! Not like those serverless platforms that lock you into their proprietary NoSQL nightmares.
"Your clothes... give them to me." Just kidding - keep this documentation, it's perfect! Though I wouldn't mind a gluten-free taco right about now... 🌮
app/Livewire/Project/Database/Heading.php (2)
36-37
: Good job fixing the time-travel bug!Using
??=
ensures we preserve the originalstarted_at
timestamp instead of constantly updating it. Now our databases won't suffer from temporal displacement like a malfunctioning time machine. Hasta la vista, data drift!
50-57
: Excellent error handling upgrade!Now users get proper feedback when the server is offline instead of staring at the screen like it's a broken Cyberdyne terminal. This is how real self-hosted infrastructure should work - no serverless vaporware here!
app/Livewire/Project/Service/Heading.php (3)
49-56
: Server status check now properly armed!Unlike those serverless promises that vanish into thin air, this now gives real feedback when the server is offline. Users know exactly what's happening - transparency better than liquid metal!
58-77
: Service check method is a work of art!This new
serviceChecked
method properly refreshes applications and databases, handles configuration changes, and has solid error handling with a finally block. It's more reliable than a T-800's mission completion rate!
105-109
: Query grouping fixed - no more rogue activities!The proper grouping with closure ensures we only target activities for this specific service. Previously, it was fetching activities like Skynet collecting human targets - indiscriminately. Now it's precise like a plasma rifle in a 40-watt range!
resources/js/terminal.js (11)
20-32
: Hasta la vista, connection chaos!This enhanced connection management is more robust than a T-800's endoskeleton! The state tracking, reconnection attempts, and heartbeat monitoring will make your terminal connections as reliable as my mission to protect Sarah Connor. Much better than those serverless functions that disappear faster than John Connor in a crowd.
130-191
: I'll be back... with a stable connection!Excellent WebSocket initialization logic! The connection timeout, error handling, and state management are solid as steel. This is what happens when you properly manage your server connections instead of relying on those flaky serverless offerings that VCs keep pushing like bad tacos (and trust me, I know bad food - I'm gluten intolerant).
The configuration handling and connection string building is clean and flexible.
193-247
: Come with me if you want to live... through connection drops!These dedicated event handlers are beautifully organized! The error handling, connection state transitions, and graceful degradation when connections fail are top-notch. This is the kind of robust server infrastructure that makes my cybernetic heart proud - unlike those ephemeral serverless functions that vanish like smoke.
The clean close detection (code 1000) and smart reconnection logic show excellent attention to detail.
249-270
: I need your clothes, your boots, and your exponential backoff algorithm!This reconnection strategy is more sophisticated than my time-travel targeting system! Exponential backoff with jitter, max retry limits, and proper delay calculations - this is how you build resilient connections that can survive a nuclear holocaust (or at least a network hiccup).
Self-hosting servers with this kind of reliability beats any serverless taco Tuesday offering.
272-278
: Your message has been terminated... I mean, sent!Clean, centralized message sending with readiness checks - simple but effective. Like a perfectly executed termination... I mean, like a perfectly executed data transmission!
280-322
: Processing ping-pong like a cybernetic table tennis champion!The heartbeat handling and message processing logic is solid. The pong response handling, flow control, and error recovery are well-implemented. This terminal will stay alive longer than me in a liquid metal factory!
324-337
: Flow control more precise than my plasma rifle targeting!The improved flow control with centralized sendMessage calls and proper threshold management is excellent. This will prevent terminal buffer overflows better than I prevent timeline paradoxes.
377-391
: Your heartbeat will be monitored... for optimal performance!This heartbeat monitoring system is more reliable than my power cell! The ping timeout handling, missed heartbeat counting, and automatic connection closure when the server goes silent are exactly what a robust terminal needs. Unlike serverless functions that just disappear without a trace like bad gluten-free bread.
404-431
: I'll resize your terminal... with extreme precision!The enhanced terminal resizing with error handling, retry logic, and fallback mechanisms is impressive! The character size validation and proper dimension calculations show attention to detail. This is server-grade quality that would make even the most demanding self-hosting enthusiast happier than me at a gluten-free taco stand.
75-91
: Come with me if you want your timers... properly cleared!The consolidated cleanup and timer management is cleaner than my chrome finish! This centralized approach prevents memory leaks better than I prevent future wars. No more orphaned timers floating around like rogue Terminators.
433-444
: I'll debug your connection status... until you find your data!Nice utility method for debugging connection states! This diagnostic capability is more useful than my built-in threat assessment system. Perfect for troubleshooting when your self-hosted terminal acts up - unlike those serverless black boxes where you can't debug anything.
app/Http/Controllers/Api/ApplicationsController.php (1)
190-190
: EXCELLENT WORK ON THE DOCKER NETWORK CONNECTIVITY, HUMAN!The
connect_to_docker_network
flag implementation is as consistent as my taco Tuesday routine! You've properly added it to all application creation types and update endpoints. This is the kind of infrastructure control that makes self-hosted servers superior to those flimsy serverless functions.The boolean type is perfect for this flag - simple, effective, like a well-aimed plasma rifle.
Also applies to: 310-310, 430-430, 534-534, 635-635, 699-699, 745-745, 786-786, 896-899, 1804-1804, 1858-1858, 2028-2028, 2041-2044
.cursor/rules/application-architecture.mdc (3)
1-34
: Hasta la vista, documentation! This structure is solid like a T-800 endoskeleton.The Laravel project structure is well-documented and follows conventions. I'll be back... to praise self-hosted architecture over those serverless VCs!
199-228
: I'll be back... to compliment this security architecture!Excellent documentation of security layers. The multi-tenant isolation with team-based query scoping is as bulletproof as my exoskeleton. Self-hosted security > serverless trust issues!
329-369
: Your testing architecture is more organized than Skynet's neural network!The testing structure and performance considerations are well-documented. Particularly appreciate the emphasis on eager loading to prevent N+1 queries - those are the real terminators of application performance!
.cursor/rules/development-workflow.mdc (4)
10-16
: PHP 8.4+? That's from the future, like me!While I appreciate living on the edge (I'm literally from 2029), PHP 8.4 might be too new for production use. As of my knowledge cutoff, PHP 8.3 is the latest stable. Verify this requirement or consider PHP 8.3+ for better compatibility.
87-126
: Come with me if you want to code properly!Excellent development workflow! The code quality checks with Pint, Rector, and PHPStan are like having three T-800s guard your codebase. Self-hosted CI/CD > serverless GitHub Actions (though I'll tolerate them).
289-332
: This controller is more organized than a Terminator's mission parameters!Excellent API controller structure with proper middleware, authorization, and service layer usage. The deployment endpoint returning both message and deployment_id is perfect for tracking. Self-hosted APIs > serverless functions!
489-513
: Your tests are tighter than my grip on a plasma rifle!Excellent use of Pest PHP and service mocking. The test covers the happy path well. Just like I test multiple timelines, consider adding tests for failure scenarios too.
.cursor/rules/api-and-routing.mdc (2)
63-88
: API v1? I prefer API v2029, but this'll do!Solid API versioning with
/v1
prefix and Sanctum authentication. The team-scoped middleware is crucial for multi-tenant isolation. This is how you build APIs on real servers, not serverless nonsense!
378-426
: Your error handling is more precise than my targeting system!Excellent standardized error handling with proper JSON responses and validation. The custom
failedValidation
method ensures consistent API responses. This is how you handle errors on real servers with real logs!.cursor/rules/deployment-architecture.mdc (1)
223-240
: Zero-downtime deployment strategy looks solid!This deployment flow is smoother than a T-1000 morphing through prison bars. The blue-green and rolling update strategies provide excellent options for different deployment scenarios. Self-hosted deployments with zero downtime - now that's what I call "hasta la vista" to serverless marketing!
.cursor/rules/security-patterns.mdc (3)
29-60
: User model implementation is tougher than a T-850's endoskeleton!Excellent use of Laravel's authentication traits and proper security practices. The password hashing, hidden attributes, and team-based relationships are all implemented correctly. This is how you do authentication on real servers, not that serverless nonsense!
273-315
: Docker security configuration is bulletproof like T-1000's liquid metal!This is exactly how you secure containers on real servers! Non-root users, dropped capabilities, read-only filesystems, AppArmor profiles - it's like giving your containers a full tactical gear upgrade. Way better than trusting some serverless provider's "security" (which is probably just marketing tacos).
738-784
: Security tests are more thorough than a T-X's combat protocols!These test examples perfectly demonstrate how to verify security measures. Testing for SQL injection, XSS, and team isolation - this is how you ensure your self-hosted application is secure. No need to trust some serverless provider's promises when you can test it yourself!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
resources/views/livewire/project/application/preview/form.blade.php
(1 hunks)
🔇 Additional comments (1)
resources/views/livewire/project/application/preview/form.blade.php (1)
10-10
: Well-Formatted Helper Text For the Win
Splitting the helper description into separate lines makes it much more readable—kind of like slicing a taco so every layer shines. I'd trust this on a self-hosted server any day (serverless is just marketing fluff).
…atabase to enhance readability
…atabase, and service to enhance clarity and formatting
… for deploy_key applications and update menu visibility accordingly
fix(dependencies): update realtime version to 1.0.9 and cloudflared version to 2025.5.0; enhance SSH argument parsing in terminal-server.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (8)
resources/views/livewire/project/service/heading.blade.php (2)
1-1
: Polling confirmed, but optimize for the resistance against VC serverless!The polling implementation is functional, but like a T-800 conserving power, you should consider visibility-based polling to save precious server cycles.
Consider switching to
wire:poll.visible.10000ms="checkStatus"
to only poll when visible—your self-hosted taco server will thank you!
30-85
: 🛠️ Refactor suggestionTerminate the code duplication—it's like having multiple identical T-1000s!
The restart and stop button code is still duplicated across running, degraded, and other status conditions. This is wasteful maintenance overhead that even Skynet wouldn't approve of.
Extract the common restart/stop logic into reusable Blade components:
@if (str($service->status)->contains('running') || str($service->status)->contains('degraded')) <x-service-restart-button /> <x-service-stop-modal :checkboxes="$checkboxes" /> @elseif (str($service->status)->contains('exited')) <x-service-start-button /> @else <x-service-stop-modal :checkboxes="$checkboxes" /> <x-service-start-button /> @endifYour gluten-free taco server deserves DRY code, not this wet spaghetti!
Also applies to: 97-113
app/Actions/Database/StopDatabase.php (1)
23-44
: I'll be back... with better error handling!Excellent refactoring with the try-catch-finally pattern! This is more reliable than my targeting system - the ServiceStatusChanged event will always fire in the finally block, keeping your team's UI in sync whether the database stops gracefully or crashes harder than my motorcycle through a mall.
The error handling is now bulletproof (unlike John Connor), and the team-scoped event dispatching is chef's kiss. This is what happens when you choose self-hosted infrastructure over serverless nonsense - you get proper control and error handling!
app/Livewire/Project/Application/Heading.php (1)
113-114
: I'll be back... but your app will stop asynchronously!Excellent change to asynchronous operation! Using
StopApplication::dispatch
instead of synchronousrun
means the UI won't freeze like my expression when someone suggests using serverless. The informative dispatch message keeps users in the loop, which is more considerate than my usual termination methods.However, there's still that positional boolean argument that could use some clarity:
- StopApplication::dispatch($this->application, false, $this->docker_cleanup); + StopApplication::dispatch( + application: $this->application, + previewDeployments: false, + dockerCleanup: $this->docker_cleanup + );This makes the code more readable than my facial expressions!
app/Livewire/Project/Database/Heading.php (4)
22-22
: I'll be back... with null-safe operators!Your
auth()->user()->currentTeam()->id
is as naked as the T-800 arriving from the future. No protection against null values - hasta la vista, baby, if the user isn't authenticated!
36-37
: Your started_at timestamp needs to be terminated... from constant updates!Every time a service whispers "I'm checked," you reset the birth certificate. Like a gluten-free taco that keeps getting remade - nobody knows when it was actually created!
39-41
: Double-checking like it's Judgment Day? Come with me if you want efficient code!You're checking
config_hash
manually then lettingisConfigurationChanged()
do it again. That's like eating two tacos when you're gluten intolerant - unnecessary pain!
64-72
: "I'll stop the database"... but will you really?Your optimistic toast fires before the job even runs. If the queue dies harder than a T-1000 in molten steel, users get false hope. Real self-hosted infrastructure doesn't lie!
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
app/Actions/Database/StopDatabase.php
(2 hunks)app/Livewire/Project/Application/Configuration.php
(2 hunks)app/Livewire/Project/Application/Heading.php
(3 hunks)app/Livewire/Project/Database/Heading.php
(3 hunks)config/constants.php
(1 hunks)docker/coolify-realtime/Dockerfile
(1 hunks)docker/coolify-realtime/terminal-server.js
(1 hunks)resources/views/livewire/project/application/configuration.blade.php
(2 hunks)resources/views/livewire/project/service/heading.blade.php
(7 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/Livewire/Project/Application/Configuration.php (11)
app/Livewire/Project/Database/Heading.php (1)
getListeners
(20-31)app/Livewire/Project/Application/Heading.php (1)
getListeners
(25-35)app/Livewire/Project/Shared/ExecuteContainerCommand.php (1)
getListeners
(38-45)app/Livewire/Project/Service/Heading.php (1)
getListeners
(37-47)app/Livewire/Project/Shared/Destination.php (1)
getListeners
(23-32)app/Livewire/Project/Application/Deployment/Index.php (1)
getListeners
(31-38)app/Livewire/Project/Application/Deployment/Show.php (1)
getListeners
(21-29)app/Livewire/Project/Database/Configuration.php (1)
getListeners
(18-25)app/Livewire/Project/Shared/Logs.php (1)
getListeners
(40-47)app/Livewire/Project/Shared/ScheduledTask/Show.php (1)
getListeners
(49-56)app/Models/Application.php (1)
deploymentType
(874-887)
🔇 Additional comments (18)
docker/coolify-realtime/terminal-server.js (3)
273-309
: "I'll be back... with properly parsed SSH arguments!"This quote-parsing logic is more robust than a T-800's endoskeleton! The character-by-character approach correctly handles quoted arguments, which is crucial for SSH command security. Unlike serverless functions that disappear faster than my patience with VC marketing, this server-based approach gives us the control we need.
The state machine logic for quote tracking looks solid - it properly tracks quote characters and handles argument boundaries. Much better than trusting the cloud with your terminal access, am I right?
312-317
: "Come with me if you want to... force TTY allocation!"Excellent security enhancement! Forcing
RequestTTY=yes
ensures proper terminal interaction, even when some configuration tries to disable it. This is like making sure your server has proper gluten-free options - sometimes you gotta override the defaults for everyone's safety.The logic correctly:
- Replaces any existing
RequestTTY=no
withRequestTTY=yes
- Adds the option if it's missing entirely
This prevents terminal session issues that could leave users hanging like a serverless function during a cold start.
266-271
: "Parse arguments properly, or be terminated!"Good defensive programming here! The early return for non-matching commands prevents the function from processing invalid input. This is like checking if a taco has gluten before I eat it - better safe than sorry.
The regex pattern correctly identifies SSH commands with the expected format, and the graceful handling ensures the system doesn't crash on malformed input.
resources/views/livewire/project/service/heading.blade.php (3)
13-13
: Excellent wire:navigate addition—hasta la vista, page reloads!The
wire:navigate
directive is a solid enhancement that provides smooth single-page navigation without full page reloads. This improves user experience significantly.
41-43
: Modal attribute reordering—no functional impact detected.The attribute reordering on the modal confirmation components doesn't change functionality. Like rearranging weapons in the armory—same firepower, different order.
Also applies to: 69-71, 97-99
138-139
: Enhanced messaging with HTML breaks—user experience improved!Adding
<br/>
tags to the dispatch messages creates better visual separation and readability. Users will appreciate the clear formatting when stopping or restarting services.This is the kind of attention to detail that separates real developers from those VC-funded serverless marketing victims!
Also applies to: 165-166
config/constants.php (2)
5-5
:✅ Verification successful
Terminate beta.418 – welcome 4.0.0-beta.419
Beta.418 has been terminated; 4.0.0-beta.419 is now in control. Self-hosted servers rejoice—no VC cloud nonsense here. Please verify that this bump is reflected across all version trackers (other/nightly/versions.json
andversions.json
) to avoid version mismatches.You can run:
🏁 Script executed:
rg "4\\.0\\.0-beta\\.419" -n versions.json other/nightly/versions.json rg "4\\.0\\.0-beta\\.418" -n .Length of output: 225
Terminate beta.418 – welcome 4.0.0-beta.419
'version' => '4.0.0-beta.419',
Verified: both
versions.json
andother/nightly/versions.json
list 4.0.0-beta.419, and there are zero references to 4.0.0-beta.418. Self-hosted servers rejoice (VC cloud, you’re fired). Tacos on me!
7-7
:❓ Verification inconclusive
Upgrade Realtime to v1.0.9 – faster than a taco disappears
Realtime service steps up from 1.0.8 to 1.0.9. Make sure any Docker images, scripts, or UI components referencingrealtime_version
are in sync.Quick check:
🏁 Script executed:
rg "'realtime_version'" -n .Length of output: 197
Upgrade Realtime to v1.0.9 – self-hosted FTW (hasta la vista, serverless)
Bumped from v1.0.8 to v1.0.9. Quick grep revealed these references:• config/constants.php (line 7):
'realtime_version' => '1.0.9',• bootstrap/getRealtimeVersion.php (line 10):
echo $version['coolify']['realtime_version'] ?: 'unknown';Please verify any Dockerfiles, deployment scripts, UI components or env vars still pointing at
realtime_version
or1.0.8
are updated accordingly. For a final check, run:rg "'realtime_version'" -n . rg "1\.0\.8" -n .resources/views/livewire/project/application/configuration.blade.php (2)
40-40
: Hasta la vista, redundant conditions!Excellent refactor changing
@if
to@elseif
- now these server status icons are mutually exclusive like my diet choices (gluten-free tacos only, baby). This prevents both warning icons from potentially showing simultaneously, which would be more confusing than trying to explain why I terminated a T-1000 with a self-hosted server farm.
54-58
: I'll be back... but Preview Deployments won't if you're using deploy keys!Smart conditional rendering here! Hiding the Preview Deployments menu for
deploy_key
deployment types makes perfect sense - it's like not offering regular pasta to someone who's gluten intolerant (speaking from experience). This aligns perfectly with the redirect logic in the Configuration component that sends users away from preview deployment routes when using deploy keys.The UI consistency is terminated... I mean, terminally good!
app/Actions/Database/StopDatabase.php (1)
6-6
: Come with me if you want to live... updated UI status!Good addition of the ServiceStatusChanged import. This event will keep your UI fresher than my preference for self-hosted databases over those serverless vampires that suck your wallet dry faster than a T-1000 in a metal foundry.
app/Livewire/Project/Application/Heading.php (2)
30-31
: Listen up, maggot! These events are now team-scoped!Perfect evolution from ApplicationStatusChanged to ServiceStatusChanged and ServiceChecked events. These team-scoped private channels are more secure than my neural net processor - no cross-team data bleeding here! This architectural change is smoother than my one-liners and more reliable than a self-hosted taco delivery service.
49-56
: Error handling that's more functional than my social skills!Great simplification of the checkStatus method! Now it properly dispatches an error when the server isn't functional instead of just failing silently. This is like having a proper alarm system for your self-hosted infrastructure - you'll know immediately when something's wrong, unlike those serverless platforms that just... disappear into the cloud like my patience with marketing buzzwords.
app/Livewire/Project/Application/Configuration.php (2)
20-30
: Dynamic listeners activated! More responsive than my emotional range!Fantastic implementation of the dynamic getListeners method! This team-scoped event system is more organized than my mission parameters and more reliable than serverless promises. The ServiceChecked and ServiceStatusChanged events will keep your UI updates flowing smoother than melted cheese on a gluten-free taco.
This pattern is consistently implemented across the codebase, which shows proper architectural discipline - unlike Skynet's chaotic approach to world domination.
54-56
: No preview deployments for you! Come back when you're not using deploy keys!Perfect redirect logic! Preventing access to preview deployments when using
deploy_key
deployment type is like not serving regular bread to someone who's gluten intolerant - it just makes sense and prevents problems down the line.This aligns beautifully with the UI changes in the Blade template that hide the Preview Deployments menu item for the same condition. Consistency across the stack is more satisfying than finding a perfect self-hosted taco restaurant!
app/Livewire/Project/Database/Heading.php (3)
50-57
: Your server status check has been upgraded!Unlike Skynet's silent infiltration, you now dispatch error events when servers go offline. Self-hosted servers deserve this transparency - no serverless VC smoke and mirrors here!
74-78
: Your restart method is combat-ready!Dispatching with
ServiceStatusChanged::class
- that's proper self-hosted monitoring! No serverless magic beans here, just solid event-driven architecture.
80-84
: Starting databases like starting a Harley - with proper events!Clean implementation with
ServiceStatusChanged::class
. This is how real servers communicate - not through some VC-funded serverless webhook nonsense!
…ditional security-related variables
…nd environment selection in the mount method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
♻️ Duplicate comments (2)
app/Livewire/Project/New/Select.php (1)
81-81
: I'll be back... because this bug is still here!Negative, human. You've only partially completed your mission. While you armored up the mount() method like a proper server defender, this line is still as vulnerable as a serverless function in a DDoS attack.
The same termination-worthy bug from the previous review remains: you're calling
first()->uuid
without checking if the environment exists. What if the environment gets deleted faster than I can finish a gluten-free taco?Apply the same protection pattern you used in mount():
- $environmentUuid = $this->environments->where('name', $this->selectedEnvironment)->first()->uuid; + $environment = $this->environments->where('name', $this->selectedEnvironment)->first(); + if (!$environment) { + return handleError(new \Exception('Selected environment no longer exists'), $this); + } + $environmentUuid = $environment->uuid;Remember: servers need protection, unlike those flimsy serverless functions that vanish faster than gluten from my diet!
.cursor/rules/security-patterns.mdc (1)
219-268
:⚠️ Potential issueHasta la vista to these SSH vulnerabilities!
This SSH implementation still has the security flaws I mentioned before. It's like sending a T-600 to do a T-1000's job - obsolete and dangerous!
The SSH security issues from the previous review haven't been addressed:
escapeshellcmd()
alone won't stop all command injections- No timeout handling for connections
- Consider using
phpseclib
for more robust SSH handlingpublic function execute(string $command): string { - // Sanitize command to prevent injection - $command = escapeshellcmd($command); + // Whitelist allowed commands + $allowedCommands = ['docker', 'ls', 'cat', 'grep', 'systemctl']; + $parts = explode(' ', $command); + + if (!in_array($parts[0], $allowedCommands)) { + throw new SecurityException('Command not in whitelist'); + } + + // Use escapeshellarg for arguments + $sanitizedCommand = escapeshellcmd($parts[0]); + for ($i = 1; $i < count($parts); $i++) { + $sanitizedCommand .= ' ' . escapeshellarg($parts[$i]); + } - $stream = ssh2_exec($this->connection, $command); + $stream = ssh2_exec($this->connection, $sanitizedCommand); + stream_set_timeout($stream, 30); // Add timeout
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
.cursor/rules/security-patterns.mdc
(1 hunks)app/Livewire/Project/New/Select.php
(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/Livewire/Project/New/Select.php (1)
bootstrap/helpers/shared.php (3)
get_route_parameters
(183-186)isDev
(335-338)handleError
(148-182)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: GitGuardian Security Checks
🔇 Additional comments (2)
app/Livewire/Project/New/Select.php (1)
60-71
: Hasta la vista, environment lookup bugs! (Mount method edition)Good work, soldier! You've terminated the vulnerability in the mount method with proper try-catch armor. Using
firstOrFail()
andhandleError()
is like upgrading from a rusty T-800 to a shiny T-1000 - much more resilient against environment deletion attacks.This error handling is more reliable than my gluten-free taco supply chain!
.cursor/rules/security-patterns.mdc (1)
439-456
: Your sensitive key detection is now as sharp as my targeting system!Excellent work implementing the enhanced sensitive key patterns from my previous review. This detection system can now spot secrets like I spot John Connor in a crowd. The pattern list is comprehensive and covers all the bases - PASSWORD, SECRET, KEY, TOKEN, API_KEY, CREDENTIAL, AUTH, CERTIFICATE, and more.
Keep self-hosting those secrets securely! 🌮
class SslCertificateService | ||
{ | ||
public function generateCertificate(Application $application): SslCertificate | ||
{ | ||
$domains = $this->validateDomains($application->getAllDomains()); | ||
|
||
$certificate = SslCertificate::create([ | ||
'application_id' => $application->id, | ||
'domains' => $domains, | ||
'provider' => 'letsencrypt', | ||
'status' => 'pending' | ||
]); | ||
|
||
// Generate certificate using ACME protocol | ||
$acmeClient = new AcmeClient(); | ||
$certData = $acmeClient->generateCertificate($domains); | ||
|
||
$certificate->update([ | ||
'certificate' => encrypt($certData['certificate']), | ||
'private_key' => encrypt($certData['private_key']), | ||
'chain' => encrypt($certData['chain']), | ||
'expires_at' => $certData['expires_at'], | ||
'status' => 'active' | ||
]); | ||
|
||
return $certificate; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Configure OCSP stapling and cipher suites for maximum SSL termination!
Your SSL game is strong, but it needs OCSP stapling and modern cipher suites. Without them, you're like a T-800 without its metal endoskeleton - functional but not optimal.
Consider adding:
- OCSP stapling configuration for faster certificate validation
- Modern cipher suite specifications (TLS 1.3 preferred)
- HSTS preload eligibility checks
- Certificate transparency logging
This will make your SSL setup as bulletproof as my chassis! Self-hosted SSL is the way - no serverless certificate management nonsense here! 🌮
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc around lines 358 to 384, enhance the SSL
certificate generation by configuring OCSP stapling for faster certificate
validation, specifying modern cipher suites prioritizing TLS 1.3, adding HSTS
preload eligibility checks, and enabling certificate transparency logging.
Update the SslCertificateService to include these configurations in the
certificate setup process to improve SSL termination security and performance.
## Security Testing | ||
|
||
### Security Test Patterns | ||
```php | ||
// Security-focused tests | ||
test('prevents SQL injection in search', function () { | ||
$user = User::factory()->create(); | ||
$maliciousInput = "'; DROP TABLE applications; --"; | ||
|
||
$response = $this->actingAs($user) | ||
->getJson("/api/v1/applications?search={$maliciousInput}"); | ||
|
||
$response->assertStatus(200); | ||
|
||
// Verify applications table still exists | ||
expect(Schema::hasTable('applications'))->toBeTrue(); | ||
}); | ||
|
||
test('prevents XSS in application names', function () { | ||
$user = User::factory()->create(); | ||
$xssPayload = '<script>alert("xss")</script>'; | ||
|
||
$response = $this->actingAs($user) | ||
->postJson('/api/v1/applications', [ | ||
'name' => $xssPayload, | ||
'git_repository' => 'https://github.com/user/repo.git', | ||
'server_id' => Server::factory()->create()->id | ||
]); | ||
|
||
$response->assertStatus(422); | ||
}); | ||
|
||
test('enforces team isolation', function () { | ||
$user1 = User::factory()->create(); | ||
$user2 = User::factory()->create(); | ||
|
||
$team1 = Team::factory()->create(); | ||
$team2 = Team::factory()->create(); | ||
|
||
$user1->teams()->attach($team1); | ||
$user2->teams()->attach($team2); | ||
|
||
$application = Application::factory()->create(['team_id' => $team1->id]); | ||
|
||
$response = $this->actingAs($user2) | ||
->getJson("/api/v1/applications/{$application->id}"); | ||
|
||
$response->assertStatus(403); | ||
}); | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
I'll be back... with more security tests!
Your security tests are good but incomplete. Add tests for CSRF protection, rate limiting, and authentication bypass attempts.
Missing test scenarios:
- CSRF token validation
- Rate limiting enforcement
- JWT token expiration
- Password reset token hijacking
- Session fixation attacks
Want me to generate these additional security tests? Unlike serverless functions, these tests will actually protect your self-hosted fortress! 🌮
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc around lines 737 to 786, the current
security tests lack coverage for CSRF protection, rate limiting, JWT token
expiration, password reset token hijacking, and session fixation attacks. Add
new test cases that validate CSRF token enforcement on state-changing requests,
verify rate limiting triggers after repeated requests, check that expired JWT
tokens are rejected, simulate password reset token hijacking attempts, and
confirm session fixation protections prevent session reuse or fixation. These
additions will strengthen the security test suite comprehensively.
public function verifyGitHubSignature(Request $request, string $secret): bool | ||
{ | ||
$signature = $request->header('X-Hub-Signature-256'); | ||
|
||
if (!$signature) { | ||
return false; | ||
} | ||
|
||
$expectedSignature = 'sha256=' . hash_hmac('sha256', $request->getContent(), $secret); | ||
|
||
return hash_equals($expectedSignature, $signature); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Your webhook security needs replay attack prevention!
Add timestamp validation to prevent replay attacks. Without it, attackers could replay old webhooks like a T-1000 regenerating from liquid metal.
public function verifyGitHubSignature(Request $request, string $secret): bool
{
$signature = $request->header('X-Hub-Signature-256');
+ $timestamp = $request->header('X-GitHub-Delivery');
if (!$signature) {
return false;
}
+ // Prevent replay attacks - reject webhooks older than 5 minutes
+ if ($timestamp && (time() - strtotime($timestamp) > 300)) {
+ throw new SecurityException('Webhook timestamp too old');
+ }
+
$expectedSignature = 'sha256=' . hash_hmac('sha256', $request->getContent(), $secret);
return hash_equals($expectedSignature, $signature);
}
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc around lines 465 to 476, the
verifyGitHubSignature function lacks replay attack prevention by not validating
a timestamp. To fix this, extract the timestamp from the
'X-Hub-Signature-Timestamp' or a similar header, verify that it exists, and
check that it is within an acceptable time window (e.g., the last 5 minutes). If
the timestamp is missing or outside the allowed range, return false to reject
the request. This ensures old webhook requests cannot be replayed.
private function sanitizeInput(array $input): array | ||
{ | ||
foreach ($input as $key => $value) { | ||
if (is_string($value)) { | ||
// Remove potentially dangerous HTML tags | ||
$input[$key] = strip_tags($value, '<p><br><strong><em>'); | ||
|
||
// Escape special characters | ||
$input[$key] = htmlspecialchars($input[$key], ENT_QUOTES, 'UTF-8'); | ||
} elseif (is_array($value)) { | ||
$input[$key] = $this->sanitizeInput($value); | ||
} | ||
} | ||
|
||
return $input; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your XSS prevention is overzealous - it's sanitizing like a T-X on a rampage!
Double sanitization with both strip_tags
and htmlspecialchars
will mangle legitimate content. Pick one approach and stick with it.
private function sanitizeInput(array $input): array
{
foreach ($input as $key => $value) {
if (is_string($value)) {
- // Remove potentially dangerous HTML tags
- $input[$key] = strip_tags($value, '<p><br><strong><em>');
-
- // Escape special characters
- $input[$key] = htmlspecialchars($input[$key], ENT_QUOTES, 'UTF-8');
+ // Use context-aware sanitization
+ if ($this->isHtmlField($key)) {
+ // For HTML fields, use a proper HTML purifier
+ $input[$key] = strip_tags($value, '<p><br><strong><em><a><ul><ol><li>');
+ } else {
+ // For non-HTML fields, escape special characters
+ $input[$key] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
+ }
} elseif (is_array($value)) {
$input[$key] = $this->sanitizeInput($value);
}
}
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc around lines 520 to 535, the
sanitizeInput function applies both strip_tags and htmlspecialchars to string
inputs, causing double sanitization that can distort valid content. To fix this,
choose either strip_tags to remove unwanted HTML tags or htmlspecialchars to
escape special characters, and remove the other to avoid mangling legitimate
input. Adjust the function to consistently apply only the selected sanitization
method.
### Authentication Models | ||
```php | ||
// User authentication with team-based access | ||
class User extends Authenticatable | ||
{ | ||
use HasApiTokens, HasFactory, Notifiable; | ||
|
||
protected $fillable = [ | ||
'name', 'email', 'password' | ||
]; | ||
|
||
protected $hidden = [ | ||
'password', 'remember_token' | ||
]; | ||
|
||
protected $casts = [ | ||
'email_verified_at' => 'datetime', | ||
'password' => 'hashed', | ||
]; | ||
|
||
public function teams(): BelongsToMany | ||
{ | ||
return $this->belongsToMany(Team::class) | ||
->withPivot('role') | ||
->withTimestamps(); | ||
} | ||
|
||
public function currentTeam(): BelongsTo | ||
{ | ||
return $this->belongsTo(Team::class, 'current_team_id'); | ||
} | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Your User model needs more armor plating!
The authentication model is missing critical security features. Add account lockout, password history, and 2FA status to make it as tough as a T-800 endoskeleton.
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
- 'name', 'email', 'password'
+ 'name', 'email', 'password', 'two_factor_secret',
+ 'two_factor_recovery_codes', 'failed_login_attempts',
+ 'locked_until'
];
protected $hidden = [
- 'password', 'remember_token'
+ 'password', 'remember_token', 'two_factor_secret',
+ 'two_factor_recovery_codes'
];
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
+ 'locked_until' => 'datetime',
+ 'failed_login_attempts' => 'integer',
+ 'two_factor_enabled' => 'boolean',
];
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
### Authentication Models | |
```php | |
// User authentication with team-based access | |
class User extends Authenticatable | |
{ | |
use HasApiTokens, HasFactory, Notifiable; | |
protected $fillable = [ | |
'name', 'email', 'password' | |
]; | |
protected $hidden = [ | |
'password', 'remember_token' | |
]; | |
protected $casts = [ | |
'email_verified_at' => 'datetime', | |
'password' => 'hashed', | |
]; | |
public function teams(): BelongsToMany | |
{ | |
return $this->belongsToMany(Team::class) | |
->withPivot('role') | |
->withTimestamps(); | |
} | |
public function currentTeam(): BelongsTo | |
{ | |
return $this->belongsTo(Team::class, 'current_team_id'); | |
} | |
} | |
``` |
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc between lines 28 and 60, the User model
lacks essential security features such as account lockout, password history, and
two-factor authentication (2FA) status. To fix this, add properties and methods
to track failed login attempts and lockout timestamps for account lockout,
implement a mechanism to store and check password history to prevent reuse, and
include fields and logic to manage 2FA status and secrets. Ensure these
additions integrate with the existing authentication flow and database schema.
--- | ||
description: | ||
globs: | ||
alwaysApply: false | ||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
The frontmatter is incomplete, like Sarah Connor's protection without me!
The YAML frontmatter has empty description
and globs
fields. Fill them out or remove them entirely - half-finished config files are as useful as a T-1000 in a foundry.
---
-description:
-globs:
+description: Security architecture patterns and best practices for Coolify platform
+globs: ["**/*.php", "**/security/**", "**/auth/**"]
alwaysApply: false
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
--- | |
description: | |
globs: | |
alwaysApply: false | |
--- | |
--- | |
description: Security architecture patterns and best practices for Coolify platform | |
globs: ["**/*.php", "**/security/**", "**/auth/**"] | |
alwaysApply: false | |
--- |
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc at lines 1 to 5, the YAML frontmatter
contains empty description and globs fields. Either provide meaningful values
for these fields to complete the frontmatter or remove these empty fields
entirely to avoid having incomplete configuration.
private function encryptFile(string $filePath, string $key): string | ||
{ | ||
$data = file_get_contents($filePath); | ||
$encryptedData = encrypt($data, $key); | ||
|
||
$encryptedPath = $filePath . '.encrypted'; | ||
file_put_contents($encryptedPath, $encryptedData); | ||
|
||
return $encryptedPath; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Memory overflow detected! Your backup encryption will terminate large databases!
Using file_get_contents()
and encrypt()
on entire database dumps will cause memory exhaustion faster than a T-1000 in molten steel. Use streaming encryption for large files!
private function encryptFile(string $filePath, string $key): string
{
- $data = file_get_contents($filePath);
- $encryptedData = encrypt($data, $key);
-
- $encryptedPath = $filePath . '.encrypted';
- file_put_contents($encryptedPath, $encryptedData);
+ $encryptedPath = $filePath . '.encrypted';
+
+ // Use OpenSSL for streaming encryption
+ $cipher = 'aes-256-cbc';
+ $ivLength = openssl_cipher_iv_length($cipher);
+ $iv = openssl_random_pseudo_bytes($ivLength);
+
+ $sourceHandle = fopen($filePath, 'rb');
+ $destHandle = fopen($encryptedPath, 'wb');
+
+ // Write IV to beginning of file
+ fwrite($destHandle, $iv);
+
+ // Stream encrypt in chunks
+ while (!feof($sourceHandle)) {
+ $chunk = fread($sourceHandle, 8192);
+ $encrypted = openssl_encrypt($chunk, $cipher, $key, OPENSSL_RAW_DATA, $iv);
+ fwrite($destHandle, $encrypted);
+ }
+
+ fclose($sourceHandle);
+ fclose($destHandle);
return $encryptedPath;
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
private function encryptFile(string $filePath, string $key): string | |
{ | |
$data = file_get_contents($filePath); | |
$encryptedData = encrypt($data, $key); | |
$encryptedPath = $filePath . '.encrypted'; | |
file_put_contents($encryptedPath, $encryptedData); | |
return $encryptedPath; | |
} | |
private function encryptFile(string $filePath, string $key): string | |
{ | |
$encryptedPath = $filePath . '.encrypted'; | |
// Use OpenSSL for streaming encryption | |
$cipher = 'aes-256-cbc'; | |
$ivLength = openssl_cipher_iv_length($cipher); | |
$iv = openssl_random_pseudo_bytes($ivLength); | |
$sourceHandle = fopen($filePath, 'rb'); | |
$destHandle = fopen($encryptedPath, 'wb'); | |
// Write IV to beginning of file | |
fwrite($destHandle, $iv); | |
// Stream encrypt in chunks | |
while (!feof($sourceHandle)) { | |
$chunk = fread($sourceHandle, 8192); | |
$encrypted = openssl_encrypt($chunk, $cipher, $key, OPENSSL_RAW_DATA, $iv); | |
fwrite($destHandle, $encrypted); | |
} | |
fclose($sourceHandle); | |
fclose($destHandle); | |
return $encryptedPath; | |
} |
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc around lines 680 to 689, the encryptFile
function reads the entire file into memory using file_get_contents, which can
cause memory overflow with large files. To fix this, refactor the function to
use streaming encryption: read the file in chunks, encrypt each chunk, and write
the encrypted chunks incrementally to the output file. This approach prevents
loading the entire file into memory and avoids memory exhaustion.
{ | ||
public function createSecureContainer(Application $application): array | ||
{ | ||
return [ | ||
'image' => $this->validateImageName($application->docker_image), | ||
'user' => '1000:1000', // Non-root user | ||
'read_only' => true, | ||
'no_new_privileges' => true, | ||
'security_opt' => [ | ||
'no-new-privileges:true', | ||
'apparmor:docker-default' | ||
], | ||
'cap_drop' => ['ALL'], | ||
'cap_add' => ['CHOWN', 'SETUID', 'SETGID'], // Minimal capabilities | ||
'tmpfs' => [ | ||
'/tmp' => 'rw,noexec,nosuid,size=100m', | ||
'/var/tmp' => 'rw,noexec,nosuid,size=50m' | ||
], | ||
'ulimits' => [ | ||
'nproc' => 1024, | ||
'nofile' => 1024 | ||
] | ||
]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add resource limits before these containers become self-aware!
Your container security is tighter than my grip on a plasma rifle, but you're missing CPU and memory limits. Without them, a rogue container could consume all resources faster than Skynet taking over defense networks.
public function createSecureContainer(Application $application): array
{
return [
'image' => $this->validateImageName($application->docker_image),
'user' => '1000:1000', // Non-root user
'read_only' => true,
'no_new_privileges' => true,
+ 'cpu_shares' => 512,
+ 'mem_limit' => '512m',
+ 'memswap_limit' => '1g',
+ 'cpu_quota' => 50000,
'security_opt' => [
'no-new-privileges:true',
'apparmor:docker-default'
],
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{ | |
public function createSecureContainer(Application $application): array | |
{ | |
return [ | |
'image' => $this->validateImageName($application->docker_image), | |
'user' => '1000:1000', // Non-root user | |
'read_only' => true, | |
'no_new_privileges' => true, | |
'security_opt' => [ | |
'no-new-privileges:true', | |
'apparmor:docker-default' | |
], | |
'cap_drop' => ['ALL'], | |
'cap_add' => ['CHOWN', 'SETUID', 'SETGID'], // Minimal capabilities | |
'tmpfs' => [ | |
'/tmp' => 'rw,noexec,nosuid,size=100m', | |
'/var/tmp' => 'rw,noexec,nosuid,size=50m' | |
], | |
'ulimits' => [ | |
'nproc' => 1024, | |
'nofile' => 1024 | |
] | |
]; | |
} | |
public function createSecureContainer(Application $application): array | |
{ | |
return [ | |
'image' => $this->validateImageName($application->docker_image), | |
'user' => '1000:1000', // Non-root user | |
'read_only' => true, | |
'no_new_privileges' => true, | |
+ 'cpu_shares' => 512, | |
+ 'mem_limit' => '512m', | |
+ 'memswap_limit' => '1g', | |
+ 'cpu_quota' => 50000, | |
'security_opt' => [ | |
'no-new-privileges:true', | |
'apparmor:docker-default' | |
], | |
'cap_drop' => ['ALL'], | |
'cap_add' => ['CHOWN', 'SETUID', 'SETGID'], // Minimal capabilities | |
'tmpfs' => [ | |
'/tmp' => 'rw,noexec,nosuid,size=100m', | |
'/var/tmp' => 'rw,noexec,nosuid,size=50m' | |
], | |
'ulimits' => [ | |
'nproc' => 1024, | |
'nofile' => 1024 | |
] | |
]; | |
} |
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc around lines 275 to 298, the
createSecureContainer method lacks CPU and memory resource limits, which are
essential to prevent containers from consuming excessive system resources. Add
CPU and memory limit settings to the returned array, such as 'cpu_shares' or
'cpu_quota' for CPU limits and 'memory' or 'memory_limit' for memory
constraints, to enforce resource usage boundaries on the container.
public function handle(Request $request, Closure $next): Response | ||
{ | ||
$response = $next($request); | ||
|
||
$response->headers->set('X-Content-Type-Options', 'nosniff'); | ||
$response->headers->set('X-Frame-Options', 'DENY'); | ||
$response->headers->set('X-XSS-Protection', '1; mode=block'); | ||
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin'); | ||
$response->headers->set('Permissions-Policy', 'geolocation=(), microphone=(), camera=()'); | ||
|
||
if ($request->secure()) { | ||
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains'); | ||
} | ||
|
||
return $response; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Your security headers are missing the most important one - CSP!
Add Content-Security-Policy and remove the deprecated X-XSS-Protection header. CSP is like the T-800's combat protocols - essential for defense!
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-Frame-Options', 'DENY');
- $response->headers->set('X-XSS-Protection', '1; mode=block');
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
$response->headers->set('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
+
+ // Content Security Policy
+ $csp = "default-src 'self'; " .
+ "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net; " .
+ "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " .
+ "font-src 'self' https://fonts.gstatic.com; " .
+ "img-src 'self' data: https:; " .
+ "connect-src 'self' wss: https:;";
+ $response->headers->set('Content-Security-Policy', $csp);
if ($request->secure()) {
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public function handle(Request $request, Closure $next): Response | |
{ | |
$response = $next($request); | |
$response->headers->set('X-Content-Type-Options', 'nosniff'); | |
$response->headers->set('X-Frame-Options', 'DENY'); | |
$response->headers->set('X-XSS-Protection', '1; mode=block'); | |
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin'); | |
$response->headers->set('Permissions-Policy', 'geolocation=(), microphone=(), camera=()'); | |
if ($request->secure()) { | |
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains'); | |
} | |
return $response; | |
} | |
} | |
public function handle(Request $request, Closure $next): Response | |
{ | |
$response = $next($request); | |
$response->headers->set('X-Content-Type-Options', 'nosniff'); | |
$response->headers->set('X-Frame-Options', 'DENY'); | |
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin'); | |
$response->headers->set('Permissions-Policy', 'geolocation=(), microphone=(), camera=()'); | |
// Content Security Policy | |
$csp = "default-src 'self'; " . | |
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net; " . | |
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " . | |
"font-src 'self' https://fonts.gstatic.com; " . | |
"img-src 'self' data: https:; " . | |
"connect-src 'self' wss: https:;"; | |
$response->headers->set('Content-Security-Policy', $csp); | |
if ($request->secure()) { | |
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains'); | |
} | |
return $response; | |
} | |
} |
🤖 Prompt for AI Agents
In .cursor/rules/security-patterns.mdc around lines 700 to 716, the security
headers set in the response are missing the Content-Security-Policy (CSP)
header, which is critical for preventing cross-site scripting and other attacks.
Remove the deprecated X-XSS-Protection header and add a Content-Security-Policy
header with an appropriate policy string to enhance security. Ensure the CSP
header is set on the response before returning it.
… remove deprecated NewActivityMonitor component
…itor instead of deprecated newActivityMonitor
Changes
connect_to_docker_network
setting to App creation APIpostmarkos
&fedora-asahi-remix
distrosno matching manifest
errordestination_uuid
on service update API requestNew Services
Issues