From 2fc119874c0e7b41d3935762147f36b4469bf074 Mon Sep 17 00:00:00 2001 From: Galia Ilanov Date: Thu, 30 Mar 2023 11:00:25 +0300 Subject: [PATCH 1/6] findings impact widget and small UI adjustements --- .../SeverityDisplay/severity-display.scss | 11 ++ .../SeverityWithCvssDisplay/index.js | 15 +-- .../severity-with-cvss-display.scss | 0 ui/src/components/Table/index.js | 20 ++-- ui/src/layout/AssetScans/AssetScansTable.js | 20 +++- .../Dashboard/FindingsImpactWidget/index.js | 91 +++++++++++++++ .../findings-tabs-widget.scss | 32 +++++ .../Dashboard/FindingsTabsWidget/index.js | 57 ++++++++- .../Dashboard/FindingsTrendsWidget/index.js | 4 +- .../Dashboard/RiskiestAssetsWidget/index.js | 109 ++++++------------ .../riskiest-assets-widget.scss | 22 ---- ui/src/layout/Dashboard/index.js | 4 +- .../MisconfigurationTable.js | 15 ++- .../TabMisconfigurationDetails.js | 19 ++- .../Findings/Misconfigurations/utils.js | 5 + .../TabVulnerabilityDetails.js | 16 ++- .../Vulnerabilities/VulnerabilitiesTable.js | 6 +- .../layout/Findings/Vulnerabilities/utils.js | 33 ------ ui/src/layout/Findings/index.js | 63 ++++++++-- .../Scans/ScanConfigWizardModal/index.js | 4 +- ui/src/layout/Scans/Scans/ScansTable.js | 4 +- .../FindingsSystemFilterLinks/index.js | 7 +- .../layout/detail-displays/Findings/index.js | 13 ++- .../detail-displays/ScanDetails/index.js | 2 +- ui/src/utils/systemConsts.js | 23 ++-- ui/src/utils/utils.js | 36 +++++- 26 files changed, 423 insertions(+), 208 deletions(-) rename ui/src/{layout/Findings/Vulnerabilities => components}/SeverityWithCvssDisplay/index.js (68%) rename ui/src/{layout/Findings/Vulnerabilities => components}/SeverityWithCvssDisplay/severity-with-cvss-display.scss (100%) create mode 100644 ui/src/layout/Dashboard/FindingsImpactWidget/index.js create mode 100644 ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss delete mode 100644 ui/src/layout/Dashboard/RiskiestAssetsWidget/riskiest-assets-widget.scss create mode 100644 ui/src/layout/Findings/Misconfigurations/utils.js delete mode 100644 ui/src/layout/Findings/Vulnerabilities/utils.js diff --git a/ui/src/components/SeverityDisplay/severity-display.scss b/ui/src/components/SeverityDisplay/severity-display.scss index 5d3f1353a..2f024a7c9 100644 --- a/ui/src/components/SeverityDisplay/severity-display.scss +++ b/ui/src/components/SeverityDisplay/severity-display.scss @@ -5,4 +5,15 @@ .severity-title { margin-left: 5px; } +} + +.severity-with-cvss-display { + display: flex; + align-items: center; + + .cvss-score-display { + margin-left: 3px; + font-size: 10px; + line-height: 18px; + } } \ No newline at end of file diff --git a/ui/src/layout/Findings/Vulnerabilities/SeverityWithCvssDisplay/index.js b/ui/src/components/SeverityWithCvssDisplay/index.js similarity index 68% rename from ui/src/layout/Findings/Vulnerabilities/SeverityWithCvssDisplay/index.js rename to ui/src/components/SeverityWithCvssDisplay/index.js index 1d4140405..5bca36b33 100644 --- a/ui/src/layout/Findings/Vulnerabilities/SeverityWithCvssDisplay/index.js +++ b/ui/src/components/SeverityWithCvssDisplay/index.js @@ -1,15 +1,10 @@ import React from 'react'; import SeverityDisplay, { SEVERITY_ITEMS } from 'components/SeverityDisplay'; import { TooltipWrapper } from 'components/Tooltip'; +import { toCapitalized } from 'utils/utils'; import './severity-with-cvss-display.scss'; -const SEVERITY_NOT_ALIGNED_MESSAGE = ( -
- While the scores may differ, the VMClarity (linux distribution severity) is more significant in your context than the CVSS base impact score. -
-); - const SeverityWithCvssDisplay = ({severity, cvssScore, cvssSeverity, compareTooltipId}) => { if (!severity) { return null; @@ -17,12 +12,18 @@ const SeverityWithCvssDisplay = ({severity, cvssScore, cvssSeverity, compareTool const showSeverityTooltip = !!cvssSeverity && cvssSeverity !== severity && !(cvssSeverity === SEVERITY_ITEMS.NONE.value && severity === SEVERITY_ITEMS.NEGLIGIBLE.value); + + const severityNotAlignedMessage = ( +
+ {`Although the CVSS base impact score is ${cvssScore} (${toCapitalized(cvssSeverity || "")}), the linux distribution severity reflects the risk more accurately.`} +
+ ); return (
{!!cvssScore &&
{`(cvss ${cvssScore})`}
} - {!!showSeverityTooltip && *} + {!!showSeverityTooltip && *}
); } diff --git a/ui/src/layout/Findings/Vulnerabilities/SeverityWithCvssDisplay/severity-with-cvss-display.scss b/ui/src/components/SeverityWithCvssDisplay/severity-with-cvss-display.scss similarity index 100% rename from ui/src/layout/Findings/Vulnerabilities/SeverityWithCvssDisplay/severity-with-cvss-display.scss rename to ui/src/components/SeverityWithCvssDisplay/severity-with-cvss-display.scss diff --git a/ui/src/components/Table/index.js b/ui/src/components/Table/index.js index a954ac800..c9a161d8a 100644 --- a/ui/src/components/Table/index.js +++ b/ui/src/components/Table/index.js @@ -254,7 +254,15 @@ const Table = props => { return ( -
+
{ + if (!!onLineClick) { + onLineClick(row.original); + } + }} + > { row.cells.map(cell => { const {className, alignToTop} = cell.column; @@ -267,15 +275,7 @@ const Table = props => { const isTextValue = !!cell.column.accessor; return ( -
{ - if (!!onLineClick) { - onLineClick(row.original); - } - }} - >{isTextValue ? cell.value : cell.render('Cell')}
+
{isTextValue ? cell.value : cell.render('Cell')}
) }) } diff --git a/ui/src/layout/AssetScans/AssetScansTable.js b/ui/src/layout/AssetScans/AssetScansTable.js index 4f4298f05..8507b8112 100644 --- a/ui/src/layout/AssetScans/AssetScansTable.js +++ b/ui/src/layout/AssetScans/AssetScansTable.js @@ -6,6 +6,14 @@ import { FILTER_TYPES } from 'context/FiltersProvider'; const TABLE_TITLE = "asset scans"; +const STATUS_MAPPING = { + NOT_SCANNED: "Not Scanned", + INIT: "Initialized", + ATTACHED: "Volume Snapshot Attached", + IN_PROGRESS: "In Progress", + DONE: "Done" +} + const AssetScansTable = () => { const columns = useMemo(() => [ { @@ -36,6 +44,16 @@ const AssetScansTable = () => { }, disableSort: true }, + { + Header: "Status", + id: "status", + accessor: original => { + const {state} = original?.status?.general || {}; + + return STATUS_MAPPING[state]; + }, + disableSort: true + }, getVulnerabilitiesColumnConfigItem(TABLE_TITLE), ...getFindingsColumnsConfigList(TABLE_TITLE) ], []); @@ -45,7 +63,7 @@ const AssetScansTable = () => { columns={columns} url={APIS.ASSET_SCANS} expand="scan,target" - select="id,target,summary,scan" + select="id,target,summary,scan,status" tableTitle={TABLE_TITLE} filterType={FILTER_TYPES.ASSET_SCANS} withMargin diff --git a/ui/src/layout/Dashboard/FindingsImpactWidget/index.js b/ui/src/layout/Dashboard/FindingsImpactWidget/index.js new file mode 100644 index 000000000..1d10f59a9 --- /dev/null +++ b/ui/src/layout/Dashboard/FindingsImpactWidget/index.js @@ -0,0 +1,91 @@ +import React from 'react'; +import SeverityWithCvssDisplay from 'components/SeverityWithCvssDisplay'; +import { getHigestVersionCvssData } from 'utils/utils'; +import { FINDINGS_MAPPING, VULNERABIITY_FINDINGS_ITEM, APIS } from 'utils/systemConsts'; +import FindingsTabsWidget from '../FindingsTabsWidget'; + +const FINDINGS_ITEMS = [VULNERABIITY_FINDINGS_ITEM, ...Object.values(FINDINGS_MAPPING)]; + +const TABS_COLUMNS_MAPPING = { + [VULNERABIITY_FINDINGS_ITEM.dataKey]: { + headerItems: ["Name", "Severity"], + bodyItems: [ + {dataKey: "vulnerability.vulnerabilityName"}, + {customDisplay: ({vulnerability}) => { + const {severity, cvss, vulnerabilityName} = vulnerability || {}; + const {score, severity: cvssSeverity} = getHigestVersionCvssData(cvss); + + return ( + + ) + }} + ] + }, + [FINDINGS_MAPPING.EXPLOITS.dataKey]: { + headerItems: ["Vulnerability name"], + bodyItems: [ + {dataKey: "exploit.cveID"} + ] + }, + [FINDINGS_MAPPING.MISCONFIGURATIONS.dataKey]: { + headerItems: ["Test description"], + bodyItems: [ + {dataKey: "misconfiguration.testDescription"} + ] + }, + [FINDINGS_MAPPING.SECRETS.dataKey]: { + headerItems: ["Fingerprint"], + bodyItems: [ + {dataKey: "secret.fingerprint"} + ] + }, + [FINDINGS_MAPPING.MALWARE.dataKey]: { + headerItems: ["Malware name"], + bodyItems: [ + {dataKey: "malware.malwareName"} + ] + }, + [FINDINGS_MAPPING.ROOTKITS.dataKey]: { + headerItems: ["Rootkit name"], + bodyItems: [ + {dataKey: "rootkit.rootkitName"} + ] + }, + [FINDINGS_MAPPING.PACKAGES.dataKey]: { + headerItems: ["Package name", "Version"], + bodyItems: [ + {dataKey: "package.name"}, + {dataKey: "package.version"} + ] + } +} + +const FindingsImpactWidget = ({className}) => ( + { + const {headerItems=[]} = TABS_COLUMNS_MAPPING[selectedId] || {}; + + return ( + ([...headerItems, "Affected assets"]) + ) + }} + getBodyItems={(selectedId) => { + const {bodyItems=[]} = TABS_COLUMNS_MAPPING[selectedId] || {}; + + return ([...bodyItems, {dataKey: "affectedAssetsCount"}]) + }} + /> +) + +export default FindingsImpactWidget; \ No newline at end of file diff --git a/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss b/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss new file mode 100644 index 000000000..5538c503d --- /dev/null +++ b/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss @@ -0,0 +1,32 @@ +@import 'utils/scss_variables.module.scss'; + +.findings-tabs-widget { + .tabbed-widget-table-wrapper { + height: calc(100% - 70px); + overflow-y: auto; + + .tabbed-widget-table { + font-size: 14px; + border-collapse: collapse; + width: 100%; + + thead { + font-size: 12px; + text-align: left; + text-transform: uppercase; + + } + tbody tr { + border-bottom: 1px solid $color-grey-light; + } + th { + padding-top: 10px; + white-space: nowrap; + } + td { + padding: 12px 0 5px 0; + overflow-wrap: anywhere; + } + } + } +} \ No newline at end of file diff --git a/ui/src/layout/Dashboard/FindingsTabsWidget/index.js b/ui/src/layout/Dashboard/FindingsTabsWidget/index.js index 7abfe6842..52fdfe896 100644 --- a/ui/src/layout/Dashboard/FindingsTabsWidget/index.js +++ b/ui/src/layout/Dashboard/FindingsTabsWidget/index.js @@ -1,13 +1,46 @@ import React, { useState } from 'react'; import classnames from 'classnames'; +import { get } from 'lodash'; +import { useFetch } from 'hooks'; +import Loader from 'components/Loader'; import Tabs from 'components/Tabs'; import IconWithTooltip from 'components/IconWithTooltip'; -import { FINDINGS_MAPPING, VULNERABIITY_FINDINGS_ITEM } from 'utils/systemConsts'; import WidgetWrapper from '../WidgetWrapper'; import COLORS from 'utils/scss_variables.module.scss'; -const FINDINGS_ITEMS = [VULNERABIITY_FINDINGS_ITEM, ...Object.values(FINDINGS_MAPPING).filter(({value}) => value !== FINDINGS_MAPPING.PACKAGES.value)]; +import './findings-tabs-widget.scss'; + +const WidgetContent = ({data=[], maxItems, getHeaderItems, getBodyItems, selectedId}) => { + const displayData = data.slice(0, maxItems); + + return ( + + + + {getHeaderItems(selectedId).map((item, index, items) => ( + + ))} + + + + { + displayData.map((item, index) => { + return ( + + {getBodyItems(selectedId).map(({dataKey, customDisplay: CustomDisplay}, index, items) => ( + + ))} + + ) + }) + } + +
{item}
+ {!!CustomDisplay ? : get(item, dataKey)} +
+ ) +} const Tab = ({widgetName, title, icon, isActive}) => ( ( /> ) -const FindingsTabsWidget = ({widgetName, className, title, tabContent: TabContent}) => { - const WIDGET_TAB_ITEMS = FINDINGS_ITEMS.map(({dataKey, icon, title}) => ( +const FindingsTabsWidget = ({widgetName, findingsItems, className, title, url, maxItems, getHeaderItems, getBodyItems}) => { + const [{data, error, loading}] = useFetch(url, {urlPrefix: "ui"}); + + const WIDGET_TAB_ITEMS = findingsItems.map(({dataKey, icon, title}) => ( {id: dataKey, customTitle: ({isActive}) => } )) @@ -34,7 +69,19 @@ const FindingsTabsWidget = ({widgetName, className, title, tabContent: TabConten onClick={({id}) => setSelectedTabId(id)} tabItemPadding={15} /> -
{!!TabContent ? :
TBD
}
+
+ { + loading ? : (error ? null : + + ) + } +
) } diff --git a/ui/src/layout/Dashboard/FindingsTrendsWidget/index.js b/ui/src/layout/Dashboard/FindingsTrendsWidget/index.js index 0ad49f92e..16b5a238e 100644 --- a/ui/src/layout/Dashboard/FindingsTrendsWidget/index.js +++ b/ui/src/layout/Dashboard/FindingsTrendsWidget/index.js @@ -105,7 +105,7 @@ const WidgetChart = ({data, selectedFilters}) => { } const FindingsTrendsWidget = ({className}) => { - const {value, label} = TIME_RANGES.HOUR; + const {value, label} = TIME_RANGES.WEEK; const [selectedRange, setSelectedRange] = useState({value, label}); const [{data, error, loading}, fetchData] = useFetch(APIS.DASHBOARD_FINDINGS_TRENDS, {loadOnMount: false}); @@ -121,7 +121,7 @@ const FindingsTrendsWidget = ({className}) => { ]); return ( - +
{ diff --git a/ui/src/layout/Dashboard/RiskiestAssetsWidget/index.js b/ui/src/layout/Dashboard/RiskiestAssetsWidget/index.js index 17bc4668b..4faf8aced 100644 --- a/ui/src/layout/Dashboard/RiskiestAssetsWidget/index.js +++ b/ui/src/layout/Dashboard/RiskiestAssetsWidget/index.js @@ -1,80 +1,43 @@ import React from 'react'; -import { useFetch } from 'hooks'; -import Loader from 'components/Loader'; import VulnerabilitiesDisplay, { VULNERABILITY_SEVERITY_ITEMS } from 'components/VulnerabilitiesDisplay'; -import { APIS, VULNERABIITY_FINDINGS_ITEM } from 'utils/systemConsts'; +import { APIS, VULNERABIITY_FINDINGS_ITEM, FINDINGS_MAPPING } from 'utils/systemConsts'; import FindingsTabsWidget from '../FindingsTabsWidget'; -import './riskiest-assets-widget.scss'; - -const WidgetContent = ({data=[], maxItems, getCountDisplay}) => { - const displayData = data.slice(0, maxItems); - - return ( - - - - - - - - - - { - displayData.map((item, index) => { - const {name, type} = item?.assetInfo || {}; - - return ( - - - - - - ) - }) +const FINDINGS_ITEMS = [VULNERABIITY_FINDINGS_ITEM, ...Object.values(FINDINGS_MAPPING).filter(({value}) => value !== FINDINGS_MAPPING.PACKAGES.value)]; + +const RiskiestAssetsWidget = ({className}) => ( + (["Name", "Type", "Findings"])} + getBodyItems={(selectedId) => ([ + {dataKey: "assetInfo.name"}, + {dataKey: "assetInfo.type"}, + {customDisplay: ({count, assetInfo, ...props}) => { + if (selectedId === VULNERABIITY_FINDINGS_ITEM.dataKey) { + const counters = Object.values(VULNERABILITY_SEVERITY_ITEMS).reduce((acc, curr) => { + const {totalKey, countKey} = curr; + + return {...acc, [totalKey]: props[countKey]}; + }, {}); + + return ( + + ) } - -
NameTypeFindings
{name}{type}{getCountDisplay(item || {})}
- ) -} - -const RiskiestAssetsWidget = ({className, maxItems=5}) => { - const [{data, error, loading}] = useFetch(APIS.DASHBOARD_RISKIEST_ASSETS, {urlPrefix: "ui"}); - - return ( - ( - loading ? : (error ? null : - { - if (selectedTabId === VULNERABIITY_FINDINGS_ITEM.dataKey) { - const counters = Object.values(VULNERABILITY_SEVERITY_ITEMS).reduce((acc, curr) => { - const {totalKey, countKey} = curr; - - return {...acc, [totalKey]: props[countKey]}; - }, {}); - - return ( - - ) - } - - return count; - }} - /> - ) - )} - /> - ) -} + + return count; + }} + ])} + /> +) export default RiskiestAssetsWidget; \ No newline at end of file diff --git a/ui/src/layout/Dashboard/RiskiestAssetsWidget/riskiest-assets-widget.scss b/ui/src/layout/Dashboard/RiskiestAssetsWidget/riskiest-assets-widget.scss deleted file mode 100644 index 4e6f41896..000000000 --- a/ui/src/layout/Dashboard/RiskiestAssetsWidget/riskiest-assets-widget.scss +++ /dev/null @@ -1,22 +0,0 @@ -@import 'utils/scss_variables.module.scss'; - -.tabbed-widget-table { - font-size: 14px; - border-collapse: collapse; - width: 100%; - - thead { - font-size: 12px; - text-align: left; - text-transform: uppercase; - } - tbody tr { - border-bottom: 1px solid $color-grey-light; - } - th { - padding-top: 10px; - } - td { - padding: 12px 0 5px 0; - } -} \ No newline at end of file diff --git a/ui/src/layout/Dashboard/index.js b/ui/src/layout/Dashboard/index.js index 8e4aa32d7..ca3346009 100644 --- a/ui/src/layout/Dashboard/index.js +++ b/ui/src/layout/Dashboard/index.js @@ -4,7 +4,7 @@ import CounterDisplay from './CounterDisplay'; import FindingsTrendsWidget from './FindingsTrendsWidget'; import RiskiestRegionsWidget from './RiskiestRegionsWidget'; import RiskiestAssetsWidget from './RiskiestAssetsWidget'; -import FindingsTabsWidget from './FindingsTabsWidget'; +import FindingsImpactWidget from './FindingsImpactWidget'; import COLORS from 'utils/scss_variables.module.scss'; @@ -27,7 +27,7 @@ const Dashboard = () => { - +
) } diff --git a/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js b/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js index bb8f020da..a8fee6a37 100644 --- a/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js +++ b/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js @@ -1,19 +1,26 @@ import React, { useMemo } from 'react'; import { getAssetAndScanColumnsConfigList } from 'layout/Findings/utils'; import FindingsTablePage from '../FindingsTablePage'; +import { MISCONFIGURATION_SEVERITY_MAP } from './utils'; const MisconfigurationsTable = () => { const columns = useMemo(() => [ { - Header: "File path", - id: "path", - accessor: "findingInfo.path", + Header: "Test ID", + id: "testId", + accessor: "findingInfo.testID", + disableSort: true + }, + { + Header: "Severity", + id: "severity", + accessor: original => MISCONFIGURATION_SEVERITY_MAP[original.findingInfo?.severity], disableSort: true }, { Header: "Description", id: "description", - accessor: "findingInfo.description", + accessor: "findingInfo.testDescription", disableSort: true }, ...getAssetAndScanColumnsConfigList() diff --git a/ui/src/layout/Findings/Misconfigurations/TabMisconfigurationDetails.js b/ui/src/layout/Findings/Misconfigurations/TabMisconfigurationDetails.js index f00725e0a..65cb0fee9 100644 --- a/ui/src/layout/Findings/Misconfigurations/TabMisconfigurationDetails.js +++ b/ui/src/layout/Findings/Misconfigurations/TabMisconfigurationDetails.js @@ -1,19 +1,32 @@ import React from 'react'; import TitleValueDisplay, { TitleValueDisplayRow } from 'components/TitleValueDisplay'; import DoublePaneDisplay from 'components/DoublePaneDisplay'; +import { MISCONFIGURATION_SEVERITY_MAP } from './utils'; const TabMisconfigurationDetails = ({data}) => { - const {path, description} = data.findingInfo; + const {testID, severity, testDescription, scannerName, scannedPath, remediation, testCategory, message} = data.findingInfo; return ( ( <> - {path} + {testID} + {MISCONFIGURATION_SEVERITY_MAP[severity]} - {description} + {scannerName} + {scannedPath} + + + {testCategory} + {remediation} + + + {message} + + + {testDescription} )} diff --git a/ui/src/layout/Findings/Misconfigurations/utils.js b/ui/src/layout/Findings/Misconfigurations/utils.js new file mode 100644 index 000000000..97979c492 --- /dev/null +++ b/ui/src/layout/Findings/Misconfigurations/utils.js @@ -0,0 +1,5 @@ +export const MISCONFIGURATION_SEVERITY_MAP = { + MisconfigurationHighSeverity: "High", + MisconfigurationMediumSeverity: "Medium", + MisconfigurationLowSeverity: "Low" +}; \ No newline at end of file diff --git a/ui/src/layout/Findings/Vulnerabilities/TabVulnerabilityDetails.js b/ui/src/layout/Findings/Vulnerabilities/TabVulnerabilityDetails.js index 5b42d23eb..0c5df0cba 100644 --- a/ui/src/layout/Findings/Vulnerabilities/TabVulnerabilityDetails.js +++ b/ui/src/layout/Findings/Vulnerabilities/TabVulnerabilityDetails.js @@ -4,11 +4,10 @@ import DoublePaneDisplay from 'components/DoublePaneDisplay'; import Title from 'components/Title'; import ProgressBar, { STATUS_MAPPPING } from 'components/ProgressBar'; import SeverityDisplay from 'components/SeverityDisplay'; -import { formatDate } from 'utils/utils'; +import SeverityWithCvssDisplay from 'components/SeverityWithCvssDisplay'; +import { formatDate, getHigestVersionCvssData } from 'utils/utils'; import LinksDisplay from 'layout/Findings/LinkesDisplay'; import ScoreTag from './ScoreTag'; -import SeverityWithCvssDisplay from './SeverityWithCvssDisplay'; -import { getHigestVersionCvssData } from './utils'; import COLORS from 'utils/scss_variables.module.scss'; @@ -31,7 +30,7 @@ const ScoreBar = ({score}) => { } const TabVulnerabilityDetails = ({data}) => { - const {findingInfo, scan} = data; + const {id, findingInfo, scan} = data; const {vulnerabilityName, package: packageInfo, severity, fix, cvss, description, links} = findingInfo; const {name: packageName, version} = packageInfo; @@ -49,7 +48,14 @@ const TabVulnerabilityDetails = ({data}) => { {version} - + + + {formatDate(scan.startTime)} diff --git a/ui/src/layout/Findings/Vulnerabilities/VulnerabilitiesTable.js b/ui/src/layout/Findings/Vulnerabilities/VulnerabilitiesTable.js index e0decafe9..d97612a5a 100644 --- a/ui/src/layout/Findings/Vulnerabilities/VulnerabilitiesTable.js +++ b/ui/src/layout/Findings/Vulnerabilities/VulnerabilitiesTable.js @@ -1,9 +1,9 @@ import React, { useMemo } from 'react'; import ExpandableList from 'components/ExpandableList'; +import SeverityWithCvssDisplay from 'components/SeverityWithCvssDisplay'; +import { getHigestVersionCvssData } from 'utils/utils'; import { getAssetAndScanColumnsConfigList } from 'layout/Findings/utils'; import FindingsTablePage from '../FindingsTablePage'; -import SeverityWithCvssDisplay from './SeverityWithCvssDisplay'; -import { getHigestVersionCvssData } from './utils'; const VulnerabilitiesTable = () => { const columns = useMemo(() => [ @@ -25,7 +25,7 @@ const VulnerabilitiesTable = () => { ) diff --git a/ui/src/layout/Findings/Vulnerabilities/utils.js b/ui/src/layout/Findings/Vulnerabilities/utils.js deleted file mode 100644 index 3e1992e44..000000000 --- a/ui/src/layout/Findings/Vulnerabilities/utils.js +++ /dev/null @@ -1,33 +0,0 @@ -import { orderBy, isEmpty } from 'lodash'; -import CVSS from '@turingpointde/cvss.js'; - -export const getHigestVersionCvssData = (cvssData) => { - if (isEmpty(cvssData)) { - return {}; - } - - const sortedCvss = orderBy(cvssData || [], ["version"], ["desc"]); - - const {vector, metrics, version} = sortedCvss[0]; - - const serverData = { - vector, - score: metrics.baseScore, - exploitabilityScore: metrics.exploitabilityScore, - impactScore: metrics.impactScore - } - - if (version === "2.0") { - return serverData - } - - const cvssVector = CVSS(vector); - - return { - ...serverData, - temporalScore: cvssVector.getTemporalScore(), - environmentalScore: cvssVector.getEnvironmentalScore(), - severity: cvssVector.getRating(), - metrics: cvssVector.getDetailedVectorObject().metrics, - } -} \ No newline at end of file diff --git a/ui/src/layout/Findings/index.js b/ui/src/layout/Findings/index.js index a4dddb183..30157a444 100644 --- a/ui/src/layout/Findings/index.js +++ b/ui/src/layout/Findings/index.js @@ -1,6 +1,7 @@ import React from 'react'; import { useLocation } from 'react-router-dom'; import TabbedPage from 'components/TabbedPage'; +import { FINDINGS_MAPPING, VULNERABIITY_FINDINGS_ITEM, ROUTES } from 'utils/systemConsts'; import Vulnerabilities from './Vulnerabilities'; import Exploits from './Exploits'; import Misconfigurations from './Misconfigurations'; @@ -10,17 +11,65 @@ import Rootkits from './Rootkits'; import Packages from './Packages'; const FINDINGS_TAB_ITEMS = { - VULNERABILITIES: {id: "vulnerabilities", path: "vulnerabilities", title: "Vulnerabilities", component: Vulnerabilities}, - EXPLOITS: {id: "exploits", path: "exploits", title: "Exploits", component: Exploits}, - MISCONFIGURATIONS: {id: "misconfigurations", path: "misconfigurations", title: "Misconfigurations", component: Misconfigurations}, - SECRETS: {id: "secrets", path: "secrets", title: "Secrets", component: Secrets}, - MALWARE: {id: "malware", path: "malware", title: "Malware", component: Malware}, - ROOTKITS: {id: "rootkits", path: "rootkits", title: "Rootkits", component: Rootkits}, - PACKAGES: {id: "packages", path: "packages", title: "Packages", component: Packages}, + VULNERABILITIES: { + id: "vulnerabilities", + path: "vulnerabilities", + title: "Vulnerabilities", + component: Vulnerabilities, + findingsType: VULNERABIITY_FINDINGS_ITEM.value + }, + EXPLOITS: { + id: "exploits", + path: "exploits", + title: "Exploits", + component: Exploits, + findingsType: FINDINGS_MAPPING.EXPLOITS.value + }, + MISCONFIGURATIONS: { + id: "misconfigurations", + path: "misconfigurations", + title: "Misconfigurations", + component: Misconfigurations, + findingsType: FINDINGS_MAPPING.MISCONFIGURATIONS.value + }, + SECRETS: { + id: "secrets", + path: "secrets", + title: "Secrets", + component: Secrets, + findingsType: FINDINGS_MAPPING.SECRETS.value + }, + MALWARE: { + id: "malware", + path: "malware", + title: "Malware", + component: Malware, + findingsType: FINDINGS_MAPPING.MALWARE.value + }, + ROOTKITS: { + id: "rootkits", + path: "rootkits", + title: "Rootkits", + component: Rootkits, + findingsType: FINDINGS_MAPPING.ROOTKITS.value + }, + PACKAGES: { + id: "packages", + path: "packages", + title: "Packages", + component: Packages, + findingsType: FINDINGS_MAPPING.PACKAGES.value + } } export const FINDINGS_PATHS = Object.keys(FINDINGS_TAB_ITEMS).reduce((acc, curr) => ({...acc, [curr]: FINDINGS_TAB_ITEMS[curr].path}), {}); +export const getFindingsAbsolutePathByFindingType = type => { + const relativePath = Object.values(FINDINGS_TAB_ITEMS).find(({findingsType}) => type === findingsType)?.path; + + return `${ROUTES.FINDINGS}/${relativePath}` +}; + const Findings = () => { const {pathname} = useLocation(); diff --git a/ui/src/layout/Scans/ScanConfigWizardModal/index.js b/ui/src/layout/Scans/ScanConfigWizardModal/index.js index ae7fbc7ae..fb93cd42d 100644 --- a/ui/src/layout/Scans/ScanConfigWizardModal/index.js +++ b/ui/src/layout/Scans/ScanConfigWizardModal/index.js @@ -54,7 +54,7 @@ const ScanConfigWizardModal = ({initialData, onClose, onSubmitSuccess}) => { if (!isEmpty(regions)) { initialValues.scope.regions = regions.map(({name, vpcs}) => { - return {name, vpcs: !vpcs ? VPCS_EMPTY_VALUE : vpcs.map(({id, securityGroups}) => { + return {name, vpcs: isEmpty(vpcs) ? VPCS_EMPTY_VALUE : vpcs.map(({id, securityGroups}) => { return {id: id || "", securityGroups: (securityGroups || []).map(({id}) => id)} })} }) @@ -112,7 +112,7 @@ const ScanConfigWizardModal = ({initialData, onClose, onSubmitSuccess}) => { objectType: "AwsScanScope", allRegions: isAllScope, regions: isAllScope ? [] : regions.map(({name, vpcs}) => { - return {name, vpcs: vpcs.map(({id, securityGroups}) => { + return {name, vpcs: vpcs.filter(({id}) => !!id).map(({id, securityGroups}) => { return {id, securityGroups: securityGroups.map(id => ({id}))} })} }), diff --git a/ui/src/layout/Scans/Scans/ScansTable.js b/ui/src/layout/Scans/Scans/ScansTable.js index f76b39a33..9ca4a5868 100644 --- a/ui/src/layout/Scans/Scans/ScansTable.js +++ b/ui/src/layout/Scans/Scans/ScansTable.js @@ -61,7 +61,7 @@ const ScansTable = () => { id: "status", Cell: ({row}) => { const {id, state, stateReason, stateMessage, summary} = row.original; - const {jobsCompleted, jobsLeftToRun} = summary; + const {jobsCompleted, jobsLeftToRun} = summary || {}; return ( { Header: "Scanned assets", id: "assets", accessor: original => { - const {jobsCompleted, jobsLeftToRun} = original.summary; + const {jobsCompleted, jobsLeftToRun} = original.summary || {}; return `${jobsCompleted}/${jobsCompleted + jobsLeftToRun}`; }, diff --git a/ui/src/layout/detail-displays/Findings/FindingsSystemFilterLinks/index.js b/ui/src/layout/detail-displays/Findings/FindingsSystemFilterLinks/index.js index 1fc2aa8a3..9c9ee3197 100644 --- a/ui/src/layout/detail-displays/Findings/FindingsSystemFilterLinks/index.js +++ b/ui/src/layout/detail-displays/Findings/FindingsSystemFilterLinks/index.js @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import Button from 'components/Button'; import Icon from 'components/Icon'; import { FINDINGS_MAPPING, VULNERABIITY_FINDINGS_ITEM } from 'utils/systemConsts'; +import { getFindingsAbsolutePathByFindingType } from 'layout/Findings'; import './findings-system-filter-links.scss'; @@ -21,12 +22,12 @@ const FindingsSystemFilterLinks = ({totalVulnerabilitiesCount, findingsSummary})
See other findings:
{ - [VULNERABIITY_FINDINGS_ITEM, ...Object.values(FINDINGS_MAPPING)].map(({value, totalKey, title, icon, appRoute}) => { + [VULNERABIITY_FINDINGS_ITEM, ...Object.values(FINDINGS_MAPPING)].map(({value, totalKey, title, icon}) => { const LinkTitle = VULNERABIITY_FINDINGS_ITEM.value === value ? `${totalVulnerabilitiesCount} ${title}` : - `${findingsSummary[totalKey] || 0} ${title}`; + `${!!findingsSummary ? (findingsSummary[totalKey] || 0) : 0} ${title}`; return ( - + ) }) } diff --git a/ui/src/layout/detail-displays/Findings/index.js b/ui/src/layout/detail-displays/Findings/index.js index 0b1039855..eeeb3c413 100644 --- a/ui/src/layout/detail-displays/Findings/index.js +++ b/ui/src/layout/detail-displays/Findings/index.js @@ -6,11 +6,12 @@ import LinksList from 'components/LinksList'; import VulnerabilitiesDisplay, { getTotlalVulnerabilitiesFromCounters } from 'components/VulnerabilitiesDisplay'; import { FINDINGS_MAPPING, VULNERABIITY_FINDINGS_ITEM } from 'utils/systemConsts'; import { useFilterDispatch, setFilters, FILTER_TYPES } from 'context/FiltersProvider'; +import { getFindingsAbsolutePathByFindingType } from 'layout/Findings'; import FindingsCounterDisplay from './FindingsCounterDisplay'; import FindingsSystemFilterLinks from './FindingsSystemFilterLinks'; -const Findings = ({findingsSummary={}, findingsFilter, findingsFilterTitle, findingsFilterSuffix=""}) => { - const {totalVulnerabilities} = findingsSummary; +const Findings = ({findingsSummary, findingsFilter, findingsFilterTitle, findingsFilterSuffix=""}) => { + const {totalVulnerabilities} = findingsSummary || {}; const {pathname} = useLocation(); const filtersDispatch = useFilterDispatch(); @@ -25,7 +26,7 @@ const Findings = ({findingsSummary={}, findingsFilter, findingsFilterTitle, find backPath: pathname, customDisplay: () => ( ) @@ -42,15 +43,15 @@ const Findings = ({findingsSummary={}, findingsFilter, findingsFilterTitle, find , callback: onFindingsClick }, ...Object.keys(FINDINGS_MAPPING).map(findingType => { - const {totalKey, title, icon, color, appRoute} = FINDINGS_MAPPING[findingType]; + const {totalKey, title, icon, color, value} = FINDINGS_MAPPING[findingType]; return { - path: appRoute, + path: getFindingsAbsolutePathByFindingType(value), component: () => ( ), diff --git a/ui/src/layout/detail-displays/ScanDetails/index.js b/ui/src/layout/detail-displays/ScanDetails/index.js index a3f1fde20..270ad7ec9 100644 --- a/ui/src/layout/detail-displays/ScanDetails/index.js +++ b/ui/src/layout/detail-displays/ScanDetails/index.js @@ -28,7 +28,7 @@ const ScanDetails = ({scanData, withAssetScansLink=false}) => { const filtersDispatch = useFilterDispatch(); const {id, scanConfig, scanConfigSnapshot, startTime, endTime, summary, state, stateMessage, stateReason} = scanData || {}; - const {jobsCompleted, jobsLeftToRun} = summary; + const {jobsCompleted, jobsLeftToRun} = summary || {}; const formattedStartTime = formatDate(startTime); diff --git a/ui/src/utils/systemConsts.js b/ui/src/utils/systemConsts.js index 8121a4992..9cef90df6 100644 --- a/ui/src/utils/systemConsts.js +++ b/ui/src/utils/systemConsts.js @@ -1,5 +1,4 @@ import { ICON_NAMES } from 'components/Icon'; -import { FINDINGS_PATHS } from 'layout/Findings' import COLORS from 'utils/scss_variables.module.scss'; @@ -20,7 +19,8 @@ export const APIS = { FINDINGS: "findings", DASHBOARD_RISKIEST_REGIONS: "dashboard/riskiestRegions", DASHBOARD_RISKIEST_ASSETS: "dashboard/riskiestAssets", - DASHBOARD_FINDINGS_TRENDS: "dashboard/findingsTrends" + DASHBOARD_FINDINGS_TRENDS: "dashboard/findingsTrends", + DASHBOARD_FINDINGS_IMPACT: "dashboard/findingsImpact" } export const FINDINGS_MAPPING = { @@ -32,8 +32,7 @@ export const FINDINGS_MAPPING = { title: "Exploits", icon: ICON_NAMES.BOMB, color: COLORS["color-main"], - darkColor: COLORS["color-main-variation-dark"], - appRoute: `${ROUTES.FINDINGS}/${FINDINGS_PATHS.EXPLOITS}` + darkColor: COLORS["color-main-variation-dark"] }, MISCONFIGURATIONS: { value: "MISCONFIGURATIONS", @@ -43,8 +42,7 @@ export const FINDINGS_MAPPING = { title: "Misconfigurations", icon: ICON_NAMES.COG, color: COLORS["color-findings-1"], - darkColor: COLORS["color-findings-1-variation-dark"], - appRoute: `${ROUTES.FINDINGS}/${FINDINGS_PATHS.MISCONFIGURATIONS}` + darkColor: COLORS["color-findings-1-variation-dark"] }, SECRETS: { value: "SECRETS", @@ -53,8 +51,7 @@ export const FINDINGS_MAPPING = { typeKey: "SECRET", title: "Secrets", icon: ICON_NAMES.KEY, - color: COLORS["color-findings-2"], - appRoute: `${ROUTES.FINDINGS}/${FINDINGS_PATHS.SECRETS}` + color: COLORS["color-findings-2"] }, MALWARE: { value: "MALWARE", @@ -63,8 +60,7 @@ export const FINDINGS_MAPPING = { typeKey: "MALWARE", title: "Malware", icon: ICON_NAMES.BUG, - color: COLORS["color-findings-3"], - appRoute: `${ROUTES.FINDINGS}/${FINDINGS_PATHS.MALWARE}` + color: COLORS["color-findings-3"] }, ROOTKITS: { value: "ROOTKITS", @@ -73,8 +69,7 @@ export const FINDINGS_MAPPING = { typeKey: "ROOTKIT", title: "Rootkits", icon: ICON_NAMES.GHOST, - color: COLORS["color-findings-4"], - appRoute: `${ROUTES.FINDINGS}/${FINDINGS_PATHS.ROOTKITS}` + color: COLORS["color-findings-4"] }, PACKAGES: { value: "PACKAGES", @@ -83,8 +78,7 @@ export const FINDINGS_MAPPING = { typeKey: "PACKAGE", title: "Packages", icon: ICON_NAMES.PACKAGE, - color: COLORS["color-findings-5"], - appRoute: `${ROUTES.FINDINGS}/${FINDINGS_PATHS.PACKAGES}` + color: COLORS["color-findings-5"] } } @@ -96,5 +90,4 @@ export const VULNERABIITY_FINDINGS_ITEM = { icon: ICON_NAMES.SHIELD, color: COLORS["color-main-dark"], darkColor: COLORS["color-main-dark-variation-dark"], - appRoute: `${ROUTES.FINDINGS}/${FINDINGS_PATHS.VULNERABILITIES}` } \ No newline at end of file diff --git a/ui/src/utils/utils.js b/ui/src/utils/utils.js index 094dda56b..52237d1ed 100644 --- a/ui/src/utils/utils.js +++ b/ui/src/utils/utils.js @@ -1,6 +1,7 @@ import moment from 'moment'; import cronstrue from 'cronstrue'; -import { isNull } from 'lodash'; +import CVSS from '@turingpointde/cvss.js'; +import { isEmpty, orderBy } from 'lodash'; import { FINDINGS_MAPPING, VULNERABIITY_FINDINGS_ITEM } from 'utils/systemConsts'; import IconWithTooltip from 'components/IconWithTooltip'; import VulnerabilitiesDisplay from 'components/VulnerabilitiesDisplay'; @@ -16,6 +17,37 @@ export const cronExpressionToHuman = value => cronstrue.toString(value, {use24Ho export const getScanName = ({name, startTime}) => `${name} ${formatDate(startTime)}`; +export const getHigestVersionCvssData = (cvssData) => { + if (isEmpty(cvssData)) { + return {}; + } + + const sortedCvss = orderBy(cvssData || [], ["version"], ["desc"]); + + const {vector, metrics, version} = sortedCvss[0]; + + const serverData = { + vector, + score: metrics.baseScore, + exploitabilityScore: metrics.exploitabilityScore, + impactScore: metrics.impactScore + } + + if (version === "2.0") { + return serverData + } + + const cvssVector = CVSS(vector); + + return { + ...serverData, + temporalScore: cvssVector.getTemporalScore(), + environmentalScore: cvssVector.getEnvironmentalScore(), + severity: cvssVector.getRating(), + metrics: cvssVector.getDetailedVectorObject().metrics, + } +} + export const getFindingsColumnsConfigList = (tableTitle) => Object.keys(FINDINGS_MAPPING).map(findingKey => { const {totalKey, title, icon} = FINDINGS_MAPPING[findingKey]; @@ -25,7 +57,7 @@ export const getFindingsColumnsConfigList = (tableTitle) => Object.keys(FINDINGS accessor: original => { const {summary} = original; - return isNull(summary) ? 0 : (summary[totalKey] || 0); + return isEmpty(summary) ? 0 : (summary[totalKey] || 0); }, width: 50, disableSort: true From 14e569d1c20b2f5c1f24027c733a443fc6c3dd55 Mon Sep 17 00:00:00 2001 From: Galia Ilanov Date: Thu, 30 Mar 2023 13:42:21 +0300 Subject: [PATCH 2/6] updates --- ui/src/layout/AssetScans/AssetScansTable.js | 2 +- .../FindingsTabsWidget/findings-tabs-widget.scss | 2 +- ui/src/layout/Findings/Exploits/ExploitsTable.js | 15 ++------------- .../layout/Findings/Exploits/TabExploitDetails.js | 4 ---- ui/src/layout/Findings/Malware/MalwareTable.js | 3 ++- .../Misconfigurations/MisconfigurationTable.js | 3 ++- ui/src/layout/Findings/Secrets/SecretsTable.js | 6 ++++-- 7 files changed, 12 insertions(+), 23 deletions(-) diff --git a/ui/src/layout/AssetScans/AssetScansTable.js b/ui/src/layout/AssetScans/AssetScansTable.js index 8507b8112..9cdde9c5d 100644 --- a/ui/src/layout/AssetScans/AssetScansTable.js +++ b/ui/src/layout/AssetScans/AssetScansTable.js @@ -45,7 +45,7 @@ const AssetScansTable = () => { disableSort: true }, { - Header: "Status", + Header: "Scan status", id: "status", accessor: original => { const {state} = original?.status?.general || {}; diff --git a/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss b/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss index 5538c503d..68a76b7a4 100644 --- a/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss +++ b/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss @@ -2,7 +2,7 @@ .findings-tabs-widget { .tabbed-widget-table-wrapper { - height: calc(100% - 70px); + height: calc(100% - 100px); overflow-y: auto; .tabbed-widget-table { diff --git a/ui/src/layout/Findings/Exploits/ExploitsTable.js b/ui/src/layout/Findings/Exploits/ExploitsTable.js index b0e37879f..319a3cb6f 100644 --- a/ui/src/layout/Findings/Exploits/ExploitsTable.js +++ b/ui/src/layout/Findings/Exploits/ExploitsTable.js @@ -4,23 +4,12 @@ import FindingsTablePage from '../FindingsTablePage'; const ExploitsTable = () => { const columns = useMemo(() => [ - { - Header: "Exploit name", - id: "name", - accessor: "findingInfo.name", - disableSort: true - }, - { - Header: "Title", - id: "title", - accessor: "findingInfo.title", - disableSort: true - }, { Header: "Description", id: "description", accessor: "findingInfo.description", - disableSort: true + disableSort: true, + width: 300 }, { Header: "Source DB", diff --git a/ui/src/layout/Findings/Exploits/TabExploitDetails.js b/ui/src/layout/Findings/Exploits/TabExploitDetails.js index 1874dda99..201d4b333 100644 --- a/ui/src/layout/Findings/Exploits/TabExploitDetails.js +++ b/ui/src/layout/Findings/Exploits/TabExploitDetails.js @@ -10,10 +10,6 @@ const TabExploitDetails = ({data}) => { ( <> - - {name} - {title} - {sourceDB} {cveID} diff --git a/ui/src/layout/Findings/Malware/MalwareTable.js b/ui/src/layout/Findings/Malware/MalwareTable.js index 0147f1ec4..9657e58ac 100644 --- a/ui/src/layout/Findings/Malware/MalwareTable.js +++ b/ui/src/layout/Findings/Malware/MalwareTable.js @@ -14,7 +14,8 @@ const MalwareTable = () => { Header: "File path", id: "filePath", accessor: "findingInfo.path", - disableSort: true + disableSort: true, + width: 300 }, ...getAssetAndScanColumnsConfigList() ], []); diff --git a/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js b/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js index a8fee6a37..fdf2368fa 100644 --- a/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js +++ b/ui/src/layout/Findings/Misconfigurations/MisconfigurationTable.js @@ -21,7 +21,8 @@ const MisconfigurationsTable = () => { Header: "Description", id: "description", accessor: "findingInfo.testDescription", - disableSort: true + disableSort: true, + width: 200 }, ...getAssetAndScanColumnsConfigList() ], []); diff --git a/ui/src/layout/Findings/Secrets/SecretsTable.js b/ui/src/layout/Findings/Secrets/SecretsTable.js index 4f0d25925..4bec48e65 100644 --- a/ui/src/layout/Findings/Secrets/SecretsTable.js +++ b/ui/src/layout/Findings/Secrets/SecretsTable.js @@ -8,7 +8,8 @@ const SecretsTable = () => { Header: "Fingerprint", id: "fingerprint", accessor: "findingInfo.fingerprint", - disableSort: true + disableSort: true, + width: 200 }, { Header: "Description", @@ -20,7 +21,8 @@ const SecretsTable = () => { Header: "File path", id: "findingInfo", accessor: "findingInfo.filePath", - disableSort: true + disableSort: true, + width: 200 }, ...getAssetAndScanColumnsConfigList() ], []); From 725599c8b772913ee3b9d93ce88249718fd8ffd4 Mon Sep 17 00:00:00 2001 From: Galia Ilanov Date: Thu, 30 Mar 2023 14:04:52 +0300 Subject: [PATCH 3/6] update --- ui/src/layout/Findings/Exploits/TabExploitDetails.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/layout/Findings/Exploits/TabExploitDetails.js b/ui/src/layout/Findings/Exploits/TabExploitDetails.js index 201d4b333..bdf28d7cb 100644 --- a/ui/src/layout/Findings/Exploits/TabExploitDetails.js +++ b/ui/src/layout/Findings/Exploits/TabExploitDetails.js @@ -4,7 +4,7 @@ import DoublePaneDisplay from 'components/DoublePaneDisplay'; import LinksDisplay from 'layout/Findings/LinkesDisplay'; const TabExploitDetails = ({data}) => { - const {cveID, name, description, title, sourceDB, urls} = data.findingInfo; + const {cveID, description, sourceDB, urls} = data.findingInfo; return ( Date: Thu, 30 Mar 2023 14:05:47 +0300 Subject: [PATCH 4/6] update --- .../Dashboard/FindingsTabsWidget/findings-tabs-widget.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss b/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss index 68a76b7a4..15d05b1e0 100644 --- a/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss +++ b/ui/src/layout/Dashboard/FindingsTabsWidget/findings-tabs-widget.scss @@ -2,7 +2,7 @@ .findings-tabs-widget { .tabbed-widget-table-wrapper { - height: calc(100% - 100px); + height: calc(100% - 90px); overflow-y: auto; .tabbed-widget-table { From 16fe4bac4de50330d6447165950b907eb6361496 Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 30 Mar 2023 14:55:59 +0300 Subject: [PATCH 5/6] fix cvss nil crash --- ui_backend/pkg/rest/dashboard_findings_impact.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui_backend/pkg/rest/dashboard_findings_impact.go b/ui_backend/pkg/rest/dashboard_findings_impact.go index b9267b953..507e415b1 100644 --- a/ui_backend/pkg/rest/dashboard_findings_impact.go +++ b/ui_backend/pkg/rest/dashboard_findings_impact.go @@ -346,6 +346,9 @@ func toModelsVulnerabilitySeverity(severity *backendmodels.VulnerabilitySeverity } func toModelsVulnerabilityCVSSArray(cvss *[]backendmodels.VulnerabilityCvss) *[]models.VulnerabilityCvss { + if cvss == nil { + return nil + } ret := make([]models.VulnerabilityCvss, len(*cvss)) for i, vulnerabilityCvss := range *cvss { ret[i] = toModelsVulnerabilityCVSS(vulnerabilityCvss) @@ -362,6 +365,9 @@ func toModelsVulnerabilityCVSS(cvss backendmodels.VulnerabilityCvss) models.Vuln } func toModelsVulnerabilityCVSSMetrics(metrics *backendmodels.VulnerabilityCvssMetrics) *models.VulnerabilityCvssMetrics { + if metrics == nil { + return nil + } return &models.VulnerabilityCvssMetrics{ BaseScore: metrics.BaseScore, ExploitabilityScore: metrics.ExploitabilityScore, From 7968c0f92eb010053ef95e9233908e523b50a8ee Mon Sep 17 00:00:00 2001 From: Galia Ilanov Date: Thu, 30 Mar 2023 15:00:26 +0300 Subject: [PATCH 6/6] update --- ui/src/layout/Dashboard/FindingsImpactWidget/index.js | 1 - ui/src/layout/Dashboard/FindingsTabsWidget/index.js | 7 +++---- ui/src/layout/Dashboard/RiskiestAssetsWidget/index.js | 1 - 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ui/src/layout/Dashboard/FindingsImpactWidget/index.js b/ui/src/layout/Dashboard/FindingsImpactWidget/index.js index 1d10f59a9..cf1ba190a 100644 --- a/ui/src/layout/Dashboard/FindingsImpactWidget/index.js +++ b/ui/src/layout/Dashboard/FindingsImpactWidget/index.js @@ -72,7 +72,6 @@ const FindingsImpactWidget = ({className}) => ( title="Findings impact" widgetName="findings-impact" url={APIS.DASHBOARD_FINDINGS_IMPACT} - maxItems={4} getHeaderItems={(selectedId) => { const {headerItems=[]} = TABS_COLUMNS_MAPPING[selectedId] || {}; diff --git a/ui/src/layout/Dashboard/FindingsTabsWidget/index.js b/ui/src/layout/Dashboard/FindingsTabsWidget/index.js index 52fdfe896..16f21ead4 100644 --- a/ui/src/layout/Dashboard/FindingsTabsWidget/index.js +++ b/ui/src/layout/Dashboard/FindingsTabsWidget/index.js @@ -11,8 +11,8 @@ import COLORS from 'utils/scss_variables.module.scss'; import './findings-tabs-widget.scss'; -const WidgetContent = ({data=[], maxItems, getHeaderItems, getBodyItems, selectedId}) => { - const displayData = data.slice(0, maxItems); +const WidgetContent = ({data=[], getHeaderItems, getBodyItems, selectedId}) => { + const displayData = (data || []).slice(0, 5); return ( @@ -52,7 +52,7 @@ const Tab = ({widgetName, title, icon, isActive}) => ( /> ) -const FindingsTabsWidget = ({widgetName, findingsItems, className, title, url, maxItems, getHeaderItems, getBodyItems}) => { +const FindingsTabsWidget = ({widgetName, findingsItems, className, title, url, getHeaderItems, getBodyItems}) => { const [{data, error, loading}] = useFetch(url, {urlPrefix: "ui"}); const WIDGET_TAB_ITEMS = findingsItems.map(({dataKey, icon, title}) => ( @@ -74,7 +74,6 @@ const FindingsTabsWidget = ({widgetName, findingsItems, className, title, url, m loading ? : (error ? null : ( title="Riskiest assets" widgetName="riskiers-assets" url={APIS.DASHBOARD_RISKIEST_ASSETS} - maxItems={5} getHeaderItems={() => (["Name", "Type", "Findings"])} getBodyItems={(selectedId) => ([ {dataKey: "assetInfo.name"},