diff --git a/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx b/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx index a4ce952b..990a5a51 100644 --- a/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx +++ b/client/src/app/pages/sbom-details/vulnerabilities-by-sbom.tsx @@ -30,7 +30,12 @@ import { import { getSeverityPriority } from "@app/api/model-utils"; import { VulnerabilityStatus } from "@app/api/models"; -import { SbomAdvisory, SbomPackage, SbomStatus } from "@app/client"; +import { + PurlSummary, + SbomAdvisory, + SbomPackage, + SbomStatus, +} from "@app/client"; import { LoadingWrapper } from "@app/components/LoadingWrapper"; import { PackageQualifiers } from "@app/components/PackageQualifiers"; import { SbomVulnerabilitiesDonutChart } from "@app/components/SbomVulnerabilitiesDonutChart"; @@ -328,29 +333,76 @@ export const VulnerabilitiesBySbom: React.FC = ({ {item.summary.allPackages - .flatMap((item) => item.purl) + .flatMap((item) => { + // Workaround against https://github.com/trustification/trustify/issues/1043 + // Some packages do not have purl neither ID. So we render only the parent name meanwhile + type EnrichedPurlSummary = { + parentName: string; + purlSummary?: PurlSummary; + }; + + const hasNoPurlsButOnlyName = + item.name && item.purl.length == 0; + + if (hasNoPurlsButOnlyName) { + const result: EnrichedPurlSummary = { + parentName: item.name, + }; + return [result]; + } else { + return item.purl.map((i) => { + const result: EnrichedPurlSummary = + { + ...i, + parentName: item.name, + }; + return result; + }); + } + }) .map((purl, index) => { - const decomposedPurl = decomposePurl( - purl.purl - ); - return ( - - {decomposedPurl?.type} - {decomposedPurl?.namespace} - {decomposedPurl?.name} - {decomposedPurl?.version} - {decomposedPurl?.path} - - {decomposedPurl?.qualifiers && ( - - )} - - - ); + if (purl.purlSummary) { + const decomposedPurl = decomposePurl( + purl.purlSummary.purl + ); + return ( + + {decomposedPurl?.type} + + {decomposedPurl?.namespace} + + + + {decomposedPurl?.name} + + + {decomposedPurl?.version} + {decomposedPurl?.path} + + {decomposedPurl?.qualifiers && ( + + )} + + + ); + } else { + return ( + + + + {purl.parentName} + + + + + ); + } })}