munch-ease-backend/api/auth_v2.py

62 lines
2.1 KiB
Python

from __future__ import annotations
import hashlib
from typing import Optional
import aiosqlite
from fastapi import APIRouter, Depends, Request
from api.deps import error_response, get_db
from common import ApiModel
from users import repository as users_db
from users.models import User
router = APIRouter(prefix="/auth", tags=["auth-v2"])
class RegisterBody(ApiModel):
email: str
password: str
display_name: str
class LoginBody(ApiModel):
email: str
password: str
class TokenResponse(ApiModel):
access_token: str
token_type: str = "bearer"
user: User
def _hash_pw(pw: str) -> str:
# Placeholder; replace with proper hashing (bcrypt/argon2) later
return hashlib.sha256(pw.encode("utf-8")).hexdigest()
@router.post("/register", response_model=TokenResponse, operation_id="register")
async def register(request: Request, body: RegisterBody, conn: aiosqlite.Connection = Depends(get_db)):
existing = await users_db.get_by_email(conn, body.email)
if existing:
return error_response(request, 400, "Email already registered")
uid = await users_db.insert_user(conn, body.email, body.display_name)
await users_db.set_local_credentials(conn, uid, _hash_pw(body.password))
user = await users_db.get_by_email(conn, body.email)
assert user is not None
# Token is a simple placeholder containing user id; will be replaced with JWT
token = f"user-{user.id}"
return TokenResponse(access_token=token, user=user)
@router.post("/login", response_model=TokenResponse, operation_id="loginV2")
async def login(request: Request, body: LoginBody, conn: aiosqlite.Connection = Depends(get_db)):
user: Optional[User] = await users_db.get_by_email(conn, body.email)
if not user:
return error_response(request, 401, "Invalid credentials")
stored = await users_db.get_local_password_hash(conn, user.id)
if not stored or stored != _hash_pw(body.password):
return error_response(request, 401, "Invalid credentials")
token = f"user-{user.id}"
return TokenResponse(access_token=token, user=user)