diff options
-rw-r--r-- | lib/install/read-shrinkwrap.js | 4 | ||||
-rw-r--r-- | lib/shrinkwrap.js | 7 | ||||
-rw-r--r-- | lib/utils/package-integrity.js | 21 | ||||
-rw-r--r-- | test/tap/shrinkwrap-empty-deps.js | 6 | ||||
-rw-r--r-- | test/tap/shrinkwrap-extra-metadata.js | 6 | ||||
-rw-r--r-- | test/tap/shrinkwrap-package-integrity.js | 50 |
6 files changed, 80 insertions, 14 deletions
diff --git a/lib/install/read-shrinkwrap.js b/lib/install/read-shrinkwrap.js index 5a6e4a85a..913c30348 100644 --- a/lib/install/read-shrinkwrap.js +++ b/lib/install/read-shrinkwrap.js @@ -9,7 +9,7 @@ const log = require('npmlog') const parseJSON = require('../utils/parse-json.js') const path = require('path') const PKGLOCK_VERSION = require('../npm.js').lockfileVersion -const ssri = require('ssri') +const pkgSri = require('../utils/package-integrity.js') const readFileAsync = BB.promisify(fs.readFile) @@ -38,7 +38,7 @@ function readShrinkwrap (child, next) { pkgJson && parsed && parsed.packageIntegrity && - !ssri.checkData(pkgJson, parsed.packageIntegrity) + !pkgSri.check(JSON.parse(pkgJson), parsed.packageIntegrity) ) { log.info('read-shrinkwrap', `${name} will be updated because package.json does not match what it was generated against.`) } diff --git a/lib/shrinkwrap.js b/lib/shrinkwrap.js index 77deb1958..82023c6ab 100644 --- a/lib/shrinkwrap.js +++ b/lib/shrinkwrap.js @@ -19,6 +19,7 @@ const move = require('move-concurrently') const npm = require('./npm.js') const packageId = require('./utils/package-id.js') const path = require('path') +const pkgSri = require('./utils/package-integrity.js') const readPackageTree = BB.promisify(require('read-package-tree')) const ssri = require('ssri') const validate = require('aproba') @@ -230,9 +231,7 @@ function updateLockfileMetadata (pkginfo, pkgJson) { function writeMetainfo (pkginfo) { pkginfo.createdWith = `npm@${npm.version}` pkginfo.lockfileVersion = PKGLOCK_VERSION - pkginfo.packageIntegrity = pkgJson && ssri.fromData(pkgJson, { - algorithms: ['sha512'] - }).toString() + pkginfo.packageIntegrity = pkgJson && pkgSri.hash(pkgJson) metainfoWritten = true } return newPkg @@ -245,7 +244,7 @@ function checkPackageFile (dir, name) { ).then((data) => { return { path: file, - data, + data: JSON.parse(data), indent: detectIndent(data).indent || 2 } }).catch({code: 'ENOENT'}, () => {}) diff --git a/lib/utils/package-integrity.js b/lib/utils/package-integrity.js new file mode 100644 index 000000000..f9560d660 --- /dev/null +++ b/lib/utils/package-integrity.js @@ -0,0 +1,21 @@ +'use strict' + +// Utilities for generating and verifying the packageIntegrity field for +// package-lock +// +// Spec: https://github.com/npm/npm/pull/16441 + +const ssri = require('ssri') +const SSRI_OPTS = { + algorithms: ['sha512'] +} + +module.exports.check = check +function check (pkg, integrity) { + return ssri.checkData(JSON.stringify(pkg), integrity, SSRI_OPTS) +} + +module.exports.hash = hash +function hash (pkg) { + return ssri.fromData(JSON.stringify(pkg), SSRI_OPTS).toString() +} diff --git a/test/tap/shrinkwrap-empty-deps.js b/test/tap/shrinkwrap-empty-deps.js index c4c218850..f2761a19b 100644 --- a/test/tap/shrinkwrap-empty-deps.js +++ b/test/tap/shrinkwrap-empty-deps.js @@ -7,8 +7,8 @@ const mr = require('npm-registry-mock') const npm = require('../../lib/npm.js') const osenv = require('osenv') const path = require('path') +const pkgSri = require('../../lib/utils/package-integrity.js') const rimraf = require('rimraf') -const ssri = require('ssri') const test = require('tap').test const pkg = path.resolve(__dirname, 'shrinkwrap-empty-deps') @@ -56,9 +56,7 @@ test('returns a list of removed items', function (t) { 'version': '0.0.0', 'createdWith': `npm@${npm.version}`, 'lockfileVersion': npm.lockfileVersion, - 'packageIntegrity': ssri.fromData(JSON.stringify(json, null, 2), { - algorithms: ['sha512'] - }).toString() + 'packageIntegrity': pkgSri.hash(json) }, JSON.parse(desired), 'shrinkwrap handled empty deps without exploding' diff --git a/test/tap/shrinkwrap-extra-metadata.js b/test/tap/shrinkwrap-extra-metadata.js index 011f7a7a5..5c40faf5c 100644 --- a/test/tap/shrinkwrap-extra-metadata.js +++ b/test/tap/shrinkwrap-extra-metadata.js @@ -7,8 +7,8 @@ const mr = require('npm-registry-mock') const npm = require('../../lib/npm.js') const osenv = require('osenv') const path = require('path') +const pkgSri = require('../../lib/utils/package-integrity.js') const rimraf = require('rimraf') -const ssri = require('ssri') const test = require('tap').test const pkg = path.join(__dirname, path.basename(__filename, '.js')) @@ -54,9 +54,7 @@ test('adds additional metadata fields from the pkglock spec', function (t) { 'version': '0.0.0', 'createdWith': `npm@${npm.version}`, 'lockfileVersion': npm.lockfileVersion, - 'packageIntegrity': ssri.fromData(JSON.stringify(json, null, 2), { - algorithms: ['sha512'] - }).toString() + 'packageIntegrity': pkgSri.hash(json) }, JSON.parse(desired), 'shrinkwrap wrote the expected metadata fields' diff --git a/test/tap/shrinkwrap-package-integrity.js b/test/tap/shrinkwrap-package-integrity.js new file mode 100644 index 000000000..6333757d7 --- /dev/null +++ b/test/tap/shrinkwrap-package-integrity.js @@ -0,0 +1,50 @@ +'use strict' + +const pkgsri = require('../../lib/utils/package-integrity.js') +const ssri = require('ssri') +const test = require('tap').test + +test('generates integrity according to spec', (t) => { + const pkgJson = { + 'name': 'foo', + 'version': '1.0.0', + 'dependencies': { + 'x': '1.0.0' + }, + 'devDependencies': { + 'y': '1.0.0' + }, + 'optionalDependencies': { + 'z': '1.0.0' + } + } + const integrity = pkgsri.hash(pkgJson) + t.ok(integrity && integrity.toString(), 'hash returned') + t.equal( + ssri.parse(integrity).toString(), + integrity, + 'hash is a valid ssri string' + ) + t.ok(pkgsri.check(pkgJson, integrity), 'same-data integrity check succeeds') + t.done() +}) + +test('updates if anything changes in package.json', (t) => { + const pkgJson = { + 'name': 'foo', + 'version': '1.0.0', + 'dependencies': { + 'x': '1.0.0' + }, + 'devDependencies': { + 'y': '1.0.0' + }, + 'optionalDependencies': { + 'z': '1.0.0' + } + } + const sri = pkgsri.hash(pkgJson) + pkgJson.version = '1.2.3' + t.equal(pkgsri.check(pkgJson, sri), false, 'no match after pkgJson change') + t.done() +}) |