import secrets import smtplib import ssl from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import bcrypt import logging import os # Configure logging logger = logging.getLogger(__name__) # Email configuration # Email configuration SMTP_SERVER = os.getenv("SMTP_SERVER", "127.0.0.1") SMTP_PORT = int(os.getenv("SMTP_PORT", "1025")) # Prioritize EMAIL_ID and EMAIL_PASSWORD if available SMTP_USERNAME = os.getenv("EMAIL_ID") or os.getenv("SMTP_USERNAME", "sender@domain.com") SMTP_PASSWORD = os.getenv("EMAIL_PASSWORD") or os.getenv("SMTP_PASSWORD", "yourpassword") # Auto-configure for Gmail if using defaults and gmail address if SMTP_SERVER == "127.0.0.1" and "gmail.com" in SMTP_USERNAME: SMTP_SERVER = "smtp.gmail.com" SMTP_PORT = 465 SMTP_SENDER = os.getenv("SMTP_SENDER", SMTP_USERNAME) from gmail_service import GmailService # Initialize Gmail Service gmail_service = GmailService() def verify_password(plain_password: str, hashed_password: str) -> bool: """ Verify a password against a hash. """ if isinstance(hashed_password, str): hashed_password = hashed_password.encode('utf-8') return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password) def get_password_hash(password: str) -> str: """ Hash a password using bcrypt. """ # rounds=12 as per spec salt = bcrypt.gensalt(rounds=12) hashed = bcrypt.hashpw(password.encode('utf-8'), salt) return hashed.decode('utf-8') def generate_secret_key() -> str: """ Generate a secure secret key starting with 'sk_'. """ return "sk_" + secrets.token_urlsafe(32) def send_email(to_email: str, subject: str, body: str): """ Send an email using Gmail API. This function is blocking and should be run in a background task. """ # Try Gmail API first if gmail_service.authenticate(): return gmail_service.send_email(to_email, subject, body) logger.warning("Gmail API credentials not found or invalid. Falling back to SMTP (may fail on some platforms).") # Fallback to SMTP (Original Implementation) try: message = MIMEMultipart() message["From"] = SMTP_SENDER message["To"] = to_email message["Subject"] = subject message.attach(MIMEText(body, "plain")) # Create a secure SSL context context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT, context=context) as server: server.login(SMTP_USERNAME, SMTP_PASSWORD) server.sendmail(SMTP_SENDER, to_email, message.as_string()) logger.info(f"Email sent successfully to {to_email} via SMTP") return True except Exception as e: logger.error(f"Failed to send email to {to_email}: {e}") return False