Add SES Driver as an email provider option for hosted

This commit is contained in:
David Bomba
2025-08-28 07:43:41 +10:00
parent 5160555d7a
commit 39483d7c63
5 changed files with 150 additions and 1 deletions

View File

@@ -231,7 +231,7 @@ class CompanySettings extends BaseSettings
public $require_quote_signature = false; //@TODO ben to confirm
//email settings
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun', 'mailgun', 'client_brevo', 'client_ses' //@implemented
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun', 'mailgun', 'client_brevo', 'client_ses', 'ses' //@implemented
public $gmail_sending_user_id = '0'; //@implemented

View File

@@ -399,6 +399,10 @@ class NinjaMailerJob implements ShouldQueue
$this->mailer = 'mailgun';
$this->setHostedMailgunMailer();
return $this;
case 'ses':
$this->mailer = 'ses';
$this->setHostedSesMailer();
return $this;
case 'gmail':
$this->mailer = 'gmail';
$this->setGmailMailer();
@@ -580,6 +584,20 @@ class NinjaMailerJob implements ShouldQueue
}
private function setHostedSesMailer()
{
if (property_exists($this->nmo->settings, 'email_from_name') && strlen($this->nmo->settings->email_from_name) > 1) {
$email_from_name = $this->nmo->settings->email_from_name;
} else {
$email_from_name = $this->company->present()->name();
}
$this->nmo
->mailable
->from(config('services.ses.from.address'), $email_from_name);
}
/**
* Configures Mailgun using client supplied secret
* as the Mailer

View File

@@ -546,7 +546,20 @@ class Email implements ShouldQueue
}
private function setHostedSesMailer()
{
if (property_exists($this->email_object->settings, 'email_from_name') && strlen($this->email_object->settings->email_from_name) > 1) {
$email_from_name = $this->email_object->settings->email_from_name;
} else {
$email_from_name = $this->company->present()->name();
}
$this->mailable
->from(config('services.ses.from.address'), $email_from_name);
}
/**
* Sets the mail driver to use and applies any specific configuration
* the the mailable
@@ -601,6 +614,10 @@ class Email implements ShouldQueue
$this->mailer = 'mailgun';
$this->setHostedMailgunMailer();
return $this;
case 'ses':
$this->mailer = 'ses';
$this->setHostedSesMailer();
return $this;
case 'gmail':
$this->mailer = 'gmail';
$this->setGmailMailer();

View File

@@ -77,6 +77,9 @@ return [
'secret' => env('SES_AWS_SECRET_ACCESS_KEY'),
'region' => env('SES_REGION', 'us-east-1'),
'topic_arn' => env('SES_TOPIC_ARN', ''),
'from' => [
'address' => env('SES_FROM_ADDRESS', ''),
],
],
'sparkpost' => [

View File

@@ -0,0 +1,111 @@
<?php
namespace Tests\Unit\Rules;
use App\Rules\CommaSeparatedEmails;
use PHPUnit\Framework\TestCase;
class CommaSeparatedEmailsTest extends TestCase
{
public function test_validates_single_email()
{
$rule = new CommaSeparatedEmails();
$failed = false;
$rule->validate('emails', 'test@example.com', function() use (&$failed) {
$failed = true;
});
$this->assertFalse($failed);
}
public function test_validates_multiple_emails()
{
$rule = new CommaSeparatedEmails();
$failed = false;
$rule->validate('emails', 'test1@example.com, test2@example.com, test3@example.com', function() use (&$failed) {
$failed = true;
});
$this->assertFalse($failed);
}
public function test_validates_emails_with_whitespace()
{
$rule = new CommaSeparatedEmails();
$failed = false;
$rule->validate('emails', ' test1@example.com , test2@example.com ', function() use (&$failed) {
$failed = true;
});
$this->assertFalse($failed);
}
public function test_fails_with_invalid_email()
{
$rule = new CommaSeparatedEmails();
$failed = false;
$errorMessage = '';
$rule->validate('emails', 'invalid-email, test@example.com', function($message) use (&$failed, &$errorMessage) {
$failed = true;
$errorMessage = $message;
});
$this->assertTrue($failed);
$this->assertStringContainsString('invalid-email', $errorMessage);
}
public function test_fails_with_empty_emails()
{
$rule = new CommaSeparatedEmails();
$failed = false;
$rule->validate('emails', 'test@example.com, , test2@example.com', function() use (&$failed) {
$failed = true;
});
$this->assertFalse($failed); // Empty emails are filtered out
}
public function test_fails_when_exceeding_max_emails()
{
$rule = new CommaSeparatedEmails(2); // Max 2 emails
$failed = false;
$errorMessage = '';
$rule->validate('emails', 'test1@example.com, test2@example.com, test3@example.com', function($message) use (&$failed, &$errorMessage) {
$failed = true;
$errorMessage = $message;
});
$this->assertTrue($failed);
$this->assertStringContainsString('cannot contain more than 2', $errorMessage);
}
public function test_validates_null_value()
{
$rule = new CommaSeparatedEmails();
$failed = false;
$rule->validate('emails', null, function() use (&$failed) {
$failed = true;
});
$this->assertFalse($failed);
}
public function test_validates_empty_string()
{
$rule = new CommaSeparatedEmails();
$failed = false;
$rule->validate('emails', '', function() use (&$failed) {
$failed = true;
});
$this->assertFalse($failed);
}
}