Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKat Marchán <kzm@zkat.tech>2018-07-27 04:55:31 +0300
committerKat Marchán <kzm@zkat.tech>2018-12-11 01:55:40 +0300
commitdec07ebe3312245f6421c6e523660be4973ae8c2 (patch)
treef04f2a91204e4b1846d56d06bff64185a2c8a5ed /lib
parent514558e094460fd0284a759c13965b685133b3fe (diff)
audit: convert audit to new version of n-r-f
Diffstat (limited to 'lib')
-rw-r--r--lib/audit.js55
-rw-r--r--lib/config/figgy-config.js11
-rw-r--r--lib/install/audit.js141
3 files changed, 115 insertions, 92 deletions
diff --git a/lib/audit.js b/lib/audit.js
index 06852610e..076ca256b 100644
--- a/lib/audit.js
+++ b/lib/audit.js
@@ -3,17 +3,37 @@
const Bluebird = require('bluebird')
const audit = require('./install/audit.js')
+const figgyPudding = require('figgy-pudding')
const fs = require('graceful-fs')
const Installer = require('./install.js').Installer
const lockVerify = require('lock-verify')
const log = require('npmlog')
-const npa = require('npm-package-arg')
+const npa = require('libnpm/parse-arg')
const npm = require('./npm.js')
+const npmConfig = require('./config/figgy-config.js')
const output = require('./utils/output.js')
const parseJson = require('json-parse-better-errors')
const readFile = Bluebird.promisify(fs.readFile)
+const AuditConfig = figgyPudding({
+ also: {},
+ 'audit-level': {},
+ deepArgs: 'deep-args',
+ 'deep-args': {},
+ dev: {},
+ force: {},
+ 'dry-run': {},
+ global: {},
+ json: {},
+ only: {},
+ parseable: {},
+ prod: {},
+ production: {},
+ registry: {},
+ runId: {}
+})
+
module.exports = auditCmd
const usage = require('./utils/usage')
@@ -110,12 +130,12 @@ function maybeReadFile (name) {
})
}
-function filterEnv (action) {
- const includeDev = npm.config.get('dev') ||
- (!/^prod(uction)?$/.test(npm.config.get('only')) && !npm.config.get('production')) ||
- /^dev(elopment)?$/.test(npm.config.get('only')) ||
- /^dev(elopment)?$/.test(npm.config.get('also'))
- const includeProd = !/^dev(elopment)?$/.test(npm.config.get('only'))
+function filterEnv (action, opts) {
+ const includeDev = opts.dev ||
+ (!/^prod(uction)?$/.test(opts.only) && !opts.production) ||
+ /^dev(elopment)?$/.test(opts.only) ||
+ /^dev(elopment)?$/.test(opts.also)
+ const includeProd = !/^dev(elopment)?$/.test(opts.only)
const resolves = action.resolves.filter(({dev}) => {
return (dev && includeDev) || (!dev && includeProd)
})
@@ -125,7 +145,8 @@ function filterEnv (action) {
}
function auditCmd (args, cb) {
- if (npm.config.get('global')) {
+ const opts = AuditConfig(npmConfig())
+ if (opts.global) {
const err = new Error('`npm audit` does not support testing globals')
err.code = 'EAUDITGLOBAL'
throw err
@@ -169,7 +190,7 @@ function auditCmd (args, cb) {
return audit.submitForFullReport(auditReport)
}).catch((err) => {
if (err.statusCode === 404 || err.statusCode >= 500) {
- const ne = new Error(`Your configured registry (${npm.config.get('registry')}) does not support audit requests.`)
+ const ne = new Error(`Your configured registry (${opts.registry}) does not support audit requests.`)
ne.code = 'ENOAUDIT'
ne.wrapped = err
throw ne
@@ -178,7 +199,7 @@ function auditCmd (args, cb) {
}).then((auditResult) => {
if (args[0] === 'fix') {
const actions = (auditResult.actions || []).reduce((acc, action) => {
- action = filterEnv(action)
+ action = filterEnv(action, opts)
if (!action) { return acc }
if (action.isMajor) {
acc.major.add(`${action.module}@${action.target}`)
@@ -215,7 +236,7 @@ function auditCmd (args, cb) {
review: new Set()
})
return Bluebird.try(() => {
- const installMajor = npm.config.get('force')
+ const installMajor = opts.force
const installCount = actions.install.size + (installMajor ? actions.major.size : 0) + actions.update.size
const vulnFixCount = new Set([...actions.installFixes, ...actions.updateFixes, ...(installMajor ? actions.majorFixes : [])]).size
const metavuln = auditResult.metadata.vulnerabilities
@@ -230,16 +251,16 @@ function auditCmd (args, cb) {
return Bluebird.fromNode(cb => {
new Auditor(
npm.prefix,
- !!npm.config.get('dry-run'),
+ !!opts['dry-run'],
[...actions.install, ...(installMajor ? actions.major : [])],
- {
+ opts.concat({
runId: auditResult.runId,
deepArgs: [...actions.update].map(u => u.split('>'))
- }
+ }).toJSON()
).run(cb)
}).then(() => {
const numScanned = auditResult.metadata.totalDependencies
- if (!npm.config.get('json') && !npm.config.get('parseable')) {
+ if (!opts.json && !opts.parseable) {
output(`fixed ${vulnFixCount} of ${total} vulnerabilit${total === 1 ? 'y' : 'ies'} in ${numScanned} scanned package${numScanned === 1 ? '' : 's'}`)
if (actions.review.size) {
output(` ${actions.review.size} vulnerabilit${actions.review.size === 1 ? 'y' : 'ies'} required manual review and could not be updated`)
@@ -258,12 +279,12 @@ function auditCmd (args, cb) {
})
} else {
const levels = ['low', 'moderate', 'high', 'critical']
- const minLevel = levels.indexOf(npm.config.get('audit-level'))
+ const minLevel = levels.indexOf(opts['audit-level'])
const vulns = levels.reduce((count, level, i) => {
return i < minLevel ? count : count + (auditResult.metadata.vulnerabilities[level] || 0)
}, 0)
if (vulns > 0) process.exitCode = 1
- if (npm.config.get('parseable')) {
+ if (opts.parseable) {
return audit.printParseableReport(auditResult)
} else {
return audit.printFullReport(auditResult)
diff --git a/lib/config/figgy-config.js b/lib/config/figgy-config.js
index 3ad5009c7..b50370330 100644
--- a/lib/config/figgy-config.js
+++ b/lib/config/figgy-config.js
@@ -12,7 +12,12 @@ const path = require('path')
const npmSession = crypto.randomBytes(8).toString('hex')
log.verbose('npm-session', npmSession)
-const NpmConfig = figgyPudding({})
+const SCOPE_REGISTRY_REGEX = /@.*:registry$/gi
+const NpmConfig = figgyPudding({}, {
+ other (key) {
+ return key.match(SCOPE_REGISTRY_REGEX)
+ }
+})
let baseConfig
@@ -25,8 +30,8 @@ function mkConfig (...providers) {
dirPacker: pack.packGitDep,
hashAlgorithm: 'sha1',
includeDeprecated: false,
- npmSession,
- projectScope: npm.projectScope,
+ 'npm-session': npmSession,
+ 'project-scope': npm.projectScope,
refer: npm.registry.refer,
dmode: npm.modes.exec,
fmode: npm.modes.file,
diff --git a/lib/install/audit.js b/lib/install/audit.js
index f372b425a..f5bc5ae1a 100644
--- a/lib/install/audit.js
+++ b/lib/install/audit.js
@@ -7,118 +7,115 @@ exports.printInstallReport = printInstallReport
exports.printParseableReport = printParseableReport
exports.printFullReport = printFullReport
-const Bluebird = require('bluebird')
const auditReport = require('npm-audit-report')
+const npmConfig = require('../config/figgy-config.js')
+const figgyPudding = require('figgy-pudding')
const treeToShrinkwrap = require('../shrinkwrap.js').treeToShrinkwrap
const packageId = require('../utils/package-id.js')
const output = require('../utils/output.js')
const npm = require('../npm.js')
const qw = require('qw')
-const registryFetch = require('npm-registry-fetch')
-const zlib = require('zlib')
-const gzip = Bluebird.promisify(zlib.gzip)
-const log = require('npmlog')
+const regFetch = require('npm-registry-fetch')
const perf = require('../utils/perf.js')
-const url = require('url')
const npa = require('npm-package-arg')
const uuid = require('uuid')
const ssri = require('ssri')
const cloneDeep = require('lodash.clonedeep')
-const pacoteOpts = require('../config/pacote.js')
// used when scrubbing module names/specifiers
const runId = uuid.v4()
+const InstallAuditConfig = figgyPudding({
+ color: {},
+ json: {},
+ unicode: {}
+}, {
+ other (key) {
+ return /:registry$/.test(key)
+ }
+})
+
function submitForInstallReport (auditData) {
- const cfg = npm.config // avoid the no-dynamic-lookups test
- const scopedRegistries = cfg.keys.filter(_ => /:registry$/.test(_)).map(_ => cfg.get(_))
- perf.emit('time', 'audit compress')
- // TODO: registryFetch will be adding native support for `Content-Encoding: gzip` at which point
- // we'll pass in something like `gzip: true` and not need to JSON stringify, gzip or headers.
- return gzip(JSON.stringify(auditData)).then(body => {
- perf.emit('timeEnd', 'audit compress')
- log.info('audit', 'Submitting payload of ' + body.length + 'bytes')
- scopedRegistries.forEach(reg => {
- // we don't care about the response so destroy the stream if we can, or leave it flowing
- // so it can eventually finish and clean up after itself
- fetchAudit(url.resolve(reg, '/-/npm/v1/security/audits/quick'))
- .then(_ => {
- _.body.on('error', () => {})
- if (_.body.destroy) {
- _.body.destroy()
- } else {
- _.body.resume()
- }
- }, _ => {})
- })
- perf.emit('time', 'audit submit')
- return fetchAudit('/-/npm/v1/security/audits/quick', body).then(response => {
- perf.emit('timeEnd', 'audit submit')
- perf.emit('time', 'audit body')
- return response.json()
- }).then(result => {
- perf.emit('timeEnd', 'audit body')
- return result
- })
+ const opts = InstallAuditConfig(npmConfig())
+ const scopedRegistries = [...opts.keys()].filter(
+ k => /:registry$/.test(k)
+ ).map(k => opts[k])
+ scopedRegistries.forEach(registry => {
+ // we don't care about the response so destroy the stream if we can, or leave it flowing
+ // so it can eventually finish and clean up after itself
+ regFetch('/-/npm/v1/security/audits/quick', opts.concat({
+ method: 'POST',
+ registry,
+ gzip: true,
+ body: auditData
+ })).then(_ => {
+ _.body.on('error', () => {})
+ if (_.body.destroy) {
+ _.body.destroy()
+ } else {
+ _.body.resume()
+ }
+ }, _ => {})
})
-}
-
-function submitForFullReport (auditData) {
- perf.emit('time', 'audit compress')
- // TODO: registryFetch will be adding native support for `Content-Encoding: gzip` at which point
- // we'll pass in something like `gzip: true` and not need to JSON stringify, gzip or headers.
- return gzip(JSON.stringify(auditData)).then(body => {
- perf.emit('timeEnd', 'audit compress')
- log.info('audit', 'Submitting payload of ' + body.length + ' bytes')
- perf.emit('time', 'audit submit')
- return fetchAudit('/-/npm/v1/security/audits', body).then(response => {
- perf.emit('timeEnd', 'audit submit')
- perf.emit('time', 'audit body')
- return response.json()
- }).then(result => {
- perf.emit('timeEnd', 'audit body')
- result.runId = runId
- return result
- })
+ perf.emit('time', 'audit submit')
+ return regFetch('/-/npm/v1/security/audits/quick', opts.concat({
+ method: 'POST',
+ gzip: true,
+ body: auditData
+ })).then(response => {
+ perf.emit('timeEnd', 'audit submit')
+ perf.emit('time', 'audit body')
+ return response.json()
+ }).then(result => {
+ perf.emit('timeEnd', 'audit body')
+ return result
})
}
-function fetchAudit (href, body) {
- const opts = pacoteOpts()
- return registryFetch(href, {
+function submitForFullReport (auditData) {
+ perf.emit('time', 'audit submit')
+ const opts = InstallAuditConfig(npmConfig())
+ return regFetch('/-/npm/v1/security/audits', opts.concat({
method: 'POST',
- headers: { 'content-encoding': 'gzip', 'content-type': 'application/json' },
- config: npm.config,
- npmSession: opts.npmSession,
- projectScope: npm.projectScope,
- log: log,
- body: body
+ gzip: true,
+ body: auditData
+ })).then(response => {
+ perf.emit('timeEnd', 'audit submit')
+ perf.emit('time', 'audit body')
+ return response.json()
+ }).then(result => {
+ perf.emit('timeEnd', 'audit body')
+ result.runId = runId
+ return result
})
}
function printInstallReport (auditResult) {
+ const opts = InstallAuditConfig(npmConfig())
return auditReport(auditResult, {
reporter: 'install',
- withColor: npm.color,
- withUnicode: npm.config.get('unicode')
+ withColor: opts.color,
+ withUnicode: opts.unicode
}).then(result => output(result.report))
}
function printFullReport (auditResult) {
+ const opts = InstallAuditConfig(npmConfig())
return auditReport(auditResult, {
log: output,
- reporter: npm.config.get('json') ? 'json' : 'detail',
- withColor: npm.color,
- withUnicode: npm.config.get('unicode')
+ reporter: opts.json ? 'json' : 'detail',
+ withColor: opts.color,
+ withUnicode: opts.unicode
}).then(result => output(result.report))
}
function printParseableReport (auditResult) {
+ const opts = InstallAuditConfig(npmConfig())
return auditReport(auditResult, {
log: output,
reporter: 'parseable',
- withColor: npm.color,
- withUnicode: npm.config.get('unicode')
+ withColor: opts.color,
+ withUnicode: opts.unicode
}).then(result => output(result.report))
}