@backstage-community/plugin-mend-backend 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @backstage-community/plugin-mend-backend
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - ba05827: Enhance Mapping Logic to support GitLab Subgroup Repository
8
+
9
+ ## 1.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 93f75d2: Backstage version bump to v1.48.2
14
+
3
15
  ## 1.0.0
4
16
 
5
17
  ### Major Changes
package/README.md CHANGED
@@ -1,24 +1,25 @@
1
1
  # Mend.io - backend
2
2
 
3
- > [!IMPORTANT]
4
- > New Backend System
5
-
6
3
  In your `packages/backend/src/index.ts` file:
7
4
 
8
5
  ```ts
9
6
  backend.add(import('@backstage-community/plugin-mend-backend'));
10
7
  ```
11
8
 
12
- ### Permission Control (optional)
9
+ ## Mend.io Projects Control (Optional)
13
10
 
14
11
  The plugin supports configuration-based permission control to filter which projects are visible to users.
15
12
 
16
- - Provide a list of project IDs in the configuration to filter projects.
17
- - Use the `exclude` property to control the filtering behavior:
18
- - `true` (blocklist mode): Show all projects EXCEPT those in the list
19
- - `false` (allowlist mode): Show ONLY projects in the list
13
+ ### How It Works
14
+
15
+ - **Project Filtering**: Provide a list of project IDs in the configuration to filter projects
16
+ - **Control Modes**: Use the `exclude` property to control the filtering behavior:
17
+ - `true` (blocklist mode): Show all projects **EXCEPT** those in the list
18
+ - `false` (allowlist mode): Show **ONLY** projects in the list
20
19
 
21
- Add the following configuration to your `app-config.yaml`:
20
+ ### Configuration
21
+
22
+ Add the following configuration to your `app-config.yaml` or `app-config.production.yaml`:
22
23
 
23
24
  ```yaml
24
25
  mend:
@@ -30,13 +31,39 @@ mend:
30
31
  exclude: true # Set to true for blocklist mode, false for allowlist mode
31
32
  ```
32
33
 
33
- **Configuration Options:**
34
+ ### Configuration Options
35
+
36
+ | Option | Type | Default | Description |
37
+ | --------- | ------- | ------- | ----------------------------------------------------------- |
38
+ | `ids` | Array | - | Array of project UUIDs to include or exclude |
39
+ | `exclude` | Boolean | `true` | Filtering mode: `true` for blocklist, `false` for allowlist |
40
+
41
+ ### Mode Examples
42
+
43
+ #### Blocklist Mode (exclude: true)
44
+
45
+ ```yaml
46
+ permissionControl:
47
+ ids:
48
+ - project-123
49
+ - project-456
50
+ exclude: true
51
+ ```
52
+
53
+ _Result: Show all projects **except** project-123 and project-456_
54
+
55
+ #### Allowlist Mode (exclude: false)
56
+
57
+ ```yaml
58
+ permissionControl:
59
+ ids:
60
+ - project-789
61
+ - project-101
62
+ exclude: false
63
+ ```
34
64
 
35
- - `ids`: Array of project UUIDs to include or exclude
36
- - `exclude`: Boolean flag (default: `true`)
37
- - `true`: Exclude the listed projects (blocklist)
38
- - `false`: Only show the listed projects (allowlist)
65
+ _Result: Show **only** project-789 and project-101_
39
66
 
40
- **Add the Mend.io frontend plugin**
67
+ ## Add the Mend.io frontend plugin
41
68
 
42
69
  See the [mend frontend plugin instructions](../mend/README.md).
