<script setup lang="ts">
import EventDetails from "components/EventTable/EventDetails.vue";
import ScoreTag from "components/ScoreTag.vue";
import {
type FilterActions,
type GeoData,
getHoneypot,
useBlocklistStore,
useFilterActions,
useIPInfoStore,
} from "src/store";
import { type HoneypotEvent } from "src/types";
import { formatTimestamp } from "utils/formatting";
import { computed, ref } from "vue";
import EventFilterMenu from "./EventFilterMenu.vue";
import EventSourceInfo from "./EventSourceInfo.vue";
const ipInfoStore = useIPInfoStore();
const { getIPInfo } = ipInfoStore;
const blocklistStore = useBlocklistStore();
const props = withDefaults(
defineProps<{
evt: HoneypotEvent;
columns?: string[];
filterActions?: FilterActions;
width?: number;
}>(),
{
columns: () => ["time", "event", "remote_addr", "details"],
},
);
const filterActions = props.filterActions || useFilterActions();
const geo = computed<GeoData | undefined>(() => {
if (!filterActions.state.resolve_ips) return undefined;
return getIPInfo(props.evt.remote_addr!).value;
});
const showLinks = ref(false);
</script>
<template>
<tr
@mouseenter="showLinks = true"
@mouseleave="showLinks = false"
@click="showLinks = !showLinks"
>
<td v-if="columns.includes('time')" class="md:whitespace-nowrap">
{{ formatTimestamp(evt.time, true) }}
</td>
<td v-if="columns.includes('event')">
<div class="max-w-48 md:whitespace-nowrap">
<span class="text-xs font-semibold">
<router-link
:to="`/honeypot/${evt.type}`"
class="text-muted hover:text-secondary-400"
v-if="getHoneypot(evt.type)"
>
{{ getHoneypot(evt.type)?.label }}:
</router-link>
<span class="uppercase">{{ evt.event || "—" }}</span>
</span>
</div>
</td>
<td v-if="columns.includes('remote_addr')">
<div
v-if="evt.remote_addr"
class="group flex items-center justify-between gap-2"
>
<EventSourceInfo
:evt="evt"
:filter-actions="filterActions"
:geo="geo"
/>
<div class="flex items-center gap-2">
<div
class="flex gap-1"
v-if="blocklistStore.getTagsByIp(evt.remote_addr!).length"
>
<ScoreTag
v-for="tag in blocklistStore.getTagsByIp(evt.remote_addr!)"
:key="tag"
:tag="tag"
no-label
/>
</div>
<EventFilterMenu
:evt="evt"
:geo="geo"
:filter-actions="filterActions"
:show-links="showLinks"
/>
</div>
</div>
<span v-else class="text-muted">—</span>
</td>
<td v-if="columns.includes('details')" class="align-top text-xs">
<EventDetails
:evt="evt"
:filter-actions="filterActions"
:width="width || 1000"
/>
</td>
</tr>
</template>
<style scoped>
@reference "src/style.css";
a {
@apply hover:text-secondary-400;
}
</style>