[Fleet][EPM] If proxy url has username & password, add to Node's Agent options (#86807)

## Summary

A user received a `407` response when using a `registryProxyUrl` format like `http://user:pass@host:port`

I believe the issue is we're not including the [`auth` property as described in this issue](https://github.com/TooTallNate/node-https-proxy-agent/issues/12#issuecomment-216098644). 

Add tests to ensure it only adds `auth` if username & password are given.

### Checklist
Delete any items that are not applicable to this PR.
- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios

```
  getProxyAgentOptions
    auth property
      present & correct if given username and password
        ✓ proxy url is http (1 ms)
        ✓ proxy url is https
      missing if not given username and password
        ✓ proxy url is http
        ✓ proxy url is https
```
This commit is contained in:
John Schulz 2021-01-19 07:24:11 -05:00 committed by GitHub
parent b00fe2a4e7
commit c52339e606
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 0 deletions

View file

@ -67,4 +67,65 @@ describe('getProxyAgentOptions', () => {
rejectUnauthorized: undefined,
});
});
describe('auth property', () => {
describe('present & correct if given username and password', () => {
test('proxy url is http', () => {
const httpProxyWithAuth = {
proxyUrl: 'http://user:pass@example.com:8080/p/a/t/h',
targetUrl: 'https://epr.elastic.co/',
};
expect(getProxyAgentOptions(httpProxyWithAuth)).toEqual({
auth: 'user:pass',
headers: { Host: 'epr.elastic.co' },
host: 'example.com',
port: 8080,
protocol: 'http:',
rejectUnauthorized: undefined,
});
});
test('proxy url is https', () => {
const httpsProxyWithAuth = {
proxyUrl: 'https://user:pass@example.com:8080/p/a/t/h',
targetUrl: 'https://epr.elastic.co/',
};
expect(getProxyAgentOptions(httpsProxyWithAuth)).toEqual({
auth: 'user:pass',
headers: { Host: 'epr.elastic.co' },
host: 'example.com',
port: 8080,
protocol: 'https:',
rejectUnauthorized: undefined,
});
});
});
describe('missing if not given username and password', () => {
test('proxy url is http', () => {
const httpProxyWithout = {
proxyUrl: 'http://example.com:8080/p/a/t/h',
targetUrl: 'https://epr.elastic.co/',
};
expect(getProxyAgentOptions(httpProxyWithout)).toEqual({
headers: { Host: 'epr.elastic.co' },
host: 'example.com',
port: 8080,
protocol: 'http:',
rejectUnauthorized: undefined,
});
});
test('proxy url is https', () => {
const httpsProxyWithoutAuth = {
proxyUrl: 'https://example.com:8080/p/a/t/h',
targetUrl: 'https://epr.elastic.co/',
};
expect(getProxyAgentOptions(httpsProxyWithoutAuth)).toEqual({
headers: { Host: 'epr.elastic.co' },
host: 'example.com',
port: 8080,
protocol: 'https:',
rejectUnauthorized: undefined,
});
});
});
});
});

View file

@ -38,11 +38,15 @@ export function getProxyAgent(options: GetProxyAgentParams): ProxyAgent {
export function getProxyAgentOptions(options: GetProxyAgentParams): HttpsProxyAgentOptions {
const endpointParsed = new URL(options.targetUrl);
const proxyParsed = new URL(options.proxyUrl);
const authValue = proxyParsed.username
? `${proxyParsed.username}:${proxyParsed.password}`
: undefined;
return {
host: proxyParsed.hostname,
port: Number(proxyParsed.port),
protocol: proxyParsed.protocol,
auth: authValue,
// The headers to send
headers: options.proxyHeaders || {
// the proxied URL's host is put in the header instead of the server's actual host