Catalyst / admin/Bid-Sentinel 14.8 GB / 57.8 GB 40.0 GB free
Help Sign in

admin / Bid-Sentinel

public

Bid Scrape and Tracking Application with AI Capability

Code Issues Pull requests Pipelines Packages Security Insights Wiki Settings
Bid-Sentinel / bid-sentinel-v2 / backend / app / routers / mail.py 2105 B · main
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""Email endpoints: email a generated report to the logged-in user's own address."""
from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile, status

from app import mailer
from app.audit import write_audit
from app.deps import get_current_user
from app.models import User

router = APIRouter(prefix="/email", tags=["email"])

_MAX_ATTACH = 15 * 1024 * 1024  # 15 MB


@router.get("/status")
async def email_status(_user: User = Depends(get_current_user)):
    return {"available": mailer.is_available()}


@router.post("/report")
async def email_report(
    file: UploadFile = File(...),
    subject: str = Form("Bid Sentinel report"),
    user: User = Depends(get_current_user),
):
    """Email an uploaded report to the current user's own address (only)."""
    if not mailer.is_available():
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Email is not configured on the server (set SMTP_HOST).",
        )
    data = await file.read()
    if len(data) > _MAX_ATTACH:
        raise HTTPException(status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, detail="Attachment too large")

    filename = file.filename or "report"
    content_type = file.content_type or "application/octet-stream"
    try:
        await mailer.send_report(
            to=user.email,  # self only — never a client-supplied recipient
            subject=subject[:200],
            body=(
                f"Hi,\n\nYour requested report '{filename}' is attached.\n\n"
                "— Bid Sentinel"
            ),
            filename=filename,
            content=data,
            content_type=content_type,
        )
    except Exception as exc:  # noqa: BLE001
        await write_audit(user.email, "Email report failed", detail=f"{filename}: {exc}"[:512], status_code=502)
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY, detail=f"Could not send email: {exc}"
        )

    await write_audit(user.email, "Emailed report to self", detail=filename, status_code=200)
    return {"sent": True, "to": user.email}