fix(security): verifier les fichiers televerses et retirer un intent Discord
SEC-021 -- rien ne validait le contrat signe upload_signed_contract se contentait d un nom de fichier non vide. ALLOWED_SIGNED_EXTENSIONS etait declaree juste a cote et jamais lue. Le fichier atterrissait sur le disque sous un nom que download_signed_contract sert ensuite : ce qu un joueur televerse est ce qu un gerant ouvre. Le nom seul ne suffisait pas non plus cote upload_contract, qui verifiait `.pdf` en fin de chaine -- payload.pdf ne dit rien des octets. pdf_upload_error() couvre les deux routes : extension dans la liste, puis signature %PDF- en tete de flux. Le flux est rembobine, l appelant enregistre toujours le fichier entier. OPS-014 -- intent Discord privilegie inutile Le bot demandait GUILD_MEMBERS et ne s en servait pas : rien n enumere ni ne recherche de membre de serveur, les personnes sont jointes par le discord_user_id enregistre sur leur compte. Retire. message_content reste : on_raw_reaction_add lit le texte de la reponse d un coach pour consigner un motif de refus. CI-003 et CI-005 sont deja appliques (permissions: contents: read, checkout@v4, exclusions de deploiement). L epinglage par SHA des actions n est pas fait : ce sont des actions GitHub de premiere partie, et l epingler sans Dependabot echange une exposition contre une autre. 11 tests, dont deux verifient que signer un contrat marche toujours et qu un autre joueur ne peut pas le faire. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: team-tryouts VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2026-08-08 14:58-0400\n"
|
||||
"POT-Creation-Date: 2026-08-08 15:07-0400\n"
|
||||
"PO-Revision-Date: 2026-08-07 20:22-0400\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: fr\n"
|
||||
@@ -102,50 +102,50 @@ msgstr "Les points ne doivent pas dépasser 2000 caractères."
|
||||
msgid "Day must be 0 (Monday) to 6 (Sunday)."
|
||||
msgstr "Le jour doit aller de 0 (lundi) à 6 (dimanche)."
|
||||
|
||||
#: app/routes/auth.py:169 app/routes/auth.py:297 app/routes/users.py:49
|
||||
#: app/routes/users.py:653
|
||||
#: app/routes/auth.py:186 app/routes/auth.py:314 app/routes/users.py:83
|
||||
#: app/routes/users.py:687
|
||||
#, python-format
|
||||
msgid "%(field)s: %(msg)s"
|
||||
msgstr "%(field)s : %(msg)s"
|
||||
|
||||
#: app/routes/auth.py:187
|
||||
#: app/routes/auth.py:204
|
||||
msgid "This account has been deactivated."
|
||||
msgstr "Ce compte a été désactivé."
|
||||
|
||||
#: app/routes/auth.py:225
|
||||
#: app/routes/auth.py:242
|
||||
#, python-format
|
||||
msgid "Welcome back, %(username)s!"
|
||||
msgstr "Bon retour, %(username)s !"
|
||||
|
||||
#: app/routes/auth.py:246
|
||||
#: app/routes/auth.py:263
|
||||
msgid ""
|
||||
"Login unsuccessful. Please check your username and password, or ask a "
|
||||
"president for help."
|
||||
msgstr ""
|
||||
"Échec de la connexion. Vérifiez le nom d’utilisateur et le mot de passe, ou "
|
||||
"demandez de l’aide à un président."
|
||||
"Échec de la connexion. Vérifiez le nom d’utilisateur et le mot de passe, "
|
||||
"ou demandez de l’aide à un président."
|
||||
|
||||
#: app/routes/auth.py:278
|
||||
#: app/routes/auth.py:295
|
||||
msgid "Incorrect CAPTCHA answer. Please try again."
|
||||
msgstr "Réponse au CAPTCHA incorrecte. Veuillez réessayer."
|
||||
|
||||
#: app/routes/auth.py:320 app/routes/users.py:336
|
||||
#: app/routes/auth.py:337 app/routes/users.py:370
|
||||
msgid "Username already exists."
|
||||
msgstr "Ce nom d’utilisateur est déjà pris."
|
||||
|
||||
#: app/routes/auth.py:332 app/routes/users.py:340
|
||||
#: app/routes/auth.py:349 app/routes/users.py:374
|
||||
msgid "Email already registered."
|
||||
msgstr "Cette adresse courriel est déjà enregistrée."
|
||||
|
||||
#: app/routes/auth.py:378
|
||||
#: app/routes/auth.py:395
|
||||
msgid "Your account has been created! You can now log in."
|
||||
msgstr "Votre compte a été créé. Vous pouvez maintenant vous connecter."
|
||||
|
||||
#: app/routes/auth.py:404
|
||||
#: app/routes/auth.py:421
|
||||
msgid "Discord OAuth2 is not configured."
|
||||
msgstr "La connexion Discord n’est pas configurée."
|
||||
|
||||
#: app/routes/auth.py:444
|
||||
#: app/routes/auth.py:461
|
||||
msgid ""
|
||||
"Discord authorization could not be verified. Please start the connection "
|
||||
"again from this page."
|
||||
@@ -153,27 +153,27 @@ msgstr ""
|
||||
"L’autorisation Discord n’a pas pu être vérifiée. Relancez la connexion "
|
||||
"depuis cette page."
|
||||
|
||||
#: app/routes/auth.py:452
|
||||
#: app/routes/auth.py:469
|
||||
msgid "Discord authorization failed. No code received."
|
||||
msgstr "L’autorisation Discord a échoué : aucun code reçu."
|
||||
|
||||
#: app/routes/auth.py:476
|
||||
#: app/routes/auth.py:493
|
||||
msgid "Failed to connect to Discord. Please try again."
|
||||
msgstr "Impossible de joindre Discord. Veuillez réessayer."
|
||||
|
||||
#: app/routes/auth.py:480
|
||||
#: app/routes/auth.py:497
|
||||
msgid "Failed to obtain Discord access token."
|
||||
msgstr "Impossible d’obtenir le jeton d’accès Discord."
|
||||
|
||||
#: app/routes/auth.py:495
|
||||
#: app/routes/auth.py:512
|
||||
msgid "Failed to fetch Discord user profile."
|
||||
msgstr "Impossible de récupérer le profil Discord."
|
||||
|
||||
#: app/routes/auth.py:542
|
||||
#: app/routes/auth.py:559
|
||||
msgid "Discord account connected! Your profile has been pre-filled."
|
||||
msgstr "Compte Discord connecté. Votre profil a été pré-rempli."
|
||||
|
||||
#: app/routes/auth.py:565
|
||||
#: app/routes/auth.py:587
|
||||
msgid "You have been logged out."
|
||||
msgstr "Vous avez été déconnecté."
|
||||
|
||||
@@ -412,7 +412,7 @@ msgstr "Vous n’avez pas les droits pour ajouter des notes à cette équipe."
|
||||
msgid "Team notes added successfully!"
|
||||
msgstr "Notes d’équipe ajoutées."
|
||||
|
||||
#: app/routes/teams.py:444 app/routes/users.py:1241 app/routes/users.py:1283
|
||||
#: app/routes/teams.py:444 app/routes/users.py:1266 app/routes/users.py:1308
|
||||
msgid "Can only add notes for players."
|
||||
msgstr "Il n’est possible d’ajouter des notes que pour des joueurs."
|
||||
|
||||
@@ -530,25 +530,37 @@ msgstr "Vous n’avez pas les droits pour supprimer cette sélection."
|
||||
msgid "Tryout deleted successfully."
|
||||
msgstr "Sélection supprimée."
|
||||
|
||||
#: app/routes/users.py:119
|
||||
#: app/routes/users.py:61
|
||||
msgid "No file selected."
|
||||
msgstr "Aucun fichier sélectionné."
|
||||
|
||||
#: app/routes/users.py:65
|
||||
msgid "Only PDF files are allowed for contracts."
|
||||
msgstr "Seuls les fichiers PDF sont acceptés pour les contrats."
|
||||
|
||||
#: app/routes/users.py:70
|
||||
msgid "That file is not a PDF, whatever its name says."
|
||||
msgstr "Ce fichier n’est pas un PDF, quel que soit son nom."
|
||||
|
||||
#: app/routes/users.py:153
|
||||
msgid "Only the president can manage users."
|
||||
msgstr "Seul le président peut gérer les utilisateurs."
|
||||
|
||||
#: app/routes/users.py:131
|
||||
#: app/routes/users.py:165
|
||||
msgid "Only the president can edit users."
|
||||
msgstr "Seul le président peut modifier des utilisateurs."
|
||||
|
||||
#: app/routes/users.py:168
|
||||
#: app/routes/users.py:202
|
||||
msgid "Email already in use by another account."
|
||||
msgstr "Cette adresse courriel est déjà utilisée par un autre compte."
|
||||
|
||||
#: app/routes/users.py:178
|
||||
#: app/routes/users.py:212
|
||||
msgid "You cannot change your own role. Ask another president to do it."
|
||||
msgstr ""
|
||||
"Vous ne pouvez pas modifier votre propre rôle. Demandez à un autre "
|
||||
"président de le faire."
|
||||
|
||||
#: app/routes/users.py:189
|
||||
#: app/routes/users.py:223
|
||||
msgid ""
|
||||
"This is the last active president. Promote another account before "
|
||||
"changing this one."
|
||||
@@ -556,183 +568,174 @@ msgstr ""
|
||||
"C’est le dernier président actif. Promouvez un autre compte avant de "
|
||||
"modifier celui-ci."
|
||||
|
||||
#: app/routes/users.py:251
|
||||
#: app/routes/users.py:285
|
||||
#, python-format
|
||||
msgid "User %(username)s updated successfully!"
|
||||
msgstr "Utilisateur %(username)s mis à jour."
|
||||
|
||||
#: app/routes/users.py:266
|
||||
#: app/routes/users.py:300
|
||||
msgid "Only the president can delete users."
|
||||
msgstr "Seul le président peut supprimer des utilisateurs."
|
||||
|
||||
#: app/routes/users.py:270
|
||||
#: app/routes/users.py:304
|
||||
msgid "You cannot delete your own account."
|
||||
msgstr "Vous ne pouvez pas supprimer votre propre compte."
|
||||
|
||||
#: app/routes/users.py:307
|
||||
#: app/routes/users.py:341
|
||||
#, python-format
|
||||
msgid "User %(deleted_username)s has been removed."
|
||||
msgstr "L’utilisateur %(deleted_username)s a été supprimé."
|
||||
|
||||
#: app/routes/users.py:316
|
||||
#: app/routes/users.py:350
|
||||
msgid "Only the president can create users."
|
||||
msgstr "Seul le président peut créer des utilisateurs."
|
||||
|
||||
#: app/routes/users.py:355
|
||||
#: app/routes/users.py:389
|
||||
#, python-format
|
||||
msgid "User %(full_name)s created as %(role)s!"
|
||||
msgstr "Utilisateur %(full_name)s créé avec le rôle %(role)s."
|
||||
|
||||
#: app/routes/users.py:412
|
||||
#: app/routes/users.py:446
|
||||
msgid "Username already taken."
|
||||
msgstr "Ce nom d’utilisateur est déjà pris."
|
||||
|
||||
#: app/routes/users.py:418
|
||||
#: app/routes/users.py:452
|
||||
msgid "Email already in use."
|
||||
msgstr "Cette adresse courriel est déjà utilisée."
|
||||
|
||||
#: app/routes/users.py:443
|
||||
#: app/routes/users.py:477
|
||||
msgid "Profile updated successfully!"
|
||||
msgstr "Profil mis à jour."
|
||||
|
||||
#: app/routes/users.py:641
|
||||
#: app/routes/users.py:675
|
||||
msgid "Only presidents, managers, and coaches can upload contracts."
|
||||
msgstr "Seuls les présidents, gérants et coachs peuvent téléverser un contrat."
|
||||
|
||||
#: app/routes/users.py:660
|
||||
#: app/routes/users.py:694
|
||||
msgid "You do not have permission to upload a contract for this player."
|
||||
msgstr "Vous n’avez pas les droits pour téléverser un contrat pour ce joueur."
|
||||
|
||||
#: app/routes/users.py:664 app/routes/users.py:669 app/routes/users.py:721
|
||||
#: app/routes/users.py:726
|
||||
msgid "No file selected."
|
||||
msgstr "Aucun fichier sélectionné."
|
||||
|
||||
#: app/routes/users.py:672
|
||||
msgid "Only PDF files are allowed for contracts."
|
||||
msgstr "Seuls les fichiers PDF sont acceptés pour les contrats."
|
||||
|
||||
#: app/routes/users.py:705
|
||||
#: app/routes/users.py:733
|
||||
#, python-format
|
||||
msgid "Contract uploaded successfully for %(username)s!"
|
||||
msgstr "Contrat téléversé pour %(username)s."
|
||||
|
||||
#: app/routes/users.py:717
|
||||
#: app/routes/users.py:745
|
||||
msgid "Only the player can upload their signed contract."
|
||||
msgstr "Seul le joueur peut téléverser son contrat signé."
|
||||
|
||||
#: app/routes/users.py:737
|
||||
#: app/routes/users.py:762
|
||||
msgid "Signed contract uploaded successfully!"
|
||||
msgstr "Contrat signé téléversé."
|
||||
|
||||
#: app/routes/users.py:747 app/routes/users.py:758
|
||||
#: app/routes/users.py:772 app/routes/users.py:783
|
||||
msgid "You do not have permission to download this contract."
|
||||
msgstr "Vous n’avez pas les droits pour télécharger ce contrat."
|
||||
|
||||
#: app/routes/users.py:761
|
||||
#: app/routes/users.py:786
|
||||
msgid "No signed contract available."
|
||||
msgstr "Aucun contrat signé disponible."
|
||||
|
||||
#: app/routes/users.py:828
|
||||
#: app/routes/users.py:853
|
||||
msgid "Only players can request One on One sessions."
|
||||
msgstr "Seuls les joueurs peuvent demander une rencontre individuelle."
|
||||
|
||||
#: app/routes/users.py:841
|
||||
#: app/routes/users.py:866
|
||||
msgid "You do not have a coach assigned to your team."
|
||||
msgstr "Aucun coach n’est assigné à votre équipe."
|
||||
|
||||
#: app/routes/users.py:868
|
||||
#: app/routes/users.py:893
|
||||
msgid "Cannot request One on One - no coach assigned."
|
||||
msgstr "Impossible de demander une rencontre : aucun coach assigné."
|
||||
|
||||
#: app/routes/users.py:876
|
||||
#: app/routes/users.py:901
|
||||
msgid "Invalid date or time format."
|
||||
msgstr "Format de date ou d’heure invalide."
|
||||
|
||||
#: app/routes/users.py:890
|
||||
#: app/routes/users.py:915
|
||||
msgid "The requested time is not within the coach's availability."
|
||||
msgstr "L’horaire demandé ne correspond à aucune disponibilité du coach."
|
||||
|
||||
#: app/routes/users.py:913
|
||||
#: app/routes/users.py:938
|
||||
msgid "Your One on One request has been submitted!"
|
||||
msgstr "Votre demande de rencontre a été envoyée."
|
||||
|
||||
#: app/routes/users.py:948
|
||||
#: app/routes/users.py:973
|
||||
msgid "Only coaches can accept One on One requests."
|
||||
msgstr "Seuls les coachs peuvent accepter une demande de rencontre."
|
||||
|
||||
#: app/routes/users.py:954 app/routes/users.py:995
|
||||
#: app/routes/users.py:979 app/routes/users.py:1020
|
||||
msgid "This request is not for you."
|
||||
msgstr "Cette demande ne vous est pas destinée."
|
||||
|
||||
#: app/routes/users.py:958 app/routes/users.py:999
|
||||
#: app/routes/users.py:983 app/routes/users.py:1024
|
||||
msgid "This request has already been processed."
|
||||
msgstr "Cette demande a déjà été traitée."
|
||||
|
||||
#: app/routes/users.py:980
|
||||
#: app/routes/users.py:1005
|
||||
#, python-format
|
||||
msgid "One on One request from %(player)s has been approved!"
|
||||
msgstr "La demande de rencontre de %(player)s a été approuvée."
|
||||
|
||||
#: app/routes/users.py:989
|
||||
#: app/routes/users.py:1014
|
||||
msgid "Only coaches can reject One on One requests."
|
||||
msgstr "Seuls les coachs peuvent refuser une demande de rencontre."
|
||||
|
||||
#: app/routes/users.py:1026
|
||||
#: app/routes/users.py:1051
|
||||
#, python-format
|
||||
msgid "One on One request from %(player)s has been rejected."
|
||||
msgstr "La demande de rencontre de %(player)s a été refusée."
|
||||
|
||||
#: app/routes/users.py:1039
|
||||
#: app/routes/users.py:1064
|
||||
msgid "This page is for players only."
|
||||
msgstr "Cette page est réservée aux joueurs."
|
||||
|
||||
#: app/routes/users.py:1070
|
||||
#: app/routes/users.py:1095
|
||||
msgid "Only coaches can manage availability."
|
||||
msgstr "Seuls les coachs peuvent gérer leurs disponibilités."
|
||||
|
||||
#: app/routes/users.py:1132
|
||||
#: app/routes/users.py:1157
|
||||
msgid "Only coaches can access the notes dashboard."
|
||||
msgstr "Seuls les coachs ont accès au tableau des notes."
|
||||
|
||||
#: app/routes/users.py:1196
|
||||
#: app/routes/users.py:1221
|
||||
msgid "Only coaches can manage team notes."
|
||||
msgstr "Seuls les coachs peuvent gérer les notes d’équipe."
|
||||
|
||||
#: app/routes/users.py:1202
|
||||
#: app/routes/users.py:1227
|
||||
msgid "You are not assigned to a team."
|
||||
msgstr "Vous n’êtes assigné à aucune équipe."
|
||||
|
||||
#: app/routes/users.py:1215
|
||||
#: app/routes/users.py:1240
|
||||
msgid "Team notes saved successfully!"
|
||||
msgstr "Notes d’équipe enregistrées."
|
||||
|
||||
#: app/routes/users.py:1229
|
||||
#: app/routes/users.py:1254
|
||||
msgid "Only coaches can manage personal notes."
|
||||
msgstr "Seuls les coachs peuvent gérer les notes personnelles."
|
||||
|
||||
#: app/routes/users.py:1236 app/routes/users.py:1278 app/routes/users.py:1328
|
||||
#: app/routes/users.py:1379
|
||||
#: app/routes/users.py:1261 app/routes/users.py:1303 app/routes/users.py:1353
|
||||
#: app/routes/users.py:1404
|
||||
msgid "Player and content are required."
|
||||
msgstr "Le joueur et le contenu sont obligatoires."
|
||||
|
||||
#: app/routes/users.py:1245 app/routes/users.py:1287 app/routes/users.py:1332
|
||||
#: app/routes/users.py:1383
|
||||
#: app/routes/users.py:1270 app/routes/users.py:1312 app/routes/users.py:1357
|
||||
#: app/routes/users.py:1408
|
||||
msgid "You can only write notes about players you work with."
|
||||
msgstr ""
|
||||
"Vous ne pouvez écrire des notes que sur les joueurs avec qui vous "
|
||||
"travaillez."
|
||||
|
||||
#: app/routes/users.py:1255 app/routes/users.py:1300
|
||||
#: app/routes/users.py:1280 app/routes/users.py:1325
|
||||
#, python-format
|
||||
msgid "Note added for %(username)s."
|
||||
msgstr "Note ajoutée pour %(username)s."
|
||||
|
||||
#: app/routes/users.py:1268 app/routes/users.py:1313 app/routes/users.py:1363
|
||||
#: app/routes/users.py:1293 app/routes/users.py:1338 app/routes/users.py:1388
|
||||
msgid "Only coaches can add personal notes."
|
||||
msgstr "Seuls les coachs peuvent ajouter des notes personnelles."
|
||||
|
||||
#: app/routes/users.py:1343 app/routes/users.py:1394
|
||||
#: app/routes/users.py:1368 app/routes/users.py:1419
|
||||
msgid "Note added successfully."
|
||||
msgstr "Note ajoutée."
|
||||
|
||||
@@ -851,7 +854,7 @@ msgstr "Réessayer"
|
||||
msgid "Language"
|
||||
msgstr "Langue"
|
||||
|
||||
#: app/templates/layouts/base.html:33 app/templates/layouts/base.html:133
|
||||
#: app/templates/layouts/base.html:33 app/templates/layouts/base.html:139
|
||||
#: app/templates/pages/dashboard.html:2 app/templates/pages/dashboard.html:3
|
||||
msgid "Dashboard"
|
||||
msgstr "Tableau de bord"
|
||||
@@ -910,19 +913,19 @@ msgstr "Contrats"
|
||||
msgid "My Profile"
|
||||
msgstr "Mon profil"
|
||||
|
||||
#: app/templates/layouts/base.html:117
|
||||
#: app/templates/layouts/base.html:122
|
||||
msgid "Logout"
|
||||
msgstr "Déconnexion"
|
||||
|
||||
#: app/templates/layouts/base.html:137
|
||||
#: app/templates/layouts/base.html:143
|
||||
msgid "Toggle dark mode"
|
||||
msgstr "Basculer le mode sombre"
|
||||
|
||||
#: app/templates/layouts/base.html:149 app/templates/layouts/base.html:168
|
||||
#: app/templates/layouts/base.html:155 app/templates/layouts/base.html:174
|
||||
msgid "Dismiss"
|
||||
msgstr "Fermer"
|
||||
|
||||
#: app/templates/layouts/base.html:178
|
||||
#: app/templates/layouts/base.html:184
|
||||
msgid "Team Tryout Management System"
|
||||
msgstr "Système de gestion des sélections d’équipe"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user