Skip to content

Commit ae8d856

Browse files
committed
audit: convert audit to new version of n-r-f
1 parent 5e0bdcb commit ae8d856

File tree

3 files changed

+114
-91
lines changed

3 files changed

+114
-91
lines changed

lib/audit.js

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,37 @@
33
const Bluebird = require('bluebird')
44

55
const audit = require('./install/audit.js')
6+
const figgyPudding = require('figgy-pudding')
67
const fs = require('graceful-fs')
78
const Installer = require('./install.js').Installer
89
const lockVerify = require('lock-verify')
910
const log = require('npmlog')
1011
const npa = require('npm-package-arg')
1112
const npm = require('./npm.js')
13+
const npmConfig = require('./config/figgy-config.js')
1214
const output = require('./utils/output.js')
1315
const parseJson = require('json-parse-better-errors')
1416

1517
const readFile = Bluebird.promisify(fs.readFile)
1618

19+
const AuditConfig = figgyPudding({
20+
also: {},
21+
'audit-level': {},
22+
deepArgs: 'deep-args',
23+
'deep-args': {},
24+
dev: {},
25+
force: {},
26+
'dry-run': {},
27+
global: {},
28+
json: {},
29+
only: {},
30+
parseable: {},
31+
prod: {},
32+
production: {},
33+
registry: {},
34+
runId: {}
35+
})
36+
1737
module.exports = auditCmd
1838

1939
const usage = require('./utils/usage')
@@ -110,12 +130,12 @@ function maybeReadFile (name) {
110130
})
111131
}
112132

