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:
authorGar <gar+gh@danger.computer>2022-05-18 23:29:21 +0300
committerLuke Karrys <luke@lukekarrys.com>2022-05-20 00:14:58 +0300
commitf3b0a2407c7e213b1660ef7024c861dcb0eacb50 (patch)
tree10bbcb33ff0b3f5f93f0364bb3a4d9320ca5243b
parent7b2b77adca730e516c1b187092374a01de7f0f56 (diff)
deps: pacote@13.4.1
* pass prefix and workspaces to npm-packlist * add verifySignatures to registry.manifest
-rw-r--r--node_modules/pacote/lib/dir.js4
-rw-r--r--node_modules/pacote/lib/registry.js191
-rw-r--r--node_modules/pacote/package.json6
-rw-r--r--package-lock.json14
-rw-r--r--package.json2
5 files changed, 128 insertions, 89 deletions
diff --git a/node_modules/pacote/lib/dir.js b/node_modules/pacote/lib/dir.js
index 598b029f7..502379810 100644
--- a/node_modules/pacote/lib/dir.js
+++ b/node_modules/pacote/lib/dir.js
@@ -63,10 +63,12 @@ class DirFetcher extends Fetcher {
stream.resolved = this.resolved
stream.integrity = this.integrity
+ const { prefix, workspaces } = this.opts
+
// run the prepare script, get the list of files, and tar it up
// pipe to the stream, and proxy errors the chain.
this[_prepareDir]()
- .then(() => packlist({ path: this.resolved }))
+ .then(() => packlist({ path: this.resolved, prefix, workspaces }))
.then(files => tar.c(tarCreateOptions(this.package), files)
.on('error', er => stream.emit('error', er)).pipe(stream))
.catch(er => stream.emit('error', er))
diff --git a/node_modules/pacote/lib/registry.js b/node_modules/pacote/lib/registry.js
index e8ca16f59..2eb37bcec 100644
--- a/node_modules/pacote/lib/registry.js
+++ b/node_modules/pacote/lib/registry.js
@@ -7,6 +7,7 @@ const npa = require('npm-package-arg')
const rpj = require('read-package-json-fast')
const pickManifest = require('npm-pick-manifest')
const ssri = require('ssri')
+const crypto = require('crypto')
// Corgis are cute. 🐕🐶
const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*'
@@ -14,8 +15,6 @@ const fullDoc = 'application/json'
const fetch = require('npm-registry-fetch')
-// TODO: memoize reg requests, so we don't even have to check cache
-
const _headers = Symbol('_headers')
class RegistryFetcher extends Fetcher {
constructor (spec, opts) {
@@ -39,28 +38,30 @@ class RegistryFetcher extends Fetcher {
this.packumentUrl = removeTrailingSlashes(this.registry) + '/' +
this.spec.escapedName
+ const parsed = new URL(this.registry)
+ const regKey = `//${parsed.host}${parsed.pathname}`
+ // unlike the nerf-darted auth keys, this one does *not* allow a mismatch
+ // of trailing slashes. It must match exactly.
+ if (this.opts[`${regKey}:_keys`]) {
+ this.registryKeys = this.opts[`${regKey}:_keys`]
+ }
+
// XXX pacote <=9 has some logic to ignore opts.resolved if
// the resolved URL doesn't go to the same registry.
// Consider reproducing that here, to throw away this.resolved
// in that case.
}
- resolve () {
- if (this.resolved) {
- return Promise.resolve(this.resolved)
- }
-
- // fetching the manifest sets resolved and (usually) integrity
- return this.manifest().then(() => {
- if (this.resolved) {
- return this.resolved
- }
-
+ async resolve () {
+ // fetching the manifest sets resolved and (if present) integrity
+ await this.manifest()
+ if (!this.resolved) {
throw Object.assign(
new Error('Invalid package manifest: no `dist.tarball` field'),
{ package: this.spec.toString() }
)
- })
+ }
+ return this.resolved
}
[_headers] () {
@@ -87,91 +88,127 @@ class RegistryFetcher extends Fetcher {
// npm-registry-fetch the packument
// set the appropriate header for corgis if fullMetadata isn't set
// return the res.json() promise
- const p = fetch(this.packumentUrl, {
- ...this.opts,
- headers: this[_headers](),
- spec: this.spec,
- // never check integrity for packuments themselves
- integrity: null,
- }).then(res => res.json().then(packument => {
+ try {
+ const res = await fetch(this.packumentUrl, {
+ ...this.opts,
+ headers: this[_headers](),
+ spec: this.spec,
+ // never check integrity for packuments themselves
+ integrity: null,
+ })
+ const packument = await res.json()
packument._cached = res.headers.has('x-local-cache')
packument._contentLength = +res.headers.get('content-length')
if (this.packumentCache) {
this.packumentCache.set(this.packumentUrl, packument)
}
return packument
- })).catch(er => {
+ } catch (err) {
if (this.packumentCache) {
this.packumentCache.delete(this.packumentUrl)
}
- if (er.code === 'E404' && !this.fullMetadata) {
- // possible that corgis are not supported by this registry
- this.fullMetadata = true
- return this.packument()
+ if (err.code !== 'E404' || this.fullMetadata) {
+ throw err
}
- throw er
- })
- if (this.packumentCache) {
- this.packumentCache.set(this.packumentUrl, p)
+ // possible that corgis are not supported by this registry
+ this.fullMetadata = true
+ return this.packument()
}
- return p
}
- manifest () {
+ async manifest () {
if (this.package) {
- return Promise.resolve(this.package)
+ return this.package
}
- return this.packument()
- .then(packument => pickManifest(packument, this.spec.fetchSpec, {
- ...this.opts,
- defaultTag: this.defaultTag,
- before: this.before,
- }) /* XXX add ETARGET and E403 revalidation of cached packuments here */)
- .then(mani => {
- // add _resolved and _integrity from dist object
- const { dist } = mani
- if (dist) {
- this.resolved = mani._resolved = dist.tarball
- mani._from = this.from
- const distIntegrity = dist.integrity ? ssri.parse(dist.integrity)
- : dist.shasum ? ssri.fromHex(dist.shasum, 'sha1', { ...this.opts })
- : null
- if (distIntegrity) {
- if (!this.integrity) {
- this.integrity = distIntegrity
- } else if (!this.integrity.match(distIntegrity)) {
- // only bork if they have algos in common.
- // otherwise we end up breaking if we have saved a sha512
- // previously for the tarball, but the manifest only
- // provides a sha1, which is possible for older publishes.
- // Otherwise, this is almost certainly a case of holding it
- // wrong, and will result in weird or insecure behavior
- // later on when building package tree.
- for (const algo of Object.keys(this.integrity)) {
- if (distIntegrity[algo]) {
- throw Object.assign(new Error(
- `Integrity checksum failed when using ${algo}: ` +
- `wanted ${this.integrity} but got ${distIntegrity}.`
- ), { code: 'EINTEGRITY' })
- }
- }
- // made it this far, the integrity is worthwhile. accept it.
- // the setter here will take care of merging it into what we
- // already had.
- this.integrity = distIntegrity
+ const packument = await this.packument()
+ const mani = await pickManifest(packument, this.spec.fetchSpec, {
+ ...this.opts,
+ defaultTag: this.defaultTag,
+ before: this.before,
+ })
+ /* XXX add ETARGET and E403 revalidation of cached packuments here */
+
+ // add _resolved and _integrity from dist object
+ const { dist } = mani
+ if (dist) {
+ this.resolved = mani._resolved = dist.tarball
+ mani._from = this.from
+ const distIntegrity = dist.integrity ? ssri.parse(dist.integrity)
+ : dist.shasum ? ssri.fromHex(dist.shasum, 'sha1', { ...this.opts })
+ : null
+ if (distIntegrity) {
+ if (this.integrity && !this.integrity.match(distIntegrity)) {
+ // only bork if they have algos in common.
+ // otherwise we end up breaking if we have saved a sha512
+ // previously for the tarball, but the manifest only
+ // provides a sha1, which is possible for older publishes.
+ // Otherwise, this is almost certainly a case of holding it
+ // wrong, and will result in weird or insecure behavior
+ // later on when building package tree.
+ for (const algo of Object.keys(this.integrity)) {
+ if (distIntegrity[algo]) {
+ throw Object.assign(new Error(
+ `Integrity checksum failed when using ${algo}: ` +
+ `wanted ${this.integrity} but got ${distIntegrity}.`
+ ), { code: 'EINTEGRITY' })
}
}
}
- if (this.integrity) {
- mani._integrity = String(this.integrity)
- if (dist.signatures) {
+ // made it this far, the integrity is worthwhile. accept it.
+ // the setter here will take care of merging it into what we already
+ // had.
+ this.integrity = distIntegrity
+ }
+ }
+ if (this.integrity) {
+ 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} ` +
+ `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' })
+ }
+ }
mani._signatures = dist.signatures
}
+ // if no keys, don't set _signatures
+ } else {
+ mani._signatures = dist.signatures
}
- this.package = rpj.normalize(mani)
- return this.package
- })
+ }
+ }
+ this.package = rpj.normalize(mani)
+ return this.package
}
[_tarballFromResolved] () {
diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json
index 2f4323c44..f1a86938f 100644
--- a/node_modules/pacote/package.json
+++ b/node_modules/pacote/package.json
@@ -1,6 +1,6 @@
{
"name": "pacote",
- "version": "13.3.0",
+ "version": "13.4.1",
"description": "JavaScript package downloader",
"author": "GitHub Inc.",
"bin": {
@@ -26,7 +26,7 @@
},
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
- "@npmcli/template-oss": "3.4.3",
+ "@npmcli/template-oss": "3.5.0",
"hosted-git-info": "^5.0.0",
"mutate-fs": "^2.1.1",
"nock": "^13.2.4",
@@ -74,7 +74,7 @@
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
- "version": "3.4.3",
+ "version": "3.5.0",
"windowsCI": false
}
}
diff --git a/package-lock.json b/package-lock.json
index 3154dc554..b5a784cb3 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.3.0",
+ "pacote": "^13.4.1",
"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.3.0",
- "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.3.0.tgz",
- "integrity": "sha512-auhJAUlfC2TALo6I0s1vFoPvVFgWGx+uz/PnIojTTgkGwlK3Np8sGJ0ghfFhiuzJXTZoTycMLk8uLskdntPbDw==",
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.4.1.tgz",
+ "integrity": "sha512-FqlSWlD8n+ejCE17GF/lf0yasztMGFl4UFzYQk5njaK/qPPWfVDWnfQwqmqeXObWLSmIBew+O+CFD24vxkVDjg==",
"inBundle": true,
"dependencies": {
"@npmcli/git": "^3.0.0",
@@ -13877,9 +13877,9 @@
}
},
"pacote": {
- "version": "13.3.0",
- "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.3.0.tgz",
- "integrity": "sha512-auhJAUlfC2TALo6I0s1vFoPvVFgWGx+uz/PnIojTTgkGwlK3Np8sGJ0ghfFhiuzJXTZoTycMLk8uLskdntPbDw==",
+ "version": "13.4.1",
+ "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.4.1.tgz",
+ "integrity": "sha512-FqlSWlD8n+ejCE17GF/lf0yasztMGFl4UFzYQk5njaK/qPPWfVDWnfQwqmqeXObWLSmIBew+O+CFD24vxkVDjg==",
"requires": {
"@npmcli/git": "^3.0.0",
"@npmcli/installed-package-contents": "^1.0.7",
diff --git a/package.json b/package.json
index a2fd510a7..1b0027ba5 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.3.0",
+ "pacote": "^13.4.1",
"parse-conflict-json": "^2.0.2",
"proc-log": "^2.0.1",
"qrcode-terminal": "^0.12.0",