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>
100 lines
3.5 KiB
Python
100 lines
3.5 KiB
Python
"""auth — comptes utilisateurs, connexion, 2FA (TOTP) et isolation par
|
|
utilisateur d'un SEUL projet (sauf le rôle "admin", illimité) — voir
|
|
create_user.py pour le détail des règles. Base SQLite entièrement séparée
|
|
de db/ (une base par JEU) : ces comptes n'appartiennent à aucun jeu, ils
|
|
en POSSÈDENT un (project_slug)."""
|
|
|
|
from .confirm_totp import confirm_totp
|
|
from .connection import users_db_path
|
|
from .count_admins import count_admins
|
|
from .create_user import UserCreationError, create_user
|
|
from .create_user_asset import create_user_asset
|
|
from .delete_user import delete_user
|
|
from .delete_user_asset import delete_user_asset
|
|
from .ensure_schema import ensure_users_schema
|
|
from .ensure_user_assets_schema import ensure_user_assets_schema
|
|
from .get_user_asset import get_user_asset
|
|
from .get_user_by_email import get_user_by_email
|
|
from .get_user_by_id import get_user_by_id
|
|
from .image_dimensions import image_dimensions
|
|
from .is_first_user import is_first_user
|
|
from .list_user_assets import list_user_assets
|
|
from .password_reset import (
|
|
TOKEN_TTL_MINUTES,
|
|
consume_password_reset_token,
|
|
create_password_reset_token,
|
|
get_user_id_for_valid_token,
|
|
)
|
|
from .password_strength import MIN_SCORE_REQUIRED, password_strength
|
|
from .rate_limit import lockout_message, lockout_minutes_for, seconds_locked_remaining
|
|
from .record_failed_attempt import record_failed_attempt
|
|
from .recovery_codes import generate_recovery_codes, verify_recovery_code
|
|
from .reset_failed_attempts import reset_failed_attempts
|
|
from .save_user_asset import save_user_asset
|
|
from .send_email import EmailNotConfiguredError, send_password_reset_email
|
|
from .set_password import set_password
|
|
from .set_project_slug import set_project_slug
|
|
from .set_support_slug import set_support_slug
|
|
from .totp_qrcode_svg import totp_provisioning_uri, totp_qrcode_svg
|
|
from .update_email import EmailUpdateError, update_email
|
|
from .update_profile import update_profile
|
|
from .update_user_asset_scene_kind import update_user_asset_scene_kind
|
|
from .user_asset_kind import user_asset_kind
|
|
from .user_assets_dir import user_assets_dir
|
|
from .validate_audio_duration import MAX_AUDIO_SECONDS, validate_audio_duration
|
|
from .validate_video_duration import MAX_VIDEO_SECONDS, validate_video_duration
|
|
from .verify_password import verify_password
|
|
from .verify_totp import verify_totp
|
|
|
|
__all__ = [
|
|
"users_db_path",
|
|
"ensure_users_schema",
|
|
"is_first_user",
|
|
"create_user",
|
|
"UserCreationError",
|
|
"get_user_by_email",
|
|
"get_user_by_id",
|
|
"verify_password",
|
|
"confirm_totp",
|
|
"verify_totp",
|
|
"set_project_slug",
|
|
"set_support_slug",
|
|
"password_strength",
|
|
"MIN_SCORE_REQUIRED",
|
|
"totp_provisioning_uri",
|
|
"totp_qrcode_svg",
|
|
"lockout_minutes_for",
|
|
"seconds_locked_remaining",
|
|
"lockout_message",
|
|
"record_failed_attempt",
|
|
"reset_failed_attempts",
|
|
"generate_recovery_codes",
|
|
"verify_recovery_code",
|
|
"set_password",
|
|
"create_password_reset_token",
|
|
"get_user_id_for_valid_token",
|
|
"consume_password_reset_token",
|
|
"TOKEN_TTL_MINUTES",
|
|
"send_password_reset_email",
|
|
"EmailNotConfiguredError",
|
|
"update_profile",
|
|
"count_admins",
|
|
"delete_user",
|
|
"update_email",
|
|
"EmailUpdateError",
|
|
"ensure_user_assets_schema",
|
|
"user_assets_dir",
|
|
"create_user_asset",
|
|
"list_user_assets",
|
|
"get_user_asset",
|
|
"delete_user_asset",
|
|
"save_user_asset",
|
|
"user_asset_kind",
|
|
"validate_audio_duration",
|
|
"MAX_AUDIO_SECONDS",
|
|
"validate_video_duration",
|
|
"MAX_VIDEO_SECONDS",
|
|
"image_dimensions",
|
|
"update_user_asset_scene_kind",
|
|
]
|