security: harden data auth and deployment
This commit is contained in:
@@ -1025,16 +1025,12 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
|
||||
raise RuntimeError("SMTP email settings are incomplete.")
|
||||
local_hostname = _derive_mail_hostname(from_address=from_address)
|
||||
logger.info(
|
||||
"smtp send started recipient=%s from=%s host=%s port=%s tls=%s ssl=%s auth=%s subject=%s ehlo=%s",
|
||||
recipient_email,
|
||||
from_address,
|
||||
"smtp send started host=%s port=%s tls=%s ssl=%s auth=%s",
|
||||
host,
|
||||
port,
|
||||
use_tls,
|
||||
use_ssl,
|
||||
bool(username and password),
|
||||
subject,
|
||||
local_hostname,
|
||||
)
|
||||
if delivery_warning:
|
||||
logger.warning("smtp delivery warning host=%s detail=%s", host, delivery_warning)
|
||||
@@ -1083,11 +1079,7 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
|
||||
message=message,
|
||||
)
|
||||
logger.info(
|
||||
"smtp send accepted recipient=%s host=%s mode=ssl provider_message_id=%s provider_internal_id=%s",
|
||||
recipient_email,
|
||||
host,
|
||||
receipt.get("provider_message_id"),
|
||||
receipt.get("provider_internal_id"),
|
||||
"smtp send accepted host=%s mode=ssl", host,
|
||||
)
|
||||
return receipt
|
||||
|
||||
@@ -1100,7 +1092,7 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
|
||||
logger.debug("smtp starttls negotiated host=%s port=%s", host, port)
|
||||
if username and password:
|
||||
smtp.login(username, password)
|
||||
logger.debug("smtp login succeeded host=%s username=%s", host, username)
|
||||
logger.debug("smtp login succeeded host=%s", host)
|
||||
receipt = _send_via_smtp_session(
|
||||
smtp,
|
||||
from_address=from_address,
|
||||
@@ -1108,11 +1100,7 @@ def _send_email_sync(*, recipient_email: str, subject: str, body_text: str, body
|
||||
message=message,
|
||||
)
|
||||
logger.info(
|
||||
"smtp send accepted recipient=%s host=%s mode=plain provider_message_id=%s provider_internal_id=%s",
|
||||
recipient_email,
|
||||
host,
|
||||
receipt.get("provider_message_id"),
|
||||
receipt.get("provider_internal_id"),
|
||||
"smtp send accepted host=%s mode=plain", host,
|
||||
)
|
||||
return receipt
|
||||
|
||||
@@ -1153,7 +1141,7 @@ async def send_templated_email(
|
||||
body_text=rendered["body_text"],
|
||||
body_html=rendered["body_html"],
|
||||
)
|
||||
logger.info("Email template sent: template=%s recipient=%s", template_key, resolved_email)
|
||||
logger.info("Email template sent: template=%s", template_key)
|
||||
return {
|
||||
"recipient_email": resolved_email,
|
||||
"subject": rendered["subject"],
|
||||
@@ -1185,7 +1173,7 @@ async def send_generic_email(
|
||||
body_text=body_text.strip(),
|
||||
body_html=body_html.strip(),
|
||||
)
|
||||
logger.info("Generic email sent recipient=%s subject=%s", resolved_email, subject)
|
||||
logger.info("Generic email sent")
|
||||
return {
|
||||
"recipient_email": resolved_email,
|
||||
"subject": subject.strip() or f"{env_settings.app_name} notification",
|
||||
@@ -1284,7 +1272,7 @@ async def send_test_email(recipient_email: Optional[str] = None) -> Dict[str, st
|
||||
body_text=body_text,
|
||||
body_html=body_html,
|
||||
)
|
||||
logger.info("SMTP test email sent: recipient=%s", resolved_email)
|
||||
logger.info("SMTP test email sent")
|
||||
result = {"recipient_email": resolved_email, "subject": subject}
|
||||
result.update(
|
||||
{
|
||||
@@ -1383,9 +1371,8 @@ async def send_password_reset_email(
|
||||
body_html=body_html,
|
||||
)
|
||||
logger.info(
|
||||
"Password reset email sent: username=%s recipient=%s provider=%s",
|
||||
"Password reset email sent: username=%s provider=%s",
|
||||
username,
|
||||
resolved_email,
|
||||
auth_provider,
|
||||
)
|
||||
result = {
|
||||
|
||||
@@ -18,6 +18,7 @@ from ..db import (
|
||||
mark_password_reset_token_used,
|
||||
set_user_auth_provider,
|
||||
set_user_password,
|
||||
increment_user_auth_version,
|
||||
sync_jellyfin_password_state,
|
||||
)
|
||||
from ..runtime import get_runtime_settings
|
||||
@@ -243,7 +244,7 @@ async def request_password_reset(
|
||||
delete_expired_password_reset_tokens()
|
||||
target = await _resolve_reset_target(identifier)
|
||||
if not target:
|
||||
logger.info("password reset requested with no eligible match identifier=%s", identifier.strip().lower()[:256])
|
||||
logger.info("password reset requested with no eligible match")
|
||||
return {"status": "ok", "issued": False}
|
||||
|
||||
token = secrets.token_urlsafe(32)
|
||||
@@ -324,6 +325,7 @@ async def apply_password_reset(token: str, new_password: str) -> Dict[str, Any]:
|
||||
raise ValueError("Password reset link is invalid or has expired.")
|
||||
await client.set_user_password(user_id, new_password)
|
||||
sync_jellyfin_password_state(username, new_password)
|
||||
increment_user_auth_version(username)
|
||||
if str(stored_user.get("auth_provider") or "").strip().lower() != "jellyfin":
|
||||
set_user_auth_provider(username, "jellyfin")
|
||||
mark_password_reset_token_used(token)
|
||||
|
||||
Reference in New Issue
Block a user