Skip to content

Commit efecdb2

Browse files
committed
feat: use mapping for security cards categories keys
1 parent dce41f8 commit efecdb2

File tree

4 files changed

+124
-100
lines changed

4 files changed

+124
-100
lines changed

src/Shared/Components/Security/SecurityDetailsCards/SecurityCard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const SecurityCard = ({
6464
const { title, subtitle } = getTitleSubtitle()
6565

6666
const onKeyDown = (event) => {
67-
if (event.key === 'Enter' || event.key === 'Space') {
67+
if (event.key === 'Enter') {
6868
handleCardClick()
6969
}
7070
}
@@ -86,9 +86,9 @@ const SecurityCard = ({
8686
</div>
8787
</div>
8888
{hasThreats ? (
89-
<ICShieldWarning className="icon-dim-24 scr-5" />
89+
<ICShieldWarning className="icon-dim-24 scr-5 dc__no-shrink" />
9090
) : (
91-
<ICShieldSecure className="icon-dim-24 scg-5" />
91+
<ICShieldSecure className="icon-dim-24 scg-5 dc__no-shrink" />
9292
)}
9393
</div>
9494
<div className="flexbox-col dc__gap-12">

src/Shared/Components/Security/SecurityDetailsCards/SecurityDetailsCards.tsx

Lines changed: 52 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,35 @@ import { CATEGORIES, SecurityModalStateType, SUB_CATEGORIES } from '../SecurityM
66
import { SecurityCardProps, SecurityDetailsCardsProps } from './types'
77
import { SecurityModal } from '../SecurityModal'
88
import { DEFAULT_SECURITY_MODAL_IMAGE_STATE } from '../SecurityModal/constants'
9-
import { ScanSubCategories } from '../types'
9+
import { ScanCategories, ScanSubCategories } from '../types'
1010
import './securityCard.scss'
11+
import { getSecurityConfig } from '../utils'
1112

1213
const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps) => {
1314
const [showSecurityModal, setShowSecurityModal] = useState<boolean>(false)
1415
const [modalState, setModalState] = useState<SecurityModalStateType>(DEFAULT_SECURITY_MODAL_IMAGE_STATE)
1516
const { imageScan, codeScan, kubernetesManifest } = scanResult
1617

17-
const imageScanToolId =
18-
imageScan?.vulnerability?.list?.[0].scanToolName === 'TRIVY' ? SCAN_TOOL_ID_TRIVY : SCAN_TOOL_ID_CLAIR
19-
const codeScanToolId = codeScan?.scanToolName === 'TRIVY' ? SCAN_TOOL_ID_TRIVY : SCAN_TOOL_ID_CLAIR
20-
const manifestScanToolId = kubernetesManifest?.scanToolName === 'TRIVY' ? SCAN_TOOL_ID_TRIVY : SCAN_TOOL_ID_CLAIR
18+
const SECURITY_CONFIG = getSecurityConfig({
19+
imageScan: !!imageScan,
20+
codeScan: !!codeScan,
21+
kubernetesManifest: !!kubernetesManifest,
22+
})
23+
24+
const getScanToolId = (category: string) => {
25+
switch (category) {
26+
case CATEGORIES.CODE_SCAN:
27+
return codeScan?.scanToolName === 'TRIVY' ? SCAN_TOOL_ID_TRIVY : SCAN_TOOL_ID_CLAIR
28+
case CATEGORIES.KUBERNETES_MANIFEST:
29+
return kubernetesManifest?.scanToolName === 'TRIVY' ? SCAN_TOOL_ID_TRIVY : SCAN_TOOL_ID_CLAIR
30+
case CATEGORIES.IMAGE_SCAN:
31+
return imageScan?.vulnerability?.list?.[0].scanToolName === 'TRIVY'
32+
? SCAN_TOOL_ID_TRIVY
33+
: SCAN_TOOL_ID_CLAIR
34+
default:
35+
return SCAN_TOOL_ID_TRIVY
36+
}
37+
}
2138

2239
const handleCardClick = (
2340
category: SecurityCardProps['category'],
@@ -35,91 +52,40 @@ const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps
3552
setShowSecurityModal(false)
3653
}
3754

38-
const isValidSubCategory = (subCategory: ScanSubCategories): boolean =>
39-
Object.values(SUB_CATEGORIES).includes(subCategory)
40-
4155
return (
4256
<>
4357
<div className="flexbox-col dc__gap-20">
44-
{imageScan ? (
45-
<div className="flexbox-col dc__gap-12">
46-
<div className="flexbox dc__content-space pb-8 dc__border-bottom-n1">
47-
<span className="fs-13 fw-6 lh-1-5 cn-9">Image Scan</span>
48-
<ScannedByToolModal scanToolId={imageScanToolId} />
49-
</div>
50-
<div className="dc__grid security-cards">
51-
{Object.keys(imageScan).map((subCategory: SecurityCardProps['subCategory']) => {
52-
if (!isValidSubCategory(subCategory)) {
53-
return null
54-
}
55-
return (
56-
<SecurityCard
57-
category={CATEGORIES.IMAGE_SCAN}
58-
subCategory={subCategory}
59-
severityCount={imageScan[subCategory]?.summary.severities}
60-
handleCardClick={() => handleCardClick(CATEGORIES.IMAGE_SCAN, subCategory)}
61-
/>
62-
)
63-
})}
64-
</div>
65-
</div>
66-
) : null}
67-
{codeScan ? (
68-
<div className="flexbox-col dc__gap-12">
69-
<div className="flexbox dc__content-space pb-8 dc__border-bottom-n1">
70-
<span className="fs-13 fw-6 lh-1-5 cn-9">Code Scan</span>
71-
<ScannedByToolModal scanToolId={codeScanToolId} />
72-
</div>
73-
<div className="dc__grid security-cards">
74-
{Object.keys(codeScan).map((subCategory: SecurityCardProps['subCategory']) => {
75-
if (!isValidSubCategory(subCategory)) {
76-
return null
77-
}
78-
const severityCount =
79-
subCategory === 'misConfigurations'
80-
? codeScan.misConfigurations?.misConfSummary?.status
81-
: codeScan[subCategory]?.summary?.severities
82-
return (
83-
<SecurityCard
84-
category={CATEGORIES.CODE_SCAN}
85-
subCategory={subCategory}
86-
severityCount={severityCount}
87-
handleCardClick={() => handleCardClick(CATEGORIES.CODE_SCAN, subCategory)}
88-
/>
89-
)
90-
})}
91-
</div>
92-
</div>
93-
) : null}
94-
{kubernetesManifest ? (
95-
<div className="flexbox-col dc__gap-12">
96-
<div className="flexbox dc__content-space pb-8 dc__border-bottom-n1">
97-
<span className="fs-13 fw-6 lh-1-5 cn-9">Manifest Scan</span>
98-
<ScannedByToolModal scanToolId={manifestScanToolId} />
99-
</div>
100-
<div className="dc__grid security-cards">
101-
{Object.keys(kubernetesManifest).map((subCategory: SecurityCardProps['subCategory']) => {
102-
if (!isValidSubCategory(subCategory)) {
103-
return null
104-
}
105-
const severityCount =
106-
subCategory === 'misConfigurations'
107-
? kubernetesManifest.misConfigurations?.misConfSummary?.status
108-
: kubernetesManifest[subCategory]?.summary?.severities
109-
return (
110-
<SecurityCard
111-
category={CATEGORIES.KUBERNETES_MANIFEST}
112-
subCategory={subCategory}
113-
severityCount={severityCount}
114-
handleCardClick={() =>
115-
handleCardClick(CATEGORIES.KUBERNETES_MANIFEST, subCategory)
116-
}
117-
/>
118-
)
119-
})}
58+
{Object.values(CATEGORIES).map((category: ScanCategories) => {
59+
if (!SECURITY_CONFIG[category]) {
60+
return null
61+
}
62+
const scanToolId = getScanToolId(category)
63+
return (
64+
<div className="flexbox-col dc__gap-12" key={category}>
65+
<div className="flexbox dc__content-space pb-8 dc__border-bottom-n1">
66+
<span className="fs-13 fw-6 lh-1-5 cn-9">{SECURITY_CONFIG[category].label}</span>
67+
<ScannedByToolModal scanToolId={scanToolId} />
68+
</div>
69+
<div className="dc__grid security-cards">
70+
{SECURITY_CONFIG[category].subCategories.map((subCategory: ScanSubCategories) => {
71+
const severityCount =
72+
subCategory === SUB_CATEGORIES.MISCONFIGURATIONS
73+
? scanResult[category][subCategory]?.misConfSummary?.status
74+
: scanResult[category][subCategory]?.summary?.severities
75+
76+
return (
77+
<SecurityCard
78+
category={category}
79+
subCategory={subCategory}
80+
severityCount={severityCount}
81+
handleCardClick={() => handleCardClick(category, subCategory)}
82+
/>
83+
)
84+
})}
85+
</div>
12086
</div>
121-
</div>
122-
) : null}
87+
)
88+
})}
12389
</div>
12490
{showSecurityModal && (
12591
<SecurityModal

src/Shared/Components/Security/types.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,20 @@ import { CATEGORIES, SUB_CATEGORIES } from './SecurityModal/types'
22

33
export type ScanCategories = (typeof CATEGORIES)[keyof typeof CATEGORIES]
44
export type ScanSubCategories = (typeof SUB_CATEGORIES)[keyof typeof SUB_CATEGORIES]
5+
6+
export type CategoriesConfig = {
7+
imageScan: boolean
8+
codeScan: boolean
9+
kubernetesManifest: boolean
10+
}
11+
12+
interface SecurityConfigCategoryType {
13+
label: string
14+
subCategories: ScanSubCategories[]
15+
}
16+
17+
export interface GetSecurityConfigReturnType {
18+
imageScan?: SecurityConfigCategoryType
19+
codeScan?: SecurityConfigCategoryType
20+
kubernetesManifest?: SecurityConfigCategoryType
21+
}
Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { ScanResultDTO, SeveritiesDTO } from './SecurityModal'
1+
import { CATEGORY_LABELS, ScanResultDTO, SeveritiesDTO } from './SecurityModal'
2+
import { CATEGORIES, SUB_CATEGORIES } from './SecurityModal/types'
3+
import { CategoriesConfig, GetSecurityConfigReturnType, ScanCategories, ScanSubCategories } from './types'
24

35
export const getCVEUrlFromCVEName = (cveName: string): string =>
46
`https://cve.mitre.org/cgi-bin/cvename.cgi?name=${cveName}`
@@ -8,16 +10,55 @@ export const getTotalSeverities = (severityCount: Partial<Record<SeveritiesDTO,
810
.filter(([key]) => key !== SeveritiesDTO.SUCCESSES)
911
.reduce((acc, [, value]) => acc + value, 0)
1012

13+
export const getSecurityConfig = (categoriesConfig: CategoriesConfig): GetSecurityConfigReturnType => {
14+
const { imageScan, codeScan, kubernetesManifest } = categoriesConfig
15+
16+
return {
17+
...(imageScan && {
18+
[CATEGORIES.IMAGE_SCAN]: {
19+
label: CATEGORY_LABELS.IMAGE_SCAN,
20+
subCategories: [SUB_CATEGORIES.VULNERABILITIES, SUB_CATEGORIES.LICENSE],
21+
},
22+
}),
23+
...(codeScan && {
24+
[CATEGORIES.CODE_SCAN]: {
25+
label: CATEGORY_LABELS.CODE_SCAN,
26+
subCategories: [
27+
SUB_CATEGORIES.VULNERABILITIES,
28+
SUB_CATEGORIES.LICENSE,
29+
SUB_CATEGORIES.MISCONFIGURATIONS,
30+
SUB_CATEGORIES.EXPOSED_SECRETS,
31+
],
32+
},
33+
}),
34+
...(kubernetesManifest && {
35+
[CATEGORIES.KUBERNETES_MANIFEST]: {
36+
label: CATEGORY_LABELS.KUBERNETES_MANIFEST,
37+
subCategories: [SUB_CATEGORIES.MISCONFIGURATIONS, SUB_CATEGORIES.EXPOSED_SECRETS],
38+
},
39+
}),
40+
}
41+
}
42+
1143
export const getSecurityThreatsArray = (scanResult: ScanResultDTO): Partial<Record<SeveritiesDTO, number>>[] => {
1244
const { imageScan, codeScan, kubernetesManifest } = scanResult
13-
return [
14-
imageScan?.vulnerability?.summary?.severities || {},
15-
imageScan?.license?.summary?.severities || {},
16-
codeScan?.vulnerability?.summary.severities || {},
17-
codeScan?.license?.summary?.severities || {},
18-
codeScan?.misConfigurations?.misConfSummary?.status || {},
19-
codeScan?.exposedSecrets?.summary?.severities || {},
20-
kubernetesManifest?.misConfigurations?.misConfSummary?.status || {},
21-
kubernetesManifest?.exposedSecrets?.summary?.severities || {},
22-
]
45+
const SECURITY_CONFIG = getSecurityConfig({
46+
imageScan: !!imageScan,
47+
codeScan: !!codeScan,
48+
kubernetesManifest: !!kubernetesManifest,
49+
})
50+
51+
const threatsArray: Partial<Record<SeveritiesDTO, number>>[] = []
52+
53+
Object.keys(SECURITY_CONFIG).forEach((category: ScanCategories) => {
54+
SECURITY_CONFIG[category].subCategories.forEach((subCategory: ScanSubCategories) => {
55+
const severity =
56+
subCategory === SUB_CATEGORIES.MISCONFIGURATIONS
57+
? scanResult[category][subCategory]?.misConfSummary?.status
58+
: scanResult[category][subCategory]?.summary?.severities
59+
threatsArray.push(severity)
60+
})
61+
})
62+
63+
return threatsArray
2364
}

0 commit comments

Comments
 (0)