# API Auth JWT — Documentation ## Sprint 2-3 (HRT-28) Base URL: `http://localhost:8792` --- ## Endpoints d'authentification ### `POST /api/v1/auth/register` Inscription d'un nouvel utilisateur (plan free par défaut). **Body JSON:** ```json { "email": "user@example.com", "password": "motdepasse123" } ``` **Réponse 201:** ```json { "message": "Compte créé avec succès", "user_id": 1 } ``` **Erreurs:** `400` (email invalide / mot de passe < 8 car.), `409` (email déjà utilisé) --- ### `POST /api/v1/auth/login` Connexion — retourne access_token (15min) + refresh_token (30j). **Body JSON:** ```json { "email": "user@example.com", "password": "motdepasse123" } ``` **Réponse 200:** ```json { "access_token": "", "refresh_token": "", "token_type": "Bearer", "plan": "free" } ``` --- ### `POST /api/v1/auth/refresh` Rotation du refresh token — invalide l'ancien, émet un nouveau. **Body JSON:** ```json { "refresh_token": "" } ``` **Réponse 200:** identique à `/login` --- ### `POST /api/v1/auth/logout` Révocation du refresh token. **Body JSON:** ```json { "refresh_token": "" } ``` **Réponse 200:** ```json { "message": "Déconnexion réussie" } ``` --- ## Routes protégées Toutes les routes protégées nécessitent le header: ``` Authorization: Bearer ``` ### `GET /api/v1/predictions` | Plan | Accès | |---------|---------------------------------------------| | free | Top 3 uniquement, 1 course/jour | | premium | Toutes les courses + alertes Telegram | | pro | API complète + lien export CSV | ### `GET /api/v1/predictions/export` Export CSV — **plan pro uniquement** (`403` pour free/premium). ### `GET /api/v1/subscription/upgrade` Infos sur les plans disponibles et plan courant de l'utilisateur. ### `GET /api/v1/health` Vérification d'état du service (pas d'auth requise). --- ## Sécurité - **Passwords:** hashés avec bcrypt (saltRounds=12) - **JWT access:** expiration 15 minutes (HS256) - **JWT refresh:** expiration 30 jours, stocké hashé (SHA-256) en DB, rotation à chaque usage - **Rate limiting:** 100 requêtes/min par IP — header `X-RateLimit-Remaining` - **CORS:** configuré pour `https://turf-ia.h3r7.tech` + localhost dev - **Logs d'accès:** horodatés ISO 8601 dans `logs/saas_api.log` --- ## Lancement ```bash JWT_SECRET_KEY="votre_cle_secrete" \ CORS_ORIGINS="https://turf-ia.h3r7.tech" \ ./venv/bin/python saas_api.py ``` --- ## Tests ```bash ./venv/bin/pytest tests/test_auth.py -v # Avec couverture: ./venv/bin/pytest tests/test_auth.py --cov=auth --cov=auth_db --cov=middleware --cov=saas_api --cov-report=term-missing # Résultat: 27 tests OK, couverture globale 83% ``` --- ## Structure des tables DB ```sql -- users: id, email, password_hash, plan(free/premium/pro), created_at, is_active, daily_usage, last_usage_date -- subscriptions: id, user_id, plan, start_date, end_date, stripe_customer_id -- refresh_tokens: id, user_id, token_hash, created_at, expires_at, revoked ```