forked from lix-project/lix-website
155 lines
3.8 KiB
JavaScript
155 lines
3.8 KiB
JavaScript
|
#!/usr/bin/env node
|
|||
|
'use strict'
|
|||
|
|
|||
|
const debug = require('debug')('lockfile-lint')
|
|||
|
const glob = require('fast-glob')
|
|||
|
const main = require('../src/main')
|
|||
|
|
|||
|
const isSupported =
|
|||
|
process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'
|
|||
|
|
|||
|
const symbolsDefault = {
|
|||
|
info: 'ℹ',
|
|||
|
success: '✔',
|
|||
|
error: '✖'
|
|||
|
}
|
|||
|
|
|||
|
const symbolsFallback = {
|
|||
|
info: 'i',
|
|||
|
success: '√',
|
|||
|
error: '×'
|
|||
|
}
|
|||
|
|
|||
|
const symbols = isSupported ? symbolsDefault : symbolsFallback
|
|||
|
|
|||
|
const RESET = '\x1b[0m'
|
|||
|
const RED = '\x1b[31m'
|
|||
|
const GREEN = '\x1b[32m'
|
|||
|
const YELLOW = '\x1b[33m'
|
|||
|
|
|||
|
let config
|
|||
|
|
|||
|
try {
|
|||
|
config = require('../src/config')(process.argv)
|
|||
|
debug(`parsed the following options: ${JSON.stringify(config)}`)
|
|||
|
} catch (errorPayload) {
|
|||
|
debug(`error loading options from CLI arguments/files: ${errorPayload}`)
|
|||
|
process.exit(1)
|
|||
|
}
|
|||
|
|
|||
|
const isPrettyFormat = config.format === 'pretty'
|
|||
|
|
|||
|
const validators = []
|
|||
|
const supportedValidators = new Map([
|
|||
|
['allowed-hosts', 'validateHosts'],
|
|||
|
['validate-https', 'validateHttps'],
|
|||
|
['validate-package-names', 'ValidatePackageNames'],
|
|||
|
['allowed-schemes', 'validateSchemes'],
|
|||
|
['allowed-urls', 'validateUrls'],
|
|||
|
['validate-integrity', 'validateIntegrity']
|
|||
|
])
|
|||
|
|
|||
|
let lockfilesList = []
|
|||
|
if (config.path) {
|
|||
|
lockfilesList = glob.sync(config.path)
|
|||
|
}
|
|||
|
|
|||
|
for (const lockfilePath of lockfilesList) {
|
|||
|
if (lockfilesList.length > 1) {
|
|||
|
console.log(`\nlockfile-lint scanning: ${lockfilePath}\n`)
|
|||
|
}
|
|||
|
|
|||
|
for (const [commandArgument, commandValue] of Object.entries(config)) {
|
|||
|
/**
|
|||
|
* If we have both --allowed-urls and --allowed-hosts flags active
|
|||
|
* then we can skip doing the work for allowed urls as the validator
|
|||
|
* for allowed hosts will check for both.
|
|||
|
*
|
|||
|
* We only need to run the check for allowed urls if the user does not
|
|||
|
* specify allowed hosts.
|
|||
|
*/
|
|||
|
if (commandArgument === 'allowed-urls' && config['allowed-hosts']) {
|
|||
|
continue
|
|||
|
}
|
|||
|
|
|||
|
if (commandValue && supportedValidators.has(commandArgument)) {
|
|||
|
const validatorItem = supportedValidators.get(commandArgument)
|
|||
|
validators.push({
|
|||
|
name: validatorItem,
|
|||
|
values: commandValue,
|
|||
|
options: {
|
|||
|
emptyHostname: config['empty-hostname'],
|
|||
|
allowedHosts: config['allowed-hosts'],
|
|||
|
allowedUrls: config['allowed-urls'],
|
|||
|
allowedPackageNameAliases: config['allowed-package-name-aliases'],
|
|||
|
integrityExclude: config['integrity-exclude']
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
let result
|
|||
|
try {
|
|||
|
result = main.runValidators({
|
|||
|
path: lockfilePath,
|
|||
|
type: config.type,
|
|||
|
validators
|
|||
|
})
|
|||
|
} catch (errorPayload) {
|
|||
|
warn('ABORTING lockfile lint process due to error exceptions')
|
|||
|
console.error(errorPayload.message, '\n')
|
|||
|
console.error(errorPayload.stack, '\n')
|
|||
|
error('Error: command failed with exit code 1')
|
|||
|
process.exit(1)
|
|||
|
}
|
|||
|
|
|||
|
const {validatorCount, validatorFailures, validatorSuccesses} = result
|
|||
|
|
|||
|
debug(`total validators invoked: ${validatorCount}`)
|
|||
|
debug(`total validator failures: ${validatorFailures}`)
|
|||
|
debug(`total validator successes: ${validatorSuccesses}`)
|
|||
|
|
|||
|
if (validatorFailures !== 0) {
|
|||
|
error('Error: security issues detected!')
|
|||
|
process.exit(1)
|
|||
|
} else {
|
|||
|
success('No issues detected')
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function success (message) {
|
|||
|
const m = [
|
|||
|
isPrettyFormat ? GREEN : '',
|
|||
|
isPrettyFormat ? symbols.success : '',
|
|||
|
message,
|
|||
|
'\n',
|
|||
|
isPrettyFormat ? RESET : ''
|
|||
|
].filter(e => !!e)
|
|||
|
|
|||
|
console.info(m.join(' '))
|
|||
|
}
|
|||
|
|
|||
|
function warn (message) {
|
|||
|
const m = [
|
|||
|
isPrettyFormat ? YELLOW : '',
|
|||
|
isPrettyFormat ? symbols.info : '',
|
|||
|
message,
|
|||
|
'\n',
|
|||
|
isPrettyFormat ? RESET : ''
|
|||
|
].filter(e => !!e)
|
|||
|
|
|||
|
console.error(m.join(' '))
|
|||
|
}
|
|||
|
|
|||
|
function error (message) {
|
|||
|
const m = [
|
|||
|
isPrettyFormat ? RED : '',
|
|||
|
isPrettyFormat ? symbols.error : '',
|
|||
|
message,
|
|||
|
'\n',
|
|||
|
isPrettyFormat ? RESET : ''
|
|||
|
].filter(e => !!e)
|
|||
|
|
|||
|
console.error(m.join(' '))
|
|||
|
}
|