from fastapi import APIRouter, Depends, HTTPException, Request, Response, status from sqlalchemy.orm import Session from app.core.config import settings from app.core.deps import get_current_user from app.core.security import create_access_token, hash_password, verify_password from app.db.session import get_db from app.models import User from app.schemas import LoginRequest, RegisterRequest, UserResponse router = APIRouter(prefix="/api/auth", tags=["auth"]) @router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED) def register(payload: RegisterRequest, db: Session = Depends(get_db)): existing = db.query(User).filter(User.email == payload.email).first() if existing: raise HTTPException(status_code=400, detail="Email already registered") user = User(email=payload.email, password_hash=hash_password(payload.password)) db.add(user) db.commit() db.refresh(user) return user def _is_secure_request(request: Request) -> bool: forwarded_proto = request.headers.get("x-forwarded-proto", "") if "https" in forwarded_proto.lower(): return True if request.url.scheme == "https": return True return settings.BACKEND_BASE_URL.startswith("https://") @router.post("/login") def login(payload: LoginRequest, request: Request, response: Response, db: Session = Depends(get_db)): user = db.query(User).filter(User.email == payload.email).first() if not user or not verify_password(payload.password, user.password_hash): raise HTTPException(status_code=401, detail="Invalid credentials") token = create_access_token(subject=user.id) response.set_cookie( key="access_token", value=token, httponly=True, samesite="lax", secure=_is_secure_request(request), max_age=60 * 60 * 24 * 7, ) return {"message": "Logged in", "user": UserResponse.model_validate(user)} @router.post("/logout") def logout(response: Response): response.delete_cookie("access_token") return {"message": "Logged out"} @router.get("/me", response_model=UserResponse) def me(current_user: User = Depends(get_current_user)): return current_user