Files
Infrastruktur-Monitoring-Sy…/frontend/src/components/FindingTable.vue
Dennis Nemec 872f4373ff
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / ui (push) Has been cancelled
WP-20/21: vulnerability management with Trivy and mail notifications
Trivy scanner adapter (rootfs + image JSON, parsed and deduplicated),
findings repository, scan diff that keeps first_seen, marks disappeared
findings fixed and skips failed targets, vulnerability_scan job (daily by
default), digest mail for new findings at or above a configurable severity,
/api/vulnerabilities routes, Vulnerabilities page with severity tiles,
filters, details and acknowledge, notification threshold in settings.
Deploy script installs Trivy from the Aqua apt repository.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 22:45:57 +02:00

70 lines
2.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import type { Finding } from '../api/types'
defineProps<{ findings: Finding[]; canAct: boolean }>()
defineEmits<{ status: [f: Finding, status: 'open' | 'acknowledged']; select: [f: Finding] }>()
const sev: Record<string, string> = {
critical: 'bg-red-600 text-white',
high: 'bg-orange-500 text-white',
medium: 'bg-amber-300 text-amber-900',
low: 'bg-gray-200 text-gray-700',
unknown: 'bg-gray-100 text-gray-500',
}
</script>
<template>
<table class="w-full text-left text-sm">
<thead class="border-b border-gray-200 text-gray-500">
<tr>
<th class="py-2">Severity</th>
<th>CVE</th>
<th>Package</th>
<th>Installed</th>
<th>Fixed in</th>
<th>Target</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
<tr
v-for="f in findings"
:key="f.id"
class="border-b border-gray-100"
:class="f.status === 'acknowledged' ? 'text-gray-500' : ''"
>
<td class="py-1.5">
<span class="rounded-full px-2 py-0.5 text-xs font-medium" :class="sev[f.severity]">{{
f.severity
}}</span>
</td>
<td class="font-mono">{{ f.cve_id }}</td>
<td class="font-mono">{{ f.package }}</td>
<td class="font-mono text-xs">{{ f.installed_version }}</td>
<td class="font-mono text-xs" :class="f.fixed_version ? 'text-green-700' : 'text-gray-400'">
{{ f.fixed_version ?? '–' }}
</td>
<td class="max-w-xs truncate font-mono text-xs" :title="f.target">{{ f.target }}</td>
<td>{{ f.status }}</td>
<td class="space-x-3 whitespace-nowrap text-right">
<button name="details" class="text-blue-600 hover:underline" @click="$emit('select', f)">
Details
</button>
<button
v-if="canAct"
name="ack"
class="text-blue-600 hover:underline"
@click="$emit('status', f, f.status === 'acknowledged' ? 'open' : 'acknowledged')"
>
{{ f.status === 'acknowledged' ? 'Reopen' : 'Acknowledge' }}
</button>
</td>
</tr>
<tr v-if="findings.length === 0">
<td colspan="8" class="py-6 text-center text-gray-500">No findings.</td>
</tr>
</tbody>
</table>
</template>