Compare commits
	
		
			2 Commits
		
	
	
		
			commit-442
			...
			commit-8f4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8f4c23bf40 | ||
|  | 54c764c996 | 
							
								
								
									
										18
									
								
								src/api.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/api.js
									
									
									
									
									
								
							| @@ -1,11 +1,11 @@ | ||||
| import axios from 'axios'; | ||||
| import { isEmpty } from 'lodash'; | ||||
| import { sortByCriteria } from 'utilities/sortCriteria'; | ||||
| import { logoutUser } from 'utilities/authUtilities'; | ||||
| import { isAuthenticationEnabled, logoutUser } from 'utilities/authUtilities'; | ||||
| import { host } from 'host'; | ||||
|  | ||||
| axios.interceptors.request.use((config) => { | ||||
|   if (config.url.includes(endpoints.authConfig)) { | ||||
|   if (config.url.includes(endpoints.authConfig) || !isAuthenticationEnabled()) { | ||||
|     config.withCredentials = false; | ||||
|   } else { | ||||
|     config.headers['X-ZOT-API-CLIENT'] = 'zot-ui'; | ||||
| @@ -98,10 +98,18 @@ const endpoints = { | ||||
|     } | ||||
|     return `${query}){Tag Page {TotalCount ItemCount} CVEList {Id Title Description Severity PackageList {Name InstalledVersion FixedVersion}}}}`; | ||||
|   }, | ||||
|   imageListWithCVEFixed: (cveId, repoName, { pageNumber = 1, pageSize = 3 }) => | ||||
|     `/v2/_zot/ext/search?query={ImageListWithCVEFixed(id:"${cveId}", image:"${repoName}", requestedPage: {limit:${pageSize} offset:${ | ||||
|   imageListWithCVEFixed: (cveId, repoName, { pageNumber = 1, pageSize = 3 }, filter = {}) => { | ||||
|     let filterParam = ''; | ||||
|     if (filter.Os || filter.Arch) { | ||||
|       filterParam = `,filter:{`; | ||||
|       if (filter.Os) filterParam += ` Os:${!isEmpty(filter.Os) ? `${JSON.stringify(filter.Os)}` : '""'}`; | ||||
|       if (filter.Arch) filterParam += ` Arch:${!isEmpty(filter.Arch) ? `${JSON.stringify(filter.Arch)}` : '""'}`; | ||||
|       filterParam += '}'; | ||||
|     } | ||||
|     return `/v2/_zot/ext/search?query={ImageListWithCVEFixed(id:"${cveId}", image:"${repoName}", requestedPage: {limit:${pageSize} offset:${ | ||||
|       (pageNumber - 1) * pageSize | ||||
|     }}) {Page {TotalCount ItemCount} Results {Tag}}}`, | ||||
|     }}${filterParam}) {Page {TotalCount ItemCount} Results {Tag}}}`; | ||||
|   }, | ||||
|   dependsOnForImage: (name, { pageNumber = 1, pageSize = 15 } = {}) => | ||||
|     `/v2/_zot/ext/search?query={BaseImageList(image: "${name}", requestedPage: {limit:${pageSize} offset:${ | ||||
|       (pageNumber - 1) * pageSize | ||||
|   | ||||
| @@ -72,7 +72,7 @@ const useStyles = makeStyles((theme) => ({ | ||||
| })); | ||||
| function VulnerabilitiyCard(props) { | ||||
|   const classes = useStyles(); | ||||
|   const { cve, name } = props; | ||||
|   const { cve, name, platform } = props; | ||||
|   const [openDesc, setOpenDesc] = useState(false); | ||||
|   const [openFixed, setOpenFixed] = useState(false); | ||||
|   const [loadingFixed, setLoadingFixed] = useState(true); | ||||
| @@ -90,7 +90,12 @@ function VulnerabilitiyCard(props) { | ||||
|     setLoadingFixed(true); | ||||
|     api | ||||
|       .get( | ||||
|         `${host()}${endpoints.imageListWithCVEFixed(cve.id, name, { pageNumber, pageSize: CVE_FIXEDIN_PAGE_SIZE })}`, | ||||
|         `${host()}${endpoints.imageListWithCVEFixed( | ||||
|           cve.id, | ||||
|           name, | ||||
|           { pageNumber, pageSize: CVE_FIXEDIN_PAGE_SIZE }, | ||||
|           platform ? { Os: platform.Os, Arch: platform.Arch } : {} | ||||
|         )}`, | ||||
|         abortController.signal | ||||
|       ) | ||||
|       .then((response) => { | ||||
|   | ||||
| @@ -73,7 +73,7 @@ function VulnerabilitiesDetails(props) { | ||||
|   const [cveData, setCveData] = useState([]); | ||||
|   const [isLoading, setIsLoading] = useState(true); | ||||
|   const abortController = useMemo(() => new AbortController(), []); | ||||
|   const { name, tag } = props; | ||||
|   const { name, tag, digest, platform } = props; | ||||
|  | ||||
|   // pagination props | ||||
|   const [cveFilter, setCveFilter] = useState(''); | ||||
| @@ -81,11 +81,15 @@ function VulnerabilitiesDetails(props) { | ||||
|   const [isEndOfList, setIsEndOfList] = useState(false); | ||||
|   const listBottom = useRef(null); | ||||
|  | ||||
|   const getCVERequestName = () => { | ||||
|     return digest !== '' ? `${name}@${digest}` : `${name}:${tag}`; | ||||
|   }; | ||||
|  | ||||
|   const getPaginatedCVEs = () => { | ||||
|     api | ||||
|       .get( | ||||
|         `${host()}${endpoints.vulnerabilitiesForRepo( | ||||
|           `${name}:${tag}`, | ||||
|           getCVERequestName(), | ||||
|           { pageNumber, pageSize: EXPLORE_PAGE_SIZE }, | ||||
|           cveFilter | ||||
|         )}`, | ||||
| @@ -171,7 +175,7 @@ function VulnerabilitiesDetails(props) { | ||||
|   const renderCVEs = () => { | ||||
|     return !isEmpty(cveData) ? ( | ||||
|       cveData.map((cve, index) => { | ||||
|         return <VulnerabilitiyCard key={index} cve={cve} name={name} />; | ||||
|         return <VulnerabilitiyCard key={index} cve={cve} name={name} platform={platform} />; | ||||
|       }) | ||||
|     ) : ( | ||||
|       <div>{!isLoading && <Typography className={classes.none}> No Vulnerabilities </Typography>}</div> | ||||
|   | ||||
| @@ -59,7 +59,6 @@ const useStyles = makeStyles((theme) => ({ | ||||
|     fontSize: '1rem', | ||||
|     lineHeight: '1.5rem', | ||||
|     color: '#52637A', | ||||
|     padding: '1rem 0 0 0', | ||||
|     maxWidth: '100%', | ||||
|     [theme.breakpoints.down('md')]: { | ||||
|       padding: '0.5rem 0 0 0', | ||||
| @@ -209,7 +208,14 @@ function TagDetails() { | ||||
|       case 'IsDependentOn': | ||||
|         return <IsDependentOn name={imageDetailData.name} digest={selectedManifest.digest} />; | ||||
|       case 'Vulnerabilities': | ||||
|         return <VulnerabilitiesDetails name={reponame} tag={tag} />; | ||||
|         return ( | ||||
|           <VulnerabilitiesDetails | ||||
|             name={reponame} | ||||
|             tag={tag} | ||||
|             digest={selectedManifest?.digest} | ||||
|             platform={selectedManifest.platform} | ||||
|           /> | ||||
|         ); | ||||
|       case 'ReferredBy': | ||||
|         return <ReferredBy referrers={imageDetailData.referrers} />; | ||||
|       default: | ||||
| @@ -227,10 +233,10 @@ function TagDetails() { | ||||
|             <Card className={classes.cardRoot}> | ||||
|               <CardContent className={classes.cardContent}> | ||||
|                 <Grid container> | ||||
|                   <Grid item xs={12} md={8} className={classes.header}> | ||||
|                   <Grid item xs={12} md={9} className={classes.header}> | ||||
|                     <Stack | ||||
|                       alignItems="center" | ||||
|                       sx={{ width: { xs: '100%', md: 'auto' } }} | ||||
|                       sx={{ width: { xs: '100%', md: 'auto' }, marginBottom: '1rem' }} | ||||
|                       direction={{ xs: 'column', md: 'row' }} | ||||
|                       spacing={1} | ||||
|                     > | ||||
| @@ -256,30 +262,29 @@ function TagDetails() { | ||||
|                         /> | ||||
|                         <SignatureIconCheck isSigned={imageDetailData.isSigned} /> | ||||
|                       </Stack> | ||||
|  | ||||
|                       <Stack sx={{ width: { xs: '100%', md: 'auto' } }}> | ||||
|                         <FormControl sx={{ m: '1', minWidth: '4.6875rem' }} className={classes.sortForm} size="small"> | ||||
|                           <InputLabel>OS/Arch</InputLabel> | ||||
|                           {!isEmpty(selectedManifest) && ( | ||||
|                             <Select | ||||
|                               label="OS/Arch" | ||||
|                               value={selectedManifest} | ||||
|                               onChange={handleOSArchChange} | ||||
|                               MenuProps={{ disableScrollLock: true }} | ||||
|                             > | ||||
|                               {imageDetailData.manifests.map((el) => ( | ||||
|                                 <MenuItem key={el.digest} value={el}> | ||||
|                                   {`${el.platform?.Os}/${el.platform?.Arch}`} | ||||
|                                 </MenuItem> | ||||
|                               ))} | ||||
|                             </Select> | ||||
|                           )} | ||||
|                         </FormControl> | ||||
|                       </Stack> | ||||
|                     </Stack> | ||||
|                     <Typography gutterBottom className={classes.digest}> | ||||
|                       Digest: {selectedManifest?.digest} | ||||
|                     </Typography> | ||||
|                     <Stack direction="row" alignItems="center" spacing="1rem"> | ||||
|                       <FormControl sx={{ m: '1', minWidth: '4.6875rem' }} className={classes.sortForm} size="small"> | ||||
|                         <InputLabel>OS/Arch</InputLabel> | ||||
|                         {!isEmpty(selectedManifest) && ( | ||||
|                           <Select | ||||
|                             label="OS/Arch" | ||||
|                             value={selectedManifest} | ||||
|                             onChange={handleOSArchChange} | ||||
|                             MenuProps={{ disableScrollLock: true }} | ||||
|                           > | ||||
|                             {imageDetailData.manifests.map((el) => ( | ||||
|                               <MenuItem key={el.digest} value={el}> | ||||
|                                 {`${el.platform?.Os}/${el.platform?.Arch}`} | ||||
|                               </MenuItem> | ||||
|                             ))} | ||||
|                           </Select> | ||||
|                         )} | ||||
|                       </FormControl> | ||||
|                       <Typography gutterBottom className={classes.digest}> | ||||
|                         Digest: {selectedManifest?.digest} | ||||
|                       </Typography> | ||||
|                     </Stack> | ||||
|                   </Grid> | ||||
|                 </Grid> | ||||
|               </CardContent> | ||||
|   | ||||
| @@ -23,7 +23,7 @@ const VerifiedShieldIcon = createSvgIcon( | ||||
|  | ||||
| const NoneVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
|   return ( | ||||
|     <Tooltip title={`${vulnerabilityStringTitle} Vulnerability`} placement="top"> | ||||
|     <Tooltip title={`${vulnerabilityStringTitle}`} placement="top"> | ||||
|       <OutlinedBugIcon | ||||
|         sx={{ | ||||
|           color: '#43A047!important', | ||||
| @@ -40,7 +40,7 @@ const NoneVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
| }; | ||||
| const UnknownVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
|   return ( | ||||
|     <Tooltip title={`${vulnerabilityStringTitle} Vulnerability`} placement="top"> | ||||
|     <Tooltip title={`${vulnerabilityStringTitle}`} placement="top"> | ||||
|       <OutlinedBugIcon | ||||
|         sx={{ | ||||
|           color: '#52637A', | ||||
| @@ -75,7 +75,7 @@ const FailedScanIcon = () => { | ||||
| }; | ||||
| const LowVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
|   return ( | ||||
|     <Tooltip title={`${vulnerabilityStringTitle} Vulnerability`} placement="top"> | ||||
|     <Tooltip title={`${vulnerabilityStringTitle}`} placement="top"> | ||||
|       <OutlinedBugIcon | ||||
|         sx={{ | ||||
|           color: '#FB8C00', | ||||
| @@ -92,7 +92,7 @@ const LowVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
| }; | ||||
| const MediumVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
|   return ( | ||||
|     <Tooltip title={`${vulnerabilityStringTitle} Vulnerability`} placement="top"> | ||||
|     <Tooltip title={`${vulnerabilityStringTitle}`} placement="top"> | ||||
|       <FilledBugIcon | ||||
|         sx={{ | ||||
|           color: '#FB8C00', | ||||
| @@ -109,7 +109,7 @@ const MediumVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
| }; | ||||
| const HighVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
|   return ( | ||||
|     <Tooltip title={`${vulnerabilityStringTitle} Vulnerability`} placement="top"> | ||||
|     <Tooltip title={`${vulnerabilityStringTitle}`} placement="top"> | ||||
|       <OutlinedBugIcon | ||||
|         sx={{ | ||||
|           color: '#E53935', | ||||
| @@ -126,7 +126,7 @@ const HighVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
| }; | ||||
| const CriticalVulnerabilityIcon = ({ vulnerabilityStringTitle }) => { | ||||
|   return ( | ||||
|     <Tooltip title={`${vulnerabilityStringTitle} Vulnerability`} placement="top"> | ||||
|     <Tooltip title={`${vulnerabilityStringTitle}`} placement="top"> | ||||
|       <FilledBugIcon | ||||
|         sx={{ | ||||
|           color: '#E53935', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user