Add error log management and bulk admin actions

Introduces error log tracking with new ErrorLog model, controller, views, and migration. Adds admin UI for viewing, resolving, and deleting errors. Implements bulk actions for users and notification groups, refactors domain filtering/pagination, and centralizes admin access checks using Auth::requireAdmin().
This commit is contained in:
Hosteroid
2025-10-10 14:01:19 +03:00
parent a29becc944
commit b50377492c
38 changed files with 3726 additions and 428 deletions

View File

@@ -2,30 +2,30 @@
namespace Core;
use App\Services\ErrorHandler;
class Application
{
public static Router $router;
public static Database $db;
private ErrorHandler $errorHandler;
public function __construct()
{
self::$router = new Router();
self::$db = new Database();
// Initialize error handler
$this->errorHandler = new ErrorHandler();
}
public function run()
{
try {
self::$router->resolve();
} catch (\Exception $e) {
http_response_code(500);
if ($_ENV['APP_ENV'] === 'development') {
echo '<h1>Error</h1>';
echo '<pre>' . $e->getMessage() . '</pre>';
echo '<pre>' . $e->getTraceAsString() . '</pre>';
} else {
echo '<h1>500 - Internal Server Error</h1>';
}
} catch (\Throwable $e) {
// Use centralized error handler
$this->errorHandler->handleException($e);
}
}
}

View File

@@ -69,5 +69,37 @@ class Auth
exit;
}
}
/**
* Require admin role (redirect with error if not admin)
*/
public static function requireAdmin(): void
{
// First ensure user is authenticated
self::require();
// Then check for admin role
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
$_SESSION['error'] = 'Access denied. Admin privileges required.';
header('Location: /');
exit;
}
}
/**
* Check if current user is admin
*/
public static function isAdmin(): bool
{
return isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
}
/**
* Get current user's role
*/
public static function role(): ?string
{
return $_SESSION['role'] ?? null;
}
}

View File

@@ -18,11 +18,23 @@ class Database
private function connect()
{
$host = $_ENV['DB_HOST'];
$port = $_ENV['DB_PORT'];
$database = $_ENV['DB_DATABASE'];
$username = $_ENV['DB_USERNAME'];
$password = $_ENV['DB_PASSWORD'];
$host = $_ENV['DB_HOST'] ?? null;
$port = $_ENV['DB_PORT'] ?? '3306';
$database = $_ENV['DB_DATABASE'] ?? null;
$username = $_ENV['DB_USERNAME'] ?? null;
$password = $_ENV['DB_PASSWORD'] ?? '';
// Validate required credentials
if (empty($host) || empty($database) || empty($username)) {
throw new \Exception(
"Database credentials not configured!\n\n" .
"Missing in .env file:\n" .
(!empty($host) ? "" : "- DB_HOST\n") .
(!empty($database) ? "" : "- DB_DATABASE\n") .
(!empty($username) ? "" : "- DB_USERNAME\n") .
"\nPlease update your .env file with valid database credentials."
);
}
try {
$dsn = "mysql:host=$host;port=$port;dbname=$database;charset=utf8mb4";
@@ -32,7 +44,7 @@ class Database
PDO::ATTR_EMULATE_PREPARES => false,
]);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
throw new \Exception("Database connection failed: " . $e->getMessage());
}
}