diff --git a/app/Http/Requests/Company/UpdateCompanyRequest.php b/app/Http/Requests/Company/UpdateCompanyRequest.php index f697042384..c130073f7a 100644 --- a/app/Http/Requests/Company/UpdateCompanyRequest.php +++ b/app/Http/Requests/Company/UpdateCompanyRequest.php @@ -114,6 +114,7 @@ class UpdateCompanyRequest extends Request $rules['settings.ses_secret_key'] = 'required_if:settings.email_sending_method,client_ses'; //ses specific rules $rules['settings.ses_access_key'] = 'required_if:settings.email_sending_method,client_ses'; //ses specific rules $rules['settings.ses_region'] = 'required_if:settings.email_sending_method,client_ses'; //ses specific rules + $rules['settings.ses_from_address'] = 'required_if:settings.email_sending_method,client_ses'; //ses specific rules $rules['settings.reply_to_email'] = 'sometimes|nullable|email'; // ensures that the reply to email address is a valid email address $rules['settings.bcc_email'] = ['sometimes', 'nullable', new \App\Rules\CommaSeparatedEmails]; //ensure that the BCC's are valid comma separated emails diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index 638b022163..b4b63c9b1b 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -66,6 +66,8 @@ class NinjaMailerJob implements ShouldQueue protected $client_brevo_secret = false; + protected $client_ses_secret = false; + public function __construct(public ?NinjaMailerObject $nmo, public bool $override = false) { } @@ -138,6 +140,10 @@ class NinjaMailerJob implements ShouldQueue $mailer->brevo_config($this->client_brevo_secret); } + if($this->client_ses_secret) { + $mailer->ses_config($this->nmo->settings->ses_access_key, $this->nmo->settings->ses_secret_key, $this->nmo->settings->ses_region, $this->nmo->settings->ses_topic_arn); + } + $mailable = $this->nmo->mailable; /** May need to re-build it here @todo explain why we need this? */ @@ -398,10 +404,11 @@ class NinjaMailerJob implements ShouldQueue $this->mailer = 'ses'; $this->setHostedSesMailer(); return $this; - // case 'client_ses': - // $this->mailer = 'ses'; - // $this->setSesMailer(); - // return $this; + case 'client_ses': + $this->mailer = 'ses'; + $this->client_ses_secret = true; + $this->setSesMailer(); + return $this; case 'gmail': $this->mailer = 'gmail'; $this->setGmailMailer(); @@ -545,6 +552,8 @@ class NinjaMailerJob implements ShouldQueue $this->client_brevo_secret = false; + $this->client_ses_secret = false; + //always dump the drivers to prevent reuse app('mail.manager')->forgetMailers(); } @@ -646,6 +655,20 @@ class NinjaMailerJob implements ShouldQueue ->from($sending_email, $sending_user); } + private function setSesMailer(): self + { + $this->mailer = 'ses'; + + $user = $this->resolveSendingUser(); + $sending_user = (isset($this->nmo->settings->email_from_name) && strlen($this->nmo->settings->email_from_name) > 2) ? $this->nmo->settings->email_from_name : $user->name(); + + $this->nmo + ->mailable + ->from($this->nmo->settings->ses_from_address, $sending_user); + + return $this; + } + /** * Configures Postmark using client supplied secret * as the Mailer @@ -788,7 +811,7 @@ class NinjaMailerJob implements ShouldQueue } /* GMail users are uncapped */ - if (Ninja::isHosted() && (in_array($this->nmo->settings->email_sending_method, ['gmail', 'office365', 'client_postmark', 'client_mailgun', 'client_brevo']))) { + if (Ninja::isHosted() && (in_array($this->nmo->settings->email_sending_method, ['gmail', 'office365', 'client_postmark', 'client_mailgun', 'client_brevo', 'client_ses']))) { return false; } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index e69bbc9ac4..bb54b50738 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -149,23 +149,18 @@ class AppServiceProvider extends ServiceProvider // Macro to configure SES with runtime credentials Mailer::macro('ses_config', function (string $key, string $secret, string $region = 'us-east-1', ?string $topic_arn = null) { $config = [ + 'transport' => 'ses', 'key' => $key, 'secret' => $secret, 'region' => $region, - 'version' => 'latest', - 'service' => 'email', ]; - $options = []; if ($topic_arn) { - $options['ConfigurationSetName'] = $topic_arn; + $config['configuration_set'] = $topic_arn; } - $sesClient = new \Aws\Ses\SesClient($config); - $transport = new \Illuminate\Mail\Transport\SesTransport($sesClient, $options); - // @phpstan-ignore /** @phpstan-ignore-next-line **/ - Mailer::setSymfonyTransport($transport); + Mailer::setSymfonyTransport(app('mail.manager')->createSymfonyTransport($config)); return $this; }); diff --git a/app/Services/Email/Email.php b/app/Services/Email/Email.php index 17beead6a1..4e757d92b3 100644 --- a/app/Services/Email/Email.php +++ b/app/Services/Email/Email.php @@ -78,6 +78,9 @@ class Email implements ShouldQueue /** Brevo endpoint */ protected ?string $client_brevo_secret = null; + /** SES api key */ + protected ?string $client_ses_secret = null; + /** Default mailer */ private string $mailer = 'default'; @@ -263,11 +266,10 @@ class Email implements ShouldQueue */ public function email() { - +nlog("Email::email"); /* Init the mailer*/ $mailer = Mail::mailer($this->mailer); - /* Additional configuration if using a client third party mailer */ if ($this->client_postmark_secret) { $mailer->postmark_config($this->client_postmark_secret); @@ -281,6 +283,10 @@ class Email implements ShouldQueue $mailer->brevo_config($this->client_brevo_secret); } + if ($this->client_ses_secret) { + $mailer->ses_config($this->email_object->settings->ses_access_key, $this->email_object->settings->ses_secret_key, $this->email_object->settings->ses_region, $this->email_object->settings->ses_topic_arn); + } + /* Attempt the send! */ try { nlog("Using mailer => " . $this->mailer . " " . now()->toDateTimeString()); @@ -463,7 +469,7 @@ class Email implements ShouldQueue } /* GMail users are uncapped */ - if (in_array($this->email_object->settings->email_sending_method, ['gmail', 'office365', 'client_postmark', 'client_mailgun', 'client_brevo'])) { + if (in_array($this->email_object->settings->email_sending_method, ['gmail', 'office365', 'client_postmark', 'client_mailgun', 'client_brevo', 'client_ses'])) { return false; } @@ -640,6 +646,10 @@ class Email implements ShouldQueue $this->mailer = 'brevo'; $this->setBrevoMailer(); return $this; + case 'client_ses': + $this->mailer = 'ses'; + $this->setSesMailer(); + return $this; case 'smtp': $this->mailer = 'smtp'; $this->configureSmtpMailer(); @@ -718,6 +728,8 @@ class Email implements ShouldQueue $this->client_brevo_secret = null; + $this->client_ses_secret = null; + //always dump the drivers to prevent reuse app('mail.manager')->forgetMailers(); } @@ -782,6 +794,21 @@ class Email implements ShouldQueue $this->mailable ->from($sending_email, $sending_user); } + + private function setSesMailer() + { + + $this->client_ses_secret = 'true'; + + $user = $this->resolveSendingUser(); + + $sending_user = (isset($this->email_object->settings->email_from_name) && strlen($this->email_object->settings->email_from_name) > 2) ? $this->email_object->settings->email_from_name : $user->name(); + + $this->mailable + ->from($this->email_object->settings->ses_from_address, $sending_user); + + } + /** * Configures Brevo using client supplied secret * as the Mailer