Repository navigation
feat(auth): coordinateur d'auth persisté pour tous les services - #900
Merged
Merged
Conversation
Ajoute un 3e paramètre optionnel hooks à loginToken (onCredentialSent, onAuthenticationSent, onTokenIssued), appelé entre les requêtes. onTokenIssued livre le nouveau jeton avant ParametresUtilisateur, qui pouvait échouer et le perdre. Même changement que BlocksHub/Pawnote-LTS#4, à retirer dès sa release.
runAuthRefresh enveloppe le login d'un service : il déduplique les appels, pose un bail persisté de 15 s rafraîchi pendant le login, écrit chaque étape (starting, credential_sent, awaiting_new_credential, credential_received, ready, failed) et classe l'échec. L'état vit dans un MMKV chiffré (clé statique), avec une empreinte courte des identifiants, jamais les identifiants eux-mêmes. Les règles de réessai sont des fonctions pures (policy.ts) : backoff réseau de 30 s à 15 min, 30 min après une suspension d'IP, un seul essai pour un jeton refusé. Elles ne valent que pour le lancement en cours.
Le login sauve le nouveau jeton dès onTokenIssued, avant ParametresUtilisateur. Le classement des erreurs pawnote vit dans services/pronote/errors.ts : un message de maintenance (AuthenticateError) devient service_error et le jeton est gardé. Les 17 méthodes passent par withSession : une session expirée est renouvelée puis la requête rejouée une fois, une suspension d'IP bloque toute requête. isTokenValid exige aussi l'état ready : une session expirée, en échec ou remise à zéro n'est plus réutilisée. La déduplication du plugin disparaît, le coordinateur s'en charge.
EcoleDirecte, Skolengo, Multi, AppScho, Izly, TurboSelf, Alise et ARD lisent leurs identifiants dans le store et laissent le coordinateur écrire le nouveau jeton. - Skolengo sépare OIDCRefresh et GetUserInfo : le refresh token tourné est sauvé avant que GetUserInfo puisse échouer. - EcoleDirecte part du jeton du store, pas de la copie de l'appelant. - Skolengo et Multi lèvent CredentialsMissingError sans refresh token, au lieu d'envoyer une requête avec undefined. - ARD réessaie dans une boucle : un appel récursif rejoindrait sa propre promesse.
- L'erreur affichée porte la raison persistée (credential_lost, account_disabled…), qui sait qu'une rotation a été coupée. - Une maintenance PRONOTE ou une session expirée ne déconnectent plus : seules les raisons qui demandent une action de l'utilisateur lèvent AuthenticationError. - initializeAccountManager accepte force, qui lève un backoff ou un blocage. Un appel forcé pendant une synchro en cours attend sa fin puis relance, au lieu de la rejoindre. - Les états des services supprimés sont retirés.
L'alerte de déconnexion explique ce qui s'est passé : jeton perdu pendant un renouvellement, compte désactivé, vérification de sécurité ou session expirée. Une suspension d'IP a son propre message, et l'indisponibilité nomme le bon service au lieu de toujours dire PRONOTE. Le tirer-pour-rafraîchir passe force, qui lève un backoff en cours. Textes ajoutés en français et en anglais.
Section « État d'auth » : étape, dernière erreur, prochain essai et jeton peut-être consommé. Toucher une ligne efface l'état et relance une connexion forcée. Les lignes de détail ont leur propre composant, pour que leur horloge ne rafraîchisse pas tout l'écran.
PRONOTE lève une suspension d'IP en quelques minutes, pas en 30. La pause passe à 5 minutes, et le message invite à réessayer quelques minutes plus tard en tirant la page vers le bas.
- timeout de 60 s sur le fetcher PRONOTE : une requête sans réponse ne gèle plus la file de la session ni le bail - le bail n'est plus renouvelé après 2 min de login - UnreachableError (bug de décodage) n'est plus classée comme erreur réseau - commentaire du store d'auth corrigé sur la portée du chiffrement
Un seul runtime JS tourne à la fois : un réveil en arrière-plan par PapillonKit et l'ouverture de l'app partagent le même process, la déduplication en mémoire suffit. Le bail faisait attendre jusqu'à 15 s au lancement suivant quand iOS tuait un réveil en plein login.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Règles de contribution
Caution
Afin de garantir une application stable et pérenne dans le temps, nous t'invitons à vérifier que tu as bien respecté les règles de contribution. Sans cela, ta Pull Request ne pourra pas être examinée.
Résumé des changements
Note
Chaque renouvellement de session passe par un coordinateur qui écrit son étape sur disque : jeton envoyé, en attente du nouveau, reçu, prêt ou en échec. Le nouveau jeton est sauvé dès que le serveur le donne. Une coupure au mauvais moment ne déconnecte plus. Remplace #892.
ParametresUtilisateuréchoue aprèsAuthentification(PRONOTE)onTokenIssued, le login suivant passeGetUserInfoéchoue (Skolengo)GetUserInfocredential_lostet un message dédiéCe qui change
services/auth/:runAuthRefreshdéduplique, pose le bail, écrit chaque étape et classe l'échec. Les règles de réessai sont des fonctions pures (policy.ts).stores/authState/: MMKV chiffré (clé statique). Seule une empreinte courte des identifiants est stockée.hookssurloginToken, même changement que feat(login): add progress hooks to loginToken BlocksHub/Pawnote-LTS#4. À retirer à sa release.withSession.Tests
tsc: aucune nouvelle erreur, 18 en moins.ready. Relance de l'app → nouveau login avec le jeton sauvé,ready. Fichierauth-state-storagevérifié chiffré (aucun texte en clair, même format queaccount-storage).AuthentificationetParametresUtilisateur.