fix landing page

This commit is contained in:
Stefano Manfredi
2025-12-02 23:18:43 +00:00
parent 7168fa4b72
commit ce9e2fdf2a
17 changed files with 727 additions and 457 deletions

View File

@@ -2,20 +2,23 @@
Authentication Routes
Login, register, logout, and user info
"""
from fastapi import APIRouter, Depends, HTTPException, status, Response
from fastapi import APIRouter, Depends, HTTPException, status, Response, Request
from pydantic import BaseModel, EmailStr
from sqlalchemy.orm import Session
from slowapi import Limiter
from slowapi.util import get_remote_address
from database.connection import get_db
from services.auth import (
create_user, authenticate_user, create_access_token,
get_user_by_email, hash_password, verify_password
get_user_by_email
)
from utils.auth_middleware import get_current_user
from utils.helpers import validate_password, format_password_errors, get_notification_default
from app import config
import re
router = APIRouter(prefix="/api/auth", tags=["auth"])
limiter = Limiter(key_func=get_remote_address)
class RegisterRequest(BaseModel):
@@ -52,7 +55,8 @@ class UserResponse(BaseModel):
@router.post("/register", response_model=TokenResponse)
def register(data: RegisterRequest, db: Session = Depends(get_db)):
@limiter.limit(f"{config.RATE_LIMIT_REQUESTS}/minute")
def register(request: Request, data: RegisterRequest, db: Session = Depends(get_db)):
"""Register a new user"""
if get_user_by_email(db, data.email):
raise HTTPException(
@@ -60,10 +64,12 @@ def register(data: RegisterRequest, db: Session = Depends(get_db)):
detail="Email already registered"
)
if len(data.password) < 8:
# Validate password strength
password_errors = validate_password(data.password)
if password_errors:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Password must be at least 8 characters"
detail=format_password_errors(password_errors)
)
user = create_user(
@@ -74,16 +80,19 @@ def register(data: RegisterRequest, db: Session = Depends(get_db)):
manager_id=data.manager_id
)
config.logger.info(f"New user registered: {data.email}")
token = create_access_token(user.id, user.email)
return TokenResponse(access_token=token)
@router.post("/login", response_model=TokenResponse)
def login(data: LoginRequest, response: Response, db: Session = Depends(get_db)):
@limiter.limit(f"{config.RATE_LIMIT_REQUESTS}/minute")
def login(request: Request, data: LoginRequest, response: Response, db: Session = Depends(get_db)):
"""Login with email and password"""
user = authenticate_user(db, data.email, data.password)
if not user:
config.logger.warning(f"Failed login attempt for: {data.email}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials"
@@ -99,6 +108,7 @@ def login(data: LoginRequest, response: Response, db: Session = Depends(get_db))
samesite="lax"
)
config.logger.info(f"User logged in: {data.email}")
return TokenResponse(access_token=token)
@@ -119,15 +129,27 @@ def get_me(user=Depends(get_current_user)):
manager_id=user.manager_id,
role=user.role,
manager_parking_quota=user.manager_parking_quota,
week_start_day=user.week_start_day or 0,
notify_weekly_parking=user.notify_weekly_parking if user.notify_weekly_parking is not None else 1,
notify_daily_parking=user.notify_daily_parking if user.notify_daily_parking is not None else 1,
notify_daily_parking_hour=user.notify_daily_parking_hour if user.notify_daily_parking_hour is not None else 8,
notify_daily_parking_minute=user.notify_daily_parking_minute if user.notify_daily_parking_minute is not None else 0,
notify_parking_changes=user.notify_parking_changes if user.notify_parking_changes is not None else 1
week_start_day=get_notification_default(user.week_start_day, 0),
notify_weekly_parking=get_notification_default(user.notify_weekly_parking, 1),
notify_daily_parking=get_notification_default(user.notify_daily_parking, 1),
notify_daily_parking_hour=get_notification_default(user.notify_daily_parking_hour, 8),
notify_daily_parking_minute=get_notification_default(user.notify_daily_parking_minute, 0),
notify_parking_changes=get_notification_default(user.notify_parking_changes, 1)
)
@router.get("/config")
def get_auth_config():
"""Get authentication configuration for frontend.
Returns info about auth mode and external URLs.
"""
return {
"authelia_enabled": config.AUTHELIA_ENABLED,
"login_url": config.AUTHELIA_LOGIN_URL if config.AUTHELIA_ENABLED else None,
"registration_url": config.REGISTRATION_URL if config.AUTHELIA_ENABLED else None
}
@router.get("/holidays/{year}")
def get_holidays(year: int):
"""Get public holidays for a given year"""