import { canSee } from "@/lib/session"; import { getPortalSession } from "@/lib/get-session"; import { loadTenantForShell } from "@/lib/portal-data"; import { Panel } from "@/components/portal/Panel"; import { NotAllowed } from "@/components/portal/NotAllowed"; const EVENT_FILTERS = ["all", "auth", "scan", "finding", "evidence", "billing", "settings"]; export default async function AuditPage({ params, searchParams, }: { params: Promise<{ slug: string }>; searchParams: Promise<{ q?: string; type?: string; product?: string }>; }) { const { slug } = await params; const sp = await searchParams; const session = await getPortalSession(); if (!canSee(session, "audit")) return ; const t = await loadTenantForShell(slug); if (!t) return null; const q = sp.q?.toLowerCase() ?? ""; const type = sp.type ?? "all"; const product = sp.product ?? "all"; const rows = t.audit.filter((r) => { if (q && !`${r.event} ${r.actor} ${r.product}`.toLowerCase().includes(q)) return false; if (type !== "all" && !r.event.startsWith(type)) return false; if (product !== "all" && r.product !== product) return false; return true; }); return (
Audit log
{rows.length} of {t.audit.length}{" "} events · retention 365 days · hash-chained
{EVENT_FILTERS.map((f) => ( ))} {rows.slice(0, 50).map((r, i) => ( ))}
When Event Actor Product Source IP Result
{r.date} {r.time} {r.event} {r.actor} {r.product} {r.ip} {r.result === "denied" ? "DENIED" : "OK"}
); }