Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node_modules/pacote/lib/fetcher.js52
-rw-r--r--node_modules/pacote/lib/registry.js77
-rw-r--r--node_modules/pacote/lib/remote.js27
-rw-r--r--node_modules/pacote/package.json5
-rw-r--r--package-lock.json14
-rw-r--r--package.json2
6 files changed, 90 insertions, 87 deletions
diff --git a/node_modules/pacote/lib/fetcher.js b/node_modules/pacote/lib/fetcher.js
index d88724c5d..5f93e703b 100644
--- a/node_modules/pacote/lib/fetcher.js
+++ b/node_modules/pacote/lib/fetcher.js
@@ -18,6 +18,7 @@ const removeTrailingSlashes = require('./util/trailing-slashes.js')
const getContents = require('@npmcli/installed-package-contents')
const readPackageJsonFast = require('read-package-json-fast')
const readPackageJson = promisify(require('read-package-json'))
+const Minipass = require('minipass')
// we only change ownership on unix platforms, and only if uid is 0
const selfOwner = process.getuid && process.getuid() === 0 ? {
@@ -105,15 +106,10 @@ class FetcherBase {
this[_readPackageJson] = readPackageJsonFast
}
- // config values: npmjs (default), never, always
- // we don't want to mutate the original value
- if (opts.replaceRegistryHost !== 'never'
- && opts.replaceRegistryHost !== 'always'
- ) {
- this.replaceRegistryHost = 'npmjs'
- } else {
- this.replaceRegistryHost = opts.replaceRegistryHost
- }
+ // rrh is a registry hostname or 'never' or 'always'
+ // defaults to registry.npmjs.org
+ this.replaceRegistryHost = (!opts.replaceRegistryHost || opts.replaceRegistryHost === 'npmjs') ?
+ 'registry.npmjs.org' : opts.replaceRegistryHost
this.defaultTag = opts.defaultTag || 'latest'
this.registry = removeTrailingSlashes(opts.registry || 'https://registry.npmjs.org')
@@ -224,18 +220,18 @@ class FetcherBase {
}
[_istream] (stream) {
- // everyone will need one of these, either for verifying or calculating
- // We always set it, because we have might only have a weak legacy hex
- // sha1 in the packument, and this MAY upgrade it to a stronger algo.
- // If we had an integrity, and it doesn't match, then this does not
- // override that error; the istream will raise the error before it
- // gets to the point of re-setting the integrity.
- const istream = ssri.integrityStream(this.opts)
- istream.on('integrity', i => this.integrity = i)
- stream.on('error', er => istream.emit('error', er))
-
- // if not caching this, just pipe through to the istream and return it
+ // if not caching this, just return it
if (!this.opts.cache || !this[_cacheFetches]) {
+ // instead of creating a new integrity stream, we only piggyback on the
+ // provided stream's events
+ if (stream.hasIntegrityEmitter) {
+ stream.on('integrity', i => this.integrity = i)
+ return stream
+ }
+
+ const istream = ssri.integrityStream(this.opts)
+ istream.on('integrity', i => this.integrity = i)
+ stream.on('error', err => istream.emit('error', err))
return stream.pipe(istream)
}
@@ -243,21 +239,23 @@ class FetcherBase {
// but then pipe from the original tarball stream into the cache as well.
// To do this without losing any data, and since the cacache put stream
// is not a passthrough, we have to pipe from the original stream into
- // the cache AFTER we pipe into the istream. Since the cache stream
+ // the cache AFTER we pipe into the middleStream. Since the cache stream
// has an asynchronous flush to write its contents to disk, we need to
- // defer the istream end until the cache stream ends.
- stream.pipe(istream, { end: false })
+ // defer the middleStream end until the cache stream ends.
+ const middleStream = new Minipass()
+ stream.on('error', err => middleStream.emit('error', err))
+ stream.pipe(middleStream, { end: false })
const cstream = cacache.put.stream(
this.opts.cache,
`pacote:tarball:${this.from}`,
this.opts
)
+ cstream.on('integrity', i => this.integrity = i)
+ cstream.on('error', err => stream.emit('error', err))
stream.pipe(cstream)
- // defer istream end until after cstream
- // cache write errors should not crash the fetch, this is best-effort.
- cstream.promise().catch(() => {}).then(() => istream.end())
- return istream
+ cstream.promise().catch(() => {}).then(() => middleStream.end())
+ return middleStream
}
pickIntegrityAlgorithm () {
diff --git a/node_modules/pacote/lib/registry.js b/node_modules/pacote/lib/registry.js
index 2eb37bcec..c8eb6b029 100644
--- a/node_modules/pacote/lib/registry.js
+++ b/node_modules/pacote/lib/registry.js
@@ -122,11 +122,12 @@ class RegistryFetcher extends Fetcher {
}
const packument = await this.packument()
- const mani = await pickManifest(packument, this.spec.fetchSpec, {
+ let mani = await pickManifest(packument, this.spec.fetchSpec, {
...this.opts,
defaultTag: this.defaultTag,
before: this.before,
})
+ mani = rpj.normalize(mani)
/* XXX add ETARGET and E403 revalidation of cached packuments here */
// add _resolved and _integrity from dist object
@@ -165,49 +166,53 @@ class RegistryFetcher extends Fetcher {
mani._integrity = String(this.integrity)
if (dist.signatures) {
if (this.opts.verifySignatures) {
- if (this.registryKeys) {
- // validate and throw on error, then set _signatures
- const message = `${mani._id}:${mani._integrity}`
- for (const signature of dist.signatures) {
- const publicKey = this.registryKeys.filter(key => (key.keyid === signature.keyid))[0]
- if (!publicKey) {
- throw Object.assign(new Error(
- `${mani._id} has a signature with keyid: ${signature.keyid} ` +
- 'but no corresponding public key can be found.'
- ), { code: 'EMISSINGSIGNATUREKEY' })
- }
- const validPublicKey =
- !publicKey.expires || (Date.parse(publicKey.expires) > Date.now())
- if (!validPublicKey) {
- throw Object.assign(new Error(
- `${mani._id} has a signature with keyid: ${signature.keyid} ` +
+ // validate and throw on error, then set _signatures
+ const message = `${mani._id}:${mani._integrity}`
+ for (const signature of dist.signatures) {
+ const publicKey = this.registryKeys &&
+ this.registryKeys.filter(key => (key.keyid === signature.keyid))[0]
+ if (!publicKey) {
+ throw Object.assign(new Error(
+ `${mani._id} has a registry signature with keyid: ${signature.keyid} ` +
+ 'but no corresponding public key can be found'
+ ), { code: 'EMISSINGSIGNATUREKEY' })
+ }
+ const validPublicKey =
+ !publicKey.expires || (Date.parse(publicKey.expires) > Date.now())
+ if (!validPublicKey) {
+ throw Object.assign(new Error(
+ `${mani._id} has a registry signature with keyid: ${signature.keyid} ` +
`but the corresponding public key has expired ${publicKey.expires}`
- ), { code: 'EEXPIREDSIGNATUREKEY' })
- }
- const verifier = crypto.createVerify('SHA256')
- verifier.write(message)
- verifier.end()
- const valid = verifier.verify(
- publicKey.pemkey,
- signature.sig,
- 'base64'
- )
- if (!valid) {
- throw Object.assign(new Error(
- 'Integrity checksum signature failed: ' +
- `key ${publicKey.keyid} signature ${signature.sig}`
- ), { code: 'EINTEGRITYSIGNATURE' })
- }
+ ), { code: 'EEXPIREDSIGNATUREKEY' })
+ }
+ const verifier = crypto.createVerify('SHA256')
+ verifier.write(message)
+ verifier.end()
+ const valid = verifier.verify(
+ publicKey.pemkey,
+ signature.sig,
+ 'base64'
+ )
+ if (!valid) {
+ throw Object.assign(new Error(
+ `${mani._id} has an invalid registry signature with ` +
+ `keyid: ${publicKey.keyid} and signature: ${signature.sig}`
+ ), {
+ code: 'EINTEGRITYSIGNATURE',
+ keyid: publicKey.keyid,
+ signature: signature.sig,
+ resolved: mani._resolved,
+ integrity: mani._integrity,
+ })
}
- mani._signatures = dist.signatures
}
- // if no keys, don't set _signatures
+ mani._signatures = dist.signatures
} else {
mani._signatures = dist.signatures
}
}
}
- this.package = rpj.normalize(mani)
+ this.package = mani
return this.package
}
diff --git a/node_modules/pacote/lib/remote.js b/node_modules/pacote/lib/remote.js
index 14e687805..6759dbba3 100644
--- a/node_modules/pacote/lib/remote.js
+++ b/node_modules/pacote/lib/remote.js
@@ -4,8 +4,6 @@ const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved')
const pacoteVersion = require('../package.json').version
const fetch = require('npm-registry-fetch')
const Minipass = require('minipass')
-// The default registry URL is a string of great magic.
-const magicHost = 'https://registry.npmjs.org'
const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches')
const _headers = Symbol('_headers')
@@ -14,11 +12,9 @@ class RemoteFetcher extends Fetcher {
super(spec, opts)
this.resolved = this.spec.fetchSpec
const resolvedURL = new URL(this.resolved)
- if (
- (this.replaceRegistryHost === 'npmjs'
- && resolvedURL.origin === magicHost)
- || this.replaceRegistryHost === 'always'
- ) {
+ if (this.replaceRegistryHost !== 'never'
+ && (this.replaceRegistryHost === 'always'
+ || this.replaceRegistryHost === resolvedURL.host)) {
this.resolved = new URL(resolvedURL.pathname, this.registry).href
}
@@ -35,6 +31,8 @@ class RemoteFetcher extends Fetcher {
[_tarballFromResolved] () {
const stream = new Minipass()
+ stream.hasIntegrityEmitter = true
+
const fetchOpts = {
...this.opts,
headers: this[_headers](),
@@ -42,16 +40,19 @@ class RemoteFetcher extends Fetcher {
integrity: this.integrity,
algorithms: [this.pickIntegrityAlgorithm()],
}
- fetch(this.resolved, fetchOpts).then(res => {
- const hash = res.headers.get('x-local-cache-hash')
- if (hash) {
- this.integrity = decodeURIComponent(hash)
- }
+ fetch(this.resolved, fetchOpts).then(res => {
res.body.on('error',
/* istanbul ignore next - exceedingly rare and hard to simulate */
er => stream.emit('error', er)
- ).pipe(stream)
+ )
+
+ res.body.on('integrity', i => {
+ this.integrity = i
+ stream.emit('integrity', i)
+ })
+
+ res.body.pipe(stream)
}).catch(er => stream.emit('error', er))
return stream
diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json
index 5045e3f06..af100fa8d 100644
--- a/node_modules/pacote/package.json
+++ b/node_modules/pacote/package.json
@@ -1,6 +1,6 @@
{
"name": "pacote",
- "version": "13.5.0",
+ "version": "13.6.0",
"description": "JavaScript package downloader",
"author": "GitHub Inc.",
"bin": {
@@ -21,8 +21,7 @@
"template-oss-apply": "template-oss-apply --force"
},
"tap": {
- "timeout": 300,
- "coverage-map": "map.js"
+ "timeout": 300
},
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
diff --git a/package-lock.json b/package-lock.json
index ef669eb3a..5b07bc270 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -138,7 +138,7 @@
"npm-user-validate": "^1.0.1",
"npmlog": "^6.0.2",
"opener": "^1.5.2",
- "pacote": "^13.4.1",
+ "pacote": "^13.6.0",
"parse-conflict-json": "^2.0.2",
"proc-log": "^2.0.1",
"qrcode-terminal": "^0.12.0",
@@ -5547,9 +5547,9 @@
}
},
"node_modules/pacote": {
- "version": "13.5.0",
- "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.5.0.tgz",
- "integrity": "sha512-yekp0ykEsaBH0t0bYA/89R+ywdYV5ZnEdg4YMIfqakSlpIhoF6b8+aEUm8NZpfWRgmy6lxgywcW05URhLRogVQ==",
+ "version": "13.6.0",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.6.0.tgz",
+ "integrity": "sha512-zHmuCwG4+QKnj47LFlW3LmArwKoglx2k5xtADiMCivVWPgNRP5QyLDGOIjGjwOe61lhl1rO63m/VxT16pEHLWg==",
"inBundle": true,
"dependencies": {
"@npmcli/git": "^3.0.0",
@@ -13877,9 +13877,9 @@
}
},
"pacote": {
- "version": "13.5.0",
- "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.5.0.tgz",
- "integrity": "sha512-yekp0ykEsaBH0t0bYA/89R+ywdYV5ZnEdg4YMIfqakSlpIhoF6b8+aEUm8NZpfWRgmy6lxgywcW05URhLRogVQ==",
+ "version": "13.6.0",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.6.0.tgz",
+ "integrity": "sha512-zHmuCwG4+QKnj47LFlW3LmArwKoglx2k5xtADiMCivVWPgNRP5QyLDGOIjGjwOe61lhl1rO63m/VxT16pEHLWg==",
"requires": {
"@npmcli/git": "^3.0.0",
"@npmcli/installed-package-contents": "^1.0.7",
diff --git a/package.json b/package.json
index fb276d359..778cb83af 100644
--- a/package.json
+++ b/package.json
@@ -107,7 +107,7 @@
"npm-user-validate": "^1.0.1",
"npmlog": "^6.0.2",
"opener": "^1.5.2",
- "pacote": "^13.4.1",
+ "pacote": "^13.6.0",
"parse-conflict-json": "^2.0.2",
"proc-log": "^2.0.1",
"qrcode-terminal": "^0.12.0",