Interactive
diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts
index 47eb474ab9ed2..bf9f90b03c22d 100644
--- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts
+++ b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts
@@ -13,7 +13,7 @@ import { DEFAULT_DATE_COLUMN_MIN_WIDTH } from '../../../timelines/components/tim
import {
COLUMN_SESSION_START,
COLUMN_EXECUTABLE,
- COLUMN_ENTRY_USER,
+ COLUMN_ENTRY_USER_ID,
COLUMN_INTERACTIVE,
COLUMN_HOST_NAME,
COLUMN_ENTRY_TYPE,
@@ -34,8 +34,8 @@ export const sessionsHeaders: ColumnHeaderOptions[] = [
},
{
columnHeaderType: defaultColumnHeaderType,
- id: 'process.entry_leader.user.name',
- display: COLUMN_ENTRY_USER,
+ id: 'process.entry_leader.user.id',
+ display: COLUMN_ENTRY_USER_ID,
},
{
columnHeaderType: defaultColumnHeaderType,
diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts
index 15e12212bb998..ef16595b99742 100644
--- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts
+++ b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts
@@ -39,10 +39,10 @@ export const COLUMN_EXECUTABLE = i18n.translate(
}
);
-export const COLUMN_ENTRY_USER = i18n.translate(
- 'xpack.securitySolution.sessionsView.columnEntryUser',
+export const COLUMN_ENTRY_USER_ID = i18n.translate(
+ 'xpack.securitySolution.sessionsView.columnEntryUserID',
{
- defaultMessage: 'User',
+ defaultMessage: 'User ID',
}
);
diff --git a/x-pack/plugins/session_view/common/types/process_tree/index.ts b/x-pack/plugins/session_view/common/types/process_tree/index.ts
index 4d8808d53999d..264d1685908ae 100644
--- a/x-pack/plugins/session_view/common/types/process_tree/index.ts
+++ b/x-pack/plugins/session_view/common/types/process_tree/index.ts
@@ -191,7 +191,7 @@ export interface ProcessEvent {
'@timestamp'?: string;
event?: {
kind?: EventKind;
- category?: string[];
+ category?: string | string[];
action?: EventAction | EventAction[];
id?: string;
};
diff --git a/x-pack/plugins/session_view/kibana.jsonc b/x-pack/plugins/session_view/kibana.jsonc
index 647990ab6a977..47585565fffde 100644
--- a/x-pack/plugins/session_view/kibana.jsonc
+++ b/x-pack/plugins/session_view/kibana.jsonc
@@ -1,7 +1,7 @@
{
"type": "plugin",
"id": "@kbn/session-view-plugin",
- "owner": "@elastic/awp-viz",
+ "owner": "@elastic/sec-cloudnative-integrations",
"plugin": {
"id": "sessionView",
"server": true,
diff --git a/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx b/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx
index e6f68ce6ae230..cf1da761fde96 100644
--- a/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx
+++ b/x-pack/plugins/session_view/public/components/detail_panel_alert_list_item/index.tsx
@@ -64,7 +64,9 @@ export const DetailPanelAlertListItem = ({
const { args, name: processName } = event.process ?? {};
const { event: processEvent } = event;
const forceState = !isInvestigated ? 'open' : undefined;
- const category = processEvent?.category?.[0];
+ const category = Array.isArray(processEvent?.category)
+ ? processEvent?.category?.[0]
+ : processEvent?.category;
const processEventAlertCategory = category ?? ProcessEventAlertCategory.process;
const alertCategoryDetailDisplayText =
category !== ProcessEventAlertCategory.process
diff --git a/x-pack/plugins/session_view/public/components/process_tree/helpers.ts b/x-pack/plugins/session_view/public/components/process_tree/helpers.ts
index 349a162d6b612..830306af4864f 100644
--- a/x-pack/plugins/session_view/public/components/process_tree/helpers.ts
+++ b/x-pack/plugins/session_view/public/components/process_tree/helpers.ts
@@ -266,6 +266,20 @@ export const autoExpandProcessTree = (processMap: ProcessMap, jumpToEntityId?: s
return processMap;
};
+// recusively collapses all children below provided node
+export const collapseProcessTree = (node: Process) => {
+ if (!node.autoExpand) {
+ return;
+ }
+
+ if (node.children) {
+ node.children.forEach((child) => {
+ child.autoExpand = false;
+ collapseProcessTree(child);
+ });
+ }
+};
+
export const processNewEvents = (
eventsProcessMap: ProcessMap,
events: ProcessEvent[] | undefined,
diff --git a/x-pack/plugins/session_view/public/components/process_tree/index.tsx b/x-pack/plugins/session_view/public/components/process_tree/index.tsx
index 9ba3845d0cab0..9dea1e07a8fdb 100644
--- a/x-pack/plugins/session_view/public/components/process_tree/index.tsx
+++ b/x-pack/plugins/session_view/public/components/process_tree/index.tsx
@@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n';
import { ProcessTreeNode } from '../process_tree_node';
import { BackToInvestigatedAlert } from '../back_to_investigated_alert';
import { useProcessTree } from './hooks';
+import { collapseProcessTree } from './helpers';
import { ProcessTreeLoadMoreButton } from '../process_tree_load_more_button';
import {
AlertStatusEventEntityIdMap,
@@ -97,6 +98,7 @@ export const ProcessTree = ({
verboseMode,
jumpToEntityId,
});
+ const [forceRerender, setForceRerender] = useState(0);
const eventsRemaining = useMemo(() => {
const total = data?.[0]?.total || 0;
@@ -126,6 +128,14 @@ export const ProcessTree = ({
setIsInvestigatedEventVisible(true);
}, [onProcessSelected]);
+ const handleCollapseProcessTree = useCallback(() => {
+ collapseProcessTree(sessionLeader);
+ if (scrollerRef.current) {
+ scrollerRef.current.scrollTop = 0;
+ }
+ setForceRerender(Math.random());
+ }, [sessionLeader]);
+
useEffect(() => {
if (setSearchResults) {
setSearchResults(searchResults);
@@ -160,6 +170,7 @@ export const ProcessTree = ({
ref={scrollerRef}
css={styles.sessionViewProcessTree}
data-test-subj="sessionView:sessionViewProcessTree"
+ key={forceRerender}
>
{sessionLeader && (
{
overflow: 'auto',
height: '100%',
backgroundColor: euiVars.euiColorLightestShade,
- paddingTop: size.base,
- paddingLeft: size.s,
};
const selectionArea: CSSObject = {
diff --git a/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap b/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap
index c2b05ef38a3e0..39e1778dd1f4a 100644
--- a/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap
+++ b/x-pack/plugins/session_view/public/components/process_tree_alert/__snapshots__/index.test.tsx.snap
@@ -54,6 +54,7 @@ Object {
>
cmd test alert
+
{
renderResult = mockedContext.render(
);
expect(renderResult.container.textContent?.replace(/\s+/g, ' ')).toEqual(
- ' bash started by vagrant'
+ ' bash started by vagrant '
);
});
diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx b/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx
index fa5c16bee19bd..6ffc4415fb47b 100644
--- a/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx
+++ b/x-pack/plugins/session_view/public/components/process_tree_node/index.tsx
@@ -20,7 +20,7 @@ import React, {
RefObject,
ReactElement,
} from 'react';
-import { EuiButton, EuiIcon, EuiToolTip, formatDate } from '@elastic/eui';
+import { EuiButton, EuiIcon, EuiToolTip, formatDate, EuiButtonIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { chain } from 'lodash';
@@ -61,6 +61,7 @@ export interface ProcessDeps {
onJumpToOutput: (entityId: string) => void;
loadNextButton?: ReactElement | null;
loadPreviousButton?: ReactElement | null;
+ handleCollapseProcessTree?: () => void;
}
/**
@@ -83,6 +84,7 @@ export function ProcessTreeNode({
onJumpToOutput,
loadPreviousButton,
loadNextButton,
+ handleCollapseProcessTree,
}: ProcessDeps) {
const [childrenExpanded, setChildrenExpanded] = useState(isSessionLeader || process.autoExpand);
const [alertsExpanded, setAlertsExpanded] = useState(false);
@@ -133,7 +135,15 @@ export function ProcessTreeNode({
const alertTypeCounts = useMemo(() => {
const alertCounts: AlertTypeCount[] = chain(alerts)
- .groupBy((alert) => alert.event?.category?.[0])
+ .groupBy((alert) => {
+ const category = alert.event?.category;
+
+ if (Array.isArray(category)) {
+ return category?.[0];
+ }
+
+ return category;
+ })
.map((processAlerts, alertCategory) => ({
category: alertCategory as ProcessEventAlertCategory,
count: processAlerts.length,
@@ -176,8 +186,12 @@ export function ProcessTreeNode({
}
onProcessSelected?.(process);
+
+ if (isSessionLeader && scrollerRef.current) {
+ scrollerRef.current.scrollTop = 0;
+ }
},
- [onProcessSelected, process]
+ [isSessionLeader, onProcessSelected, process, scrollerRef]
);
const processDetails = process.getDetails();
@@ -219,6 +233,19 @@ export function ProcessTreeNode({
const children = process.getChildren(verboseMode);
+ const user = processDetails?.process?.user;
+ const userName = useMemo(() => {
+ if (user?.name) {
+ return user.name;
+ } else if (user?.id === '0') {
+ return 'root';
+ } else if (user?.id) {
+ return `uid: ${user?.id}`;
+ }
+
+ return '-';
+ }, [user?.id, user?.name]);
+
if (!processDetails?.process) {
return null;
}
@@ -231,7 +258,6 @@ export function ProcessTreeNode({
parent,
working_directory: workingDirectory,
start,
- user,
} = processDetails.process;
const shouldRenderChildren = isSessionLeader || (childrenExpanded && children?.length > 0);
@@ -275,7 +301,14 @@ export function ProcessTreeNode({
-
{user?.name || 'ID: ' + user?.id}
+
{userName}
+
+
) : (
<>
diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts b/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts
index 3936fc35aac81..32048cfd97585 100644
--- a/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts
+++ b/x-pack/plugins/session_view/public/components/process_tree_node/styles.ts
@@ -95,7 +95,6 @@ export const useStyles = ({
display: 'block',
cursor: 'pointer',
position: 'relative',
- marginBottom: isSessionLeader ? size.s : '0px',
'&:hover:before': {
backgroundColor: hoverColor,
},
@@ -114,6 +113,10 @@ export const useStyles = ({
},
};
+ const jumpToTop: CSSObject = {
+ float: 'right',
+ };
+
const textSection: CSSObject = {
marginLeft: size.s,
span: {
@@ -131,13 +134,23 @@ export const useStyles = ({
display: 'inline-block',
verticalAlign: 'middle',
},
+ paddingLeft: PROCESS_TREE_LEFT_PADDING,
};
- const searchHighlight = `
- color: ${colors.fullShade};
- border-radius: '0px';
- background-color: ${searchResColor};
- `;
+ if (isSessionLeader) {
+ processNode.position = 'sticky';
+ processNode.top = '-' + size.base;
+ processNode.zIndex = 1;
+ processNode.borderTop = `${size.base} solid transparent`;
+ processNode.backgroundColor = euiVars.euiColorLightestShade;
+ processNode.borderBottom = border.editable;
+ }
+
+ const searchHighlight: CSSObject = {
+ color: colors.fullShade,
+ borderRadius: '0px',
+ backgroundColor: searchResColor,
+ };
const wrapper: CSSObject = {
paddingLeft: size.s,
@@ -188,6 +201,7 @@ export const useStyles = ({
icon,
textSection,
sessionLeader,
+ jumpToTop,
};
}, [depth, euiTheme, hasAlerts, hasInvestigatedAlert, isSelected, euiVars, isSessionLeader]);
diff --git a/x-pack/plugins/session_view/public/components/process_tree_node/text_highlight.tsx b/x-pack/plugins/session_view/public/components/process_tree_node/text_highlight.tsx
index 6d21726e0d430..c06b208e6c262 100644
--- a/x-pack/plugins/session_view/public/components/process_tree_node/text_highlight.tsx
+++ b/x-pack/plugins/session_view/public/components/process_tree_node/text_highlight.tsx
@@ -20,7 +20,6 @@ const css: CSSObject = {
display: 'inline',
fontSize: 0,
lineHeight: 0,
- verticalAlign: 'middle',
},
};
// Component that takes an array of matching indices in a text and pass down a highlight
diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx
index 955b042ff9cfb..5f52f5ff8e935 100644
--- a/x-pack/plugins/session_view/public/components/session_view/index.tsx
+++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx
@@ -201,6 +201,10 @@ export const SessionView = ({
[onProcessSelected, searchResults]
);
+ useEffect(() => {
+ onSearchIndexChange(0);
+ }, [onSearchIndexChange, searchResults]);
+
const handleOnAlertDetailsClosed = useCallback((alertUuid: string) => {
setFetchAlertStatus([alertUuid]);
}, []);
diff --git a/x-pack/plugins/session_view/public/utils/alert_category_display_test.test.ts b/x-pack/plugins/session_view/public/utils/alert_category_display_test.test.ts
index 24b474111b860..fdc5cbedfd82e 100644
--- a/x-pack/plugins/session_view/public/utils/alert_category_display_test.test.ts
+++ b/x-pack/plugins/session_view/public/utils/alert_category_display_test.test.ts
@@ -21,24 +21,22 @@ describe('getAlertCategoryDisplayText(alert, category)', () => {
it('should display rule name when alert category is process', () => {
expect(getAlertCategoryDisplayText(mockAlerts[0], ProcessEventAlertCategory.process)).toEqual(
- undefined
+ ''
);
});
it('should display rule name when alert category is undefined', () => {
- expect(getAlertCategoryDisplayText(mockAlerts[0], undefined)).toEqual(undefined);
+ expect(getAlertCategoryDisplayText(mockAlerts[0], undefined)).toEqual('');
});
it('should display rule name when file path is undefined', () => {
const fileAlert = { ...mockFileAlert, file: {} };
- expect(getAlertCategoryDisplayText(fileAlert, ProcessEventAlertCategory.file)).toEqual(
- undefined
- );
+ expect(getAlertCategoryDisplayText(fileAlert, ProcessEventAlertCategory.file)).toEqual('');
});
it('should display rule name when destination address is undefined and alert category is network', () => {
const networkAlert = { ...mockNetworkAlert, destination: undefined };
expect(getAlertCategoryDisplayText(networkAlert, ProcessEventAlertCategory.network)).toEqual(
- undefined
+ ''
);
});
});
diff --git a/x-pack/plugins/session_view/public/utils/alert_category_display_text.ts b/x-pack/plugins/session_view/public/utils/alert_category_display_text.ts
index 3ac2658f37e28..bf4c74681a2be 100644
--- a/x-pack/plugins/session_view/public/utils/alert_category_display_text.ts
+++ b/x-pack/plugins/session_view/public/utils/alert_category_display_text.ts
@@ -19,7 +19,7 @@ export const getAlertCategoryDisplayText = (alert: ProcessEvent, category: strin
if (filePath && category === ProcessEventAlertCategory.file) return dataOrDash(filePath);
if (destination?.address && category === ProcessEventAlertCategory.network)
return dataOrDash(getAlertNetworkDisplay(destination));
- return;
+ return '';
};
export const getAlertNetworkDisplay = (destination: ProcessEventIPAddress) => {
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index eb246088e6caf..d7ca1a1e8ae34 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -31385,7 +31385,6 @@
"xpack.securitySolution.kpiUsers.totalUsers.title": "Utilisateurs",
"xpack.securitySolution.kubernetes.columnContainer": "Conteneur",
"xpack.securitySolution.kubernetes.columnEntryType": "Type d’entrée",
- "xpack.securitySolution.kubernetes.columnEntryUser": "Utilisateur d’entrée de session",
"xpack.securitySolution.kubernetes.columnExecutable": "Leader de session",
"xpack.securitySolution.kubernetes.columnInteractive": "Interactivité",
"xpack.securitySolution.kubernetes.columnNode": "Nœud",
@@ -32054,7 +32053,6 @@
"xpack.securitySolution.selector.summaryView.options.summaryView.description": "Afficher un rendu du flux d'événements pour chaque alerte",
"xpack.securitySolution.sessionsView.columnEntrySourceIp": "IP source",
"xpack.securitySolution.sessionsView.columnEntryType": "Type",
- "xpack.securitySolution.sessionsView.columnEntryUser": "Utilisateur",
"xpack.securitySolution.sessionsView.columnExecutable": "Exécutable",
"xpack.securitySolution.sessionsView.columnHostName": "Nom d'hôte",
"xpack.securitySolution.sessionsView.columnInteractive": "Interactif",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 3a1a956245022..a7be27a7b1bec 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -31364,7 +31364,6 @@
"xpack.securitySolution.kpiUsers.totalUsers.title": "ユーザー",
"xpack.securitySolution.kubernetes.columnContainer": "コンテナー",
"xpack.securitySolution.kubernetes.columnEntryType": "エントリタイプ",
- "xpack.securitySolution.kubernetes.columnEntryUser": "セッションエントリユーザー",
"xpack.securitySolution.kubernetes.columnExecutable": "セッションリーダー",
"xpack.securitySolution.kubernetes.columnInteractive": "インタラクティブ",
"xpack.securitySolution.kubernetes.columnNode": "ノード",
@@ -32033,7 +32032,6 @@
"xpack.securitySolution.selector.summaryView.options.summaryView.description": "各アラートのイベントフローのレンダリングを表示",
"xpack.securitySolution.sessionsView.columnEntrySourceIp": "ソース IP",
"xpack.securitySolution.sessionsView.columnEntryType": "型",
- "xpack.securitySolution.sessionsView.columnEntryUser": "ユーザー",
"xpack.securitySolution.sessionsView.columnExecutable": "実行ファイル",
"xpack.securitySolution.sessionsView.columnHostName": "ホスト名",
"xpack.securitySolution.sessionsView.columnInteractive": "インタラクティブ",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index d46d6d85c9dcc..c0fbb29b33e85 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -31380,7 +31380,6 @@
"xpack.securitySolution.kpiUsers.totalUsers.title": "用户",
"xpack.securitySolution.kubernetes.columnContainer": "容器",
"xpack.securitySolution.kubernetes.columnEntryType": "条目类型",
- "xpack.securitySolution.kubernetes.columnEntryUser": "会话条目用户",
"xpack.securitySolution.kubernetes.columnExecutable": "会话 Leader",
"xpack.securitySolution.kubernetes.columnInteractive": "交互性",
"xpack.securitySolution.kubernetes.columnNode": "节点",
@@ -32049,7 +32048,6 @@
"xpack.securitySolution.selector.summaryView.options.summaryView.description": "查看每个告警的事件渲染",
"xpack.securitySolution.sessionsView.columnEntrySourceIp": "源 IP",
"xpack.securitySolution.sessionsView.columnEntryType": "类型",
- "xpack.securitySolution.sessionsView.columnEntryUser": "用户",
"xpack.securitySolution.sessionsView.columnExecutable": "可执行",
"xpack.securitySolution.sessionsView.columnHostName": "主机名",
"xpack.securitySolution.sessionsView.columnInteractive": "交互",