113-
function filterEnv (action) {
114-
const includeDev = npm.config.get('dev') ||
115-
(!/^prod(uction)?$/.test(npm.config.get('only')) && !npm.config.get('production')) ||
116-
/^dev(elopment)?$/.test(npm.config.get('only')) ||
117-
/^dev(elopment)?$/.test(npm.config.get('also'))
118-
const includeProd = !/^dev(elopment)?$/.test(npm.config.get('only'))
133+
function filterEnv (action, opts) {
134+
const includeDev = opts.dev ||
135+
(!/^prod(uction)?$/.test(opts.only) && !opts.production) ||
136+
/^dev(elopment)?$/.test(opts.only) ||
137+
/^dev(elopment)?$/.test(opts.also)
138+
const includeProd = !/^dev(elopment)?$/.test(opts.only)
119139
const resolves = action.resolves.filter(({dev}) => {
120140
return (dev && includeDev) || (!dev && includeProd)
121141
})
@@ -125,7 +145,8 @@ function filterEnv (action) {
125145
}
126146

127147
function auditCmd (args, cb) {
128-
if (npm.config.get('global')) {
148+
const opts = AuditConfig(npmConfig())
149+
if (opts.global) {
129150
const err = new Error('`npm audit` does not support testing globals')
130151
err.code = 'EAUDITGLOBAL'
131152
throw err
@@ -169,7 +190,7 @@ function auditCmd (args, cb) {
169190
return audit.submitForFullReport(auditReport)
170191
}).catch((err) => {
171192
if (err.statusCode === 404 || err.statusCode >= 500) {
172-
const ne = new Error(`Your configured registry (${npm.config.get('registry')}) does not support audit requests.`)
193+
const ne = new Error(`Your configured registry (${opts.registry}) does not support audit requests.`)
173194
ne.code = 'ENOAUDIT'
174195
ne.wrapped = err
175196
throw ne
@@ -178,7 +199,7 @@ function auditCmd (args, cb) {
178199
}).then((auditResult) => {
179200
if (args[0] === 'fix') {
180201
const actions = (auditResult.actions || []).reduce((acc, action) => {
181-
action = filterEnv(action)
202+
action = filterEnv(action, opts)
182203
if (!action) { return acc }
183204
if (action.isMajor) {
184205
acc.major.add(`${action.module}@${action.target}`)
@@ -215,7 +236,7 @@ function auditCmd (args, cb) {
215236
review: new Set()
216237
})
217238
return Bluebird.try(() => {
218-
const installMajor = npm.config.get('force')
239+
const installMajor = opts.force
219240
const installCount = actions.install.size + (installMajor ? actions.major.size : 0) + actions.update.size
220241
const vulnFixCount = new Set([...actions.installFixes, ...actions.updateFixes, ...(installMajor ? actions.majorFixes : [])]).size
221242
const metavuln = auditResult.metadata.vulnerabilities
@@ -230,16 +251,16 @@ function auditCmd (args, cb) {
230251
return Bluebird.fromNode(cb => {
231252
new Auditor(
232253
npm.prefix,
233-
!!npm.config.get('dry-run'),
254+
!!opts['dry-run'],
234255
[...actions.install, ...(installMajor ? actions.major : [])],
235-
{
256+
opts.concat({
236257
runId: auditResult.runId,
237258
deepArgs: [...actions.update].map(u => u.split('>'))
238-
}
259+
}).toJSON()
239260
).run(cb)
240261
}).then(() => {
241262
const numScanned = auditResult.metadata.totalDependencies
242-
if (!npm.config.get('json') && !npm.config.get('parseable')) {
263+
if (!opts.json && !opts.parseable) {
243264
output(`fixed ${vulnFixCount} of ${total} vulnerabilit${total === 1 ? 'y' : 'ies'} in ${numScanned} scanned package${numScanned === 1 ? '' : 's'}`)
244265
if (actions.review.size) {
245266
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) {
258279
})
259280
} else {
260281
const levels = ['low', 'moderate', 'high', 'critical']
261-
const minLevel = levels.indexOf(npm.config.get('audit-level'))
282+
const minLevel = levels.indexOf(opts['audit-level'])
262283
const vulns = levels.reduce((count, level, i) => {
263284
return i < minLevel ? count : count + (auditResult.metadata.vulnerabilities[level] || 0)
264285
}, 0)
265286
if (vulns > 0) process.exitCode = 1
266-
if (npm.config.get('parseable')) {
287+
if (opts.parseable) {
267288
return audit.printParseableReport(auditResult)
268289
} else {
269290
return audit.printFullReport(auditResult)

lib/config/figgy-config.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ const path = require('path')
1212
const npmSession = crypto.randomBytes(8).toString('hex')
1313
log.verbose('npm-session', npmSession)
1414

15-
const NpmConfig = figgyPudding({})
15+
const SCOPE_REGISTRY_REGEX = /@.*:registry$/gi
16+
const NpmConfig = figgyPudding({}, {
17+
other (key) {
18+
return key.match(SCOPE_REGISTRY_REGEX)
19+
}
20+
})
1621

1722
let baseConfig
1823

@@ -25,8 +30,8 @@ function mkConfig (...providers) {
2530
dirPacker: pack.packGitDep,
2631
hashAlgorithm: 'sha1',
2732
includeDeprecated: false,
28-
npmSession,
29-
projectScope: npm.projectScope,
33+
'npm-session': npmSession,
34+
'project-scope': npm.projectScope,
3035
refer: npm.registry.refer,
3136
dmode: npm.modes.exec,
3237
fmode: npm.modes.file,

lib/install/audit.js

Lines changed: 69 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7,118 +7,115 @@ exports.printInstallReport = printInstallReport
77
exports.printParseableReport = printParseableReport
88
exports.printFullReport = printFullReport
99

10-
const Bluebird = require('bluebird')
1110
const auditReport = require('npm-audit-report')
11+
const npmConfig = require('../config/figgy-config.js')
12+
const figgyPudding = require('figgy-pudding')
1213
const treeToShrinkwrap = require('../shrinkwrap.js').treeToShrinkwrap
1314
const packageId = require('../utils/package-id.js')
1415
const output = require('../utils/output.js')
1516
const npm = require('../npm.js')
1617
const qw = require('qw')
17-
const registryFetch = require('npm-registry-fetch')
18-
const zlib = require('zlib')
19-
const gzip = Bluebird.promisify(zlib.gzip)
20-
const log = require('npmlog')
18+
const regFetch = require('npm-registry-fetch')
2119
const perf = require('../utils/perf.js')
22-
const url = require('url')
2320
const npa = require('npm-package-arg')
2421
const uuid = require('uuid')
2522
const ssri = require('ssri')
2623
const cloneDeep = require('lodash.clonedeep')
27-
const pacoteOpts = require('../config/pacote.js')
2824

2925
// used when scrubbing module names/specifiers
3026
const runId = uuid.v4()
3127

28+
const InstallAuditConfig = figgyPudding({
29+
color: {},
30+
json: {},
31+
unicode: {}
32+
}, {
33+
other (key) {
34+
return /:registry$/.test(key)
35+
}
36+
})
37+
3238
function submitForInstallReport (auditData) {
33-
const cfg = npm.config // avoid the no-dynamic-lookups test
34-
const scopedRegistries = cfg.keys.filter(_ => /:registry$/.test(_)).map(_ => cfg.get(_))
35-
perf.emit('time', 'audit compress')
36-
// TODO: registryFetch will be adding native support for `Content-Encoding: gzip` at which point
37-
// we'll pass in something like `gzip: true` and not need to JSON stringify, gzip or headers.
38-
return gzip(JSON.stringify(auditData)).then(body => {
39-
perf.emit('timeEnd', 'audit compress')
40-
log.info('audit', 'Submitting payload of ' + body.length + 'bytes')
41-
scopedRegistries.forEach(reg => {
42-
// we don't care about the response so destroy the stream if we can, or leave it flowing
43-
// so it can eventually finish and clean up after itself
44-
fetchAudit(url.resolve(reg, '/-/npm/v1/security/audits/quick'))
45-
.then(_ => {
46-
_.body.on('error', () => {})
47-
if (_.body.destroy) {
48-
_.body.destroy()
49-
} else {
50-
_.body.resume()
51-
}
52-
}, _ => {})
53-
})
54-
perf.emit('time', 'audit submit')
55-
return fetchAudit('/-/npm/v1/security/audits/quick', body).then(response => {
56-
perf.emit('timeEnd', 'audit submit')
57-
perf.emit('time', 'audit body')
58-
return response.json()
59-
}).then(result => {
60-
perf.emit('timeEnd', 'audit body')
61-
return result
62-
})
39+
const opts = InstallAuditConfig(npmConfig())
40+
const scopedRegistries = [...opts.keys()].filter(
41+
k => /:registry$/.test(k)
42+
).map(k => opts[k])
43+
scopedRegistries.forEach(registry => {
44+
// we don't care about the response so destroy the stream if we can, or leave it flowing
45+
// so it can eventually finish and clean up after itself
46+
regFetch('/-/npm/v1/security/audits/quick', opts.concat({
47+
method: 'POST',
48+
registry,
49+
gzip: true,
50+
body: auditData
51+
})).then(_ => {
52+
_.body.on('error', () => {})
53+
if (_.body.destroy) {
54+
_.body.destroy()
55+
} else {
56+
_.body.resume()
57+
}
58+
}, _ => {})
6359
})
64-
}
65-
66-
function submitForFullReport (auditData) {
67-
perf.emit('time', 'audit compress')
68-
// TODO: registryFetch will be adding native support for `Content-Encoding: gzip` at which point
69-
// we'll pass in something like `gzip: true` and not need to JSON stringify, gzip or headers.
70-
return gzip(JSON.stringify(auditData)).then(body => {
71-
perf.emit('timeEnd', 'audit compress')
72-
log.info('audit', 'Submitting payload of ' + body.length + ' bytes')
73-
perf.emit('time', 'audit submit')
74-
return fetchAudit('/-/npm/v1/security/audits', body).then(response => {
75-
perf.emit('timeEnd', 'audit submit')
76-
perf.emit('time', 'audit body')
77-
return response.json()
78-
}).then(result => {
79-
perf.emit('timeEnd', 'audit body')
80-
result.runId = runId
81-
return result
82-
})
60+
perf.emit('time', 'audit submit')
61+
return regFetch('/-/npm/v1/security/audits/quick', opts.concat({
62+
method: 'POST',
63+
gzip: true,
64+
body: auditData
65+
})).then(response => {
66+
perf.emit('timeEnd', 'audit submit')
67+
perf.emit('time', 'audit body')
68+
return response.json()
69+
}).then(result => {
70+
perf.emit('timeEnd', 'audit body')
71+
return result
8372
})
8473
}
8574

86-
function fetchAudit (href, body) {
87-
const opts = pacoteOpts()
88-
return registryFetch(href, {
75+
function submitForFullReport (auditData) {
76+
perf.emit('time', 'audit submit')
77+
const opts = InstallAuditConfig(npmConfig())
78+
return regFetch('/-/npm/v1/security/audits', opts.concat({
8979
method: 'POST',
90-
headers: { 'Content-Encoding': 'gzip', 'Content-Type': 'application/json' },
91-
config: npm.config,
92-
npmSession: opts.npmSession,
93-
projectScope: npm.projectScope,
94-
log: log,
95-
body: body
80+
gzip: true,
81+
body: auditData
82+
})).then(response => {
83+
perf.emit('timeEnd', 'audit submit')
84+
perf.emit('time', 'audit body')
85+
return response.json()
86+
}).then(result => {
87+
perf.emit('timeEnd', 'audit body')
88+
result.runId = runId
89+
return result
9690
})
9791
}
9892

9993
function printInstallReport (auditResult) {
94+
const opts = InstallAuditConfig(npmConfig())
10095
return auditReport(auditResult, {
10196
reporter: 'install',
102-
withColor: npm.color,
103-
withUnicode: npm.config.get('unicode')
97+
withColor: opts.color,
98+
withUnicode: opts.unicode
10499
}).then(result => output(result.report))
105100
}
106101

107102
function printFullReport (auditResult) {
103+
const opts = InstallAuditConfig(npmConfig())
108104
return auditReport(auditResult, {
109105
log: output,
110-
reporter: npm.config.get('json') ? 'json' : 'detail',
111-
withColor: npm.color,
112-
withUnicode: npm.config.get('unicode')
106+
reporter: opts.json ? 'json' : 'detail',
107+
withColor: opts.color,
108+
withUnicode: opts.unicode
113109
}).then(result => output(result.report))
114110
}
115111

116112
function printParseableReport (auditResult) {
113+
const opts = InstallAuditConfig(npmConfig())
117114
return auditReport(auditResult, {
118115
log: output,
119116
reporter: 'parseable',
120-
withColor: npm.color,
121-
withUnicode: npm.config.get('unicode')
117+
withColor: opts.color,
118+
withUnicode: opts.unicode
122119
}).then(result => output(result.report))
123120
}
124121

0 commit comments

Comments
 (0)