diff --git a/app/classes/messages.php b/app/classes/messages.php
index a336820..5f1c44e 100644
--- a/app/classes/messages.php
+++ b/app/classes/messages.php
@@ -7,106 +7,136 @@ class Messages {
const TYPE_INFO = 'info';
const TYPE_WARNING = 'warning';
- // Message categories
- const SECURITY = [
- 'WHITELIST_ADD_SUCCESS' => [
- 'message' => 'IP address successfully added to whitelist.',
- 'type' => self::TYPE_SUCCESS,
- 'dismissible' => true
- ],
- 'WHITELIST_ADD_ERROR' => [
- 'message' => 'Failed to add IP to whitelist. Please check the IP format.',
- 'type' => self::TYPE_ERROR,
- 'dismissible' => true
- ],
- 'WHITELIST_REMOVE_SUCCESS' => [
- 'message' => 'IP address successfully removed from whitelist.',
- 'type' => self::TYPE_SUCCESS,
- 'dismissible' => true
- ],
- 'WHITELIST_REMOVE_ERROR' => [
- 'message' => 'Failed to remove IP from whitelist.',
- 'type' => self::TYPE_ERROR,
- 'dismissible' => true
- ],
- 'BLACKLIST_ADD_SUCCESS' => [
- 'message' => 'IP address successfully added to blacklist.',
- 'type' => self::TYPE_SUCCESS,
- 'dismissible' => true
- ],
- 'BLACKLIST_ADD_ERROR' => [
- 'message' => 'Failed to add IP to blacklist. Please check the IP format.',
- 'type' => self::TYPE_ERROR,
- 'dismissible' => true
- ],
- 'BLACKLIST_REMOVE_SUCCESS' => [
- 'message' => 'IP address successfully removed from blacklist.',
- 'type' => self::TYPE_SUCCESS,
- 'dismissible' => true
- ],
- 'BLACKLIST_REMOVE_ERROR' => [
- 'message' => 'Failed to remove IP from blacklist.',
- 'type' => self::TYPE_ERROR,
- 'dismissible' => true
- ],
- 'IP_REQUIRED' => [
- 'message' => 'IP address is required.',
- 'type' => self::TYPE_ERROR,
- 'dismissible' => true
- ],
- 'PERMISSION_DENIED' => [
- 'message' => 'You do not have permission to perform this action.',
- 'type' => self::TYPE_ERROR,
- 'dismissible' => false
- ],
- 'RATE_LIMIT_INFO' => [
- 'message' => 'Rate limiting is active. This helps protect against brute force attacks.',
+ // Default message configurations
+ const NOTICE = [
+ 'DEFAULT' => [
'type' => self::TYPE_INFO,
+ 'dismissible' => true
+ ]
+ ];
+
+ const ERROR = [
+ 'DEFAULT' => [
+ 'type' => self::TYPE_ERROR,
'dismissible' => false
]
];
const LOGIN = [
- 'LOGIN_FAILED' => [
- 'message' => 'Invalid username or password.',
- 'type' => self::TYPE_ERROR,
+ 'LOGIN_SUCCESS' => [
+ 'type' => self::TYPE_SUCCESS,
'dismissible' => true
],
- 'LOGIN_BLOCKED' => [
- 'message' => 'Too many failed attempts. Please try again later.',
+ 'LOGIN_FAILED' => [
'type' => self::TYPE_ERROR,
'dismissible' => false
],
+ 'LOGOUT_SUCCESS' => [
+ 'type' => self::TYPE_SUCCESS,
+ 'dismissible' => true
+ ],
'IP_BLACKLISTED' => [
- 'message' => 'Access denied. Your IP address is blacklisted.',
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => false
+ ],
+ 'IP_NOT_WHITELISTED' => [
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => false
+ ],
+ 'TOO_MANY_ATTEMPTS' => [
'type' => self::TYPE_ERROR,
'dismissible' => false
]
];
+ const SECURITY = [
+ 'WHITELIST_ADD_SUCCESS' => [
+ 'type' => self::TYPE_SUCCESS,
+ 'dismissible' => true
+ ],
+ 'WHITELIST_ADD_ERROR' => [
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => true
+ ],
+ 'WHITELIST_REMOVE_SUCCESS' => [
+ 'type' => self::TYPE_SUCCESS,
+ 'dismissible' => true
+ ],
+ 'WHITELIST_REMOVE_ERROR' => [
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => true
+ ],
+ 'BLACKLIST_ADD_SUCCESS' => [
+ 'type' => self::TYPE_SUCCESS,
+ 'dismissible' => true
+ ],
+ 'BLACKLIST_ADD_ERROR' => [
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => true
+ ],
+ 'BLACKLIST_REMOVE_SUCCESS' => [
+ 'type' => self::TYPE_SUCCESS,
+ 'dismissible' => true
+ ],
+ 'BLACKLIST_REMOVE_ERROR' => [
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => true
+ ],
+ 'RATE_LIMIT_INFO' => [
+ 'type' => self::TYPE_INFO,
+ 'dismissible' => false
+ ],
+ 'PERMISSION_DENIED' => [
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => false
+ ],
+ 'IP_REQUIRED' => [
+ 'type' => self::TYPE_ERROR,
+ 'dismissible' => false
+ ]
+ ];
+
+ private static $strings = null;
+
+ /**
+ * Get message strings
+ */
+ private static function getStrings() {
+ if (self::$strings === null) {
+ self::$strings = require __DIR__ . '/../includes/messages-strings.php';
+ }
+ return self::$strings;
+ }
+
/**
* Get message configuration by key
*/
public static function get($category, $key) {
- $messages = constant("self::$category");
- return $messages[$key] ?? null;
+ $config = constant("self::$category")[$key] ?? null;
+ if (!$config) return null;
+
+ $strings = self::getStrings();
+ $message = $strings[$category][$key] ?? '';
+
+ return array_merge($config, ['message' => $message]);
}
/**
* Render message HTML
*/
- public static function render($category, $key, $customMessage = null) {
+ public static function render($category, $key, $customMessage = null, $dismissible = null) {
$config = self::get($category, $key);
if (!$config) return '';
$message = $customMessage ?? $config['message'];
- $dismissible = $config['dismissible'] ? ' alert-dismissible fade show' : '';
- $dismissButton = $config['dismissible'] ? '' : '';
+ $isDismissible = $dismissible ?? $config['dismissible'];
+ $dismissClass = $isDismissible ? ' alert-dismissible fade show' : '';
+ $dismissButton = $isDismissible ? '' : '';
return sprintf(
'
%s%s
',
$config['type'],
- $dismissible,
+ $dismissClass,
htmlspecialchars($message),
$dismissButton
);
@@ -115,14 +145,15 @@ class Messages {
/**
* Store message in session for display after redirect
*/
- public static function flash($category, $key, $customMessage = null) {
+ public static function flash($category, $key, $customMessage = null, $dismissible = null) {
if (!isset($_SESSION['flash_messages'])) {
$_SESSION['flash_messages'] = [];
}
$_SESSION['flash_messages'][] = [
'category' => $category,
'key' => $key,
- 'custom_message' => $customMessage
+ 'custom_message' => $customMessage,
+ 'dismissible' => $dismissible
];
}
diff --git a/app/classes/ratelimiter.php b/app/classes/ratelimiter.php
index 42dfa1d..a3e3b85 100644
--- a/app/classes/ratelimiter.php
+++ b/app/classes/ratelimiter.php
@@ -3,8 +3,8 @@
class RateLimiter {
public $db;
private $log;
- public $maxAttempts = 5; // Maximum login attempts
- public $decayMinutes = 15; // Time window in minutes
+ public $maxAttempts = 5; // Maximum login attempts
+ public $decayMinutes = 15; // Time window in minutes
public $autoBlacklistThreshold = 10; // Attempts before auto-blacklist
public $autoBlacklistDuration = 24; // Hours to blacklist for
public $ratelimitTable = 'login_attempts';
@@ -22,7 +22,7 @@ class RateLimiter {
// Login attempts table
$sql = "CREATE TABLE IF NOT EXISTS {$this->ratelimitTable} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
- ip_address TEXT NOT NULL,
+ ip_address TEXT NOT NULL UNIQUE,
username TEXT NOT NULL,
attempted_at TEXT DEFAULT (DATETIME('now'))
)";
@@ -45,7 +45,7 @@ class RateLimiter {
ip_address TEXT NOT NULL UNIQUE,
is_network BOOLEAN DEFAULT 0 CHECK(is_network IN (0,1)),
reason TEXT,
- expiry_time TEXT NULL,
+ expiry_time TEXT NULL,
created_at TEXT DEFAULT (DATETIME('now')),
created_by TEXT
)";
@@ -53,11 +53,11 @@ class RateLimiter {
// Default IPs to whitelist (local interface and private networks IPs)
$defaultIps = [
- ['127.0.0.1', 0, 'localhost IPv4'],
- ['::1', 0, 'localhost IPv6'],
- ['10.0.0.0/8', 1, 'Private network (Class A)'],
- ['172.16.0.0/12', 1, 'Private network (Class B)'],
- ['192.168.0.0/16', 1, 'Private network (Class C)']
+ ['127.0.0.1', false, 'localhost IPv4'],
+ ['::1', false, 'localhost IPv6'],
+ ['10.0.0.0/8', true, 'Private network (Class A)'],
+ ['172.16.0.0/12', true, 'Private network (Class B)'],
+ ['192.168.0.0/16', true, 'Private network (Class C)']
];
// Insert default whitelisted IPs if they don't exist
@@ -70,11 +70,11 @@ class RateLimiter {
// Insert known malicious networks
$defaultBlacklist = [
- ['0.0.0.0/8', 1, 'Reserved address space - RFC 1122'],
- ['100.64.0.0/10', 1, 'Carrier-grade NAT space - RFC 6598'],
- ['192.0.2.0/24', 1, 'TEST-NET-1 Documentation space - RFC 5737'],
- ['198.51.100.0/24', 1, 'TEST-NET-2 Documentation space - RFC 5737'],
- ['203.0.113.0/24', 1, 'TEST-NET-3 Documentation space - RFC 5737']
+ ['0.0.0.0/8', true, 'Reserved address space - RFC 1122'],
+ ['100.64.0.0/10', true, 'Carrier-grade NAT space - RFC 6598'],
+ ['192.0.2.0/24', true, 'TEST-NET-1 Documentation space - RFC 5737'],
+ ['198.51.100.0/24', true, 'TEST-NET-2 Documentation space - RFC 5737'],
+ ['203.0.113.0/24', true, 'TEST-NET-3 Documentation space - RFC 5737']
];
$stmt = $this->db->prepare("INSERT OR IGNORE INTO {$this->blacklistTable}
@@ -87,27 +87,21 @@ class RateLimiter {
}
- private function isIpWhitelisted($ip) {
- // Check exact IP match and CIDR ranges
- $stmt = $this->db->prepare("SELECT ip_address, is_network FROM {$this->whitelistTable}");
- $stmt->execute();
-
- while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
- if ($row['is_network']) {
- if ($this->ipInRange($ip, $row['ip_address'])) {
- return true;
- }
- } else {
- if ($ip === $row['ip_address']) {
- return true;
- }
- }
- }
-
- return false;
+ /**
+ * Get number of recent login attempts for an IP
+ */
+ public function getRecentAttempts($ip) {
+ $stmt = $this->db->prepare("SELECT COUNT(*) as attempts FROM {$this->ratelimitTable}
+ WHERE ip_address = ? AND attempted_at > datetime('now', '-' || :minutes || ' minutes')");
+ $stmt->execute([$ip, $this->decayMinutes]);
+ $result = $stmt->fetch(PDO::FETCH_ASSOC);
+ return intval($result['attempts']);
}
- private function isIpBlacklisted($ip) {
+ /**
+ * Check if an IP is blacklisted
+ */
+ public function isIpBlacklisted($ip) {
// First check if IP is explicitly blacklisted or in a blacklisted range
$stmt = $this->db->prepare("SELECT ip_address, is_network, expiry_time FROM {$this->blacklistTable}");
$stmt->execute();
@@ -132,6 +126,29 @@ class RateLimiter {
return false;
}
+ /**
+ * Check if an IP is whitelisted
+ */
+ public function isIpWhitelisted($ip) {
+ // Check exact IP match and CIDR ranges
+ $stmt = $this->db->prepare("SELECT ip_address, is_network FROM {$this->whitelistTable}");
+ $stmt->execute();
+
+ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['is_network']) {
+ if ($this->ipInRange($ip, $row['ip_address'])) {
+ return true;
+ }
+ } else {
+ if ($ip === $row['ip_address']) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
private function ipInRange($ip, $cidr) {
list($subnet, $bits) = explode('/', $cidr);
@@ -151,6 +168,7 @@ class RateLimiter {
$message = "Cannot whitelist {$ip} - IP is currently blacklisted";
if ($userId) {
$this->log->insertLog($userId, "IP Whitelist: {$message}", 'system');
+ Messages::flash('ERROR', 'DEFAULT', $message);
}
return false;
}
@@ -177,6 +195,7 @@ class RateLimiter {
} catch (Exception $e) {
if ($userId) {
$this->log->insertLog($userId, "IP Whitelist: Failed to add {$ip}: " . $e->getMessage(), 'system');
+ Messages::flash('ERROR', 'DEFAULT', "IP Whitelist: Failed to add {$ip}: " . $e->getMessage());
}
return false;
}
@@ -211,6 +230,7 @@ class RateLimiter {
} catch (Exception $e) {
if ($userId) {
$this->log->insertLog($userId, "IP Whitelist: Failed to remove {$ip}: " . $e->getMessage(), 'system');
+ Messages::flash('ERROR', 'DEFAULT', "IP Whitelist: Failed to remove {$ip}: " . $e->getMessage());
}
return false;
}
@@ -223,6 +243,7 @@ class RateLimiter {
$message = "Cannot blacklist {$ip} - IP is currently whitelisted";
if ($userId) {
$this->log->insertLog($userId, "IP Blacklist: {$message}", 'system');
+ Messages::flash('ERROR', 'DEFAULT', $message);
}
return false;
}
@@ -251,6 +272,7 @@ class RateLimiter {
} catch (Exception $e) {
if ($userId) {
$this->log->insertLog($userId, "IP Blacklist: Failed to add {$ip}: " . $e->getMessage(), 'system');
+ Messages::flash('ERROR', 'DEFAULT', "IP Blacklist: Failed to add {$ip}: " . $e->getMessage());
}
return false;
}
@@ -283,6 +305,7 @@ class RateLimiter {
} catch (Exception $e) {
if ($userId) {
$this->log->insertLog($userId, "IP Blacklist: Failed to remove {$ip}: " . $e->getMessage(), 'system');
+ Messages::flash('ERROR', 'DEFAULT', "IP Blacklist: Failed to remove {$ip}: " . $e->getMessage());
}
return false;
}
@@ -317,6 +340,7 @@ class RateLimiter {
return true;
} catch (Exception $e) {
$this->log->insertLog(0, "Failed to cleanup expired entries: " . $e->getMessage(), 'system');
+ Messages::flash('ERROR', 'DEFAULT', "Failed to cleanup expired entries: " . $e->getMessage());
return false;
}
}
@@ -390,9 +414,9 @@ class RateLimiter {
$stmt = $this->db->prepare($sql);
$stmt->execute([
- ':ip' => $ipAddress,
- ':username' => $username,
- ':minutes' => $this->decayMinutes
+ ':ip' => $ipAddress,
+ ':username' => $username,
+ ':minutes' => $this->decayMinutes
]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
@@ -405,7 +429,7 @@ class RateLimiter {
$stmt = $this->db->prepare($sql);
$stmt->execute([
- ':minutes' => $this->decayMinutes
+ ':minutes' => $this->decayMinutes
]);
}
@@ -418,9 +442,9 @@ class RateLimiter {
$stmt = $this->db->prepare($sql);
$stmt->execute([
- ':ip' => $ipAddress,
- ':username' => $username,
- ':minutes' => $this->decayMinutes
+ ':ip' => $ipAddress,
+ ':username' => $username,
+ ':minutes' => $this->decayMinutes
]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
diff --git a/app/includes/messages-show.php b/app/includes/messages-show.php
new file mode 100644
index 0000000..9cc4ddf
--- /dev/null
+++ b/app/includes/messages-show.php
@@ -0,0 +1,9 @@
+
diff --git a/app/includes/messages-strings.php b/app/includes/messages-strings.php
new file mode 100644
index 0000000..6c72862
--- /dev/null
+++ b/app/includes/messages-strings.php
@@ -0,0 +1,36 @@
+ [
+ 'LOGIN_SUCCESS' => 'Login successful.',
+ 'LOGIN_FAILED' => 'Login failed. Please check your credentials.',
+ 'LOGOUT_SUCCESS' => 'Logout successful. You can log in again.',
+ 'IP_BLACKLISTED' => 'Access denied. Your IP address is blacklisted.',
+ 'IP_NOT_WHITELISTED' => 'Access denied. Your IP address is not whitelisted.',
+ 'TOO_MANY_ATTEMPTS' => 'Too many login attempts. Please try again later.',
+ ],
+ 'SECURITY' => [
+ 'WHITELIST_ADD_SUCCESS' => 'IP address successfully added to whitelist.',
+ 'WHITELIST_ADD_ERROR' => 'Failed to add IP to whitelist. Please check the IP format.',
+ 'WHITELIST_REMOVE_SUCCESS' => 'IP address successfully removed from whitelist.',
+ 'WHITELIST_REMOVE_ERROR' => 'Failed to remove IP from whitelist.',
+ 'BLACKLIST_ADD_SUCCESS' => 'IP address successfully added to blacklist.',
+ 'BLACKLIST_ADD_ERROR' => 'Failed to add IP to blacklist. Please check the IP format.',
+ 'BLACKLIST_REMOVE_SUCCESS' => 'IP address successfully removed from blacklist.',
+ 'BLACKLIST_REMOVE_ERROR' => 'Failed to remove IP from blacklist.',
+ 'RATE_LIMIT_INFO' => 'Rate limiting is active. This helps protect against brute force attacks.',
+ 'PERMISSION_DENIED' => 'Permission denied. You do not have the required rights.',
+ 'IP_REQUIRED' => 'IP address is required.',
+ ],
+ 'REGISTER' => [
+ 'SUCCESS' => 'Registration successful. You can log in now.',
+ 'FAILED' => 'Registration failed: %s',
+ 'DISABLED' => 'Registration is disabled.',
+ ],
+ 'SYSTEM' => [
+ 'DB_ERROR' => 'Error connecting to the database: %s',
+ 'DB_CONNECT_ERROR' => 'Error connecting to DB: %s',
+ 'DB_UNKNOWN_TYPE' => 'Error: unknown database type "%s"',
+ ],
+];
diff --git a/app/includes/messages.php b/app/includes/messages.php
index 58b95d5..d9fdc3f 100644
--- a/app/includes/messages.php
+++ b/app/includes/messages.php
@@ -1,17 +1,15 @@
$flash['category'],
+ 'key' => $flash['key'],
+ 'custom_message' => $flash['custom_message']
+ ];
+ }, $flash_messages));
}
+
+?>
diff --git a/app/includes/sanitize.php b/app/includes/sanitize.php
index 6cff317..ad15a5e 100644
--- a/app/includes/sanitize.php
+++ b/app/includes/sanitize.php
@@ -21,6 +21,15 @@ if (isset($_REQUEST['until_time'])) {
$until_time = htmlspecialchars($_REQUEST['until_time']);
}
+// sanitize session vars
+if (isset($_SESSION)) {
+ foreach ($_SESSION as $key => $value) {
+ if (is_string($value)) {
+ $_SESSION[$key] = htmlspecialchars($value);
+ }
+ }
+}
+
// hosts
if (isset($_POST['address'])) {
$address = htmlspecialchars($_POST['address']);
diff --git a/app/pages/dashboard.php b/app/pages/dashboard.php
index 73651a1..f0d7f15 100644
--- a/app/pages/dashboard.php
+++ b/app/pages/dashboard.php
@@ -9,6 +9,10 @@
* 3. The most recent 10 conferences.
*/
+// Get any new messages
+include '../app/includes/messages.php';
+include '../app/includes/messages-show.php';
+
require '../app/classes/conference.php';
require '../app/classes/participant.php';
diff --git a/app/pages/login.php b/app/pages/login.php
index c9a0523..0eb3ae1 100644
--- a/app/pages/login.php
+++ b/app/pages/login.php
@@ -21,11 +21,28 @@ try {
// connect to database
$dbWeb = connectDB($config);
+ // Initialize RateLimiter
+ require_once '../app/classes/ratelimiter.php';
+ $rateLimiter = new RateLimiter($dbWeb);
+
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
try {
$username = $_POST['username'];
$password = $_POST['password'];
+ // Check if IP is blacklisted
+ if ($rateLimiter->isIpBlacklisted($user_IP)) {
+ throw new Exception(Messages::get('LOGIN', 'IP_BLACKLISTED')['message']);
+ }
+
+ // Check rate limiting (but skip if IP is whitelisted)
+ if (!$rateLimiter->isIpWhitelisted($user_IP)) {
+ $attempts = $rateLimiter->getRecentAttempts($user_IP);
+ if ($attempts >= $rateLimiter->maxAttempts) {
+ throw new Exception(Messages::get('LOGIN', 'LOGIN_BLOCKED')['message']);
+ }
+ }
+
// login successful
if ( $userObject->login($username, $password) ) {
// if remember_me is checked, max out the session
@@ -52,32 +69,40 @@ try {
'samesite' => 'Strict'
]);
- // redirect to index
- $_SESSION['notice'] = "Login successful";
+ // Log successful login
$user_id = $userObject->getUserId($username)[0]['id'];
$logObject->insertLog($user_id, "Login: User \"$username\" logged in. IP: $user_IP", 'user');
+
+ // Set success message and redirect
+ Messages::flash('LOGIN', 'LOGIN_SUCCESS');
header('Location: ' . htmlspecialchars($app_root));
exit();
+ } else {
+ throw new Exception(Messages::get('LOGIN', 'LOGIN_FAILED')['message']);
}
} catch (Exception $e) {
// Log the failed attempt
- $error = $e->getMessage();
+ Messages::flash('ERROR', 'DEFAULT', $e->getMessage());
if (isset($username)) {
$user_id = $userObject->getUserId($username)[0]['id'] ?? 0;
- $logObject->insertLog($user_id, "Login: Failed login attempt for user \"$username\". IP: $user_IP. Reason: {$error}", 'user');
+ $logObject->insertLog($user_id, "Login: Failed login attempt for user \"$username\". IP: $user_IP. Reason: {$e->getMessage()}", 'user');
}
- include '../app/templates/block-message.php';
}
}
} catch (Exception $e) {
- $error = getError('There was an unexpected error. Please try again.', $e->getMessage());
+ Messages::flash('ERROR', 'DEFAULT', 'There was an unexpected error. Please try again.');
}
+// Show configured login message if any
if (!empty($config['login_message'])) {
- $notice = $config['login_message'];
- include '../app/templates/block-message.php';
+ echo Messages::render('NOTICE', 'DEFAULT', $config['login_message'], false);
}
+// Get any new messages
+include '../app/includes/messages.php';
+include '../app/includes/messages-show.php';
+
+// Load the template
include '../app/templates/form-login.php';
?>
diff --git a/app/pages/register.php b/app/pages/register.php
index 420c65b..f3aa431 100644
--- a/app/pages/register.php
+++ b/app/pages/register.php
@@ -8,12 +8,9 @@
* and redirects to the login page on success or displays an error message on failure.
*/
-// check if the registration is allowed
+// registration is allowed, go on
if ($config['registration_enabled'] === true) {
- // clear any previous error messages
- unset($error);
-
try {
// connect to database
@@ -28,27 +25,30 @@ if ($config['registration_enabled'] === true) {
// redirect to login
if ($result === true) {
- $_SESSION['notice'] = "Registration successful.
You can log in now.";
+ Messages::flash('NOTICE', 'DEFAULT', "Registration successful.
You can log in now.");
header('Location: ' . htmlspecialchars($app_root));
exit();
// registration fail, redirect to login
} else {
- $_SESSION['error'] = "Registration failed. $result";
+ Messages::flash('ERROR', 'DEFAULT', "Registration failed. $result");
header('Location: ' . htmlspecialchars($app_root));
exit();
}
}
} catch (Exception $e) {
- $error = $e->getMessage();
+ Messages::flash('ERROR', 'DEFAULT', $e->getMessage());
}
- include '../app/templates/block-message.php';
+ // Get any new messages
+ include '../app/includes/messages.php';
+ include '../app/includes/messages-show.php';
+
+ // Load the template
include '../app/templates/form-register.php';
// registration disabled
} else {
- $notice = 'Registration is disabled';
- include '../app/templates/block-message.php';
+ echo Messages::render('NOTICE', 'DEFAULT', 'Registration is disabled', false);
}
?>
diff --git a/app/pages/security.php b/app/pages/security.php
index 6146b80..78ae7c8 100644
--- a/app/pages/security.php
+++ b/app/pages/security.php
@@ -9,15 +9,18 @@ if (!($userObject->hasRight($user_id, 'superuser') ||
exit;
}
-// Include Messages class
-require_once '../app/classes/messages.php';
-
-// Initialize variables for feedback messages
-$messages = [];
+if (!isset($currentUser)) {
+ include '../app/templates/error-unauthorized.php';
+ exit;
+}
// Get current section
$section = isset($_POST['section']) ? $_POST['section'] : (isset($_GET['section']) ? $_GET['section'] : 'whitelist');
+// Initialize RateLimiter
+require_once '../app/classes/ratelimiter.php';
+$rateLimiter = new RateLimiter($dbWeb);
+
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
@@ -81,6 +84,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
}
} catch (Exception $e) {
$messages[] = ['category' => 'SECURITY', 'key' => 'CUSTOM_ERROR', 'custom_message' => $e->getMessage()];
+ Messages::flash('SECURITY', 'CUSTOM_ERROR', 'custom_message');
}
if (empty($messages)) {
@@ -90,16 +94,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
}
}
-// Get flash messages from previous request
-$flash_messages = Messages::getFlash();
-$messages = array_merge($messages, array_map(function($flash) {
- return [
- 'category' => $flash['category'],
- 'key' => $flash['key'],
- 'custom_message' => $flash['custom_message']
- ];
-}, $flash_messages));
-
// Always show rate limit info message for rate limiting section
if ($section === 'ratelimit') {
$messages[] = ['category' => 'SECURITY', 'key' => 'RATE_LIMIT_INFO'];
@@ -109,7 +103,11 @@ if ($section === 'ratelimit') {
$whitelisted = $rateLimiter->getWhitelistedIps();
$blacklisted = $rateLimiter->getBlacklistedIps();
-// Include template
+// Get any new messages
+include '../app/includes/messages.php';
+include '../app/includes/messages-show.php';
+
+// Load the template
include '../app/templates/security.php';
?>
diff --git a/app/templates/block-message.php b/app/templates/block-message.php
deleted file mode 100644
index 79490a0..0000000
--- a/app/templates/block-message.php
+++ /dev/null
@@ -1,18 +0,0 @@
-
diff --git a/app/templates/page-footer.php b/app/templates/page-footer.php
index 079813d..802962d 100644
--- a/app/templates/page-footer.php
+++ b/app/templates/page-footer.php
@@ -18,6 +18,28 @@ $(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
+
+
+
+
+