Skip to content

Commit

Permalink
feat: add --integrity-exclude option (#188)
Browse files Browse the repository at this point in the history
Add a new option available on the CLI as --integrity-exclude which allows user to disable the
--validate-integrity check for specific packages.As an aside, this also formats the table in the
lockfile-lint package's README.

fix #187
  • Loading branch information
ericcornelissen committed Feb 11, 2024
1 parent 7958b39 commit 73cc59d
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 18 deletions.
Expand Up @@ -17,6 +17,15 @@ describe('Validator: Integrity', () => {
expect(() => new ValidateIntegrity()).toThrowError()
})

it('validator should throw an error when excludedPackages is not an array', () => {
const options = {
integrityExclude: 'not-an-array'
}

const validator = new ValidateIntegrity({packages: {}})
expect(() => validator.validate(options)).toThrowError()
})

it('validator should fail if not allowed hash type is used for a resource', () => {
const mockedPackages = {
bolt11: {
Expand All @@ -29,7 +38,8 @@ describe('Validator: Integrity', () => {
type: 'error',
errors: [
{
message: 'detected invalid integrity hash type for package: bolt11\n expected: sha512\n actual: sha1-1ZNEUixLxGSmWnMKxpUAf9tm3Yg=\n',
message:
'detected invalid integrity hash type for package: bolt11\n expected: sha512\n actual: sha1-1ZNEUixLxGSmWnMKxpUAf9tm3Yg=\n',
package: 'bolt11'
}
]
Expand Down Expand Up @@ -71,6 +81,23 @@ describe('Validator: Integrity', () => {
})
})

it('validator should not fail if an excluded package has an invalid integrity hash type', () => {
const mockedPackages = {
typescript: {
integrity: 'sha1-1ZNEUixLxGSmWnMKxpUAf9tm3Yg='
}
}
const options = {
integrityExclude: ['typescript']
}

const validator = new ValidateIntegrity({packages: mockedPackages})
expect(validator.validate(options)).toEqual({
type: 'success',
errors: []
})
})

it('validator should return true for a single package with a valid URL', () => {
const mockedPackages = {
typescript: {
Expand Down
15 changes: 11 additions & 4 deletions packages/lockfile-lint-api/src/validators/ValidateIntegrity.js
Expand Up @@ -13,7 +13,12 @@ module.exports = class ValidateIntegrity {
this.packages = packages
}

validate () {
validate (options) {
const excludedPackages = options && options.integrityExclude ? options.integrityExclude : []
if (!Array.isArray(excludedPackages)) {
throw new Error('excluded packages must be an array')
}

const validationResult = {
type: 'success',
errors: []
Expand All @@ -24,12 +29,14 @@ module.exports = class ValidateIntegrity {
continue
}

if (excludedPackages.includes(packageName)) {
continue
}

try {
if (!isSha512(packageMetadata)) {
validationResult.errors.push({
message: `detected invalid integrity hash type for package: ${packageName}\n expected: sha512\n actual: ${
packageMetadata.integrity
}\n`,
message: `detected invalid integrity hash type for package: ${packageName}\n expected: sha512\n actual: ${packageMetadata.integrity}\n`,
package: packageName
})
}
Expand Down
23 changes: 12 additions & 11 deletions packages/lockfile-lint/README.md
Expand Up @@ -78,17 +78,18 @@ lockfile-lint --path yarn.lock --allowed-hosts yarn --allowed-urls https://githu

| command line argument | description | implemented |
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
| `--path`, `-p` | path to the lockfile but you can also provide a glob matching pattern as long as it isn't expanded by a shell like bash or zsh. If that's the case, you can provide it as a string, for example: `-p '/Users/lirantal/repos/**/package-lock.json'` to match multiple lockfiles ||
| `--type`, `-t` | lockfile type, options are `npm` or `yarn` ||
| `--format`, `-f` | sets what type of report output is desired, one of [ `pretty`, `plain` ] with `plain` removing colors & status symbols from output ||
| `--validate-https`, `-s` | validates the use of HTTPS as protocol schema for all resources in the lockfile ||
| `--allowed-hosts`, `-a` | validates a list 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-urls`, `-u` | allowed URLs (e.g. `https://github.com/some-org/some-repo#some-hash`) ||
| `--empty-hostname`, `-e` | allow empty hostnames, or set to false if you wish for a stricter policy ||
| `--validate-package-names`, `-n` | validates that the resolved URL matches the package name ||
| `--validate-integrity`, `-i` | validates the integrity field is a sha512 hash ||
| `--allowed-package-name-aliases`, `-l` | allow package name aliases to be used by specifying package name and their alias as pairs (e.g: `string-width-cjs:string-width`) ||
| `--path`, `-p` | path to the lockfile but you can also provide a glob matching pattern as long as it isn't expanded by a shell like bash or zsh. If that's the case, you can provide it as a string, for example: `-p '/Users/lirantal/repos/**/package-lock.json'` to match multiple lockfiles ||
| `--type`, `-t` | lockfile type, options are `npm` or `yarn` ||
| `--format`, `-f` | sets what type of report output is desired, one of [ `pretty`, `plain` ] with `plain` removing colors & status symbols from output ||
| `--validate-https`, `-s` | validates the use of HTTPS as protocol schema for all resources in the lockfile ||
| `--allowed-hosts`, `-a` | validates a list 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-urls`, `-u` | allowed URLs (e.g. `https://github.com/some-org/some-repo#some-hash`) ||
| `--empty-hostname`, `-e` | allow empty hostnames, or set to false if you wish for a stricter policy ||
| `--validate-package-names`, `-n` | validates that the resolved URL matches the package name ||
| `--validate-integrity`, `-i` | validates the integrity field is a sha512 hash ||
| `--allowed-package-name-aliases`, `-l` | allow package name aliases to be used by specifying package name and their alias as pairs (e.g: `string-width-cjs:string-width`) ||
| `--integrity-exclude` | exclude packages from the `--validate-integrity` check ||

# File-Based Configuration

Expand Down
3 changes: 2 additions & 1 deletion packages/lockfile-lint/bin/lockfile-lint.js
Expand Up @@ -81,7 +81,8 @@ for (const lockfilePath of lockfilesList) {
emptyHostname: config['empty-hostname'],
allowedHosts: config['allowed-hosts'],
allowedUrls: config['allowed-urls'],
allowedPackageNameAliases: config['allowed-package-name-aliases']
allowedPackageNameAliases: config['allowed-package-name-aliases'],
integrityExclude: config['integrity-exclude']
}
})
}
Expand Down
4 changes: 4 additions & 0 deletions packages/lockfile-lint/src/config.js
Expand Up @@ -85,6 +85,10 @@ module.exports = (argv, exitProcess = false, searchFrom = process.cwd()) => {
type: 'array',
describe: 'validates an alias of package names to be used for resources in the lockfile'
},
'integrity-exclude': {
type: 'array',
describe: 'do not validate integrity for these package'
},
format: {
alias: ['f'],
type: 'string',
Expand Down
2 changes: 1 addition & 1 deletion packages/lockfile-lint/src/validators/index.js
Expand Up @@ -134,5 +134,5 @@ function ValidateIntegrityManager ({path, type, validatorValues, validatorOption
const lockfile = parser.parseSync()
const validator = new ValidateIntegrity({packages: lockfile.object})

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

0 comments on commit 73cc59d

Please sign in to comment.