PawTrace / backend /app /api /auth.py
Elliott Duke
HomingPet: lost-dog reunification (FastAPI + React) with Render deploy
de1e3fc
Raw
History Blame Contribute Delete
2.09 kB
from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.orm import Session
from ..db import get_db
from ..models import User
from ..models.base import UserRole
from ..schemas.auth import (
LoginRequest,
RegisterRequest,
TokenResponse,
UserOut,
)
from ..schemas.common import Message
from ..security import (
create_access_token,
get_current_user,
hash_password,
verify_password,
)
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/register", response_model=TokenResponse, status_code=status.HTTP_201_CREATED)
def register(payload: RegisterRequest, db: Session = Depends(get_db)) -> TokenResponse:
existing = db.execute(select(User).where(User.email == payload.email)).scalar_one_or_none()
if existing:
raise HTTPException(status.HTTP_409_CONFLICT, "Email already registered")
user = User(
name=payload.name,
email=payload.email,
phone=payload.phone,
zip=payload.zip,
password_hash=hash_password(payload.password),
role=UserRole.owner,
)
db.add(user)
db.commit()
db.refresh(user)
return TokenResponse(access_token=create_access_token(user.id))
@router.post("/login", response_model=TokenResponse)
def login(payload: LoginRequest, db: Session = Depends(get_db)) -> TokenResponse:
user = db.execute(select(User).where(User.email == payload.email)).scalar_one_or_none()
if not user or not user.password_hash or not verify_password(payload.password, user.password_hash):
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Invalid email or password")
return TokenResponse(access_token=create_access_token(user.id))
@router.post("/logout", response_model=Message)
def logout() -> Message:
# Stateless JWT: client simply discards the token. Endpoint exists for symmetry (spec §12).
return Message(detail="Logged out")
@router.get("/me", response_model=UserOut)
def me(user: User = Depends(get_current_user)) -> User:
return user