feat: frontend JWT handling, rate limiting [H-02], CORS config

Frontend:
- Creiez frontend/lib/auth.ts cu saveToken, getToken, getAuthHeader, clearAuth
- Modific api.ts: axiosInstance cu interceptor Bearer token + 401 → /login redirect
- Modific login page: salveaza JWT token din response

Backend:
- [H-02] Integrez slowapi rate limiting: 10 req/minute pe /items/extract-label
- [M-01] CORS: ALLOWED_ORIGINS din env (dev fallback: localhost:3000, localhost:3002)
- [C-01] JWT_SECRET_KEY din env (dev fallback: ephemeral key)

docker-compose.yml:
- Adaug ALLOWED_ORIGINS env var (dev: localhost)
- Adaug JWT_SECRET_KEY env var cu fallback warning

Status:
-  JWT backend: complet
-  JWT frontend: token save + attach + 401 handling
-  Rate limiting: 10/min pe extract-label
-  CORS: configurable via env

Gata pentru dev + testing local.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Bedeleanu
2026-04-11 13:42:09 +03:00
parent e9ada00497
commit e6ca33f2f0
6 changed files with 181 additions and 55 deletions

View File

@@ -1,10 +1,15 @@
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Request
from sqlalchemy.orm import Session
from sqlalchemy import func
from typing import List
from slowapi import Limiter
from slowapi.util import get_remote_address
from .. import models, schemas, auth
from ..database import get_db
# [H-02] Rate limiter pentru extract-label endpoint
limiter = Limiter(key_func=get_remote_address)
router = APIRouter(
prefix="/items",
tags=["Items"]
@@ -55,12 +60,13 @@ def read_item(
_ALLOWED_IMAGE_TYPES = {"image/jpeg", "image/png", "image/webp", "image/gif"}
_MAX_IMAGE_SIZE = 10 * 1024 * 1024 # 10 MB
@limiter.limit("10/minute")
@router.post("/extract-label")
async def extract_label(
file: UploadFile = File(...),
current_user: auth.TokenData = Depends(auth.get_current_user)
):
"""[C-01] Extragere etichetă din imagine — doar utilizatori autentificati. [H-02] Rate limit pe endpoint."""
"""[C-01] Extragere etichetă din imagine — doar utilizatori autentificati. [H-02] Rate limit: 10 req/min per IP."""
from ..ai_vision import extract_label_info
# [SECURITY FIX H-03] Validare tip MIME și dimensiune maximă