Phase A — HTML removed from PHP files: - RateLimitMiddleware.php: heredoc moved to views/errors/429.php - public/index.php: inline HTML replaced with View::error() - AuthMiddleware.php: <script> redirect replaced with <meta refresh> Phase B — Inline CSS/JS extracted from views: - CSS: landing.css (459 lines), legal.css (shared by terms+privacy) - JS: 17 new files extracted from ~20 view files - main.js (layout sidebar + notifications) - dashboard-chart.js, server-show.js, server-services.js - nginx-manager.js, database-manager.js - terminal.js, team-show.js, team-index.js - server-list.js, server-permissions.js (shared by edit+create) - server-ssl.js, server-processes.js, system-users.js - admin-users.js, audit-log.js, admin-notifications.js, admin-security.js - notifications.js Total: -3264 lines from views, +288 lines in new assets
191 lines
10 KiB
PHP
Executable File
191 lines
10 KiB
PHP
Executable File
<?php
|
|
$logs = $logs ?? [];
|
|
$action = $action ?? '';
|
|
$username = $username ?? '';
|
|
$ipAddress = $ipAddress ?? '';
|
|
$entityType = $entityType ?? '';
|
|
$details = $details ?? '';
|
|
$dateFrom = $dateFrom ?? '';
|
|
$dateTo = $dateTo ?? '';
|
|
|
|
function selected(string $value, string $compare): string {
|
|
return $value === $compare ? 'selected' : '';
|
|
}
|
|
?>
|
|
|
|
<div class="page-header">
|
|
<div class="page-header-left">
|
|
<h1 class="page-title">Audit Logs</h1>
|
|
<p class="page-subtitle">Comprehensive activity tracking and security monitoring</p>
|
|
</div>
|
|
<div class="page-header-right">
|
|
<button class="btn btn-sm" onclick="clearFilters()"><i class="fas fa-times"></i> Clear Filters</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>User</th>
|
|
<th>Action</th>
|
|
<th>Entity</th>
|
|
<th>Details</th>
|
|
<th>IP Address</th>
|
|
</tr>
|
|
<tr class="filter-row">
|
|
<th>
|
|
<div class="filter-date-group">
|
|
<input type="date" id="f_date_from" class="form-input" placeholder="From" value="<?= htmlspecialchars($dateFrom) ?>">
|
|
<span class="filter-date-sep">—</span>
|
|
<input type="date" id="f_date_to" class="form-input" placeholder="To" value="<?= htmlspecialchars($dateTo) ?>">
|
|
</div>
|
|
</th>
|
|
<th>
|
|
<div class="filter-input-wrap">
|
|
<input type="text" id="f_username" class="form-input filter-input" placeholder="User..." value="<?= htmlspecialchars($username) ?>">
|
|
<?php if ($username !== ''): ?>
|
|
<button class="filter-clear" onclick="clearField('f_username')" title="Clear">×</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</th>
|
|
<th>
|
|
<select id="f_action" class="form-select">
|
|
<option value="">All Actions</option>
|
|
<option value="login_success" <?= selected($action, 'login_success') ?>>Login Success</option>
|
|
<option value="login_failed" <?= selected($action, 'login_failed') ?>>Login Failed</option>
|
|
<option value="server_created" <?= selected($action, 'server_created') ?>>Server Created</option>
|
|
<option value="server_deleted" <?= selected($action, 'server_deleted') ?>>Server Deleted</option>
|
|
<option value="credential_access" <?= selected($action, 'credential_access') ?>>Credential Access</option>
|
|
<option value="command_executed" <?= selected($action, 'command_executed') ?>>Command Executed</option>
|
|
<option value="user_created" <?= selected($action, 'user_created') ?>>User Created</option>
|
|
<option value="user_deleted" <?= selected($action, 'user_deleted') ?>>User Deleted</option>
|
|
<option value="logout" <?= selected($action, 'logout') ?>>Logout</option>
|
|
<option value="user_registered" <?= selected($action, 'user_registered') ?>>User Registered</option>
|
|
<option value="profile_updated" <?= selected($action, 'profile_updated') ?>>Profile Updated</option>
|
|
<option value="server_action" <?= selected($action, 'server_action') ?>>Server Action</option>
|
|
<option value="user_updated" <?= selected($action, 'user_updated') ?>>User Updated</option>
|
|
</select>
|
|
</th>
|
|
<th>
|
|
<select id="f_entity_type" class="form-select">
|
|
<option value="">All Entities</option>
|
|
<option value="user" <?= selected($entityType, 'user') ?>>User</option>
|
|
<option value="server" <?= selected($entityType, 'server') ?>>Server</option>
|
|
<option value="server_credentials" <?= selected($entityType, 'server_credentials') ?>>Credentials</option>
|
|
</select>
|
|
</th>
|
|
<th>
|
|
<div class="filter-input-wrap">
|
|
<input type="text" id="f_details" class="form-input filter-input" placeholder="Details..." value="<?= htmlspecialchars($details) ?>">
|
|
<?php if ($details !== ''): ?>
|
|
<button class="filter-clear" onclick="clearField('f_details')" title="Clear">×</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</th>
|
|
<th>
|
|
<div class="filter-input-wrap">
|
|
<input type="text" id="f_ip_address" class="form-input filter-input" placeholder="IP..." value="<?= htmlspecialchars($ipAddress) ?>">
|
|
<?php if ($ipAddress !== ''): ?>
|
|
<button class="filter-clear" onclick="clearField('f_ip_address')" title="Clear">×</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($logs['data'] as $log): ?>
|
|
<tr class="audit-row <?= str_contains($log['action'] ?? '', 'failed') ? 'audit-row-danger' : '' ?>">
|
|
<td><?= htmlspecialchars($log['created_at'] ?? '') ?></td>
|
|
<td><?= htmlspecialchars($log['actor_name'] ?? $log['username'] ?? 'System') ?></td>
|
|
<td>
|
|
<span class="badge badge-<?= match(true) {
|
|
str_contains($log['action'] ?? '', 'failed') => 'danger',
|
|
str_contains($log['action'] ?? '', 'success') => 'success',
|
|
str_contains($log['action'] ?? '', 'deleted') => 'danger',
|
|
str_contains($log['action'] ?? '', 'created') => 'success',
|
|
default => 'info',
|
|
} ?>">
|
|
<?= htmlspecialchars(str_replace('_', ' ', $log['action'] ?? '')) ?>
|
|
</span>
|
|
</td>
|
|
<td><?= htmlspecialchars(($log['entity_type'] ?? '') . ' #' . ($log['entity_id'] ?? '')) ?></td>
|
|
<td>
|
|
<?php if ($log['details'] ?? false): ?>
|
|
<pre class="audit-details"><?= htmlspecialchars($log['details']) ?></pre>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><code><?= htmlspecialchars($log['ip_address'] ?? '') ?></code></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<?php
|
|
$totalPages = $logs['total_pages'] ?? 0;
|
|
$currentPage = $logs['page'] ?? 1;
|
|
if ($totalPages > 1):
|
|
$window = 3;
|
|
$qs = function (int $p) use ($action, $username, $ipAddress, $entityType, $details, $dateFrom, $dateTo) {
|
|
return '?page=' . $p
|
|
. ($action !== '' ? '&action=' . urlencode($action) : '')
|
|
. ($username !== '' ? '&username=' . urlencode($username) : '')
|
|
. ($ipAddress !== '' ? '&ip_address=' . urlencode($ipAddress) : '')
|
|
. ($entityType !== '' ? '&entity_type=' . urlencode($entityType) : '')
|
|
. ($details !== '' ? '&details=' . urlencode($details) : '')
|
|
. ($dateFrom !== '' ? '&date_from=' . urlencode($dateFrom) : '')
|
|
. ($dateTo !== '' ? '&date_to=' . urlencode($dateTo) : '');
|
|
};
|
|
?>
|
|
<div class="pagination">
|
|
<?php if ($currentPage > 1): ?>
|
|
<a href="<?= $qs($currentPage - 1) ?>" class="page-link">« Previous</a>
|
|
<?php endif; ?>
|
|
|
|
<?php
|
|
$showPages = [];
|
|
$showPages[] = 1;
|
|
|
|
if ($currentPage > $window + 2) {
|
|
$showPages[] = '...';
|
|
}
|
|
|
|
$start = max(2, $currentPage - $window);
|
|
$end = min($totalPages - 1, $currentPage + $window);
|
|
for ($i = $start; $i <= $end; $i++) {
|
|
$showPages[] = $i;
|
|
}
|
|
|
|
if ($currentPage < $totalPages - $window - 1) {
|
|
$showPages[] = '...';
|
|
}
|
|
|
|
if ($totalPages > 1) {
|
|
$showPages[] = $totalPages;
|
|
}
|
|
|
|
foreach ($showPages as $p):
|
|
?>
|
|
<?php if ($p === '...'): ?>
|
|
<span class="page-link page-ellipsis">…</span>
|
|
<?php else: ?>
|
|
<a href="<?= $qs($p) ?>" class="page-link <?= $p === $currentPage ? 'active' : '' ?>"><?= $p ?></a>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
|
|
<?php if ($currentPage < $totalPages): ?>
|
|
<a href="<?= $qs($currentPage + 1) ?>" class="page-link">Next »</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/assets/js/audit-log.js"></script>
|