""" 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'.")