From 1f1fe1f1843da7977dfafc5ae134058d2c91098e Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:37:46 +0200 Subject: [PATCH 1/5] fix(dev): disable IP seeding in dev as it does not work --- database/seeders/InstanceSettingsSeeder.php | 34 +++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/database/seeders/InstanceSettingsSeeder.php b/database/seeders/InstanceSettingsSeeder.php index baa7abffc..930a7db8e 100644 --- a/database/seeders/InstanceSettingsSeeder.php +++ b/database/seeders/InstanceSettingsSeeder.php @@ -23,23 +23,25 @@ public function run(): void 'smtp_from_address' => 'hi@localhost.com', 'smtp_from_name' => 'Coolify', ]); - try { - $ipv4 = Process::run('curl -4s https://ifconfig.io')->output(); - $ipv4 = trim($ipv4); - $ipv4 = filter_var($ipv4, FILTER_VALIDATE_IP); - $settings = instanceSettings(); - if (is_null($settings->public_ipv4) && $ipv4) { - $settings->update(['public_ipv4' => $ipv4]); + if (! isDev()) { + try { + $ipv4 = Process::run('curl -4s https://ifconfig.io')->output(); + $ipv4 = trim($ipv4); + $ipv4 = filter_var($ipv4, FILTER_VALIDATE_IP); + $settings = instanceSettings(); + if (is_null($settings->public_ipv4) && $ipv4) { + $settings->update(['public_ipv4' => $ipv4]); + } + $ipv6 = Process::run('curl -6s https://ifconfig.io')->output(); + $ipv6 = trim($ipv6); + $ipv6 = filter_var($ipv6, FILTER_VALIDATE_IP); + $settings = instanceSettings(); + if (is_null($settings->public_ipv6) && $ipv6) { + $settings->update(['public_ipv6' => $ipv6]); + } + } catch (\Throwable $e) { + echo "Error: {$e->getMessage()}\n"; } - $ipv6 = Process::run('curl -6s https://ifconfig.io')->output(); - $ipv6 = trim($ipv6); - $ipv6 = filter_var($ipv6, FILTER_VALIDATE_IP); - $settings = instanceSettings(); - if (is_null($settings->public_ipv6) && $ipv6) { - $settings->update(['public_ipv6' => $ipv6]); - } - } catch (\Throwable $e) { - echo "Error: {$e->getMessage()}\n"; } } } From 8e22ce4ba745d39b2672c0cc13023d3b0a4404ba Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:23:07 +0200 Subject: [PATCH 2/5] fix(vite): restrict CORS to known origins instead of wildcard Add explicit CORS allowlist covering localhost variants, APP_URL env var, and the configured vite host/port pair. Replaces implicit open CORS with regex-based origin matching. --- vite.config.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vite.config.js b/vite.config.js index 4b967c40e..6c706d272 100644 --- a/vite.config.js +++ b/vite.config.js @@ -17,6 +17,15 @@ export default defineConfig(({ mode }) => { }, host: "0.0.0.0", allowedHosts: true, + cors: { + origin: [ + /^https?:\/\/localhost(:\d+)?$/, + /^https?:\/\/127\.0\.0\.1(:\d+)?$/, + /^https?:\/\/\[::1\](:\d+)?$/, + ...(env.APP_URL ? [env.APP_URL] : []), + ...(viteHost ? [`http://${viteHost}:${vitePort}`, `https://${viteHost}:${vitePort}`] : []), + ], + }, origin: viteHost ? `http://${viteHost}:${vitePort}` : undefined, hmr: viteHost ? { host: viteHost, clientPort: vitePort } From e89820b46552e848ec30825927c9c5a2d74ccde8 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 5 May 2026 15:30:32 +0200 Subject: [PATCH 3/5] refactor(deployment): move copyLogs to client-side and hide refund when ineligible Move copyLogs from PHP Livewire method to Alpine.js to avoid unnecessary server round-trips. Extract collectVisibleLogs() helper shared by both copy and download actions. Hide refund section entirely when not eligible instead of rendering a permanently disabled button. --- .../Project/Application/Deployment/Show.php | 13 ------- .../application/deployment/show.blade.php | 22 +++++++----- .../livewire/subscription/actions.blade.php | 34 +++++++++---------- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/app/Livewire/Project/Application/Deployment/Show.php b/app/Livewire/Project/Application/Deployment/Show.php index 954670582..c9f818e2c 100644 --- a/app/Livewire/Project/Application/Deployment/Show.php +++ b/app/Livewire/Project/Application/Deployment/Show.php @@ -108,19 +108,6 @@ public function getLogLinesProperty() return decode_remote_command_output($this->application_deployment_queue); } - public function copyLogs(): string - { - $logs = decode_remote_command_output($this->application_deployment_queue) - ->map(function ($line) { - return $line['timestamp'].' '. - (isset($line['command']) && $line['command'] ? '[CMD]: ' : ''). - trim($line['line']); - }) - ->join("\n"); - - return sanitizeLogsForExport($logs); - } - public function downloadAllLogs(): string { $logs = decode_remote_command_output($this->application_deployment_queue, includeAll: true) diff --git a/resources/views/livewire/project/application/deployment/show.blade.php b/resources/views/livewire/project/application/deployment/show.blade.php index 8618872f5..8ef2c3f51 100644 --- a/resources/views/livewire/project/application/deployment/show.blade.php +++ b/resources/views/livewire/project/application/deployment/show.blade.php @@ -155,9 +155,9 @@ this.matchCount = query ? count : 0; }, - downloadLogs() { + collectVisibleLogs() { const logs = document.getElementById('logs'); - if (!logs) return; + if (!logs) return ''; const visibleLines = logs.querySelectorAll('[data-log-line]:not(.hidden)'); let content = ''; visibleLines.forEach(line => { @@ -166,6 +166,17 @@ content += text + String.fromCharCode(10); } }); + return content; + }, + copyLogs() { + const content = this.collectVisibleLogs(); + if (!content) return; + navigator.clipboard.writeText(content); + Livewire.dispatch('success', ['Logs copied to clipboard.']); + }, + downloadLogs() { + const content = this.collectVisibleLogs(); + if (!content) return; const blob = new Blob([content], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); @@ -258,12 +269,7 @@ class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-6