fix: persister le token après chaque opération de données + corriger doc QR code

Cause racine : pronotepy peut rafraîchir (rotater) le token en mémoire pendant
l'exécution via refresh() automatique après une PronoteAPIError. L'ancien code
ne persistait les credentials qu'après le login initial, pas après les
opérations de données. Le token roté en mémoire était perdu → au run suivant,
token_login échouait avec le token périmé (KeyError 'dataSec').

Correction :
- PronoteClient._persist_credentials() : méthode centralisée qui persiste
  export_credentials() après chaque opération réussie (get_lessons,
  get_homeworks, get_messages, get_informations)
- Le token rafraîchi par le serveur pendant l'exécution est maintenant
  toujours persisté, même si le pipeline échoue ensuite

Documentation :
- .env.example : variables QR plus visibles (exemple qr_token décommentable)
- AGENTS.md : QR code depuis le site web Pronote (pas l'app mobile),
  persistance après chaque opération de données
- Wiki GuidePronote : procédure corrigée (site web, pas app Android/iOS),
  mention de la persistance après chaque opération

Tests : 5 nouveaux tests de persistance (691 passés, couverture 94.92%)
This commit is contained in:
2026-09-10 12:10:42 +02:00
parent 7dc48f6f43
commit d26cef8d3d
4 changed files with 240 additions and 14 deletions

View File

@@ -153,10 +153,15 @@ pronote-sync --dry-run
- `qr_token` : authentification par QR code puis token persistant (pour les instances Pronote
utilisant HubEduConnect/EduConnect où l'authentification par mot de passe échoue).
- En mode `qr_token`, le premier login utilise `pronotepy.qrcode_login(qr_code, pin, uuid)` avec
les paramètres `PRONOTE_QR_CODE_FILE` (chemin du JSON QR) et `PRONOTE_QR_PIN` (PIN SecretStr).
les paramètres `PRONOTE_QR_CODE_FILE` (chemin du JSON QR) et `PRONOTE_QR_PIN` (PIN SecretStr). Le
QR code est obtenu depuis le site web Pronote (espace parent → paramètres → QR code), pas depuis
l'application mobile.
- Après chaque login réussi, les credentials exportées par `pronotepy.export_credentials()` sont
persistées dans `.pronote_auth_state.json` (permissions `0600`, format JSON versionné, écriture
atomique). Le token rotate à chaque session — le fichier doit être mis à jour après chaque run.
atomique). Le token rotate à chaque session et peut également être rafraîchi pendant l'exécution
(refresh automatique pronotepy après une `PronoteAPIError`). Les credentials sont persistées après
chaque login réussi **et après chaque opération de données réussie** (agenda, devoirs, messages,
informations) pour garantir la persistance du token valide.
- Les logins suivants utilisent `pronotepy.token_login(**credentials)` avec le token persisté.
- En cas d'échec de `token_login` (token expiré/invalide), une `PronoteAuthRotationError` est levée.
Cette erreur se propage sans wrapping à travers `PronoteFetcher` et `fetch_step` jusqu'à