1'use strict' 2 3const report = function (data, options) { 4 const defaults = { 5 severityThreshold: 'info' 6 } 7 8 const config = Object.assign({}, defaults, options) 9 10 let exit = 0 11 12 const actions = function (data, config) { 13 let accumulator = { 14 critical: '', 15 high: '', 16 moderate: '', 17 low: '' 18 } 19 20 if (Object.keys(data.advisories).length !== 0) { 21 data.actions.forEach((action) => { 22 let l = {} 23 // Start with install/update actions 24 if (action.action === 'update' || action.action === 'install') { 25 const recommendation = getRecommendation(action, config) 26 l.recommendation = recommendation.cmd 27 l.breaking = recommendation.isBreaking ? 'Y' : 'N' 28 29 action.resolves.forEach((resolution) => { 30 const advisory = data.advisories[resolution.id] 31 32 l.sevLevel = advisory.severity 33 l.severity = advisory.title 34 l.package = advisory.module_name 35 l.moreInfo = advisory.url || `https://www.npmjs.com/advisories/${advisory.id}` 36 l.path = resolution.path 37 38 accumulator[advisory.severity] += [action.action, l.package, l.sevLevel, l.recommendation, l.severity, l.moreInfo, l.path, l.breaking] 39 .join('\t') + '\n' 40 }) // forEach resolves 41 } 42 43 if (action.action === 'review') { 44 action.resolves.forEach((resolution) => { 45 const advisory = data.advisories[resolution.id] 46 47 l.sevLevel = advisory.severity 48 l.severity = advisory.title 49 l.package = advisory.module_name 50 l.moreInfo = advisory.url || `https://www.npmjs.com/advisories/${advisory.id}` 51 l.patchedIn = advisory.patched_versions.replace(' ', '') === '<0.0.0' ? 'No patch available' : advisory.patched_versions 52 l.path = resolution.path 53 54 accumulator[advisory.severity] += [action.action, l.package, l.sevLevel, l.patchedIn, l.severity, l.moreInfo, l.path].join('\t') + '\n' 55 }) // forEach resolves 56 } // is review 57 }) // forEach actions 58 } 59 return accumulator['critical'] + accumulator['high'] + accumulator['moderate'] + accumulator['low'] 60 } 61 62 const exitCode = function (metadata) { 63 let total = 0 64 const keys = Object.keys(metadata.vulnerabilities) 65 for (let key of keys) { 66 const value = metadata.vulnerabilities[key] 67 total = total + value 68 } 69 70 if (total > 0) { 71 exit = 1 72 } 73 } 74 75 exitCode(data.metadata) 76 77 return { 78 report: actions(data, config), 79 exitCode: exit 80 } 81} 82 83const getRecommendation = function (action, config) { 84 if (action.action === 'install') { 85 const isDev = action.resolves[0].dev 86 87 return { 88 cmd: `npm install ${isDev ? '--save-dev ' : ''}${action.module}@${action.target}`, 89 isBreaking: action.isMajor 90 } 91 } else { 92 return { 93 cmd: `npm update ${action.module} --depth ${action.depth}`, 94 isBreaking: false 95 } 96 } 97} 98 99module.exports = report 100