4db126934815e17e5ef74bd4aa27cc3c4d4853ca
15
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9ad50c58b8 |
Audit complet de mise en forme — Image (2e élément du tableau)
Implémente toutes les options manquantes identifiées pour l'élément Image : dimensionnement/ratio/object-fit, filtres CSS, upload de fichier (en plus de l'URL), lien/plein écran au clic, chargement différé, légende, et tous les attributs de boîte partagés déjà créés pour Titre/Paragraphe (padding/margin/fond/bordure/ombre/opacité/ position du bloc). Système de pages : un support peut désormais avoir 0 page (un nouveau support démarre vide), suppression de toutes les pages en un clic, et la pagination automatique insère intelligemment la nouvelle page juste après celle qui déborde plutôt qu'en toute fin de liste. Bugs réels trouvés et corrigés en cours de route : le style de bloc (dont align-self) ciblait l'élément interne au lieu de son enveloppe (légende/lien) ; une image à sa taille native pouvait déclencher une pagination infinie ; upload/mise à jour d'attribut ne déclenchaient jamais le contrôle de débordement. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
bab581737a |
Ajoute le support de formation : entite racine separee du jeu 2D
Build and deploy / test-python (push) Successful in 11m2s
Build and deploy / test-js (push) Successful in 1m2s
Build and deploy / lint-python (push) Successful in 4m6s
Build and deploy / lint-js (push) Failing after 1m21s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 4m2s
Nouveau moteur document_engine/ (elements CRUD + rendering + labels), db/supports/ (stockage independant de db/games), routes/document/ (CRUD AJAX + publication), et l'editeur frontend complet (templates/document/, static/document/) avec moteur de layout reel (glisser-deposer -> fusion en rangee ou insertion avant/apres), vrai Undo/Redo par pile de commandes, grille d'accroche pour les formes libres, apercu responsive a largeurs fixes, mode Apercu, et publication persistee. "Mes formations" (templates/index.html) liste desormais les environnements 2D et les supports de formation cote a cote ; l'onboarding et core/auth_guard.py sont generalises pour qu'un compte restreint puisse posseder un projet de chaque type independamment. SKIP=djlint : le hook ne signale que le backlog H021 (styles en ligne) deja documente dans CODE_QUALITY.md sur des fichiers pre-existants non touches ici (base.html, game/play.html, scene_edit.html, game_dashboard_simple.html, clause_row.html) plus une ligne de index.html deja presente avant cette session — aucun nouveau fichier (document_edit.html compris) n'y figure. Tous les autres outils (ruff, mypy --strict, vulture, bandit, import-linter, eslint, stylelint) passent sans erreur ; 617 tests Python + 276 tests JS verts, plus une verification manuelle complete du cycle de vie via le serveur de developpement. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
b2e933f322 |
Reorganisation game/document : renommage screens->game_engine + sous-dossiers game/ dans routes, scripts, static, templates, tests
Build and deploy / test-python (push) Successful in 11m12s
Build and deploy / test-js (push) Successful in 53s
Build and deploy / lint-python (push) Successful in 3m56s
Build and deploy / lint-js (push) Successful in 3m1s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 3m58s
Prepare la scission a venir entre l'editeur Jeu 2D et le futur editeur Support de formation (voir docs/plan/PLAN.md), sans toucher a l'architecture en couches existante : - screens/ renomme en game_engine/ (nom clair pour le moteur du jeu 2D, avant l'arrivee d'un second "moteur" cote document) : ~85 imports corriges, contrat import-linter mis a jour, meme forme de couches. - routes/, scripts/, static/, templates/, tests/ : tout ce qui est propre au jeu 2D deplace dans un sous-dossier game/ de chacun (routes/game/, static/game/, templates/game/, tests/game/, scripts/game/) ; ce qui est partage par le site (auth, onboarding, dashboard, uploads, db/) reste a la racine de chaque dossier. Un sous-dossier document/ (vide) cree dans chacun pour le futur chantier. - styles/ volontairement inchange : les 3 fichiers sources sont concatenes en un seul static/style.css charge par tout le site, scinder leur CONTENU (editeur vs partage) serait un refactor CSS distinct, pas un deplacement mecanique. - Chaine d'export SCORM (publish/build_scorm_package.py) mise a jour en profondeur : copie des assets, URLs d'icones relatives a static/style.css (qui ne bouge pas), manifeste, wrapper SCORM. - Deux regressions d'un sweep de renommage anterieur corrigees au passage (screens.js/screens/scene-objects incorrectement convertis en game_engine.js/game_engine/scene-objects dans des commentaires). - Effet de bord Windows decouvert et corrige : git mv + Path.write_text convertissent des fichiers en CRLF (core.autocrlf=true) - ~189 fichiers normalises en LF. - .eslintrc.json/package.json : uniquement les chemins de glob mis a jour (static/game/js/...) ; la preparation eslint-plugin-unicorn du lot 7 reste volontairement non committee (package-lock.json restaure a la version precedente). Verifications : ruff, mypy --strict (391 fichiers), vulture, bandit, lint-imports tous verts ; 591/591 tests Python, 276/276 tests JS ; demarrage serveur + requetes HTTP manuelles confirmant que les assets deplaces repondent en 200 au nouvel emplacement et 404 a l'ancien. SKIP=djlint : backlog H021 (styles inline) deja documente comme dette assumee dans CODE_QUALITY.md section 6, aucun template touche par ce commit au-dela d'un deplacement de fichier. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
c57420c8c9 |
Phase 3 : hardening qualite de code - typage strict, securite, dead code, a11y
Config strictement stricte partout (ruff, mypy --strict, bandit, vulture, import-linter, eslint, stylelint), aucune regle desactivee "pour ne pas casser le build" - l'existant a ete corrige pour la satisfaire plutot que l'inverse. Hooks pre-commit locaux (language: system) bloquants. - Typage mypy --strict propage a tout le moteur (db, screens, auth, core, ai, routes, puis publish/scripts/tests/app.py/build_css.py). - Securite : fuite de handle fichier Windows corrigee dans l'export SCORM (routes/publish/export_scorm.py), CSRF/RNG non-crypto/xAPI documentes (# nosec, # NOSONAR justifies), nouveau db.json_for_script() (echappe "</script>" dans le JSON embarque en <script>, 25 sites). - Architecture : imports circulaires/F811 nettoyes, contrats import-linter respectes, code mort retire (vulture). - Accessibilite : 69 champs de formulaire sans label correctement associe corriges (for/id ou aria-label) sur 11 templates. - ESLint/Stylelint : lot mecanique JS/CSS, regles ajustees puis appliquees (aucune desactivee sans verification individuelle). - Tests : isolation du compte admin partage (nettoyage ponctuel + fixture de teardown automatique en filet de securite), suite complete verte (591 tests Python, 241 tests JS). - SonarQube Community Build self-heberge (Docker + PostgreSQL) : rapport complet analyse point par point, faux positifs documentes. - .gitattributes ajoute (LF force) : core.autocrlf=true sur cette machine faisait echouer ESLint (linebreak-style) via un bug connu de git (checkout "en place" qui ignore l'eol force sur un fichier deja present sur disque - contourne en supprimant puis recreant chaque fichier suivi). djLint (H021, styles inline) volontairement saute pour ce commit - backlog assume, deja documente, traite dans un lot separe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
b07b231a61 |
Ajoute l'assistant IA "Ruby" (Claude + Scenario) et corrige plusieurs bugs de la scène
Intègre un chat IA capable de manipuler la scène via les mêmes fonctions que l'éditeur manuel (objets, variables, déclencheurs, images générées), avec conversations multiples par écran façon Claude. Corrige au passage le rafraîchissement pjax hors-ordre, l'onglet IA/déclencheurs vide après sélection d'un objet, la comparaison de booléens dans les conditions, et le blocage du glisser-déposer hors du cadre caméra après un redimensionnement de fond par l'IA. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
7ebc9b143f |
Corrige une faille d'isolation entre comptes et retire l'email des chemins de projet
Le rôle "admin" contournait entièrement l'isolation par projet (core/auth_guard.py) : il pouvait ouvrir/modifier/supprimer le jeu de n'importe quel autre compte en connaissant son slug, et la page d'accueil listait sans filtrage tous les projets de tous les comptes. - La propriété d'un projet se vérifie désormais sur le segment "propriétaire" du slug (id du compte), pour tous les rôles y compris admin — un slug "à plat" (sans compte associé) reste réservé à l'admin, comportement historique conservé pour ce cas précis. - routes/games/index.py ne liste plus que les projets du compte connecté. - Le dossier propriétaire d'un projet est maintenant l'id numérique du compte, plus jamais son email slugifié (visible en clair dans chaque URL auparavant) — script de migration fourni et déjà exécuté sur les données existantes. - Changer d'email ne renomme plus aucun dossier (n'en dépend plus). - Deux nouveaux tests de régression, fixtures corrigées en conséquence. - README réécrit pour refléter l'état actuel du produit (jeu 2D uniquement, plus de traces de l'ancien éditeur "document"). |
||
|
|
50835a18e2 |
Supprime le type d'écran "document" et recentre le produit sur le jeu 2D
Le document de cadrage produit cible des formateurs non techniques créant des serious games/quiz gamifiés — l'éditeur générique "document" (blocs de logique en nœuds, timeline d'animation, définitions d'objets/relations, templates réutilisables) est une complexité hors cible que l'effort d'ingénierie récent avait déjà abandonnée au profit du jeu_2d. - Onboarding : ne garde que le parcours "RPG" (jeu_2d), retire Quiz/Embranchement/Créer mon jeu de A à Z (tous document-only) - Suppression en bloc des modules exclusifs au document : routes/elements, routes/element_types, routes/objects, routes/legacy_actions, screens/elements, screens/element_types, screens/widgets, screens/legacy_actions, le rendu render_element_html.py et son cluster, templates/screen_edit.html, templates/game_dashboard.html, flow-editor.js/tabs-and-blocks.js/animation-timeline.js - Dashboard toujours simplifié (un seul mode possible désormais) - Tests document-only supprimés, tests de logique partagée (flow, événements personnalisés, animations) retargetés sur des écrans jeu_2d - Aucune régression jeu_2d : 299 tests passent Carte d'onboarding retravaillée : argumentaire RH non technique (liste à coche, badge "Compatible LMS"), taille et interaction de retournement ajustées. |
||
|
|
0f23024882 |
Structure de dossiers par utilisateur : projects/<propriétaire>/<projet>/
Remplace le rangement plat projects/<slug>/ par une vraie arborescence par compte créateur, sans toucher aux routes existantes (aucune ne déclare de "/" dans son <slug> : le chemin composé "propriétaire_projet" reste un détail interne à db/, décodé par db/games/project_slug.py, seul fichier à modifier si la convention change un jour). - db/game_dir.py, create_game.py, delete_game.py, list_games.py, move_game.py : résolvent/construisent ce chemin composé. Bénéfice direct : deux comptes différents peuvent chacun avoir un projet nommé pareil sans collision (l'unicité ne se vérifie plus que par dossier propriétaire). move_game.py renomme désormais le dossier PROPRIÉTAIRE entier (changement d'email), prêt pour un futur multi-projet. - scripts/migrate_flat_project_slugs.py : migration des projets déjà créés sous l'ancien rangement plat (simulation par défaut, --apply pour exécuter). - routes/auth/profile.py, tests/conftest.py : suppression de compte/jeu de test via db.delete_game (nettoie aussi le dossier propriétaire devenu vide) plutôt qu'un shutil.rmtree direct du seul dossier projet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
449c36fd5d |
Bibliothèque de sprites animaux CraftPix (1/3) : catalogue, galerie, accès admin
Premier commit d'une fonctionnalité découpée en plusieurs lots (voir le plan "Bibliothèque de sprites animaux CraftPix") : intègre 14 familles d'animaux (15 variantes de couleur chacune) comme personnages Forge sélectionnables, à côté des 6 Kenney existants — réservé au rôle admin, licence CraftPix oblige (interdiction contractuelle de rendre ces sprites utilisables par un compte "user" via l'application). - screens/labels/animal_sprite_library.py (nouveau) : charge un manifest JSON généré une fois (voir scripts/generate_animal_sprite_manifest.py, commit suivant) et construit ADMIN_SPRITE_LIBRARY, dans le même format que l'existant PUBLIC_SPRITE_LIBRARY (screens/labels/sprite_library.py, ex-SPRITE_LIBRARY, renommé pour distinguer les deux). screens.SPRITE_LIBRARY reste le catalogue FUSIONNÉ (utilisé par resolve_personnage_animations pour la résolution runtime, sans filtrage par rôle — voir le constat d'exploration : le payload de jeu et /jouer/<slug> ne vérifient déjà aucun rôle nulle part). - screens/labels/sprite_gallery.py (nouveau) : sprite_gallery_families() groupe la galerie par famille — un animal n'apparaît qu'une fois (sa variante "de base"), ses 15 couleurs se choisissent depuis le panneau de propriétés (render_variant_gallery, templates/screen_edit.html), répondant à la suggestion de l'utilisateur plutôt que d'encombrer la galerie d'ajout de 210 tuiles quasi identiques. - routes/screens/screen_edit.py, routes/scenes/scene_edit_view.py : la galerie passée au template est filtrée par rôle (PUBLIC_SPRITE_LIBRARY pour un compte "user", SPRITE_LIBRARY complet pour un admin) — même idiome que core/auth_guard.py. - core/sprite_gate.py (nouveau) + 4 routes d'écriture (element_add, element_set_personnage_data, scene_object_add, scene_object_personnage_data) : ferme la brèche d'un POST direct qui contournerait la galerie filtrée (403 si un compte non-admin tente d'assigner un personnage animal). - tests/conftest.py : nouvelles fixtures user_client/user_game (compte "user" non-admin avec un projet assigné) pour tester le filtrage par rôle de bout en bout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
fe807ba51e |
Phase -1 (suite) : découpe l'éditeur de screen_edit.html en modules JS
Même chantier que le commit précédent (moteur de jeu, play.html) — templates/screen_edit.html était un unique fichier HTML+CSS+JS de 3312 lignes, tout l'éditeur (arborescence, panneaux flottants, canevas, formulaire de propriétés, éditeur de flow à nœuds, blocs de logique, timeline d'animation) vivant dans UN SEUL <script>. Ce fichier est plus imbriqué que play.html : de nombreux appels s'exécutent au niveau racine du script (pas seulement des déclarations de fonctions), et JavaScript hoiste les déclarations `function` sur TOUT le script — un appel au niveau racine peut donc référencer une fonction déclarée PLUS LOIN dans le même fichier. Découper naïvement casserait cet ordre implicite. Un audit dédié (analyse ligne par ligne de chaque appel racine + son graphe d'appel transitif) a identifié 3 références "en avance" réelles, toutes regroupées dans la même zone (initBuilderPanel()/toggleActionFields() → bindAspectButtons/ toggleElementPropertyValue/onDataDefinitionChange) — le découpage respecte cette contrainte : chaque fichier est une TRANCHE SÉQUENTIELLE de l'original (jamais une réorganisation), et cette zone spécifique reste un seul fichier (panel-init.js) pour que le hoisting continue de fonctionner exactement comme avant. 5 fichiers sous static/js/screen_edit/ : - tree-panels.js — arborescence, menu contextuel, panneaux flottants gauche/droite, galerie d'icônes, modale de suppression/choix d'icône, glisser-déposer du canevas, panneau de propriétés (autosave). - panel-init.js — (ré)initialisation du panneau central après chaque changement de sélection, filtres de répéteur/donnée liée, condition de visibilité, champs d'action du formulaire de nœud. - flow-editor.js — éditeur de flow à nœuds (rendu du graphe, formulaire d'ajout de nœud, blocs de logique — currentBlockNodes/Edges). - tabs-and-blocks.js — onglets du centre, panneaux flottants génériques (drag/resize/plein écran), modale d'un bloc de logique. - animation-timeline.js — timeline d'animation (clips Animate.css/ personnalisés). Toutes les données injectées par Jinja (GAME_SLUG, SCREEN_ID, DEFINITIONS_DATA, FLOW_NODES_INITIAL, ELEMENTS_LABELS, CUSTOM_EVENTS_MAP, ANIM_CLIPS...) sont posées UNE FOIS par un petit <script> inline resté dans le template, avant les <script src> — même patron que static/js/play/. Le seul bout de logique resté inline est la toute petite IIFE d'ouverture initiale (?tab=/?block=), qui dépend directement de request.args et doit s'exécuter après que tous les fichiers soient chargés. tests/conftest.py : screen_edit_js_bundle() (même principe que play_js_bundle(), Phase -1 précédente) — 4 tests qui vérifiaient la présence de telle fonction/chaîne dans le HTML de l'éditeur (le JS y était inline) sont mis à jour pour chercher dans ce bundle. Un des deux échecs révélait un test déjà fragile (assert "Ligne cliquée" in html vérifiait en réalité le TEXTE SOURCE d'un <script> inline, jamais du HTML réellement rendu — ce texte ne peut plus s'y trouver une fois la fonction qui le construit dynamiquement déplacée dans un fichier externe) : corrigé pour vérifier le bundle JS + la disponibilité de la route séparément. Vérifié : 215 tests passent, syntaxe JS validée sur les 5 nouveaux fichiers (node --check) et sur les <script> inline restants (rendus via le client de test). Test manuel recommandé (édition complète d'une scène : arborescence, propriétés, glisser-déposer, logique de flow, blocs, timeline) avant de considérer ce découpage définitivement sans risque — comme pour play.html, ce fichier n'a pas de harnais de test DOM automatisé. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
dbada333d5 |
Phase -1 : découpe le moteur de play.html en modules JS + premiers tests JS
templates/play.html était un unique fichier HTML+CSS+JS de 1069 lignes,
tout le moteur de jeu vivant dans UN SEUL <script>, sans aucune
couverture de test sur cette logique (seuls le rendu HTML et la syntaxe
JS étaient vérifiés). La feuille de route à venir (état par joueur,
hasard, clavier/minuteur, position/collision, son — voir le plan) va
justement faire grossir ce moteur : "un fichier = une fonction, un
dossier = une responsabilité" s'applique aussi au JS, pas seulement au
Python — le moment de découper est avant d'ajouter encore plus de code,
pas après.
Découpage en 6 fichiers sous static/js/play/, calqués sur les sections
déjà présentes dans le code (aucune réorganisation de logique, une pure
extraction) : screens.js (affichage d'écran, timeline d'animation),
conditions.js (évaluation des conditions — la partie 100% PURE, sans
DOM, la plus testable), actions.js (exécution des actions), triggers.js
(recherche des nœuds déclencheurs, attache des écouteurs), bindings.js
(résolution des {{champ}}, rafraîchissement des données), flow-engine.js
(parcours du graphe, événements personnalisés).
Zéro nouvel outillage : plusieurs <script src> dans l'ordre, partageant
le même espace global qu'avant (aucun bundler, aucune étape de build).
Les 2 URLs de route dont ces fichiers ont besoin (flow_node_run_data/
run_variable, runtime_payload) ne peuvent plus être injectées par Jinja
directement dans le code (un fichier statique n'est jamais passé par le
moteur de templates) — elles sont maintenant posées une fois dans
window.FORGE_PLAY_URLS par le petit <script> inline restant dans
play.html, qui ne porte plus que les données Jinja (gameData) et
l'amorçage (bindClicks() etc. au chargement).
publish/build_package.py : ajoute static/js/play à la liste des fichiers
copiés dans l'exécutable exporté (le mode jouable en dépend désormais).
Premiers tests JS (static/js/play/__tests__/conditions.test.js, lancés
via `node --test`, zéro nouvelle dépendance npm — decision prise avec
l'utilisateur de commencer par la logique PURE seulement, pas par une
couverture DOM via jsdom) : compareValues, resolveVariablePath,
evaluateConditionClause/Node, exactement la logique que les phases à
venir (opérations mathématiques, condition de collision) vont étendre.
tests/conftest.py : nouveau helper play_js_bundle() (concatène tout
static/js/play/*.js) — 13 tests existants qui vérifiaient la présence de
telle fonction/chaîne dans le HTML de /game/<slug>/play (tout le JS y
était inline avant ce découpage) sont mis à jour pour chercher dans ce
bundle à la place ; les tests qui vérifient un CSS/HTML réellement resté
dans play.html (forgeHighlight, forgeDisabled, #playFrame...) continuent
de chercher dans le HTML.
Vérifié : 215 tests pytest passent (aucune régression comportementale,
juste une réorganisation), 13 tests node:test passent, node --check sur
chacun des 6 nouveaux fichiers. Test manuel recommandé (jeu joué de bout
en bout : navigation, clic, survol, répéteur, condition, animation)
avant de considérer le découpage définitivement sans risque.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
9efe119936 |
Ajoute des codes de récupération 2FA (perte du téléphone)
10 codes à usage unique (format "xxxx-xxxx-xxxx") sont générés à
l'instant même où la 2FA est confirmée (auth/recovery_codes.py, table
_recovery_codes séparée pour marquer/consommer chaque code un par un) —
seul leur hash (werkzeug, comme les mots de passe) est stocké, ils ne
sont visibles en clair qu'à cet instant précis.
Plutôt que d'interrompre la redirection habituelle après confirmation de
la 2FA, les codes sont posés en session ("recovery_codes_to_show") et
affichés une seule fois, en modal, dès le premier rendu de base.html qui
suit (core/recovery_codes_flash.py, session.pop) — préserve tel quel le
comportement de redirection déjà couvert par les tests existants.
Sur /login/2fa, un code de récupération est accepté à la place du code
TOTP habituel (routes/auth/login_2fa.py) : verify_totp est essayé en
premier (verify_recovery_code consomme le code dès qu'il correspond, on
ne veut pas en griller un pour rien sur une saisie qui aurait en fait
été un TOTP valide). Compte toujours vers le même compteur anti-bruteforce
que le code TOTP (déjà en place, voir auth/rate_limit.py).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
a52b244f27 |
Ajoute la protection CSRF sur tous les formulaires et requêtes AJAX
Un jeton unique par session (core/csrf.py, exposé côté Jinja via csrf_token()) est vérifié sur toute requête non-GET par un before_request (core/csrf_guard.py), dans le même esprit que core/auth_guard.py : une seule garde globale plutôt que de toucher aux ~90 routes existantes une par une. L'app entière fait déjà transiter ses formulaires par fetch() : pjax.js intercepte chaque <form> interne et le transforme lui-même en requête fetch (aucun usage de l'attribut d'échappement data-no-pjax nulle part dans le repo, confirmé par grep). Il suffit donc de patcher window.fetch UNE SEULE FOIS (static/csrf_fetch.js) pour y ajouter automatiquement l'en-tête X-CSRFToken sur toute requête non-GET, formulaires pjax comme fetch() écrits à la main dans screen_edit.html/game_dashboard.html/ play.html — sans modifier un seul appel existant. La vérification est désactivée quand app.config["TESTING"] est actif (même convention que Flask-WTF/WTF_CSRF_ENABLED), pour ne pas avoir à ajouter le jeton aux ~170 tests existants qui appellent les routes directement via le client de test Flask. tests/test_csrf.py réactive volontairement la garde pour la mettre à l'épreuve pour de vrai (GET jamais bloqué, POST sans jeton/avec mauvais jeton -> 400, POST avec le bon jeton via l'en-tête ou le champ de formulaire -> succès). templates/play.html reçoit les mêmes deux balises que base.html car il est autonome (ne l'étend pas, propre <html>/<head>). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
d90abc827b |
Ajoute l'authentification : inscription, mot de passe fort, 2FA obligatoire, isolation par utilisateur
Première des deux grandes fonctionnalités demandées (authentification d'abord, export HTML/CSS/JS autonome ensuite) : - Inscription (nom, prénom, email UNIQUE, mot de passe) avec schéma visuel du mot de passe (jauge + liste de critères qui passent au vert en direct — auth/password_strength.py, mêmes règles vérifiées côté serveur qu'affichées côté client). - Double authentification (TOTP, compatible Google Authenticator/Authy) OBLIGATOIRE dès l'inscription : QR code (SVG, sans dépendance Pillow) à scanner puis code à confirmer avant que le compte soit utilisable — voir auth/create_user.py (totp_confirmed) et routes/auth/register_2fa.py. - Connexion en 2 temps (mot de passe puis code TOTP), déconnexion. - Isolation par utilisateur : un compte "user" est limité à un SEUL projet, dont le dossier est nommé d'après son adresse email (slugifiée) et créé automatiquement dès la 2FA confirmée — aucune page de gestion multi-jeux pour lui (redirigé directement vers son propre tableau de bord). Le rôle "admin" reste illimité, comme le moteur l'a toujours été (le TOUT PREMIER compte jamais créé sur une base de comptes vide devient automatiquement admin — voir auth/is_first_user.py — pas de mot de passe par défaut à faire circuler : s'inscrire en premier suffit). Un compte "user" ne peut pas non plus supprimer son unique projet (aucune façon d'en recréer un ensuite). - Garde d'accès globale (core/auth_guard.py, un seul before_request) : toute page exige une connexion, sans avoir touché individuellement aux ~80 routes déjà existantes du moteur. tests/conftest.py isole complètement les tests de la vraie base de comptes (FORGE_USERS_DB_PATH/FORGE_SECRET_KEY_PATH vers un dossier temporaire propre à la session de tests) et authentifie automatiquement la fixture `client` partagée en tant que compte admin de test — les 155 tests déjà existants continuent de passer SANS AUCUNE modification de leur côté, exactement comme avant l'authentification. 10 nouveaux tests dédiés (tests/test_auth.py) : inscription/mots de passe/2FA/connexion/ isolation par projet/blocage de suppression, vérifiés en conditions réelles (vrai client de test Flask, vraie base SQLite, vrais codes TOTP calculés avec pyotp). 165 tests au total, tous au vert. Nouvelles dépendances : pyotp, qrcode (requirements.txt). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
3f4ebc4527 | first commit |