diff --git a/app/Livewire/Notifications/Email.php b/app/Livewire/Notifications/Email.php index eac48cf77..3ed20f907 100644 --- a/app/Livewire/Notifications/Email.php +++ b/app/Livewire/Notifications/Email.php @@ -41,8 +41,8 @@ class Email extends Component #[Validate(['nullable', 'numeric', 'min:1', 'max:65535'])] public ?int $smtpPort = null; - #[Validate(['nullable', 'string', 'in:tls,ssl,none'])] - public ?string $smtpEncryption = 'tls'; + #[Validate(['nullable', 'string', 'in:starttls,tls,none'])] + public ?string $smtpEncryption = null; #[Validate(['nullable', 'string'])] public ?string $smtpUsername = null; @@ -235,7 +235,7 @@ class Email extends Component 'smtpFromName' => 'required|string', 'smtpHost' => 'required|string', 'smtpPort' => 'required|numeric', - 'smtpEncryption' => 'required|string|in:tls,ssl,none', + 'smtpEncryption' => 'required|string|in:starttls,tls,none', 'smtpUsername' => 'nullable|string', 'smtpPassword' => 'nullable|string', 'smtpTimeout' => 'nullable|numeric', diff --git a/app/Livewire/SettingsEmail.php b/app/Livewire/SettingsEmail.php index 1c5edb108..058f080e4 100644 --- a/app/Livewire/SettingsEmail.php +++ b/app/Livewire/SettingsEmail.php @@ -35,8 +35,8 @@ class SettingsEmail extends Component #[Validate(['nullable', 'numeric', 'min:1', 'max:65535'])] public ?int $smtpPort = null; - #[Validate(['nullable', 'string', 'in:tls,ssl,none'])] - public ?string $smtpEncryption = 'tls'; + #[Validate(['nullable', 'string', 'in:starttls,tls,none'])] + public ?string $smtpEncryption = null; #[Validate(['nullable', 'string'])] public ?string $smtpUsername = null; @@ -142,7 +142,7 @@ class SettingsEmail extends Component 'smtpFromName' => 'required|string', 'smtpHost' => 'required|string', 'smtpPort' => 'required|numeric', - 'smtpEncryption' => 'required|string|in:tls,ssl,none', + 'smtpEncryption' => 'required|string|in:starttls,tls,none', 'smtpUsername' => 'nullable|string', 'smtpPassword' => 'nullable|string', 'smtpTimeout' => 'nullable|numeric', diff --git a/app/Models/Server.php b/app/Models/Server.php index 767327b8e..8d11e23a9 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -347,7 +347,7 @@ class Server extends BaseModel 'loadBalancer' => [ 'servers' => [ 0 => [ - 'url' => 'http://coolify:80', + 'url' => 'http://coolify:8080', ], ], ], @@ -445,7 +445,7 @@ $schema://$host { handle /terminal/ws { reverse_proxy coolify-realtime:6002 } - reverse_proxy coolify:80 + reverse_proxy coolify:8080 }"; $base64 = base64_encode($caddy_file); instant_remote_process([ diff --git a/app/Notifications/Channels/EmailChannel.php b/app/Notifications/Channels/EmailChannel.php index 0985f4393..6ffe5c4d7 100644 --- a/app/Notifications/Channels/EmailChannel.php +++ b/app/Notifications/Channels/EmailChannel.php @@ -66,17 +66,24 @@ class EmailChannel } if ($emailSettings->smtp_enabled) { + $encryption = match (strtolower($emailSettings->smtp_encryption)) { + 'starttls' => null, + 'tls' => 'tls', + 'none' => null, + default => null, + }; + config()->set('mail.default', 'smtp'); config()->set('mail.mailers.smtp', [ 'transport' => 'smtp', 'host' => $emailSettings->smtp_host, 'port' => $emailSettings->smtp_port, - 'encryption' => $emailSettings->smtp_encryption === 'none' ? null : $emailSettings->smtp_encryption, + 'encryption' => $encryption, 'username' => $emailSettings->smtp_username, 'password' => $emailSettings->smtp_password, 'timeout' => $emailSettings->smtp_timeout, 'local_domain' => null, - 'auto_tls' => $emailSettings->smtp_encryption === 'none' ? '0' : '', + 'auto_tls' => $emailSettings->smtp_encryption === 'none' ? '0' : '', // If encryption is "none", it will not try to upgrade to TLS via StartTLS to make sure it is unencrypted. ]); } } diff --git a/bootstrap/helpers/notifications.php b/bootstrap/helpers/notifications.php index 3b1eb758b..46f0ebca7 100644 --- a/bootstrap/helpers/notifications.php +++ b/bootstrap/helpers/notifications.php @@ -67,17 +67,26 @@ function set_transanctional_email_settings(?InstanceSettings $settings = null): return 'resend'; } + + $encryption = match (strtolower(data_get($settings, 'smtp_encryption'))) { + 'starttls' => null, + 'tls' => 'tls', + 'none' => null, + default => null, + }; + if (data_get($settings, 'smtp_enabled')) { config()->set('mail.default', 'smtp'); config()->set('mail.mailers.smtp', [ 'transport' => 'smtp', 'host' => data_get($settings, 'smtp_host'), 'port' => data_get($settings, 'smtp_port'), - 'encryption' => data_get($settings, 'smtp_encryption'), + 'encryption' => $encryption, 'username' => data_get($settings, 'smtp_username'), 'password' => data_get($settings, 'smtp_password'), 'timeout' => data_get($settings, 'smtp_timeout'), 'local_domain' => null, + 'auto_tls' => data_get($settings, 'smtp_encryption') === 'none' ? '0' : '', // If encryption is "none", it will not try to upgrade to TLS via StartTLS to make sure it is unencrypted. ]); return 'smtp'; diff --git a/config/constants.php b/config/constants.php index 37832ce27..3f3ce2a74 100644 --- a/config/constants.php +++ b/config/constants.php @@ -47,7 +47,7 @@ return [ ], 'docker' => [ - 'minimum_required_version' => '26.0', + 'minimum_required_version' => '24.0', ], 'ssh' => [ diff --git a/database/migrations/2024_12_10_122142_encrypt_instance_settings_email_columns.php b/database/migrations/2024_12_10_122142_encrypt_instance_settings_email_columns.php index 5602e0ae9..83540ca3c 100644 --- a/database/migrations/2024_12_10_122142_encrypt_instance_settings_email_columns.php +++ b/database/migrations/2024_12_10_122142_encrypt_instance_settings_email_columns.php @@ -13,15 +13,15 @@ return new class extends Migration */ public function up(): void { - if (DB::table('instance_settings')->exists()) { - Schema::table('instance_settings', function (Blueprint $table) { - $table->text('smtp_from_address')->nullable()->change(); - $table->text('smtp_from_name')->nullable()->change(); - $table->text('smtp_recipients')->nullable()->change(); - $table->text('smtp_host')->nullable()->change(); - $table->text('smtp_username')->nullable()->change(); - }); + Schema::table('instance_settings', function (Blueprint $table) { + $table->text('smtp_from_address')->nullable()->change(); + $table->text('smtp_from_name')->nullable()->change(); + $table->text('smtp_recipients')->nullable()->change(); + $table->text('smtp_host')->nullable()->change(); + $table->text('smtp_username')->nullable()->change(); + }); + if (DB::table('instance_settings')->exists()) { $settings = DB::table('instance_settings')->get(); foreach ($settings as $setting) { try { @@ -45,11 +45,11 @@ return new class extends Migration public function down(): void { Schema::table('instance_settings', function (Blueprint $table) { - $table->text('smtp_from_address')->nullable()->change(); - $table->text('smtp_from_name')->nullable()->change(); - $table->text('smtp_recipients')->nullable()->change(); - $table->text('smtp_host')->nullable()->change(); - $table->text('smtp_username')->nullable()->change(); + $table->string('smtp_from_address')->nullable()->change(); + $table->string('smtp_from_name')->nullable()->change(); + $table->string('smtp_recipients')->nullable()->change(); + $table->string('smtp_host')->nullable()->change(); + $table->string('smtp_username')->nullable()->change(); }); if (DB::table('instance_settings')->exists()) { diff --git a/database/migrations/2024_12_23_142402_update_email_encryption_values.php b/database/migrations/2024_12_23_142402_update_email_encryption_values.php new file mode 100644 index 000000000..dfb5b4a7c --- /dev/null +++ b/database/migrations/2024_12_23_142402_update_email_encryption_values.php @@ -0,0 +1,114 @@ + 'starttls', + 'ssl' => 'tls', + '' => 'none', + ]; + + /** + * Run the migrations. + */ + public function up(): void + { + try { + DB::beginTransaction(); + + $instanceSettings = DB::table('instance_settings')->get(); + foreach ($instanceSettings as $setting) { + try { + if (array_key_exists($setting->smtp_encryption, $this->encryptionMappings)) { + DB::table('instance_settings') + ->where('id', $setting->id) + ->update([ + 'smtp_encryption' => $this->encryptionMappings[$setting->smtp_encryption], + ]); + } + } catch (\Exception $e) { + \Log::error('Failed to update instance settings: '.$e->getMessage()); + } + } + + $emailSettings = DB::table('email_notification_settings')->get(); + foreach ($emailSettings as $setting) { + try { + if (array_key_exists($setting->smtp_encryption, $this->encryptionMappings)) { + DB::table('email_notification_settings') + ->where('id', $setting->id) + ->update([ + 'smtp_encryption' => $this->encryptionMappings[$setting->smtp_encryption], + ]); + } + } catch (\Exception $e) { + \Log::error('Failed to update email settings: '.$e->getMessage()); + } + } + + DB::commit(); + } catch (\Exception $e) { + DB::rollBack(); + \Log::error('Failed to update email encryption: '.$e->getMessage()); + throw $e; + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + try { + DB::beginTransaction(); + + $reverseMapping = [ + 'starttls' => 'tls', + 'tls' => 'ssl', + 'none' => '', + ]; + + $instanceSettings = DB::table('instance_settings')->get(); + foreach ($instanceSettings as $setting) { + try { + if (array_key_exists($setting->smtp_encryption, $reverseMapping)) { + DB::table('instance_settings') + ->where('id', $setting->id) + ->update([ + 'smtp_encryption' => $reverseMapping[$setting->smtp_encryption], + ]); + } + } catch (\Exception $e) { + \Log::error('Failed to reverse instance settings: '.$e->getMessage()); + } + } + + $emailSettings = DB::table('email_notification_settings')->get(); + foreach ($emailSettings as $setting) { + try { + if (array_key_exists($setting->smtp_encryption, $reverseMapping)) { + DB::table('email_notification_settings') + ->where('id', $setting->id) + ->update([ + 'smtp_encryption' => $reverseMapping[$setting->smtp_encryption], + ]); + } + } catch (\Exception $e) { + \Log::error('Failed to reverse email settings: '.$e->getMessage()); + } + } + + DB::commit(); + } catch (\Exception $e) { + DB::rollBack(); + \Log::error('Failed to reverse email encryption: '.$e->getMessage()); + throw $e; + } + } +} diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index c7349f7b0..459b93ac6 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -58,7 +58,7 @@ services: expose: - "${APP_PORT:-8000}" healthcheck: - test: curl --fail http://127.0.0.1:80/api/health || exit 1 + test: curl --fail http://127.0.0.1:8080/api/health || exit 1 interval: 5s retries: 10 timeout: 2s @@ -93,7 +93,7 @@ services: retries: 10 timeout: 2s soketi: - image: 'ghcr.io/coollabsio/coolify-realtime:1.0.4' + image: 'ghcr.io/coollabsio/coolify-realtime:1.0.5' ports: - "${SOKETI_PORT:-6001}:6001" - "6002:6002" diff --git a/docker-compose.windows.yml b/docker-compose.windows.yml index f2b03d209..1e2601b34 100644 --- a/docker-compose.windows.yml +++ b/docker-compose.windows.yml @@ -48,11 +48,11 @@ services: - SSH_MUX_ENABLED=false - IS_WINDOWS_DOCKER_DESKTOP=true ports: - - "${APP_PORT:-8000}:80" + - "${APP_PORT:-8000}:8080" expose: - "${APP_PORT:-8000}" healthcheck: - test: curl --fail http://localhost:80/api/health || exit 1 + test: curl --fail http://localhost:8080/api/health || exit 1 interval: 5s retries: 10 timeout: 2s diff --git a/other/nightly/docker-compose.prod.yml b/other/nightly/docker-compose.prod.yml index f9cded363..459b93ac6 100644 --- a/other/nightly/docker-compose.prod.yml +++ b/other/nightly/docker-compose.prod.yml @@ -58,7 +58,7 @@ services: expose: - "${APP_PORT:-8000}" healthcheck: - test: curl --fail http://127.0.0.1:80/api/health || exit 1 + test: curl --fail http://127.0.0.1:8080/api/health || exit 1 interval: 5s retries: 10 timeout: 2s @@ -93,7 +93,7 @@ services: retries: 10 timeout: 2s soketi: - image: 'ghcr.io/coollabsio/coolify-realtime:next' + image: 'ghcr.io/coollabsio/coolify-realtime:1.0.5' ports: - "${SOKETI_PORT:-6001}:6001" - "6002:6002" diff --git a/other/nightly/docker-compose.windows.yml b/other/nightly/docker-compose.windows.yml index ef2de82e9..e19ec961f 100644 --- a/other/nightly/docker-compose.windows.yml +++ b/other/nightly/docker-compose.windows.yml @@ -48,11 +48,11 @@ services: - SSH_MUX_ENABLED=false - IS_WINDOWS_DOCKER_DESKTOP=true ports: - - "${APP_PORT:-8000}:80" + - "${APP_PORT:-8000}:8080" expose: - "${APP_PORT:-8000}" healthcheck: - test: curl --fail http://localhost:80/api/health || exit 1 + test: curl --fail http://localhost:8080/api/health || exit 1 interval: 5s retries: 10 timeout: 2s diff --git a/resources/views/livewire/notifications/email.blade.php b/resources/views/livewire/notifications/email.blade.php index 1977df516..7b0878b25 100644 --- a/resources/views/livewire/notifications/email.blade.php +++ b/resources/views/livewire/notifications/email.blade.php @@ -70,9 +70,9 @@