Initial commit: AegisSight-Monitor-Verwaltung
Dieser Commit ist enthalten in:
0
src/email_utils/__init__.py
Normale Datei
0
src/email_utils/__init__.py
Normale Datei
53
src/email_utils/sender.py
Normale Datei
53
src/email_utils/sender.py
Normale Datei
@@ -0,0 +1,53 @@
|
||||
"""Async E-Mail-Versand via SMTP."""
|
||||
import logging
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
|
||||
import aiosmtplib
|
||||
|
||||
from config import (
|
||||
SMTP_HOST,
|
||||
SMTP_PORT,
|
||||
SMTP_USER,
|
||||
SMTP_PASSWORD,
|
||||
SMTP_FROM_EMAIL,
|
||||
SMTP_FROM_NAME,
|
||||
SMTP_USE_TLS,
|
||||
)
|
||||
|
||||
logger = logging.getLogger("verwaltung.email")
|
||||
|
||||
|
||||
async def send_email(to_email: str, subject: str, html_body: str) -> bool:
|
||||
"""Sendet eine HTML-E-Mail.
|
||||
|
||||
Returns:
|
||||
True bei Erfolg, False bei Fehler.
|
||||
"""
|
||||
if not SMTP_HOST:
|
||||
logger.warning(f"SMTP nicht konfiguriert - E-Mail an {to_email} nicht gesendet: {subject}")
|
||||
return False
|
||||
|
||||
msg = MIMEMultipart("alternative")
|
||||
msg["From"] = f"{SMTP_FROM_NAME} <{SMTP_FROM_EMAIL}>"
|
||||
msg["To"] = to_email
|
||||
msg["Subject"] = subject
|
||||
|
||||
text_content = f"Betreff: {subject}\n\nBitte oeffnen Sie diese E-Mail in einem HTML-faehigen E-Mail-Client."
|
||||
msg.attach(MIMEText(text_content, "plain", "utf-8"))
|
||||
msg.attach(MIMEText(html_body, "html", "utf-8"))
|
||||
|
||||
try:
|
||||
await aiosmtplib.send(
|
||||
msg,
|
||||
hostname=SMTP_HOST,
|
||||
port=SMTP_PORT,
|
||||
username=SMTP_USER if SMTP_USER else None,
|
||||
password=SMTP_PASSWORD if SMTP_PASSWORD else None,
|
||||
start_tls=SMTP_USE_TLS,
|
||||
)
|
||||
logger.info(f"E-Mail gesendet an {to_email}: {subject}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"E-Mail-Versand fehlgeschlagen an {to_email}: {e}")
|
||||
return False
|
||||
36
src/email_utils/templates.py
Normale Datei
36
src/email_utils/templates.py
Normale Datei
@@ -0,0 +1,36 @@
|
||||
"""HTML-E-Mail-Vorlagen fuer das Verwaltungsportal."""
|
||||
|
||||
|
||||
def invite_email(username: str, org_name: str, code: str, link: str) -> tuple[str, str]:
|
||||
"""Erzeugt Einladungs-E-Mail fuer neue OSINT-Monitor-Nutzer.
|
||||
|
||||
Returns:
|
||||
(subject, html_body)
|
||||
"""
|
||||
subject = f"Einladung zum IntelSight OSINT Monitor - {org_name}"
|
||||
html = f"""<!DOCTYPE html>
|
||||
<html>
|
||||
<head><meta charset="UTF-8"></head>
|
||||
<body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0f172a; color: #e2e8f0; padding: 40px 20px;">
|
||||
<div style="max-width: 480px; margin: 0 auto; background: #1e293b; border-radius: 12px; padding: 32px; border: 1px solid #334155;">
|
||||
<h1 style="color: #f0b429; font-size: 20px; margin: 0 0 24px 0;">IntelSight OSINT Monitor</h1>
|
||||
|
||||
<p style="margin: 0 0 16px 0;">Hallo {username},</p>
|
||||
|
||||
<p style="margin: 0 0 16px 0;">Sie wurden zur Organisation <strong>{org_name}</strong> im IntelSight OSINT Monitor eingeladen.</p>
|
||||
|
||||
<p style="margin: 0 0 24px 0;">Klicken Sie auf den Link, um Ihren Zugang zu aktivieren:</p>
|
||||
|
||||
<div style="background: #0f172a; border-radius: 8px; padding: 20px; text-align: center; margin: 0 0 24px 0;">
|
||||
<div style="font-size: 32px; font-weight: 700; letter-spacing: 8px; color: #f0b429; font-family: monospace;">{code}</div>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin: 0 0 24px 0;">
|
||||
<a href="{link}" style="display: inline-block; background: #f0b429; color: #0f172a; padding: 12px 32px; border-radius: 6px; text-decoration: none; font-weight: 600;">Einladung annehmen</a>
|
||||
</div>
|
||||
|
||||
<p style="color: #94a3b8; font-size: 13px; margin: 0;">Dieser Link ist 10 Minuten gueltig.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>"""
|
||||
return subject, html
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren