All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
234 lines
7.6 KiB
Python
234 lines
7.6 KiB
Python
import smtplib
|
|
from email.mime.text import MIMEText
|
|
from email.mime.multipart import MIMEMultipart
|
|
from typing import Optional
|
|
from app.config import settings
|
|
|
|
|
|
def send_email(
|
|
to_email: str,
|
|
subject: str,
|
|
body: str,
|
|
html_body: Optional[str] = None
|
|
) -> bool:
|
|
"""
|
|
Send an email using SMTP configuration from settings.
|
|
|
|
Args:
|
|
to_email: Recipient email address
|
|
subject: Email subject
|
|
body: Plain text body
|
|
html_body: Optional HTML body (if provided, will be sent as multipart)
|
|
|
|
Returns:
|
|
bool: True if email sent successfully, False otherwise
|
|
"""
|
|
try:
|
|
# Create message
|
|
message = MIMEMultipart('alternative') if html_body else MIMEText(body, 'plain')
|
|
|
|
if html_body:
|
|
message['Subject'] = subject
|
|
message['From'] = settings.smtp_from
|
|
message['To'] = to_email
|
|
|
|
# Attach plain text and HTML versions
|
|
part1 = MIMEText(body, 'plain')
|
|
part2 = MIMEText(html_body, 'html')
|
|
message.attach(part1)
|
|
message.attach(part2)
|
|
else:
|
|
message['Subject'] = subject
|
|
message['From'] = settings.smtp_from
|
|
message['To'] = to_email
|
|
|
|
# Check if SMTP is configured
|
|
if not settings.smtp_username or not settings.smtp_password:
|
|
print(f"⚠️ SMTP not configured. Email would have been sent to: {to_email}")
|
|
print(f"Subject: {subject}")
|
|
print(f"Body:\n{body}")
|
|
return False
|
|
|
|
# Connect to SMTP server
|
|
with smtplib.SMTP(settings.smtp_host, settings.smtp_port) as server:
|
|
server.starttls()
|
|
server.login(settings.smtp_username, settings.smtp_password)
|
|
server.send_message(message)
|
|
|
|
print(f"✅ Email sent successfully to {to_email}")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Failed to send email to {to_email}: {str(e)}")
|
|
return False
|
|
|
|
|
|
def send_password_reset_pin(email: str, pin: str, expires_minutes: int = 15) -> bool:
|
|
"""
|
|
Send password reset PIN email.
|
|
|
|
Args:
|
|
email: User's email address
|
|
pin: 6-digit PIN code
|
|
expires_minutes: Minutes until PIN expires
|
|
|
|
Returns:
|
|
bool: True if email sent successfully
|
|
"""
|
|
subject = "Brand Master - Password Reset PIN"
|
|
|
|
# Plain text version
|
|
body = f"""
|
|
Hello,
|
|
|
|
You requested a password reset for your Brand Master account.
|
|
|
|
Your 6-digit PIN code is: {pin}
|
|
|
|
This PIN will expire in {expires_minutes} minutes.
|
|
|
|
To reset your password:
|
|
1. Go to the login page
|
|
2. Click "Forgot Password"
|
|
3. Enter this PIN when prompted
|
|
4. Create your new password
|
|
|
|
If you didn't request this reset, please ignore this email.
|
|
|
|
Best regards,
|
|
Brand Master Team
|
|
"""
|
|
|
|
# HTML version
|
|
html_body = f"""
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }}
|
|
.container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
|
|
.header {{ background: #007bff; color: white; padding: 20px; text-align: center; border-radius: 5px 5px 0 0; }}
|
|
.content {{ background: #f9f9f9; padding: 30px; border-radius: 0 0 5px 5px; }}
|
|
.pin-box {{ background: white; padding: 20px; text-align: center; border: 2px solid #007bff; border-radius: 5px; margin: 20px 0; }}
|
|
.pin {{ font-size: 32px; font-weight: bold; color: #007bff; letter-spacing: 5px; }}
|
|
.warning {{ color: #dc3545; font-weight: bold; }}
|
|
.footer {{ text-align: center; color: #666; margin-top: 20px; font-size: 12px; }}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>Password Reset Request</h1>
|
|
</div>
|
|
<div class="content">
|
|
<p>Hello,</p>
|
|
<p>You requested a password reset for your Brand Master account.</p>
|
|
|
|
<div class="pin-box">
|
|
<p style="margin: 0; font-size: 14px;">Your 6-digit PIN code is:</p>
|
|
<p class="pin">{pin}</p>
|
|
<p style="margin: 0; color: #666;">Expires in {expires_minutes} minutes</p>
|
|
</div>
|
|
|
|
<p><strong>To reset your password:</strong></p>
|
|
<ol>
|
|
<li>Go to the <a href="https://brand-master.dvirlabs.com/login">login page</a></li>
|
|
<li>Click "Forgot Password"</li>
|
|
<li>Enter this PIN when prompted</li>
|
|
<li>Create your new password</li>
|
|
</ol>
|
|
|
|
<p class="warning">⚠️ If you didn't request this reset, please ignore this email.</p>
|
|
|
|
<div class="footer">
|
|
<p>This is an automated message from Brand Master. Please do not reply.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
return send_email(email, subject, body, html_body)
|
|
|
|
|
|
def send_welcome_email(email: str, full_name: str) -> bool:
|
|
"""
|
|
Send welcome email to new users.
|
|
|
|
Args:
|
|
email: User's email address
|
|
full_name: User's full name
|
|
|
|
Returns:
|
|
bool: True if email sent successfully
|
|
"""
|
|
subject = "Welcome to Brand Master!"
|
|
|
|
body = f"""
|
|
Hello {full_name},
|
|
|
|
Welcome to Brand Master! Your account has been created successfully.
|
|
|
|
You can now:
|
|
- Browse our collection of premium shoes and apparel
|
|
- Add items to your wishlist
|
|
- Place orders with secure checkout
|
|
- Track your order history
|
|
|
|
Visit us at: https://brand-master.dvirlabs.com
|
|
|
|
Best regards,
|
|
Brand Master Team
|
|
"""
|
|
|
|
html_body = f"""
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }}
|
|
.container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
|
|
.header {{ background: linear-gradient(135deg, #007bff 0%, #0056b3 100%); color: white; padding: 30px; text-align: center; border-radius: 5px 5px 0 0; }}
|
|
.content {{ background: #f9f9f9; padding: 30px; border-radius: 0 0 5px 5px; }}
|
|
.button {{ display: inline-block; padding: 12px 30px; background: #007bff; color: white; text-decoration: none; border-radius: 5px; margin: 20px 0; }}
|
|
.features {{ background: white; padding: 20px; border-radius: 5px; margin: 20px 0; }}
|
|
.footer {{ text-align: center; color: #666; margin-top: 20px; font-size: 12px; }}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>Welcome to Brand Master!</h1>
|
|
<p>Your premium fashion destination</p>
|
|
</div>
|
|
<div class="content">
|
|
<p>Hello {full_name},</p>
|
|
<p>Welcome aboard! Your account has been created successfully.</p>
|
|
|
|
<div class="features">
|
|
<h3>What you can do:</h3>
|
|
<ul>
|
|
<li>✅ Browse our collection of premium shoes and apparel</li>
|
|
<li>✅ Add items to your wishlist</li>
|
|
<li>✅ Place orders with secure checkout</li>
|
|
<li>✅ Track your order history</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div style="text-align: center;">
|
|
<a href="https://brand-master.dvirlabs.com" class="button">Start Shopping</a>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<p>Questions? Contact us at info@brandmaster.com</p>
|
|
<p>This is an automated message from Brand Master.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
return send_email(email, subject, body, html_body)
|