@backstage-community/plugin-mend-backend 0.1.1 → 0.2.0
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 +6 -0
- package/dist/api/index.cjs.js +68 -0
- package/dist/api/index.cjs.js.map +1 -0
- package/dist/index.cjs.js +11 -742
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/permission/conditions.cjs.js +33 -0
- package/dist/permission/conditions.cjs.js.map +1 -0
- package/dist/permission/permissions.cjs.js +17 -0
- package/dist/permission/permissions.cjs.js.map +1 -0
- package/dist/permission/rules.cjs.js +31 -0
- package/dist/permission/rules.cjs.js.map +1 -0
- package/dist/plugin.cjs.js +48 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/service/auth.service.cjs.js +93 -0
- package/dist/service/auth.service.cjs.js.map +1 -0
- package/dist/service/auth.service.helpers.cjs.js +14 -0
- package/dist/service/auth.service.helpers.cjs.js.map +1 -0
- package/dist/service/data.service.cjs.js +65 -0
- package/dist/service/data.service.cjs.js.map +1 -0
- package/dist/service/data.service.helpers.cjs.js +248 -0
- package/dist/service/data.service.helpers.cjs.js.map +1 -0
- package/dist/service/data.service.types.cjs.js +11 -0
- package/dist/service/data.service.types.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +194 -0
- package/dist/service/router.cjs.js.map +1 -0
- package/package.json +20 -13
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/service/data.service.types.ts","../src/service/data.service.helpers.ts","../src/service/auth.service.helpers.ts","../src/service/auth.service.ts","../src/api/index.ts","../src/service/data.service.ts","../src/permission/permissions.ts","../src/permission/rules.ts","../src/permission/conditions.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["export 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 issue: {\n issueStatus: string;\n reporter: string;\n creationDate: string;\n ticketName: string;\n link: string;\n status: string;\n };\n};\n","import { 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';\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: Object.entries(next.statistics.LIBRARY_TYPE_HISTOGRAM).sort(\n (a, b) => b[1] - a[1],\n ),\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\nconst 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\n const url = new URL(matches[0]);\n const fn = match('/:org/:repo', { end: false });\n return fn(url.pathname);\n } catch (error) {\n return null;\n }\n};\n\nexport const dataMatcher = (\n entities: Entity[],\n projects: ProjectStatisticsSuccessResponseData[],\n) => {\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 GH_ prefix\n const project = projects.find(\n (item: { path: string }) =>\n item.path.match(/^GH_(.*)/)?.[1] === entityURL?.params.repo,\n );\n\n if (!project) {\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 prev.push({ ...project, entity });\n\n return prev;\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) => {\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 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 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 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","export const caesarCipherDecrypt = (activationKey: string): string => {\n let tmp = '';\n const OFFSET = 4;\n for (let i = 0; i < activationKey.length; i++) {\n tmp += String.fromCharCode(activationKey.charCodeAt(i) - OFFSET);\n }\n\n const reversed = tmp.split('').reverse().join('');\n return Buffer.from(reversed, 'base64').toString();\n};\n","import jwt from 'jsonwebtoken';\nimport { post } from '../api';\nimport { caesarCipherDecrypt } from './auth.service.helpers';\nimport {\n JwtAuthToken,\n JwtLicenceKeyPayload,\n LoginSuccessResponseData,\n MendConfig,\n RefreshAccessTokenSuccessResponseData,\n} from './auth.services.types';\n\nenum AuthRoutes {\n LOGIN = '/login',\n REFRESH_TOKEN = '/login/accessToken',\n}\n\nexport class MendAuthSevice {\n private static authToken = '';\n private static refreshToken = '';\n private static baseUrl = '';\n private static clientEmail = '';\n private static clientKey = '';\n private static clientUrl = '';\n private static clientName = '';\n private static clientUuid = '';\n\n constructor(config: MendConfig) {\n MendAuthSevice.baseUrl = config.baseUrl;\n this.getConfig(config.activationKey);\n }\n\n private getConfig(activationKey: string) {\n const licenseKey = caesarCipherDecrypt(activationKey);\n const jwtPayload = jwt.decode(licenseKey) as JwtLicenceKeyPayload;\n MendAuthSevice.clientEmail = jwtPayload.integratorEmail;\n MendAuthSevice.clientKey = jwtPayload.userKey;\n MendAuthSevice.clientUrl = jwtPayload.wsEnvUrl;\n }\n\n private static async login(): Promise<void> {\n return post<LoginSuccessResponseData>(AuthRoutes.LOGIN, {\n body: {\n email: this.clientEmail,\n userKey: this.clientKey,\n },\n }).then(data => {\n this.refreshToken = data.response.refreshToken;\n return Promise.resolve();\n });\n }\n\n private static async refreshAccessToken(): Promise<void> {\n return post<RefreshAccessTokenSuccessResponseData>(\n AuthRoutes.REFRESH_TOKEN,\n {\n headers: {\n 'wss-refresh-token': this.refreshToken,\n },\n },\n ).then(data => {\n this.authToken = data.response.jwtToken;\n this.clientName = data.response.orgName;\n this.clientUuid = data.response.orgUuid;\n return Promise.resolve();\n });\n }\n\n static async connect(): Promise<void> {\n return MendAuthSevice.login().then(() =>\n MendAuthSevice.refreshAccessToken(),\n );\n }\n\n static async validateAuthToken(url: string): Promise<void> {\n if (\n [AuthRoutes.LOGIN, AuthRoutes.REFRESH_TOKEN].includes(url as AuthRoutes)\n ) {\n return Promise.resolve();\n }\n\n if (!this.authToken) {\n return this.connect();\n }\n\n const token = jwt.decode(this.authToken) as JwtAuthToken;\n if (new Date(Number(`${token.exp}000`)).getTime() - Date.now() < 0) {\n return this.connect();\n }\n\n return Promise.resolve();\n }\n\n static getAuthToken(): string {\n return MendAuthSevice.authToken;\n }\n\n static getBaseUrl(): string {\n return MendAuthSevice.baseUrl;\n }\n\n static getOrganizationUuid(): string {\n return MendAuthSevice.clientUuid;\n }\n\n static getClientUrl(): string {\n return MendAuthSevice.clientUrl;\n }\n\n static getClientName(): string {\n return MendAuthSevice.clientName;\n }\n}\n","import { MendAuthSevice } from '../service/auth.service';\n\nexport type QueryParams = Record<string, string>;\n\ntype RequestHeaders = Record<string, string>;\n\nenum ApiHeaders {\n AUTH_TOKEN = 'Authorization',\n CONTENT_TYPE = 'Content-Type',\n AGENT_NAME = 'agent-name',\n AGENT_VERSION = 'agent-version',\n}\n\nenum REQUEST_METHOD {\n GET = 'GET',\n POST = 'POST',\n PUT = 'PUT',\n DELETE = 'DELETE',\n}\n\ninterface RequestOptions {\n body?: any;\n headers?: RequestHeaders;\n params?: Record<string, any> | null;\n}\n\nfunction assembleUri(uri: string, params?: QueryParams): string {\n if (!params) {\n return uri;\n }\n\n const queryString = new URLSearchParams(params).toString();\n return `${uri}?${queryString}`;\n}\n\nfunction buildHeaders(optionHeaders: RequestHeaders): Headers {\n const headers = new Headers();\n headers.set(ApiHeaders.CONTENT_TYPE, 'application/json');\n headers.set(ApiHeaders.AGENT_NAME, 'pi-backstage');\n headers.set(ApiHeaders.AGENT_VERSION, '24.8.2');\n\n const authToken = MendAuthSevice.getAuthToken();\n\n if (authToken) {\n headers.set(ApiHeaders.AUTH_TOKEN, `Bearer ${authToken}`);\n }\n\n Object.keys(optionHeaders).forEach(header => {\n const headerValue = optionHeaders[header];\n if (headerValue) {\n headers.set(header, headerValue);\n }\n });\n\n return headers;\n}\n\nfunction fetchRequest(\n method: REQUEST_METHOD,\n path: string,\n opts: RequestOptions,\n): Promise<any> {\n return MendAuthSevice.validateAuthToken(path).then(() => {\n const { params, body, headers } = opts;\n\n const url = `${MendAuthSevice.getBaseUrl()}${path}`;\n const requestURL = params ? assembleUri(url, params) : url;\n\n const requestParams = {\n headers: buildHeaders(headers || {}),\n method,\n body,\n };\n\n if (body) {\n requestParams.body =\n typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n const requestObject: Request = new Request(requestURL, requestParams);\n\n return fetch(requestObject);\n });\n}\n\nfunction toJson(response: Response): Promise<any> {\n if (response.status === 204 || response.body === null) {\n return Promise.resolve({});\n }\n\n return response.json().then(json => {\n return response.ok ? json : Promise.reject(json);\n });\n}\n\nconst defaultOpts: RequestOptions = {\n body: null,\n headers: {},\n params: null,\n};\n\nexport function get<T>(\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(REQUEST_METHOD.GET, url, opts).then(toJson);\n}\n\nexport function post<T>(\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(REQUEST_METHOD.POST, url, opts).then(toJson);\n}\n\nexport function put<T>(\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(REQUEST_METHOD.PUT, url, opts).then(toJson);\n}\n\nexport function remove<T>(\n url: string,\n opts: RequestOptions = defaultOpts,\n): Promise<T> {\n return fetchRequest(REQUEST_METHOD.DELETE, url, opts).then(toJson);\n}\n","import { get, post } from '../api';\nimport { MendAuthSevice } from './auth.service';\nimport {\n GetOrganizationProjectRequestData,\n GetProjectStatisticsRequestData,\n GetCodeFindingsRequestData,\n GetDependenciesFindingsRequestData,\n GetContainersFindingsRequestData,\n GetOrganizationProjectSuccessResponseData,\n GetProjectStatisticsSuccessResponseData,\n GetCodeFindingSuccessResponseData,\n GetDependenciesFindingSuccessResponseData,\n GetContainersFindingSuccessResponseData,\n} from './data.service.types';\n\nexport class MendDataService extends MendAuthSevice {\n async getOrganizationProject({\n queryParams,\n }: GetOrganizationProjectRequestData): Promise<GetOrganizationProjectSuccessResponseData> {\n return get(`/orgs/${MendAuthSevice.getOrganizationUuid()}/projects`, {\n params: {\n ...queryParams,\n },\n });\n }\n\n async getProjectStatistics({\n queryParams,\n bodyParams,\n }: GetProjectStatisticsRequestData): Promise<GetProjectStatisticsSuccessResponseData> {\n return post(\n `/orgs/${MendAuthSevice.getOrganizationUuid()}/projects/summaries`,\n {\n params: {\n ...queryParams,\n },\n body: {\n ...bodyParams,\n },\n },\n );\n }\n\n async getCodeFinding({\n pathParams,\n queryParams,\n }: GetCodeFindingsRequestData): Promise<GetCodeFindingSuccessResponseData> {\n return get(`/projects/${pathParams.uuid}/code/findings`, {\n params: {\n ...queryParams,\n },\n });\n }\n\n async getDependenciesFinding({\n pathParams,\n queryParams,\n }: GetDependenciesFindingsRequestData): Promise<GetDependenciesFindingSuccessResponseData> {\n return get(`/projects/${pathParams.uuid}/dependencies/findings/security`, {\n params: {\n ...queryParams,\n },\n });\n }\n\n async getContainersFinding({\n pathParams,\n queryParams,\n }: GetContainersFindingsRequestData): Promise<GetContainersFindingSuccessResponseData> {\n return get(`/projects/${pathParams.uuid}/images/findings/security`, {\n params: {\n ...queryParams,\n },\n });\n }\n}\n","import { createPermission } from '@backstage/plugin-permission-common';\n\n/** @public */\nexport enum RESOURCE_TYPE {\n PROJECT = 'mend-project',\n}\n\n/** @public */\nexport const mendReadPermission = createPermission({\n name: 'mend.project.read',\n attributes: { action: 'read' },\n resourceType: RESOURCE_TYPE.PROJECT,\n});\n\nexport const mendPermissions = [mendReadPermission];\n","import { z } from 'zod';\nimport { makeCreatePermissionRule } from '@backstage/plugin-permission-node';\nimport { RESOURCE_TYPE } from './permissions';\n\ntype PermissionAttributes = {\n action?: 'create' | 'read' | 'update' | 'delete';\n};\n\ntype ResourceProps = {\n permission: {\n type: string;\n name: string;\n attributes: PermissionAttributes;\n resourceType: typeof RESOURCE_TYPE.PROJECT;\n };\n resourceRef: string;\n};\n\n/** @public */\nexport type FilterProps = {\n ids: string[];\n exclude?: boolean;\n};\n\nexport const createProjectPermissionRule = makeCreatePermissionRule<\n ResourceProps,\n FilterProps,\n typeof RESOURCE_TYPE.PROJECT\n>();\n\nexport const filter = createProjectPermissionRule({\n name: 'filter',\n description: 'Should allow read-only access to filtered projects.',\n resourceType: RESOURCE_TYPE.PROJECT,\n paramsSchema: z.object({\n ids: z.string().array().describe('Project ID to match resource'),\n exclude: z.boolean().optional().describe('Exclude or include project'),\n }),\n apply: (resource, { ids, exclude = true }) => {\n return exclude\n ? !ids.includes(resource.resourceRef)\n : ids.includes(resource.resourceRef);\n },\n toQuery: ({ ids, exclude = true }) => {\n return {\n ids,\n exclude,\n };\n },\n});\n\nexport const rules = { filter };\n","import express from 'express';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport {\n createPermissionIntegrationRouter,\n createConditionTransformer,\n ConditionTransformer,\n} from '@backstage/plugin-permission-node';\nimport { rules, type FilterProps } from './rules';\nimport { RESOURCE_TYPE, mendReadPermission } from './permissions';\n\nconst { conditions, createConditionalDecision } = createConditionExports({\n pluginId: 'mend',\n resourceType: RESOURCE_TYPE.PROJECT,\n rules,\n});\n\n/** @public */\nexport const mendConditions = conditions;\n\n/** @public */\nexport const createMendProjectConditionalDecision = createConditionalDecision;\n\nexport const permissionIntegrationRouter: express.Router =\n createPermissionIntegrationRouter({\n permissions: [mendReadPermission],\n getResources: async resourceRefs => {\n return resourceRefs.map(resourceRef => {\n return {\n permission: mendReadPermission,\n resourceRef,\n };\n });\n },\n resourceType: RESOURCE_TYPE.PROJECT,\n rules: Object.values(rules),\n });\n\nexport const transformConditions: ConditionTransformer<FilterProps> =\n createConditionTransformer(Object.values(rules));\n","import express from 'express';\nimport Router from 'express-promise-router';\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n LoggerService,\n DiscoveryService,\n AuthService,\n HttpAuthService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { CatalogClient } from '@backstage/catalog-client';\nimport { Config } from '@backstage/config';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport {\n dataFindingParser,\n dataMatcher,\n dataProjectParser,\n fetchQueryPagination,\n} from './data.service.helpers';\nimport { MendDataService } from './data.service';\nimport { MendAuthSevice } from './auth.service';\nimport {\n PaginationQueryParams,\n ProjectStatisticsSuccessResponseData,\n OrganizationProjectSuccessResponseData,\n CodeFindingSuccessResponseData,\n DependenciesFindingSuccessResponseData,\n ContainersFindingSuccessResponseData,\n} from './data.service.types';\nimport {\n mendReadPermission,\n transformConditions,\n permissionIntegrationRouter,\n type FilterProps,\n} from '../permission';\n\n/** @internal */\nexport type RouterOptions = {\n logger: LoggerService;\n config: Config;\n discovery: DiscoveryService;\n auth: AuthService;\n httpAuth: HttpAuthService;\n permissions: PermissionsService;\n};\n\nenum ROUTE {\n PROJECT = '/project',\n FINDING = '/finding',\n}\n\n/** @internal */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, discovery, auth, httpAuth, permissions } = options;\n\n const router = Router();\n router.use(express.json());\n\n router.use(permissionIntegrationRouter);\n\n const checkForAuth = (\n _request: express.Request,\n response: express.Response,\n next: express.NextFunction,\n ) => {\n if (MendAuthSevice.getAuthToken()) {\n next();\n return;\n }\n\n MendAuthSevice.connect()\n .then(next)\n .catch(() => {\n response.status(401).json({ error: 'Oops! Unauthorized' });\n });\n };\n\n const baseUrl = config.getString('mend.baseUrl');\n const activationKey = config.getString('mend.activationKey');\n\n // Init api service\n const mendDataService = new MendDataService({\n baseUrl,\n activationKey,\n });\n\n // Init catalog client\n const catalogClient = new CatalogClient({ discoveryApi: discovery });\n\n // Routes\n router.get(ROUTE.PROJECT, checkForAuth, async (request, response) => {\n try {\n // service to service auth\n const credentials = await httpAuth.credentials(request);\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'plugin.catalog.service',\n });\n\n // entity to project match\n const results = await Promise.all([\n catalogClient.getEntities(\n { filter: [{ kind: ['Component'] }] },\n { token },\n ),\n fetchQueryPagination<ProjectStatisticsSuccessResponseData>(\n mendDataService.getProjectStatistics,\n ),\n fetchQueryPagination<OrganizationProjectSuccessResponseData>(\n mendDataService.getOrganizationProject,\n ),\n ]);\n\n // permission - filter to exclude or include project\n const decision = (\n await permissions.authorizeConditional(\n [{ permission: mendReadPermission }],\n {\n credentials,\n },\n )\n )[0];\n\n let items;\n if (decision.result === AuthorizeResult.CONDITIONAL) {\n const filter = transformConditions(decision.conditions) as FilterProps;\n items = results[1].filter(item =>\n filter?.exclude\n ? !filter.ids.includes(item.uuid)\n : filter.ids.includes(item.uuid),\n );\n }\n\n const data = dataMatcher(results[0].items, items || results[1]);\n\n // parse data\n const projects = dataProjectParser(data, results[2]);\n\n response.json({\n ...projects,\n clientUrl: MendAuthSevice.getClientUrl(),\n clientName: MendAuthSevice.getClientName(),\n });\n // Allow any object structure here\n } catch (error: any) {\n logger.error('/project', error);\n response.status(500).json({ error: 'Oops! Please try again later.' });\n }\n });\n\n router.post(ROUTE.FINDING, checkForAuth, async (request, response) => {\n try {\n // service to service auth\n const credentials = await httpAuth.credentials(request);\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'plugin.catalog.service',\n });\n\n // entity to project match\n const uid = request.body.uid;\n\n if (!uid) {\n response.status(401).json({ error: 'Oops! No UUID provided' });\n return;\n }\n\n const projectResult = await Promise.all([\n catalogClient.getEntities(\n { filter: [{ 'metadata.uid': uid }] },\n { token },\n ),\n fetchQueryPagination<ProjectStatisticsSuccessResponseData>(\n mendDataService.getProjectStatistics,\n ),\n fetchQueryPagination<OrganizationProjectSuccessResponseData>(\n mendDataService.getOrganizationProject,\n ),\n ]);\n\n // permission - filter to exclude or include project\n const decision = (\n await permissions.authorizeConditional(\n [{ permission: mendReadPermission }],\n {\n credentials,\n },\n )\n )[0];\n\n let items;\n if (decision.result === AuthorizeResult.CONDITIONAL) {\n const filter = transformConditions(decision.conditions) as FilterProps;\n items = projectResult[1].filter(item =>\n filter?.exclude\n ? !filter.ids.includes(item.uuid)\n : filter.ids.includes(item.uuid),\n );\n }\n\n const data = dataMatcher(\n projectResult[0].items,\n items || projectResult[1],\n );\n\n if (!data.length) {\n response.json({\n findingList: [],\n projectName: '',\n projectUuid: '',\n clientUrl: MendAuthSevice.getClientUrl(),\n clientName: MendAuthSevice.getClientName(),\n });\n return;\n }\n\n const params = {\n pathParams: {\n uuid: data[0].uuid,\n },\n };\n\n // get project findings\n const findingResult = await Promise.all([\n fetchQueryPagination<CodeFindingSuccessResponseData>(\n (queryParam: PaginationQueryParams) =>\n mendDataService.getCodeFinding({\n ...params,\n ...queryParam,\n }),\n ),\n fetchQueryPagination<DependenciesFindingSuccessResponseData>(\n (queryParam: PaginationQueryParams) =>\n mendDataService.getDependenciesFinding({\n ...params,\n ...queryParam,\n }),\n ),\n fetchQueryPagination<ContainersFindingSuccessResponseData>(\n (queryParam: PaginationQueryParams) =>\n mendDataService.getContainersFinding({\n ...params,\n ...queryParam,\n }),\n ),\n ]);\n\n const project = dataProjectParser(data, projectResult[2]);\n const findingList = dataFindingParser(\n findingResult[0].filter(item => !item.suppressed), // NOTE: Do not show suppressed item\n findingResult[1].filter(\n item => !(item.findingInfo.status === 'IGNORED'),\n ), // NOTE: Do not show ignored item\n findingResult[2], // ESC-51: Follow Jira activity\n );\n\n response.json({\n findingList,\n projectName: project.projectList[0].entity.params.repo,\n projectUuid: project.projectList[0].uuid,\n clientUrl: MendAuthSevice.getClientUrl(),\n clientName: MendAuthSevice.getClientName(),\n });\n // Allow any object structure here\n } catch (error: any) {\n logger.error('/finding', error);\n response.status(500).json({ error: 'Oops! Please try again later.' });\n }\n });\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\n response.json({ status: 'ok' });\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n\n router.use(middleware.error());\n return router;\n}\n","import {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * mendPlugin backend plugin\n *\n * @public\n */\nexport const mendPlugin = createBackendPlugin({\n pluginId: 'mend',\n register(env) {\n env.registerInit({\n deps: {\n auth: coreServices.auth,\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n httpAuth: coreServices.httpAuth,\n httpRouter: coreServices.httpRouter,\n logger: coreServices.logger,\n permissions: coreServices.permissions,\n },\n async init({\n auth,\n config,\n discovery,\n httpAuth,\n httpRouter,\n logger,\n permissions,\n }) {\n httpRouter.use(\n await createRouter({\n auth,\n config,\n discovery,\n httpAuth,\n logger,\n permissions,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["StatisticsEngine","match","jwt","RESOURCE_TYPE","createPermission","makeCreatePermissionRule","z","createConditionExports","createPermissionIntegrationRouter","createConditionTransformer","Router","express","catalogClient","CatalogClient","AuthorizeResult","MiddlewareFactory","createBackendPlugin","coreServices"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
2
|
import * as _backstage_plugin_permission_common from '@backstage/plugin-permission-common';
|
|
3
|
+
import * as _backstage_plugin_permission_common_index from '@backstage/plugin-permission-common/index';
|
|
3
4
|
import * as _backstage_plugin_permission_node from '@backstage/plugin-permission-node';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -7,7 +8,7 @@ import * as _backstage_plugin_permission_node from '@backstage/plugin-permission
|
|
|
7
8
|
*
|
|
8
9
|
* @public
|
|
9
10
|
*/
|
|
10
|
-
declare const mendPlugin: _backstage_backend_plugin_api.
|
|
11
|
+
declare const mendPlugin: _backstage_backend_plugin_api.BackendFeature;
|
|
11
12
|
|
|
12
13
|
/** @public */
|
|
13
14
|
declare enum RESOURCE_TYPE {
|
|
@@ -40,6 +41,6 @@ declare const mendConditions: _backstage_plugin_permission_node.Conditions<{
|
|
|
40
41
|
}>;
|
|
41
42
|
}>;
|
|
42
43
|
/** @public */
|
|
43
|
-
declare const createMendProjectConditionalDecision: (permission:
|
|
44
|
+
declare const createMendProjectConditionalDecision: (permission: _backstage_plugin_permission_common_index.ResourcePermission<RESOURCE_TYPE>, conditions: _backstage_plugin_permission_common_index.PermissionCriteria<_backstage_plugin_permission_common_index.PermissionCondition<RESOURCE_TYPE>>) => _backstage_plugin_permission_common_index.ConditionalPolicyDecision;
|
|
44
45
|
|
|
45
46
|
export { type FilterProps, RESOURCE_TYPE, createMendProjectConditionalDecision, mendPlugin as default, mendConditions, mendReadPermission };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
4
|
+
var rules = require('./rules.cjs.js');
|
|
5
|
+
var permissions = require('./permissions.cjs.js');
|
|
6
|
+
|
|
7
|
+
const { conditions, createConditionalDecision } = pluginPermissionNode.createConditionExports({
|
|
8
|
+
pluginId: "mend",
|
|
9
|
+
resourceType: permissions.RESOURCE_TYPE.PROJECT,
|
|
10
|
+
rules: rules.rules
|
|
11
|
+
});
|
|
12
|
+
const mendConditions = conditions;
|
|
13
|
+
const createMendProjectConditionalDecision = createConditionalDecision;
|
|
14
|
+
const permissionIntegrationRouter = pluginPermissionNode.createPermissionIntegrationRouter({
|
|
15
|
+
permissions: [permissions.mendReadPermission],
|
|
16
|
+
getResources: async (resourceRefs) => {
|
|
17
|
+
return resourceRefs.map((resourceRef) => {
|
|
18
|
+
return {
|
|
19
|
+
permission: permissions.mendReadPermission,
|
|
20
|
+
resourceRef
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
},
|
|
24
|
+
resourceType: permissions.RESOURCE_TYPE.PROJECT,
|
|
25
|
+
rules: Object.values(rules.rules)
|
|
26
|
+
});
|
|
27
|
+
const transformConditions = pluginPermissionNode.createConditionTransformer(Object.values(rules.rules));
|
|
28
|
+
|
|
29
|
+
exports.createMendProjectConditionalDecision = createMendProjectConditionalDecision;
|
|
30
|
+
exports.mendConditions = mendConditions;
|
|
31
|
+
exports.permissionIntegrationRouter = permissionIntegrationRouter;
|
|
32
|
+
exports.transformConditions = transformConditions;
|
|
33
|
+
//# sourceMappingURL=conditions.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditions.cjs.js","sources":["../../src/permission/conditions.ts"],"sourcesContent":["import express from 'express';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport {\n createPermissionIntegrationRouter,\n createConditionTransformer,\n ConditionTransformer,\n} from '@backstage/plugin-permission-node';\nimport { rules, type FilterProps } from './rules';\nimport { RESOURCE_TYPE, mendReadPermission } from './permissions';\n\nconst { conditions, createConditionalDecision } = createConditionExports({\n pluginId: 'mend',\n resourceType: RESOURCE_TYPE.PROJECT,\n rules,\n});\n\n/** @public */\nexport const mendConditions = conditions;\n\n/** @public */\nexport const createMendProjectConditionalDecision = createConditionalDecision;\n\nexport const permissionIntegrationRouter: express.Router =\n createPermissionIntegrationRouter({\n permissions: [mendReadPermission],\n getResources: async resourceRefs => {\n return resourceRefs.map(resourceRef => {\n return {\n permission: mendReadPermission,\n resourceRef,\n };\n });\n },\n resourceType: RESOURCE_TYPE.PROJECT,\n rules: Object.values(rules),\n });\n\nexport const transformConditions: ConditionTransformer<FilterProps> =\n createConditionTransformer(Object.values(rules));\n"],"names":["createConditionExports","RESOURCE_TYPE","rules","createPermissionIntegrationRouter","mendReadPermission","createConditionTransformer"],"mappings":";;;;;;AAUA,MAAM,EAAE,UAAA,EAAY,yBAA0B,EAAA,GAAIA,2CAAuB,CAAA;AAAA,EACvE,QAAU,EAAA,MAAA;AAAA,EACV,cAAcC,yBAAc,CAAA,OAAA;AAAA,SAC5BC;AACF,CAAC,CAAA;AAGM,MAAM,cAAiB,GAAA;AAGvB,MAAM,oCAAuC,GAAA;AAE7C,MAAM,8BACXC,sDAAkC,CAAA;AAAA,EAChC,WAAA,EAAa,CAACC,8BAAkB,CAAA;AAAA,EAChC,YAAA,EAAc,OAAM,YAAgB,KAAA;AAClC,IAAO,OAAA,YAAA,CAAa,IAAI,CAAe,WAAA,KAAA;AACrC,MAAO,OAAA;AAAA,QACL,UAAY,EAAAA,8BAAA;AAAA,QACZ;AAAA,OACF;AAAA,KACD,CAAA;AAAA,GACH;AAAA,EACA,cAAcH,yBAAc,CAAA,OAAA;AAAA,EAC5B,KAAA,EAAO,MAAO,CAAA,MAAA,CAAOC,WAAK;AAC5B,CAAC;AAEI,MAAM,mBACX,GAAAG,+CAAA,CAA2B,MAAO,CAAA,MAAA,CAAOH,WAAK,CAAC;;;;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
|
|
4
|
+
|
|
5
|
+
var RESOURCE_TYPE = /* @__PURE__ */ ((RESOURCE_TYPE2) => {
|
|
6
|
+
RESOURCE_TYPE2["PROJECT"] = "mend-project";
|
|
7
|
+
return RESOURCE_TYPE2;
|
|
8
|
+
})(RESOURCE_TYPE || {});
|
|
9
|
+
const mendReadPermission = pluginPermissionCommon.createPermission({
|
|
10
|
+
name: "mend.project.read",
|
|
11
|
+
attributes: { action: "read" },
|
|
12
|
+
resourceType: "mend-project" /* PROJECT */
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
exports.RESOURCE_TYPE = RESOURCE_TYPE;
|
|
16
|
+
exports.mendReadPermission = mendReadPermission;
|
|
17
|
+
//# sourceMappingURL=permissions.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.cjs.js","sources":["../../src/permission/permissions.ts"],"sourcesContent":["import { createPermission } from '@backstage/plugin-permission-common';\n\n/** @public */\nexport enum RESOURCE_TYPE {\n PROJECT = 'mend-project',\n}\n\n/** @public */\nexport const mendReadPermission = createPermission({\n name: 'mend.project.read',\n attributes: { action: 'read' },\n resourceType: RESOURCE_TYPE.PROJECT,\n});\n\nexport const mendPermissions = [mendReadPermission];\n"],"names":["RESOURCE_TYPE","createPermission"],"mappings":";;;;AAGY,IAAA,aAAA,qBAAAA,cAAL,KAAA;AACL,EAAAA,eAAA,SAAU,CAAA,GAAA,cAAA;AADA,EAAAA,OAAAA,cAAAA;AAAA,CAAA,EAAA,aAAA,IAAA,EAAA;AAKL,MAAM,qBAAqBC,uCAAiB,CAAA;AAAA,EACjD,IAAM,EAAA,mBAAA;AAAA,EACN,UAAA,EAAY,EAAE,MAAA,EAAQ,MAAO,EAAA;AAAA,EAC7B,YAAc,EAAA,cAAA;AAChB,CAAC;;;;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
5
|
+
var permissions = require('./permissions.cjs.js');
|
|
6
|
+
|
|
7
|
+
const createProjectPermissionRule = pluginPermissionNode.makeCreatePermissionRule();
|
|
8
|
+
const filter = createProjectPermissionRule({
|
|
9
|
+
name: "filter",
|
|
10
|
+
description: "Should allow read-only access to filtered projects.",
|
|
11
|
+
resourceType: permissions.RESOURCE_TYPE.PROJECT,
|
|
12
|
+
paramsSchema: zod.z.object({
|
|
13
|
+
ids: zod.z.string().array().describe("Project ID to match resource"),
|
|
14
|
+
exclude: zod.z.boolean().optional().describe("Exclude or include project")
|
|
15
|
+
}),
|
|
16
|
+
apply: (resource, { ids, exclude = true }) => {
|
|
17
|
+
return exclude ? !ids.includes(resource.resourceRef) : ids.includes(resource.resourceRef);
|
|
18
|
+
},
|
|
19
|
+
toQuery: ({ ids, exclude = true }) => {
|
|
20
|
+
return {
|
|
21
|
+
ids,
|
|
22
|
+
exclude
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const rules = { filter };
|
|
27
|
+
|
|
28
|
+
exports.createProjectPermissionRule = createProjectPermissionRule;
|
|
29
|
+
exports.filter = filter;
|
|
30
|
+
exports.rules = rules;
|
|
31
|
+
//# sourceMappingURL=rules.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.cjs.js","sources":["../../src/permission/rules.ts"],"sourcesContent":["import { z } from 'zod';\nimport { makeCreatePermissionRule } from '@backstage/plugin-permission-node';\nimport { RESOURCE_TYPE } from './permissions';\n\ntype PermissionAttributes = {\n action?: 'create' | 'read' | 'update' | 'delete';\n};\n\ntype ResourceProps = {\n permission: {\n type: string;\n name: string;\n attributes: PermissionAttributes;\n resourceType: typeof RESOURCE_TYPE.PROJECT;\n };\n resourceRef: string;\n};\n\n/** @public */\nexport type FilterProps = {\n ids: string[];\n exclude?: boolean;\n};\n\nexport const createProjectPermissionRule = makeCreatePermissionRule<\n ResourceProps,\n FilterProps,\n typeof RESOURCE_TYPE.PROJECT\n>();\n\nexport const filter = createProjectPermissionRule({\n name: 'filter',\n description: 'Should allow read-only access to filtered projects.',\n resourceType: RESOURCE_TYPE.PROJECT,\n paramsSchema: z.object({\n ids: z.string().array().describe('Project ID to match resource'),\n exclude: z.boolean().optional().describe('Exclude or include project'),\n }),\n apply: (resource, { ids, exclude = true }) => {\n return exclude\n ? !ids.includes(resource.resourceRef)\n : ids.includes(resource.resourceRef);\n },\n toQuery: ({ ids, exclude = true }) => {\n return {\n ids,\n exclude,\n };\n },\n});\n\nexport const rules = { filter };\n"],"names":["makeCreatePermissionRule","RESOURCE_TYPE","z"],"mappings":";;;;;;AAwBO,MAAM,8BAA8BA,6CAIzC;AAEK,MAAM,SAAS,2BAA4B,CAAA;AAAA,EAChD,IAAM,EAAA,QAAA;AAAA,EACN,WAAa,EAAA,qDAAA;AAAA,EACb,cAAcC,yBAAc,CAAA,OAAA;AAAA,EAC5B,YAAA,EAAcC,MAAE,MAAO,CAAA;AAAA,IACrB,KAAKA,KAAE,CAAA,MAAA,GAAS,KAAM,EAAA,CAAE,SAAS,8BAA8B,CAAA;AAAA,IAC/D,SAASA,KAAE,CAAA,OAAA,GAAU,QAAS,EAAA,CAAE,SAAS,4BAA4B;AAAA,GACtE,CAAA;AAAA,EACD,OAAO,CAAC,QAAA,EAAU,EAAE,GAAK,EAAA,OAAA,GAAU,MAAW,KAAA;AAC5C,IAAO,OAAA,OAAA,GACH,CAAC,GAAA,CAAI,QAAS,CAAA,QAAA,CAAS,WAAW,CAClC,GAAA,GAAA,CAAI,QAAS,CAAA,QAAA,CAAS,WAAW,CAAA;AAAA,GACvC;AAAA,EACA,SAAS,CAAC,EAAE,GAAK,EAAA,OAAA,GAAU,MAAW,KAAA;AACpC,IAAO,OAAA;AAAA,MACL,GAAA;AAAA,MACA;AAAA,KACF;AAAA;AAEJ,CAAC;AAEY,MAAA,KAAA,GAAQ,EAAE,MAAO;;;;;;"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
var router = require('./service/router.cjs.js');
|
|
5
|
+
|
|
6
|
+
const mendPlugin = backendPluginApi.createBackendPlugin({
|
|
7
|
+
pluginId: "mend",
|
|
8
|
+
register(env) {
|
|
9
|
+
env.registerInit({
|
|
10
|
+
deps: {
|
|
11
|
+
auth: backendPluginApi.coreServices.auth,
|
|
12
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
13
|
+
discovery: backendPluginApi.coreServices.discovery,
|
|
14
|
+
httpAuth: backendPluginApi.coreServices.httpAuth,
|
|
15
|
+
httpRouter: backendPluginApi.coreServices.httpRouter,
|
|
16
|
+
logger: backendPluginApi.coreServices.logger,
|
|
17
|
+
permissions: backendPluginApi.coreServices.permissions
|
|
18
|
+
},
|
|
19
|
+
async init({
|
|
20
|
+
auth,
|
|
21
|
+
config,
|
|
22
|
+
discovery,
|
|
23
|
+
httpAuth,
|
|
24
|
+
httpRouter,
|
|
25
|
+
logger,
|
|
26
|
+
permissions
|
|
27
|
+
}) {
|
|
28
|
+
httpRouter.use(
|
|
29
|
+
await router.createRouter({
|
|
30
|
+
auth,
|
|
31
|
+
config,
|
|
32
|
+
discovery,
|
|
33
|
+
httpAuth,
|
|
34
|
+
logger,
|
|
35
|
+
permissions
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
httpRouter.addAuthPolicy({
|
|
39
|
+
path: "/health",
|
|
40
|
+
allow: "unauthenticated"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
exports.mendPlugin = mendPlugin;
|
|
48
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * mendPlugin backend plugin\n *\n * @public\n */\nexport const mendPlugin = createBackendPlugin({\n pluginId: 'mend',\n register(env) {\n env.registerInit({\n deps: {\n auth: coreServices.auth,\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n httpAuth: coreServices.httpAuth,\n httpRouter: coreServices.httpRouter,\n logger: coreServices.logger,\n permissions: coreServices.permissions,\n },\n async init({\n auth,\n config,\n discovery,\n httpAuth,\n httpRouter,\n logger,\n permissions,\n }) {\n httpRouter.use(\n await createRouter({\n auth,\n config,\n discovery,\n httpAuth,\n logger,\n permissions,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","createRouter"],"mappings":";;;;;AAWO,MAAM,aAAaA,oCAAoB,CAAA;AAAA,EAC5C,QAAU,EAAA,MAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,MAAMC,6BAAa,CAAA,IAAA;AAAA,QACnB,QAAQA,6BAAa,CAAA,UAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,UAAUA,6BAAa,CAAA,QAAA;AAAA,QACvB,YAAYA,6BAAa,CAAA,UAAA;AAAA,QACzB,QAAQA,6BAAa,CAAA,MAAA;AAAA,QACrB,aAAaA,6BAAa,CAAA;AAAA,OAC5B;AAAA,MACA,MAAM,IAAK,CAAA;AAAA,QACT,IAAA;AAAA,QACA,MAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA,UAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACC,EAAA;AACD,QAAW,UAAA,CAAA,GAAA;AAAA,UACT,MAAMC,mBAAa,CAAA;AAAA,YACjB,IAAA;AAAA,YACA,MAAA;AAAA,YACA,SAAA;AAAA,YACA,QAAA;AAAA,YACA,MAAA;AAAA,YACA;AAAA,WACD;AAAA,SACH;AACA,QAAA,UAAA,CAAW,aAAc,CAAA;AAAA,UACvB,IAAM,EAAA,SAAA;AAAA,UACN,KAAO,EAAA;AAAA,SACR,CAAA;AAAA;AACH,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jwt = require('jsonwebtoken');
|
|
4
|
+
var index = require('../api/index.cjs.js');
|
|
5
|
+
var auth_service_helpers = require('./auth.service.helpers.cjs.js');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var jwt__default = /*#__PURE__*/_interopDefaultCompat(jwt);
|
|
10
|
+
|
|
11
|
+
class MendAuthSevice {
|
|
12
|
+
static authToken = "";
|
|
13
|
+
static refreshToken = "";
|
|
14
|
+
static baseUrl = "";
|
|
15
|
+
static clientEmail = "";
|
|
16
|
+
static clientKey = "";
|
|
17
|
+
static clientUrl = "";
|
|
18
|
+
static clientName = "";
|
|
19
|
+
static clientUuid = "";
|
|
20
|
+
constructor(config) {
|
|
21
|
+
MendAuthSevice.baseUrl = config.baseUrl;
|
|
22
|
+
this.getConfig(config.activationKey);
|
|
23
|
+
}
|
|
24
|
+
getConfig(activationKey) {
|
|
25
|
+
const licenseKey = auth_service_helpers.caesarCipherDecrypt(activationKey);
|
|
26
|
+
const jwtPayload = jwt__default.default.decode(licenseKey);
|
|
27
|
+
MendAuthSevice.clientEmail = jwtPayload.integratorEmail;
|
|
28
|
+
MendAuthSevice.clientKey = jwtPayload.userKey;
|
|
29
|
+
MendAuthSevice.clientUrl = jwtPayload.wsEnvUrl;
|
|
30
|
+
}
|
|
31
|
+
static async login() {
|
|
32
|
+
return index.post("/login" /* LOGIN */, {
|
|
33
|
+
body: {
|
|
34
|
+
email: this.clientEmail,
|
|
35
|
+
userKey: this.clientKey
|
|
36
|
+
}
|
|
37
|
+
}).then((data) => {
|
|
38
|
+
this.refreshToken = data.response.refreshToken;
|
|
39
|
+
return Promise.resolve();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
static async refreshAccessToken() {
|
|
43
|
+
return index.post(
|
|
44
|
+
"/login/accessToken" /* REFRESH_TOKEN */,
|
|
45
|
+
{
|
|
46
|
+
headers: {
|
|
47
|
+
"wss-refresh-token": this.refreshToken
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
).then((data) => {
|
|
51
|
+
this.authToken = data.response.jwtToken;
|
|
52
|
+
this.clientName = data.response.orgName;
|
|
53
|
+
this.clientUuid = data.response.orgUuid;
|
|
54
|
+
return Promise.resolve();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
static async connect() {
|
|
58
|
+
return MendAuthSevice.login().then(
|
|
59
|
+
() => MendAuthSevice.refreshAccessToken()
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
static async validateAuthToken(url) {
|
|
63
|
+
if (["/login" /* LOGIN */, "/login/accessToken" /* REFRESH_TOKEN */].includes(url)) {
|
|
64
|
+
return Promise.resolve();
|
|
65
|
+
}
|
|
66
|
+
if (!this.authToken) {
|
|
67
|
+
return this.connect();
|
|
68
|
+
}
|
|
69
|
+
const token = jwt__default.default.decode(this.authToken);
|
|
70
|
+
if (new Date(Number(`${token.exp}000`)).getTime() - Date.now() < 0) {
|
|
71
|
+
return this.connect();
|
|
72
|
+
}
|
|
73
|
+
return Promise.resolve();
|
|
74
|
+
}
|
|
75
|
+
static getAuthToken() {
|
|
76
|
+
return MendAuthSevice.authToken;
|
|
77
|
+
}
|
|
78
|
+
static getBaseUrl() {
|
|
79
|
+
return MendAuthSevice.baseUrl;
|
|
80
|
+
}
|
|
81
|
+
static getOrganizationUuid() {
|
|
82
|
+
return MendAuthSevice.clientUuid;
|
|
83
|
+
}
|
|
84
|
+
static getClientUrl() {
|
|
85
|
+
return MendAuthSevice.clientUrl;
|
|
86
|
+
}
|
|
87
|
+
static getClientName() {
|
|
88
|
+
return MendAuthSevice.clientName;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
exports.MendAuthSevice = MendAuthSevice;
|
|
93
|
+
//# sourceMappingURL=auth.service.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.service.cjs.js","sources":["../../src/service/auth.service.ts"],"sourcesContent":["import jwt from 'jsonwebtoken';\nimport { post } from '../api';\nimport { caesarCipherDecrypt } from './auth.service.helpers';\nimport {\n JwtAuthToken,\n JwtLicenceKeyPayload,\n LoginSuccessResponseData,\n MendConfig,\n RefreshAccessTokenSuccessResponseData,\n} from './auth.services.types';\n\nenum AuthRoutes {\n LOGIN = '/login',\n REFRESH_TOKEN = '/login/accessToken',\n}\n\nexport class MendAuthSevice {\n private static authToken = '';\n private static refreshToken = '';\n private static baseUrl = '';\n private static clientEmail = '';\n private static clientKey = '';\n private static clientUrl = '';\n private static clientName = '';\n private static clientUuid = '';\n\n constructor(config: MendConfig) {\n MendAuthSevice.baseUrl = config.baseUrl;\n this.getConfig(config.activationKey);\n }\n\n private getConfig(activationKey: string) {\n const licenseKey = caesarCipherDecrypt(activationKey);\n const jwtPayload = jwt.decode(licenseKey) as JwtLicenceKeyPayload;\n MendAuthSevice.clientEmail = jwtPayload.integratorEmail;\n MendAuthSevice.clientKey = jwtPayload.userKey;\n MendAuthSevice.clientUrl = jwtPayload.wsEnvUrl;\n }\n\n private static async login(): Promise<void> {\n return post<LoginSuccessResponseData>(AuthRoutes.LOGIN, {\n body: {\n email: this.clientEmail,\n userKey: this.clientKey,\n },\n }).then(data => {\n this.refreshToken = data.response.refreshToken;\n return Promise.resolve();\n });\n }\n\n private static async refreshAccessToken(): Promise<void> {\n return post<RefreshAccessTokenSuccessResponseData>(\n AuthRoutes.REFRESH_TOKEN,\n {\n headers: {\n 'wss-refresh-token': this.refreshToken,\n },\n },\n ).then(data => {\n this.authToken = data.response.jwtToken;\n this.clientName = data.response.orgName;\n this.clientUuid = data.response.orgUuid;\n return Promise.resolve();\n });\n }\n\n static async connect(): Promise<void> {\n return MendAuthSevice.login().then(() =>\n MendAuthSevice.refreshAccessToken(),\n );\n }\n\n static async validateAuthToken(url: string): Promise<void> {\n if (\n [AuthRoutes.LOGIN, AuthRoutes.REFRESH_TOKEN].includes(url as AuthRoutes)\n ) {\n return Promise.resolve();\n }\n\n if (!this.authToken) {\n return this.connect();\n }\n\n const token = jwt.decode(this.authToken) as JwtAuthToken;\n if (new Date(Number(`${token.exp}000`)).getTime() - Date.now() < 0) {\n return this.connect();\n }\n\n return Promise.resolve();\n }\n\n static getAuthToken(): string {\n return MendAuthSevice.authToken;\n }\n\n static getBaseUrl(): string {\n return MendAuthSevice.baseUrl;\n }\n\n static getOrganizationUuid(): string {\n return MendAuthSevice.clientUuid;\n }\n\n static getClientUrl(): string {\n return MendAuthSevice.clientUrl;\n }\n\n static getClientName(): string {\n return MendAuthSevice.clientName;\n }\n}\n"],"names":["caesarCipherDecrypt","jwt","post"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const caesarCipherDecrypt = (activationKey) => {
|
|
4
|
+
let tmp = "";
|
|
5
|
+
const OFFSET = 4;
|
|
6
|
+
for (let i = 0; i < activationKey.length; i++) {
|
|
7
|
+
tmp += String.fromCharCode(activationKey.charCodeAt(i) - OFFSET);
|
|
8
|
+
}
|
|
9
|
+
const reversed = tmp.split("").reverse().join("");
|
|
10
|
+
return Buffer.from(reversed, "base64").toString();
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
exports.caesarCipherDecrypt = caesarCipherDecrypt;
|
|
14
|
+
//# sourceMappingURL=auth.service.helpers.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.service.helpers.cjs.js","sources":["../../src/service/auth.service.helpers.ts"],"sourcesContent":["export const caesarCipherDecrypt = (activationKey: string): string => {\n let tmp = '';\n const OFFSET = 4;\n for (let i = 0; i < activationKey.length; i++) {\n tmp += String.fromCharCode(activationKey.charCodeAt(i) - OFFSET);\n }\n\n const reversed = tmp.split('').reverse().join('');\n return Buffer.from(reversed, 'base64').toString();\n};\n"],"names":[],"mappings":";;AAAa,MAAA,mBAAA,GAAsB,CAAC,aAAkC,KAAA;AACpE,EAAA,IAAI,GAAM,GAAA,EAAA;AACV,EAAA,MAAM,MAAS,GAAA,CAAA;AACf,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,aAAA,CAAc,QAAQ,CAAK,EAAA,EAAA;AAC7C,IAAA,GAAA,IAAO,OAAO,YAAa,CAAA,aAAA,CAAc,UAAW,CAAA,CAAC,IAAI,MAAM,CAAA;AAAA;AAGjE,EAAM,MAAA,QAAA,GAAW,IAAI,KAAM,CAAA,EAAE,EAAE,OAAQ,EAAA,CAAE,KAAK,EAAE,CAAA;AAChD,EAAA,OAAO,MAAO,CAAA,IAAA,CAAK,QAAU,EAAA,QAAQ,EAAE,QAAS,EAAA;AAClD;;;;"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('../api/index.cjs.js');
|
|
4
|
+
var auth_service = require('./auth.service.cjs.js');
|
|
5
|
+
|
|
6
|
+
class MendDataService extends auth_service.MendAuthSevice {
|
|
7
|
+
async getOrganizationProject({
|
|
8
|
+
queryParams
|
|
9
|
+
}) {
|
|
10
|
+
return index.get(`/orgs/${auth_service.MendAuthSevice.getOrganizationUuid()}/projects`, {
|
|
11
|
+
params: {
|
|
12
|
+
...queryParams
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async getProjectStatistics({
|
|
17
|
+
queryParams,
|
|
18
|
+
bodyParams
|
|
19
|
+
}) {
|
|
20
|
+
return index.post(
|
|
21
|
+
`/orgs/${auth_service.MendAuthSevice.getOrganizationUuid()}/projects/summaries`,
|
|
22
|
+
{
|
|
23
|
+
params: {
|
|
24
|
+
...queryParams
|
|
25
|
+
},
|
|
26
|
+
body: {
|
|
27
|
+
...bodyParams
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
async getCodeFinding({
|
|
33
|
+
pathParams,
|
|
34
|
+
queryParams
|
|
35
|
+
}) {
|
|
36
|
+
return index.get(`/projects/${pathParams.uuid}/code/findings`, {
|
|
37
|
+
params: {
|
|
38
|
+
...queryParams
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async getDependenciesFinding({
|
|
43
|
+
pathParams,
|
|
44
|
+
queryParams
|
|
45
|
+
}) {
|
|
46
|
+
return index.get(`/projects/${pathParams.uuid}/dependencies/findings/security`, {
|
|
47
|
+
params: {
|
|
48
|
+
...queryParams
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async getContainersFinding({
|
|
53
|
+
pathParams,
|
|
54
|
+
queryParams
|
|
55
|
+
}) {
|
|
56
|
+
return index.get(`/projects/${pathParams.uuid}/images/findings/security`, {
|
|
57
|
+
params: {
|
|
58
|
+
...queryParams
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
exports.MendDataService = MendDataService;
|
|
65
|
+
//# sourceMappingURL=data.service.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.service.cjs.js","sources":["../../src/service/data.service.ts"],"sourcesContent":["import { get, post } from '../api';\nimport { MendAuthSevice } from './auth.service';\nimport {\n GetOrganizationProjectRequestData,\n GetProjectStatisticsRequestData,\n GetCodeFindingsRequestData,\n GetDependenciesFindingsRequestData,\n GetContainersFindingsRequestData,\n GetOrganizationProjectSuccessResponseData,\n GetProjectStatisticsSuccessResponseData,\n GetCodeFindingSuccessResponseData,\n GetDependenciesFindingSuccessResponseData,\n GetContainersFindingSuccessResponseData,\n} from './data.service.types';\n\nexport class MendDataService extends MendAuthSevice {\n async getOrganizationProject({\n queryParams,\n }: GetOrganizationProjectRequestData): Promise<GetOrganizationProjectSuccessResponseData> {\n return get(`/orgs/${MendAuthSevice.getOrganizationUuid()}/projects`, {\n params: {\n ...queryParams,\n },\n });\n }\n\n async getProjectStatistics({\n queryParams,\n bodyParams,\n }: GetProjectStatisticsRequestData): Promise<GetProjectStatisticsSuccessResponseData> {\n return post(\n `/orgs/${MendAuthSevice.getOrganizationUuid()}/projects/summaries`,\n {\n params: {\n ...queryParams,\n },\n body: {\n ...bodyParams,\n },\n },\n );\n }\n\n async getCodeFinding({\n pathParams,\n queryParams,\n }: GetCodeFindingsRequestData): Promise<GetCodeFindingSuccessResponseData> {\n return get(`/projects/${pathParams.uuid}/code/findings`, {\n params: {\n ...queryParams,\n },\n });\n }\n\n async getDependenciesFinding({\n pathParams,\n queryParams,\n }: GetDependenciesFindingsRequestData): Promise<GetDependenciesFindingSuccessResponseData> {\n return get(`/projects/${pathParams.uuid}/dependencies/findings/security`, {\n params: {\n ...queryParams,\n },\n });\n }\n\n async getContainersFinding({\n pathParams,\n queryParams,\n }: GetContainersFindingsRequestData): Promise<GetContainersFindingSuccessResponseData> {\n return get(`/projects/${pathParams.uuid}/images/findings/security`, {\n params: {\n ...queryParams,\n },\n });\n }\n}\n"],"names":["MendAuthSevice","get","post"],"mappings":";;;;;AAeO,MAAM,wBAAwBA,2BAAe,CAAA;AAAA,EAClD,MAAM,sBAAuB,CAAA;AAAA,IAC3B;AAAA,GACwF,EAAA;AACxF,IAAA,OAAOC,SAAI,CAAA,CAAA,MAAA,EAASD,2BAAe,CAAA,mBAAA,EAAqB,CAAa,SAAA,CAAA,EAAA;AAAA,MACnE,MAAQ,EAAA;AAAA,QACN,GAAG;AAAA;AACL,KACD,CAAA;AAAA;AACH,EAEA,MAAM,oBAAqB,CAAA;AAAA,IACzB,WAAA;AAAA,IACA;AAAA,GACoF,EAAA;AACpF,IAAO,OAAAE,UAAA;AAAA,MACL,CAAA,MAAA,EAASF,2BAAe,CAAA,mBAAA,EAAqB,CAAA,mBAAA,CAAA;AAAA,MAC7C;AAAA,QACE,MAAQ,EAAA;AAAA,UACN,GAAG;AAAA,SACL;AAAA,QACA,IAAM,EAAA;AAAA,UACJ,GAAG;AAAA;AACL;AACF,KACF;AAAA;AACF,EAEA,MAAM,cAAe,CAAA;AAAA,IACnB,UAAA;AAAA,IACA;AAAA,GACyE,EAAA;AACzE,IAAA,OAAOC,SAAI,CAAA,CAAA,UAAA,EAAa,UAAW,CAAA,IAAI,CAAkB,cAAA,CAAA,EAAA;AAAA,MACvD,MAAQ,EAAA;AAAA,QACN,GAAG;AAAA;AACL,KACD,CAAA;AAAA;AACH,EAEA,MAAM,sBAAuB,CAAA;AAAA,IAC3B,UAAA;AAAA,IACA;AAAA,GACyF,EAAA;AACzF,IAAA,OAAOA,SAAI,CAAA,CAAA,UAAA,EAAa,UAAW,CAAA,IAAI,CAAmC,+BAAA,CAAA,EAAA;AAAA,MACxE,MAAQ,EAAA;AAAA,QACN,GAAG;AAAA;AACL,KACD,CAAA;AAAA;AACH,EAEA,MAAM,oBAAqB,CAAA;AAAA,IACzB,UAAA;AAAA,IACA;AAAA,GACqF,EAAA;AACrF,IAAA,OAAOA,SAAI,CAAA,CAAA,UAAA,EAAa,UAAW,CAAA,IAAI,CAA6B,yBAAA,CAAA,EAAA;AAAA,MAClE,MAAQ,EAAA;AAAA,QACN,GAAG;AAAA;AACL,KACD,CAAA;AAAA;AAEL;;;;"}
|