From 5678ab9a366ceed937355134e64f93f5c95d14bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malte=20M=C3=BCns?= Date: Mon, 2 Oct 2023 13:38:21 +0200 Subject: [PATCH] [Mailer] Use idn encoded address otherwise Brevo throws an error --- .../Tests/Transport/BrevoApiTransportTest.php | 43 ++++++++++++++++++- .../Brevo/Transport/BrevoApiTransport.php | 2 +- .../Transport/SendinblueApiTransportTest.php | 43 ++++++++++++++++++- .../Transport/SendinblueApiTransport.php | 2 +- 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Mailer/Bridge/Brevo/Tests/Transport/BrevoApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Brevo/Tests/Transport/BrevoApiTransportTest.php index f7fc0b7b91976..09c82e55e2330 100644 --- a/src/Symfony/Component/Mailer/Bridge/Brevo/Tests/Transport/BrevoApiTransportTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Brevo/Tests/Transport/BrevoApiTransportTest.php @@ -34,7 +34,7 @@ public function testToString(BrevoApiTransport $transport, string $expected) $this->assertSame($expected, (string) $transport); } - public static function getTransportData() + public static function getTransportData(): \Generator { yield [ new BrevoApiTransport('ACCESS_KEY'), @@ -143,4 +143,45 @@ public function testSend() $this->assertSame('foobar', $message->getMessageId()); } + + /** + * IDN (internationalized domain names) like kältetechnik-xyz.de need to be transformed to ACE + * (ASCII Compatible Encoding) e.g.xn--kltetechnik-xyz-0kb.de, otherwise brevo api answers with 400 http code. + * + * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface + */ + public function testSendForIdnDomains() + { + $client = new MockHttpClient(function (string $method, string $url, array $options): ResponseInterface { + $this->assertSame('POST', $method); + $this->assertSame('https://api.brevo.com:8984/v3/smtp/email', $url); + $this->assertStringContainsString('Accept: */*', $options['headers'][2] ?? $options['request_headers'][1]); + + $body = json_decode($options['body'], true); + // to + $this->assertSame('kältetechnik@xn--kltetechnik-xyz-0kb.de', $body['to'][0]['email']); + $this->assertSame('Kältetechnik Xyz', $body['to'][0]['name']); + // sender + $this->assertSame('info@xn--kltetechnik-xyz-0kb.de', $body['sender']['email']); + $this->assertSame('Kältetechnik Xyz', $body['sender']['name']); + + return new MockResponse(json_encode(['messageId' => 'foobar']), [ + 'http_code' => 201, + ]); + }); + + $transport = new BrevoApiTransport('ACCESS_KEY', $client); + $transport->setPort(8984); + + $mail = new Email(); + $mail->subject('Hello!') + ->to(new Address('kältetechnik@kältetechnik-xyz.de', 'Kältetechnik Xyz')) + ->from(new Address('info@kältetechnik-xyz.de', 'Kältetechnik Xyz')) + ->text('Hello here!') + ->html('Hello there!'); + + $message = $transport->send($mail); + + $this->assertSame('foobar', $message->getMessageId()); + } } diff --git a/src/Symfony/Component/Mailer/Bridge/Brevo/Transport/BrevoApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Brevo/Transport/BrevoApiTransport.php index d5facfaf69231..5e5050f77d196 100644 --- a/src/Symfony/Component/Mailer/Bridge/Brevo/Transport/BrevoApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Brevo/Transport/BrevoApiTransport.php @@ -172,7 +172,7 @@ private function prepareHeadersAndTags(Headers $headers): array private function formatAddress(Address $address): array { - $formattedAddress = ['email' => $address->getAddress()]; + $formattedAddress = ['email' => $address->getEncodedAddress()]; if ($address->getName()) { $formattedAddress['name'] = $address->getName(); diff --git a/src/Symfony/Component/Mailer/Bridge/Sendinblue/Tests/Transport/SendinblueApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Sendinblue/Tests/Transport/SendinblueApiTransportTest.php index 9962005775fd3..4e1249de39077 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendinblue/Tests/Transport/SendinblueApiTransportTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendinblue/Tests/Transport/SendinblueApiTransportTest.php @@ -37,7 +37,7 @@ public function testToString(SendinblueApiTransport $transport, string $expected $this->assertSame($expected, (string) $transport); } - public static function getTransportData() + public static function getTransportData(): \Generator { yield [ new SendinblueApiTransport('ACCESS_KEY'), @@ -149,4 +149,45 @@ public function testSend() $this->assertSame('foobar', $message->getMessageId()); } + + /** + * IDN (internationalized domain names) like kältetechnik-xyz.de need to be transformed to ACE + * (ASCII Compatible Encoding) e.g.xn--kltetechnik-xyz-0kb.de, otherwise SendinBlue api answers with 400 http code. + * + * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface + */ + public function testSendForIdnDomains() + { + $client = new MockHttpClient(function (string $method, string $url, array $options): ResponseInterface { + $this->assertSame('POST', $method); + $this->assertSame('https://api.sendinblue.com:8984/v3/smtp/email', $url); + $this->assertStringContainsString('Accept: */*', $options['headers'][2] ?? $options['request_headers'][1]); + + $body = json_decode($options['body'], true); + // to + $this->assertSame('kältetechnik@xn--kltetechnik-xyz-0kb.de', $body['to'][0]['email']); + $this->assertSame('Kältetechnik Xyz', $body['to'][0]['name']); + // sender + $this->assertSame('info@xn--kltetechnik-xyz-0kb.de', $body['sender']['email']); + $this->assertSame('Kältetechnik Xyz', $body['sender']['name']); + + return new MockResponse(json_encode(['messageId' => 'foobar']), [ + 'http_code' => 201, + ]); + }); + + $transport = new SendinblueApiTransport('ACCESS_KEY', $client); + $transport->setPort(8984); + + $mail = new Email(); + $mail->subject('Hello!') + ->to(new Address('kältetechnik@kältetechnik-xyz.de', 'Kältetechnik Xyz')) + ->from(new Address('info@kältetechnik-xyz.de', 'Kältetechnik Xyz')) + ->text('Hello here!') + ->html('Hello there!'); + + $message = $transport->send($mail); + + $this->assertSame('foobar', $message->getMessageId()); + } } diff --git a/src/Symfony/Component/Mailer/Bridge/Sendinblue/Transport/SendinblueApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Sendinblue/Transport/SendinblueApiTransport.php index e1e2bb69d3b6d..2c022c294ee72 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendinblue/Transport/SendinblueApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendinblue/Transport/SendinblueApiTransport.php @@ -171,7 +171,7 @@ private function prepareHeadersAndTags(Headers $headers): array private function stringifyAddress(Address $address): array { - $stringifiedAddress = ['email' => $address->getAddress()]; + $stringifiedAddress = ['email' => $address->getEncodedAddress()]; if ($address->getName()) { $stringifiedAddress['name'] = $address->getName();