117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends
|
|
|
|
from app.api.v1.schemas import (
|
|
MailConnectionTestResponse,
|
|
MailImapFolderListResponse,
|
|
MailImapFolderResponse,
|
|
MailImapTestRequest,
|
|
MailSmtpTestRequest,
|
|
)
|
|
from app.auth.dependencies import ApiPrincipal, require_scope
|
|
from app.mailer.sending.imap import list_imap_folders, test_imap_login
|
|
from app.mailer.sending.smtp import test_smtp_login
|
|
|
|
router = APIRouter(prefix="/mail", tags=["mail"])
|
|
|
|
|
|
def _safe_error_message(exc: Exception) -> str:
|
|
text = str(exc).strip()
|
|
return text or exc.__class__.__name__
|
|
|
|
|
|
@router.post("/test-smtp", response_model=MailConnectionTestResponse)
|
|
def test_smtp_settings(
|
|
payload: MailSmtpTestRequest,
|
|
principal: ApiPrincipal = Depends(require_scope("campaign:write")),
|
|
):
|
|
"""Test SMTP connectivity/login without sending any message."""
|
|
|
|
del principal
|
|
try:
|
|
result = test_smtp_login(smtp_config=payload)
|
|
return MailConnectionTestResponse(
|
|
ok=True,
|
|
protocol="smtp",
|
|
host=result.host,
|
|
port=result.port,
|
|
security=result.security,
|
|
message="SMTP connection successful.",
|
|
details={"authenticated": result.authenticated},
|
|
)
|
|
except Exception as exc:
|
|
return MailConnectionTestResponse(
|
|
ok=False,
|
|
protocol="smtp",
|
|
host=payload.host,
|
|
port=payload.port,
|
|
security=payload.security.value,
|
|
message=_safe_error_message(exc),
|
|
details={"error_type": exc.__class__.__name__},
|
|
)
|
|
|
|
|
|
@router.post("/test-imap", response_model=MailConnectionTestResponse)
|
|
def test_imap_settings(
|
|
payload: MailImapTestRequest,
|
|
principal: ApiPrincipal = Depends(require_scope("campaign:write")),
|
|
):
|
|
"""Test IMAP connectivity/login without selecting or appending messages."""
|
|
|
|
del principal
|
|
try:
|
|
result = test_imap_login(imap_config=payload)
|
|
return MailConnectionTestResponse(
|
|
ok=True,
|
|
protocol="imap",
|
|
host=result.host,
|
|
port=result.port,
|
|
security=result.security,
|
|
message="IMAP connection successful.",
|
|
details={"authenticated": result.authenticated},
|
|
)
|
|
except Exception as exc:
|
|
return MailConnectionTestResponse(
|
|
ok=False,
|
|
protocol="imap",
|
|
host=payload.host,
|
|
port=payload.port,
|
|
security=payload.security.value,
|
|
message=_safe_error_message(exc),
|
|
details={"error_type": exc.__class__.__name__},
|
|
)
|
|
|
|
|
|
@router.post("/list-imap-folders", response_model=MailImapFolderListResponse)
|
|
def list_imap_folder_settings(
|
|
payload: MailImapTestRequest,
|
|
principal: ApiPrincipal = Depends(require_scope("campaign:write")),
|
|
):
|
|
"""List visible IMAP folders and return the best Sent-folder guess."""
|
|
|
|
del principal
|
|
try:
|
|
result = list_imap_folders(imap_config=payload)
|
|
folders = [MailImapFolderResponse(name=item.name, flags=item.flags) for item in result.folders]
|
|
return MailImapFolderListResponse(
|
|
ok=True,
|
|
host=result.host,
|
|
port=result.port,
|
|
security=result.security,
|
|
message=f"Found {len(folders)} IMAP folder(s).",
|
|
folders=folders,
|
|
detected_sent_folder=result.detected_sent_folder,
|
|
)
|
|
except Exception as exc:
|
|
return MailImapFolderListResponse(
|
|
ok=False,
|
|
host=payload.host,
|
|
port=payload.port,
|
|
security=payload.security.value,
|
|
message=_safe_error_message(exc),
|
|
folders=[],
|
|
detected_sent_folder=None,
|
|
details={"error_type": exc.__class__.__name__},
|
|
)
|