Merge branch 'main' into next
This commit is contained in:
		@@ -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',
 | 
			
		||||
 
 | 
			
		||||
@@ -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',
 | 
			
		||||
 
 | 
			
		||||
@@ -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([
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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';
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ return [
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    'docker' => [
 | 
			
		||||
        'minimum_required_version' => '26.0',
 | 
			
		||||
        'minimum_required_version' => '24.0',
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    'ssh' => [
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ 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();
 | 
			
		||||
@@ -22,6 +21,7 @@ return new class extends Migration
 | 
			
		||||
            $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()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,114 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
 | 
			
		||||
class UpdateEmailEncryptionValues extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Encryption mappings.
 | 
			
		||||
     */
 | 
			
		||||
    private array $encryptionMappings = [
 | 
			
		||||
        'tls' => '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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -70,9 +70,9 @@
 | 
			
		||||
                        <div class="flex flex-col w-full gap-2 xl:flex-row">
 | 
			
		||||
                            <x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" />
 | 
			
		||||
                            <x-forms.input required id="smtpPort" placeholder="587" label="Port" />
 | 
			
		||||
                            <x-forms.select id="smtpEncryption" label="Encryption">
 | 
			
		||||
                                <option value="tls">TLS</option>
 | 
			
		||||
                                <option value="ssl">SSL</option>
 | 
			
		||||
                            <x-forms.select required id="smtpEncryption" label="Encryption">
 | 
			
		||||
                                <option value="starttls">StartTLS</option>
 | 
			
		||||
                                <option value="tls">TLS/SSL</option>
 | 
			
		||||
                                <option value="none">None</option>
 | 
			
		||||
                            </x-forms.select>
 | 
			
		||||
                        </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -43,9 +43,9 @@
 | 
			
		||||
                    <div class="flex flex-col w-full gap-2 xl:flex-row">
 | 
			
		||||
                        <x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" />
 | 
			
		||||
                        <x-forms.input required id="smtpPort" placeholder="587" label="Port" />
 | 
			
		||||
                        <x-forms.select id="smtpEncryption" label="Encryption">
 | 
			
		||||
                            <option value="tls">TLS</option>
 | 
			
		||||
                            <option value="ssl">SSL</option>
 | 
			
		||||
                        <x-forms.select required id="smtpEncryption" label="Encryption">
 | 
			
		||||
                            <option value="starttls">StartTLS</option>
 | 
			
		||||
                            <option value="tls">TLS/SSL</option>
 | 
			
		||||
                            <option value="none">None</option>
 | 
			
		||||
                        </x-forms.select>
 | 
			
		||||
                    </div>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user