From 9b1f57769e5288c99fa7b6a4d015e73dcecdaf01 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Tue, 7 Jul 2026 12:39:55 -0400 Subject: [PATCH] July 7 - Test mail --- test_mail.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 test_mail.py diff --git a/test_mail.py b/test_mail.py new file mode 100644 index 0000000..3788b83 --- /dev/null +++ b/test_mail.py @@ -0,0 +1,72 @@ +""" +test_mail.py — one-off SMTP diagnostic. NOT part of the app. + +Run on the server, in the app directory, with the venv active: + + python test_mail.py your-address@example.com + +It prints the live mail config and tries TWO sends with different From +addresses so we can see whether the problem is SMTP itself or the sender +address the reset email uses. Delete this file once diagnosed. +""" + +import sys +from app import create_app, mail +from flask_mail import Message + +app = create_app('production') # match how gunicorn runs it + +to_addr = sys.argv[1] if len(sys.argv) > 1 else None +if not to_addr: + print("Usage: python test_mail.py your-address@example.com") + sys.exit(1) + +with app.app_context(): + cfg = app.config + print("=" * 60) + print("MAIL_SERVER :", cfg.get("MAIL_SERVER")) + print("MAIL_PORT :", cfg.get("MAIL_PORT")) + print("MAIL_USE_SSL :", cfg.get("MAIL_USE_SSL")) + print("MAIL_USE_TLS :", cfg.get("MAIL_USE_TLS")) + print("MAIL_USERNAME :", cfg.get("MAIL_USERNAME")) + print("MAIL_DEFAULT_SENDER:", cfg.get("MAIL_DEFAULT_SENDER")) + print("APP_BASE_URL :", cfg.get("APP_BASE_URL")) + print("=" * 60) + + if not cfg.get("MAIL_SERVER"): + print("STOP: MAIL_SERVER is not set in this environment. " + "No email can be sent at all.") + sys.exit(2) + + # Attempt A — send from MAIL_DEFAULT_SENDER (what notification emails use) + default_sender = cfg.get("MAIL_DEFAULT_SENDER") or cfg.get("MAIL_USERNAME") + print(f"\n[A] Sending from MAIL_DEFAULT_SENDER: {default_sender}") + try: + mail.send(Message( + subject="[JQC] Test A (default sender)", + sender=default_sender, + recipients=[to_addr], + body="Test A: sent from MAIL_DEFAULT_SENDER.", + )) + print(" [A] RESULT: relay ACCEPTED") + except Exception as e: + print(" [A] RESULT: FAILED ->", repr(e)) + + # Attempt B — send from noreply@ (what the reset/invite email uses) + from urllib.parse import urlparse + base = (cfg.get("APP_BASE_URL") or "").rstrip("/") + host = urlparse(base).netloc or "janitorialqc.local" + noreply_sender = f"noreply@{host}" + print(f"\n[B] Sending from reset-style sender: {noreply_sender}") + try: + mail.send(Message( + subject="[JQC] Test B (noreply sender)", + sender=noreply_sender, + recipients=[to_addr], + body="Test B: sent from noreply@.", + )) + print(" [B] RESULT: relay ACCEPTED") + except Exception as e: + print(" [B] RESULT: FAILED ->", repr(e)) + + print("\nDone. Check the inbox/spam for 'Test A' and 'Test B'.")