diff --git a/web/app/(app)/servers/[id]/page.tsx b/web/app/(app)/servers/[id]/page.tsx index cb8105a..6d70617 100644 --- a/web/app/(app)/servers/[id]/page.tsx +++ b/web/app/(app)/servers/[id]/page.tsx @@ -9,6 +9,7 @@ import { Badge, Button, Card, CardHeader, CardTitle } from "@/components/ui"; import { Table, Thead, Tbody, Tr, Th, Td } from "@/components/ui"; import { useLicense } from "@/lib/useLicense"; import { TagChips } from "@/components/servers/TagChips"; +import { ServerVulnerabilities } from "@/components/vulnerabilities/ServerVulnerabilities"; function statusVariant(status: ServerStatus) { switch (status) { @@ -549,6 +550,10 @@ export default function ServerDetailPage() { +
+ Installed packages matched against distribution security advisories. +
+Loading…
} + {groups.error &&{(groups.error as Error).message}
} + + {groups.data && groups.data.length === 0 && ( +No {state} findings.
++ Servers report packages hourly. A server whose distribution has no advisory feed is reported as unsupported on its own + page rather than counted here. +
++ The finding is hidden from counts and alerts until this date, then reopens automatically. Your name and reason are recorded in + the audit log. +
+ ++ Vulnerability database v{summary.db_version ?? "?"} · pulled {relativeTime(summary.pulled_at)} + {summary.last_full_scan_at && <> · last scan {relativeTime(summary.last_full_scan_at)}>} +
+ ); + } + + return ( ++ {age === null ? "No vulnerability database has been pulled yet" : `Vulnerability database is ${relativeTime(summary.pulled_at)}`} +
++ Findings below are matched against that data. Counts may be incomplete until a fresh pull succeeds. +
+ {summary.last_error &&{summary.last_error}
} +Loading…
+ ) : !pkg ? ( ++ No package inventory yet. Agents report hourly, and only when vulnerability scanning is included in this instance's + licence. +
+ ) : pkg.status === "unsupported" ? ( + <> ++ {pkg.os.family} {pkg.os.version_id} has no advisory feed, so this server cannot be scanned. +
++ This is not the same as having no vulnerabilities — it means we cannot answer the question for this distribution. +
+ > + ) : ( + <> +No known vulnerabilities.
+ ) : ( + counts.map((c) => ( + ++ {pkg.packages.length} packages · {pkg.os.family} {pkg.os.version_id} · collected {relativeTime(pkg.collected_at)} + {pkg.scan_pending && " · rescan queued"} +
+ + {open.length > 0 && ( ++ One digest per rule per scan, summarising what newly opened — never one message per finding. +
+Loading…
+ ) : !rules.data || rules.data.length === 0 ? ( ++ No rules yet. Without one, findings appear on the board but nobody is told about them. +
+ ) : ( ++ Space-separated key:value pairs. Resolved the same way a workflow resolves its targets. +
+No channels configured yet. A rule needs at least one.
+ )} +{(create.error as Error).message}
} + +