Update auth.py
Browse files
auth.py
CHANGED
|
@@ -13,6 +13,7 @@ import logging
|
|
| 13 |
import random
|
| 14 |
import smtplib
|
| 15 |
import uuid
|
|
|
|
| 16 |
from datetime import datetime, timezone, timedelta
|
| 17 |
from email.mime.text import MIMEText
|
| 18 |
from email.mime.multipart import MIMEMultipart
|
|
@@ -31,6 +32,7 @@ JWT_SECRET = os.environ.get("JWT_SECRET", "change-me-in-production")
|
|
| 31 |
JWT_ALGORITHM = "HS256"
|
| 32 |
JWT_EXPIRE_HOURS = 24 * 7 # 7 days
|
| 33 |
|
|
|
|
| 34 |
SMTP_EMAIL = os.environ.get("SMTP_EMAIL", "")
|
| 35 |
SMTP_APP_PASSWORD = os.environ.get("SMTP_APP_PASSWORD", "")
|
| 36 |
SMTP_HOST = os.environ.get("SMTP_HOST", "smtp.gmail.com")
|
|
@@ -90,32 +92,17 @@ def _generate_code() -> str:
|
|
| 90 |
|
| 91 |
|
| 92 |
def _send_verification_email(to_email: str, code: str, username: str) -> bool:
|
| 93 |
-
"""Send verification code via Gmail SMTP. Returns True on success."""
|
| 94 |
-
if not SMTP_EMAIL or not SMTP_APP_PASSWORD:
|
| 95 |
logger.warning(
|
| 96 |
-
"
|
| 97 |
"Skipping email — code is: %s", code
|
| 98 |
)
|
| 99 |
return True # Allow registration to proceed in dev mode
|
| 100 |
|
| 101 |
try:
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
msg["To"] = to_email
|
| 105 |
-
msg["Subject"] = f"SADA — Kode Verifikasi Anda: {code}"
|
| 106 |
-
|
| 107 |
-
# Plain text version
|
| 108 |
-
text = (
|
| 109 |
-
f"Halo {username},\n\n"
|
| 110 |
-
f"Kode verifikasi akun SADA Anda adalah:\n\n"
|
| 111 |
-
f" {code}\n\n"
|
| 112 |
-
f"Kode ini berlaku selama {VERIFY_CODE_EXPIRE_MINUTES} menit.\n\n"
|
| 113 |
-
f"Jika Anda tidak mendaftar di SADA, abaikan email ini.\n\n"
|
| 114 |
-
f"— Tim SADA"
|
| 115 |
-
)
|
| 116 |
-
|
| 117 |
-
# HTML version
|
| 118 |
-
html = f"""
|
| 119 |
<div style="font-family: 'Segoe UI', Arial, sans-serif; max-width: 480px; margin: 0 auto; padding: 32px;">
|
| 120 |
<div style="text-align: center; margin-bottom: 32px;">
|
| 121 |
<h1 style="font-size: 28px; font-weight: 700; color: #111; margin: 0;">SADA</h1>
|
|
@@ -143,16 +130,40 @@ def _send_verification_email(to_email: str, code: str, username: str) -> bool:
|
|
| 143 |
</div>
|
| 144 |
"""
|
| 145 |
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
except Exception as e:
|
| 158 |
logger.error("Failed to send verification email to %s: %s", to_email, e)
|
|
|
|
| 13 |
import random
|
| 14 |
import smtplib
|
| 15 |
import uuid
|
| 16 |
+
import requests
|
| 17 |
from datetime import datetime, timezone, timedelta
|
| 18 |
from email.mime.text import MIMEText
|
| 19 |
from email.mime.multipart import MIMEMultipart
|
|
|
|
| 32 |
JWT_ALGORITHM = "HS256"
|
| 33 |
JWT_EXPIRE_HOURS = 24 * 7 # 7 days
|
| 34 |
|
| 35 |
+
BREVO_API_KEY = os.environ.get("BREVO_API_KEY", "")
|
| 36 |
SMTP_EMAIL = os.environ.get("SMTP_EMAIL", "")
|
| 37 |
SMTP_APP_PASSWORD = os.environ.get("SMTP_APP_PASSWORD", "")
|
| 38 |
SMTP_HOST = os.environ.get("SMTP_HOST", "smtp.gmail.com")
|
|
|
|
| 92 |
|
| 93 |
|
| 94 |
def _send_verification_email(to_email: str, code: str, username: str) -> bool:
|
| 95 |
+
"""Send verification code via Brevo API or Gmail SMTP. Returns True on success."""
|
| 96 |
+
if not BREVO_API_KEY and (not SMTP_EMAIL or not SMTP_APP_PASSWORD):
|
| 97 |
logger.warning(
|
| 98 |
+
"Neither BREVO_API_KEY nor SMTP configured. "
|
| 99 |
"Skipping email — code is: %s", code
|
| 100 |
)
|
| 101 |
return True # Allow registration to proceed in dev mode
|
| 102 |
|
| 103 |
try:
|
| 104 |
+
subject = f"SADA — Kode Verifikasi Anda: {code}"
|
| 105 |
+
html_content = f"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
<div style="font-family: 'Segoe UI', Arial, sans-serif; max-width: 480px; margin: 0 auto; padding: 32px;">
|
| 107 |
<div style="text-align: center; margin-bottom: 32px;">
|
| 108 |
<h1 style="font-size: 28px; font-weight: 700; color: #111; margin: 0;">SADA</h1>
|
|
|
|
| 130 |
</div>
|
| 131 |
"""
|
| 132 |
|
| 133 |
+
if BREVO_API_KEY:
|
| 134 |
+
# Menggunakan Brevo REST API (Bypasses SMTP port blocking)
|
| 135 |
+
headers = {
|
| 136 |
+
"accept": "application/json",
|
| 137 |
+
"api-key": BREVO_API_KEY,
|
| 138 |
+
"content-type": "application/json"
|
| 139 |
+
}
|
| 140 |
+
payload = {
|
| 141 |
+
"sender": {"name": "SADA", "email": SMTP_EMAIL or "noreply@sada-detection.com"},
|
| 142 |
+
"to": [{"email": to_email, "name": username}],
|
| 143 |
+
"subject": subject,
|
| 144 |
+
"htmlContent": html_content
|
| 145 |
+
}
|
| 146 |
+
res = requests.post("https://api.brevo.com/v3/smtp/email", json=payload, headers=headers)
|
| 147 |
+
res.raise_for_status()
|
| 148 |
+
logger.info("Verification email sent via Brevo API to %s", to_email)
|
| 149 |
+
return True
|
| 150 |
+
else:
|
| 151 |
+
# Fallback ke standar Gmail SMTP
|
| 152 |
+
text = f"Halo {username},\n\nKode verifikasi SADA Anda: {code}\nBerlaku {VERIFY_CODE_EXPIRE_MINUTES} menit."
|
| 153 |
+
msg = MIMEMultipart("alternative")
|
| 154 |
+
msg["From"] = f"SADA <{SMTP_EMAIL}>"
|
| 155 |
+
msg["To"] = to_email
|
| 156 |
+
msg["Subject"] = subject
|
| 157 |
+
msg.attach(MIMEText(text, "plain"))
|
| 158 |
+
msg.attach(MIMEText(html_content, "html"))
|
| 159 |
+
|
| 160 |
+
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
|
| 161 |
+
server.starttls()
|
| 162 |
+
server.login(SMTP_EMAIL, SMTP_APP_PASSWORD)
|
| 163 |
+
server.send_message(msg)
|
| 164 |
+
|
| 165 |
+
logger.info("Verification email sent via SMTP to %s", to_email)
|
| 166 |
+
return True
|
| 167 |
|
| 168 |
except Exception as e:
|
| 169 |
logger.error("Failed to send verification email to %s: %s", to_email, e)
|