feat: show RDP session duration in Overview and Events (0.5.16)
Add session_duration_sec to EventSummary and a Duration column (HH:MM:SS / Nd HH:MM:SS).
This commit is contained in:
@@ -192,6 +192,7 @@ export interface EventSummary {
|
||||
title: string;
|
||||
summary: string;
|
||||
actor_user?: string | null;
|
||||
session_duration_sec?: number | null;
|
||||
rdg_flap?: boolean;
|
||||
rdg_flap_pair_event_id?: number | null;
|
||||
rdg_flap_qwinsta_event_id?: number | null;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
"""Human-readable session_duration_sec for event tables."""
|
||||
|
||||
export function formatSessionDuration(seconds: number | null | undefined): string {
|
||||
if (seconds == null || !Number.isFinite(seconds) || seconds < 0) {
|
||||
return "—";
|
||||
}
|
||||
const total = Math.floor(seconds);
|
||||
const days = Math.floor(total / 86_400);
|
||||
const hours = Math.floor((total % 86_400) / 3600);
|
||||
const minutes = Math.floor((total % 3600) / 60);
|
||||
const secs = total % 60;
|
||||
const clock = `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
|
||||
if (days > 0) {
|
||||
return `${days}д ${clock}`;
|
||||
}
|
||||
return clock;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
|
||||
export const APP_NAME = "Security Alert Center";
|
||||
export const APP_VERSION = "0.5.15";
|
||||
export const APP_VERSION = "0.5.16";
|
||||
export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;
|
||||
|
||||
@@ -238,6 +238,8 @@
|
||||
|
||||
<th>Пользователь</th>
|
||||
|
||||
<th title="Длительность сессии (из session_duration_sec)">Длительность</th>
|
||||
|
||||
<th>Версия агента</th>
|
||||
|
||||
<th>Severity</th>
|
||||
@@ -276,6 +278,8 @@
|
||||
|
||||
<td>{{ e.actor_user || "—" }}</td>
|
||||
|
||||
<td>{{ formatSessionDuration(e.session_duration_sec) }}</td>
|
||||
|
||||
<td>{{ e.product_version || "—" }}</td>
|
||||
|
||||
<td :class="'sev-' + e.severity">{{ e.severity }}</td>
|
||||
@@ -354,6 +358,7 @@ import RdgQwinstaModal from "../components/RdgQwinstaModal.vue";
|
||||
import { useRdgQwinsta } from "../composables/useRdgQwinsta";
|
||||
import { formatServerName } from "../utils/hostDisplay";
|
||||
import { hasRdgFlapUi, rdgQwinstaEventId } from "../utils/rdgFlap";
|
||||
import { formatSessionDuration } from "../utils/sessionDuration";
|
||||
import { markEventSessionTerminatedInList, showEventSessionTerminateButton } from "../utils/sessionActions";
|
||||
|
||||
const { qwinstaLoadingId, qwinstaModal, closeQwinstaModal, runQwinsta, runLogoff } = useRdgQwinsta();
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<th>Хост</th>
|
||||
<th>Имя сервера</th>
|
||||
<th>Пользователь</th>
|
||||
<th title="Длительность сессии (из session_duration_sec)">Длительность</th>
|
||||
<th>Версия агента</th>
|
||||
<th>Severity</th>
|
||||
<th>Type</th>
|
||||
@@ -50,6 +51,7 @@
|
||||
<td>{{ e.hostname }}</td>
|
||||
<td>{{ formatServerName(e.display_name) }}</td>
|
||||
<td>{{ e.actor_user || "—" }}</td>
|
||||
<td>{{ formatSessionDuration(e.session_duration_sec) }}</td>
|
||||
<td>{{ e.product_version || "—" }}</td>
|
||||
<td :class="'sev-' + e.severity">{{ e.severity }}</td>
|
||||
<td><code>{{ e.type }}</code></td>
|
||||
@@ -120,6 +122,7 @@ import {
|
||||
type EventsListState,
|
||||
} from "../utils/eventsListQuery";
|
||||
import { formatServerName } from "../utils/hostDisplay";
|
||||
import { formatSessionDuration } from "../utils/sessionDuration";
|
||||
import { markEventSessionTerminatedInList, showEventSessionTerminateButton } from "../utils/sessionActions";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
Reference in New Issue
Block a user