mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-01-25 16:48:56 -06:00
139 lines
3.3 KiB
JavaScript
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
|
|
|
|
let 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 = 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
|
|
}
|
|
}
|
|
}
|