api/app/services/email_service.py
Yoga Pangestu 104a58e6e7 Add password reset functionality with email notifications
- Implemented endpoints for forgot password and reset password
- Added PasswordResetToken model and relationships
- Integrated email service using Resend for sending reset links
- Updated configuration for email and frontend URL
- Enhanced user model to include password reset tokens
- Added necessary schemas for password reset requests
- Updated requirements to include Resend SDK
- Created comprehensive documentation for the new feature
2026-07-22 20:22:58 +07:00

56 lines
2.6 KiB
Python

import resend
from app.config import settings
def send_password_reset_email(to_email: str, reset_url: str) -> None:
resend.api_key = settings.RESEND_API_KEY
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap" rel="stylesheet">
</head>
<body style="font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background-color: #fafafa; margin: 0; padding: 40px 20px;">
<div style="max-width: 480px; margin: 0 auto; background: #ffffff; border-radius: 16px; padding: 40px; box-shadow: 0 2px 8px rgba(0,0,0,0.06);">
<div style="text-align: center; margin: 0 0 24px;">
<div style="display: inline-block; width: 48px; height: 48px; background-color: #f0fdf4; border-radius: 12px; line-height: 48px;">
<span style="font-size: 24px;">🔒</span>
</div>
</div>
<h1 style="font-size: 20px; font-weight: 600; color: #1a1a1a; margin: 0 0 8px; text-align: center;">Reset Kata Sandi</h1>
<p style="font-size: 14px; color: #71717a; margin: 0 0 24px; line-height: 1.6; text-align: center;">
Anda menerima email ini karena kami menerima permintaan reset kata sandi untuk akun Anda.
</p>
<div style="text-align: center; margin: 0 0 24px;">
<a href="{reset_url}"
style="display: inline-block; background-color: #22C55E; color: #ffffff; text-decoration: none; padding: 12px 32px; border-radius: 30px; font-size: 15px; font-weight: 500;">
Reset Kata Sandi
</a>
</div>
<p style="font-size: 13px; color: #a1a1aa; margin: 0 0 8px; line-height: 1.6; text-align: center;">
Link ini berlaku selama <strong>1 jam</strong>.
</p>
<p style="font-size: 13px; color: #a1a1aa; margin: 0; line-height: 1.6; text-align: center;">
Jika Anda tidak meminta reset kata sandi, abaikan email ini.
</p>
</div>
<p style="font-size: 12px; color: #d4d4d8; text-align: center; margin: 24px 0 0;">
&copy; 2026 Profitra. Semua hak dilindungi.
</p>
</body>
</html>
"""
params: resend.Emails.SendParams = {
"from": settings.EMAIL_FROM,
"to": [to_email],
"subject": "Reset Kata Sandi - Profitra",
"html": html_content,
}
resend.Emails.send(params)