fix: obfuscate email in contact links, raise rate limits, make Libre toggleable

- about.php: use EmailObfuscator::email() for contact email link text instead of htmlspecialchars
- SearchController: raise rate limit from 30 to 300 req/min
- request-access.php: raise rate limit from 3 to 30 req/10min
- partage/index.php: raise rate limit from 5 to 50 req/10min
- contenus.php: make Libre option toggleable (remove disabled class), move to top of Degré d'ouverture, remove temporary note about next academic year
This commit is contained in:
Pontoporeia
2026-05-10 23:40:27 +02:00
parent 2bacc78492
commit 48da914bc8
7 changed files with 29 additions and 14 deletions

View File

@@ -471,7 +471,7 @@ function handleShareLinkSubmission(string $slug): void
// 5 submissions per IP per 10 minutes, keyed per share link.
$rateLimitCacheDir = STORAGE_ROOT . '/cache/rate_limit';
$shareRateLimitId = 'share_' . $slug . '_' . ($_SERVER['REMOTE_ADDR'] ?? 'unknown');
$rateLimit = new RateLimit(5, 600, $rateLimitCacheDir);
$rateLimit = new RateLimit(50, 600, $rateLimitCacheDir);
if (!$rateLimit->checkKey($shareRateLimitId)) {
$_SESSION['_flash_error'] = 'Trop de tentatives. Veuillez réessayer plus tard.';

View File

@@ -88,7 +88,7 @@ if ($accessTypeId !== 2) {
// Rate limiting: max 3 requests per 10 minutes per IP
$rateLimitKey = 'access_request_' . ($_SERVER['REMOTE_ADDR'] ?? 'unknown');
if (!(new RateLimit(3, 600))->checkKey($rateLimitKey)) {
if (!(new RateLimit(30, 600))->checkKey($rateLimitKey)) {
http_response_code(429);
echo json_encode(['success' => false, 'message' => 'Trop de requêtes. Veuillez réessayer dans quelques minutes.']);
exit;

View File

@@ -22,7 +22,7 @@
*/
class SearchController
{
private const RATE_LIMIT_MAX = 30;
private const RATE_LIMIT_MAX = 300;
private const RATE_LIMIT_WINDOW = 60; // seconds
private const ITEMS_PER_PAGE = 30;

View File

@@ -532,6 +532,19 @@
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
+\\\\\\\ to: ryqustol a5179270 "import dialog: add Terminé button, fix padding, make success permanent, avoid POST resend" (rebased revision)
++ $linkName = $link['name'] ?? '';
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: ryqustol a5179270 "import dialog: add Terminé button, fix padding, make success permanent, avoid POST resend" (rebased revision)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
- $linkName = $link['name'] ?? '';
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: nqmqrqmo 2b244c73 "fix: obfuscate email in contact links, raise rate limits, make Libre toggleable" (rebased revision)
$linkName = $link['name'] ?? '';
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
$linkLockedYear = $link['locked_year'] ?? null;
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
+\\\\\\\ to: nqmqrqmo dd511b0d "fix: obfuscate email in contact links, raise rate limits, make Libre toggleable" (rebased revision)
++ $linkName = $link['name'] ?? '';
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
?>
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">

View File

@@ -108,18 +108,17 @@
<fieldset>
<legend>Degré d'ouverture</legend>
<p>Options de visibilité disponibles dans le formulaire d'ajout de TFE.</p>
<p class="param-note">L'option <strong>Libre</strong> ne sera activée qu'à partir de l'année académique prochaine.</p>
<form method="post" action="actions/settings.php" class="param-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="section" value="formulaire">
<label class="param-checkbox">
<input type="checkbox" name="access_type_interdit_enabled" value="1"
<?= ($siteSettings['access_type_interdit_enabled'] ?? '1') === '1' ? 'checked' : '' ?>>
<input type="checkbox" name="access_type_libre_enabled" value="1"
<?= ($siteSettings['access_type_libre_enabled'] ?? '0') === '1' ? 'checked' : '' ?>>
<span>
<strong>Interdit</strong><br>
<small>TFE non disponible en physique ni sur le site</small>
<strong>Libre</strong><br>
<small>Libre accès — TFE accessible publiquement sur la plateforme et en bibliothèque</small>
</span>
</label>
@@ -132,12 +131,12 @@
</span>
</label>
<label class="param-checkbox param-checkbox--disabled">
<input type="checkbox" name="access_type_libre_enabled" value="1"
<?= ($siteSettings['access_type_libre_enabled'] ?? '0') === '1' ? 'checked' : '' ?>>
<label class="param-checkbox">
<input type="checkbox" name="access_type_interdit_enabled" value="1"
<?= ($siteSettings['access_type_interdit_enabled'] ?? '1') === '1' ? 'checked' : '' ?>>
<span>
<strong>Libre</strong><br>
<small>Libre accès — disponible à partir de l'année académique prochaine</small>
<strong>Interdit</strong><br>
<small>TFE non disponible en physique ni sur le site</small>
</span>
</label>

View File

@@ -83,7 +83,7 @@ function renderEntries(array $entries): string
fn($e) => !empty($e),
);
foreach ($emails as $email): ?>
<a href="<?= EmailObfuscator::mailto($email) ?>"><?= htmlspecialchars($email) ?></a>
<a href="<?= EmailObfuscator::mailto($email) ?>"><?= EmailObfuscator::email($email) ?></a>
<?php endforeach;
?>
</address>