From 3f7de25538cd891abd4e8c6da31fbf913422ee1c Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 23 Dec 2024 09:43:18 -0500 Subject: [PATCH 1/7] Refined Severity Levels filtering in Bar Chart - Ensured N/A severity level in Bar Chart includes all permutations of null, undefined, and empty strings. - Ensured filtering by severity level in All Vulns table matches the filtering in the Bar Chart. --- backend/src/api/vulnerabilities.ts | 5 +++-- frontend/src/pages/Risk/VulnerabilityBarChart.tsx | 13 ++++++++++++- .../src/pages/Vulnerabilities/Vulnerabilities.tsx | 14 +++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/backend/src/api/vulnerabilities.ts b/backend/src/api/vulnerabilities.ts index 1e0cbe6a..7e433a52 100644 --- a/backend/src/api/vulnerabilities.ts +++ b/backend/src/api/vulnerabilities.ts @@ -124,11 +124,12 @@ class VulnerabilitySearch { if (this.filters?.severity) { if (this.filters.severity === 'N/A') { qs.andWhere( - "vulnerability.severity IS NULL OR vulnerability.severity = ''" + "vulnerability.severity IS NULL OR vulnerability.severity = '' OR vulnerability.severity ILIKE 'N/A' OR vulnerability.severity ILIKE 'NULL'" ); } else if (this.filters.severity === 'Other') { qs.andWhere( - `vulnerability.severity NOT ILIKE 'N/A' AND + `vulnerability.severity NOT ILIKE 'NULL' AND + vulnerability.severity NOT ILIKE 'N/A' AND vulnerability.severity NOT ILIKE 'Low' AND vulnerability.severity NOT ILIKE 'Medium' AND vulnerability.severity NOT ILIKE 'High' AND diff --git a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx index 2a14a806..e099e4b3 100644 --- a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx +++ b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx @@ -75,7 +75,14 @@ const VulnerabilityBarChart = (props: { // Place null values in "N/A" and capitalize the first letter of each word in the data. const titleCaseData: BarData[] = data.map((d) => { - if (d.id === 'null' || d.id === null || d.id === '') { + if ( + d.id === null || + d.id === 'null' || + d.id === 'NULL' || + d.id === undefined || + d.id === '' || + d.id === 'N/A' + ) { return { id: 'N/A', value: d.value }; } else { return { @@ -84,6 +91,8 @@ const VulnerabilityBarChart = (props: { }; } }); + console.log('data', data); + console.log('titleCaseData', titleCaseData); // Group the data by severity level and "Other". Sum the values for each group. const groupedData = titleCaseData @@ -111,6 +120,8 @@ const VulnerabilityBarChart = (props: { return acc; }, {}); + console.log('groupedData', groupedData); + // Sort the data to ensure "N/A", "Low", "Medium", "High", and "Critical" appear in the desired order const sortedData = Object.entries(groupedData) .map(([id, value]) => ({ id, value })) diff --git a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx index 09c2bdd9..8806d121 100644 --- a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx +++ b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx @@ -314,8 +314,17 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ const severityLevels: string[] = ['Low', 'Medium', 'High', 'Critical']; + // const NA_SEVERITY_Levels = [null, undefined, 'NULL', 'N/A']; + const formatSeverity = (severity: string) => { - if (severity === null || severity === '' || severity === 'N/A') { + if ( + severity === null || + severity === 'null' || + severity === 'NULL' || + severity === undefined || + severity === '' || + severity === 'N/A' + ) { return 'N/A'; } else if (severityLevels.includes(titleCase(severity))) { return titleCase(severity); @@ -351,6 +360,9 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ }; }); + const vulRowsSeverities = vulnerabilities.map((vuln) => vuln.severity); + console.log('vulRows', vulRowsSeverities); + const vulCols: GridColDef[] = [ { field: 'title', From e5a8017cdbf4622a1a7e1138af302c01fc7237f5 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 23 Dec 2024 13:09:44 -0500 Subject: [PATCH 2/7] Added to-do for N/A values array --- frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx index 8806d121..1d0998c6 100644 --- a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx +++ b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx @@ -314,7 +314,7 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ const severityLevels: string[] = ['Low', 'Medium', 'High', 'Critical']; - // const NA_SEVERITY_Levels = [null, undefined, 'NULL', 'N/A']; + // To-Do: Create array(s) to handle permutations of null and N/A values const formatSeverity = (severity: string) => { if ( From c562310b7c07f008be23685b2090bee853bc2ffd Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 27 Dec 2024 15:54:31 -0500 Subject: [PATCH 3/7] Refined Severity Level sorting and grouping - Null, undefined, empty strings, and stringified versions on Null, N/A, and undefined are now grouped into the N/A category in both the Vulns Bar Chart and All Vulns table. - Both components now force Title Case on the severity level strings first then sort and group into their respective categories. - Edited the comporator function in the All Vulns tables to sort the severity levels in the correct order from N/A, Low, Medium, High, Critical, Other. --- .../src/pages/Risk/VulnerabilityBarChart.tsx | 31 +++++----- .../pages/Vulnerabilities/Vulnerabilities.tsx | 61 ++++++++++++++----- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx index e099e4b3..db467a51 100644 --- a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx +++ b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx @@ -73,23 +73,12 @@ const VulnerabilityBarChart = (props: { ); - // Place null values in "N/A" and capitalize the first letter of each word in the data. + // Capitalize the first letter of each word in the data. const titleCaseData: BarData[] = data.map((d) => { - if ( - d.id === null || - d.id === 'null' || - d.id === 'NULL' || - d.id === undefined || - d.id === '' || - d.id === 'N/A' - ) { - return { id: 'N/A', value: d.value }; - } else { - return { - id: d.id[0]?.toUpperCase() + d.id.slice(1)?.toLowerCase(), - value: d.value - }; - } + return { + id: d.id[0]?.toUpperCase() + d.id.slice(1)?.toLowerCase(), + value: d.value + }; }); console.log('data', data); console.log('titleCaseData', titleCaseData); @@ -107,6 +96,16 @@ const VulnerabilityBarChart = (props: { ]; if (severityLevels.includes(d.id)) { return d; + } + if ( + d.id === null || + d.id === undefined || + d.id === 'Null' || + d.id === 'N/a' || + d.id === 'undefined' || + d.id === '' + ) { + return { id: 'N/A', value: d.value }; } else { return { id: 'Other', value: d.value }; } diff --git a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx index 1d0998c6..13945599 100644 --- a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx +++ b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx @@ -312,28 +312,39 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ const titleCase = (str: string) => str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); - const severityLevels: string[] = ['Low', 'Medium', 'High', 'Critical']; + const severityLevels: string[] = [ + 'N/A', + 'Low', + 'Medium', + 'High', + 'Critical', + 'Other' + ]; // To-Do: Create array(s) to handle permutations of null and N/A values - const formatSeverity = (severity: string) => { + const formatSeverity = (severity?: any) => { + const titleCaseSev = titleCase(severity); + if (severityLevels.includes(titleCaseSev)) { + return titleCaseSev; + } + console.log('severity', severity); + console.log('titleCaseSev', titleCaseSev); if ( - severity === null || - severity === 'null' || - severity === 'NULL' || - severity === undefined || - severity === '' || - severity === 'N/A' + titleCaseSev === null || + titleCaseSev === undefined || + titleCaseSev === 'Null' || + titleCaseSev === 'N/a' || + titleCaseSev === 'undefined' || + titleCaseSev === '' ) { return 'N/A'; - } else if (severityLevels.includes(titleCase(severity))) { - return titleCase(severity); } else { return 'Other'; } }; - const severity = formatSeverity(vuln.severity ?? ''); + const severity = formatSeverity(vuln.severity ?? 'N/A'); return { id: vuln.id, @@ -360,8 +371,10 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ }; }); - const vulRowsSeverities = vulnerabilities.map((vuln) => vuln.severity); - console.log('vulRows', vulRowsSeverities); + const vulnSeverities = vulnerabilities.map((vuln) => vuln.severity); + console.log('vulnSevs', vulnSeverities); + const vulRowsSeverities = vulRows.map((vuln) => vuln.severity); + console.log('vulnRowsSevs', vulRowsSeverities); const vulCols: GridColDef[] = [ { @@ -400,21 +413,39 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ flex: 0.5, sortComparator: (v1, v2, cellParams1, cellParams2) => { const severityLevels: Record = { + 'N/A': 0, Low: 1, Medium: 2, High: 3, - Critical: 4 + Critical: 4, + Other: 5 }; + if ( + cellParams1.value === 'N/A' && + cellParams2.value !== 'N/A' && + cellParams2.value !== 'Other' + ) { + return -1; + } + if ( + cellParams2.value === 'N/A' && + cellParams1.value !== 'N/A' && + cellParams1.value !== 'Other' + ) { + return 1; + } return ( severityLevels[cellParams1.value] - severityLevels[cellParams2.value] ); }, renderCell: (cellValues: GridRenderCellParams) => { const severityLevels: Record = { + NA: 0, Low: 1, Medium: 2, High: 3, - Critical: 4 + Critical: 4, + Other: 5 }; return ( From 2da4510cf0165bddae9bef9da7b10c0bded08979 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 27 Dec 2024 16:27:40 -0500 Subject: [PATCH 4/7] Removed unnecessary if statement from Comparator - Adjusted the number values of the severity levels object to start with 1 instead of 0. - This removes the need for the long if statement previously used to handle N/A values. --- .../pages/Vulnerabilities/Vulnerabilities.tsx | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx index 13945599..33658e19 100644 --- a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx +++ b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx @@ -413,27 +413,13 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ flex: 0.5, sortComparator: (v1, v2, cellParams1, cellParams2) => { const severityLevels: Record = { - 'N/A': 0, - Low: 1, - Medium: 2, - High: 3, - Critical: 4, - Other: 5 + 'N/A': 1, + Low: 2, + Medium: 3, + High: 4, + Critical: 5, + Other: 6 }; - if ( - cellParams1.value === 'N/A' && - cellParams2.value !== 'N/A' && - cellParams2.value !== 'Other' - ) { - return -1; - } - if ( - cellParams2.value === 'N/A' && - cellParams1.value !== 'N/A' && - cellParams1.value !== 'Other' - ) { - return 1; - } return ( severityLevels[cellParams1.value] - severityLevels[cellParams2.value] ); From cbd704d63c5e90ba839f6a637a91f6f36510704e Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 27 Dec 2024 16:42:27 -0500 Subject: [PATCH 5/7] Removed unused console.logs and variables --- frontend/src/pages/Risk/VulnerabilityBarChart.tsx | 4 ---- frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx | 8 +------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx index db467a51..3cafd97d 100644 --- a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx +++ b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx @@ -80,8 +80,6 @@ const VulnerabilityBarChart = (props: { value: d.value }; }); - console.log('data', data); - console.log('titleCaseData', titleCaseData); // Group the data by severity level and "Other". Sum the values for each group. const groupedData = titleCaseData @@ -119,8 +117,6 @@ const VulnerabilityBarChart = (props: { return acc; }, {}); - console.log('groupedData', groupedData); - // Sort the data to ensure "N/A", "Low", "Medium", "High", and "Critical" appear in the desired order const sortedData = Object.entries(groupedData) .map(([id, value]) => ({ id, value })) diff --git a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx index 33658e19..1f41b052 100644 --- a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx +++ b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx @@ -328,8 +328,7 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ if (severityLevels.includes(titleCaseSev)) { return titleCaseSev; } - console.log('severity', severity); - console.log('titleCaseSev', titleCaseSev); + if ( titleCaseSev === null || titleCaseSev === undefined || @@ -371,11 +370,6 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ }; }); - const vulnSeverities = vulnerabilities.map((vuln) => vuln.severity); - console.log('vulnSevs', vulnSeverities); - const vulRowsSeverities = vulRows.map((vuln) => vuln.severity); - console.log('vulnRowsSevs', vulRowsSeverities); - const vulCols: GridColDef[] = [ { field: 'title', From 1afe5c36d2327f037fb6832f6b329288996ef585 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 30 Dec 2024 13:59:57 -0500 Subject: [PATCH 6/7] Refactored if statement for N/A values --- frontend/src/pages/Risk/VulnerabilityBarChart.tsx | 12 ++++-------- .../src/pages/Vulnerabilities/Vulnerabilities.tsx | 15 ++++++--------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx index 3cafd97d..5089bd4d 100644 --- a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx +++ b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx @@ -95,14 +95,7 @@ const VulnerabilityBarChart = (props: { if (severityLevels.includes(d.id)) { return d; } - if ( - d.id === null || - d.id === undefined || - d.id === 'Null' || - d.id === 'N/a' || - d.id === 'undefined' || - d.id === '' - ) { + if (!d.id || ['Null', 'N/a', 'undefined', ''].includes(d.id)) { return { id: 'N/A', value: d.value }; } else { return { id: 'Other', value: d.value }; @@ -125,6 +118,9 @@ const VulnerabilityBarChart = (props: { return order.indexOf(a.id) - order.indexOf(b.id); }); + console.log('severities', data); + console.log('groupedData', groupedData); + useEffect(() => { const label = `${title} bar chart. ` + diff --git a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx index 1f41b052..879bb5b5 100644 --- a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx +++ b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx @@ -321,21 +321,14 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ 'Other' ]; - // To-Do: Create array(s) to handle permutations of null and N/A values - const formatSeverity = (severity?: any) => { const titleCaseSev = titleCase(severity); if (severityLevels.includes(titleCaseSev)) { return titleCaseSev; } - if ( - titleCaseSev === null || - titleCaseSev === undefined || - titleCaseSev === 'Null' || - titleCaseSev === 'N/a' || - titleCaseSev === 'undefined' || - titleCaseSev === '' + !titleCaseSev || + ['Null', 'N/a', 'undefined', ''].includes(titleCaseSev) ) { return 'N/A'; } else { @@ -369,6 +362,10 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ state: vuln.state + (vuln.substate ? ` (${vuln.substate})` : '') }; }); + const vulnSev = vulnerabilities.map((vuln) => vuln.severity); + console.log('vulnSev', vulnSev); + const vulRowsSev = vulRows.map((vuln) => vuln.severity); + console.log('vulRows', vulRowsSev); const vulCols: GridColDef[] = [ { From ffa2013af3bfbdd2d4e253e0ed28b877468dbd80 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 30 Dec 2024 14:07:36 -0500 Subject: [PATCH 7/7] Removed console.logs and unused variables --- frontend/src/pages/Risk/VulnerabilityBarChart.tsx | 3 --- frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx | 4 ---- 2 files changed, 7 deletions(-) diff --git a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx index 5089bd4d..1872a45d 100644 --- a/frontend/src/pages/Risk/VulnerabilityBarChart.tsx +++ b/frontend/src/pages/Risk/VulnerabilityBarChart.tsx @@ -118,9 +118,6 @@ const VulnerabilityBarChart = (props: { return order.indexOf(a.id) - order.indexOf(b.id); }); - console.log('severities', data); - console.log('groupedData', groupedData); - useEffect(() => { const label = `${title} bar chart. ` + diff --git a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx index 879bb5b5..65b32ba9 100644 --- a/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx +++ b/frontend/src/pages/Vulnerabilities/Vulnerabilities.tsx @@ -362,10 +362,6 @@ export const Vulnerabilities: React.FC<{ groupBy?: string }> = ({ state: vuln.state + (vuln.substate ? ` (${vuln.substate})` : '') }; }); - const vulnSev = vulnerabilities.map((vuln) => vuln.severity); - console.log('vulnSev', vulnSev); - const vulRowsSev = vulRows.map((vuln) => vuln.severity); - console.log('vulRows', vulRowsSev); const vulCols: GridColDef[] = [ {