""" Email Service - AWS SES integration for verification and password reset emails. """ import os import secrets from datetime import datetime, timedelta import boto3 from botocore.exceptions import ClientError AWS_REGION = os.getenv("AWS_SES_REGION", "us-east-1") EMAIL_FROM = os.getenv("EMAIL_FROM", "noreply@elmeg.xyz") FRONTEND_URL = os.getenv("FRONTEND_URL", "https://elmeg.xyz") # AWS credentials from environment (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) # or from IAM role if running on AWS infrastructure def get_ses_client(): """Get boto3 SES client""" return boto3.client('ses', region_name=AWS_REGION) def send_email(to: str, subject: str, html_content: str) -> bool: """Send email via AWS SES""" # Dev mode - just log if not os.getenv("AWS_ACCESS_KEY_ID"): print(f"[EMAIL DEV MODE] To: {to}, Subject: {subject}") print(f"[EMAIL DEV MODE] Content: {html_content[:200]}...") return True try: client = get_ses_client() response = client.send_email( Source=EMAIL_FROM, Destination={'ToAddresses': [to]}, Message={ 'Subject': {'Data': subject, 'Charset': 'UTF-8'}, 'Body': { 'Html': {'Data': html_content, 'Charset': 'UTF-8'} } } ) print(f"Email sent to {to}, MessageId: {response['MessageId']}") return True except ClientError as e: print(f"Failed to send email: {e.response['Error']['Message']}") return False def generate_token() -> str: """Generate a secure random token""" return secrets.token_urlsafe(32) async def send_verification_email(email: str, token: str) -> bool: """Send email verification link""" verify_url = f"{FRONTEND_URL}/verify-email?token={token}" html = f"""
Please verify your email address by clicking the button below:
Verify EmailOr copy this link: {verify_url}
This link expires in 48 hours.
You requested a password reset. Click below to set a new password:
Reset PasswordOr copy this link: {reset_url}
This link expires in 1 hour. If you didn't request this, ignore this email.