From 67a446aca06fc6ff40d46ddc706034521aebb074 Mon Sep 17 00:00:00 2001 From: Mison Date: Tue, 24 Mar 2026 10:26:48 +0800 Subject: [PATCH] fix(email): resolve Tempmail.lol field drift and OTP anchor race condition --- src/services/tempmail.py | 6 +++- tests/test_tempmail_timestamp_filter.py | 48 +++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/services/tempmail.py b/src/services/tempmail.py index aef3350..a0a5ca8 100644 --- a/src/services/tempmail.py +++ b/src/services/tempmail.py @@ -89,7 +89,11 @@ class TempmailService(BaseEmailService): def _get_received_timestamp(self, message: Dict[str, Any]) -> Optional[float]: """返回 Tempmail 邮件的接收时间戳。""" - return self._parse_message_time(message.get("received_at")) + for field_name in ("received_at", "date", "created_at", "createdAt", "timestamp"): + timestamp = self._parse_message_time(message.get(field_name)) + if timestamp is not None: + return timestamp + return None def _save_token_to_db(self, email: str, token: str) -> None: """将邮箱 token 持久化到 Setting 表,key=tempmail_token:{email}""" diff --git a/tests/test_tempmail_timestamp_filter.py b/tests/test_tempmail_timestamp_filter.py index 9723997..10ba8e7 100644 --- a/tests/test_tempmail_timestamp_filter.py +++ b/tests/test_tempmail_timestamp_filter.py @@ -63,7 +63,7 @@ def test_get_verification_code_ignores_messages_received_before_otp_sent_at(): assert code == "222222" -def test_get_verification_code_requires_received_at_when_otp_sent_at_is_present(): +def test_get_verification_code_uses_date_field_when_received_at_is_missing(): service = TempmailService({"base_url": "https://api.tempmail.test"}) service._email_cache["tester@example.com"] = {"token": "token-1"} service.http_client = FakeHTTPClient([ @@ -95,4 +95,48 @@ def test_get_verification_code_requires_received_at_when_otp_sent_at_is_present( otp_sent_at=_to_timestamp("2026-03-23T10:00:05Z"), ) - assert code == "444444" + assert code == "333333" + + +def test_get_verification_code_accepts_tempmail_date_field_as_timestamp(): + service = TempmailService({"base_url": "https://api.tempmail.test"}) + service._email_cache["tester@example.com"] = {"token": "token-1"} + service.http_client = FakeHTTPClient([ + FakeResponse( + { + "emails": [ + { + "id": "old-mail", + "date": "2026-03-23T10:00:02Z", + "from": "noreply@openai.com", + "subject": "Old code", + "body": "111111", + }, + { + "id": "new-mail", + "date": "2026-03-23T10:00:08Z", + "from": "noreply@openai.com", + "subject": "New code", + "body": "222222", + }, + ] + } + ) + ]) + + code = service.get_verification_code( + email="tester@example.com", + timeout=1, + otp_sent_at=_to_timestamp("2026-03-23T10:00:05Z"), + ) + + assert code == "222222" + + +def test_parse_message_time_normalizes_timezone_offset(): + service = TempmailService({"base_url": "https://api.tempmail.test"}) + + utc_timestamp = service._parse_message_time("2026-03-23T10:00:07Z") + offset_timestamp = service._parse_message_time("2026-03-23T18:00:07+08:00") + + assert utc_timestamp == offset_timestamp