internal/dashboard/frontend/src/components/EventTable/EventDetails.vue

<script setup lang="ts">
import DnsDetails from "components/EventTable/EventDetails/DnsDetails.vue";
import HttpDetails from "components/EventTable/EventDetails/HttpDetails.vue";
import PrettyJson from "components/EventTable/EventDetails/PrettyJson.vue";
import RdpDetails from "components/EventTable/EventDetails/RdpDetails.vue";
import SipDetails from "components/EventTable/EventDetails/SipDetails.vue";
import SmtpDetails from "components/EventTable/EventDetails/SmtpDetails.vue";
import SshDetails from "components/EventTable/EventDetails/SshDetails.vue";
import { useFilterStore, type FilterActions } from "src/store";
import { type HoneypotEvent } from "src/types";

const props = defineProps<{
  evt: HoneypotEvent;
  filterActions?: FilterActions;
  width: number;
}>();

const filterStore = props.filterActions?.state || useFilterStore().state;
const actions = props.filterActions || useFilterStore();

function handleFieldClick(ev: MouseEvent, key: string, value: string) {
  if (!value) return;

  if (ev.metaKey || ev.ctrlKey) {
    actions.addJsonField(key, "!" + value);
  } else {
    actions.addJsonField(key, value);
  }

  filterStore.offset = 0;
}
</script>

<template>
  <div class="mb-1 font-medium" v-if="width && width > 768 && evt.dst_port">
    <span class="text-muted">Port: </span>
    <router-link
      :to="`/port/${evt.dst_port}`"
      class="hover:text-secondary-400"
      >{{ evt.dst_port }}</router-link
    >
  </div>
  <PrettyJson :json="evt.fields" v-if="filterStore.expand_details" />
  <div class="details" v-else>
    <button
      v-if="evt.fields?.username"
      @click="
        handleFieldClick($event, 'username', evt.fields.username as string)
      "
      class="cursor-pointer"
    >
      <span>Username:</span>
      <strong>{{ evt.fields.username }}</strong>
    </button>
    <button
      v-if="evt.fields?.password"
      @click="
        handleFieldClick($event, 'password', evt.fields.password as string)
      "
    >
      <span>Password:</span>
      <strong>{{ evt.fields.password }}</strong>
    </button>
    <HttpDetails
      :evt="evt"
      @field-click="handleFieldClick"
      v-if="evt.type === 'http'"
    />
    <SshDetails
      :evt="evt"
      @field-click="handleFieldClick"
      v-if="evt.type === 'ssh'"
    />
    <SmtpDetails
      :evt="evt"
      v-if="evt.type === 'smtp'"
      @field-click="handleFieldClick"
    />
    <RdpDetails
      :evt="evt"
      v-if="evt.type === 'rdp'"
      @field-click="handleFieldClick"
    />
    <DnsDetails
      :evt="evt"
      v-if="evt.type === 'dns'"
      @field-click="handleFieldClick"
    />
    <SipDetails
      :evt="evt"
      v-if="evt.type === 'sip'"
      @field-click="handleFieldClick"
    />
  </div>
</template>

<style>
@reference "src/style.css";

.details {
  @apply inline-flex max-h-40 max-w-full flex-col gap-0.5 overflow-x-auto empty:hidden;

  span:first-child {
    @apply text-stone-400;
  }

  button {
    @apply inline text-left;

    &:hover {
      @apply text-primary-400;
    }
  }
}
</style>