diff --git a/backend/app/__init__.py b/backend/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/api/__init__.py b/backend/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/api/api_v1/__init__.py b/backend/app/api/api_v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/api/api_v1/endpoints/__init__.py b/backend/app/api/api_v1/endpoints/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/api/api_v1/endpoints/imap.py b/backend/app/api/api_v1/endpoints/imap.py index 94940d9..b66328a 100644 --- a/backend/app/api/api_v1/endpoints/imap.py +++ b/backend/app/api/api_v1/endpoints/imap.py @@ -1,39 +1,43 @@ import logging from datetime import datetime -from typing import Any, Dict +from typing import Any, Dict, Optional from app.core.security import require_admin_auth from app.services.imap_client import IMAPClient from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException +from pydantic import BaseModel router = APIRouter() logger = logging.getLogger(__name__) +class IMAPTestRequest(BaseModel): + """IMAP connection test request body""" + + server: Optional[str] = None + port: int = 993 + username: Optional[str] = None + password: Optional[str] = None + ssl: bool = True + + @router.post("/test-connection") async def test_imap_connection( - auth: dict = Depends(require_admin_auth), - server: str = None, - port: int = 993, - username: str = None, - password: str = None, - ssl: bool = True, + request: IMAPTestRequest, + _auth: dict = Depends(require_admin_auth), ) -> Dict[str, Any]: """ Test connection to an IMAP server and gather mailbox statistics Security: Requires authentication (X-API-Key or Bearer token) - Note: Credentials should be passed in request body, not query params + Credentials should be passed in request body """ - # Security: Don't accept credentials in query parameters (they get logged) - if any([server, username, password]): - logger.warning("IMAP credentials passed as query parameters - this is insecure") - raise HTTPException( - status_code=400, - detail="Credentials should be passed in request body, not query parameters", - ) - - imap_client = IMAPClient(server=server, port=port, username=username, password=password) + imap_client = IMAPClient( + server=request.server, + port=request.port, + username=request.username, + password=request.password, + ) success, message, stats = imap_client.test_connection() @@ -51,7 +55,7 @@ async def test_imap_connection( @router.post("/fetch-reports") async def fetch_imap_reports( background_tasks: BackgroundTasks, - auth: dict = Depends(require_admin_auth), + _auth: dict = Depends(require_admin_auth), days: int = 7, delete_emails: bool = False, ) -> Dict[str, Any]: @@ -88,14 +92,14 @@ async def fetch_imap_reports( "timestamp": datetime.now().isoformat(), } except Exception as e: - logger.error(f"Error fetching IMAP reports: {str(e)}") + logger.error("Error fetching IMAP reports: %s", str(e)) raise HTTPException( status_code=500, detail="Failed to fetch reports. Check server logs for details." - ) + ) from e @router.get("/status") -async def get_imap_status(auth: dict = Depends(require_admin_auth)) -> Dict[str, Any]: +async def get_imap_status(_auth: dict = Depends(require_admin_auth)) -> Dict[str, Any]: """ Get the current status of IMAP polling background processes diff --git a/backend/app/api/api_v1/endpoints/setup.py b/backend/app/api/api_v1/endpoints/setup.py index 7a04f85..ca2dca1 100644 --- a/backend/app/api/api_v1/endpoints/setup.py +++ b/backend/app/api/api_v1/endpoints/setup.py @@ -1,4 +1,3 @@ - from fastapi import APIRouter, HTTPException, status from pydantic import BaseModel, EmailStr @@ -38,7 +37,8 @@ class SystemConfigRequest(BaseModel): async def get_setup_status(): """Get the current setup status""" return SetupStatusResponse( - is_setup_complete=setup_status["is_setup_complete"], app_name=setup_status["app_name"] + is_setup_complete=setup_status["is_setup_complete"], + app_name=setup_status["app_name"], ) diff --git a/backend/app/core/__init__.py b/backend/app/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/models/user.py b/backend/app/models/user.py index e5d0d33..1370a83 100644 --- a/backend/app/models/user.py +++ b/backend/app/models/user.py @@ -1,8 +1,8 @@ - -from app.core.database import Base from sqlalchemy import Boolean, Column, Integer, String from sqlalchemy.orm import relationship +from app.core.database import Base + class User(Base): """User model""" diff --git a/backend/app/services/__init__.py b/backend/app/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/tests/__init__.py b/backend/app/tests/__init__.py new file mode 100644 index 0000000..e69de29