diff --git a/TODO.md b/TODO.md index 6b096a7..379b2ab 100644 --- a/TODO.md +++ b/TODO.md @@ -28,6 +28,6 @@ - [x] Implement delete link action - [x] Copy-to-clipboard button for full partage URL -- [ ] Security and validation considerations - - [ ] Rate limiting on form submissions per share link - - [ ] Add flash messages / error handling for invalid/disabled/password-protected links +- [x] Security and validation considerations + - [x] Rate limiting on form submissions per share link — integrate RateLimit into partage index.php POST handler + - [x] Add flash messages / error handling for invalid/disabled/password-protected links — replace plain die() with styled error pages and flash messages diff --git a/public/partage/index.php b/public/partage/index.php index 217a105..8ff726b 100644 --- a/public/partage/index.php +++ b/public/partage/index.php @@ -23,8 +23,10 @@ $action = $parts[1] ?? ''; // Validate slug format: YYYYMMDD-XXXXXXXX (17 chars) if (!preg_match('/^\d{8}-[A-Z2-7]{8}$/', $slug)) { - http_response_code(404); - die('Lien invalide.'); + App::boot(); + $_SESSION['_flash_error'] = 'Ce lien de partage n\'est pas valide.'; + header('Location: /'); + exit; } // ── POST: form submission ───────────────────────────────────────────────────── @@ -45,18 +47,19 @@ if (!$validationResult['valid']) { $reason = $validationResult['reason']; if ($reason === 'not_found') { - http_response_code(404); - die('Ce lien de partage n\'existe pas ou a été supprimé.'); + $_SESSION['_flash_error'] = 'Ce lien de partage n\'existe pas ou a été supprimé.'; + header('Location: /'); + exit; } if ($reason === 'disabled') { - http_response_code(403); - die('Ce lien de partage a été désactivé.'); + renderShareLinkError('Lien désactivé', 'Ce lien de partage a été désactivé par un administrateur.'); + exit; } if ($reason === 'expired') { - http_response_code(403); - die('Ce lien de partage a expiré.'); + renderShareLinkError('Lien expiré', 'Ce lien de partage a expiré.'); + exit; } if ($reason === 'needs_password') { @@ -66,8 +69,9 @@ if (!$validationResult['valid']) { exit; } - http_response_code(400); - die('Erreur inattendue.'); + $_SESSION['_flash_error'] = 'Erreur inattendue.'; + header('Location: /'); + exit; } // Link is valid — render the form @@ -76,10 +80,66 @@ renderShareLinkForm($slug, $link); // ── Functions ───────────────────────────────────────────────────────────────── +/** + * Render a styled error page for invalid/expired/disabled share links. + */ +function renderShareLinkError(string $title, string $message): void +{ + $pageTitle = htmlspecialchars($title); + ?> + + +
+ + += htmlspecialchars($error) ?>
+ += htmlspecialchars($flashError) ?>