From 2aacb1dc28233043403f28902a3b63c133b596b5 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:39:50 +0100 Subject: [PATCH] fix: Instance email settins - fix: resend, smtp save button should only save respective settings - feat: ability to send test email --- app/Livewire/SettingsEmail.php | 143 +++++++++++++++--- .../views/livewire/settings-email.blade.php | 133 ++++++++-------- 2 files changed, 196 insertions(+), 80 deletions(-) diff --git a/app/Livewire/SettingsEmail.php b/app/Livewire/SettingsEmail.php index abf3a12f9..daf8e8cab 100644 --- a/app/Livewire/SettingsEmail.php +++ b/app/Livewire/SettingsEmail.php @@ -3,6 +3,8 @@ namespace App\Livewire; use App\Models\InstanceSettings; +use App\Notifications\Test; +use Illuminate\Support\Facades\RateLimiter; use Livewire\Attributes\Validate; use Livewire\Component; @@ -13,6 +15,15 @@ class SettingsEmail extends Component #[Validate(['boolean'])] public bool $smtpEnabled = false; + #[Validate(['nullable', 'email'])] + public ?string $smtpFromAddress = null; + + #[Validate(['nullable', 'string'])] + public ?string $smtpFromName = null; + + #[Validate(['nullable', 'string'])] + public ?string $smtpRecipients = null; + #[Validate(['nullable', 'string'])] public ?string $smtpHost = null; @@ -20,29 +31,26 @@ class SettingsEmail extends Component public ?int $smtpPort = null; #[Validate(['nullable', 'string', 'in:tls,ssl,none'])] - public ?string $smtpEncryption = null; + public ?string $smtpEncryption = 'tls'; #[Validate(['nullable', 'string'])] public ?string $smtpUsername = null; - #[Validate(['nullable'])] + #[Validate(['nullable', 'string'])] public ?string $smtpPassword = null; #[Validate(['nullable', 'numeric'])] public ?int $smtpTimeout = null; - #[Validate(['nullable', 'email'])] - public ?string $smtpFromAddress = null; - - #[Validate(['nullable', 'string'])] - public ?string $smtpFromName = null; - #[Validate(['boolean'])] public bool $resendEnabled = false; #[Validate(['nullable', 'string'])] public ?string $resendApiKey = null; + #[Validate(['nullable', 'email'])] + public ?string $testEmailAddress = null; + public function mount() { if (isInstanceAdmin() === false) { @@ -90,7 +98,7 @@ class SettingsEmail extends Component try { $this->resetErrorBag(); $this->syncData(true); - $this->dispatch('success', 'Settings saved.'); + $this->dispatch('success', 'Transactional email settings updated.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -99,19 +107,120 @@ class SettingsEmail extends Component public function instantSave(string $type) { try { + $this->resetErrorBag(); + if ($type === 'SMTP') { - $this->resendEnabled = false; - } else { - $this->smtpEnabled = false; + $this->submitSmtp(); + } elseif ($type === 'Resend') { + $this->submitResend(); } - $this->syncData(true); - if ($this->smtpEnabled || $this->resendEnabled) { - $this->dispatch('success', "{$type} enabled."); - } else { - $this->dispatch('success', "{$type} disabled."); + + } catch (\Throwable $e) { + if ($type === 'SMTP') { + $this->smtpEnabled = false; + } elseif ($type === 'Resend') { + $this->resendEnabled = false; + } + + return handleError($e, $this); + } + } + + public function submitSmtp(): void + { + $this->validate([ + 'smtpEnabled' => 'boolean', + 'smtpFromAddress' => 'required|email', + 'smtpFromName' => 'required|string', + 'smtpHost' => 'required|string', + 'smtpPort' => 'required|numeric', + 'smtpEncryption' => 'required|string|in:tls,ssl,none', + 'smtpUsername' => 'nullable|string', + 'smtpPassword' => 'nullable|string', + 'smtpTimeout' => 'nullable|numeric', + ], [ + 'smtpFromAddress.required' => 'From Address is required.', + 'smtpFromAddress.email' => 'Please enter a valid email address.', + 'smtpFromName.required' => 'From Name is required.', + 'smtpHost.required' => 'SMTP Host is required.', + 'smtpPort.required' => 'SMTP Port is required.', + 'smtpPort.numeric' => 'SMTP Port must be a number.', + 'smtpEncryption.required' => 'Encryption type is required.', + ]); + + $this->resendEnabled = false; + + $this->settings->smtp_enabled = $this->smtpEnabled; + $this->settings->smtp_host = $this->smtpHost; + $this->settings->smtp_port = $this->smtpPort; + $this->settings->smtp_encryption = $this->smtpEncryption; + $this->settings->smtp_username = $this->smtpUsername; + $this->settings->smtp_password = $this->smtpPassword; + $this->settings->smtp_timeout = $this->smtpTimeout; + $this->settings->smtp_from_address = $this->smtpFromAddress; + $this->settings->smtp_from_name = $this->smtpFromName; + $this->settings->resend_enabled = false; + $this->settings->save(); + + $this->dispatch('success', 'SMTP settings updated.'); + } + + public function submitResend(): void + { + $this->validate([ + 'resendEnabled' => 'boolean', + 'resendApiKey' => 'required|string', + 'smtpFromAddress' => 'required|email', + 'smtpFromName' => 'required|string', + ], [ + 'resendApiKey.required' => 'Resend API Key is required.', + 'smtpFromAddress.required' => 'From Address is required.', + 'smtpFromAddress.email' => 'Please enter a valid email address.', + 'smtpFromName.required' => 'From Name is required.', + ]); + + $this->smtpEnabled = false; + + $this->settings->resend_enabled = $this->resendEnabled; + $this->settings->resend_api_key = $this->resendApiKey; + $this->settings->smtp_from_address = $this->smtpFromAddress; + $this->settings->smtp_from_name = $this->smtpFromName; + $this->settings->smtp_enabled = false; + $this->settings->save(); + + $this->dispatch('success', 'Resend settings updated.'); + } + + public function sendTestEmail() + { + try { + $this->validate([ + 'testEmailAddress' => 'required|email', + ], [ + 'testEmailAddress.required' => 'Test email address is required.', + 'testEmailAddress.email' => 'Please enter a valid email address.', + ]); + + $executed = RateLimiter::attempt( + 'test-email:'.$this->team->id, + $perMinute = 0, + function () { + $this->team?->notify(new Test($this->testEmailAddress)); + $this->dispatch('success', 'Test Email sent.'); + }, + $decaySeconds = 10, + ); + + if (! $executed) { + throw new \Exception('Too many messages sent!'); } } catch (\Throwable $e) { return handleError($e, $this); } } + + public function isEmailEnabled(): bool + { + return $this->settings->smtp_enabled || $this->settings->resend_enabled; + } } diff --git a/resources/views/livewire/settings-email.blade.php b/resources/views/livewire/settings-email.blade.php index 141922584..bbe9512a0 100644 --- a/resources/views/livewire/settings-email.blade.php +++ b/resources/views/livewire/settings-email.blade.php @@ -1,71 +1,78 @@