diff --git a/src/lib/formatters/get-vuln-url.ts b/src/lib/formatters/get-vuln-url.ts new file mode 100644 index 0000000000..0bb1121402 --- /dev/null +++ b/src/lib/formatters/get-vuln-url.ts @@ -0,0 +1,9 @@ +import config from '../config'; + +const licenseRegex = /^snyk:lic/i; + +export function getVulnerabilityUrl(vulnerabilityId: string): string { + return licenseRegex.test(vulnerabilityId) + ? `${config.ROOT}/vuln/${vulnerabilityId}` + : `${config.PUBLIC_VULN_DB_URL}/vuln/${vulnerabilityId}`; +} diff --git a/src/lib/formatters/legacy-format-issue.ts b/src/lib/formatters/legacy-format-issue.ts index 5e4c75e630..7840fd445c 100644 --- a/src/lib/formatters/legacy-format-issue.ts +++ b/src/lib/formatters/legacy-format-issue.ts @@ -1,7 +1,6 @@ const uniq = require('lodash.uniq'); import chalk from 'chalk'; -import config from '../../lib/config'; import { Options, TestOptions, ShowVulnPaths } from '../../lib/types'; import { isLocalFolder } from '../../lib/detect'; import { parsePackageString as snykModule } from 'snyk-module'; @@ -18,6 +17,7 @@ import { import { formatLegalInstructions } from './legal-license-instructions'; import { colorTextBySeverity } from '../../lib/snyk-test/common'; import { PATH_SEPARATOR } from '../constants'; +import { getVulnerabilityUrl } from './get-vuln-url'; export function formatIssues( vuln: GroupedVuln, @@ -45,9 +45,7 @@ export function formatIssues( }), introducedThrough: ' Introduced through: ' + uniquePackages, description: ' Description: ' + vuln.title, - info: - ' Info: ' + - chalk.underline(config.PUBLIC_VULN_DB_URL + '/vuln/' + vulnID), + info: ' Info: ' + chalk.underline(getVulnerabilityUrl(vulnID)), fromPaths: createTruncatedVulnsPathsText(vuln.list, options.showVulnPaths), extraInfo: vuln.note ? chalk.bold('\n Note: ' + vuln.note) : '', remediationInfo: diff --git a/src/lib/formatters/remediation-based-format-issues.ts b/src/lib/formatters/remediation-based-format-issues.ts index 6873fcb121..b9042489d0 100644 --- a/src/lib/formatters/remediation-based-format-issues.ts +++ b/src/lib/formatters/remediation-based-format-issues.ts @@ -1,6 +1,5 @@ import chalk from 'chalk'; import { icon } from '../theme'; -import config from '../../lib/config'; import { TestOptions } from '../../lib/types'; import { DependencyPins, @@ -19,6 +18,7 @@ import { formatLegalInstructions } from './legal-license-instructions'; import { BasicVulnInfo, UpgradesByAffectedPackage } from './types'; import { PATH_SEPARATOR } from '../constants'; import { getSeverityValue } from './get-severity-value'; +import { getVulnerabilityUrl } from './get-vuln-url'; export function formatIssuesWithRemediation( vulns: GroupedVuln[], @@ -454,7 +454,7 @@ export function formatIssue( severity, )} Severity${originalSeverityStr}]`, ) + - `[${config.PUBLIC_VULN_DB_URL}/vuln/${id}]` + + `[${getVulnerabilityUrl(id)}]` + name + introducedBy + (legalLicenseInstructionsText diff --git a/src/lib/spotlight-vuln-notification.ts b/src/lib/spotlight-vuln-notification.ts index 37dd1cfca7..efba90acbd 100644 --- a/src/lib/spotlight-vuln-notification.ts +++ b/src/lib/spotlight-vuln-notification.ts @@ -2,6 +2,7 @@ import * as theme from './theme'; import * as createDebug from 'debug'; import { EOL } from 'os'; import config from './config'; +import { getVulnerabilityUrl } from './formatters/get-vuln-url'; const debug = createDebug('snyk-spotlight-vuln-notification'); @@ -42,7 +43,7 @@ export function notificationForSpotlightVulns( ); for (const vulnId of foundSpotlightVulnsIds) { - message += ` - ${vulnId} (See ${config.PUBLIC_VULN_DB_URL}/vuln/${vulnId})`; + message += ` - ${vulnId} (See ${getVulnerabilityUrl(vulnId)})`; } message += EOL + EOL; diff --git a/test/jest/unit/lib/formatters/get-vuln-url.spec.ts b/test/jest/unit/lib/formatters/get-vuln-url.spec.ts new file mode 100644 index 0000000000..efd3dc34ed --- /dev/null +++ b/test/jest/unit/lib/formatters/get-vuln-url.spec.ts @@ -0,0 +1,24 @@ +import { getVulnerabilityUrl } from '../../../../../src/lib/formatters/get-vuln-url'; +import config from '../../../../../src/lib/config'; + +describe('getVulnerabilityUrl', () => { + it('returns a valid license URL', () => { + expect(getVulnerabilityUrl('snyk:lic:pip:certifi:MPL-2.0')).toBe( + `${config.ROOT}/vuln/snyk:lic:pip:certifi:MPL-2.0`, + ); + }); + + it('returns a valid license URL - UPPERCASE', () => { + expect(getVulnerabilityUrl('SNYK:LIC:PIP:CERTIFI:MPL-2.0')).toBe( + `${config.ROOT}/vuln/SNYK:LIC:PIP:CERTIFI:MPL-2.0`, + ); + }); + + it('returns a valid vulnerability URL', () => { + expect( + getVulnerabilityUrl('SNYK-JS-LOOPBACKCONNECTORPOSTGRESQL-2980123'), + ).toBe( + `${config.PUBLIC_VULN_DB_URL}/vuln/SNYK-JS-LOOPBACKCONNECTORPOSTGRESQL-2980123`, + ); + }); +});