queue() time, so a * loop that booted before SMTP was configured would bake `log` into every alert mail forever — * the worker then "sends" them into laravel.log no matter how correct its own config is. Applying * fresh settings immediately before queueing bakes the right mailer name. * * Mail::purge() drops the cached mailer instance so a config change actually rebuilds the * transport in long-lived processes instead of reusing the old connection. */ class MailSettings { /** True when a usable SMTP transport is configured (host + from set) — drives the alerts * "no delivery channel" warning. Mirrors the guard in apply() below. */ public static function isConfigured(): bool { try { return ((string) (Setting::get('mail_host') ?? '')) !== '' && ((string) (Setting::get('mail_from_address') ?? '')) !== ''; } catch (Throwable) { return false; // settings not migrated yet } } public static function apply(): void { try { $host = Setting::get('mail_host'); $from = Setting::get('mail_from_address'); if ($host === null || $host === '' || $from === null || $from === '') { return; // unconfigured -> keep the safe default mailer } $encryption = Setting::get('mail_encryption', 'tls'); // The password is a SECRET whose target is $host: read it uncached so a stale cached // value can't be paired with a freshly-changed host (credential exfil). See Setting::uncached. $storedPassword = Setting::uncached('mail_password'); $password = null; if ($storedPassword !== null && $storedPassword !== '') { $password = Crypt::decryptString($storedPassword); } $changed = config('mail.default') !== 'smtp' || config('mail.mailers.smtp.host') !== $host; config([ 'mail.default' => 'smtp', 'mail.mailers.smtp.host' => $host, 'mail.mailers.smtp.port' => (int) (Setting::get('mail_port', '587') ?? 587), 'mail.mailers.smtp.username' => Setting::get('mail_username') ?: null, 'mail.mailers.smtp.password' => $password ?: null, 'mail.mailers.smtp.encryption' => $encryption === 'none' ? null : $encryption, 'mail.from.address' => $from, 'mail.from.name' => Setting::get('mail_from_name') ?: $from, ]); if ($changed) { Mail::purge('smtp'); // rebuild the cached transport with the new settings } } catch (Throwable) { // Settings table not migrated yet (install/migrate) or an undecryptable value — // leave the default mailer untouched. Never break the caller. } } }