From d726da1e04187f00c9bda6a3f95a331ddcea0312 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 11 May 2026 10:37:45 +0300 Subject: [PATCH 1/5] add mailjet mailer --- backend/app/Email/MailjetMailer.php | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 backend/app/Email/MailjetMailer.php diff --git a/backend/app/Email/MailjetMailer.php b/backend/app/Email/MailjetMailer.php new file mode 100644 index 0000000..dd1b0c5 --- /dev/null +++ b/backend/app/Email/MailjetMailer.php @@ -0,0 +1,36 @@ +mailjet->post(Resources::$Email, [ + 'body' => [ + 'Messages' => [ + [ + 'From' => [ + 'Email' => $from, + 'Name' => $this->fromName, + ], + 'To' => [ + [ + 'Email' => $to, + ], + ], + 'Subject' => 'TIDE', + 'TextPart' => $body, + ], + ], + ], + ]); + } +} From 2902addc769cbf14e2faf227f83b570dc88e893c Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 11 May 2026 10:37:54 +0300 Subject: [PATCH 2/5] bind mailjet mailer to emailer --- backend/app/Providers/AppServiceProvider.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/backend/app/Providers/AppServiceProvider.php b/backend/app/Providers/AppServiceProvider.php index d17a4c9..fcc0865 100644 --- a/backend/app/Providers/AppServiceProvider.php +++ b/backend/app/Providers/AppServiceProvider.php @@ -12,11 +12,12 @@ use App\Email\EmailConfirmationToken\EmailConfirmationTokenRepository; use App\Email\Emailer; use App\Email\EmailFactory; use App\Email\LaravelEmailFactory; -use App\Email\LaravelMailer; +use App\Email\MailjetMailer; use App\User\UseCases\SignupUser\SignupUser; use App\User\UserRepository; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\ServiceProvider; +use Mailjet\Client; class AppServiceProvider extends ServiceProvider { @@ -25,7 +26,17 @@ class AppServiceProvider extends ServiceProvider $this->app->bind(Clock::class, SystemClock::class); $this->app->bind(TokenGenerator::class, RandomTokenGenerator::class); $this->app->bind(PasswordHasher::class, BcryptPasswordHasher::class); - $this->app->bind(Emailer::class, LaravelMailer::class); + $this->app->bind(Emailer::class, function (Application $app) { + return new MailjetMailer( + mailjet: new Client( + config('services.mailjet.key'), + config('services.mailjet.secret'), + true, + ['version' => 'v3.1'], + ), + fromName: config('mail.from.name'), + ); + }); $this->app->bind( EmailFactory::class, function () { From ee675b8e767c19d56e1f3d214cf01caa246d8ed4 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 11 May 2026 10:38:11 +0300 Subject: [PATCH 3/5] install mailjet sdk --- backend/composer.json | 3 +- backend/composer.lock | 167 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/backend/composer.json b/backend/composer.json index 1947a93..46865c7 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -8,7 +8,8 @@ "require": { "php": "^8.4", "laravel/framework": "^12.0", - "laravel/tinker": "^2.10.1" + "laravel/tinker": "^2.10.1", + "mailjet/mailjet-apiv3-php": "^1.6" }, "require-dev": { "barryvdh/laravel-ide-helper": "^3.7", diff --git a/backend/composer.lock b/backend/composer.lock index a51e6aa..31d1e7a 100644 --- a/backend/composer.lock +++ b/backend/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2444476efd69100b99a6fdd87c19a200", + "content-hash": "3dbd75f32e2817f5cb61bd672fb6ae1f", "packages": [ { "name": "brick/math", @@ -2020,6 +2020,67 @@ ], "time": "2026-03-08T20:05:35+00:00" }, + { + "name": "mailjet/mailjet-apiv3-php", + "version": "v1.6.6", + "source": { + "type": "git", + "url": "https://github.com/mailjet/mailjet-apiv3-php.git", + "reference": "9d5cea25f347719d7df7909fb4a43a72bd4e5011" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mailjet/mailjet-apiv3-php/zipball/9d5cea25f347719d7df7909fb4a43a72bd4e5011", + "reference": "9d5cea25f347719d7df7909fb4a43a72bd4e5011", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^7.4.4", + "php": "^8.1", + "psr/http-client": "^1.0", + "symfony/validator": "^6.3|^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.4", + "php-coveralls/php-coveralls": "^2.0", + "phpcompatibility/php-compatibility": "*", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^11.4.0", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Mailjet": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mailjet", + "email": "dev@mailjet.com", + "homepage": "https://dev.mailjet.com" + } + ], + "description": "PHP wrapper for the Mailjet API", + "homepage": "https://github.com/mailjet/mailjet-apiv3-php/", + "keywords": [ + "Mailjet", + "api", + "email", + "php", + "v3" + ], + "support": { + "issues": "https://github.com/mailjet/mailjet-apiv3-php/issues", + "source": "https://github.com/mailjet/mailjet-apiv3-php/tree/v1.6.6" + }, + "time": "2025-12-24T15:55:48+00:00" + }, { "name": "monolog/monolog", "version": "3.10.0", @@ -5700,6 +5761,110 @@ ], "time": "2026-04-30T15:19:22+00:00" }, + { + "name": "symfony/validator", + "version": "v7.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/validator.git", + "reference": "c76458623af9a3fe3b2e5b09b36453f334c2a361" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/validator/zipball/c76458623af9a3fe3b2e5b09b36453f334c2a361", + "reference": "c76458623af9a3fe3b2e5b09b36453f334c2a361", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php83": "^1.27", + "symfony/translation-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/lexer": "<1.1", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<7.0", + "symfony/expression-language": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/intl": "<6.4", + "symfony/property-info": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/var-exporter": "<6.4.25|>=7.0,<7.3.3", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/string": "^6.4|^7.0|^8.0", + "symfony/translation": "^6.4.3|^7.0.3|^8.0", + "symfony/type-info": "^7.1.8", + "symfony/yaml": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + }, + "exclude-from-classmap": [ + "/Tests/", + "/Resources/bin/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to validate values", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/validator/tree/v7.4.10" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-05T15:30:56+00:00" + }, { "name": "symfony/var-dumper", "version": "v7.4.8", From 0f3b1b560db6eaadb40a483950df1a752ccb139f Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 11 May 2026 10:38:19 +0300 Subject: [PATCH 4/5] add frontend url to config --- backend/config/app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/config/app.php b/backend/config/app.php index 423eed5..765b705 100644 --- a/backend/config/app.php +++ b/backend/config/app.php @@ -14,7 +14,7 @@ return [ */ 'name' => env('APP_NAME', 'Laravel'), - + 'frontend_url' => env('FRONTEND_URL', 'https://tide.yisroelbaum.com'), /* |-------------------------------------------------------------------------- | Application Environment From 8d72ff121fe136d08867368da2b18cae2aadd7ff Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Mon, 11 May 2026 10:38:28 +0300 Subject: [PATCH 5/5] add mailjet config --- backend/config/services.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/config/services.php b/backend/config/services.php index 6a90eb8..e25151d 100644 --- a/backend/config/services.php +++ b/backend/config/services.php @@ -13,6 +13,10 @@ return [ | a conventional file to locate the various service credentials. | */ + 'mailjet' => [ + 'key' => env('MAILJET_API_KEY'), + 'secret' => env('MAILJET_SECRET_KEY'), + ], 'postmark' => [ 'key' => env('POSTMARK_API_KEY'),