fix: test connection authenticates only, no email sent to avoid agent self-reply loop

linuztx committed Mar 16, 2026 at 11:30 UTC 3d9f5a846b8a13076c3ec52a13bc9abc868bd815
2 files changed +28 -8
plugins/_email_integration/api/test_connection.py
+3 -8
@@ -8,7 +8,7 @@ from plugins._email_integration.helpers.imap_client import (
8 disconnect_imap,
9 get_highest_uid,
10 )
11 -from plugins._email_integration.helpers.smtp_client import SmtpConfig, send_reply
11 +from plugins._email_integration.helpers.smtp_client import SmtpConfig, test_smtp
12
13
14 class TestConnection(ApiHandler):
@@ -56,19 +56,14 @@ class TestConnection(ApiHandler):
56 username=handler.get("username", ""),
57 password=handler.get("password", ""),
58 )
59 - error = await send_reply(
60 - config=cfg,
61 - to=handler.get("username", ""),
62 - subject="Agent Zero - Connection Test",
63 - body="SMTP connection test successful.",
64 - )
59 + error = await test_smtp(cfg)
60 if error:
61 results.append({"test": "SMTP", "ok": False, "message": error})
62 else:
63 results.append({
64 "test": "SMTP",
65 "ok": True,
71 - "message": "Connected, test email sent to self",
66 + "message": "Authenticated successfully",
67 })
68 except Exception as e:
69 results.append({
plugins/_email_integration/helpers/smtp_client.py
+25
@@ -87,3 +87,28 @@ async def send_reply(
87 error = format_error(e)
88 PrintStyle.error(f"Email send failed: {error}")
89 return error
90 +
91 +
92 +# ------------------------------------------------------------------
93 +# Connection test (auth only, no email sent)
94 +# ------------------------------------------------------------------
95 +
96 +async def test_smtp(config: SmtpConfig) -> str | None:
97 + loop = asyncio.get_event_loop()
98 +
99 + def _sync_test():
100 + if config.use_tls:
101 + with smtplib.SMTP(config.server, config.port) as server:
102 + server.ehlo()
103 + server.starttls()
104 + server.ehlo()
105 + server.login(config.username, config.password)
106 + else:
107 + with smtplib.SMTP_SSL(config.server, config.port) as server:
108 + server.login(config.username, config.password)
109 +
110 + try:
111 + await loop.run_in_executor(None, _sync_test)
112 + return None
113 + except Exception as e:
114 + return format_error(e)