from fastapi import APIRouter, Depends, HTTPException, status, Response from sqlalchemy.orm import Session from app.core.database import get_db from app.core.security import get_password_hash, verify_password, create_access_token, validate_password_strength from app.models.user import User from app.schemas.user import UserCreate, UserResponse, UserLogin from app.api.deps import get_current_user from datetime import timedelta from app.core.config import settings router = APIRouter() @router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED) def register(user_in: UserCreate, db: Session = Depends(get_db)): # Verify password strength if not validate_password_strength(user_in.password): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Mật khẩu phải dài tối thiểu 8 ký tự." ) # Check if email exists user = db.query(User).filter(User.email == user_in.email).first() if user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Email đã được sử dụng." ) hashed_password = get_password_hash(user_in.password) new_user = User(email=user_in.email, password_hash=hashed_password) db.add(new_user) db.commit() db.refresh(new_user) return new_user @router.post("/login") def login(response: Response, user_in: UserLogin, db: Session = Depends(get_db)): user = db.query(User).filter(User.email == user_in.email).first() if not user or not verify_password(user_in.password, user.password_hash): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Email hoặc mật khẩu không chính xác." ) # Generate token token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token(user.id, expires_delta=token_expires) # Store token in cookie # secure=False because we're on HTTP (dev); samesite=none requires HTTPS # For cross-origin (FE port 4173 → BE port 8002), we also return token in body response.set_cookie( key="access_token", value=access_token, httponly=True, secure=False, samesite="lax", max_age=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60, path="/" ) return { "status": "success", "message": "Đăng nhập thành công", "access_token": access_token, "token_type": "bearer" } @router.post("/logout") def logout(response: Response, current_user: User = Depends(get_current_user)): response.delete_cookie(key="access_token", path="/") return {"status": "success", "message": "Đăng xuất thành công"} @router.get("/me", response_model=UserResponse) def get_me(current_user: User = Depends(get_current_user)): return current_user