diff --git a/node_modules/@npmcli/arborist/lib/arborist/reify.js b/node_modules/@npmcli/arborist/lib/arborist/reify.js index 5375b6df4c02c..d916b49c22c01 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/reify.js +++ b/node_modules/@npmcli/arborist/lib/arborist/reify.js @@ -830,9 +830,14 @@ module.exports = cls => class Reifier extends cls { const pname = child.package.name const alias = name !== pname updateDepSpec(pkg, name, (alias ? `npm:${pname}@` : '') + range) - } else if (req.hosted) - updateDepSpec(pkg, name, req.hosted.shortcut({ noCommittish: false })) - else + } else if (req.hosted) { + // save the git+https url if it has auth, otherwise shortcut + const h = req.hosted + const opt = { noCommittish: false } + const save = h.https && h.auth ? `git+${h.https(opt)}` + : h.shortcut(opt) + updateDepSpec(pkg, name, save) + } else updateDepSpec(pkg, name, req.saveSpec) } diff --git a/node_modules/@npmcli/arborist/lib/consistent-resolve.js b/node_modules/@npmcli/arborist/lib/consistent-resolve.js index 5d648de5bd87b..3227648241901 100644 --- a/node_modules/@npmcli/arborist/lib/consistent-resolve.js +++ b/node_modules/@npmcli/arborist/lib/consistent-resolve.js @@ -9,6 +9,7 @@ const consistentResolve = (resolved, fromPath, toPath, relPaths = false) => { return null try { + const hostedOpt = { noCommittish: false } const { fetchSpec, saveSpec, @@ -20,7 +21,9 @@ const consistentResolve = (resolved, fromPath, toPath, relPaths = false) => { const isPath = type === 'file' || type === 'directory' return isPath && !relPaths ? `file:${fetchSpec}` : isPath ? 'file:' + (toPath ? relpath(toPath, fetchSpec) : fetchSpec) - : hosted ? 'git+' + hosted.sshurl({ noCommittish: false }) + : hosted ? `git+${ + hosted.auth ? hosted.https(hostedOpt) : hosted.sshurl(hostedOpt) + }` : type === 'git' ? saveSpec // always return something. 'foo' is interpreted as 'foo@' otherwise. : rawSpec === '' && raw.slice(-1) !== '@' ? raw diff --git a/node_modules/@npmcli/arborist/package.json b/node_modules/@npmcli/arborist/package.json index 1a46daa19082a..fafd1fb0f865f 100644 --- a/node_modules/@npmcli/arborist/package.json +++ b/node_modules/@npmcli/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "2.0.5", + "version": "2.0.6", "description": "Manage node_modules trees", "dependencies": { "@npmcli/installed-package-contents": "^1.0.5", @@ -20,7 +20,7 @@ "npm-package-arg": "^8.1.0", "npm-pick-manifest": "^6.1.0", "npm-registry-fetch": "^9.0.0", - "pacote": "^11.2.1", + "pacote": "^11.2.3", "parse-conflict-json": "^1.1.1", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^1.0.1", diff --git a/node_modules/pacote/lib/fetcher.js b/node_modules/pacote/lib/fetcher.js index a0a1447a31dc4..c4e5852daf8a8 100644 --- a/node_modules/pacote/lib/fetcher.js +++ b/node_modules/pacote/lib/fetcher.js @@ -47,6 +47,8 @@ class FetcherBase { throw new TypeError('options object is required') this.spec = npa(spec, opts.where) + this.allowGitIgnore = !!opts.allowGitIgnore + // a bit redundant because presumably the caller already knows this, // but it makes it easier to not have to keep track of the requested // spec when we're dispatching thousands of these at once, and normalizing @@ -414,7 +416,7 @@ class FetcherBase { const base = basename(entry.path) if (base === '.npmignore') sawIgnores.add(entry.path) - else if (base === '.gitignore') { + else if (base === '.gitignore' && !this.allowGitIgnore) { // rename, but only if there's not already a .npmignore const ni = entry.path.replace(/\.gitignore$/, '.npmignore') if (sawIgnores.has(ni)) diff --git a/node_modules/pacote/lib/git.js b/node_modules/pacote/lib/git.js index 81f7ca2567ce3..406ab5c600221 100644 --- a/node_modules/pacote/lib/git.js +++ b/node_modules/pacote/lib/git.js @@ -24,13 +24,16 @@ const _cloneRepo = Symbol('_cloneRepo') const _setResolvedWithSha = Symbol('_setResolvedWithSha') const _prepareDir = Symbol('_prepareDir') -// get the repository url. prefer ssh, fall back to git:// +// get the repository url. +// prefer https if there's auth, since ssh will drop that. +// otherwise, prefer ssh if available (more secure). // We have to add the git+ back because npa suppresses it. -const repoUrl = (hosted, opts) => - hosted.sshurl && addGitPlus(hosted.sshurl(opts)) || - hosted.https && addGitPlus(hosted.https(opts)) +const repoUrl = (h, opts) => + h.sshurl && !(h.https && h.auth) && addGitPlus(h.sshurl(opts)) || + h.https && addGitPlus(h.https(opts)) -const addGitPlus = url => url && `git+${url}` +// add git+ to the url, but only one time. +const addGitPlus = url => url && `git+${url}`.replace(/^(git\+)+/, 'git+') class GitFetcher extends Fetcher { constructor (spec, opts) { @@ -51,6 +54,11 @@ class GitFetcher extends Fetcher { this.resolvedSha = '' } + // just exposed to make it easier to test all the combinations + static repoUrl (hosted, opts) { + return repoUrl(hosted, opts) + } + get types () { return ['git'] } @@ -69,13 +77,16 @@ class GitFetcher extends Fetcher { } // first try https, since that's faster and passphrase-less for - // public repos. Fall back to SSH to support private repos. - // NB: we always store the SSH url in the 'resolved' field. + // public repos, and supports private repos when auth is provided. + // Fall back to SSH to support private repos + // NB: we always store the https url in resolved field if auth + // is present, otherwise ssh if the hosted type provides it [_resolvedFromHosted] (hosted) { return this[_resolvedFromRepo](hosted.https && hosted.https()) .catch(er => { const ssh = hosted.sshurl && hosted.sshurl() - if (!ssh) + // no fallthrough if we can't fall through or have https auth + if (!ssh || hosted.auth) throw er return this[_resolvedFromRepo](ssh) }) @@ -121,9 +132,11 @@ class GitFetcher extends Fetcher { // either a git url with a hash, or a tarball download URL [_addGitSha] (sha) { if (this.spec.hosted) { - this[_setResolvedWithSha]( - this.spec.hosted.shortcut({ noCommittish: true }) + '#' + sha - ) + const h = this.spec.hosted + const opt = { noCommittish: true } + const base = h.https && h.auth ? h.https(opt) : h.shortcut(opt) + + this[_setResolvedWithSha](`${base}#${sha}`) } else { const u = url.format(new url.URL(`#${sha}`, this.spec.rawSpec)) this[_setResolvedWithSha](url.format(u)) @@ -207,6 +220,7 @@ class GitFetcher extends Fetcher { const nameat = this.spec.name ? `${this.spec.name}@` : '' return new RemoteFetcher(h.tarball({ noCommittish: false }), { ...this.opts, + allowGitIgnore: true, pkgid: `git:${nameat}${this.resolved}`, resolved: this.resolved, integrity: null, // it'll always be different, if we have one @@ -231,14 +245,19 @@ class GitFetcher extends Fetcher { }) } + // first try https, since that's faster and passphrase-less for + // public repos, and supports private repos when auth is provided. + // Fall back to SSH to support private repos + // NB: we always store the https url in resolved field if auth + // is present, otherwise ssh if the hosted type provides it [_cloneHosted] (ref, tmp) { const hosted = this.spec.hosted const https = hosted.https() return this[_cloneRepo](hosted.https({ noCommittish: true }), ref, tmp) .catch(er => { const ssh = hosted.sshurl && hosted.sshurl({ noCommittish: true }) - /* istanbul ignore if - should be covered by the resolve() call */ - if (!ssh) + // no fallthrough if we can't fall through or have https auth + if (!ssh || hosted.auth) throw er return this[_cloneRepo](ssh, ref, tmp) }) diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json index 8de6a07a24258..b55685a48b241 100644 --- a/node_modules/pacote/package.json +++ b/node_modules/pacote/package.json @@ -1,6 +1,6 @@ { "name": "pacote", - "version": "11.2.1", + "version": "11.2.3", "description": "JavaScript package downloader", "author": "Isaac Z. Schlueter (https://izs.me)", "bin": { diff --git a/package-lock.json b/package-lock.json index dec2683b34664..369e67f7bebe5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -354,7 +354,7 @@ ], "license": "Artistic-2.0", "dependencies": { - "@npmcli/arborist": "^2.0.5", + "@npmcli/arborist": "^2.0.6", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^1.2.8", "@npmcli/run-script": "^1.8.1", @@ -682,9 +682,9 @@ } }, "node_modules/@npmcli/arborist": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.0.5.tgz", - "integrity": "sha512-hUXn8XRChDG2Af4NpfPQpMiVbb0/IfhONdX1f1bcxjPXXKV54DMshU25tItcnKIeT5iKF1fqebQg8F3xHb5pCw==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.0.6.tgz", + "integrity": "sha512-3VF6rr3TlGABVZHksblQCcG+aXvsND+pdkUc7vKsKyvY5DB1b6QxXUHwJTPTZz7hKvFM5GQPewp8OxMUdMDMRQ==", "inBundle": true, "dependencies": { "@npmcli/installed-package-contents": "^1.0.5", @@ -704,7 +704,7 @@ "npm-package-arg": "^8.1.0", "npm-pick-manifest": "^6.1.0", "npm-registry-fetch": "^9.0.0", - "pacote": "^11.2.1", + "pacote": "^11.2.3", "parse-conflict-json": "^1.1.1", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^1.0.1", @@ -5347,9 +5347,9 @@ } }, "node_modules/pacote": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.2.1.tgz", - "integrity": "sha512-r5GzxJdmyLdWxP98xYcXinyyj1MIO3wwgJeJpaIIql7rnMBkcLx5k3WKCPpknZU11ybOiXCrIjWuZt3le0Es9A==", + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.2.3.tgz", + "integrity": "sha512-Jphxyk1EjGyLzNwa+MkbcQUQeTIqlKcIoPq0t9ekR9ZxsTGjzhRjz/cOoL9PTVkqAW1FH7qBoVbYL4FqQGNNJg==", "inBundle": true, "dependencies": { "@npmcli/git": "^2.0.1", @@ -9870,9 +9870,9 @@ } }, "@npmcli/arborist": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.0.5.tgz", - "integrity": "sha512-hUXn8XRChDG2Af4NpfPQpMiVbb0/IfhONdX1f1bcxjPXXKV54DMshU25tItcnKIeT5iKF1fqebQg8F3xHb5pCw==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.0.6.tgz", + "integrity": "sha512-3VF6rr3TlGABVZHksblQCcG+aXvsND+pdkUc7vKsKyvY5DB1b6QxXUHwJTPTZz7hKvFM5GQPewp8OxMUdMDMRQ==", "requires": { "@npmcli/installed-package-contents": "^1.0.5", "@npmcli/map-workspaces": "^1.0.1", @@ -9891,7 +9891,7 @@ "npm-package-arg": "^8.1.0", "npm-pick-manifest": "^6.1.0", "npm-registry-fetch": "^9.0.0", - "pacote": "^11.2.1", + "pacote": "^11.2.3", "parse-conflict-json": "^1.1.1", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^1.0.1", @@ -13301,9 +13301,9 @@ } }, "pacote": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.2.1.tgz", - "integrity": "sha512-r5GzxJdmyLdWxP98xYcXinyyj1MIO3wwgJeJpaIIql7rnMBkcLx5k3WKCPpknZU11ybOiXCrIjWuZt3le0Es9A==", + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.2.3.tgz", + "integrity": "sha512-Jphxyk1EjGyLzNwa+MkbcQUQeTIqlKcIoPq0t9ekR9ZxsTGjzhRjz/cOoL9PTVkqAW1FH7qBoVbYL4FqQGNNJg==", "requires": { "@npmcli/git": "^2.0.1", "@npmcli/installed-package-contents": "^1.0.5", diff --git a/package.json b/package.json index d2bbe02cae695..50d1accd273d9 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@npmcli/arborist": "^2.0.5", + "@npmcli/arborist": "^2.0.6", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^1.2.8", "@npmcli/run-script": "^1.8.1",