Skip to content

Commit

Permalink
feat(emptyhostname): allow empty hostnames in lockfiles (#26)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: lockfile-lint-api internal method API has changed its function signature
to allow receiving a value, and then an options object in a second argument.

Relevant issues:
- #23
- #25
  • Loading branch information
lirantal committed Nov 22, 2019
1 parent abc71fa commit 7d859e1
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 17 deletions.
4 changes: 2 additions & 2 deletions packages/lockfile-lint/README.md
Expand Up @@ -61,7 +61,6 @@ lockfile-lint --path yarn.lock --allowed-hosts yarn github.com --validate-https
- `--allowed-hosts` explicitly set to match github.com as a host and specifies `yarn` as the alias for yarn's official mirror host
- `--allowed-schemes` overrides `validate-https` and so it explicitly allows both `https:` and `git+https:` for the github URL


# CLI command options

| command line argument | description | implemented |
Expand All @@ -70,7 +69,8 @@ lockfile-lint --path yarn.lock --allowed-hosts yarn github.com --validate-https
| `--type`, `-t` | lockfile type, options are `npm` or `yarn` ||
| `--validate-https`, `-s` | validates the use of HTTPS as protocol schema for all resources in the lockfile ||
| `--allowed-hosts`, `-a` | validates a whitelist of allowed hosts to be used for all resources in the lockfile. Supported short-hands aliases are `npm`, `yarn`, and `verdaccio` which will match URLs `https://registry.npmjs.org`, `https://registry.yarnpkg.com` and `https://registry.verdaccio.org` respectively ||
| `--allowed-schemes`, `-o` | allowed [URI schemes](https://tools.ietf.org/html/rfc2396#section-3.1) such as "https:", "http", "git+ssh:", or "git+https:" ||
| `--allowed-schemes`, `-o` | allowed [URI schemes](https://tools.ietf.org/html/rfc2396#section-3.1) such as "https:", "http", "git+ssh:", or "git+https:" ||
| `--empty-hostname`, `-e` | allow empty hostnames, or set to false if you wish for a stricter policy ||
| `--validate-checksum`, `-c` | check that all resources include a checksum | ❌ PRs welcome |
| `--validate-integrity`, `-i` | check that all resources include an integrity field | ❌ PRs welcome |

Expand Down
@@ -0,0 +1,47 @@
{
"name": "asdada",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "^2.1.1"
}
},
"metalsmith-permalinks": {
"version": "github:XhmikosR/metalsmith-permalinks#432843d5823a292b2e47397ba46fd761d03eb9d3",
"from": "github:XhmikosR/metalsmith-permalinks#master",
"requires": {
"debug": "^4.1.1",
"moment": "^2.24.0",
"slugify": "^1.3.5",
"substitute": "https://github.com/segment-boneyard/substitute/archive/0.1.0.tar.gz"
},
"dependencies": {
"substitute": {
"version": "https://github.com/segment-boneyard/substitute/archive/0.1.0.tar.gz",
"integrity": "sha512-2ccHCDdgHt0ZrXAFM/7G/3zEwMhsUfOKfwzSAv2vqO2JQcPpNAlp10e8F5uMa6zpGFYRrdy7BGLvBZsthHrLag=="
}
}
},
"moment": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"slugify": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.3.6.tgz",
"integrity": "sha512-wA9XS475ZmGNlEnYYLPReSfuz/c3VQsEMoU43mi6OnKMCdbnFXd4/Yg7J0lBv8jkPolacMpOrWEaoYxuE1+hoQ=="
}
}
}
37 changes: 31 additions & 6 deletions packages/lockfile-lint/__tests__/main.test.js
Expand Up @@ -83,7 +83,7 @@ describe('Main CLI logic', () => {
const validators = [
{
name: 'validateHosts',
options: ['npm']
values: ['npm']
}
]

Expand All @@ -97,13 +97,38 @@ describe('Main CLI logic', () => {
expect(result.validatorCount).toEqual(1)
expect(result.validatorSuccesses).toEqual(0)
})

test('a failing validator should throw an error if an empty host is not allowed', () => {
const lockfilePath = `${__dirname}/fixtures/package-lock-empty-hostname.json`
const lockfileType = 'npm'
const validators = [
{
name: 'validateHosts',
values: ['npm'],
options: {
emptyHostname: false
}
}
]

const result = main.runValidators({
path: lockfilePath,
type: lockfileType,
validators
})

expect(result.validatorFailures).toEqual(2)
expect(result.validatorCount).toEqual(1)
expect(result.validatorSuccesses).toEqual(0)
})

test('a successful validator should return proper validation object', () => {
const lockfilePath = `${__dirname}/fixtures/yarn-only-https.lock`
const lockfileType = 'yarn'
const validators = [
{
name: 'validateHosts',
options: ['yarn']
values: ['yarn']
}
]

Expand All @@ -126,7 +151,7 @@ describe('Main CLI logic', () => {
const validators = [
{
name: 'validateSchemes',
options: ['https']
values: ['https']
}
]

Expand All @@ -147,7 +172,7 @@ describe('Main CLI logic', () => {
const validators = [
{
name: 'validateSchemes',
options: ['https:', 'git+https:']
values: ['https:', 'git+https:']
}
]

Expand All @@ -168,7 +193,7 @@ describe('Main CLI logic', () => {
const validators = [
{
name: 'validateSchemes',
options: ['https']
values: ['https']
}
]

Expand All @@ -189,7 +214,7 @@ describe('Main CLI logic', () => {
const validators = [
{
name: 'validateSchemes',
options: ['https:', 'git+https:']
values: ['https:', 'git+https:']
}
]

Expand Down
5 changes: 4 additions & 1 deletion packages/lockfile-lint/bin/lockfile-lint.js
Expand Up @@ -18,7 +18,10 @@ for (const [commandArgument, commandValue] of Object.entries(cli)) {
const validatorItem = supportedValidators.get(commandArgument)
validators.push({
name: validatorItem,
options: commandValue
values: commandValue,
options: {
emptyHostname: cli['empty-hostname']
}
})
}
}
Expand Down
6 changes: 6 additions & 0 deletions packages/lockfile-lint/src/cli.js
Expand Up @@ -24,6 +24,12 @@ const argv = yargs
type: 'boolean',
describe: 'validates the use of HTTPS as protocol schema for all resources'
},
e: {
alias: 'empty-hostname',
type: 'boolean',
default: true,
describe: 'allows empty hostnames, or set to false if you wish for a stricter policy'
},
a: {
alias: ['allowed-hosts'],
type: 'array',
Expand Down
1 change: 1 addition & 0 deletions packages/lockfile-lint/src/main.js
Expand Up @@ -35,6 +35,7 @@ function runValidators ({type, path, validators} = {}) {
let validationResult = validatorFunction({
path,
type,
validatorValues: validator.values,
validatorOptions: validator.options
})

Expand Down
16 changes: 8 additions & 8 deletions packages/lockfile-lint/src/validators/index.js
Expand Up @@ -9,9 +9,9 @@ module.exports = {
ValidateSchemeManager
}

function ValidateSchemeManager ({path, type, validatorOptions}) {
function ValidateSchemeManager ({path, type, validatorValues, validatorOptions}) {
debug('validate-scheme-manager')(
`invoked with validator options: ${JSON.stringify(validatorOptions)}`
`invoked with validator options: ${JSON.stringify(validatorValues)}`
)

const options = {
Expand All @@ -23,12 +23,12 @@ function ValidateSchemeManager ({path, type, validatorOptions}) {
const lockfile = parser.parseSync()
const validator = new ValidateScheme({packages: lockfile.object})

return validator.validate(validatorOptions)
return validator.validate(validatorValues)
}

function ValidateHostManager ({path, type, validatorOptions}) {
function ValidateHostManager ({path, type, validatorValues, validatorOptions}) {
debug('validate-host-manager')(
`invoked with validator options: ${JSON.stringify(validatorOptions)}`
`invoked with validator options: ${JSON.stringify(validatorValues)}`
)

const options = {
Expand All @@ -40,12 +40,12 @@ function ValidateHostManager ({path, type, validatorOptions}) {
const lockfile = parser.parseSync()
const validator = new ValidateHost({packages: lockfile.object})

return validator.validate(validatorOptions)
return validator.validate(validatorValues, validatorOptions)
}

function ValidateHttpsManager ({path, type, validatorOptions}) {
function ValidateHttpsManager ({path, type, validatorValues, validatorOptions}) {
debug('validate-host-manager')(
`invoked with validator options: ${JSON.stringify(validatorOptions)}`
`invoked with validator options: ${JSON.stringify(validatorValues)}`
)

const options = {
Expand Down

0 comments on commit 7d859e1

Please sign in to comment.