fix(auth): retirer un CAPTCHA qui ne protegeait rien, filtrer autrement
SEC-AUTH-008. L addition a deux operandes entre 1 et 10 avait dix-neuf reponses possibles et se resolvait en lisant la question comme une chaine. Elle n arretait aucune inscription automatisee. Elle ajoutait en revanche une etape a chaque personne, lecteur d ecran compris, contre une apparence de protection — ce qui est pire que rien, puisque ca se compte comme une protection. L autre branche proposee par l audit etait un vrai service de CAPTCHA : un tiers, une cle d API, une requete a chaque affichage, et un script etranger remis dans script-src, defaisant le travail qui a ferme SEC-WEB-001. Disproportionne pour le site d un club. A la place, deux verifications invisibles pour un visiteur : un champ piege, cache par la feuille de style et hors du parcours clavier, qu un robot remplisseur complete et qu une personne ne voit jamais ; et un delai minimal entre la remise du formulaire et son retour, l horodatage etant dans la session signee et non dans un champ. Le plafond est dit dans le code plutot que sous-entendu : ceci arrete le pourriel de masse, pas quelqu un qui lit la page. Ce qui filtrerait vraiment les inscriptions serait l activation des comptes par le staff — is_active_account vaut True par defaut. C est une decision de produit. L angle « session forgeable » du constat tombe : avec SECRET_KEY compromise (SEC-001), on forge une session connectee sur n importe quel compte et on n a aucune raison de s inscrire. Au passage, ARCH-005 en partie : le bloc « regenerer, purger les mots de passe, re-rendre » etait recopie quatre fois. Un seul helper, et la purge des mots de passe ne peut plus etre oubliee dans la cinquieme copie. Les refus sont journalises avec leur motif — c est le seul endroit ou un abus du formulaire devient visible — mais restent indistinguables pour l expediteur : nommer la regle indique comment la contourner. 429 tests.
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 15:57-0400\n"
|
||||
"POT-Creation-Date: 2026-08-11 12:05-0400\n"
|
||||
"PO-Revision-Date: 2026-08-07 20:22-0400\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: en\n"
|
||||
@@ -19,7 +19,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.18.0\n"
|
||||
|
||||
#: app/validators.py:49
|
||||
#: app/validators.py:50
|
||||
msgid ""
|
||||
"Password must be at least 8 characters with uppercase, lowercase, and a "
|
||||
"number."
|
||||
@@ -27,95 +27,95 @@ msgstr ""
|
||||
"Password must be at least 8 characters with uppercase, lowercase, and a "
|
||||
"number."
|
||||
|
||||
#: app/validators.py:67
|
||||
#: app/validators.py:68
|
||||
msgid "Username must be 3-30 characters (letters, numbers, underscore, hyphen)."
|
||||
msgstr "Username must be 3-30 characters (letters, numbers, underscore, hyphen)."
|
||||
|
||||
#: app/validators.py:86
|
||||
#: app/validators.py:87
|
||||
msgid "Invalid Discord username format."
|
||||
msgstr "Invalid Discord username format."
|
||||
|
||||
#: app/validators.py:103
|
||||
#: app/validators.py:104
|
||||
msgid "Discord User ID must be a 17-20 digit number."
|
||||
msgstr "Discord User ID must be a 17-20 digit number."
|
||||
|
||||
#: app/validators.py:121
|
||||
#: app/validators.py:122
|
||||
msgid "Invalid phone number format."
|
||||
msgstr "Invalid phone number format."
|
||||
|
||||
#: app/validators.py:163
|
||||
#: app/validators.py:164
|
||||
msgid "Username is required."
|
||||
msgstr "Username is required."
|
||||
|
||||
#: app/validators.py:167
|
||||
#: app/validators.py:168
|
||||
msgid "Password is required."
|
||||
msgstr "Password is required."
|
||||
|
||||
#: app/validators.py:189 app/validators.py:261
|
||||
#: app/validators.py:190 app/validators.py:262
|
||||
msgid "Username must be 3-80 characters."
|
||||
msgstr "Username must be 3-80 characters."
|
||||
|
||||
#: app/validators.py:195
|
||||
#: app/validators.py:196
|
||||
msgid "Email must be 120 characters or less."
|
||||
msgstr "Email must be 120 characters or less."
|
||||
|
||||
#: app/validators.py:208 app/validators.py:276 app/validators.py:307
|
||||
#: app/validators.py:371
|
||||
#: app/validators.py:209 app/validators.py:277 app/validators.py:308
|
||||
#: app/validators.py:372
|
||||
msgid "Full name is required."
|
||||
msgstr "Full name is required."
|
||||
|
||||
#: app/validators.py:243
|
||||
#: app/validators.py:244
|
||||
msgid "Passwords do not match."
|
||||
msgstr "Passwords do not match."
|
||||
|
||||
#: app/validators.py:280 app/validators.py:315
|
||||
#: app/validators.py:281 app/validators.py:316
|
||||
msgid "Invalid role selected."
|
||||
msgstr "Invalid role selected."
|
||||
|
||||
#: app/validators.py:416
|
||||
#: app/validators.py:417
|
||||
msgid "Player must be selected."
|
||||
msgstr "Player must be selected."
|
||||
|
||||
#: app/validators.py:419
|
||||
#: app/validators.py:420
|
||||
msgid "Notes must be 2000 characters or less."
|
||||
msgstr "Notes must be 2000 characters or less."
|
||||
|
||||
#: app/validators.py:438
|
||||
#: app/validators.py:439
|
||||
msgid "Date must be in YYYY-MM-DD format."
|
||||
msgstr "Date must be in YYYY-MM-DD format."
|
||||
|
||||
#: app/validators.py:443 app/validators.py:470
|
||||
#: app/validators.py:444 app/validators.py:471
|
||||
msgid "Start time must be in HH:MM format."
|
||||
msgstr "Start time must be in HH:MM format."
|
||||
|
||||
#: app/validators.py:447
|
||||
#: app/validators.py:448
|
||||
msgid "End time must be in HH:MM format."
|
||||
msgstr "End time must be in HH:MM format."
|
||||
|
||||
#: app/validators.py:450
|
||||
#: app/validators.py:451
|
||||
msgid "Points must be 2000 characters or less."
|
||||
msgstr "Points must be 2000 characters or less."
|
||||
|
||||
#: app/validators.py:466
|
||||
#: app/validators.py:467
|
||||
msgid "Day must be 0 (Monday) to 6 (Sunday)."
|
||||
msgstr "Day must be 0 (Monday) to 6 (Sunday)."
|
||||
|
||||
#: app/routes/auth.py:186 app/routes/auth.py:322 app/routes/users.py:106
|
||||
#: app/routes/users.py:821
|
||||
#: app/routes/auth.py:224 app/routes/auth.py:374 app/routes/users/_shared.py:64
|
||||
#: app/routes/users/contracts.py:95
|
||||
#, python-format
|
||||
msgid "%(field)s: %(msg)s"
|
||||
msgstr "%(field)s: %(msg)s"
|
||||
|
||||
#: app/routes/auth.py:203
|
||||
#: app/routes/auth.py:241
|
||||
msgid "This account has been deactivated."
|
||||
msgstr "This account has been deactivated."
|
||||
|
||||
#: app/routes/auth.py:238
|
||||
#: app/routes/auth.py:276
|
||||
#, python-format
|
||||
msgid "Welcome back, %(username)s!"
|
||||
msgstr "Welcome back, %(username)s!"
|
||||
|
||||
#: app/routes/auth.py:268
|
||||
#: app/routes/auth.py:306
|
||||
msgid ""
|
||||
"Login unsuccessful. Please check your username and password, or ask a "
|
||||
"president for help."
|
||||
@@ -123,27 +123,27 @@ msgstr ""
|
||||
"Login unsuccessful. Please check your username and password, or ask a "
|
||||
"president for help."
|
||||
|
||||
#: app/routes/auth.py:303
|
||||
msgid "Incorrect CAPTCHA answer. Please try again."
|
||||
msgstr "Incorrect CAPTCHA answer. Please try again."
|
||||
#: app/routes/auth.py:363
|
||||
msgid "Your registration could not be processed. Please try again."
|
||||
msgstr "Your registration could not be processed. Please try again."
|
||||
|
||||
#: app/routes/auth.py:345 app/routes/users.py:436
|
||||
#: app/routes/auth.py:388 app/routes/users/accounts.py:308
|
||||
msgid "Username already exists."
|
||||
msgstr "Username already exists."
|
||||
|
||||
#: app/routes/auth.py:357 app/routes/users.py:440
|
||||
#: app/routes/auth.py:392 app/routes/users/accounts.py:312
|
||||
msgid "Email already registered."
|
||||
msgstr "Email already registered."
|
||||
|
||||
#: app/routes/auth.py:404
|
||||
#: app/routes/auth.py:436
|
||||
msgid "Your account has been created! You can now log in."
|
||||
msgstr "Your account has been created! You can now log in."
|
||||
|
||||
#: app/routes/auth.py:430
|
||||
#: app/routes/auth.py:457
|
||||
msgid "Discord OAuth2 is not configured."
|
||||
msgstr "Discord OAuth2 is not configured."
|
||||
|
||||
#: app/routes/auth.py:471
|
||||
#: app/routes/auth.py:498
|
||||
msgid ""
|
||||
"Discord authorization could not be verified. Please start the connection "
|
||||
"again from this page."
|
||||
@@ -151,418 +151,419 @@ msgstr ""
|
||||
"Discord authorization could not be verified. Please start the connection "
|
||||
"again from this page."
|
||||
|
||||
#: app/routes/auth.py:480
|
||||
#: app/routes/auth.py:507
|
||||
msgid "Discord authorization failed. No code received."
|
||||
msgstr "Discord authorization failed. No code received."
|
||||
|
||||
#: app/routes/auth.py:504
|
||||
#: app/routes/auth.py:531
|
||||
msgid "Failed to connect to Discord. Please try again."
|
||||
msgstr "Failed to connect to Discord. Please try again."
|
||||
|
||||
#: app/routes/auth.py:508
|
||||
#: app/routes/auth.py:535
|
||||
msgid "Failed to obtain Discord access token."
|
||||
msgstr "Failed to obtain Discord access token."
|
||||
|
||||
#: app/routes/auth.py:523
|
||||
#: app/routes/auth.py:550
|
||||
msgid "Failed to fetch Discord user profile."
|
||||
msgstr "Failed to fetch Discord user profile."
|
||||
|
||||
#: app/routes/auth.py:570
|
||||
#: app/routes/auth.py:597
|
||||
msgid "Discord account connected! Your profile has been pre-filled."
|
||||
msgstr "Discord account connected! Your profile has been pre-filled."
|
||||
|
||||
#: app/routes/auth.py:598
|
||||
#: app/routes/auth.py:625
|
||||
msgid "You have been logged out."
|
||||
msgstr "You have been logged out."
|
||||
|
||||
#: app/routes/evaluations.py:45
|
||||
#: app/routes/evaluations.py:46
|
||||
msgid "You do not have permission to view evaluations."
|
||||
msgstr "You do not have permission to view evaluations."
|
||||
|
||||
#: app/routes/evaluations.py:135
|
||||
#: app/routes/evaluations.py:136
|
||||
msgid "You do not have permission to evaluate players."
|
||||
msgstr "You do not have permission to evaluate players."
|
||||
|
||||
#: app/routes/evaluations.py:140 app/routes/evaluations.py:263
|
||||
#: app/routes/evaluations.py:141 app/routes/evaluations.py:264
|
||||
msgid "You do not have permission to evaluate players in this tryout."
|
||||
msgstr "You do not have permission to evaluate players in this tryout."
|
||||
|
||||
#: app/routes/evaluations.py:151
|
||||
#: app/routes/evaluations.py:152
|
||||
msgid "Player is not registered for this tryout."
|
||||
msgstr "Player is not registered for this tryout."
|
||||
|
||||
#: app/routes/evaluations.py:156
|
||||
#: app/routes/evaluations.py:157
|
||||
msgid "Can only evaluate players."
|
||||
msgstr "Can only evaluate players."
|
||||
|
||||
#: app/routes/evaluations.py:208
|
||||
#: app/routes/evaluations.py:209
|
||||
msgid "Evaluation updated!"
|
||||
msgstr "Evaluation updated!"
|
||||
|
||||
#: app/routes/evaluations.py:228
|
||||
#: app/routes/evaluations.py:229
|
||||
msgid "Evaluation submitted successfully!"
|
||||
msgstr "Evaluation submitted successfully!"
|
||||
|
||||
#: app/routes/evaluations.py:258 app/routes/teams.py:268
|
||||
#: app/routes/teams.py:309 app/routes/teams.py:350 app/routes/teams.py:375
|
||||
#: app/routes/teams.py:400 app/routes/teams.py:435 app/routes/tryouts.py:472
|
||||
#: app/routes/tryouts.py:488 app/routes/tryouts.py:508
|
||||
#: app/routes/tryouts.py:547 app/routes/tryouts.py:583
|
||||
#: app/routes/tryouts.py:602
|
||||
#: app/routes/evaluations.py:259 app/routes/teams.py:270
|
||||
#: app/routes/teams.py:311 app/routes/teams.py:352 app/routes/teams.py:377
|
||||
#: app/routes/teams.py:402 app/routes/teams.py:437 app/routes/tryouts.py:505
|
||||
#: app/routes/tryouts.py:521 app/routes/tryouts.py:541
|
||||
#: app/routes/tryouts.py:580 app/routes/tryouts.py:616
|
||||
#: app/routes/tryouts.py:635
|
||||
msgid "Permission denied."
|
||||
msgstr "Permission denied."
|
||||
|
||||
#: app/routes/main.py:53
|
||||
#: app/routes/main.py:55
|
||||
msgid "That language is not available."
|
||||
msgstr "That language is not available."
|
||||
|
||||
#: app/routes/matches.py:245
|
||||
#: app/routes/matches.py:307
|
||||
msgid "You do not have permission to schedule matches for this tryout."
|
||||
msgstr "You do not have permission to schedule matches for this tryout."
|
||||
|
||||
#: app/routes/matches.py:249 app/routes/matches.py:422
|
||||
#: app/routes/matches.py:311 app/routes/matches.py:473
|
||||
msgid "This tryout has ended. Matches can no longer be created or modified."
|
||||
msgstr "This tryout has ended. Matches can no longer be created or modified."
|
||||
|
||||
#: app/routes/matches.py:270
|
||||
#: app/routes/matches.py:332
|
||||
msgid "Start time is required. Please select a time slot."
|
||||
msgstr "Start time is required. Please select a time slot."
|
||||
|
||||
#: app/routes/matches.py:282 app/routes/matches.py:445
|
||||
#: app/routes/team_matches.py:151 app/routes/team_matches.py:255
|
||||
#: app/routes/matches.py:344 app/routes/matches.py:496
|
||||
#: app/routes/team_matches.py:153 app/routes/team_matches.py:247
|
||||
msgid "Invalid date format."
|
||||
msgstr "Invalid date format."
|
||||
|
||||
#: app/routes/matches.py:302 app/routes/team_matches.py:172
|
||||
#: app/routes/matches.py:364 app/routes/team_matches.py:174
|
||||
msgid "Invalid time format."
|
||||
msgstr "Invalid time format."
|
||||
|
||||
#: app/routes/matches.py:398
|
||||
#: app/routes/matches.py:449
|
||||
msgid "Match scheduled successfully!"
|
||||
msgstr "Match scheduled successfully!"
|
||||
|
||||
#: app/routes/matches.py:418 app/routes/team_matches.py:242
|
||||
#: app/routes/matches.py:469 app/routes/team_matches.py:234
|
||||
msgid "You do not have permission to edit this match."
|
||||
msgstr "You do not have permission to edit this match."
|
||||
|
||||
#: app/routes/matches.py:456
|
||||
#: app/routes/matches.py:507
|
||||
msgid "Start time is required."
|
||||
msgstr "Start time is required."
|
||||
|
||||
#: app/routes/matches.py:578 app/routes/team_matches.py:284
|
||||
#: app/routes/matches.py:616 app/routes/team_matches.py:276
|
||||
msgid "Match updated successfully!"
|
||||
msgstr "Match updated successfully!"
|
||||
|
||||
#: app/routes/matches.py:631 app/routes/team_matches.py:299
|
||||
#: app/routes/matches.py:669 app/routes/team_matches.py:291
|
||||
msgid "You do not have permission to delete this match."
|
||||
msgstr "You do not have permission to delete this match."
|
||||
|
||||
#: app/routes/matches.py:634
|
||||
#: app/routes/matches.py:672
|
||||
msgid "This tryout has ended. Matches can no longer be deleted."
|
||||
msgstr "This tryout has ended. Matches can no longer be deleted."
|
||||
|
||||
#: app/routes/matches.py:647 app/routes/team_matches.py:303
|
||||
#: app/routes/matches.py:685 app/routes/team_matches.py:295
|
||||
msgid "Match deleted successfully."
|
||||
msgstr "Match deleted successfully."
|
||||
|
||||
#: app/routes/team_matches.py:98
|
||||
#: app/routes/team_matches.py:100
|
||||
msgid "You do not have permission to schedule matches for this team."
|
||||
msgstr "You do not have permission to schedule matches for this team."
|
||||
|
||||
#: app/routes/team_matches.py:140
|
||||
#: app/routes/team_matches.py:142
|
||||
msgid "Date is required."
|
||||
msgstr "Date is required."
|
||||
|
||||
#: app/routes/team_matches.py:228
|
||||
#: app/routes/team_matches.py:220
|
||||
#, python-format
|
||||
msgid "Team match \"%(title)s\" scheduled successfully!"
|
||||
msgstr "Team match \"%(title)s\" scheduled successfully!"
|
||||
|
||||
#: app/routes/team_matches.py:267
|
||||
#: app/routes/team_matches.py:259
|
||||
msgid "Invalid start time format."
|
||||
msgstr "Invalid start time format."
|
||||
|
||||
#: app/routes/team_matches.py:275
|
||||
#: app/routes/team_matches.py:267
|
||||
msgid "Invalid end time format."
|
||||
msgstr "Invalid end time format."
|
||||
|
||||
#: app/routes/teams.py:38
|
||||
#: app/routes/teams.py:40
|
||||
msgid "Use My Team(s) to view your teams."
|
||||
msgstr "Use My Team(s) to view your teams."
|
||||
|
||||
#: app/routes/teams.py:41
|
||||
#: app/routes/teams.py:43
|
||||
msgid "You do not have permission to view teams."
|
||||
msgstr "You do not have permission to view teams."
|
||||
|
||||
#: app/routes/teams.py:68
|
||||
#: app/routes/teams.py:70
|
||||
msgid "This page is for players."
|
||||
msgstr "This page is for players."
|
||||
|
||||
#: app/routes/teams.py:121
|
||||
#: app/routes/teams.py:123
|
||||
msgid "You do not have permission to create teams."
|
||||
msgstr "You do not have permission to create teams."
|
||||
|
||||
#: app/routes/teams.py:129 app/routes/teams.py:174
|
||||
#: app/routes/teams.py:131 app/routes/teams.py:176
|
||||
msgid "Team name is required."
|
||||
msgstr "Team name is required."
|
||||
|
||||
#: app/routes/teams.py:134 app/routes/teams.py:179
|
||||
#: app/routes/teams.py:136 app/routes/teams.py:181
|
||||
#, python-format
|
||||
msgid "Team \"%(name)s\" already exists."
|
||||
msgstr "Team \"%(name)s\" already exists."
|
||||
|
||||
#: app/routes/teams.py:156
|
||||
#: app/routes/teams.py:158
|
||||
#, python-format
|
||||
msgid "Team \"%(name)s\" created successfully!"
|
||||
msgstr "Team \"%(name)s\" created successfully!"
|
||||
|
||||
#: app/routes/teams.py:166
|
||||
#: app/routes/teams.py:168
|
||||
msgid "You do not have permission to edit this team."
|
||||
msgstr "You do not have permission to edit this team."
|
||||
|
||||
#: app/routes/teams.py:217
|
||||
#: app/routes/teams.py:219
|
||||
#, python-format
|
||||
msgid "Team \"%(name)s\" updated successfully!"
|
||||
msgstr "Team \"%(name)s\" updated successfully!"
|
||||
|
||||
#: app/routes/teams.py:226
|
||||
#: app/routes/teams.py:228
|
||||
msgid "You do not have permission to delete teams."
|
||||
msgstr "You do not have permission to delete teams."
|
||||
|
||||
#: app/routes/teams.py:258
|
||||
#: app/routes/teams.py:260
|
||||
#, python-format
|
||||
msgid "Team \"%(name)s\" deleted successfully."
|
||||
msgstr "Team \"%(name)s\" deleted successfully."
|
||||
|
||||
#: app/routes/teams.py:273
|
||||
#: app/routes/teams.py:275
|
||||
msgid "Please select a coach."
|
||||
msgstr "Please select a coach."
|
||||
|
||||
#: app/routes/teams.py:278
|
||||
#: app/routes/teams.py:280
|
||||
msgid "Only coaches can be assigned as coach."
|
||||
msgstr "Only coaches can be assigned as coach."
|
||||
|
||||
#: app/routes/teams.py:284
|
||||
#: app/routes/teams.py:286
|
||||
#, python-format
|
||||
msgid "%(username)s is already a coach of %(name)s."
|
||||
msgstr "%(username)s is already a coach of %(name)s."
|
||||
|
||||
#: app/routes/teams.py:297
|
||||
#: app/routes/teams.py:299
|
||||
#, python-format
|
||||
msgid "%(username)s added as coach of %(name)s."
|
||||
msgstr "%(username)s added as coach of %(name)s."
|
||||
|
||||
#: app/routes/teams.py:314
|
||||
#: app/routes/teams.py:316
|
||||
msgid "Please select a manager."
|
||||
msgstr "Please select a manager."
|
||||
|
||||
#: app/routes/teams.py:319
|
||||
#: app/routes/teams.py:321
|
||||
msgid "Only managers can be assigned as manager."
|
||||
msgstr "Only managers can be assigned as manager."
|
||||
|
||||
#: app/routes/teams.py:325
|
||||
#: app/routes/teams.py:327
|
||||
#, python-format
|
||||
msgid "%(username)s is already a manager of %(name)s."
|
||||
msgstr "%(username)s is already a manager of %(name)s."
|
||||
|
||||
#: app/routes/teams.py:338
|
||||
#: app/routes/teams.py:340
|
||||
#, python-format
|
||||
msgid "%(username)s added as manager of %(name)s."
|
||||
msgstr "%(username)s added as manager of %(name)s."
|
||||
|
||||
#: app/routes/teams.py:365
|
||||
#: app/routes/teams.py:367
|
||||
#, python-format
|
||||
msgid "Coach removed from %(name)s."
|
||||
msgstr "Coach removed from %(name)s."
|
||||
|
||||
#: app/routes/teams.py:390
|
||||
#: app/routes/teams.py:392
|
||||
#, python-format
|
||||
msgid "Manager removed from %(name)s."
|
||||
msgstr "Manager removed from %(name)s."
|
||||
|
||||
#: app/routes/teams.py:406 app/routes/tryouts.py:512 app/routes/tryouts.py:613
|
||||
#: app/routes/teams.py:408 app/routes/tryouts.py:545 app/routes/tryouts.py:646
|
||||
msgid "Please select a player."
|
||||
msgstr "Please select a player."
|
||||
|
||||
#: app/routes/teams.py:411
|
||||
#: app/routes/teams.py:413
|
||||
msgid "Can only assign players to teams."
|
||||
msgstr "Can only assign players to teams."
|
||||
|
||||
#: app/routes/teams.py:417
|
||||
#: app/routes/teams.py:419
|
||||
#, python-format
|
||||
msgid "%(username)s is already on %(name)s."
|
||||
msgstr "%(username)s is already on %(name)s."
|
||||
|
||||
#: app/routes/teams.py:425
|
||||
#: app/routes/teams.py:427
|
||||
#, python-format
|
||||
msgid "%(username)s added to %(name)s!"
|
||||
msgstr "%(username)s added to %(name)s!"
|
||||
|
||||
#: app/routes/teams.py:442 app/routes/teams.py:515
|
||||
#: app/routes/teams.py:444 app/routes/teams.py:517
|
||||
#, python-format
|
||||
msgid "%(username)s is not on %(name)s."
|
||||
msgstr "%(username)s is not on %(name)s."
|
||||
|
||||
#: app/routes/teams.py:450
|
||||
#: app/routes/teams.py:452
|
||||
#, python-format
|
||||
msgid "%(username)s removed from %(name)s."
|
||||
msgstr "%(username)s removed from %(name)s."
|
||||
|
||||
#: app/routes/teams.py:486 app/routes/teams.py:504
|
||||
#: app/routes/teams.py:488 app/routes/teams.py:506
|
||||
msgid "You do not have permission to add notes to this team."
|
||||
msgstr "You do not have permission to add notes to this team."
|
||||
|
||||
#: app/routes/teams.py:494
|
||||
#: app/routes/teams.py:496
|
||||
msgid "Team notes added successfully!"
|
||||
msgstr "Team notes added successfully!"
|
||||
|
||||
#: app/routes/teams.py:509 app/routes/users.py:1530 app/routes/users.py:1573
|
||||
#: app/routes/teams.py:511 app/routes/users/notes.py:207
|
||||
#: app/routes/users/notes.py:250
|
||||
msgid "Can only add notes for players."
|
||||
msgstr "Can only add notes for players."
|
||||
|
||||
#: app/routes/teams.py:525
|
||||
#: app/routes/teams.py:527
|
||||
#, python-format
|
||||
msgid "Note added for %(username)s!"
|
||||
msgstr "Note added for %(username)s!"
|
||||
|
||||
#: app/routes/tryouts.py:56
|
||||
#: app/routes/tryouts.py:77
|
||||
msgid "You do not have permission to create tryouts."
|
||||
msgstr "You do not have permission to create tryouts."
|
||||
|
||||
#: app/routes/tryouts.py:82 app/routes/tryouts.py:189
|
||||
#: app/routes/tryouts.py:103 app/routes/tryouts.py:210
|
||||
msgid "Invalid start date format."
|
||||
msgstr "Invalid start date format."
|
||||
|
||||
#: app/routes/tryouts.py:97 app/routes/tryouts.py:204
|
||||
#: app/routes/tryouts.py:118 app/routes/tryouts.py:225
|
||||
msgid "End date cannot be before start date."
|
||||
msgstr "End date cannot be before start date."
|
||||
|
||||
#: app/routes/tryouts.py:107 app/routes/tryouts.py:214
|
||||
#: app/routes/tryouts.py:128 app/routes/tryouts.py:235
|
||||
msgid "Invalid end date format."
|
||||
msgstr "Invalid end date format."
|
||||
|
||||
#: app/routes/tryouts.py:139
|
||||
#: app/routes/tryouts.py:160
|
||||
msgid "Tryout created successfully!"
|
||||
msgstr "Tryout created successfully!"
|
||||
|
||||
#: app/routes/tryouts.py:159
|
||||
#: app/routes/tryouts.py:180
|
||||
msgid "You do not have permission to edit this tryout."
|
||||
msgstr "You do not have permission to edit this tryout."
|
||||
|
||||
#: app/routes/tryouts.py:163
|
||||
#: app/routes/tryouts.py:184
|
||||
msgid "This tryout has ended and can no longer be modified."
|
||||
msgstr "This tryout has ended and can no longer be modified."
|
||||
|
||||
#: app/routes/tryouts.py:242
|
||||
#: app/routes/tryouts.py:263
|
||||
msgid "Tryout updated successfully!"
|
||||
msgstr "Tryout updated successfully!"
|
||||
|
||||
#: app/routes/tryouts.py:289
|
||||
#: app/routes/tryouts.py:310
|
||||
msgid "You do not have permission to view this tryout."
|
||||
msgstr "You do not have permission to view this tryout."
|
||||
|
||||
#: app/routes/tryouts.py:439
|
||||
#: app/routes/tryouts.py:472
|
||||
msgid "Only players can register for tryouts."
|
||||
msgstr "Only players can register for tryouts."
|
||||
|
||||
#: app/routes/tryouts.py:443
|
||||
#: app/routes/tryouts.py:476
|
||||
msgid "This tryout is not accepting registrations."
|
||||
msgstr "This tryout is not accepting registrations."
|
||||
|
||||
#: app/routes/tryouts.py:450
|
||||
#: app/routes/tryouts.py:483
|
||||
msgid "You are already registered for this tryout."
|
||||
msgstr "You are already registered for this tryout."
|
||||
|
||||
#: app/routes/tryouts.py:456 app/routes/tryouts.py:531
|
||||
#: app/routes/tryouts.py:489 app/routes/tryouts.py:564
|
||||
msgid "This tryout is full."
|
||||
msgstr "This tryout is full."
|
||||
|
||||
#: app/routes/tryouts.py:462
|
||||
#: app/routes/tryouts.py:495
|
||||
msgid "Successfully registered for tryout!"
|
||||
msgstr "Successfully registered for tryout!"
|
||||
|
||||
#: app/routes/tryouts.py:478
|
||||
#: app/routes/tryouts.py:511
|
||||
#, python-format
|
||||
msgid "Tryout status updated to %(new_status)s."
|
||||
msgstr "Tryout status updated to %(new_status)s."
|
||||
|
||||
#: app/routes/tryouts.py:498
|
||||
#: app/routes/tryouts.py:531
|
||||
msgid "Registration status updated."
|
||||
msgstr "Registration status updated."
|
||||
|
||||
#: app/routes/tryouts.py:517
|
||||
#: app/routes/tryouts.py:550
|
||||
msgid "Can only register players."
|
||||
msgstr "Can only register players."
|
||||
|
||||
#: app/routes/tryouts.py:523
|
||||
#: app/routes/tryouts.py:556
|
||||
#, python-format
|
||||
msgid "%(username)s is already registered for this tryout."
|
||||
msgstr "%(username)s is already registered for this tryout."
|
||||
|
||||
#: app/routes/tryouts.py:537
|
||||
#: app/routes/tryouts.py:570
|
||||
#, python-format
|
||||
msgid "%(username)s registered for tryout!"
|
||||
msgstr "%(username)s registered for tryout!"
|
||||
|
||||
#: app/routes/tryouts.py:573
|
||||
#: app/routes/tryouts.py:606
|
||||
#, python-format
|
||||
msgid "%(username)s removed from tryout."
|
||||
msgstr "%(username)s removed from tryout."
|
||||
|
||||
#: app/routes/tryouts.py:591
|
||||
#: app/routes/tryouts.py:624
|
||||
#, python-format
|
||||
msgid "Team \"%(team_name)s\" created!"
|
||||
msgstr "Team \"%(team_name)s\" created!"
|
||||
|
||||
#: app/routes/tryouts.py:622
|
||||
#: app/routes/tryouts.py:655
|
||||
msgid "That player is not registered for this tryout."
|
||||
msgstr "That player is not registered for this tryout."
|
||||
|
||||
#: app/routes/tryouts.py:628
|
||||
#: app/routes/tryouts.py:661
|
||||
msgid "Player is already on this team."
|
||||
msgstr "Player is already on this team."
|
||||
|
||||
#: app/routes/tryouts.py:633
|
||||
#: app/routes/tryouts.py:666
|
||||
msgid "Player added to team!"
|
||||
msgstr "Player added to team!"
|
||||
|
||||
#: app/routes/tryouts.py:643
|
||||
#: app/routes/tryouts.py:676
|
||||
msgid "You do not have permission to delete this tryout."
|
||||
msgstr "You do not have permission to delete this tryout."
|
||||
|
||||
#: app/routes/tryouts.py:679
|
||||
#: app/routes/tryouts.py:712
|
||||
msgid "Tryout deleted successfully."
|
||||
msgstr "Tryout deleted successfully."
|
||||
|
||||
#: app/routes/users.py:83
|
||||
#: app/routes/users/_shared.py:46
|
||||
msgid "No file selected."
|
||||
msgstr "No file selected."
|
||||
|
||||
#: app/routes/users.py:87
|
||||
#: app/routes/users/_shared.py:50
|
||||
msgid "Only PDF files are allowed for contracts."
|
||||
msgstr "Only PDF files are allowed for contracts."
|
||||
|
||||
#: app/routes/users.py:92
|
||||
#: app/routes/users/_shared.py:55
|
||||
msgid "That file is not a PDF, whatever its name says."
|
||||
msgstr "That file is not a PDF, whatever its name says."
|
||||
|
||||
#: app/routes/users.py:181
|
||||
#: app/routes/users/accounts.py:53
|
||||
msgid "Only the president can manage users."
|
||||
msgstr "Only the president can manage users."
|
||||
|
||||
#: app/routes/users.py:193
|
||||
#: app/routes/users/accounts.py:65
|
||||
msgid "Only the president can edit users."
|
||||
msgstr "Only the president can edit users."
|
||||
|
||||
#: app/routes/users.py:234
|
||||
#: app/routes/users/accounts.py:106
|
||||
msgid "Email already in use by another account."
|
||||
msgstr "Email already in use by another account."
|
||||
|
||||
#: app/routes/users.py:245
|
||||
#: app/routes/users/accounts.py:117
|
||||
msgid "You cannot change your own role. Ask another president to do it."
|
||||
msgstr "You cannot change your own role. Ask another president to do it."
|
||||
|
||||
#: app/routes/users.py:258
|
||||
#: app/routes/users/accounts.py:130
|
||||
msgid ""
|
||||
"This is the last active president. Promote another account before "
|
||||
"changing this one."
|
||||
@@ -570,175 +571,176 @@ msgstr ""
|
||||
"This is the last active president. Promote another account before "
|
||||
"changing this one."
|
||||
|
||||
#: app/routes/users.py:337
|
||||
#: app/routes/users/accounts.py:209
|
||||
#, python-format
|
||||
msgid "User %(username)s updated successfully!"
|
||||
msgstr "User %(username)s updated successfully!"
|
||||
|
||||
#: app/routes/users.py:358
|
||||
#: app/routes/users/accounts.py:230
|
||||
msgid "Only the president can delete users."
|
||||
msgstr "Only the president can delete users."
|
||||
|
||||
#: app/routes/users.py:362
|
||||
#: app/routes/users/accounts.py:234
|
||||
msgid "You cannot delete your own account."
|
||||
msgstr "You cannot delete your own account."
|
||||
|
||||
#: app/routes/users.py:405
|
||||
#: app/routes/users/accounts.py:277
|
||||
#, python-format
|
||||
msgid "User %(deleted_username)s has been removed."
|
||||
msgstr "User %(deleted_username)s has been removed."
|
||||
|
||||
#: app/routes/users.py:416
|
||||
#: app/routes/users/accounts.py:288
|
||||
msgid "Only the president can create users."
|
||||
msgstr "Only the president can create users."
|
||||
|
||||
#: app/routes/users.py:464
|
||||
#: app/routes/users/accounts.py:336
|
||||
#, python-format
|
||||
msgid "User %(full_name)s created as %(role)s!"
|
||||
msgstr "User %(full_name)s created as %(role)s!"
|
||||
|
||||
#: app/routes/users.py:534
|
||||
msgid "Username already taken."
|
||||
msgstr "Username already taken."
|
||||
#: app/routes/users/availability.py:179
|
||||
msgid "Only coaches can manage availability."
|
||||
msgstr "Only coaches can manage availability."
|
||||
|
||||
#: app/routes/users.py:544
|
||||
msgid "Email already in use."
|
||||
msgstr "Email already in use."
|
||||
|
||||
#: app/routes/users.py:574
|
||||
msgid "Profile updated successfully!"
|
||||
msgstr "Profile updated successfully!"
|
||||
|
||||
#: app/routes/users.py:809
|
||||
#: app/routes/users/contracts.py:83
|
||||
msgid "Only presidents, managers, and coaches can upload contracts."
|
||||
msgstr "Only presidents, managers, and coaches can upload contracts."
|
||||
|
||||
#: app/routes/users.py:828
|
||||
#: app/routes/users/contracts.py:102
|
||||
msgid "You do not have permission to upload a contract for this player."
|
||||
msgstr "You do not have permission to upload a contract for this player."
|
||||
|
||||
#: app/routes/users.py:869
|
||||
#: app/routes/users/contracts.py:143
|
||||
#, python-format
|
||||
msgid "Contract uploaded successfully for %(username)s!"
|
||||
msgstr "Contract uploaded successfully for %(username)s!"
|
||||
|
||||
#: app/routes/users.py:883
|
||||
#: app/routes/users/contracts.py:157
|
||||
msgid "Only the player can upload their signed contract."
|
||||
msgstr "Only the player can upload their signed contract."
|
||||
|
||||
#: app/routes/users.py:902
|
||||
#: app/routes/users/contracts.py:176
|
||||
msgid "Signed contract uploaded successfully!"
|
||||
msgstr "Signed contract uploaded successfully!"
|
||||
|
||||
#: app/routes/users.py:912 app/routes/users.py:925
|
||||
#: app/routes/users/contracts.py:186 app/routes/users/contracts.py:199
|
||||
msgid "You do not have permission to download this contract."
|
||||
msgstr "You do not have permission to download this contract."
|
||||
|
||||
#: app/routes/users.py:928
|
||||
#: app/routes/users/contracts.py:202
|
||||
msgid "No signed contract available."
|
||||
msgstr "No signed contract available."
|
||||
|
||||
#: app/routes/users.py:1034
|
||||
msgid "Only players can request One on One sessions."
|
||||
msgstr "Only players can request One on One sessions."
|
||||
|
||||
#: app/routes/users.py:1047
|
||||
msgid "You do not have a coach assigned to your team."
|
||||
msgstr "You do not have a coach assigned to your team."
|
||||
|
||||
#: app/routes/users.py:1082
|
||||
msgid "Cannot request One on One - no coach assigned."
|
||||
msgstr "Cannot request One on One - no coach assigned."
|
||||
|
||||
#: app/routes/users.py:1090
|
||||
msgid "Invalid date or time format."
|
||||
msgstr "Invalid date or time format."
|
||||
|
||||
#: app/routes/users.py:1104
|
||||
msgid "The requested time is not within the coach's availability."
|
||||
msgstr "The requested time is not within the coach's availability."
|
||||
|
||||
#: app/routes/users.py:1132
|
||||
msgid "Your One on One request has been submitted!"
|
||||
msgstr "Your One on One request has been submitted!"
|
||||
|
||||
#: app/routes/users.py:1176
|
||||
msgid "Only coaches can accept One on One requests."
|
||||
msgstr "Only coaches can accept One on One requests."
|
||||
|
||||
#: app/routes/users.py:1182 app/routes/users.py:1232
|
||||
msgid "This request is not for you."
|
||||
msgstr "This request is not for you."
|
||||
|
||||
#: app/routes/users.py:1186 app/routes/users.py:1236
|
||||
msgid "This request has already been processed."
|
||||
msgstr "This request has already been processed."
|
||||
|
||||
#: app/routes/users.py:1213
|
||||
#, python-format
|
||||
msgid "One on One request from %(player)s has been approved!"
|
||||
msgstr "One on One request from %(player)s has been approved!"
|
||||
|
||||
#: app/routes/users.py:1226
|
||||
msgid "Only coaches can reject One on One requests."
|
||||
msgstr "Only coaches can reject One on One requests."
|
||||
|
||||
#: app/routes/users.py:1268
|
||||
#, python-format
|
||||
msgid "One on One request from %(player)s has been rejected."
|
||||
msgstr "One on One request from %(player)s has been rejected."
|
||||
|
||||
#: app/routes/users.py:1286
|
||||
#: app/routes/users/notes.py:34
|
||||
msgid "This page is for players only."
|
||||
msgstr "This page is for players only."
|
||||
|
||||
#: app/routes/users.py:1328
|
||||
msgid "Only coaches can manage availability."
|
||||
msgstr "Only coaches can manage availability."
|
||||
|
||||
#: app/routes/users.py:1394
|
||||
#: app/routes/users/notes.py:71
|
||||
msgid "Only coaches can access the notes dashboard."
|
||||
msgstr "Only coaches can access the notes dashboard."
|
||||
|
||||
#: app/routes/users.py:1484
|
||||
#: app/routes/users/notes.py:161
|
||||
msgid "Only coaches can manage team notes."
|
||||
msgstr "Only coaches can manage team notes."
|
||||
|
||||
#: app/routes/users.py:1490
|
||||
#: app/routes/users/notes.py:167
|
||||
msgid "You are not assigned to a team."
|
||||
msgstr "You are not assigned to a team."
|
||||
|
||||
#: app/routes/users.py:1503
|
||||
#: app/routes/users/notes.py:180
|
||||
msgid "Team notes saved successfully!"
|
||||
msgstr "Team notes saved successfully!"
|
||||
|
||||
#: app/routes/users.py:1518
|
||||
#: app/routes/users/notes.py:195
|
||||
msgid "Only coaches can manage personal notes."
|
||||
msgstr "Only coaches can manage personal notes."
|
||||
|
||||
#: app/routes/users.py:1525 app/routes/users.py:1568 app/routes/users.py:1619
|
||||
#: app/routes/users.py:1673
|
||||
#: app/routes/users/notes.py:202 app/routes/users/notes.py:245
|
||||
#: app/routes/users/notes.py:296 app/routes/users/notes.py:350
|
||||
msgid "Player and content are required."
|
||||
msgstr "Player and content are required."
|
||||
|
||||
#: app/routes/users.py:1534 app/routes/users.py:1577 app/routes/users.py:1623
|
||||
#: app/routes/users.py:1677
|
||||
#: app/routes/users/notes.py:211 app/routes/users/notes.py:254
|
||||
#: app/routes/users/notes.py:300 app/routes/users/notes.py:354
|
||||
msgid "You can only write notes about players you work with."
|
||||
msgstr "You can only write notes about players you work with."
|
||||
|
||||
#: app/routes/users.py:1544 app/routes/users.py:1590
|
||||
#: app/routes/users/notes.py:221 app/routes/users/notes.py:267
|
||||
#, python-format
|
||||
msgid "Note added for %(username)s."
|
||||
msgstr "Note added for %(username)s."
|
||||
|
||||
#: app/routes/users.py:1558 app/routes/users.py:1604 app/routes/users.py:1657
|
||||
#: app/routes/users/notes.py:235 app/routes/users/notes.py:281
|
||||
#: app/routes/users/notes.py:334
|
||||
msgid "Only coaches can add personal notes."
|
||||
msgstr "Only coaches can add personal notes."
|
||||
|
||||
#: app/routes/users.py:1634 app/routes/users.py:1688
|
||||
#: app/routes/users/notes.py:311 app/routes/users/notes.py:365
|
||||
msgid "Note added successfully."
|
||||
msgstr "Note added successfully."
|
||||
|
||||
#: app/routes/users/one_on_one.py:20
|
||||
msgid "Only players can request One on One sessions."
|
||||
msgstr "Only players can request One on One sessions."
|
||||
|
||||
#: app/routes/users/one_on_one.py:33
|
||||
msgid "You do not have a coach assigned to your team."
|
||||
msgstr "You do not have a coach assigned to your team."
|
||||
|
||||
#: app/routes/users/one_on_one.py:68
|
||||
msgid "Cannot request One on One - no coach assigned."
|
||||
msgstr "Cannot request One on One - no coach assigned."
|
||||
|
||||
#: app/routes/users/one_on_one.py:76
|
||||
msgid "Invalid date or time format."
|
||||
msgstr "Invalid date or time format."
|
||||
|
||||
#: app/routes/users/one_on_one.py:90
|
||||
msgid "The requested time is not within the coach's availability."
|
||||
msgstr "The requested time is not within the coach's availability."
|
||||
|
||||
#: app/routes/users/one_on_one.py:118
|
||||
msgid "Your One on One request has been submitted!"
|
||||
msgstr "Your One on One request has been submitted!"
|
||||
|
||||
#: app/routes/users/one_on_one.py:163
|
||||
msgid "Only coaches can accept One on One requests."
|
||||
msgstr "Only coaches can accept One on One requests."
|
||||
|
||||
#: app/routes/users/one_on_one.py:169 app/routes/users/one_on_one.py:219
|
||||
msgid "This request is not for you."
|
||||
msgstr "This request is not for you."
|
||||
|
||||
#: app/routes/users/one_on_one.py:173 app/routes/users/one_on_one.py:223
|
||||
msgid "This request has already been processed."
|
||||
msgstr "This request has already been processed."
|
||||
|
||||
#: app/routes/users/one_on_one.py:200
|
||||
#, python-format
|
||||
msgid "One on One request from %(player)s has been approved!"
|
||||
msgstr "One on One request from %(player)s has been approved!"
|
||||
|
||||
#: app/routes/users/one_on_one.py:213
|
||||
msgid "Only coaches can reject One on One requests."
|
||||
msgstr "Only coaches can reject One on One requests."
|
||||
|
||||
#: app/routes/users/one_on_one.py:255
|
||||
#, python-format
|
||||
msgid "One on One request from %(player)s has been rejected."
|
||||
msgstr "One on One request from %(player)s has been rejected."
|
||||
|
||||
#: app/routes/users/profile.py:83
|
||||
msgid "Username already taken."
|
||||
msgstr "Username already taken."
|
||||
|
||||
#: app/routes/users/profile.py:93
|
||||
msgid "Email already in use."
|
||||
msgstr "Email already in use."
|
||||
|
||||
#: app/routes/users/profile.py:123
|
||||
msgid "Profile updated successfully!"
|
||||
msgstr "Profile updated successfully!"
|
||||
|
||||
#: app/templates/errors/400.html:2
|
||||
msgid "400 Bad Request"
|
||||
msgstr "400 Bad Request"
|
||||
@@ -2372,11 +2374,7 @@ msgstr "Confirm Password"
|
||||
msgid "Confirm your password"
|
||||
msgstr "Confirm your password"
|
||||
|
||||
#: app/templates/pages/register.html:151
|
||||
msgid "Answer"
|
||||
msgstr "Answer"
|
||||
|
||||
#: app/templates/pages/register.html:154
|
||||
#: app/templates/pages/register.html:159
|
||||
msgid "Create Account"
|
||||
msgstr "Create Account"
|
||||
|
||||
@@ -2876,3 +2874,9 @@ msgstr "View Profile"
|
||||
#~ msgid "Login unsuccessful. %(remaining)s attempt(s) remaining before lockout."
|
||||
#~ msgstr "Login unsuccessful. %(remaining)s attempt(s) remaining before lockout."
|
||||
|
||||
#~ msgid "Incorrect CAPTCHA answer. Please try again."
|
||||
#~ msgstr "Incorrect CAPTCHA answer. Please try again."
|
||||
|
||||
#~ msgid "Answer"
|
||||
#~ msgstr "Answer"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user