Files
vue-cli/packages/@vue/cli-ui/ui-defaults/utils/audit.js
T
Haoqun Jiang 0f377bd31d feat: upgrade to eslint 6 (#4933)
* feat: scaffold projects with eslint 6

* style: eslint fix

* refactor: do not use hard-coded ecmaVersion, use babel-eslint for now

* fix: upgrade to @vue/eslint-config-standard

* style: continue fix lint errors

* chore: upgrade to eslint-plugin-vue@^6.1.2

* refactor: use `ecmaVersion: 2020` for dynamic import syntax support

* test: fix baseESLintConfig

* chore: also update yarn.lock to fix CI caches

* chore: update lockfile again, fix babel regressions

* test: nightwatch tests should fail if lint errors occur

* chore: update the lockfile (again), fixing a bug in airbnb config
2020-01-14 10:13:54 +08:00

139 lines
3.3 KiB
JavaScript

const { hasProjectYarn, hasProjectPnpm, execa } = require('@vue/cli-shared-utils')
const severity = {
critical: 0,
high: 1,
moderate: 2,
low: 3
}
exports.auditProject = async function (cwd) {
try {
if (hasProjectYarn(cwd)) {
const child = await execa('yarn', [
'audit',
'--json',
'--non-interactive',
'--no-progress'
], {
cwd,
reject: false
})
if (child.stderr) {
const errLines = child.stderr.split('\n').map(l => l.trim()).filter(l => l)
const error = errLines.find(l => l.startsWith('Error:'))
if (error) {
throw new Error(error.substr('Error:'.length).trim())
}
}
const data = child.stdout
const auditAdvisories = []
const ids = {}
const lines = data.split('\n').filter(l => l.trim()).map(l => JSON.parse(l))
for (const line of lines) {
if (line.type === 'auditAdvisory') {
if (!ids[line.data.advisory.id]) {
auditAdvisories.push(line)
ids[line.data.advisory.id] = true
}
}
}
const details = {
vulnerabilities: [],
summary: {
critical: 0,
high: 0,
moderate: 0,
low: 0
}
}
auditAdvisories.sort((a, b) => severity[a.data.advisory.severity] - severity[b.data.advisory.severity])
let id = 0
for (const { data: { advisory } } of auditAdvisories) {
for (const finding of advisory.findings) {
// const [finding] = advisory.findings
const detail = {
id: id++,
name: advisory.module_name,
version: finding.version,
parents: finding.paths.sort(
(a, b) => a.length - b.length
).map(
parents => parents.split('>').slice(0, parents.length - 2).map(p => ({
name: p
}))
),
moreInfo: advisory.url,
severity: advisory.severity,
title: advisory.title,
message: advisory.overview,
versions: {
vulnerable: advisory.vulnerable_versions,
patched: advisory.patched_versions
},
recommendation: advisory.recommendation
}
details.vulnerabilities.push(detail)
details.summary[advisory.severity]++
}
}
const status = {
status: 'ok',
count: details.vulnerabilities.length,
message: null
}
if (status.count) {
status.status = 'attention'
}
for (const n in details.summary) {
if (details.summary) {
status.severity = n
break
}
}
return {
status,
details
}
} else if (hasProjectPnpm(cwd)) {
// TODO pnpm audit
return {
status: {
status: 'error',
message: 'Not implemented for PNPM projects yet'
},
details: null
}
} else {
// TODO NPM audit
return {
status: {
status: 'error',
message: 'Not implemented for NPM projects yet'
},
details: null
}
}
} catch (e) {
return {
status: {
status: 'error',
message: e.message
},
details: null
}
}
}