Files
sasa-membership/backend/app/api/v1/auth.py
James Pattinson 3751ee0076 First commit
2025-11-10 13:57:46 +00:00

129 lines
3.7 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from datetime import datetime, timedelta
from typing import List
from ...core.database import get_db
from ...core.security import verify_password, get_password_hash, create_access_token
from ...models.models import User, UserRole
from ...schemas import (
UserCreate, UserResponse, Token, LoginRequest, MessageResponse
)
from ...services.email_service import email_service
router = APIRouter()
@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def register(
user_data: UserCreate,
db: Session = Depends(get_db)
):
"""Register a new user"""
# Check if user already exists
existing_user = db.query(User).filter(User.email == user_data.email).first()
if existing_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email already registered"
)
# Create new user
hashed_password = get_password_hash(user_data.password)
db_user = User(
email=user_data.email,
hashed_password=hashed_password,
first_name=user_data.first_name,
last_name=user_data.last_name,
phone=user_data.phone,
address=user_data.address,
role=UserRole.MEMBER
)
db.add(db_user)
db.commit()
db.refresh(db_user)
# Send welcome email (non-blocking, ignore errors)
try:
await email_service.send_welcome_email(
to_email=db_user.email,
first_name=db_user.first_name
)
except Exception as e:
# Log error but don't fail registration
print(f"Failed to send welcome email: {e}")
return db_user
@router.post("/login", response_model=Token)
async def login(
form_data: OAuth2PasswordRequestForm = Depends(),
db: Session = Depends(get_db)
):
"""Login with email and password"""
# Find user
user = db.query(User).filter(User.email == form_data.username).first()
if not user or not verify_password(form_data.password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Bearer"},
)
if not user.is_active:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Inactive user account"
)
# Update last login
user.last_login = datetime.utcnow()
db.commit()
# Create access token
access_token = create_access_token(subject=user.id)
return {
"access_token": access_token,
"token_type": "bearer"
}
@router.post("/login-json", response_model=Token)
async def login_json(
login_data: LoginRequest,
db: Session = Depends(get_db)
):
"""Login with JSON body (email and password)"""
# Find user
user = db.query(User).filter(User.email == login_data.email).first()
if not user or not verify_password(login_data.password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Bearer"},
)
if not user.is_active:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Inactive user account"
)
# Update last login
user.last_login = datetime.utcnow()
db.commit()
# Create access token
access_token = create_access_token(subject=user.id)
return {
"access_token": access_token,
"token_type": "bearer"
}