"""BAN YARO — Auth Routes""" from fastapi import APIRouter, HTTPException, Response, Depends from pydantic import BaseModel, EmailStr from database import db from auth import ( hash_password, verify_password, create_token, get_current_user ) router = APIRouter() COOKIE_NAME = "by_token" class LoginRequest(BaseModel): email: EmailStr password: str class RegisterRequest(BaseModel): email: EmailStr password: str name: str def _set_cookie(response: Response, token: str): response.set_cookie( key=COOKIE_NAME, value=token, httponly=True, secure=True, samesite="lax", max_age=30 * 24 * 3600 ) @router.post("/register") async def register(data: RegisterRequest, response: Response): name = data.name.strip() if len(name) < 2: raise HTTPException(400, "Name muss mindestens 2 Zeichen lang sein.") if len(name) > 40: raise HTTPException(400, "Name darf maximal 40 Zeichen lang sein.") with db() as conn: if conn.execute("SELECT 1 FROM users WHERE email=?", (data.email,)).fetchone(): raise HTTPException(400, "E-Mail bereits registriert.") if conn.execute( "SELECT 1 FROM users WHERE name=? COLLATE NOCASE", (name,) ).fetchone(): raise HTTPException(400, "Dieser Name ist bereits vergeben. Bitte wähle einen anderen.") try: conn.execute( "INSERT INTO users (email, pw_hash, name) VALUES (?,?,?)", (data.email, hash_password(data.password), name) ) except Exception: # Fallback falls UNIQUE-Index greift (Race Condition) raise HTTPException(400, "Dieser Name ist bereits vergeben. Bitte wähle einen anderen.") user = conn.execute( "SELECT id, rolle FROM users WHERE email=?", (data.email,) ).fetchone() token = create_token(user["id"], user["rolle"]) _set_cookie(response, token) return {"token": token, "name": name} @router.post("/login") async def login(data: LoginRequest, response: Response): with db() as conn: user = conn.execute( "SELECT id, pw_hash, name, rolle, is_premium FROM users WHERE email=?", (data.email,) ).fetchone() if not user or not verify_password(data.password, user["pw_hash"]): raise HTTPException(401, "E-Mail oder Passwort falsch.") token = create_token(user["id"], user["rolle"]) _set_cookie(response, token) with db() as conn: conn.execute( "UPDATE users SET last_login=datetime('now') WHERE id=?", (user["id"],) ) return {"token": token, "name": user["name"], "is_premium": bool(user["is_premium"])} @router.post("/logout") async def logout(response: Response): response.delete_cookie(COOKIE_NAME) return {"ok": True} @router.get("/me") async def me(user=Depends(get_current_user)): with db() as conn: row = conn.execute( """SELECT id, name, email, rolle, is_premium, email_verified, bio, wohnort, erfahrung, social_link, profil_sichtbarkeit, avatar_url, created_at FROM users WHERE id=?""", (user["id"],) ).fetchone() if not row: raise HTTPException(404, "User nicht gefunden.") data = dict(row) data["is_premium"] = bool(data["is_premium"]) return data