From 4e4516f9a2a95e5ffafee8ba048f189b00abf1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Elizeche=20Land=C3=B3?= Date: Mon, 7 Apr 2025 10:57:22 -0400 Subject: [PATCH] stages/email: fix for newlines in emails (#13712) * Test fix for newlines in emails * fix linting * remove base64 names from email address * Make better checks on message.to * Remove unnecessary logger --- authentik/stages/email/tasks.py | 7 +++++ authentik/stages/email/tests/test_sending.py | 31 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/authentik/stages/email/tasks.py b/authentik/stages/email/tasks.py index 7faa2ac758..92fc34dd2c 100644 --- a/authentik/stages/email/tasks.py +++ b/authentik/stages/email/tasks.py @@ -104,6 +104,13 @@ def send_mail( # can't be converted to json) message_object.attach(logo_data()) + if ( + message_object.to + and isinstance(message_object.to[0], str) + and "=?utf-8?" in message_object.to[0] + ): + message_object.to = [message_object.to[0].split("<")[-1].replace(">", "")] + LOGGER.debug("Sending mail", to=message_object.to) backend.send_messages([message_object]) Event.new( diff --git a/authentik/stages/email/tests/test_sending.py b/authentik/stages/email/tests/test_sending.py index fc36cc7db6..4f2b5758c2 100644 --- a/authentik/stages/email/tests/test_sending.py +++ b/authentik/stages/email/tests/test_sending.py @@ -97,6 +97,37 @@ class TestEmailStageSending(FlowTestCase): self.assertEqual(mail.outbox[0].subject, "authentik") self.assertEqual(mail.outbox[0].to, [f"Test User Many Words <{long_user.email}>"]) + def test_utf8_name(self): + """Test with pending user""" + plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) + utf8_user = create_test_user() + utf8_user.name = "Cirilo ЉМНЊ el cirilico И̂ӢЙӤ " + utf8_user.email = "cyrillic@authentik.local" + utf8_user.save() + plan.context[PLAN_CONTEXT_PENDING_USER] = utf8_user + session = self.client.session + session[SESSION_KEY_PLAN] = plan + session.save() + Event.objects.filter(action=EventAction.EMAIL_SENT).delete() + + url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}) + with patch( + "authentik.stages.email.models.EmailStage.backend_class", + PropertyMock(return_value=EmailBackend), + ): + response = self.client.post(url) + self.assertEqual(response.status_code, 200) + self.assertStageResponse( + response, + self.flow, + response_errors={ + "non_field_errors": [{"string": "email-sent", "code": "email-sent"}] + }, + ) + self.assertEqual(len(mail.outbox), 1) + self.assertEqual(mail.outbox[0].subject, "authentik") + self.assertEqual(mail.outbox[0].to, [f"{utf8_user.email}"]) + def test_pending_fake_user(self): """Test with pending (fake) user""" self.flow.designation = FlowDesignation.RECOVERY