Authentification
Émission et révocation de cookies de session, gestion des identifiants, vérification d'email et endpoints RGPD self-service sous /api/auth.
Authentification
L'API d'authentification émet et révoque les cookies de session, gère les identifiants, vérifie la propriété d'email et expose les endpoints RGPD self-service. Toutes les routes sont montées sous /api/auth et répondent en JSON sauf mention contraire.
Cookie de session
Les appels réussis à signup, login et password/change posent un cookie outsend_session :
| Attribut | Valeur |
|---|---|
| Nom | outsend_session |
| TTL | 7 jours (SESSION_DURATION_DAYS = 7) |
HttpOnly |
true |
Secure |
true (production) |
SameSite |
Lax |
Path |
/ |
Le cookie est un jeton signé lié à une ligne de sessions. Révoquer une session (logout, changement de mot de passe, suppression de compte) supprime la ligne côté serveur même si le cookie est rejoué.
Limites de débit et erreurs
Chaque endpoint applique des fenêtres par IP et par identité (voir Limites). Le dépassement renvoie 429 Too Many Requests avec un message en français contenant le délai de retry en secondes.
Toutes les erreurs suivent la forme FastAPI { "detail": "<message>" }. Codes génériques : 400 (payload invalide, jeton expiré, mauvais mot de passe actuel, échec captcha), 401 (identifiants erronés ou session manquante sur routes protégées), 429 (limite de débit). Les detail spécifiques sont listés en ligne ci-dessous.
POST /api/auth/signup
Crée un utilisateur, envoie l'email de bienvenue + vérification, et ouvre une session. Sans auth. Limite : 3 / heure / IP.
Corps de requête
| Champ | Type | Notes |
|---|---|---|
email |
string (email) | Requis. |
password |
string | 8 à 128 caractères, doit contenir une lettre ET un chiffre/symbole. |
invitation_code |
string | 1 à 64 caractères. L'alpha est sur invitation. |
accept_responsibility |
boolean | Doit valoir true. |
hcaptcha_token |
string ou null | Requis quand HCAPTCHA_SECRET est configuré. |
{
"email": "ada@example.com",
"password": "lovelace-1843",
"invitation_code": "ALPHA-7K2",
"accept_responsibility": true,
"hcaptcha_token": "10000000-aaaa-bbbb-cccc-000000000001"
}
Réponse — 200 OK
{
"ok": true,
"user": {
"id": 42,
"email": "ada@example.com",
"is_admin": false,
"is_active": true,
"email_verified": false,
"created_at": "2026-05-27T09:14:00Z"
}
}
Pose le cookie outsend_session.
Erreurs spécifiques
| Code | Detail |
|---|---|
400 |
Captcha invalide. Réessaie. |
400 |
Code invitation invalide |
400 |
Email existe déjà |
POST /api/auth/login
Valide les identifiants et ouvre une session. Sans auth. Limite : 5 / 15 min / IP et 5 / 15 min / email.
Corps de requête
| Champ | Type | Notes |
|---|---|---|
email |
string (email) | Requis. |
password |
string | 1 à 128 caractères. |
{ "email": "ada@example.com", "password": "lovelace-1843" }
Réponse — 200 OK
{ "ok": true, "user": { "id": 42, "email": "ada@example.com", "is_admin": false, "is_active": true, "email_verified": true, "created_at": "2026-05-27T09:14:00Z" } }
Pose le cookie outsend_session.
Erreurs spécifiques
| Code | Detail |
|---|---|
401 |
Email ou mot de passe incorrect |
401 |
Compte désactivé |
POST /api/auth/logout
Révoque la session courante et efface le cookie. Auth optionnelle. Corps vide. Réponse : 200 OK { "ok": true }.
GET /api/auth/me
Renvoie l'utilisateur authentifié.
{
"id": 42,
"email": "ada@example.com",
"is_admin": false,
"is_active": true,
"email_verified": true,
"created_at": "2026-05-27T09:14:00Z"
}
POST /api/auth/password/reset-request
Envoie un lien de réinitialisation à l'email si (et seulement si) il correspond à un utilisateur actif. La réponse est identique dans tous les cas pour prévenir l'énumération de comptes. Sans auth. Limite : 3 / heure / IP et 3 / heure / email (silencieux quand épuisé).
Corps de requête
{ "email": "ada@example.com" }
Réponse — 200 OK
{ "ok": true }
POST /api/auth/password/reset-confirm
Consomme un jeton de réinitialisation à usage unique et fixe le nouveau mot de passe. Révoque toutes les sessions existantes de l'utilisateur. Sans auth (le jeton fait office d'identifiant).
Corps de requête
| Champ | Type | Notes |
|---|---|---|
token |
string | 10 à 256 caractères, livré par email. |
new_password |
string | 8 à 128 caractères, lettre + chiffre/symbole. |
{ "token": "eyJ...", "new_password": "babbage-1822" }
Réponse — 200 OK
{ "ok": true }
Erreurs spécifiques
| Code | Detail |
|---|---|
400 |
Lien invalide ou expiré |
422 |
Complexité de mot de passe refusée par le validateur. |
POST /api/auth/password/change
Renouvelle le mot de passe d'un utilisateur connecté. Requiert le mot de passe actuel, révoque les autres sessions, émet un cookie frais. Limite : 5 / heure / utilisateur.
Corps de requête
| Champ | Type | Notes |
|---|---|---|
current_password |
string | 1 à 200 caractères. |
new_password |
string | 8 à 200 caractères, doit différer de l'actuel. |
{ "current_password": "lovelace-1843", "new_password": "babbage-1822" }
Réponse — 200 OK
{ "ok": true }
Pose un cookie outsend_session rafraîchi.
Erreurs spécifiques
| Code | Detail |
|---|---|
400 |
Mot de passe actuel incorrect |
400 |
Le nouveau mot de passe doit être différent de l'actuel |
POST /api/auth/email/verify
Consomme un jeton de vérification à usage unique et bascule email_verified à true. Sans auth.
Corps de requête
{ "token": "eyJ..." }
Réponse — 200 OK
{ "ok": true }
Erreur spécifique : 400 Lien de vérification invalide ou expiré.
POST /api/auth/email/resend-verify
Renvoie l'email de vérification à l'utilisateur authentifié. Idempotent si l'adresse est déjà vérifiée. Corps vide. Limite : 3 / heure / utilisateur.
Réponse — 200 OK
{ "ok": true }
ou, si déjà vérifié :
{ "ok": true, "already_verified": true }
DELETE /api/auth/me
Supprime définitivement le compte et tous les enregistrements possédés (jobs, pipelines, surveillances, sessions, jetons). Les fichiers de jobs sur disque sont purgés après le delete DB en cascade. Les fils de feedback sont anonymisés plutôt que supprimés.
Corps de requête
| Champ | Type | Notes |
|---|---|---|
confirm_email |
string | Doit égaler l'email de l'utilisateur (insensible à la casse). |
{ "confirm_email": "ada@example.com" }
Réponse — 204 No Content
Corps vide. Efface le cookie outsend_session.
Erreur spécifique : 400 Confirmation email incorrecte.
GET /api/auth/me/export
Endpoint de portabilité RGPD. Diffuse une archive ZIP contenant tous les enregistrements possédés par l'utilisateur.
Réponse — 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="outsend-export-<local>-<YYYY-MM-DD>.zip"
Contenu de l'archive :
| Entrée | Contenu |
|---|---|
account.json |
Métadonnées du compte, sans secrets. |
jobs.json |
Tous les jobs avec métadonnées. |
jobs/<job_id>/* |
Sorties CSV/JSON pour chaque job done. |
pipelines.json |
Définitions de pipelines. |
veille.json |
recurring_scraps + historique des runs. |
manifest.txt |
Résumé lisible. |