| 
									
										
										
										
											2025-02-17 13:05:44 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require_once __DIR__ . '/../classes/ratelimiter.php'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Rate limit middleware for page requests | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * @param Database $database Database connection | 
					
						
							|  |  |  |  * @param string $endpoint The endpoint being accessed | 
					
						
							|  |  |  |  * @param int|null $userId Current user ID if authenticated | 
					
						
							|  |  |  |  * @return bool True if request is allowed, false if rate limited | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function checkRateLimit($database, $endpoint, $userId = null) { | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |     $isTest = defined('PHPUNIT_RUNNING'); | 
					
						
							| 
									
										
										
										
											2025-02-21 09:44:52 +00:00
										 |  |  |     $rateLimiter = new RateLimiter($database); | 
					
						
							| 
									
										
										
										
											2025-02-17 13:05:44 +00:00
										 |  |  |     $ipAddress = $_SERVER['REMOTE_ADDR']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Check if request is allowed
 | 
					
						
							|  |  |  |     if (!$rateLimiter->isPageRequestAllowed($ipAddress, $endpoint, $userId)) { | 
					
						
							|  |  |  |         // Get remaining requests for error message
 | 
					
						
							|  |  |  |         $remaining = $rateLimiter->getRemainingPageRequests($ipAddress, $endpoint, $userId); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |         if (!$isTest) { | 
					
						
							|  |  |  |             // Set rate limit headers
 | 
					
						
							|  |  |  |             header('X-RateLimit-Remaining: ' . $remaining); | 
					
						
							|  |  |  |             header('X-RateLimit-Reset: ' . (time() + 60)); // Reset in 1 minute
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Return 429 Too Many Requests
 | 
					
						
							|  |  |  |             http_response_code(429); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // If AJAX request, return JSON
 | 
					
						
							|  |  |  |             if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&  | 
					
						
							|  |  |  |                 strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { | 
					
						
							|  |  |  |                 header('Content-Type: application/json'); | 
					
						
							|  |  |  |                 echo json_encode([ | 
					
						
							|  |  |  |                     'success' => false, | 
					
						
							|  |  |  |                     'message' => 'Too many requests. Please try again in a minute.', | 
					
						
							|  |  |  |                     'messageData' => Feedback::getMessageData('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true) | 
					
						
							|  |  |  |                 ]); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 // For regular requests, set flash message and redirect
 | 
					
						
							|  |  |  |                 Feedback::flash('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true); | 
					
						
							|  |  |  |                 header('Location: ' . htmlspecialchars($app_root)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             exit; | 
					
						
							| 
									
										
										
										
											2025-02-17 13:05:44 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // In test mode, just set the flash message
 | 
					
						
							|  |  |  |         Feedback::flash('ERROR', 'DEFAULT', 'Too many requests. Please try again in a minute.', true); | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2025-02-17 13:05:44 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Record this request
 | 
					
						
							|  |  |  |     $rateLimiter->recordPageRequest($ipAddress, $endpoint); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } |