- Implement BotGuard security engine (Bot, AI, Scraper & Empty UA blocking) - Add Admin Security page (/admin/security) with toggles, rate limiter & block/allowlists - Add per-IP RateLimiter handoff in index.php with HTTP 429 response - Add dynamic /robots.txt generation and noai/noimageai meta tags - Add RequestLogger status column and blocked badges in admin request logs - Fix ARIAComponents.php syntax errors on lines 67, 137, 262 - Add HAProxy / PFSense bot blocking & IP forwarding guide (docs/haproxy-bot-blocking.md) - Update version to 1.8.0 with release notes in version.php and guides
207 lines
9.3 KiB
PHP
207 lines
9.3 KiB
PHP
<?php
|
|
// Load theme sidebar color from site config
|
|
$layoutConfigFile = __DIR__ . '/../../config.json';
|
|
$layoutSiteConfig = file_exists($layoutConfigFile) ? json_decode(file_get_contents($layoutConfigFile), true) : [];
|
|
$layoutActiveTheme = $layoutSiteConfig['active_theme'] ?? 'default';
|
|
$layoutThemeDir = dirname(__DIR__, 1) . '/../themes/' . $layoutActiveTheme;
|
|
$layoutThemeFile = $layoutThemeDir . '/theme.json';
|
|
$layoutThemeConfig = file_exists($layoutThemeFile) ? json_decode(file_get_contents($layoutThemeFile), true) : [];
|
|
$layoutSidebarColor = $layoutThemeConfig['header_color'] ?? '#0a369d';
|
|
?><!DOCTYPE html>
|
|
<html lang="nl">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>CodePress Admin</title>
|
|
<link rel="stylesheet" href="/assets/css/bootstrap.min.css">
|
|
<link rel="stylesheet" href="/assets/css/bootstrap-icons.css">
|
|
<style>
|
|
body { background-color: #f5f6fa; min-height: 100vh; }
|
|
.admin-sidebar { background-color: <?= htmlspecialchars($layoutSidebarColor) ?>; min-height: 100vh; width: 240px; position: fixed; top: 0; left: 0; z-index: 100; }
|
|
.admin-sidebar .nav-link { color: rgba(255,255,255,0.8); padding: 0.75rem 1.25rem; border-radius: 0; }
|
|
.admin-sidebar .nav-link:hover { color: #fff; background-color: rgba(255,255,255,0.1); }
|
|
.admin-sidebar .nav-link.active { color: #fff; background-color: rgba(255,255,255,0.2); border-left: 3px solid #fff; }
|
|
.admin-sidebar .nav-link i { width: 24px; text-align: center; margin-right: 0.5rem; }
|
|
.admin-main { margin-left: 240px; padding: 2rem; }
|
|
.admin-brand { color: #fff; padding: 1.25rem; font-size: 1.1rem; border-bottom: 1px solid rgba(255,255,255,0.15); }
|
|
.admin-brand i { margin-right: 0.5rem; }
|
|
.stat-card { border: none; border-radius: 0.5rem; }
|
|
.stat-card .stat-icon { font-size: 2rem; opacity: 0.7; }
|
|
.admin-user { color: rgba(255,255,255,0.6); padding: 0.75rem 1.25rem; font-size: 0.85rem; border-top: 1px solid rgba(255,255,255,0.15); position: absolute; bottom: 0; width: 100%; }
|
|
@media (max-width: 768px) {
|
|
.admin-sidebar { width: 100%; min-height: auto; position: relative; }
|
|
.admin-main { margin-left: 0; }
|
|
}
|
|
</style>
|
|
<?php if (in_array($route ?? '', ['content-edit', 'content-new', 'plugins-edit'])): ?>
|
|
<link rel="stylesheet" href="/assets/codemirror/codemirror.min.css">
|
|
<link rel="stylesheet" href="/assets/css/editor.css">
|
|
<?php endif; ?>
|
|
</head>
|
|
<body>
|
|
<!-- Sidebar -->
|
|
<nav class="admin-sidebar d-flex flex-column">
|
|
<div class="admin-brand">
|
|
<i class="bi bi-gear-fill"></i> CodePress Admin
|
|
</div>
|
|
<ul class="nav flex-column mt-2">
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'dashboard' || ($route ?? '') === '' ? 'active' : '' ?>" href="/admin/dashboard">
|
|
<i class="bi bi-speedometer2"></i> Dashboard
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'content' || str_starts_with($route ?? '', 'content') ? 'active' : '' ?>" href="/admin/content">
|
|
<i class="bi bi-file-earmark-text"></i> Content
|
|
</a>
|
|
</li>
|
|
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'theme' ? 'active' : '' ?>" href="/admin/theme">
|
|
<i class="bi bi-palette"></i> Thema
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'config' ? 'active' : '' ?>" href="/admin/config">
|
|
<i class="bi bi-sliders"></i> Configuratie
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'security' ? 'active' : '' ?>" href="/admin/security">
|
|
<i class="bi bi-shield-check"></i> Beveiliging
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'plugins' ? 'active' : '' ?>" href="/admin/plugins">
|
|
<i class="bi bi-plug"></i> Plugins
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'users' ? 'active' : '' ?>" href="/admin/users">
|
|
<i class="bi bi-people"></i> Gebruikers
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'guide' ? 'active' : '' ?>" href="/admin/guide">
|
|
<i class="bi bi-book"></i> Handleiding
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'logs' ? 'active' : '' ?>" href="/admin/logs">
|
|
<i class="bi bi-journal-text"></i> Logs
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link <?= ($route ?? '') === 'update' ? 'active' : '' ?>" href="/admin/update">
|
|
<i class="bi bi-cloud-arrow-down"></i> Update
|
|
</a>
|
|
</li>
|
|
<li class="nav-item mt-3">
|
|
<a class="nav-link" href="/" target="_blank">
|
|
<i class="bi bi-box-arrow-up-right"></i> Website bekijken
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link text-warning" href="/admin/logout">
|
|
<i class="bi bi-box-arrow-left"></i> Uitloggen
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<div class="admin-user">
|
|
<i class="bi bi-person-circle"></i> <?= htmlspecialchars($user['username'] ?? '') ?>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Main content -->
|
|
<main class="admin-main">
|
|
<?php if (!empty($message)): ?>
|
|
<div class="alert alert-<?= $messageType ?? 'info' ?> alert-dismissible fade show" role="alert">
|
|
<?= htmlspecialchars($message) ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php
|
|
$currentRoute = $route ?? 'dashboard';
|
|
switch ($currentRoute) {
|
|
case 'dashboard':
|
|
case '':
|
|
require __DIR__ . '/pages/dashboard.php';
|
|
break;
|
|
case 'content':
|
|
require __DIR__ . '/pages/content.php';
|
|
break;
|
|
case 'content-edit':
|
|
require __DIR__ . '/pages/content-edit.php';
|
|
break;
|
|
case 'content-new':
|
|
require __DIR__ . '/pages/content-new.php';
|
|
break;
|
|
case 'config':
|
|
require __DIR__ . '/pages/config.php';
|
|
break;
|
|
case 'security':
|
|
require __DIR__ . '/pages/security.php';
|
|
break;
|
|
# Media route (removed from menu)
|
|
// Uncomment if media functionality is needed elsewhere
|
|
// require __DIR__ . '/pages/media.php';
|
|
break;
|
|
case 'theme':
|
|
require __DIR__ . '/pages/theme.php';
|
|
break;
|
|
case 'plugins':
|
|
require __DIR__ . '/pages/plugins.php';
|
|
break;
|
|
|
|
case 'plugins-new':
|
|
require __DIR__ . '/pages/plugins-new.php';
|
|
break;
|
|
|
|
case 'plugins-edit':
|
|
require __DIR__ . '/pages/plugins-edit.php';
|
|
break;
|
|
|
|
case 'plugins-config':
|
|
require __DIR__ . '/pages/plugin-config.php';
|
|
break;
|
|
|
|
case 'content-dir-rename':
|
|
require __DIR__ . '/pages/content-dir-form.php';
|
|
break;
|
|
case 'content-move':
|
|
require __DIR__ . '/pages/content-move-form.php';
|
|
break;
|
|
case 'users':
|
|
require __DIR__ . '/pages/users.php';
|
|
break;
|
|
case 'guide':
|
|
require __DIR__ . '/pages/guide.php';
|
|
break;
|
|
case 'logs':
|
|
require __DIR__ . '/pages/logs.php';
|
|
break;
|
|
case 'update':
|
|
require __DIR__ . '/pages/update.php';
|
|
break;
|
|
}
|
|
?>
|
|
</main>
|
|
|
|
<script src="/assets/js/bootstrap.bundle.min.js"></script>
|
|
<?php if (in_array($route ?? '', ['content-edit', 'content-new', 'plugins-edit'])): ?>
|
|
<script src="/assets/codemirror/codemirror.min.js"></script>
|
|
<script src="/assets/codemirror/mode/markdown.min.js"></script>
|
|
<script src="/assets/codemirror/mode/xml.min.js"></script>
|
|
<script src="/assets/codemirror/mode/htmlmixed.min.js"></script>
|
|
<script src="/assets/codemirror/mode/php.min.js"></script>
|
|
<script src="/assets/codemirror/mode/clike.min.js"></script>
|
|
<script src="/assets/codemirror/mode/css.min.js"></script>
|
|
<script src="/assets/codemirror/mode/javascript.min.js"></script>
|
|
<script src="/assets/codemirror/addon/edit/closebrackets.min.js"></script>
|
|
<script src="/assets/codemirror/addon/selection/active-line.min.js"></script>
|
|
<script src="/assets/js/editor-toolbar.js"></script>
|
|
<?php endif; ?>
|
|
</body>
|
|
</html>
|