"use client"; import { useCallback, useEffect, useState } from "react"; import { NoPermissionState } from "@/components/auth/no-permission-state"; import { useSuperAdminSession } from "@/components/auth/session-context"; import { PageHeader } from "@/components/dashboard/page-header"; import { PaginationControls } from "@/components/dashboard/pagination-controls"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { EmptyState } from "@/components/ui/empty-state"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { useToast } from "@/components/ui/toast"; import { listAuditLogs } from "@/lib/api/audit"; import { listSuperAdminSessions, revokeSuperAdminSession } from "@/lib/api/auth"; import { getItems, getPagination } from "@/lib/api/core"; import { getSuperAdminOps } from "@/lib/api/superadmin"; import { formatDateTime } from "@/lib/format"; import { SUPERADMIN_PERMISSIONS, hasPermission } from "@/lib/permissions"; import type { AuditLogsResponse, SessionItem, SessionsResponse, SuperAdminOpsResponse, } from "@/types/api"; const EMPTY_SESSIONS: SessionsResponse = { items: [] }; const EMPTY_AUDIT: AuditLogsResponse = { items: [], data: [] }; const EMPTY_OPS: SuperAdminOpsResponse = { services: { mongodb: { status: "unknown" }, redis: { enabled: false, status: "unknown" }, queue: { enabled: false }, storage: {}, email: { enabled: false }, websocket: { redisAdapterEnabled: false }, }, queues: { outbox: { pending: 0, failed: 0 }, }, workload: { openCasesCount: 0, activeSuperAdminSessionsCount: 0, }, }; export default function SecurityPage() { const { session, permissions } = useSuperAdminSession(); const [sessionsResponse, setSessionsResponse] = useState(null); const [auditResponse, setAuditResponse] = useState(null); const [ops, setOps] = useState(null); const [auditPage, setAuditPage] = useState(1); const [loading, setLoading] = useState(true); const { toast } = useToast(); const canManageSessions = hasPermission( permissions, SUPERADMIN_PERMISSIONS.SESSIONS_MANAGE, ); const canReadAudit = hasPermission(permissions, SUPERADMIN_PERMISSIONS.AUDIT_READ); const canReadOps = hasPermission(permissions, SUPERADMIN_PERMISSIONS.OPS_READ); const loadSecurity = useCallback(async () => { if (!canManageSessions && !canReadAudit && !canReadOps) { setLoading(false); return; } setLoading(true); try { const [sessions, audit, nextOps] = await Promise.all([ canManageSessions ? listSuperAdminSessions() : Promise.resolve(EMPTY_SESSIONS), canReadAudit ? listAuditLogs({ page: auditPage, limit: 12, sortOrder: "desc" }) : Promise.resolve(EMPTY_AUDIT), canReadOps ? getSuperAdminOps() : Promise.resolve(EMPTY_OPS), ]); setSessionsResponse(sessions); setAuditResponse(audit); setOps(nextOps); } catch (error) { toast({ title: "Failed to load security page", description: String(error), variant: "danger" }); } finally { setLoading(false); } }, [auditPage, canManageSessions, canReadAudit, canReadOps, toast]); useEffect(() => { void loadSecurity(); }, [loadSecurity]); const sessions = (sessionsResponse?.items ?? []) as SessionItem[]; if (!canManageSessions && !canReadAudit && !canReadOps) { return (
); } return (
{canManageSessions ? ( Active sessions {sessions.length} ) : null} Session strategy {session?.sessionStrategy ?? "httpOnly_cookies"}

Proxy-managed secure cookies.

{canReadOps ? ( <> Mongo / Redis
MongoDB: {ops?.services.mongodb.status ?? "-"}
Redis: {ops?.services.redis.status ?? "-"}
Outbox
Pending: {ops?.queues.outbox.pending ?? 0}
Failed: {ops?.queues.outbox.failed ?? 0}
) : null}
Granted permissions {(session?.permissions ?? []).map((permission) => ( {permission} ))}
{canManageSessions ? ( SuperAdmin sessions {!sessions.length && !loading ? ( ) : (
{sessions.map((sessionItem) => (

{sessionItem.id ?? sessionItem.jti ?? "-"}

{formatDateTime(sessionItem.createdAt)} - {formatDateTime(sessionItem.expiresAt)}

))}
)}
) : null} {canReadAudit ? ( Audit log {!getItems(auditResponse).length && !loading ? ( ) : ( Action Actor Target Time {getItems(auditResponse).map((log) => ( {log.action} {log.actorIdentifier ?? log.actorType} {log.targetType} {formatDateTime(log.createdAt)} ))}
)}
) : null}
); }