Feat(Chore, Fix): Refractor, Half Baked Deletion + Admin Privilege

Refractor Codes into sub file/folders
Admin can remove users'/members mfa/2fa, unlink account from  oauth provider
Admin can  add/reset password
Different Email (OIDC + Manual)-Same Account; (Block Linking and authorize if available)
This commit is contained in:
2026-03-04 18:49:04 +05:45
parent ea1bacc794
commit 7cb522b590
63 changed files with 7896 additions and 10863 deletions
+26 -5
View File
@@ -295,6 +295,7 @@ Gatehouse Security Team
Returns True if the email was sent successfully, False otherwise.
If EMAIL_ENABLED is False, logs the email body instead (simulation mode).
All SMTP exceptions are caught and logged — this method never raises.
"""
import smtplib
from email.mime.multipart import MIMEMultipart
@@ -310,17 +311,37 @@ Gatehouse Security Team
)
return False
smtp_host = current_app.config.get(NotificationService.SMTP_HOST_KEY, "localhost")
smtp_port = int(current_app.config.get(NotificationService.SMTP_PORT_KEY, 587))
smtp_host = current_app.config.get(NotificationService.SMTP_HOST_KEY, "")
smtp_port_raw = current_app.config.get(NotificationService.SMTP_PORT_KEY, 587)
smtp_username = current_app.config.get(NotificationService.SMTP_USERNAME_KEY)
smtp_password = current_app.config.get(NotificationService.SMTP_PASSWORD_KEY)
from_address = current_app.config.get(
NotificationService.FROM_ADDRESS_KEY, ""
)
# Guard: refuse to attempt a connection when critical config is missing.
# This surfaces a clear log message instead of a confusing socket error.
missing = [k for k, v in [
("SMTP_HOST", smtp_host),
("FROM_ADDRESS", from_address),
] if not v]
if missing:
logger.error(
f"[EMAIL] Cannot send — missing config: {', '.join(missing)}. "
f"Would have sent to: {to_address} | Subject: {subject}"
)
return False
try:
smtp_port = int(smtp_port_raw)
except (TypeError, ValueError):
logger.error(f"[EMAIL] Invalid SMTP_PORT value: {smtp_port_raw!r}")
return False
smtp_use_tls = current_app.config.get(
NotificationService.SMTP_USE_TLS_KEY,
smtp_port not in (25, 1025),
)
from_address = current_app.config.get(
NotificationService.FROM_ADDRESS_KEY, "noreply@gatehouse.local"
)
try:
msg = MIMEMultipart("alternative")