diff --git a/node_modules/npm-profile/lib/index.js b/node_modules/npm-profile/lib/index.js index 26f46d27fc7f5..0a8a706f44a01 100644 --- a/node_modules/npm-profile/lib/index.js +++ b/node_modules/npm-profile/lib/index.js @@ -31,6 +31,33 @@ const isValidUrl = u => { } } +// npm's web-login response names the canonical npmjs registry in `doneUrl`, which a proxy/mirror forwards verbatim. +// The poll would then hit npmjs.org instead of the proxy that holds the session, so rewrite only that npmjs host to the configured registry origin, preserving the path prefix and query string. +// Any other done host is left untouched, since a non-npmjs canonical host cannot be inferred here and may be served intentionally. +const CANONICAL_REGISTRY_HOST = 'registry.npmjs.org' + +// doneUrl is already validated by isValidUrl and registry is the origin a prior +// POST /-/v1/login succeeded against, so both parse cleanly here. +const replaceDoneUrlOrigin = (doneUrl, registry) => { + if (!registry) { + return doneUrl + } + const done = new URL(doneUrl) + if (done.hostname !== CANONICAL_REGISTRY_HOST) { + return doneUrl + } + const reg = new URL(registry) + done.protocol = reg.protocol + done.host = reg.host + const prefix = reg.pathname.replace(/\/$/, '') + if (prefix && prefix !== '/' && + done.pathname !== prefix && + !done.pathname.startsWith(prefix + '/')) { + done.pathname = prefix + done.pathname + } + return done.href +} + const webAuth = async (opener, opts, body) => { try { const res = await fetch('/-/v1/login', { @@ -47,7 +74,7 @@ const webAuth = async (opener, opts, body) => { throw new WebLoginInvalidResponse('POST', res, content) } - return await webAuthOpener(opener, loginUrl, doneUrl, opts) + return await webAuthOpener(opener, loginUrl, replaceDoneUrlOrigin(doneUrl, opts.registry), opts) } catch (er) { if ((er.statusCode >= 400 && er.statusCode <= 499) || er.statusCode === 500) { throw new WebLoginNotSupported('POST', { diff --git a/node_modules/npm-profile/package.json b/node_modules/npm-profile/package.json index d0cdfd55b1594..9b4e5a24b57a0 100644 --- a/node_modules/npm-profile/package.json +++ b/node_modules/npm-profile/package.json @@ -1,6 +1,6 @@ { "name": "npm-profile", - "version": "13.0.0", + "version": "13.0.1", "description": "Library for updating an npmjs.com profile", "keywords": [], "author": "GitHub Inc.", @@ -20,7 +20,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^7.0.0", - "@npmcli/template-oss": "5.1.0", + "@npmcli/template-oss": "5.1.1", "nock": "^13.5.6", "tap": "^16.0.1" }, @@ -46,7 +46,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "5.1.0", + "version": "5.1.1", "publish": true } } diff --git a/package-lock.json b/package-lock.json index 7f2f76e4da60e..af92e5ebdee9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -135,7 +135,7 @@ "npm-install-checks": "^9.0.0", "npm-package-arg": "^14.0.0", "npm-pick-manifest": "^12.0.0", - "npm-profile": "^13.0.0", + "npm-profile": "^13.0.1", "npm-registry-fetch": "^20.0.1", "npm-user-validate": "^5.0.0", "p-map": "^7.0.4", @@ -10713,9 +10713,9 @@ } }, "node_modules/npm-profile": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-13.0.0.tgz", - "integrity": "sha512-g+a2FqjE94um8oZvVMnaZCcXJDuKTOpLPVNWDd/xlWQ0FLnUNYzxUsvX55I9vRTDN+6NyC3JebxnXvPyJ81lMA==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-13.0.1.tgz", + "integrity": "sha512-buFDWLwggBSiT5wsjhoSHNvGy+KHaBI5n8ilvSOBkrQUbEsyKYdCV6PloJGFsQ53ZqXCqhwds/8dbvyHQuH3IA==", "inBundle": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index ddc178d28586f..c0c0a5cd5de6e 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "npm-install-checks": "^9.0.0", "npm-package-arg": "^14.0.0", "npm-pick-manifest": "^12.0.0", - "npm-profile": "^13.0.0", + "npm-profile": "^13.0.1", "npm-registry-fetch": "^20.0.1", "npm-user-validate": "^5.0.0", "p-map": "^7.0.4",