docs: add quixzoom-auth-core product to AAMOS
- Product documentation in docs/products/ - Updated MEMORY.md with product info - quiXzoom Auth Core as AAMOS Identity product
This commit is contained in:
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
import type { ProxyAgentConfigurationInputType } from '../types';
|
||||
declare const _default: (configurationInput?: ProxyAgentConfigurationInputType) => {
|
||||
HTTP_PROXY: string | null;
|
||||
HTTPS_PROXY: string | null;
|
||||
NO_PROXY: string | null;
|
||||
};
|
||||
export default _default;
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const http_1 = __importDefault(require("http"));
|
||||
const https_1 = __importDefault(require("https"));
|
||||
const gte_1 = __importDefault(require("semver/functions/gte"));
|
||||
const Logger_1 = require("../Logger");
|
||||
const classes_1 = require("../classes");
|
||||
const errors_1 = require("../errors");
|
||||
const utilities_1 = require("../utilities");
|
||||
const parseBoolean_1 = require("../utilities/parseBoolean");
|
||||
const createProxyController_1 = __importDefault(require("./createProxyController"));
|
||||
const httpGet = http_1.default.get;
|
||||
const httpRequest = http_1.default.request;
|
||||
const httpsGet = https_1.default.get;
|
||||
const httpsRequest = https_1.default.request;
|
||||
const log = Logger_1.logger.child({
|
||||
namespace: 'createGlobalProxyAgent',
|
||||
});
|
||||
const defaultConfigurationInput = {
|
||||
environmentVariableNamespace: undefined,
|
||||
forceGlobalAgent: undefined,
|
||||
socketConnectionTimeout: 60000,
|
||||
};
|
||||
const createConfiguration = (configurationInput) => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
const environment = process.env;
|
||||
const defaultConfiguration = {
|
||||
environmentVariableNamespace: typeof environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE === 'string' ? environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE : 'GLOBAL_AGENT_',
|
||||
forceGlobalAgent: typeof environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT === 'string' ? (0, parseBoolean_1.parseBoolean)(environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT) : true,
|
||||
socketConnectionTimeout: typeof environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT === 'string' ? Number.parseInt(environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT, 10) : defaultConfigurationInput.socketConnectionTimeout,
|
||||
};
|
||||
return {
|
||||
...defaultConfiguration,
|
||||
...Object.fromEntries(Object.entries(configurationInput).filter(([, v]) => v !== undefined)),
|
||||
};
|
||||
};
|
||||
exports.default = (configurationInput = defaultConfigurationInput) => {
|
||||
var _a, _b, _c;
|
||||
const configuration = createConfiguration(configurationInput);
|
||||
if (configurationInput.logger) {
|
||||
(0, Logger_1.setLogger)(configurationInput.logger);
|
||||
}
|
||||
const proxyController = (0, createProxyController_1.default)();
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
proxyController.HTTP_PROXY = (_a = process.env[configuration.environmentVariableNamespace + 'HTTP_PROXY']) !== null && _a !== void 0 ? _a : null;
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
proxyController.HTTPS_PROXY = (_b = process.env[configuration.environmentVariableNamespace + 'HTTPS_PROXY']) !== null && _b !== void 0 ? _b : null;
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
proxyController.NO_PROXY = (_c = process.env[configuration.environmentVariableNamespace + 'NO_PROXY']) !== null && _c !== void 0 ? _c : null;
|
||||
log.info({
|
||||
configuration,
|
||||
state: proxyController,
|
||||
}, 'global agent has been initialized');
|
||||
const mustUrlUseProxy = (getProxy) => {
|
||||
return (url) => {
|
||||
if (!getProxy()) {
|
||||
return false;
|
||||
}
|
||||
if (!proxyController.NO_PROXY) {
|
||||
return true;
|
||||
}
|
||||
return !(0, utilities_1.isUrlMatchingNoProxy)(url, proxyController.NO_PROXY);
|
||||
};
|
||||
};
|
||||
const getUrlProxy = (getProxy) => {
|
||||
return () => {
|
||||
const proxy = getProxy();
|
||||
if (!proxy) {
|
||||
throw new errors_1.UnexpectedStateError('HTTP(S) proxy must be configured.');
|
||||
}
|
||||
return (0, utilities_1.parseProxyUrl)(proxy);
|
||||
};
|
||||
};
|
||||
const getHttpProxy = () => {
|
||||
return proxyController.HTTP_PROXY;
|
||||
};
|
||||
const BoundHttpProxyAgent = class extends classes_1.HttpProxyAgent {
|
||||
constructor() {
|
||||
super(() => {
|
||||
return Boolean(getHttpProxy());
|
||||
}, mustUrlUseProxy(getHttpProxy), getUrlProxy(getHttpProxy), http_1.default.globalAgent, configuration.socketConnectionTimeout, configuration.ca);
|
||||
}
|
||||
};
|
||||
const httpAgent = new BoundHttpProxyAgent();
|
||||
const getHttpsProxy = () => {
|
||||
var _a;
|
||||
return (_a = proxyController.HTTPS_PROXY) !== null && _a !== void 0 ? _a : proxyController.HTTP_PROXY;
|
||||
};
|
||||
const BoundHttpsProxyAgent = class extends classes_1.HttpsProxyAgent {
|
||||
constructor() {
|
||||
super(() => {
|
||||
return Boolean(getHttpsProxy());
|
||||
}, mustUrlUseProxy(getHttpsProxy), getUrlProxy(getHttpsProxy), https_1.default.globalAgent, configuration.socketConnectionTimeout, configuration.ca);
|
||||
}
|
||||
};
|
||||
const httpsAgent = new BoundHttpsProxyAgent();
|
||||
// Overriding globalAgent was added in v11.7.
|
||||
// @see https://nodejs.org/uk/blog/release/v11.7.0/
|
||||
if ((0, gte_1.default)(process.version, 'v11.7.0')) {
|
||||
// @see https://github.com/facebook/flow/issues/7670
|
||||
// @ts-expect-error Node.js version compatibility
|
||||
http_1.default.globalAgent = httpAgent;
|
||||
// @ts-expect-error Node.js version compatibility
|
||||
https_1.default.globalAgent = httpsAgent;
|
||||
}
|
||||
// The reason this logic is used in addition to overriding http(s).globalAgent
|
||||
// is because there is no guarantee that we set http(s).globalAgent variable
|
||||
// before an instance of http(s).Agent has been already constructed by someone,
|
||||
// e.g. Stripe SDK creates instances of http(s).Agent at the top-level.
|
||||
// @see https://github.com/gajus/global-agent/pull/13
|
||||
//
|
||||
// We still want to override http(s).globalAgent when possible to enable logic
|
||||
// in `bindHttpMethod`.
|
||||
if ((0, gte_1.default)(process.version, 'v10.0.0')) {
|
||||
// @ts-expect-error seems like we are using wrong type for httpAgent
|
||||
http_1.default.get = (0, utilities_1.bindHttpMethod)(httpGet, httpAgent, configuration.forceGlobalAgent);
|
||||
// @ts-expect-error seems like we are using wrong type for httpAgent
|
||||
http_1.default.request = (0, utilities_1.bindHttpMethod)(httpRequest, httpAgent, configuration.forceGlobalAgent);
|
||||
// @ts-expect-error seems like we are using wrong type for httpAgent
|
||||
https_1.default.get = (0, utilities_1.bindHttpMethod)(httpsGet, httpsAgent, configuration.forceGlobalAgent);
|
||||
// @ts-expect-error seems like we are using wrong type for httpAgent
|
||||
https_1.default.request = (0, utilities_1.bindHttpMethod)(httpsRequest, httpsAgent, configuration.forceGlobalAgent);
|
||||
}
|
||||
else {
|
||||
log.warn('attempt to initialize global-agent in unsupported Node.js version was ignored');
|
||||
}
|
||||
return proxyController;
|
||||
};
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Generated
Vendored
+539
@@ -0,0 +1,539 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const http_1 = __importDefault(require("http"));
|
||||
const https_1 = __importDefault(require("https"));
|
||||
const net_1 = __importDefault(require("net"));
|
||||
const vitest_1 = require("vitest");
|
||||
const axios_1 = __importDefault(require("axios"));
|
||||
const get_port_1 = __importDefault(require("get-port"));
|
||||
const got_1 = __importDefault(require("got"));
|
||||
const pem_1 = __importDefault(require("pem"));
|
||||
const request_1 = __importDefault(require("request"));
|
||||
const sinon_1 = require("sinon");
|
||||
const createGlobalProxyAgent_1 = __importDefault(require("./createGlobalProxyAgent"));
|
||||
const defaultHttpAgent = http_1.default.globalAgent;
|
||||
const defaultHttpsAgent = https_1.default.globalAgent;
|
||||
// Backup original value of NODE_TLS_REJECT_UNAUTHORIZED
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
const defaultNodeTlsRejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
||||
let lastPort = 3000;
|
||||
let localProxyServers = [];
|
||||
let localHttpServers = [];
|
||||
let localHttpsServers = [];
|
||||
let generatedCerts = null;
|
||||
const getNextPort = () => {
|
||||
return (0, get_port_1.default)({
|
||||
port: get_port_1.default.makeRange(lastPort++, 3500),
|
||||
});
|
||||
};
|
||||
// Generate self-signed certificates for HTTPS testing
|
||||
const generateCertificates = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (generatedCerts) {
|
||||
resolve(generatedCerts);
|
||||
return;
|
||||
}
|
||||
pem_1.default.createCertificate({ days: 1, selfSigned: true }, (error, keys) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
generatedCerts = { cert: keys.certificate, key: keys.serviceKey };
|
||||
resolve(generatedCerts);
|
||||
});
|
||||
});
|
||||
};
|
||||
(0, vitest_1.beforeAll)(async () => {
|
||||
// Pre-generate certificates
|
||||
await generateCertificates();
|
||||
});
|
||||
(0, vitest_1.beforeEach)(() => {
|
||||
http_1.default.globalAgent = defaultHttpAgent;
|
||||
https_1.default.globalAgent = defaultHttpsAgent;
|
||||
});
|
||||
(0, vitest_1.afterEach)(() => {
|
||||
for (const localProxyServer of localProxyServers) {
|
||||
localProxyServer.stop();
|
||||
}
|
||||
localProxyServers = [];
|
||||
for (const localHttpServer of localHttpServers) {
|
||||
localHttpServer.stop();
|
||||
}
|
||||
localHttpServers = [];
|
||||
for (const localHttpsServer of localHttpsServers) {
|
||||
localHttpsServer.stop();
|
||||
}
|
||||
localHttpsServers = [];
|
||||
// Reset NODE_TLS_REJECT_UNAUTHORIZED to original value
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = defaultNodeTlsRejectUnauthorized;
|
||||
});
|
||||
const createHttpResponseResolver = (resolve) => {
|
||||
return (response) => {
|
||||
let body = '';
|
||||
response.on('data', (data) => {
|
||||
body += data;
|
||||
});
|
||||
response.on('end', () => {
|
||||
if (!response.headers) {
|
||||
throw new Error('response.headers is not defined');
|
||||
}
|
||||
if (!response.statusCode) {
|
||||
throw new Error('response.statusCode is not defined');
|
||||
}
|
||||
resolve({
|
||||
body,
|
||||
headers: response.headers,
|
||||
statusCode: response.statusCode,
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
// Create a local HTTPS server for CONNECT tunnel targets
|
||||
const createHttpsServer = async () => {
|
||||
const port = await getNextPort();
|
||||
const certs = await generateCertificates();
|
||||
const localHttpsServer = await new Promise((resolve) => {
|
||||
const httpsServer = https_1.default.createServer({
|
||||
cert: certs.cert,
|
||||
key: certs.key,
|
||||
}, (request, response) => {
|
||||
response.writeHead(200, { 'content-type': 'text/plain' });
|
||||
response.end('OK');
|
||||
});
|
||||
httpsServer.listen(port, '127.0.0.1', () => {
|
||||
resolve({
|
||||
port,
|
||||
stop: () => {
|
||||
httpsServer.close();
|
||||
},
|
||||
url: 'https://127.0.0.1:' + port,
|
||||
});
|
||||
});
|
||||
});
|
||||
localHttpsServers.push(localHttpsServer);
|
||||
return localHttpsServer;
|
||||
};
|
||||
// Create a simple HTTP proxy server that can handle both HTTP requests and HTTPS CONNECT tunneling
|
||||
const createProxyServer = async (rules) => {
|
||||
const port = await getNextPort();
|
||||
// Create an HTTPS server that the proxy will tunnel to for CONNECT requests
|
||||
const httpsServer = await createHttpsServer();
|
||||
const localProxyServer = await new Promise((resolve) => {
|
||||
const proxyServer = http_1.default.createServer((request, response) => {
|
||||
// Handle regular HTTP proxy requests
|
||||
if (rules === null || rules === void 0 ? void 0 : rules.beforeSendRequest) {
|
||||
const result = rules.beforeSendRequest({
|
||||
requestOptions: {
|
||||
headers: request.headers,
|
||||
},
|
||||
});
|
||||
response.writeHead(result.response.statusCode, result.response.header);
|
||||
response.end(result.response.body);
|
||||
}
|
||||
else {
|
||||
// Default response
|
||||
response.writeHead(200, { 'content-type': 'text/plain' });
|
||||
response.end('OK');
|
||||
}
|
||||
});
|
||||
// Handle CONNECT requests for HTTPS tunneling
|
||||
proxyServer.on('connect', (request, clientSocket, head) => {
|
||||
// Call onConnect hook if provided
|
||||
if (rules === null || rules === void 0 ? void 0 : rules.onConnect) {
|
||||
rules.onConnect(request);
|
||||
}
|
||||
// Connect to the local HTTPS server instead of the requested host
|
||||
const serverSocket = net_1.default.connect(httpsServer.port, '127.0.0.1', () => {
|
||||
clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
|
||||
serverSocket.write(head);
|
||||
serverSocket.pipe(clientSocket);
|
||||
clientSocket.pipe(serverSocket);
|
||||
});
|
||||
serverSocket.on('error', () => {
|
||||
clientSocket.end('HTTP/1.1 500 Internal Server Error\r\n\r\n');
|
||||
});
|
||||
clientSocket.on('error', () => {
|
||||
serverSocket.end();
|
||||
});
|
||||
});
|
||||
proxyServer.listen(port, () => {
|
||||
resolve({
|
||||
httpsServer,
|
||||
port,
|
||||
stop: () => {
|
||||
proxyServer.close();
|
||||
},
|
||||
url: 'http://127.0.0.1:' + port,
|
||||
});
|
||||
});
|
||||
});
|
||||
localProxyServers.push(localProxyServer);
|
||||
return localProxyServer;
|
||||
};
|
||||
const createHttpServer = async () => {
|
||||
const port = await getNextPort();
|
||||
const localHttpServer = await new Promise((resolve) => {
|
||||
const httpServer = http_1.default.createServer((request, response) => {
|
||||
response.end('DIRECT');
|
||||
});
|
||||
httpServer.listen(port, () => {
|
||||
resolve({
|
||||
stop: () => {
|
||||
httpServer.close();
|
||||
},
|
||||
url: 'http://127.0.0.1:' + port,
|
||||
});
|
||||
});
|
||||
});
|
||||
localHttpServers.push(localHttpServer);
|
||||
return localHttpServer;
|
||||
};
|
||||
(0, vitest_1.test)('proxies HTTP request', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await new Promise((resolve) => {
|
||||
http_1.default.get('http://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTP request with proxy-authorization header', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const beforeSendRequest = (0, sinon_1.stub)().callsFake(() => {
|
||||
return {
|
||||
response: {
|
||||
body: 'OK',
|
||||
header: { 'content-type': 'text/plain' },
|
||||
statusCode: 200,
|
||||
},
|
||||
};
|
||||
});
|
||||
const proxyServer = await createProxyServer({
|
||||
beforeSendRequest,
|
||||
});
|
||||
globalProxyAgent.HTTP_PROXY = 'http://foo@127.0.0.1:' + proxyServer.port;
|
||||
const response = await new Promise((resolve) => {
|
||||
http_1.default.get('http://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
(0, vitest_1.expect)(beforeSendRequest.firstCall.args[0].requestOptions.headers['proxy-authorization']).toBe('Basic Zm9v');
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = undefined', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
const { NODE_TLS_REJECT_UNAUTHORIZED, ...restEnvironments } = process.env; // oxlint-disable-line @typescript-eslint/no-unused-vars
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env = restEnvironments;
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.GLOBAL_AGENT_FORCE_GLOBAL_AGENT = 'true';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(true);
|
||||
const response = await new Promise((resolve) => {
|
||||
http_1.default.get('http://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = null', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 'null';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(false);
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = 1', async () => {
|
||||
// @ts-expect-error it is expected as we wanted to set process variable with int
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 1;
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(true);
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = 0', async () => {
|
||||
// @ts-expect-error it is expected as we wanted to set process variable with int
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(false);
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = true', async () => {
|
||||
// @ts-expect-error it is expected as we wanted to set process variable with boolean
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = true;
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(true);
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = false', async () => {
|
||||
// @ts-expect-error it is expected as we wanted to set process variable with boolean
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = false;
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(false);
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = yes', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 'yes';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(true);
|
||||
});
|
||||
(0, vitest_1.test)('Test reject unauthorized variable when NODE_TLS_REJECT_UNAUTHORIZED = no', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 'no';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.getRejectUnauthorized()).toBe(false);
|
||||
});
|
||||
(0, vitest_1.test)('Test addCACertificates and clearCACertificates methods', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.ca).toBe(undefined);
|
||||
globalAgent.addCACertificates(['test-ca-certficate1', 'test-ca-certficate2']);
|
||||
globalAgent.addCACertificates(['test-ca-certficate3']);
|
||||
const result = ['test-ca-certficate1', 'test-ca-certficate2', 'test-ca-certficate3'];
|
||||
(0, vitest_1.expect)(globalAgent.ca.length).toBe(result.length);
|
||||
(0, vitest_1.expect)(JSON.stringify(globalAgent.ca)).toBe(JSON.stringify(result));
|
||||
globalAgent.clearCACertificates();
|
||||
(0, vitest_1.expect)(globalAgent.ca).toBe(undefined);
|
||||
});
|
||||
(0, vitest_1.test)('Test addCACertificates when passed ca is a string', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.ca).toBe(undefined);
|
||||
globalAgent.addCACertificates('test-ca-certficate1');
|
||||
globalAgent.addCACertificates('test-ca-certficate2');
|
||||
(0, vitest_1.expect)(globalAgent.ca).toBe('test-ca-certficate1test-ca-certficate2');
|
||||
const response = await new Promise((resolve) => {
|
||||
https_1.default.get('https://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('Test addCACertificates when input ca is a string and existing ca is array', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)({ ca: ['test-ca'] });
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.ca.length).toBe(1);
|
||||
globalAgent.addCACertificates('test-ca-certficate1');
|
||||
(0, vitest_1.expect)(globalAgent.ca.length).toBe(1);
|
||||
(0, vitest_1.expect)(JSON.stringify(globalAgent.ca)).toBe(JSON.stringify(['test-ca']));
|
||||
const response = await new Promise((resolve) => {
|
||||
https_1.default.get('https://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('Test addCACertificates when input ca array is null or undefined', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.ca).toBe(undefined);
|
||||
globalAgent.addCACertificates(undefined);
|
||||
globalAgent.addCACertificates(null);
|
||||
(0, vitest_1.expect)(globalAgent.ca).toBe(undefined);
|
||||
const response = await new Promise((resolve) => {
|
||||
https_1.default.get('https://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('Test initializing ca certificate property while creating global proxy agent', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)({ ca: ['test-ca'] });
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const globalAgent = https_1.default.globalAgent;
|
||||
(0, vitest_1.expect)(globalAgent.ca.length).toBe(1);
|
||||
globalAgent.addCACertificates(['test-ca1']);
|
||||
(0, vitest_1.expect)(globalAgent.ca.length).toBe(2);
|
||||
(0, vitest_1.expect)(globalAgent.ca[0]).toBe('test-ca');
|
||||
(0, vitest_1.expect)(globalAgent.ca[1]).toBe('test-ca1');
|
||||
const response = await new Promise((resolve) => {
|
||||
https_1.default.get('https://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTPS request', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await new Promise((resolve) => {
|
||||
https_1.default.get('https://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTPS request with proxy-authorization header', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const onConnect = (0, sinon_1.stub)();
|
||||
const proxyServer = await createProxyServer({
|
||||
onConnect,
|
||||
});
|
||||
globalProxyAgent.HTTP_PROXY = 'http://foo@127.0.0.1:' + proxyServer.port;
|
||||
const response = await new Promise((resolve) => {
|
||||
https_1.default.get('https://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
(0, vitest_1.expect)(onConnect.firstCall.args[0].headers['proxy-authorization']).toBe('Basic Zm9v');
|
||||
});
|
||||
(0, vitest_1.test)('does not produce unhandled rejection when cannot connect to proxy', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const port = await getNextPort();
|
||||
globalProxyAgent.HTTP_PROXY = 'http://127.0.0.1:' + port;
|
||||
await (0, vitest_1.expect)((0, got_1.default)('http://127.0.0.1')).rejects.toThrow();
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTPS request with dedicated proxy', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTPS_PROXY = proxyServer.url;
|
||||
const response = await new Promise((resolve) => {
|
||||
https_1.default.get('https://127.0.0.1', createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('ignores dedicated HTTPS proxy for HTTP urls', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
globalProxyAgent.HTTPS_PROXY = 'http://example.org';
|
||||
const response = await new Promise((resolve) => {
|
||||
http_1.default.get('http://127.0.0.1', {}, createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('forwards requests matching NO_PROXY', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
const httpServer = await createHttpServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
globalProxyAgent.NO_PROXY = '127.0.0.1';
|
||||
const response = await new Promise((resolve) => {
|
||||
http_1.default.get(httpServer.url, createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('DIRECT');
|
||||
});
|
||||
(0, vitest_1.test)('forwards requests that go to a socket', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
// not relevant as traffic shouldn't go through proxy
|
||||
globalProxyAgent.HTTP_PROXY = 'localhost:10324';
|
||||
const server = http_1.default.createServer((request, serverResponse) => {
|
||||
serverResponse.writeHead(200);
|
||||
serverResponse.write('OK');
|
||||
serverResponse.end();
|
||||
});
|
||||
server.listen('/tmp/test.sock');
|
||||
const response = await new Promise((resolve) => {
|
||||
http_1.default.get({
|
||||
path: '/endpoint',
|
||||
socketPath: '/tmp/test.sock',
|
||||
}, createHttpResponseResolver(resolve));
|
||||
});
|
||||
server.close();
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTP request (using http.get(host))', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await new Promise((resolve) => {
|
||||
http_1.default.get({
|
||||
host: '127.0.0.1',
|
||||
}, createHttpResponseResolver(resolve));
|
||||
});
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTP request (using got)', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await (0, got_1.default)('http://127.0.0.1');
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTPS request (using got)', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await (0, got_1.default)('https://127.0.0.1');
|
||||
(0, vitest_1.expect)(response.body).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTP request (using axios)', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await axios_1.default.get('http://127.0.0.1');
|
||||
(0, vitest_1.expect)(response.data).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTPS request (using axios)', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await axios_1.default.get('https://127.0.0.1');
|
||||
(0, vitest_1.expect)(response.data).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTP request (using request)', async () => {
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await new Promise((resolve) => {
|
||||
(0, request_1.default)('http://127.0.0.1', (error, requestResponse, body) => {
|
||||
(0, vitest_1.expect)(error).toBe(null);
|
||||
resolve(body);
|
||||
});
|
||||
});
|
||||
(0, vitest_1.expect)(response).toBe('OK');
|
||||
});
|
||||
(0, vitest_1.test)('proxies HTTPS request (using request)', async () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const globalProxyAgent = (0, createGlobalProxyAgent_1.default)();
|
||||
const proxyServer = await createProxyServer();
|
||||
globalProxyAgent.HTTP_PROXY = proxyServer.url;
|
||||
const response = await new Promise((resolve) => {
|
||||
(0, request_1.default)('https://127.0.0.1', (error, requestResponse, body) => {
|
||||
(0, vitest_1.expect)(error).toBe(null);
|
||||
resolve(body);
|
||||
});
|
||||
});
|
||||
(0, vitest_1.expect)(response).toBe('OK');
|
||||
});
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
type ProxyController = {
|
||||
HTTP_PROXY: string | null;
|
||||
HTTPS_PROXY: string | null;
|
||||
NO_PROXY: string | null;
|
||||
};
|
||||
declare const _default: () => ProxyController;
|
||||
export default _default;
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Logger_1 = require("../Logger");
|
||||
const log = Logger_1.logger.child({
|
||||
namespace: 'createProxyController',
|
||||
});
|
||||
const KNOWN_PROPERTY_NAMES = [
|
||||
'HTTP_PROXY',
|
||||
'HTTPS_PROXY',
|
||||
'NO_PROXY',
|
||||
];
|
||||
exports.default = () => {
|
||||
// oxlint-disable-next-line fp/no-proxy
|
||||
return new Proxy({
|
||||
HTTP_PROXY: null,
|
||||
HTTPS_PROXY: null,
|
||||
NO_PROXY: null,
|
||||
}, {
|
||||
set: (subject, name, value) => {
|
||||
if (typeof name !== 'string') {
|
||||
throw new TypeError('Unexpected object member.');
|
||||
}
|
||||
if (!KNOWN_PROPERTY_NAMES.includes(name)) {
|
||||
throw new Error('Cannot set an unmapped property "' + name + '".');
|
||||
}
|
||||
// @ts-expect-error string cannot be used to index an object
|
||||
subject[name] = value;
|
||||
log.info({
|
||||
change: {
|
||||
name,
|
||||
value,
|
||||
},
|
||||
newConfiguration: subject,
|
||||
}, 'configuration changed');
|
||||
return true;
|
||||
},
|
||||
});
|
||||
};
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Generated
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const vitest_1 = require("vitest");
|
||||
const createProxyController_1 = __importDefault(require("./createProxyController"));
|
||||
(0, vitest_1.test)('sets HTTP_PROXY', () => {
|
||||
const globalAgentGlobal = (0, createProxyController_1.default)();
|
||||
globalAgentGlobal.HTTP_PROXY = 'http://127.0.0.1';
|
||||
(0, vitest_1.expect)(globalAgentGlobal.HTTP_PROXY).toBe('http://127.0.0.1');
|
||||
});
|
||||
(0, vitest_1.test)('sets HTTPS_PROXY', () => {
|
||||
const globalAgentGlobal = (0, createProxyController_1.default)();
|
||||
globalAgentGlobal.HTTPS_PROXY = 'http://127.0.0.1';
|
||||
(0, vitest_1.expect)(globalAgentGlobal.HTTPS_PROXY).toBe('http://127.0.0.1');
|
||||
});
|
||||
(0, vitest_1.test)('sets NO_PROXY', () => {
|
||||
const globalAgentGlobal = (0, createProxyController_1.default)();
|
||||
globalAgentGlobal.NO_PROXY = '*';
|
||||
(0, vitest_1.expect)(globalAgentGlobal.NO_PROXY).toBe('*');
|
||||
});
|
||||
(0, vitest_1.test)('throws an error if unknown property is set', () => {
|
||||
const globalAgentGlobal = (0, createProxyController_1.default)();
|
||||
(0, vitest_1.expect)(() => {
|
||||
// @ts-expect-error expected unknown property.
|
||||
globalAgentGlobal.FOO = 'BAR';
|
||||
}).toThrow('Cannot set an unmapped property "FOO".');
|
||||
});
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { default as createGlobalProxyAgent, } from './createGlobalProxyAgent';
|
||||
export { default as createProxyController, } from './createProxyController';
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createProxyController = exports.createGlobalProxyAgent = void 0;
|
||||
var createGlobalProxyAgent_1 = require("./createGlobalProxyAgent");
|
||||
Object.defineProperty(exports, "createGlobalProxyAgent", { enumerable: true, get: function () { return __importDefault(createGlobalProxyAgent_1).default; } });
|
||||
var createProxyController_1 = require("./createProxyController");
|
||||
Object.defineProperty(exports, "createProxyController", { enumerable: true, get: function () { return __importDefault(createProxyController_1).default; } });
|
||||
Reference in New Issue
Block a user