108 lines
6.0 KiB
HTML
108 lines
6.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Audit Log</title>
|
|
<link rel="icon" type="image/png" href="{{ LOGO_PNG }}">
|
|
<link href="/static/css/output.css" rel="stylesheet">
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
|
|
</head>
|
|
<body class="bg-gray-300 text-gray-900 dark:bg-zinc-900 dark:text-gray-100 min-h-screen flex flex-col">
|
|
{% include 'header.html' %}
|
|
<div class="flex-1 flex items-center justify-center mx-4">
|
|
<div class="container py-8 max-w-8xl pt-20">
|
|
<h1 class="text-3xl font-bold mb-6 text-center">Audit Log</h1>
|
|
<form method="GET" class="flex flex-wrap gap-4 mb-6 justify-center">
|
|
<select name="user_id" class="border p-2 rounded-lg bg-gray-300 dark:bg-zinc-900 border-gray-600">
|
|
<option value="">All Users</option>
|
|
{% for user in users %}
|
|
<option value="{{ user[0] }}" {% if request.args.get('user_id') == user[0]|string %}selected{% endif %}>{{ user[1] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<select name="subnet_id" class="border p-2 rounded-lg bg-gray-300 dark:bg-zinc-900 border-gray-600">
|
|
<option value="">All Subnets</option>
|
|
{% for subnet in subnets %}
|
|
<option value="{{ subnet[0] }}" {% if request.args.get('subnet_id') == subnet[0]|string %}selected{% endif %}>{{ subnet[1] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<select name="action" class="border p-2 rounded-lg bg-gray-300 dark:bg-zinc-900 border-gray-600">
|
|
<option value="">All Actions</option>
|
|
{% for a in actions %}
|
|
<option value="{{ a }}" {% if request.args.get('action') == a %}selected{% endif %}>{{ a }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<select name="device_name" class="border p-2 rounded-lg bg-gray-300 dark:bg-zinc-900 border-gray-600">
|
|
<option value="">All Devices</option>
|
|
{% for device in devices %}
|
|
<option value="{{ device[0] }}" {% if request.args.get('device_name') == device[0] %}selected{% endif %}>{{ device[0] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<button type="submit" class="bg-gray-200 hover:bg-gray-400 dark:bg-zinc-700 dark:hover:bg-zinc-600 px-4 py-2 rounded-lg flex items-center gap-2">
|
|
<i class="fas fa-search"></i>
|
|
<span>Filter</span>
|
|
</button>
|
|
</form>
|
|
<table class="w-full table-auto bg-gray-200 dark:bg-zinc-800 rounded-lg overflow-hidden">
|
|
<thead>
|
|
<tr class="bg-gray-400 dark:bg-zinc-700">
|
|
<th class="px-4 py-2 text-center">User</th>
|
|
<th class="px-4 py-2 text-center">Action</th>
|
|
<th class="px-4 py-2 text-center">Details</th>
|
|
<th class="px-4 py-2 text-center">Subnet</th>
|
|
<th class="px-4 py-2 text-center">Timestamp</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for log in logs %}
|
|
<tr class="border-b border-gray-700">
|
|
<td class="px-4 py-2 text-center">{{ log[1] or 'Unknown' }}</td>
|
|
<td class="px-4 py-2 text-center">{{ log[2] }}</td>
|
|
<td class="px-4 py-2 text-center truncate" title="{{ log[3] }}">{{ log[3][:100] ~ ('…' if log[3]|length > 100 else '') }}</td>
|
|
<td class="px-4 py-2 text-center">{{ log[4] or 'N/A' }}</td>
|
|
<td class="px-4 py-2 text-center" data-utc="{{ log[5] }}">{{ log[5] }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% if total_pages > 1 %}
|
|
<div class="flex justify-center mt-6 space-x-2">
|
|
{% if page > 1 %}
|
|
{% set prev_args = query_args.copy() %}
|
|
{% set _ = prev_args.update({'page': page-1}) %}
|
|
<a href="{{ url_for('audit', **prev_args) }}" class="px-3 py-1 rounded bg-gray-400 hover:bg-gray-200 dark:bg-zinc-700 dark:hover:bg-zinc-600 flex items-center gap-2">
|
|
<i class="fa fa-angle-left"></i>
|
|
<span class="hidden sm:inline">Prev</span>
|
|
</a>
|
|
{% endif %}
|
|
{% for p in range(1, total_pages+1) %}
|
|
{% set page_args = query_args.copy() %}
|
|
{% set _ = page_args.update({'page': p}) %}
|
|
<a href="{{ url_for('audit', **page_args) }}" class="px-3 py-1 rounded {{ 'bg-gray-200 dark:bg-gray-500' if p == page else 'bg-gray-400 hover:bg-gray-200 dark:bg-zinc-700 dark:hover:bg-zinc-600' }}">{{ p }}</a>
|
|
{% endfor %}
|
|
{% if page < total_pages %}
|
|
{% set next_args = query_args.copy() %}
|
|
{% set _ = next_args.update({'page': page+1}) %}
|
|
<a href="{{ url_for('audit', **next_args) }}" class="px-3 py-1 rounded bg-gray-400 hover:bg-gray-200 dark:bg-zinc-700 dark:hover:bg-zinc-600 flex items-center gap-2">
|
|
<span class="hidden sm:inline">Next</span>
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.querySelectorAll('td[data-utc]').forEach(function(td) {
|
|
const utc = td.getAttribute('data-utc');
|
|
if (utc) {
|
|
const date = new Date(utc + 'Z');
|
|
td.textContent = date.toLocaleString();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|