UNPKG

3.02 kBJavaScriptView Raw
1const fs = require('fs');
2const ejs = require('ejs');
3const marked = require('marked');
4const { promisify } = require('util');
5
6const bootstrapClassSeverityMap = {
7 critical: 'danger',
8 high: 'warning',
9 moderate: 'secondary',
10 low: 'primary',
11};
12const severitySortPriority = Object.keys(bootstrapClassSeverityMap);
13
14const generateTemplate = async (data, template) => {
15 try {
16 const readFile = promisify(fs.readFile);
17 const htmlTemplate = await readFile(template, 'utf8');
18
19 return ejs.render(htmlTemplate, {
20 ...data,
21 formatDate: (dateStr) => (new Date(dateStr)).toLocaleString(),
22 severityClass: (severity) => bootstrapClassSeverityMap[ severity ],
23 markdown: marked,
24 });
25 } catch (err) {
26 throw err;
27 }
28};
29
30const writeReport = async (report, output) => {
31 try {
32 const writeFile = promisify(fs.writeFile);
33 await writeFile(output, report);
34 } catch (err) {
35 throw err;
36 }
37};
38
39const modifyData = async (data, showUnique) => {
40 const auditAdvisories = data.filter((vulnerability) => vulnerability.type === 'auditAdvisory');
41 const reportDate = new Date();
42 const summaryData = data.pop().data;
43 const summary = {
44 ...summaryData,
45 vulnerabilities: Object.values(summaryData.vulnerabilities).reduce((sum, next) => (sum + next), 0),
46 };
47
48 let vulnerabilities = auditAdvisories.map((vulnerability) => ({
49 ...vulnerability.data.advisory,
50 paths: [vulnerability.data.resolution.path],
51 }));
52
53 if (showUnique) {
54 const vulnerabilitiesMap = {};
55
56 vulnerabilities.forEach((vulnerability) => {
57 vulnerability.findings.forEach((finding) => {
58 const key = `${vulnerability.module_name}@${finding.version}.${vulnerability.cwe}`;
59
60 if (!(key in vulnerabilitiesMap)) {
61 vulnerabilitiesMap[key] = {
62 ...vulnerability,
63 paths: finding.paths,
64 version: finding.version,
65 };
66 } else {
67 // Add reasons to the existing group list
68 vulnerabilitiesMap[key].paths = Array.from(
69 new Set(vulnerabilitiesMap[key].paths.concat(finding.paths))
70 );
71 }
72 });
73 });
74
75 vulnerabilities = Object.values(vulnerabilitiesMap);
76 }
77
78 vulnerabilities.sort((left, right) => (
79 severitySortPriority.indexOf(left.severity) - severitySortPriority.indexOf(right.severity))
80 );
81
82 return {
83 showUnique,
84 reportDate,
85 vulnerabilities,
86 summary,
87 };
88};
89
90module.exports = async (data, templateFile, outputFile, showUnique) => {
91 const modifiedData = await modifyData(data, showUnique);
92 const report = await generateTemplate(modifiedData, templateFile);
93
94 await writeReport(report, outputFile);
95 return modifiedData;
96};