snyk-to-html
Advanced tools
Comparing version 1.12.0 to 1.13.0
@@ -23,7 +23,17 @@ #!/usr/bin/env node | ||
if (typeof template === 'boolean') { | ||
template = path.join(__dirname, '../template/test-report.hbs'); | ||
if (program.actionableRemediation) { | ||
template = path.join(__dirname, '../template/remediation-report.hbs'); | ||
} | ||
else { | ||
template = path.join(__dirname, '../template/test-report.hbs'); | ||
} | ||
} | ||
} | ||
else { | ||
template = path.join(__dirname, '../template/test-report.hbs'); | ||
if (program.actionableRemediation) { | ||
template = path.join(__dirname, '../template/remediation-report.hbs'); | ||
} | ||
else { | ||
template = path.join(__dirname, '../template/test-report.hbs'); | ||
} | ||
} | ||
@@ -30,0 +40,0 @@ if (program.input) { // input source |
@@ -106,10 +106,18 @@ #!/usr/bin/env node | ||
} | ||
async function generateTemplate(data, template, remediation, summary) { | ||
if (remediation && data.remediation) { | ||
data.showRemediations = remediation; | ||
data.unresolved = groupVulns(data.remediation.unresolved); | ||
data.upgrades = vuln_1.getUpgrades(data.remediation.upgrade, data.vulnerabilities); | ||
async function generateTemplate(data, template, showRemediation, summary) { | ||
var _a; | ||
if (showRemediation && data.remediation) { | ||
data.showRemediations = showRemediation; | ||
const { upgrade, pin, unresolved, patch } = data.remediation; | ||
data.anyRemediations = !_.isEmpty(upgrade) || | ||
!_.isEmpty(patch) || !_.isEmpty(pin); | ||
data.anyUnresolved = !!((_a = unresolved) === null || _a === void 0 ? void 0 : _a.vulnerabilities); | ||
data.unresolved = groupVulns(unresolved); | ||
data.upgrades = vuln_1.getUpgrades(upgrade, data.vulnerabilities); | ||
data.pins = vuln_1.getUpgrades(pin, data.vulnerabilities); | ||
data.patches = vuln_1.addIssueDataToPatch(patch, data.vulnerabilities); | ||
} | ||
const vulnMetadata = groupVulns(data.vulnerabilities); | ||
const sortedVulns = _.orderBy(vulnMetadata.vulnerabilities, ['metadata.severityValue', 'metadata.name'], ['desc', 'desc']); | ||
data.hasMetatableData = !!data.projectName || !!data.path || !!data.displayTargetFile; | ||
data.vulnerabilities = sortedVulns; | ||
@@ -123,5 +131,6 @@ data.uniqueCount = vulnMetadata.vulnerabilitiesUniqueCount; | ||
await registerPeerPartial(template, 'metatable'); | ||
await registerPeerPartial(template, 'inline-js'); | ||
await registerPeerPartial(template, 'vuln-card'); | ||
await registerPeerPartial(template, 'remediation-css'); | ||
await registerPeerPartial(template, 'actionable-remediations'); | ||
await registerPeerPartial(template, 'remediation-card'); | ||
const htmlTemplate = await compileTemplate(template); | ||
@@ -195,3 +204,3 @@ return htmlTemplate(data); | ||
}, | ||
getRemediation: function (description, fixedIn) { | ||
getRemediation: (description, fixedIn) => { | ||
// check remediation in the description | ||
@@ -210,4 +219,7 @@ const index = description.indexOf('## Remediation'); | ||
}, | ||
severityLabel: (severity) => { | ||
return severity[0].toUpperCase(); | ||
}, | ||
}; | ||
Object.keys(hh).forEach(k => Handlebars.registerHelper(k, hh[k])); | ||
//# sourceMappingURL=snyk-to-html.js.map |
@@ -1,2 +0,2 @@ | ||
export interface ActionableRemediation { | ||
export interface UpgradeRemediation { | ||
upgradeFrom: string; | ||
@@ -6,3 +6,11 @@ upgradeTo: string; | ||
severityScore: number; | ||
isTransitive?: boolean; | ||
} | ||
export interface PatchRemediation { | ||
paths: object[]; | ||
issueData: Vuln; | ||
name: string; | ||
version: string; | ||
severityScore: number; | ||
} | ||
export interface Vuln { | ||
@@ -9,0 +17,0 @@ id: string; |
@@ -1,2 +0,2 @@ | ||
import { ActionableRemediation, Vuln } from './types'; | ||
import { UpgradeRemediation, Vuln } from './types'; | ||
export declare const severityMap: { | ||
@@ -8,2 +8,3 @@ low: number; | ||
export declare function getSeverityScore(vulns: Vuln[]): number; | ||
export declare function getUpgrades(upgrade: any, vulnerabilities: any): ActionableRemediation[]; | ||
export declare function getUpgrades(upgrade: any, vulnerabilities: any): UpgradeRemediation[]; | ||
export declare function addIssueDataToPatch(remediation: any, vulnerabilities: any): any; |
@@ -20,3 +20,3 @@ "use strict"; | ||
Object.keys(upgrade).forEach((key) => { | ||
const { upgradeTo, vulns: vulnIds } = upgrade[key]; | ||
const { upgradeTo, vulns: vulnIds, isTransitive } = upgrade[key]; | ||
const vulns = vulnIds.map((id) => getVuln(id, vulnerabilities)); | ||
@@ -26,5 +26,8 @@ const actionableRemediation = { | ||
upgradeTo, | ||
vulns, | ||
severityScore: getSeverityScore(vulns), | ||
vulns, | ||
}; | ||
if (isTransitive) { | ||
actionableRemediation.isTransitive = isTransitive; | ||
} | ||
result.push(actionableRemediation); | ||
@@ -36,2 +39,23 @@ }); | ||
exports.getUpgrades = getUpgrades; | ||
function addIssueDataToPatch(remediation, vulnerabilities) { | ||
const patches = []; | ||
Object.entries(remediation).forEach(([pkg, pkgData]) => { | ||
const vuln = vulnerabilities.find((v) => v.id === pkg); | ||
const issueData = { | ||
severity: vuln.severity, | ||
title: vuln.title, | ||
id: pkg, | ||
}; | ||
patches.push({ | ||
issueData, | ||
paths: pkgData.paths, | ||
name: vuln.packageName, | ||
version: vuln.version, | ||
severityScore: exports.severityMap[vuln.severity], | ||
}); | ||
}); | ||
const sortedPatches = _.orderBy(patches, 'severityScore', 'desc'); | ||
return sortedPatches; | ||
} | ||
exports.addIssueDataToPatch = addIssueDataToPatch; | ||
//# sourceMappingURL=vuln.js.map |
@@ -9,3 +9,3 @@ { | ||
"tap": "tap test/*.test.* -Rspec --timeout=180 --node-path ts-node --test-file-pattern '/\\.[tj]s$/'", | ||
"test": "npm run lint && npm run tap", | ||
"test": "npm run build && npm run lint && npm run tap", | ||
"lint": "tslint --project tsconfig.json --format stylish --exclude **/src/**/*.js", | ||
@@ -58,3 +58,3 @@ "report": "mkdir -p output && cat sample-data/test-report.json | node dist/. > output/test-report.html && open output/test-report.html", | ||
}, | ||
"version": "1.12.0" | ||
"version": "1.13.0" | ||
} |
[![Snyk logo](https://snyk.io/style/asset/logo/snyk-print.svg)](https://snyk.io) | ||
*** | ||
--- | ||
# Snyk JSON to HTML Mapper | ||
The Snyk JSON to HTML Mapper takes the json outputted from `snyk test --json` and creates a local HTML file displaying the vulnerabilities discovered. | ||
@@ -16,12 +17,21 @@ | ||
Alternatively, you can skip this step, clone the repo and run the script locally (using `node ./snyk-to-html.js`) | ||
Alternatively, you can clone the repo and run the script locally using: | ||
## Options of the CLI | ||
```javascript | ||
npm install | ||
npm run build | ||
node ./dist/index.js | ||
``` | ||
1. `-t` or `--template`- Template location for generating the html. Defaults to template/test-report.hbs | ||
2. `-i` or `--input` - Input path from where to read the json. Defaults to stdin | ||
3. `-o` or `--output` - Output of the resulting HTML. Example: -o snyk.html. Defaults to stdout | ||
4. `-s` or `--summary` - Generates an HTML with only the summary, instead of the details report. Defaults to details vulnerability report | ||
5. `-d` or `--debug` - Runs the CLI in debug mode | ||
## Options | ||
| Short | Long | Description | | ||
| ----- | -------------------------- | ---------------------------------------------------------------------------------------------------------------- | | ||
| `-t` | `--template` | Template location for generating the html. Defaults to template/test-report.hbs | | ||
| `-i` | `--input` | Input path from where to read the json. Defaults to stdin | | ||
| `-o` | `--output` | Output of the resulting HTML. Example: -o snyk.html. Defaults to stdout | | ||
| `-s` | `--summary` | Generates an HTML with only the summary, instead of the details report. Defaults to details vulnerability report | | ||
| `-d` | `--debug` | Runs the CLI in debug mode | | ||
| `-a` | `--actionable-remediation` | Display actionable remediation info if available | | ||
When in doubt, use `snyk-to-html --help` or `snyk-to-html -h`. | ||
@@ -36,3 +46,3 @@ | ||
Run the following line to create a file called `results.html`: | ||
`snyk test --json | snyk-to-html -o results.html` | ||
@@ -50,12 +60,31 @@ | ||
3. By default, details about each vulnerability is shown. | ||
Note input files should be valid JSON and use UTF-8 encoding. | ||
If you want a simpler version of the report to be shown, you can pass `-s` or `--summary` to only | ||
display the summary of the report. | ||
3. If you want a simpler version of the report to be shown, you can pass `-s` or `--summary` to only | ||
display the summary of the report. | ||
`snyk-to-html -i results.json -o results.html -s` | ||
`snyk-to-html -i results.json -o results.html -s` | ||
4. Show actionable remediation: | ||
To display the actions you can take to remedy vulnerabilities, pass `-a` or `--actionable-remediation`. | ||
`snyk-to-html -i results.json -o results.html -a` | ||
The report orders remediations (upgrades and patches) by the number and severity of vulnerabilities it fixes. | ||
Use this to guide when selecting the order to upgrade and patch packages. | ||
Note we currently support remediation advice with the following package managers: | ||
* npm | ||
* yarn | ||
* rubygems | ||
* maven | ||
* gradle | ||
* sbt | ||
* pip | ||
## View the HTML report | ||
Simply open your new file (`results.html` above) in a browser, and rejoice. | ||
Simply open your new file (`results.html` above) in a browser, and rejoice. | ||
@@ -65,2 +94,1 @@ ### License | ||
[License: Apache License, Version 2.0](LICENSE) | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
71155
25
384
91