Skip to content

Commit 1ae3c99

Browse files
committed
report: move rendering to html-template, consolidate logic, and add project name to default writeout
1 parent 8d5a6ec commit 1ae3c99

2 files changed

Lines changed: 168 additions & 163 deletions

File tree

lib/report/html-template.js

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
'use strict'
2+
3+
const {
4+
COLORS
5+
} = require('../ncm-style')
6+
const {
7+
filterVulns,
8+
SEVERITY_RMAP
9+
} = require('./util')
10+
11+
module.exports = renderHTML
12+
13+
function renderHTML (title, summary, report, whitelist) {
14+
const { riskCount, securityCount, insecureModules, complianceCount } = summary
15+
16+
let alternate = false
17+
let whitelistInfo = ''
18+
for (const pkg of whitelist) {
19+
whitelistInfo += segment(pkg)
20+
}
21+
22+
let pkgInfo = ''
23+
for (const pkg of report) {
24+
pkgInfo += segment(pkg)
25+
}
26+
27+
function segment (pkg) {
28+
const { name, version, maxSeverity, failures, license } = pkg
29+
const pkgVulns = filterVulns(failures).map((v, i) => v === 0
30+
? ''
31+
: `<div style="color:${['#89a19d', '#ffb726', '#ff8b40', '#ff6040'][i]}">${v} ${['Low', 'Medium', 'High', 'Critical'][i]}</div>`)
32+
const pkgLicense = license && license.data && license.data.spdx ? license.data.spdx : 'UNKNOWN'
33+
const pkgLicensePass = license && license.pass === true
34+
const pkgSeverity = SEVERITY_RMAP[maxSeverity]
35+
36+
alternate = !alternate
37+
return `
38+
<tr class="module-element" ${alternate ? 'style="background:#2e3535"' : ''}>
39+
<td>
40+
<div id="name" style="display:inline-block;color:#e1e7e6;">${name}</div>@${version}
41+
</td>
42+
<td>
43+
${pkgSeverity}
44+
</div>
45+
<td>
46+
<div style="display:inline-block;color:${pkgLicensePass ? '#5ac878">✓' : '#ff6040">X'}</div> ${pkgLicense}
47+
</td>
48+
<td>
49+
${pkgVulns.join('').length === 0 ? 'None' : pkgVulns.reverse().join(' ')}
50+
</td>
51+
</tr>
52+
`
53+
}
54+
55+
const template = `
56+
<!DOCTYPE html>
57+
<html>
58+
<head>
59+
<title>NCM Report > ${title}</title>
60+
<style type="text/css">
61+
body {
62+
padding: 2%;
63+
color: ${COLORS.light1.match(/(#[a-zA-Z0-9]*)/)[0]};
64+
vertical-align: top;
65+
font-weight: 100;
66+
}
67+
a {
68+
color: #5ac878;
69+
text-decoration: none;
70+
}
71+
td {
72+
padding-left: 10px;
73+
padding-right: 10px;
74+
}
75+
table {
76+
width: 100%;
77+
}
78+
.title {
79+
font-size: 28pt;
80+
font-weight: 100;
81+
}
82+
.sub-title {
83+
font-size: 20pt;
84+
font-weight: 100;
85+
color: #e1e7e6;
86+
}
87+
.module-element {
88+
margin: 4px;
89+
}
90+
</style>
91+
</head>
92+
<body style="background: #202525">
93+
94+
<div style="margin-bottom:20px;position">
95+
<svg xmlns="http://www.w3.org/2000/svg" height="50" width="auto" viewBox="0 0 100 100" style="display:inline-block;">
96+
<path d="M89.243 20.864L55.642 1.5a11.21 11.21 0 0 0-11.2 0L10.778 20.937a11.208 11.208 0 0 0-5.6 9.7l-.032 38.781a11.2 11.2 0 0 0 5.611 9.718L44.359 98.5a11.208 11.208 0 0 0 11.2 0l33.663-19.437a11.206 11.206 0 0 0 5.6-9.7l.028-38.784a11.2 11.2 0 0 0-5.607-9.715zM46.36 4.823a7.338 7.338 0 0 1 1.723-.718v16.552a1.917 1.917 0 0 0 3.834 0V4.079a7.369 7.369 0 0 1 1.81.741l33.6 19.366a7.322 7.322 0 0 1 1.522 1.169L68.486 37.113a22.518 22.518 0 0 0-36.983.014L11.186 25.418a7.329 7.329 0 0 1 1.51-1.16zM68.713 50a18.74 18.74 0 0 1-16.8 18.616V51.107l15.149-8.746A18.579 18.579 0 0 1 68.713 50zm-35.785-7.626l15.155 8.734v17.508a18.679 18.679 0 0 1-15.155-26.242zM50 47.786l-15.149-8.729a18.651 18.651 0 0 1 30.288-.012zM12.672 75.813a7.284 7.284 0 0 1-1.522-1.168l13.117-7.574a1.918 1.918 0 0 0-1.918-3.321L9.232 71.323a7.316 7.316 0 0 1-.251-1.9l.029-38.786a7.274 7.274 0 0 1 .254-1.9l20.318 11.71a22.53 22.53 0 0 0 18.5 32.015v22.945a1.9 1.9 0 0 0 .083.53 7.351 7.351 0 0 1-1.892-.757zm40.969 19.364a7.362 7.362 0 0 1-1.8.741 1.919 1.919 0 0 0 .077-.511V72.461A22.533 22.533 0 0 0 70.411 40.43l20.357-11.754a7.329 7.329 0 0 1 .251 1.9l-.028 38.784a7.33 7.33 0 0 1-.264 1.937L77.651 63.75a1.918 1.918 0 0 0-1.918 3.321l13.053 7.536a7.3 7.3 0 0 1-1.481 1.135z" fill="#89a19d"></path>
97+
</svg>
98+
<svg height="30" width="auto" viewBox="0 0 346.17 33.7" style="display:inline-block;fill:#fff;">
99+
<path d="M24.54,33.07a1.88,1.88,0,0,1-1.47-.71L3.75,7.9V31.2A1.88,1.88,0,1,1,0,31.2V2.5A1.88,1.88,0,0,1,3.35,1.34L22.67,25.8V2.5a1.88,1.88,0,0,1,3.75,0V31.2a1.88,1.88,0,0,1-1.87,1.88Z"></path><path d="M48.92,33.7c-8.81,0-16-7.56-16-16.85S40.11,0,48.92,0s16,7.56,16,16.85S57.72,33.7,48.92,33.7Zm0-29.95c-6.74,0-12.22,5.88-12.22,13.1s5.48,13.1,12.22,13.1,12.22-5.88,12.22-13.1S55.66,3.75,48.92,3.75Z"></path><path d="M177.24,33.7c-8.81,0-16-7.56-16-16.85S168.43,0,177.24,0s16,7.56,16,16.85S186,33.7,177.24,33.7Zm0-29.95C170.5,3.75,165,9.63,165,16.85s5.48,13.1,12.22,13.1,12.22-5.88,12.22-13.1S184,3.75,177.24,3.75Z"></path><path d="M234.8,33.07a1.88,1.88,0,0,1-1.87-1.88V2.5A1.88,1.88,0,0,1,234.8.62h13.31c5.67,0,9.78,3.79,9.78,9s-4.11,9-9.78,9H236.67V31.2A1.88,1.88,0,0,1,234.8,33.07Zm1.88-18.18h11.43c3.55,0,6-2.16,6-5.26s-2.48-5.26-6-5.26H236.67Z"></path><path d="M212.47,33.7A13.51,13.51,0,0,1,199.16,20V2.5a1.88,1.88,0,0,1,3.75,0V20A9.57,9.57,0,1,0,222,20V2.5a1.88,1.88,0,0,1,3.75,0V20A13.51,13.51,0,0,1,212.47,33.7Z"></path><path d="M152.72,6.59l-.18-.12c-.12-.08-.31-.21-.51-.33a18.63,18.63,0,0,0-1.91-1A14.31,14.31,0,0,0,147,4a13,13,0,0,0-4.25-.17,8.14,8.14,0,0,0-4.29,1.67A4.4,4.4,0,0,0,136.9,9.7a3.81,3.81,0,0,0,.3,1,3.68,3.68,0,0,0,.61,1A6.93,6.93,0,0,0,140,13.22a17.68,17.68,0,0,0,3,1c.54.14,1.09.26,1.64.37s1.15.23,1.82.41a22.48,22.48,0,0,1,3.7,1.25,13.74,13.74,0,0,1,3.49,2.14,8.41,8.41,0,0,1,2.52,3.66c.11.36.2.74.28,1.11s.09.75.1,1.12v.89l0,.17,0,.1-.06.42,0,.21-.07.29a8.86,8.86,0,0,1-5.21,6,15.75,15.75,0,0,1-6.39,1.31,12.44,12.44,0,0,1-1.47-.07,14.11,14.11,0,0,1-1.46-.22,17.07,17.07,0,0,1-2.49-.72,20.61,20.61,0,0,1-3.68-1.84,21.46,21.46,0,0,1-2.13-1.54c-.47-.39-.72-.62-.72-.62l0,0a1.69,1.69,0,0,1,2.26-2.5s.2.17.61.47a19.79,19.79,0,0,0,1.86,1.2,17.77,17.77,0,0,0,3.1,1.43,13.37,13.37,0,0,0,2,.54c.35.06.71.12,1,.14a10.25,10.25,0,0,0,1.15,0,12.07,12.07,0,0,0,4.86-1,6.41,6.41,0,0,0,2-1.38,3.17,3.17,0,0,0,.38-.45,2.58,2.58,0,0,0,.31-.48,4.25,4.25,0,0,0-1.06-5.41,14,14,0,0,0-5.61-2.57c-.48-.14-1.17-.26-1.67-.38s-1.23-.26-1.84-.42a21.32,21.32,0,0,1-3.68-1.27A10.58,10.58,0,0,1,135,14.17,7.53,7.53,0,0,1,133.17,10a3.77,3.77,0,0,1,0-.48l0-.42v-.6l0-.53c0-.35.11-.7.18-1s.19-.68.32-1A8.25,8.25,0,0,1,136,2.67a11.8,11.8,0,0,1,6.3-2.54,15.79,15.79,0,0,1,5.47.29,16.09,16.09,0,0,1,3.94,1.48A17.75,17.75,0,0,1,154,3.31l.71.53a1.69,1.69,0,0,1-2,2.75Z"></path><path d="M79.8,33.07H73.15a1.88,1.88,0,0,1-1.87-1.88V2.5A1.88,1.88,0,0,1,73.15.62H79.8c12.62,0,18.27,8.15,18.27,16.22C98.07,27.16,91.41,33.07,79.8,33.07ZM75,29.32H79.8c12,0,14.52-6.78,14.52-12.47,0-7.58-5.7-12.47-14.52-12.47H75Z"></path><path d="M125.54,33.07H106.37a1.88,1.88,0,0,1-1.87-1.88V2.5A1.88,1.88,0,0,1,106.37.62h19.17a1.87,1.87,0,1,1,0,3.75H108.24V29.32h17.29a1.88,1.88,0,0,1,0,3.75Z"></path><path d="M120.39,18.66h-14a1.88,1.88,0,0,1,0-3.75h14a1.87,1.87,0,0,1,0,3.75Z"></path><path d="M319.58,33.07H300.41a1.88,1.88,0,0,1-1.87-1.88V2.5A1.88,1.88,0,0,1,300.41.62h19.17a1.87,1.87,0,1,1,0,3.75H302.29V29.32h17.29a1.88,1.88,0,0,1,0,3.75Z"></path><path d="M314.44,18.66H300.8a1.88,1.88,0,0,1,0-3.75h13.63a1.88,1.88,0,0,1,0,3.75Z"></path><path d="M256.16,33.07a1.87,1.87,0,0,1-1.53-.79L244.5,17.93a1.88,1.88,0,0,1,3.06-2.16l10.13,14.35a1.88,1.88,0,0,1-1.53,3Z"></path><path d="M291.05,28.93l-.58.55a17.13,17.13,0,0,1-2,1.54,16.17,16.17,0,0,1-8.36,2.66h-.78l-.63,0a10.23,10.23,0,0,1-1.39-.13,16.51,16.51,0,0,1-3.05-.7,16.71,16.71,0,0,1-5.73-3.27,16.91,16.91,0,0,1-5.82-12.72l0-.91c0-.28,0-.53.05-.84.1-.63.17-1.3.31-1.9a16.8,16.8,0,0,1,1.18-3.45,17,17,0,0,1,4.24-5.62A16.71,16.71,0,0,1,274.28.86,17.45,17.45,0,0,1,280.12,0a16.27,16.27,0,0,1,8.38,2.66,17.06,17.06,0,0,1,2,1.52l.63.6a1.69,1.69,0,0,1-2.24,2.51l-.09-.07-.53-.45a14,14,0,0,0-1.61-1.11A13.58,13.58,0,0,0,280,3.76a14,14,0,0,0-4.57.66A13,13,0,0,0,271,7a13.24,13.24,0,0,0-3.3,4.37A13,13,0,0,0,266.8,14c-.11.46-.14.88-.23,1.32,0,.23,0,.53-.05.8l0,.72A13.16,13.16,0,0,0,271,26.74a12.9,12.9,0,0,0,6.71,3.06,7.27,7.27,0,0,0,1.19.11l.63,0H280A13.5,13.5,0,0,0,286.61,28a14.42,14.42,0,0,0,1.59-1.09l.59-.5h0a1.69,1.69,0,0,1,2.26,2.51Z"></path><path d="M337.88.2a8.29,8.29,0,1,0,8.29,8.29A8.3,8.3,0,0,0,337.88.2Zm0,15.12a6.83,6.83,0,1,1,6.83-6.83A6.84,6.84,0,0,1,337.88,15.32Z"></path><path d="M335.87,12.12a.61.61,0,0,1-.61-.61v-6a.61.61,0,0,1,.61-.61h2.81a2.12,2.12,0,1,1,0,4.23h-2.2v2.43A.61.61,0,0,1,335.87,12.12Zm.61-4.26h2.2a.91.91,0,1,0,0-1.79h-2.2Z"></path><path d="M340.38,12.12a.61.61,0,0,1-.5-.26l-2.13-3a.61.61,0,0,1,1-.7l2.13,3a.61.61,0,0,1-.5,1Z"></path>
100+
</svg>
101+
</div>
102+
103+
<div style="margin-bottom:20px;">
104+
<div style="display:inline-block;color:#e1e7e6;" class="title">NCM Project Report</div>
105+
<div style="display:inline-block;" class="title">&nbsp;>&nbsp;</div>
106+
<div style="display:inline-block;color:#e1e7e6;" class="title">${title}</div>
107+
<div style="margin-left:20px;"><b style="color:#5ac878;">></b> Powered by <a href="https://docs.nodesource.com/ncmv2/docs">NodeSource Certified Modules v2</a></div>
108+
</div>
109+
110+
<div style="margin-bottom:20px;margin-left:20px;">
111+
<div class="sub-title">Summary</div>
112+
<div style=""><b style="color:#e1e7e6;">${report.length}</b> packages checked</div>
113+
<br>
114+
<div style="color:${COLORS.red.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[4]}</b> Critical Risk</div>
115+
<div style="color:${COLORS.orange.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[3]}</b> High Risk</div>
116+
<div style="color:${COLORS.yellow.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[2]}</b> Medium Risk</div>
117+
<div style="color:${COLORS.light1.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[1]}</b> Low Risk</div>
118+
<br>
119+
<div><b style="color:#e1e7e6;">${securityCount}</b> security vulnerabilities found ${securityCount > 0 ? `across <b style="color:#e1e7e6;">${insecureModules}</b> modules` : ''}</div>
120+
<div><b style="color:#e1e7e6;">${complianceCount}</b> noncompliant modules found</div>
121+
${(whitelist.length > 0 ? `<div><b style="color:#e1e7e6;">${whitelist.length}</b> used modules whitelisted </div>` : '')}
122+
</div>
123+
124+
${(whitelist.length > 0 ? `
125+
<div class="sub-title">Whitelisted Modules</div>
126+
<hr>
127+
<table style="margin-bottom:20px;">
128+
<tr style="margin-bottom:5px;">
129+
<th>Module Name</th>
130+
<th>Risk</th>
131+
<th>License</th>
132+
<th>Security</th>
133+
</tr>
134+
${whitelistInfo}
135+
</table>
136+
` : '')}
137+
138+
<div class="sub-title">${whitelist.length > 0 ? 'Non-Whitelisted ' : ''}Modules</div>
139+
<hr>
140+
<table id="module-table" style="margin-bottom:20px;">
141+
<tr style="margin-bottom:5px;">
142+
<th onclick="sortTable(0, 'module-table')">Module Name</th>
143+
<th>Risk</th>
144+
<th>License</th>
145+
<th>Security</th>
146+
</tr>
147+
${pkgInfo}
148+
</table>
149+
</body>
150+
</html>
151+
`
152+
153+
return template
154+
}

