From 3c7e5eced10a443f2d4cd0a79036cf82bbd08bb0 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Tue, 26 Oct 2021 19:09:46 +0300 Subject: [PATCH] fix: proxy URLs with special chars in credentials (#3925) close #3370 --- .changeset/heavy-dolls-give.md | 5 +++++ packages/npm-registry-agent/src/index.ts | 15 +++++++++++++-- packages/npm-registry-agent/test/index.ts | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 .changeset/heavy-dolls-give.md diff --git a/.changeset/heavy-dolls-give.md b/.changeset/heavy-dolls-give.md new file mode 100644 index 0000000000..f0666a2cb5 --- /dev/null +++ b/.changeset/heavy-dolls-give.md @@ -0,0 +1,5 @@ +--- +"@pnpm/npm-registry-agent": patch +--- + +Proxy URLs with special characters in credentials should work. diff --git a/packages/npm-registry-agent/src/index.ts b/packages/npm-registry-agent/src/index.ts index 776378c505..784bfc46d9 100644 --- a/packages/npm-registry-agent/src/index.ts +++ b/packages/npm-registry-agent/src/index.ts @@ -33,7 +33,7 @@ export default function getAgent (uri: string, opts: AgentOptions) { const key = [ `https:${isHttps.toString()}`, pxuri - ? `proxy:${pxuri.protocol}//${pxuri.host}:${pxuri.port}` + ? `proxy:${pxuri.protocol}//${pxuri.username}:${pxuri.password}@${pxuri.host}:${pxuri.port}` : '>no-proxy<', `local-address:${opts.localAddress ?? '>no-local-address<'}`, `strict-ssl:${isHttps ? Boolean(opts.strictSsl).toString() : '>no-strict-ssl<'}`, @@ -154,7 +154,7 @@ function getProxy ( isHttps: boolean ) { const popts = { - auth: (proxyUrl.username ? (proxyUrl.password ? `${proxyUrl.username}:${proxyUrl.password}` : proxyUrl.username) : undefined), + auth: getAuth(proxyUrl), ca: opts.ca, cert: opts.cert, host: proxyUrl.hostname, @@ -179,3 +179,14 @@ function getProxy ( return new SocksProxyAgent(popts) } } + +function getAuth (user: { username?: string, password?: string }) { + if (!user.username) { + return undefined + } + let auth = user.username + if (user.password) { + auth += `:${user.password}` + } + return decodeURIComponent(auth) +} diff --git a/packages/npm-registry-agent/test/index.ts b/packages/npm-registry-agent/test/index.ts index 44d367e87c..2f374958a8 100644 --- a/packages/npm-registry-agent/test/index.ts +++ b/packages/npm-registry-agent/test/index.ts @@ -86,3 +86,25 @@ test('a socks proxy', () => { type: 5, }) }) + +test('proxy credentials are decoded', () => { + const opts = { + httpsProxy: 'https://use%21r:pas%2As@my.proxy:1234/foo', + ...OPTS, + } + expect(getAgent('https://foo.com/bar', opts)).toEqual({ + __type: 'https-proxy', + auth: 'use!r:pas*s', + ca: 'ca', + cert: 'cert', + host: 'my.proxy', + key: 'key', + localAddress: 'localAddress', + maxSockets: 5, + path: '/foo', + port: '1234', + protocol: 'https:', + rejectUnauthorized: true, + timeout: 6, + }) +})