| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  | <!-- security settings --> | 
					
						
							|  |  |  | <div class="container-fluid mt-2"> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |     <div class="row mb-4"> | 
					
						
							|  |  |  |         <div class="col"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |             <h2>Security settings</h2> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |             <ul class="nav nav-tabs"> | 
					
						
							|  |  |  |                 <?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist')) { ?>
 | 
					
						
							|  |  |  |                 <li class="nav-item"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                     <a class="nav-link <?= $section === 'whitelist' ? 'active' : '' ?>" href="?page=security§ion=whitelist">IP whitelist</a> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                 </li> | 
					
						
							|  |  |  |                 <?php } ?>
 | 
					
						
							|  |  |  |                 <?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist')) { ?>
 | 
					
						
							|  |  |  |                 <li class="nav-item"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                     <a class="nav-link <?= $section === 'blacklist' ? 'active' : '' ?>" href="?page=security§ion=blacklist">IP blacklist</a> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                 </li> | 
					
						
							|  |  |  |                 <?php } ?>
 | 
					
						
							|  |  |  |                 <?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting')) { ?>
 | 
					
						
							|  |  |  |                 <li class="nav-item"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                     <a class="nav-link <?= $section === 'ratelimit' ? 'active' : '' ?>" href="?page=security§ion=ratelimit">Rate limiting</a> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                 </li> | 
					
						
							|  |  |  |                 <?php } ?>
 | 
					
						
							|  |  |  |             </ul> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <?php if ($section === 'whitelist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist'))) { ?>
 | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |     <!-- whitelist section --> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |     <div class="row mb-4"> | 
					
						
							|  |  |  |         <div class="col"> | 
					
						
							|  |  |  |             <div class="card"> | 
					
						
							|  |  |  |                 <div class="card-header"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                     <h3>IP whitelist</h3> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                     IP addresses and networks that will always bypass the ratelimiting login checks. | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |                 <div class="card-body"> | 
					
						
							|  |  |  |                     <form method="POST" class="mb-4"> | 
					
						
							|  |  |  |                         <input type="hidden" name="action" value="add_whitelist"> | 
					
						
							|  |  |  |                         <div class="row g-3"> | 
					
						
							|  |  |  |                             <div class="col-md-4"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <input type="text" class="form-control" name="ip_address" placeholder="IP address or CIDR" required> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                             </div> | 
					
						
							|  |  |  |                             <div class="col-md-4"> | 
					
						
							|  |  |  |                                 <input type="text" class="form-control" name="description" placeholder="Description"> | 
					
						
							|  |  |  |                             </div> | 
					
						
							|  |  |  |                             <div class="col-md-2"> | 
					
						
							|  |  |  |                                 <div class="form-check"> | 
					
						
							|  |  |  |                                     <input type="checkbox" class="form-check-input" name="is_network" id="is_network_white"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                     <label class="form-check-label" for="is_network_white">is network</label> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                                 </div> | 
					
						
							|  |  |  |                             </div> | 
					
						
							|  |  |  |                             <div class="col-md-2"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <button type="submit" class="btn btn-primary">Add to whitelist</button> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                             </div> | 
					
						
							|  |  |  |                         </div> | 
					
						
							|  |  |  |                     </form> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     <table class="table"> | 
					
						
							|  |  |  |                         <thead> | 
					
						
							|  |  |  |                             <tr> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <th>IP address</th> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                                 <th>Network</th> | 
					
						
							|  |  |  |                                 <th>Description</th> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <th>Added by</th> | 
					
						
							|  |  |  |                                 <th>Added on</th> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                                 <th>Actions</th> | 
					
						
							|  |  |  |                             </tr> | 
					
						
							|  |  |  |                         </thead> | 
					
						
							|  |  |  |                         <tbody> | 
					
						
							|  |  |  |                             <?php foreach ($whitelisted as $ip) { ?>
 | 
					
						
							|  |  |  |                             <tr> | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['ip_address']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= $ip['is_network'] ? 'Yes' : 'No' ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['description']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['created_by']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['created_at']) ?></td>
 | 
					
						
							|  |  |  |                                 <td> | 
					
						
							|  |  |  |                                     <form method="POST" style="display: inline;"> | 
					
						
							|  |  |  |                                         <input type="hidden" name="action" value="remove_whitelist"> | 
					
						
							|  |  |  |                                         <input type="hidden" name="ip_address" value="<?= htmlspecialchars($ip['ip_address']) ?>"> | 
					
						
							|  |  |  |                                         <button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure you want to remove this IP from whitelist?')">Remove</button> | 
					
						
							|  |  |  |                                     </form> | 
					
						
							|  |  |  |                                 </td> | 
					
						
							|  |  |  |                             </tr> | 
					
						
							|  |  |  |                             <?php } ?>
 | 
					
						
							|  |  |  |                         </tbody> | 
					
						
							|  |  |  |                     </table> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <?php } ?>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <?php if ($section === 'blacklist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist'))) { ?>
 | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |     <!-- blacklist section --> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |     <div class="row mb-4"> | 
					
						
							|  |  |  |         <div class="col"> | 
					
						
							|  |  |  |             <div class="card"> | 
					
						
							|  |  |  |                 <div class="card-header"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                     <h3>IP blacklist</h3> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                     IP addresses and networks that will always get blocked at login. | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |                 <div class="card-body"> | 
					
						
							|  |  |  |                     <form method="POST" class="mb-4"> | 
					
						
							|  |  |  |                         <input type="hidden" name="action" value="add_blacklist"> | 
					
						
							|  |  |  |                         <div class="row g-3"> | 
					
						
							|  |  |  |                             <div class="col-md-3"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <input type="text" class="form-control" name="ip_address" placeholder="IP address or CIDR" required> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                             </div> | 
					
						
							|  |  |  |                             <div class="col-md-3"> | 
					
						
							|  |  |  |                                 <input type="text" class="form-control" name="reason" placeholder="Reason"> | 
					
						
							|  |  |  |                             </div> | 
					
						
							|  |  |  |                             <div class="col-md-2"> | 
					
						
							|  |  |  |                                 <input type="number" class="form-control" name="expiry_hours" placeholder="Expiry (hours)"> | 
					
						
							|  |  |  |                             </div> | 
					
						
							|  |  |  |                             <div class="col-md-2"> | 
					
						
							|  |  |  |                                 <div class="form-check"> | 
					
						
							|  |  |  |                                     <input type="checkbox" class="form-check-input" name="is_network" id="is_network_black"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                     <label class="form-check-label" for="is_network_black">is network</label> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                                 </div> | 
					
						
							|  |  |  |                             </div> | 
					
						
							|  |  |  |                             <div class="col-md-2"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <button type="submit" class="btn btn-primary">Add to blacklist</button> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                             </div> | 
					
						
							|  |  |  |                         </div> | 
					
						
							|  |  |  |                     </form> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     <table class="table"> | 
					
						
							|  |  |  |                         <thead> | 
					
						
							|  |  |  |                             <tr> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <th>IP address</th> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                                 <th>Network</th> | 
					
						
							|  |  |  |                                 <th>Reason</th> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <th>Added by</th> | 
					
						
							|  |  |  |                                 <th>Added on</th> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                                 <th>Expires</th> | 
					
						
							|  |  |  |                                 <th>Actions</th> | 
					
						
							|  |  |  |                             </tr> | 
					
						
							|  |  |  |                         </thead> | 
					
						
							|  |  |  |                         <tbody> | 
					
						
							|  |  |  |                             <?php foreach ($blacklisted as $ip) { ?>
 | 
					
						
							|  |  |  |                             <tr> | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['ip_address']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= $ip['is_network'] ? 'Yes' : 'No' ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['reason']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['created_by']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($ip['created_at']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= $ip['expiry_time'] ? htmlspecialchars($ip['expiry_time']) : 'Never' ?></td>
 | 
					
						
							|  |  |  |                                 <td> | 
					
						
							|  |  |  |                                     <form method="POST" style="display: inline;"> | 
					
						
							|  |  |  |                                         <input type="hidden" name="action" value="remove_blacklist"> | 
					
						
							|  |  |  |                                         <input type="hidden" name="ip_address" value="<?= htmlspecialchars($ip['ip_address']) ?>"> | 
					
						
							|  |  |  |                                         <button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure you want to remove this IP from blacklist?')">Remove</button> | 
					
						
							|  |  |  |                                     </form> | 
					
						
							|  |  |  |                                 </td> | 
					
						
							|  |  |  |                             </tr> | 
					
						
							|  |  |  |                             <?php } ?>
 | 
					
						
							|  |  |  |                         </tbody> | 
					
						
							|  |  |  |                     </table> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <?php } ?>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <?php if ($section === 'ratelimit' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting'))) { ?>
 | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |     <!-- rate limiting section --> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |     <div class="row mb-4"> | 
					
						
							|  |  |  |         <div class="col"> | 
					
						
							|  |  |  |             <div class="card"> | 
					
						
							|  |  |  |                 <div class="card-header"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                     <h3>Rate limiting settings</h3> | 
					
						
							| 
									
										
										
										
											2025-01-06 09:13:28 +00:00
										 |  |  |                     Rate limiting settings control how many failed login attempts are allowed before blocking an IP address. | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                 </div> | 
					
						
							|  |  |  |                 <div class="card-body"> | 
					
						
							|  |  |  |                     <div class="alert alert-info"> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                         <h4>Current settings</h4> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                         <ul> | 
					
						
							|  |  |  |                             <li>Maximum login attempts: <?= $rateLimiter->maxAttempts ?></li>
 | 
					
						
							|  |  |  |                             <li>Time window: <?= $rateLimiter->decayMinutes ?> minutes</li>
 | 
					
						
							|  |  |  |                             <li>Auto-blacklist threshold: <?= $rateLimiter->autoBlacklistThreshold ?> attempts</li>
 | 
					
						
							|  |  |  |                             <li>Auto-blacklist duration: <?= $rateLimiter->autoBlacklistDuration ?> hours</li>
 | 
					
						
							|  |  |  |                         </ul> | 
					
						
							|  |  |  |                         <p class="mb-0"> | 
					
						
							|  |  |  |                             <small>Note: These settings can be modified in the RateLimiter class configuration.</small> | 
					
						
							|  |  |  |                         </p> | 
					
						
							|  |  |  |                     </div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                     <h4>Recent failed login attempts</h4> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                     <table class="table"> | 
					
						
							|  |  |  |                         <thead> | 
					
						
							|  |  |  |                             <tr> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <th>IP sddress</th> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                                 <th>Username</th> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  |                                 <th>Attempted at</th> | 
					
						
							| 
									
										
										
										
											2025-01-04 10:30:44 +00:00
										 |  |  |                             </tr> | 
					
						
							|  |  |  |                         </thead> | 
					
						
							|  |  |  |                         <tbody> | 
					
						
							|  |  |  |                             <?php | 
					
						
							|  |  |  |                             $stmt = $rateLimiter->db->prepare("
 | 
					
						
							|  |  |  |                                 SELECT ip_address, username, attempted_at  | 
					
						
							|  |  |  |                                 FROM {$rateLimiter->ratelimitTable}  | 
					
						
							|  |  |  |                                 ORDER BY attempted_at DESC  | 
					
						
							|  |  |  |                                 LIMIT 10 | 
					
						
							|  |  |  |                             ");
 | 
					
						
							|  |  |  |                             $stmt->execute(); | 
					
						
							|  |  |  |                             $attempts = $stmt->fetchAll(PDO::FETCH_ASSOC); | 
					
						
							|  |  |  |                             foreach ($attempts as $attempt) { | 
					
						
							|  |  |  |                             ?>
 | 
					
						
							|  |  |  |                             <tr> | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($attempt['ip_address']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($attempt['username']) ?></td>
 | 
					
						
							|  |  |  |                                 <td><?= htmlspecialchars($attempt['attempted_at']) ?></td>
 | 
					
						
							|  |  |  |                             </tr> | 
					
						
							|  |  |  |                             <?php } ?>
 | 
					
						
							|  |  |  |                         </tbody> | 
					
						
							|  |  |  |                     </table> | 
					
						
							|  |  |  |                 </div> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <?php } ?>
 | 
					
						
							|  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2025-01-17 14:08:37 +00:00
										 |  |  | <!-- /security settings --> |