lib/report/html.js

Lines changed: 14 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -4,162 +4,33 @@ const path = require('path')
44
const { promisify } = require('util')
55
const writeFile = promisify(require('fs').writeFile)
66
const {
7-
summaryInfo,
8-
filterVulns,
9-
SEVERITY_RMAP
10-
} = require('./util')
11-
const {
12-
COLORS,
137
success,
148
formatError
159
} = require('../ncm-style')
10+
const {
11+
summaryInfo
12+
} = require('./util')
13+
const renderTemplate = require('./html-template')
1614
const L = console.log
1715

1816
module.exports = htmlReport
1917

2018
async function htmlReport (report, whitelist, dir, output) {
21-
if (output === true) output = path.join(process.cwd(), `ncm-report-${Date.now()}.html`)
22-
23-
const { riskCount, insecureModules, complianceCount, securityCount } = summaryInfo(report)
24-
25-
/* Define embedded CSS report styles */
26-
const reportStyles = `
27-
body {
28-
background: ${COLORS.base.match(/(#[a-zA-Z0-9]*)/)[0]};
29-
padding: 10px;
30-
}
31-
p {
32-
color: white;
33-
}
34-
.summary {
35-
text-align: left;
36-
font-size: 14pt;
37-
color: #ffffff;
38-
}
39-
.module-list {
40-
41-
}
42-
.module-element {
43-
padding: 0px;
44-
margin: 0px;
45-
font-size: 10pt;
46-
}
47-
`
19+
const title = `${path.basename(dir) || 'NCM'}`
20+
const summary = summaryInfo(report) // { riskCount, insecureModules, complianceCount, securityCount }
4821

49-
/* Begin body with report summary */
50-
let reportBody = `
51-
<h1 class="">${path.basename(dir) || 'NCM'} Report</h1>
52-
<h6>Powered by <a href="https://docs.nodesource.com/ncmv2/docs">Node Certified Modules v2</a></h6>
53-
<div class="summary">
54-
<div style=""><b>${report.length}</b> packages checked</div>
55-
<br>
56-
<div style="color:${COLORS.red.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[4]}</b> Critical Risk</div>
57-
<div style="color:${COLORS.orange.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[3]}</b> High Risk</div>
58-
<div style="color:${COLORS.yellow.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[2]}</b> Medium Risk</div>
59-
<div style="color:${COLORS.light1.match(/(#[a-zA-Z0-9]*)/)[0]}"><b>${riskCount[1]}</b> Low Risk</div>
60-
<br>
61-
<div><b>${securityCount}</b> security vulnerabilities found across <b>${insecureModules}</b> modules</div>
62-
<div><b>${complianceCount}</b> noncompliant modules found</div>
63-
${(whitelist.length > 0 ? `<div><b>${whitelist.length}</b> used modules whitelisted </div>` : '')}
64-
</div>
65-
`
22+
const htmlData = renderTemplate(
23+
title,
24+
summary,
25+
report,
26+
whitelist
27+
)
6628

67-
/* Whitelisted Modules */
68-
reportBody += `
69-
<a data-toggle="collapse" href="#collapseWL" data-target="#collapseWL">
70-
<h2>Whitelisted Modules</h2>
71-
</a>
72-
<div class="module-list collapse" id="collapseWL">`
73-
for (const pkg of whitelist) {
74-
reportBody += formatSegment(pkg)
75-
}
76-
reportBody += '</div>'
77-
78-
/* Non-whitelisted Modules */
79-
reportBody += `
80-
<h2>Non-whitelisted Modules</h2>
81-
<div class="module-list">`
82-
83-
/* Critical risk */
84-
reportBody += `
85-
<a data-toggle="collapse" href="#collapseCritRisk" data-target="#collapseCritRisk">
86-
<h4>Critical Risk Modules</h4>
87-
</a>
88-
<div class="module-list collapse" id="collapseCritRisk">`
89-
for (const pkg of report.filter(pkg => pkg.maxSeverity === 4)) {
90-
reportBody += formatSegment(pkg)
91-
}
92-
reportBody += '</div>'
93-
94-
/* High risk */
95-
reportBody += `
96-
<a data-toggle="collapse" href="#collapseHighRisk" data-target="#collapseHighRisk">
97-
<h4>High Risk Modules</h4>
98-
</a>
99-
<div class="module-list collapse" id="collapseHighRisk">`
100-
for (const pkg of report.filter(pkg => pkg.maxSeverity === 3)) {
101-
reportBody += formatSegment(pkg)
102-
}
103-
reportBody += '</div>'
104-
105-
/* Medium risk */
106-
reportBody += `
107-
<a data-toggle="collapse" href="#collapseMedRisk" data-target="#collapseMedRisk">
108-
<h4>Medium Risk Modules</h4>
109-
</a>
110-
<div class="module-list collapse" id="collapseMedRisk">`
111-
for (const pkg of report.filter(pkg => pkg.maxSeverity === 2)) {
112-
reportBody += formatSegment(pkg)
113-
}
114-
reportBody += '</div>'
115-
116-
/* Low risk */
117-
reportBody += `
118-
<a data-toggle="collapse" href="#collapseLowRisk" data-target="#collapseLowRisk">
119-
<h4>Low Risk Modules</h4>
120-
</a>
121-
<div class="module-list collapse" id="collapseLowRisk">`
122-
for (const pkg of report.filter(pkg => pkg.maxSeverity === 1)) {
123-
reportBody += formatSegment(pkg)
124-
}
125-
reportBody += '</div>'
126-
127-
/* None risk */
128-
reportBody += `
129-
<a data-toggle="collapse" href="#collapseNoneRisk" data-target="#collapseNoneRisk">
130-
<h4>No Risk Modules</h4>
131-
</a>
132-
<div class="module-list collapse" id="collapseNoneRisk">`
133-
for (const pkg of report.filter(pkg => pkg.maxSeverity === 0)) {
134-
reportBody += formatSegment(pkg)
135-
}
136-
reportBody += '</div>'
137-
138-
reportBody += '</div>'
139-
140-
/* Format final HTML report */
141-
const html = `
142-
<!DOCTYPE html>
143-
<html>
144-
<head>
145-
<title>${path.basename(dir) || 'NCM'} Report</title>
146-
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
147-
<style type="text/css">
148-
${reportStyles}
149-
</style>
150-
</head>
151-
<body>
152-
${reportBody}
153-
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
154-
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
155-
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
156-
</body>
157-
</html>
158-
`
29+
if (output === true) output = path.join(process.cwd(), `${title.toLowerCase()}-report-${Date.now()}.html`)
15930

16031
/* Write report to file */
16132
try {
162-
await writeFile(output, html)
33+
await writeFile(output, htmlData)
16334
L()
16435
L(success(`Wrote HTML report to: ${output}`))
16536
L()
@@ -170,23 +41,3 @@ async function htmlReport (report, whitelist, dir, output) {
17041
process.exitCode = 1
17142
}
17243
}
173-
174-
function formatSegment (pkg) {
175-
const { name, version, maxSeverity, failures, license } = pkg
176-
const pkgVulns = filterVulns(failures).map(v => v === 0 ? '' : `${v} ${['Critical', 'High', 'Medium', 'Low'][v]}`)
177-
const pkgLicense = license && license.data && license.data.spdx ? license.data.spdx : 'UNKNOWN'
178-
const pkgSeverity = SEVERITY_RMAP[maxSeverity]
179-
180-
const segment = `
181-
<div class="row module-element">
182-
<div class="col-4" style="display:inline-block;">${name}@${version}</div>
183-
<div class="col-2" style="display:inline-block;">Risk: ${pkgSeverity}</div>
184-
<div class="col-3" style="display:inline-block;">License: ${pkgLicense}</div>
185-
<div class="col-3" style="display:inline-block;">
186-
Vulnerabilities: ${pkgVulns.join('').length === 0 ? 'None' : pkgVulns.join(' ')}
187-
</div>
188-
</div>
189-
`
190-
191-
return segment
192-
}

0 commit comments

Comments
 (0)