@@ -63,7 +63,7 @@ const dataProjectParser = (projectStatistics, organizationProjects) => {
63
63
  uuid: next.uuid,
64
64
  name: next.name,
65
65
  path: next.path,
66
- entity: next.entity,
66
+ entityUrl: next.entityUrl,
67
67
  applicationName: organizationData[next.uuid].applicationName,
68
68
  applicationUuid: next.applicationUuid,
69
69
  lastScan: next.statistics["LAST_SCAN" /* LAST_SCAN */].lastScanTime,
@@ -88,7 +88,8 @@ const parseEntityURL = (entityUrl) => {
88
88
  if (!entityUrl) {
89
89
  return null;
90
90
  }
91
- const matches = entityUrl.match(
91
+ const cleanUrl = entityUrl.replace(/^url:/, "");
92
+ const matches = cleanUrl.match(
92
93
  /https?:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\/.*)?/g
93
94
  );
94
95
  if (!matches) {
@@ -96,15 +97,42 @@ const parseEntityURL = (entityUrl) => {
96
97
  }
97
98
  const url = new URL(matches[0]);
98
99
  const hostname = url.host.toLowerCase();
99
- let matcher = pathToRegexp.match("/:org/:repo", { end: false });
100
+ let path;
100
101
  if (hostname === constants.AZURE_HOST_NAME) {
101
- matcher = pathToRegexp.match("/:org/:project/_git/:repo", { end: false });
102
- }
103
- const extractedContent = matcher(url.pathname);
104
- if (extractedContent) {
105
- return { ...extractedContent, host: hostname };
102
+ const matcher = pathToRegexp.match("/:org/:project/_git/:repo", { end: false });
103
+ const extracted = matcher(url.pathname);
104
+ if (extracted) {
105
+ path = `/${extracted.params.org}/${extracted.params.project}/_git/${extracted.params.repo}`;
106
+ }
107
+ } else if (hostname.includes("gitlab")) {
108
+ const cleanPath = url.pathname.replace(/\/-\/(tree|blob)\/[^\/]+.*$/, "");
109
+ const matcher = pathToRegexp.match("/:org/:repo", { end: false });
110
+ const extracted = matcher(cleanPath);
111
+ if (extracted) {
112
+ path = cleanPath;
113
+ }
114
+ } else {
115
+ const matcher = pathToRegexp.match("/:org/:repo", { end: false });
116
+ const extracted = matcher(url.pathname);
117
+ if (extracted) {
118
+ path = `/${extracted.params.org}/${extracted.params.repo}`;
119
+ }
106
120
  }
121
+ return path ? { host: hostname, path } : null;
122
+ } catch (error) {
107
123
  return null;
124
+ }
125
+ };
126
+ const generateEntityUrl = (entity) => {
127
+ try {
128
+ const source = "catalog";
129
+ const namespace = entity?.metadata?.namespace;
130
+ const kind = entity?.kind?.toLowerCase();
131
+ const entityName = entity?.metadata?.name;
132
+ if (!namespace || !kind || !entityName) {
133
+ return null;
134
+ }
135
+ return `/${source}/${namespace}/${kind}/${entityName}`;
108
136
  } catch (error) {
109
137
  return null;
110
138
  }
@@ -113,24 +141,20 @@ const dataMatcher = (entities, projects) => {
113
141
  const projectSourceURL = getSourceURLWiseProject(projects);
114
142
  return entities.reduce(
115
143
  (prev, next) => {
116
- const entityURL = parseEntityURL(
144
+ const parsedSourceLocation = parseEntityURL(
117
145
  next?.metadata?.annotations?.["backstage.io/source-location"]
118
146
  );
119
- if (!entityURL) {
147
+ if (!parsedSourceLocation) {
120
148
  return prev;
121
149
  }
122
- const relatedProjects = projectSourceURL[`${entityURL?.host}${entityURL?.path}`]?.projectObjs;
150
+ const relatedProjects = projectSourceURL[`${parsedSourceLocation?.host}${parsedSourceLocation?.path}`]?.projectObjs;
123
151
  if (!relatedProjects) {
124
152
  return prev;
125
153
  }
126
- const entity = {
127
- path: entityURL.path,
128
- params: entityURL.params,
129
- namespace: next.metadata.namespace,
130
- kind: "component",
131
- source: "catalog"
132
- };
133
- relatedProjects.forEach((project) => prev.push({ ...project, entity }));
154
+ const entityUrl = generateEntityUrl(next);
155
+ relatedProjects.forEach(
156
+ (project) => prev.push({ ...project, entityUrl: entityUrl ?? void 0 })
157
+ );
134
158
  return prev;
135
159
  },
136
160
  []
@@ -292,6 +316,7 @@ exports.dataFindingParser = dataFindingParser;
292
316
  exports.dataMatcher = dataMatcher;
293
317
  exports.dataProjectParser = dataProjectParser;
294
318
  exports.fetchQueryPagination = fetchQueryPagination;
319
+ exports.generateEntityUrl = generateEntityUrl;
295
320
  exports.getSourceURLWiseProject = getSourceURLWiseProject;
296
321
  exports.parseEntityURL = parseEntityURL;
297
322
  //# sourceMappingURL=data.service.helpers.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"data.service.helpers.cjs.js","sources":["../../src/service/data.service.helpers.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport { match } from 'path-to-regexp';\nimport type { QueryParams } from '../api';\nimport {\n ProjectStatisticsSuccessResponseData,\n EntityURL,\n OrganizationProjectSuccessResponseData,\n PaginationQueryParams,\n Project,\n CodeFindingSuccessResponseData,\n DependenciesFindingSuccessResponseData,\n ContainersFindingSuccessResponseData,\n Finding,\n StatisticsEngine,\n StatisticsName,\n} from './data.service.types';\nimport { AZURE_HOST_NAME } from '../constants';\n\nenum FINDING_TYPE {\n DEPENDENCIES = 'ALERTS',\n CODE = 'SAST_VULNERABILITIES_BY_SEVERITY',\n CONTAINERS = 'IMG_SECURITY',\n LAST_SCAN = 'LAST_SCAN',\n}\n\ntype OverviewData = {\n projectList: Project[];\n};\n\nexport const dataProjectParser = (\n projectStatistics: Array<\n ProjectStatisticsSuccessResponseData & { entity: EntityURL }\n >,\n organizationProjects: OrganizationProjectSuccessResponseData[],\n) => {\n const organizationData = organizationProjects.reduce((prev, next) => {\n prev[next.uuid] = next;\n return prev;\n }, {} as { [key: string]: OrganizationProjectSuccessResponseData });\n\n const projectData = projectStatistics.reduce(\n (\n prev: OverviewData,\n next: ProjectStatisticsSuccessResponseData & { entity: EntityURL },\n ) => {\n const dependenciesCritical =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .criticalSeverityVulnerabilities;\n const dependenciesHigh =\n next.statistics[FINDING_TYPE.DEPENDENCIES].highSeverityVulnerabilities;\n const dependenciesMedium =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .mediumSeverityVulnerabilities;\n const dependenciesLow =\n next.statistics[FINDING_TYPE.DEPENDENCIES].lowSeverityVulnerabilities;\n const dependeciesTotal =\n dependenciesCritical +\n dependenciesHigh +\n dependenciesMedium +\n dependenciesLow;\n\n const codeHigh =\n next.statistics[FINDING_TYPE.CODE].sastHighVulnerabilities;\n const codeMedium =\n next.statistics[FINDING_TYPE.CODE].sastMediumVulnerabilities;\n const codeLow = next.statistics[FINDING_TYPE.CODE].sastLowVulnerabilities;\n const codeTotal = codeHigh + codeMedium + codeLow;\n\n const containersCritical =\n next.statistics[FINDING_TYPE.CONTAINERS].imgCriticalVulnerabilities;\n const containersHigh =\n next.statistics[FINDING_TYPE.CONTAINERS].imgHighVulnerabilities;\n const containersMedium =\n next.statistics[FINDING_TYPE.CONTAINERS].imgMediumVulnerabilities;\n const containersLow =\n next.statistics[FINDING_TYPE.CONTAINERS].imgLowVulnerabilities;\n const containersTotal =\n containersCritical + containersHigh + containersMedium + containersLow;\n\n const criticalTotal = dependenciesCritical + containersCritical;\n const highTotal = dependenciesHigh + codeHigh + containersHigh;\n const mediumTotal = dependenciesMedium + codeMedium + containersMedium;\n const lowTotal = dependenciesLow + codeLow + containersLow;\n const total = dependeciesTotal + codeTotal + containersTotal;\n\n const statistics = {\n [StatisticsEngine.DEPENDENCIES]: {\n critical: dependenciesCritical,\n high: dependenciesHigh,\n medium: dependenciesMedium,\n low: dependenciesLow,\n total: dependeciesTotal,\n },\n [StatisticsEngine.CODE]: {\n critical: null,\n high: codeHigh,\n medium: codeMedium,\n low: codeLow,\n total: codeTotal,\n },\n [StatisticsEngine.CONTAINERS]: {\n critical: containersCritical,\n high: containersHigh,\n medium: containersMedium,\n low: containersLow,\n total: containersTotal,\n },\n critical: criticalTotal,\n high: highTotal,\n medium: mediumTotal,\n low: lowTotal,\n total: total,\n };\n\n const project = {\n statistics,\n uuid: next.uuid,\n name: next.name,\n path: next.path,\n entity: next.entity,\n applicationName: organizationData[next.uuid].applicationName,\n applicationUuid: next.applicationUuid,\n lastScan: next.statistics[FINDING_TYPE.LAST_SCAN].lastScanTime,\n languages: next.statistics?.LIBRARY_TYPE_HISTOGRAM\n ? Object.entries(next.statistics.LIBRARY_TYPE_HISTOGRAM).sort(\n (a, b) => b[1] - a[1],\n )\n : ([] as [string, number][]),\n };\n\n prev.projectList.unshift(project);\n return prev;\n },\n {\n projectList: [],\n },\n );\n\n projectData.projectList.sort(\n (a, b) => b.statistics.critical - a.statistics.critical,\n );\n\n return projectData;\n};\n\nexport const parseEntityURL = (entityUrl?: string) => {\n try {\n if (!entityUrl) {\n return null;\n }\n\n const matches = entityUrl.match(\n /https?:\\/\\/[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\\/.*)?/g,\n );\n\n if (!matches) {\n return null;\n }\n const url = new URL(matches[0]);\n const hostname = url.host.toLowerCase();\n let matcher = match('/:org/:repo', { end: false });\n\n if (hostname === AZURE_HOST_NAME) {\n matcher = match('/:org/:project/_git/:repo', { end: false });\n }\n const extractedContent = matcher(url.pathname);\n if (extractedContent) {\n return { ...extractedContent, host: hostname };\n }\n return null;\n } catch (error) {\n return null;\n }\n};\n\nexport const dataMatcher = (\n entities: Entity[],\n projects: ProjectStatisticsSuccessResponseData[],\n) => {\n const projectSourceURL = getSourceURLWiseProject(projects);\n return entities.reduce(\n (\n prev: Array<\n ProjectStatisticsSuccessResponseData & {\n entity: EntityURL;\n }\n >,\n next: Entity,\n ) => {\n const entityURL = parseEntityURL(\n next?.metadata?.annotations?.['backstage.io/source-location'],\n );\n\n if (!entityURL) {\n return prev;\n }\n\n // NOTE: Find project based on Github URL\n const relatedProjects =\n projectSourceURL[`${entityURL?.host}${entityURL?.path}`]?.projectObjs;\n\n if (!relatedProjects) {\n return prev;\n }\n\n const entity = {\n path: entityURL.path,\n params: entityURL.params,\n namespace: next.metadata.namespace,\n kind: 'component',\n source: 'catalog',\n };\n\n relatedProjects.forEach(project => prev.push({ ...project, entity }));\n\n return prev;\n },\n [],\n );\n};\n\n/**\n * Extracts the source URL details from each project and returns a dictionary\n * where each key is a combination of the URL's host and pathname,\n * and the value is an object containing the original project and the parsed source URL data.\n *\n * @param projects Array of ProjectStatisticsSuccessResponseData\n * @returns A dictionary object with keys as `${host}${pathname}` strings extracted from sourceUrl and values as:\n * {\n * projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n * }\n */\nexport function getSourceURLWiseProject(\n projects: ProjectStatisticsSuccessResponseData[],\n) {\n return projects.reduce(\n (acc, project) => {\n const projectTags = project.tags as Array<{ key: string; value: string }>;\n const sourceUrlTag = projectTags?.find(tag => tag.key === 'sourceUrl');\n let host = null;\n let pathname = null;\n let sourceUrl = null;\n\n if (sourceUrlTag && typeof sourceUrlTag.value === 'string') {\n sourceUrl = sourceUrlTag.value;\n const urlString = sourceUrl.startsWith('http')\n ? sourceUrl\n : `https://${sourceUrl}`;\n\n try {\n const urlObj = new URL(urlString);\n host = urlObj.host.toLocaleLowerCase();\n // Remove leading/trailing slashes and split\n pathname = urlObj.pathname;\n } catch (e) {\n // fallback: leave as nulls\n }\n }\n\n if (acc[`${host}${pathname}`]) {\n acc[`${host}${pathname}`].projectObjs.push(project);\n } else {\n acc[`${host}${pathname}`] = {\n projectObjs: [project],\n sourceUrl,\n host,\n pathname,\n };\n }\n return acc;\n },\n {} as Record<\n string,\n {\n projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n }\n >,\n );\n}\n\nconst getIssueStatus = (\n engine: StatisticsEngine,\n finding:\n | CodeFindingSuccessResponseData\n | DependenciesFindingSuccessResponseData\n | ContainersFindingSuccessResponseData,\n): string => {\n if (engine === StatisticsEngine.CODE) {\n if ((finding as CodeFindingSuccessResponseData)?.suppressed)\n return 'suppressed';\n if (\n (finding as CodeFindingSuccessResponseData)?.almIssues?.jiraPlatform\n ?.issueStatus\n )\n return 'created';\n if ((finding as CodeFindingSuccessResponseData)?.reviewed)\n return 'reviewed';\n }\n\n if (engine === StatisticsEngine.DEPENDENCIES) {\n // NOTE: Available status: IGNORED and ACTIVE\n // ACTIVE means unreviewed\n // IGNORED means suppressed, comment fields are available to this status\n if (\n (finding as DependenciesFindingSuccessResponseData)?.findingInfo\n ?.status === 'IGNORED'\n )\n return 'suppressed';\n }\n\n return 'unreviewed';\n};\n\nexport const dataFindingParser = (\n code: CodeFindingSuccessResponseData[] = [],\n dependencies: DependenciesFindingSuccessResponseData[] = [],\n containers: ContainersFindingSuccessResponseData[] = [],\n projectName: string = '',\n) => {\n let codeFindings: Finding[] = [];\n let dependenciesFindings: Finding[] = [];\n let containersFindings: Finding[] = [];\n\n if (code.length) {\n codeFindings = code.map(finding => {\n return {\n kind: StatisticsEngine.CODE,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.type.cwe.title,\n origin: `${finding.sharedStep.file}:${finding.sharedStep.line}`,\n time: finding?.createdTime,\n projectId: finding.projectId,\n projectName: projectName,\n issue: {\n issueStatus: finding.almIssues.jiraPlatform.issueStatus,\n reporter: finding.almIssues.jiraPlatform.createdByName,\n creationDate: finding.almIssues.jiraPlatform.createdTime,\n ticketName: finding.almIssues.jiraPlatform.issueKey,\n link: `${finding.almIssues.jiraPlatform.publicLink}/browse/${finding.almIssues.jiraPlatform.issueKey}`,\n status: getIssueStatus(StatisticsEngine.CODE, finding),\n },\n };\n });\n }\n\n if (dependencies.length) {\n dependenciesFindings = dependencies.map(finding => {\n return {\n kind: StatisticsEngine.DEPENDENCIES,\n level: finding.vulnerability.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerability.name,\n origin: finding.component.name,\n time: finding.vulnerability.modifiedDate,\n projectId: finding.project.uuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.DEPENDENCIES, finding),\n },\n };\n });\n }\n\n if (containers.length) {\n containersFindings = containers.map(finding => {\n return {\n kind: StatisticsEngine.CONTAINERS,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerabilityId,\n origin: finding.packageName,\n time: finding.detectionDate,\n projectId: finding.projectUuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.CONTAINERS, finding), // NOTE: Currently, issue for finding in containers no exist.\n },\n };\n });\n }\n\n const order: { [k: string]: number } = {\n critical: 1,\n high: 2,\n medium: 3,\n low: 4,\n };\n\n return [...codeFindings, ...dependenciesFindings, ...containersFindings].sort(\n (a, b) => {\n return order[a.level] - order[b.level];\n },\n );\n};\n\nconst parseQueryString = (href = '?'): QueryParams => {\n const [, queryString] = href.split('?');\n\n const queryParams: QueryParams = {};\n new URLSearchParams(queryString).forEach((val, key) => {\n queryParams[key] = val;\n });\n\n return queryParams;\n};\n\nexport const fetchQueryPagination = async <T>(cb: Function) => {\n const defaultQueryParams = { limit: '10000', cursor: '0' };\n const collection: T[] = [];\n\n const fetchLoop = async (queryParams: PaginationQueryParams) => {\n const result = await cb({ queryParams });\n\n collection.push(...result.response);\n\n const nextQuery = result.additionalData?.paging?.next;\n\n if (nextQuery) {\n const newQueryParams = parseQueryString(nextQuery);\n await fetchLoop(newQueryParams);\n }\n };\n\n await fetchLoop(defaultQueryParams);\n\n return collection;\n};\n"],"names":["StatisticsEngine","match","AZURE_HOST_NAME"],"mappings":"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"}
1
+ {"version":3,"file":"data.service.helpers.cjs.js","sources":["../../src/service/data.service.helpers.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport { match } from 'path-to-regexp';\nimport type { QueryParams } from '../api';\nimport {\n ProjectStatisticsSuccessResponseData,\n OrganizationProjectSuccessResponseData,\n PaginationQueryParams,\n Project,\n CodeFindingSuccessResponseData,\n DependenciesFindingSuccessResponseData,\n ContainersFindingSuccessResponseData,\n Finding,\n StatisticsEngine,\n StatisticsName,\n} from './data.service.types';\nimport { AZURE_HOST_NAME } from '../constants';\n\nenum FINDING_TYPE {\n DEPENDENCIES = 'ALERTS',\n CODE = 'SAST_VULNERABILITIES_BY_SEVERITY',\n CONTAINERS = 'IMG_SECURITY',\n LAST_SCAN = 'LAST_SCAN',\n}\n\ntype OverviewData = {\n projectList: Project[];\n};\n\nexport const dataProjectParser = (\n projectStatistics: Array<\n ProjectStatisticsSuccessResponseData & { entityUrl?: string }\n >,\n organizationProjects: OrganizationProjectSuccessResponseData[],\n) => {\n const organizationData = organizationProjects.reduce((prev, next) => {\n prev[next.uuid] = next;\n return prev;\n }, {} as { [key: string]: OrganizationProjectSuccessResponseData });\n\n const projectData = projectStatistics.reduce(\n (\n prev: OverviewData,\n next: ProjectStatisticsSuccessResponseData & { entityUrl?: string },\n ) => {\n const dependenciesCritical =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .criticalSeverityVulnerabilities;\n const dependenciesHigh =\n next.statistics[FINDING_TYPE.DEPENDENCIES].highSeverityVulnerabilities;\n const dependenciesMedium =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .mediumSeverityVulnerabilities;\n const dependenciesLow =\n next.statistics[FINDING_TYPE.DEPENDENCIES].lowSeverityVulnerabilities;\n const dependeciesTotal =\n dependenciesCritical +\n dependenciesHigh +\n dependenciesMedium +\n dependenciesLow;\n\n const codeHigh =\n next.statistics[FINDING_TYPE.CODE].sastHighVulnerabilities;\n const codeMedium =\n next.statistics[FINDING_TYPE.CODE].sastMediumVulnerabilities;\n const codeLow = next.statistics[FINDING_TYPE.CODE].sastLowVulnerabilities;\n const codeTotal = codeHigh + codeMedium + codeLow;\n\n const containersCritical =\n next.statistics[FINDING_TYPE.CONTAINERS].imgCriticalVulnerabilities;\n const containersHigh =\n next.statistics[FINDING_TYPE.CONTAINERS].imgHighVulnerabilities;\n const containersMedium =\n next.statistics[FINDING_TYPE.CONTAINERS].imgMediumVulnerabilities;\n const containersLow =\n next.statistics[FINDING_TYPE.CONTAINERS].imgLowVulnerabilities;\n const containersTotal =\n containersCritical + containersHigh + containersMedium + containersLow;\n\n const criticalTotal = dependenciesCritical + containersCritical;\n const highTotal = dependenciesHigh + codeHigh + containersHigh;\n const mediumTotal = dependenciesMedium + codeMedium + containersMedium;\n const lowTotal = dependenciesLow + codeLow + containersLow;\n const total = dependeciesTotal + codeTotal + containersTotal;\n\n const statistics = {\n [StatisticsEngine.DEPENDENCIES]: {\n critical: dependenciesCritical,\n high: dependenciesHigh,\n medium: dependenciesMedium,\n low: dependenciesLow,\n total: dependeciesTotal,\n },\n [StatisticsEngine.CODE]: {\n critical: null,\n high: codeHigh,\n medium: codeMedium,\n low: codeLow,\n total: codeTotal,\n },\n [StatisticsEngine.CONTAINERS]: {\n critical: containersCritical,\n high: containersHigh,\n medium: containersMedium,\n low: containersLow,\n total: containersTotal,\n },\n critical: criticalTotal,\n high: highTotal,\n medium: mediumTotal,\n low: lowTotal,\n total: total,\n };\n\n const project = {\n statistics,\n uuid: next.uuid,\n name: next.name,\n path: next.path,\n entityUrl: next.entityUrl,\n applicationName: organizationData[next.uuid].applicationName,\n applicationUuid: next.applicationUuid,\n lastScan: next.statistics[FINDING_TYPE.LAST_SCAN].lastScanTime,\n languages: next.statistics?.LIBRARY_TYPE_HISTOGRAM\n ? Object.entries(next.statistics.LIBRARY_TYPE_HISTOGRAM).sort(\n (a, b) => b[1] - a[1],\n )\n : ([] as [string, number][]),\n };\n\n prev.projectList.unshift(project);\n return prev;\n },\n {\n projectList: [],\n },\n );\n\n projectData.projectList.sort(\n (a, b) => b.statistics.critical - a.statistics.critical,\n );\n\n return projectData;\n};\n\nexport const parseEntityURL = (entityUrl?: string) => {\n try {\n if (!entityUrl) {\n return null;\n }\n\n // Extract the base URL (remove \"url:\" prefix if present)\n const cleanUrl = entityUrl.replace(/^url:/, '');\n const matches = cleanUrl.match(\n /https?:\\/\\/[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\\/.*)?/g,\n );\n\n if (!matches) {\n return null;\n }\n const url = new URL(matches[0]);\n const hostname = url.host.toLowerCase();\n\n // Handle different SCM providers using path-to-regexp patterns\n let path;\n if (hostname === AZURE_HOST_NAME) {\n // Azure DevOps format: /org/project/_git/repo\n const matcher = match('/:org/:project/_git/:repo', { end: false });\n const extracted = matcher(url.pathname);\n if (extracted) {\n path = `/${extracted.params.org}/${extracted.params.project}/_git/${extracted.params.repo}`;\n }\n } else if (hostname.includes('gitlab')) {\n // GitLab format: /org/repo or /group/subgroup/.../repo\n // Remove GitLab-specific parts like /-/tree/branch\n const cleanPath = url.pathname.replace(/\\/-\\/(tree|blob)\\/[^\\/]+.*$/, '');\n\n // Use a pattern that matches any number of segments between org and repo\n const matcher = match('/:org/:repo', { end: false });\n const extracted = matcher(cleanPath);\n\n if (extracted) {\n // For GitLab, preserve the full path structure to support subgroups\n path = cleanPath;\n }\n } else {\n // GitHub and Bitbucket format: /org/repo\n const matcher = match('/:org/:repo', { end: false });\n const extracted = matcher(url.pathname);\n if (extracted) {\n path = `/${extracted.params.org}/${extracted.params.repo}`;\n }\n }\n\n return path ? { host: hostname, path } : null;\n } catch (error) {\n return null;\n }\n};\n\n/**\n * Generates entity URL for Backstage navigation\n * @param entity - Backstage entity\n * @returns Entity URL string or null if unable to generate\n */\nexport const generateEntityUrl = (entity: Entity): string | null => {\n try {\n const source = 'catalog';\n const namespace = entity?.metadata?.namespace;\n const kind = entity?.kind?.toLowerCase();\n const entityName = entity?.metadata?.name;\n\n if (!namespace || !kind || !entityName) {\n return null;\n }\n\n return `/${source}/${namespace}/${kind}/${entityName}`;\n } catch (error) {\n return null;\n }\n};\n\nexport const dataMatcher = (\n entities: Entity[],\n projects: ProjectStatisticsSuccessResponseData[],\n) => {\n const projectSourceURL = getSourceURLWiseProject(projects);\n return entities.reduce(\n (\n prev: Array<\n ProjectStatisticsSuccessResponseData & { entityUrl?: string }\n >,\n next: Entity,\n ) => {\n const parsedSourceLocation = parseEntityURL(\n next?.metadata?.annotations?.['backstage.io/source-location'],\n );\n\n if (!parsedSourceLocation) {\n return prev;\n }\n\n // NOTE: Find project based on Github URL\n const relatedProjects =\n projectSourceURL[\n `${parsedSourceLocation?.host}${parsedSourceLocation?.path}`\n ]?.projectObjs;\n\n if (!relatedProjects) {\n return prev;\n }\n\n const entityUrl = generateEntityUrl(next);\n\n relatedProjects.forEach(project =>\n prev.push({ ...project, entityUrl: entityUrl ?? undefined }),\n );\n\n return prev;\n },\n [],\n );\n};\n\n/**\n * Extracts the source URL details from each project and returns a dictionary\n * where each key is a combination of the URL's host and pathname,\n * and the value is an object containing the original project and the parsed source URL data.\n *\n * @param projects Array of ProjectStatisticsSuccessResponseData\n * @returns A dictionary object with keys as `${host}${pathname}` strings extracted from sourceUrl and values as:\n * {\n * projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n * }\n */\nexport function getSourceURLWiseProject(\n projects: ProjectStatisticsSuccessResponseData[],\n) {\n return projects.reduce(\n (acc, project) => {\n const projectTags = project.tags as Array<{ key: string; value: string }>;\n const sourceUrlTag = projectTags?.find(tag => tag.key === 'sourceUrl');\n let host = null;\n let pathname = null;\n let sourceUrl = null;\n\n if (sourceUrlTag && typeof sourceUrlTag.value === 'string') {\n sourceUrl = sourceUrlTag.value;\n const urlString = sourceUrl.startsWith('http')\n ? sourceUrl\n : `https://${sourceUrl}`;\n\n try {\n const urlObj = new URL(urlString);\n host = urlObj.host.toLocaleLowerCase();\n // Remove leading/trailing slashes and split\n pathname = urlObj.pathname;\n } catch (e) {\n // fallback: leave as nulls\n }\n }\n\n if (acc[`${host}${pathname}`]) {\n acc[`${host}${pathname}`].projectObjs.push(project);\n } else {\n acc[`${host}${pathname}`] = {\n projectObjs: [project],\n sourceUrl,\n host,\n pathname,\n };\n }\n return acc;\n },\n {} as Record<\n string,\n {\n projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n }\n >,\n );\n}\n\nconst getIssueStatus = (\n engine: StatisticsEngine,\n finding:\n | CodeFindingSuccessResponseData\n | DependenciesFindingSuccessResponseData\n | ContainersFindingSuccessResponseData,\n): string => {\n if (engine === StatisticsEngine.CODE) {\n if ((finding as CodeFindingSuccessResponseData)?.suppressed)\n return 'suppressed';\n if (\n (finding as CodeFindingSuccessResponseData)?.almIssues?.jiraPlatform\n ?.issueStatus\n )\n return 'created';\n if ((finding as CodeFindingSuccessResponseData)?.reviewed)\n return 'reviewed';\n }\n\n if (engine === StatisticsEngine.DEPENDENCIES) {\n // NOTE: Available status: IGNORED and ACTIVE\n // ACTIVE means unreviewed\n // IGNORED means suppressed, comment fields are available to this status\n if (\n (finding as DependenciesFindingSuccessResponseData)?.findingInfo\n ?.status === 'IGNORED'\n )\n return 'suppressed';\n }\n\n return 'unreviewed';\n};\n\nexport const dataFindingParser = (\n code: CodeFindingSuccessResponseData[] = [],\n dependencies: DependenciesFindingSuccessResponseData[] = [],\n containers: ContainersFindingSuccessResponseData[] = [],\n projectName: string = '',\n) => {\n let codeFindings: Finding[] = [];\n let dependenciesFindings: Finding[] = [];\n let containersFindings: Finding[] = [];\n\n if (code.length) {\n codeFindings = code.map(finding => {\n return {\n kind: StatisticsEngine.CODE,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.type.cwe.title,\n origin: `${finding.sharedStep.file}:${finding.sharedStep.line}`,\n time: finding?.createdTime,\n projectId: finding.projectId,\n projectName: projectName,\n issue: {\n issueStatus: finding.almIssues.jiraPlatform.issueStatus,\n reporter: finding.almIssues.jiraPlatform.createdByName,\n creationDate: finding.almIssues.jiraPlatform.createdTime,\n ticketName: finding.almIssues.jiraPlatform.issueKey,\n link: `${finding.almIssues.jiraPlatform.publicLink}/browse/${finding.almIssues.jiraPlatform.issueKey}`,\n status: getIssueStatus(StatisticsEngine.CODE, finding),\n },\n };\n });\n }\n\n if (dependencies.length) {\n dependenciesFindings = dependencies.map(finding => {\n return {\n kind: StatisticsEngine.DEPENDENCIES,\n level: finding.vulnerability.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerability.name,\n origin: finding.component.name,\n time: finding.vulnerability.modifiedDate,\n projectId: finding.project.uuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.DEPENDENCIES, finding),\n },\n };\n });\n }\n\n if (containers.length) {\n containersFindings = containers.map(finding => {\n return {\n kind: StatisticsEngine.CONTAINERS,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerabilityId,\n origin: finding.packageName,\n time: finding.detectionDate,\n projectId: finding.projectUuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.CONTAINERS, finding), // NOTE: Currently, issue for finding in containers no exist.\n },\n };\n });\n }\n\n const order: { [k: string]: number } = {\n critical: 1,\n high: 2,\n medium: 3,\n low: 4,\n };\n\n return [...codeFindings, ...dependenciesFindings, ...containersFindings].sort(\n (a, b) => {\n return order[a.level] - order[b.level];\n },\n );\n};\n\nconst parseQueryString = (href = '?'): QueryParams => {\n const [, queryString] = href.split('?');\n\n const queryParams: QueryParams = {};\n new URLSearchParams(queryString).forEach((val, key) => {\n queryParams[key] = val;\n });\n\n return queryParams;\n};\n\nexport const fetchQueryPagination = async <T>(cb: Function) => {\n const defaultQueryParams = { limit: '10000', cursor: '0' };\n const collection: T[] = [];\n\n const fetchLoop = async (queryParams: PaginationQueryParams) => {\n const result = await cb({ queryParams });\n\n collection.push(...result.response);\n\n const nextQuery = result.additionalData?.paging?.next;\n\n if (nextQuery) {\n const newQueryParams = parseQueryString(nextQuery);\n await fetchLoop(newQueryParams);\n }\n };\n\n await fetchLoop(defaultQueryParams);\n\n return collection;\n};\n"],"names":["StatisticsEngine","AZURE_HOST_NAME","match"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"data.service.types.cjs.js","sources":["../../src/service/data.service.types.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type PaginationQueryParams = {\n cursor?: string;\n limit?: string;\n};\n\ntype PaginationSuccessResponseData = {\n additionalData: {\n totalItems: number;\n paging: {\n next?: string;\n };\n };\n};\n\ntype BodyParams = {\n projectUuids?: string[];\n applicationUuid?: string[];\n};\n\ntype PathParams = {\n uuid: string;\n};\n\nexport type GetOrganizationProjectRequestData = {\n queryParams?: PaginationQueryParams;\n};\n\nexport type OrganizationProjectSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n};\n\nexport type GetOrganizationProjectSuccessResponseData = {\n supportToken: string;\n response: OrganizationProjectSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetProjectStatisticsRequestData = {\n queryParams?: PaginationQueryParams;\n bodyParams?: BodyParams;\n};\n\nexport type ProjectStatisticsSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n creationDate: string;\n tags: [];\n labels: [];\n statistics: {\n UNIFIED_VULNERABILITIES: {\n unifiedCriticalVulnerabilities: number;\n unifiedHighVulnerabilities: number;\n unifiedMediumVulnerabilities: number;\n unifiedLowVulnerabilities: number;\n unifiedVulnerabilities: number;\n };\n VULNERABILITY_EFFECTIVENESS: {};\n LIBRARY_TYPE_HISTOGRAM: Record<string, number>;\n IMG_USAGE: {};\n POLICY_VIOLATION_LIBRARIES: {\n policyViolatingLibraries: number;\n };\n SAST_VULNERABILITIES_BY_TYPE: Record<string, number>;\n GENERAL: {\n totalLibraries: number;\n };\n LLM_SECURITY: {\n llmTotalLines: number;\n };\n IMG_SECURITY: {\n imgCriticalVulnerabilities: number;\n imgMaxRiskScore: number;\n imgMediumVulnerabilities: number;\n imgLowVulnerabilities: number;\n imgSecretMediumVulnerabilities: number;\n imgUnknownVulnerabilities: number;\n imgSecretHighVulnerabilities: number;\n imgTotalVulnerabilities: number;\n imgHighVulnerabilities: number;\n imgSecretCriticalVulnerabilities: number;\n imgSecretLowVulnerabilities: number;\n };\n ALERTS: {\n criticalSeverityVulnerabilities: number;\n highSeverityVulnerabilities: number;\n vulnerableLibraries: number;\n mediumSeverityVulnerabilities: number;\n lowSeverityVulnerabilities: number;\n };\n OUTDATED_LIBRARIES: {\n outdatedLibraries: number;\n };\n POLICY_VIOLATIONS: {};\n SAST_SCAN: {\n sastTotalLines: number;\n sastTestedFiles: number;\n sastTotalFiles: number;\n sastTestedLines: number;\n sastTotalMended: number;\n sastTotalRemediations: number;\n };\n VULNERABILITY_SEVERITY_LIBRARIES: {\n lowSeverityLibraries: number;\n highSeverityLibraries: number;\n mediumSeverityLibraries: number;\n criticalSeverityLibraries: number;\n };\n LICENSE_RISK: {\n highRiskLicenses: number;\n mediumRiskLicenses: number;\n lowRiskLicenses: number;\n };\n IAC_SECURITY: {\n iacCriticalMisconfigurations: number;\n iacHighMisconfigurations: number;\n iacTotalMisconfigurations: number;\n iacLowMisconfigurations: number;\n iacMediumMisconfigurations: number;\n };\n SCA_SECURITY: {};\n LICENSE_HISTOGRAM: Record<string, number>;\n SAST_VULNERABILITIES_BY_SEVERITY: {\n sastVulnerabilities: number;\n sastHighVulnerabilities: number;\n sastMediumVulnerabilities: number;\n sastLowVulnerabilities: number;\n };\n LAST_SCAN: {\n lastScanTime: number;\n lastScaScanTime: number;\n lastImgScanTime: number;\n lastSastScanTime: number;\n };\n };\n};\n\nexport type GetProjectStatisticsSuccessResponseData = {\n supportToken: string;\n response: ProjectStatisticsSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type EntityURL = {\n path: string;\n params: {\n org?: string;\n repo?: string;\n };\n namespace?: string;\n kind: string;\n source: string;\n};\n\nexport enum StatisticsName {\n CRITICAL = 'critical',\n HIGH = 'high',\n MEDIUM = 'medium',\n LOW = 'low',\n TOTAL = 'total',\n}\n\nexport enum StatisticsEngine {\n DEPENDENCIES = 'dependencies',\n CODE = 'code',\n CONTAINERS = 'containers',\n}\n\ntype StatisticsBase = {\n [StatisticsName.CRITICAL]: number;\n [StatisticsName.HIGH]: number;\n [StatisticsName.MEDIUM]: number;\n [StatisticsName.LOW]: number;\n [StatisticsName.TOTAL]: number;\n};\n\nexport type Statistics = {\n [StatisticsEngine.DEPENDENCIES]: StatisticsBase;\n [StatisticsEngine.CODE]: Omit<StatisticsBase, StatisticsName.CRITICAL> & {\n [StatisticsName.CRITICAL]: null;\n };\n [StatisticsEngine.CONTAINERS]: StatisticsBase;\n} & StatisticsBase;\n\nexport type Project = {\n statistics: Statistics;\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n lastScan: number;\n languages: Array<[string, number]>;\n entity: EntityURL;\n};\n\n// Code Finding API Data\ntype CodeFindingDataFlowSuccessResponseData = {\n id: string;\n sink: string;\n sinkKind: string;\n sinkFile: string;\n sinkSnippet: string;\n sinkLine: number;\n inputSource: string;\n inputKind: string;\n inputFlow: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n functionCalls: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n filter: {\n isFiltered: boolean;\n filterTypes: unknown[];\n };\n isNew: boolean;\n rating: number;\n confidenceRating: number;\n ageRating: number;\n};\n\nexport type CodeFindingSuccessResponseData = {\n id: string;\n scanId: string;\n snapshotId: string;\n projectId: string;\n appId: string;\n type: {\n id: number;\n name: string;\n engineId: number;\n language: string;\n sarif: string;\n sarifLevel: string;\n order: number;\n severity: StatisticsName;\n severityRating: number;\n description: string;\n recommendations: [string];\n references: [string];\n cwe: {\n id: string;\n title: string;\n url: string;\n };\n pcidss: {\n section: string;\n title: string;\n };\n nist: {\n control: string;\n priority: string;\n title: string;\n url: string;\n };\n hipaa: {\n control: string;\n title: string;\n };\n hitrust: {\n control: string;\n title: string;\n };\n owasp: {\n index: string;\n title: string;\n url: string;\n };\n owasp2021: {\n index: string;\n title: string;\n url: string;\n };\n capec: {\n id: string;\n title: string;\n url: string;\n };\n sansTop25: {\n rank: number;\n title: string;\n };\n };\n description: string;\n createdTime: string;\n isNew: boolean;\n severity: StatisticsName;\n baseline: boolean;\n hasRemediation: boolean;\n suppressed: boolean;\n suppressedBy: string;\n suppressionTime: string;\n suppressionMessage: string;\n reviewed: boolean;\n IssueStatus: number;\n sharedStep: {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n lineBlame: {\n commitId: string;\n file: string;\n line: number;\n };\n };\n dataFlows: CodeFindingDataFlowSuccessResponseData[];\n severityRating: number;\n confidenceRating: number;\n ageRating: number;\n rating: number;\n almIssues: {\n jira: {\n issueId: string;\n project: string;\n };\n azure: {\n workItemId: number;\n project: string;\n };\n jiraPlatform: {\n internalStatus: string;\n issueStatus: string;\n issueKey: string;\n publicLink: string;\n createdTime: string;\n createdBy: string;\n createdByName: string;\n };\n };\n comments: unknown[];\n};\n\nexport type GetCodeFindingSuccessResponseData = {\n response: CodeFindingSuccessResponseData[];\n supportToken: string;\n} & PaginationSuccessResponseData;\n\nexport type GetCodeFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Dependencies Finding API Data\nexport type DependenciesFindingSuccessResponseData = {\n uuid: string;\n name: string;\n type: string;\n component: {\n uuid: string;\n name: string;\n description: string;\n componentType: string;\n libraryType: string;\n rootLibrary: boolean;\n references: {\n url: string;\n homePage: string;\n genericPackageIndex: string;\n };\n groupId: string;\n artifactId: string;\n version: string;\n path: string;\n };\n findingInfo: {\n status: string;\n comment: unknown;\n detectedAt: string;\n modifiedAt: string;\n };\n project: {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n };\n application: {\n uuid: string;\n name: string;\n };\n vulnerability: {\n name: string;\n type: string;\n description: string;\n score: number;\n severity: StatisticsName;\n publishDate: string;\n modifiedDate: string;\n vulnerabilityScoring: {\n score: number;\n severity: string;\n type: string;\n }[];\n };\n topFix: {\n id: number;\n vulnerability: string;\n type: string;\n origin: string;\n url: string;\n fixResolution: string;\n date: string;\n message: string;\n };\n effective: string;\n threatAssessment: {\n exploitCodeMaturity: string;\n epssPercentage: number;\n };\n exploitable: boolean;\n scoreMetadataVector: string;\n};\n\nexport type GetDependenciesFindingSuccessResponseData = {\n supportToken: string;\n response: DependenciesFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetDependenciesFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Containers Finding API Data\nexport type ContainersFindingSuccessResponseData = {\n uuid: string;\n vulnerabilityId: string;\n description: string;\n projectUuid: string;\n imageName: string;\n packageName: string;\n packageVersion: string;\n severity: StatisticsName;\n cvss: number;\n epss: number;\n hasFix: false;\n fixVersion: string;\n publishedDate: string;\n detectionDate: string;\n};\n\nexport type GetContainersFindingSuccessResponseData = {\n supportToken: string;\n response: ContainersFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetContainersFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\nexport type Finding = {\n kind: StatisticsEngine;\n level: StatisticsName;\n name: string;\n origin: string;\n time: string;\n projectId: string;\n projectName: string;\n issue: {\n issueStatus: string;\n reporter: string;\n creationDate: string;\n ticketName: string;\n link: string;\n status: string;\n };\n};\n"],"names":["StatisticsEngine"],"mappings":";;AAoLO,IAAK,gBAAA,qBAAAA,iBAAAA,KAAL;AACL,EAAAA,kBAAA,cAAA,CAAA,GAAe,cAAA;AACf,EAAAA,kBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,kBAAA,YAAA,CAAA,GAAa,YAAA;AAHH,EAAA,OAAAA,iBAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;;;;"}
1
+ {"version":3,"file":"data.service.types.cjs.js","sources":["../../src/service/data.service.types.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type PaginationQueryParams = {\n cursor?: string;\n limit?: string;\n};\n\ntype PaginationSuccessResponseData = {\n additionalData: {\n totalItems: number;\n paging: {\n next?: string;\n };\n };\n};\n\ntype BodyParams = {\n projectUuids?: string[];\n applicationUuid?: string[];\n};\n\ntype PathParams = {\n uuid: string;\n};\n\nexport type GetOrganizationProjectRequestData = {\n queryParams?: PaginationQueryParams;\n};\n\nexport type OrganizationProjectSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n};\n\nexport type GetOrganizationProjectSuccessResponseData = {\n supportToken: string;\n response: OrganizationProjectSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetProjectStatisticsRequestData = {\n queryParams?: PaginationQueryParams;\n bodyParams?: BodyParams;\n};\n\nexport type ProjectStatisticsSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n creationDate: string;\n tags: [];\n labels: [];\n statistics: {\n UNIFIED_VULNERABILITIES: {\n unifiedCriticalVulnerabilities: number;\n unifiedHighVulnerabilities: number;\n unifiedMediumVulnerabilities: number;\n unifiedLowVulnerabilities: number;\n unifiedVulnerabilities: number;\n };\n VULNERABILITY_EFFECTIVENESS: {};\n LIBRARY_TYPE_HISTOGRAM: Record<string, number>;\n IMG_USAGE: {};\n POLICY_VIOLATION_LIBRARIES: {\n policyViolatingLibraries: number;\n };\n SAST_VULNERABILITIES_BY_TYPE: Record<string, number>;\n GENERAL: {\n totalLibraries: number;\n };\n LLM_SECURITY: {\n llmTotalLines: number;\n };\n IMG_SECURITY: {\n imgCriticalVulnerabilities: number;\n imgMaxRiskScore: number;\n imgMediumVulnerabilities: number;\n imgLowVulnerabilities: number;\n imgSecretMediumVulnerabilities: number;\n imgUnknownVulnerabilities: number;\n imgSecretHighVulnerabilities: number;\n imgTotalVulnerabilities: number;\n imgHighVulnerabilities: number;\n imgSecretCriticalVulnerabilities: number;\n imgSecretLowVulnerabilities: number;\n };\n ALERTS: {\n criticalSeverityVulnerabilities: number;\n highSeverityVulnerabilities: number;\n vulnerableLibraries: number;\n mediumSeverityVulnerabilities: number;\n lowSeverityVulnerabilities: number;\n };\n OUTDATED_LIBRARIES: {\n outdatedLibraries: number;\n };\n POLICY_VIOLATIONS: {};\n SAST_SCAN: {\n sastTotalLines: number;\n sastTestedFiles: number;\n sastTotalFiles: number;\n sastTestedLines: number;\n sastTotalMended: number;\n sastTotalRemediations: number;\n };\n VULNERABILITY_SEVERITY_LIBRARIES: {\n lowSeverityLibraries: number;\n highSeverityLibraries: number;\n mediumSeverityLibraries: number;\n criticalSeverityLibraries: number;\n };\n LICENSE_RISK: {\n highRiskLicenses: number;\n mediumRiskLicenses: number;\n lowRiskLicenses: number;\n };\n IAC_SECURITY: {\n iacCriticalMisconfigurations: number;\n iacHighMisconfigurations: number;\n iacTotalMisconfigurations: number;\n iacLowMisconfigurations: number;\n iacMediumMisconfigurations: number;\n };\n SCA_SECURITY: {};\n LICENSE_HISTOGRAM: Record<string, number>;\n SAST_VULNERABILITIES_BY_SEVERITY: {\n sastVulnerabilities: number;\n sastHighVulnerabilities: number;\n sastMediumVulnerabilities: number;\n sastLowVulnerabilities: number;\n };\n LAST_SCAN: {\n lastScanTime: number;\n lastScaScanTime: number;\n lastImgScanTime: number;\n lastSastScanTime: number;\n };\n };\n};\n\nexport type GetProjectStatisticsSuccessResponseData = {\n supportToken: string;\n response: ProjectStatisticsSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport enum StatisticsName {\n CRITICAL = 'critical',\n HIGH = 'high',\n MEDIUM = 'medium',\n LOW = 'low',\n TOTAL = 'total',\n}\n\nexport enum StatisticsEngine {\n DEPENDENCIES = 'dependencies',\n CODE = 'code',\n CONTAINERS = 'containers',\n}\n\ntype StatisticsBase = {\n [StatisticsName.CRITICAL]: number;\n [StatisticsName.HIGH]: number;\n [StatisticsName.MEDIUM]: number;\n [StatisticsName.LOW]: number;\n [StatisticsName.TOTAL]: number;\n};\n\nexport type Statistics = {\n [StatisticsEngine.DEPENDENCIES]: StatisticsBase;\n [StatisticsEngine.CODE]: Omit<StatisticsBase, StatisticsName.CRITICAL> & {\n [StatisticsName.CRITICAL]: null;\n };\n [StatisticsEngine.CONTAINERS]: StatisticsBase;\n} & StatisticsBase;\n\nexport type Project = {\n statistics: Statistics;\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n lastScan: number;\n languages: Array<[string, number]>;\n entityUrl?: string;\n};\n\n// Code Finding API Data\ntype CodeFindingDataFlowSuccessResponseData = {\n id: string;\n sink: string;\n sinkKind: string;\n sinkFile: string;\n sinkSnippet: string;\n sinkLine: number;\n inputSource: string;\n inputKind: string;\n inputFlow: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n functionCalls: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n filter: {\n isFiltered: boolean;\n filterTypes: unknown[];\n };\n isNew: boolean;\n rating: number;\n confidenceRating: number;\n ageRating: number;\n};\n\nexport type CodeFindingSuccessResponseData = {\n id: string;\n scanId: string;\n snapshotId: string;\n projectId: string;\n appId: string;\n type: {\n id: number;\n name: string;\n engineId: number;\n language: string;\n sarif: string;\n sarifLevel: string;\n order: number;\n severity: StatisticsName;\n severityRating: number;\n description: string;\n recommendations: [string];\n references: [string];\n cwe: {\n id: string;\n title: string;\n url: string;\n };\n pcidss: {\n section: string;\n title: string;\n };\n nist: {\n control: string;\n priority: string;\n title: string;\n url: string;\n };\n hipaa: {\n control: string;\n title: string;\n };\n hitrust: {\n control: string;\n title: string;\n };\n owasp: {\n index: string;\n title: string;\n url: string;\n };\n owasp2021: {\n index: string;\n title: string;\n url: string;\n };\n capec: {\n id: string;\n title: string;\n url: string;\n };\n sansTop25: {\n rank: number;\n title: string;\n };\n };\n description: string;\n createdTime: string;\n isNew: boolean;\n severity: StatisticsName;\n baseline: boolean;\n hasRemediation: boolean;\n suppressed: boolean;\n suppressedBy: string;\n suppressionTime: string;\n suppressionMessage: string;\n reviewed: boolean;\n IssueStatus: number;\n sharedStep: {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n lineBlame: {\n commitId: string;\n file: string;\n line: number;\n };\n };\n dataFlows: CodeFindingDataFlowSuccessResponseData[];\n severityRating: number;\n confidenceRating: number;\n ageRating: number;\n rating: number;\n almIssues: {\n jira: {\n issueId: string;\n project: string;\n };\n azure: {\n workItemId: number;\n project: string;\n };\n jiraPlatform: {\n internalStatus: string;\n issueStatus: string;\n issueKey: string;\n publicLink: string;\n createdTime: string;\n createdBy: string;\n createdByName: string;\n };\n };\n comments: unknown[];\n};\n\nexport type GetCodeFindingSuccessResponseData = {\n response: CodeFindingSuccessResponseData[];\n supportToken: string;\n} & PaginationSuccessResponseData;\n\nexport type GetCodeFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Dependencies Finding API Data\nexport type DependenciesFindingSuccessResponseData = {\n uuid: string;\n name: string;\n type: string;\n component: {\n uuid: string;\n name: string;\n description: string;\n componentType: string;\n libraryType: string;\n rootLibrary: boolean;\n references: {\n url: string;\n homePage: string;\n genericPackageIndex: string;\n };\n groupId: string;\n artifactId: string;\n version: string;\n path: string;\n };\n findingInfo: {\n status: string;\n comment: unknown;\n detectedAt: string;\n modifiedAt: string;\n };\n project: {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n };\n application: {\n uuid: string;\n name: string;\n };\n vulnerability: {\n name: string;\n type: string;\n description: string;\n score: number;\n severity: StatisticsName;\n publishDate: string;\n modifiedDate: string;\n vulnerabilityScoring: {\n score: number;\n severity: string;\n type: string;\n }[];\n };\n topFix: {\n id: number;\n vulnerability: string;\n type: string;\n origin: string;\n url: string;\n fixResolution: string;\n date: string;\n message: string;\n };\n effective: string;\n threatAssessment: {\n exploitCodeMaturity: string;\n epssPercentage: number;\n };\n exploitable: boolean;\n scoreMetadataVector: string;\n};\n\nexport type GetDependenciesFindingSuccessResponseData = {\n supportToken: string;\n response: DependenciesFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetDependenciesFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Containers Finding API Data\nexport type ContainersFindingSuccessResponseData = {\n uuid: string;\n vulnerabilityId: string;\n description: string;\n projectUuid: string;\n imageName: string;\n packageName: string;\n packageVersion: string;\n severity: StatisticsName;\n cvss: number;\n epss: number;\n hasFix: false;\n fixVersion: string;\n publishedDate: string;\n detectionDate: string;\n};\n\nexport type GetContainersFindingSuccessResponseData = {\n supportToken: string;\n response: ContainersFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetContainersFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\nexport type Finding = {\n kind: StatisticsEngine;\n level: StatisticsName;\n name: string;\n origin: string;\n time: string;\n projectId: string;\n projectName: string;\n issue: {\n issueStatus: string;\n reporter: string;\n creationDate: string;\n ticketName: string;\n link: string;\n status: string;\n };\n};\n"],"names":["StatisticsEngine"],"mappings":";;AAyKO,IAAK,gBAAA,qBAAAA,iBAAAA,KAAL;AACL,EAAAA,kBAAA,cAAA,CAAA,GAAe,cAAA;AACf,EAAAA,kBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,kBAAA,YAAA,CAAA,GAAa,YAAA;AAHH,EAAA,OAAAA,iBAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage-community/plugin-mend-backend",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "main": "dist/index.cjs.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -37,13 +37,13 @@
37
37
  "postpack": "backstage-cli package postpack"
38
38
  },
39
39
  "dependencies": {
40
- "@backstage/backend-defaults": "^0.14.0",
41
- "@backstage/backend-plugin-api": "^1.6.0",
42
- "@backstage/catalog-client": "^1.12.1",
40
+ "@backstage/backend-defaults": "^0.15.2",
41
+ "@backstage/backend-plugin-api": "^1.7.0",
42
+ "@backstage/catalog-client": "^1.13.0",
43
43
  "@backstage/catalog-model": "^1.7.6",
44
44
  "@backstage/config": "^1.3.6",
45
- "@backstage/plugin-permission-common": "^0.9.3",
46
- "@backstage/plugin-permission-node": "^0.10.7",
45
+ "@backstage/plugin-permission-common": "^0.9.6",
46
+ "@backstage/plugin-permission-node": "^0.10.10",
47
47
  "@types/express": "^4.17.6",
48
48
  "express": "^4.17.1",
49
49
  "express-promise-router": "^4.1.0",
@@ -55,11 +55,11 @@
55
55
  "zod": "^3.23.8"
56
56
  },
57
57
  "devDependencies": {
58
- "@backstage/backend-test-utils": "^1.10.2",
59
- "@backstage/cli": "^0.35.1",
60
- "@backstage/plugin-auth-backend": "^0.25.7",
61
- "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.15",
62
- "@backstage/plugin-catalog-backend": "^3.3.0",
58
+ "@backstage/backend-test-utils": "^1.11.0",
59
+ "@backstage/cli": "^0.35.4",
60
+ "@backstage/plugin-auth-backend": "^0.27.0",
61
+ "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.16",
62
+ "@backstage/plugin-catalog-backend": "^3.4.0",
63
63
  "@types/supertest": "^6.0.0",
64
64
  "msw": "^1.0.0",
65
65
  "supertest": "^7.0.0"