Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

licensee

Package Overview
Dependencies
Maintainers
2
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

licensee - npm Package Compare versions

Comparing version 6.2.0 to 7.0.0

146

index.js

@@ -5,4 +5,5 @@ module.exports = licensee

var correctLicenseMetadata = require('correct-license-metadata')
var licenseSatisfies = require('spdx-satisfies')
var npmLicenseCorrections = require('npm-license-corrections')
var osi = require('spdx-osi')
var parse = require('spdx-expression-parse')
var parseJSON = require('json-parse-errback')

@@ -14,3 +15,3 @@ var readPackageTree = require('read-package-tree')

var spawn = require('child_process').spawn
var validSPDX = require('spdx-expression-validate')
var spdxWhitelisted = require('spdx-whitelisted')

@@ -21,11 +22,9 @@ function licensee (configuration, path, callback) {

}
if (configuration.license) {
configuration.rule = configuration.license
configuration.licenses = compileLicenseWhitelist(configuration)
if (
configuration.licenses.length === 0 &&
Object.keys(configuration.packages).length === 0
) {
callback(new Error('No licenses or packages whitelisted.'))
} else {
configuration.rule = licenseRuleFromBlueOak(configuration.blueOak)
}
if (!validSPDX(configuration.rule)) {
console.log(configuration.rule)
callback(new Error('Invalid license expression'))
} else {
if (configuration.productionOnly) {

@@ -132,28 +131,11 @@ // In order to ignore devDependencies, we need to read:

isObject(configuration) &&
XOR(
configuration.license,
configuration.blueOak
),
XOR(
( // Validate `license` property.
configuration.hasOwnProperty('license') &&
isString(configuration.license) &&
configuration.license.length > 0
),
( // Validate Blue Oak rating.
configuration.hasOwnProperty('blueOak') &&
isString(configuration.blueOak) &&
configuration.blueOak.length > 0 &&
blueOakList.some(function (element) {
return element.name === configuration.blueOak.toLowerCase()
})
)
) &&
configuration.hasOwnProperty('whitelist')
configuration.hasOwnProperty('licenses') &&
isObject(configuration.licenses) &&
configuration.hasOwnProperty('packages')
? (
// Validate `whitelist` property.
isObject(configuration.whitelist) &&
Object.keys(configuration.whitelist)
// Validate `packages` property.
isObject(configuration.packages) &&
Object.keys(configuration.packages)
.every(function (key) {
return isString(configuration.whitelist[key])
return isString(configuration.packages[key])
})

@@ -164,6 +146,2 @@ ) : true

function XOR (a, b) {
return (a || b) && !(a && b)
}
function isObject (argument) {

@@ -222,4 +200,15 @@ return typeof argument === 'object'

function resultForPackage (configuration, tree) {
var rule = configuration.rule
var whitelist = configuration.whitelist || {}
var licenseWhitelist = (configuration.licenses || [])
.reduce(function (whitelist, element) {
try {
var parsed = parse(element)
if (parsed.hasOwnProperty('conjunction')) {
throw new Error('Cannot match against "' + JSON.stringify(element) + '".')
}
return whitelist.concat(parsed)
} catch (e) {
return whitelist
}
}, [])
var packageWhitelist = configuration.packages || {}
var result = {

@@ -291,30 +280,39 @@ name: tree.package.name,

// Check if whitelisted.
var whitelisted = Object.keys(whitelist).some(function (name) {
return (
result.name === name &&
satisfies(result.version, whitelist[name]) === true
)
})
if (whitelisted) {
result.approved = false
var packageWhitelisted = Object.keys(packageWhitelist)
.some(function (name) {
return (
result.name === name &&
satisfies(result.version, packageWhitelist[name]) === true
)
})
if (packageWhitelisted) {
result.approved = true
result.whitelisted = true
result.package = true
return result
}
if (!result.license || typeof result.license !== 'string') {
return result
}
var validSPDX = true
var parsed
try {
parsed = parse(result.license)
} catch (e) {
validSPDX = false
}
// Check against licensing rule.
var matchesRule = (
rule &&
validSPDX(rule) &&
result.license &&
typeof result.license === 'string' &&
validSPDX(result.license) &&
licenseSatisfies(result.license, rule)
var licenseWhitelisted = (
validSPDX &&
spdxWhitelisted(parsed, licenseWhitelist)
)
if (matchesRule) {
if (licenseWhitelisted) {
result.approved = true
result.rule = true
} else {
result.approved = false
result.license = true
}
return result

@@ -352,3 +350,3 @@ }

function licenseRuleFromBlueOak (rating) {
function licensesFromBlueOak (rating) {
rating = rating.toLowerCase()

@@ -360,7 +358,29 @@ var ids = []

element.licenses.forEach(function (license) {
if (validSPDX(license.id)) ids.push(license.id)
try {
parse(license.id)
ids.push(license.id)
} catch (e) {
// pass
}
})
if (rating === element.name) break
}
return '(' + ids.join(' OR ') + ')'
return ids
}
function compileLicenseWhitelist (configuration) {
var licenses = configuration.licenses
var whitelist = []
var spdx = licenses.spdx
if (spdx) pushMissing(spdx, whitelist)
var blueOak = licenses.blueOak
if (blueOak) pushMissing(licensesFromBlueOak(blueOak), whitelist)
if (licenses.osi) pushMissing(osi, whitelist)
return whitelist
}
function pushMissing (source, sink) {
source.forEach(function (element) {
if (sink.indexOf(element) === -1) sink.push(element)
})
}
{
"name": "licensee",
"description": "check dependency licenses against rules",
"version": "6.2.0",
"version": "7.0.0",
"author": "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com/)",

@@ -20,4 +20,6 @@ "contributors": [

"simple-concat": "^1.0.0",
"spdx-expression-parse": "^3.0.0",
"spdx-expression-validate": "^2.0.0",
"spdx-satisfies": "^5.0.0"
"spdx-osi": "^3.0.0",
"spdx-whitelisted": "^1.0.0"
},

@@ -24,0 +26,0 @@ "bin": "./licensee",

@@ -15,4 +15,11 @@ Check npm package dependency license metadata against rules.

{
"license": "(MIT OR BSD-2-Clause OR BSD-3-Clause OR Apache-2.0)",
"whitelist": {
"licenses": {
"spdx": [
"MIT",
"BSD-2-Clause",
"BSD-3-Clause",
"Apache-2.0"
]
},
"packages": {
"optimist": "<=0.6.1"

@@ -29,14 +36,16 @@ },

The `license` property is an SPDX license expression that
[spdx-expression-parse][parse] can parse. Any package with [standard
license metadata][metadata] that satisfies the SPDX license expression
according to [spdx-satisfies][satisfies] will not cause an error.
The `licenses` object adds licenses to a whitelist.
Any package with [standard license metadata][metadata]
that satisfies that whitelist according to
[spdx-whitelisted][whitelisted] will not cause an error.
[parse]: https://www.npmjs.com/package/spdx-expression-parse
[satisfies]: https://www.npmjs.com/package/spdx-satisfies
[whitelisted]: https://www.npmjs.com/package/spdx-whitelisted
Instead of a `license` property, you can specify a minimum
Blue Oak Council [license rating]---lead, bronze, silver, or
gold---from which `licensee` will generate a rule:
Instead of whitelisting each license by SPDX identifier,
you can whitelist categories of licenses.
You can specify a minimum Blue Oak Council [license
rating]---lead, bronze, silver, or gold---like so:
[license rating]: https://blueoakcouncil.org/license

@@ -46,18 +55,45 @@

{
"blueOak": "bronze"
"licenses": {
"blueOak": "bronze"
}
}
```
The `whitelist` is a map from package name to a [node-semver][semver]
Semantic Versioning range. Packages whose license metadata don't match
the SPDX license expression in `license` but have a name and version
described in `whitelist` will not cause an error.
You can also whitelist all [OSI]-approved licenses:
[osi]: https://opensource.org
```json
{
"licenses": {
"osi": true
}
}
```
All of these can be combined:
```json
{
"licenses": {
"spdx": ["CC-BY-4.0"],
"blueOak": "gold",
"osi": true
}
}
```
The `packages` property is a map from package name to a
[node-semver][semver] Semantic Versioning range. Packages whose
license metadata don't match the SPDX license expression in
`licenses` but have a name and version described in `packages`
will not cause an error.
[metadata]: https://docs.npmjs.com/files/package.json#license
[semver]: https://www.npmjs.com/package/semver
The `corrections` flag toggles community corrections to npm package
license metadata. When enabled, `licensee` will check `license` and
`whitelist` against `license` values from [npm-license-corrections]
when available, and also use [correct-license-metadata] to try to
The `corrections` flag toggles community corrections to npm
package license metadata. When enabled, `licensee` will check
against `license` values from [npm-license-corrections] when
available, and also use [correct-license-metadata] to try to
correct old-style `licenses` arrays and other unambiguous, but

@@ -64,0 +100,0 @@ invalid, metadata.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc