my-recipes/backend/email_utils.py
2025-12-14 06:04:25 +02:00

107 lines
3.2 KiB
Python

import os
import random
import aiosmtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime, timedelta
from dotenv import load_dotenv
load_dotenv()
# In-memory storage for verification codes (in production, use Redis or database)
verification_codes = {}
def generate_verification_code():
"""Generate a 6-digit verification code"""
return str(random.randint(100000, 999999))
async def send_verification_email(email: str, code: str, purpose: str = "password_change"):
"""Send verification code via email"""
smtp_host = os.getenv("SMTP_HOST", "smtp.gmail.com")
smtp_port = int(os.getenv("SMTP_PORT", "587"))
smtp_user = os.getenv("SMTP_USER")
smtp_password = os.getenv("SMTP_PASSWORD")
smtp_from = os.getenv("SMTP_FROM", smtp_user)
if not smtp_user or not smtp_password:
raise Exception("SMTP credentials not configured")
# Create message
message = MIMEMultipart("alternative")
message["Subject"] = "קוד אימות - מתכונים שלי"
message["From"] = smtp_from
message["To"] = email
# Email content
if purpose == "password_change":
text = f"""
שלום,
קוד האימות שלך לשינוי סיסמה הוא: {code}
הקוד תקף ל-10 דקות.
אם לא ביקשת לשנות את הסיסמה, התעלם מהודעה זו.
בברכה,
צוות מתכונים שלי
"""
html = f"""
<html dir="rtl">
<body style="font-family: Arial, sans-serif; direction: rtl; text-align: right;">
<h2>שינוי סיסמה</h2>
<p>קוד האימות שלך הוא:</p>
<h1 style="color: #22c55e; font-size: 32px; letter-spacing: 5px;">{code}</h1>
<p>הקוד תקף ל-<strong>10 דקות</strong>.</p>
<hr style="border: 1px solid #e5e7eb; margin: 20px 0;">
<p style="color: #6b7280; font-size: 14px;">
אם לא ביקשת לשנות את הסיסמה, התעלם מהודעה זו.
</p>
</body>
</html>
"""
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)
# Send email
await aiosmtplib.send(
message,
hostname=smtp_host,
port=smtp_port,
username=smtp_user,
password=smtp_password,
start_tls=True,
)
def store_verification_code(user_id: int, code: str):
"""Store verification code with expiry"""
expiry = datetime.now() + timedelta(minutes=10)
verification_codes[user_id] = {
"code": code,
"expiry": expiry
}
def verify_code(user_id: int, code: str) -> bool:
"""Verify if code is correct and not expired"""
if user_id not in verification_codes:
return False
stored = verification_codes[user_id]
# Check if expired
if datetime.now() > stored["expiry"]:
del verification_codes[user_id]
return False
# Check if code matches
if stored["code"] != code:
return False
# Code is valid, remove it
del verification_codes[user_id]
return True