from fastapi import APIRouter, Depends, HTTPException, Request, Security from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from psycopg import AsyncConnection from mm_api.db import get_conn from mm_api.dependencies import current_user from mm_api.models.auth import RegisterRequest, LoginRequest, RefreshRequest import mm_api.services.auth as svc router = APIRouter(prefix="/auth", tags=["auth"]) bearer = HTTPBearer(auto_error=False) @router.post("/register", status_code=201) async def register(data: RegisterRequest, conn: AsyncConnection = Depends(get_conn)): try: return await svc.register(conn, data) except ValueError as e: raise HTTPException(400, str(e)) @router.post("/login") async def login(data: LoginRequest, request: Request, conn: AsyncConnection = Depends(get_conn)): ip = request.client.host if request.client else "unknown" user_agent = request.headers.get("user-agent", "") try: return await svc.login(conn, data, ip, user_agent) except ValueError as e: raise HTTPException(401, str(e)) @router.post("/refresh") async def refresh(data: RefreshRequest, request: Request, conn: AsyncConnection = Depends(get_conn)): ip = request.client.host if request.client else "unknown" try: return await svc.refresh(conn, data.refresh_token, ip) except ValueError as e: raise HTTPException(401, str(e)) @router.post("/logout") async def logout( credentials: HTTPAuthorizationCredentials = Security(bearer), conn: AsyncConnection = Depends(get_conn), ): if credentials: await svc.logout(conn, credentials.credentials) return {"ok": True} @router.post("/logout-all") async def logout_all( user: dict = Depends(current_user), conn: AsyncConnection = Depends(get_conn), ): await svc.logout_all(conn, user["id"]) return {"ok": True} @router.get("/me") async def me(user: dict = Depends(current_user)): return user @router.get("/sessions") async def list_sessions( user: dict = Depends(current_user), conn: AsyncConnection = Depends(get_conn), ): return await svc.list_sessions(conn, user["id"]) @router.delete("/sessions/{device_id}") async def close_session( device_id: int, user: dict = Depends(current_user), conn: AsyncConnection = Depends(get_conn), ): try: await svc.logout_device(conn, user["id"], device_id) except ValueError as e: raise HTTPException(404, str(e)) return {"ok": True}