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:
+46
@@ -0,0 +1,46 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import type * as http from 'http';
|
||||
import type * as https from 'https';
|
||||
import type { AgentType, ConnectionCallbackType, ConnectionConfigurationType, GetUrlProxyMethodType, IsProxyConfiguredMethodType, MustUrlUseProxyMethodType, ProtocolType } from '../types';
|
||||
type AgentRequestOptions = {
|
||||
host?: string;
|
||||
path?: string;
|
||||
port: number;
|
||||
};
|
||||
type HttpRequestOptions = AgentRequestOptions & Omit<http.RequestOptions, keyof AgentRequestOptions> & {
|
||||
secureEndpoint: false;
|
||||
};
|
||||
type HttpsRequestOptions = AgentRequestOptions & Omit<https.RequestOptions, keyof AgentRequestOptions> & {
|
||||
secureEndpoint: true;
|
||||
};
|
||||
type RequestOptions = HttpRequestOptions | HttpsRequestOptions;
|
||||
declare abstract class Agent {
|
||||
defaultPort: number;
|
||||
protocol: ProtocolType;
|
||||
fallbackAgent: AgentType;
|
||||
isProxyConfigured: IsProxyConfiguredMethodType;
|
||||
mustUrlUseProxy: MustUrlUseProxyMethodType;
|
||||
getUrlProxy: GetUrlProxyMethodType;
|
||||
socketConnectionTimeout: number;
|
||||
ca: string[] | string | undefined;
|
||||
constructor(isProxyConfigured: IsProxyConfiguredMethodType, mustUrlUseProxy: MustUrlUseProxyMethodType, getUrlProxy: GetUrlProxyMethodType, fallbackAgent: AgentType, socketConnectionTimeout: number, ca: string[] | string | undefined);
|
||||
/**
|
||||
* This method can be used to append new ca certificates to existing ca certificates
|
||||
*
|
||||
* @param {string[] | string} ca a ca certificate or an array of ca certificates
|
||||
*/
|
||||
addCACertificates(ca: string[] | string): void;
|
||||
/**
|
||||
* This method clears existing CA Certificates.
|
||||
* It sets ca to undefined
|
||||
*/
|
||||
clearCACertificates(): void;
|
||||
/**
|
||||
* Evaluate value for tls reject unauthorized variable
|
||||
*/
|
||||
getRejectUnauthorized(): boolean;
|
||||
abstract createConnection(configuration: ConnectionConfigurationType, callback: ConnectionCallbackType): void;
|
||||
addRequest(request: http.ClientRequest, configuration: RequestOptions): void;
|
||||
}
|
||||
export default Agent;
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const net_1 = __importDefault(require("net"));
|
||||
const serialize_error_1 = require("serialize-error");
|
||||
const Logger_1 = require("../Logger");
|
||||
const log = Logger_1.logger.child({
|
||||
namespace: 'Agent',
|
||||
});
|
||||
let requestId = 0;
|
||||
class Agent {
|
||||
constructor(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca) {
|
||||
this.fallbackAgent = fallbackAgent;
|
||||
this.isProxyConfigured = isProxyConfigured;
|
||||
this.mustUrlUseProxy = mustUrlUseProxy;
|
||||
this.getUrlProxy = getUrlProxy;
|
||||
this.socketConnectionTimeout = socketConnectionTimeout;
|
||||
this.ca = ca;
|
||||
}
|
||||
/**
|
||||
* This method can be used to append new ca certificates to existing ca certificates
|
||||
*
|
||||
* @param {string[] | string} ca a ca certificate or an array of ca certificates
|
||||
*/
|
||||
addCACertificates(ca) {
|
||||
if (!ca) {
|
||||
log.error('Invalid input ca certificate');
|
||||
}
|
||||
else if (this.ca) {
|
||||
if (typeof ca === typeof this.ca) {
|
||||
// concat valid ca certificates with the existing certificates,
|
||||
if (typeof this.ca === 'string') {
|
||||
this.ca = this.ca.concat(ca);
|
||||
}
|
||||
else {
|
||||
this.ca = this.ca.concat(ca);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.error('Input ca certificate type mismatched with existing ca certificate type');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.ca = ca;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This method clears existing CA Certificates.
|
||||
* It sets ca to undefined
|
||||
*/
|
||||
clearCACertificates() {
|
||||
this.ca = undefined;
|
||||
}
|
||||
/**
|
||||
* Evaluate value for tls reject unauthorized variable
|
||||
*/
|
||||
getRejectUnauthorized() {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
const rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
||||
let returnValue = true;
|
||||
if (typeof rejectUnauthorized === 'boolean') {
|
||||
returnValue = rejectUnauthorized;
|
||||
}
|
||||
else if (typeof rejectUnauthorized === 'number') {
|
||||
returnValue = rejectUnauthorized === 1;
|
||||
}
|
||||
else if (typeof rejectUnauthorized === 'string') {
|
||||
returnValue = ['true', 't', 'yes', 'y', 'on', '1'].includes(rejectUnauthorized.trim().toLowerCase());
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
addRequest(request, configuration) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h;
|
||||
let requestUrl;
|
||||
// It is possible that addRequest was constructed for a proxied request already, e.g.
|
||||
// "request" package does this when it detects that a proxy should be used
|
||||
// https://github.com/request/request/blob/212570b6971a732b8dd9f3c73354bcdda158a737/request.js#L402
|
||||
// https://gist.github.com/gajus/e2074cd3b747864ffeaabbd530d30218
|
||||
if ((_a = request.path.startsWith('http://')) !== null && _a !== void 0 ? _a : request.path.startsWith('https://')) {
|
||||
requestUrl = request.path;
|
||||
}
|
||||
else if (request.method === 'CONNECT') {
|
||||
requestUrl = 'https://' + request.path;
|
||||
}
|
||||
else {
|
||||
requestUrl = this.protocol + '//' + ((_b = configuration.hostname) !== null && _b !== void 0 ? _b : configuration.host) + (configuration.port === 80 || configuration.port === 443 ? '' : ':' + configuration.port) + request.path;
|
||||
}
|
||||
// If a request should go to a local socket, proxying it through an HTTP
|
||||
// server does not make sense as the information about the target socket
|
||||
// will be lost and the proxy won't be able to correctly handle the request.
|
||||
if (configuration.socketPath) {
|
||||
log.trace({
|
||||
destination: configuration.socketPath,
|
||||
}, 'not proxying request; destination is a socket');
|
||||
// @ts-expect-error seems like we are using wrong type for fallbackAgent.
|
||||
this.fallbackAgent.addRequest(request, configuration);
|
||||
return;
|
||||
}
|
||||
if (!this.isProxyConfigured()) {
|
||||
log.trace({
|
||||
destination: requestUrl,
|
||||
}, 'not proxying request; GLOBAL_AGENT.HTTP_PROXY is not configured');
|
||||
// @ts-expect-error seems like we are using wrong type for fallbackAgent.
|
||||
this.fallbackAgent.addRequest(request, configuration);
|
||||
return;
|
||||
}
|
||||
if (!this.mustUrlUseProxy(requestUrl)) {
|
||||
log.trace({
|
||||
destination: requestUrl,
|
||||
}, 'not proxying request; url matches GLOBAL_AGENT.NO_PROXY');
|
||||
// @ts-expect-error seems like we are using wrong type for fallbackAgent.
|
||||
this.fallbackAgent.addRequest(request, configuration);
|
||||
return;
|
||||
}
|
||||
const currentRequestId = requestId++;
|
||||
const proxy = this.getUrlProxy(requestUrl);
|
||||
if (this.protocol === 'http:') {
|
||||
request.path = requestUrl;
|
||||
if (proxy.authorization) {
|
||||
request.setHeader('proxy-authorization', 'Basic ' + Buffer.from(proxy.authorization).toString('base64'));
|
||||
}
|
||||
}
|
||||
log.trace({
|
||||
destination: requestUrl,
|
||||
proxy: 'http://' + proxy.hostname + ':' + proxy.port,
|
||||
requestId: currentRequestId,
|
||||
}, 'proxying request');
|
||||
request.on('error', (error) => {
|
||||
log.error({
|
||||
error: (0, serialize_error_1.serializeError)(error),
|
||||
}, 'request error');
|
||||
});
|
||||
request.once('response', (response) => {
|
||||
log.trace({
|
||||
headers: response.headers,
|
||||
requestId: currentRequestId,
|
||||
statusCode: response.statusCode,
|
||||
}, 'proxying response');
|
||||
});
|
||||
request.shouldKeepAlive = false;
|
||||
const connectionConfiguration = {
|
||||
host: (_d = (_c = configuration.hostname) !== null && _c !== void 0 ? _c : configuration.host) !== null && _d !== void 0 ? _d : '',
|
||||
port: (_e = configuration.port) !== null && _e !== void 0 ? _e : 80,
|
||||
proxy,
|
||||
tls: {},
|
||||
};
|
||||
// add optional tls options for https requests.
|
||||
// @see https://nodejs.org/docs/latest-v12.x/api/https.html#https_https_request_url_options_callback :
|
||||
// > The following additional options from tls.connect()
|
||||
// > - https://nodejs.org/docs/latest-v12.x/api/tls.html#tls_tls_connect_options_callback -
|
||||
// > are also accepted:
|
||||
// > ca, cert, ciphers, clientCertEngine, crl, dhparam, ecdhCurve, honorCipherOrder,
|
||||
// > key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext.
|
||||
if (configuration.secureEndpoint) {
|
||||
// Determine servername - Node.js doesn't allow IP addresses as servername
|
||||
const host = (_f = configuration.servername) !== null && _f !== void 0 ? _f : connectionConfiguration.host;
|
||||
const servername = net_1.default.isIP(host) ? undefined : host;
|
||||
connectionConfiguration.tls = {
|
||||
ca: (_g = configuration.ca) !== null && _g !== void 0 ? _g : this.ca,
|
||||
cert: configuration.cert,
|
||||
ciphers: configuration.ciphers,
|
||||
clientCertEngine: configuration.clientCertEngine,
|
||||
crl: configuration.crl,
|
||||
dhparam: configuration.dhparam,
|
||||
ecdhCurve: configuration.ecdhCurve,
|
||||
honorCipherOrder: configuration.honorCipherOrder,
|
||||
key: configuration.key,
|
||||
passphrase: configuration.passphrase,
|
||||
pfx: configuration.pfx,
|
||||
rejectUnauthorized: (_h = configuration.rejectUnauthorized) !== null && _h !== void 0 ? _h : this.getRejectUnauthorized(),
|
||||
secureOptions: configuration.secureOptions,
|
||||
secureProtocol: configuration.secureProtocol,
|
||||
servername,
|
||||
sessionIdContext: configuration.sessionIdContext,
|
||||
};
|
||||
}
|
||||
this.createConnection(connectionConfiguration, (error, socket) => {
|
||||
log.trace({
|
||||
target: connectionConfiguration,
|
||||
}, 'connecting');
|
||||
// @see https://github.com/nodejs/node/issues/5757#issuecomment-305969057
|
||||
if (socket) {
|
||||
socket.setTimeout(this.socketConnectionTimeout, () => {
|
||||
socket.destroy();
|
||||
});
|
||||
socket.once('connect', () => {
|
||||
log.trace({
|
||||
target: connectionConfiguration,
|
||||
}, 'connected');
|
||||
socket.setTimeout(0);
|
||||
});
|
||||
socket.once('secureConnect', () => {
|
||||
log.trace({
|
||||
target: connectionConfiguration,
|
||||
}, 'connected (secure)');
|
||||
socket.setTimeout(0);
|
||||
});
|
||||
}
|
||||
if (error) {
|
||||
request.emit('error', error);
|
||||
}
|
||||
else if (socket) {
|
||||
log.debug('created socket');
|
||||
socket.on('error', (socketError) => {
|
||||
log.error({
|
||||
error: (0, serialize_error_1.serializeError)(socketError),
|
||||
}, 'socket error');
|
||||
});
|
||||
request.onSocket(socket);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.default = Agent;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { AgentType, ConnectionCallbackType, ConnectionConfigurationType, GetUrlProxyMethodType, IsProxyConfiguredMethodType, MustUrlUseProxyMethodType } from '../types';
|
||||
import Agent from './Agent';
|
||||
declare class HttpProxyAgent extends Agent {
|
||||
constructor(isProxyConfigured: IsProxyConfiguredMethodType, mustUrlUseProxy: MustUrlUseProxyMethodType, getUrlProxy: GetUrlProxyMethodType, fallbackAgent: AgentType, socketConnectionTimeout: number, ca: string[] | string | undefined);
|
||||
createConnection(configuration: ConnectionConfigurationType, callback: ConnectionCallbackType): void;
|
||||
}
|
||||
export default HttpProxyAgent;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const net_1 = __importDefault(require("net"));
|
||||
const Agent_1 = __importDefault(require("./Agent"));
|
||||
class HttpProxyAgent extends Agent_1.default {
|
||||
// @see https://github.com/sindresorhus/eslint-plugin-unicorn/issues/169#issuecomment-486980290
|
||||
constructor(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca) {
|
||||
super(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca);
|
||||
this.protocol = 'http:';
|
||||
this.defaultPort = 80;
|
||||
}
|
||||
createConnection(configuration, callback) {
|
||||
const socket = net_1.default.connect(configuration.proxy.port, configuration.proxy.hostname);
|
||||
callback(null, socket);
|
||||
}
|
||||
}
|
||||
exports.default = HttpProxyAgent;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { AgentType, ConnectionCallbackType, ConnectionConfigurationType, GetUrlProxyMethodType, IsProxyConfiguredMethodType, MustUrlUseProxyMethodType } from '../types';
|
||||
import Agent from './Agent';
|
||||
declare class HttpsProxyAgent extends Agent {
|
||||
constructor(isProxyConfigured: IsProxyConfiguredMethodType, mustUrlUseProxy: MustUrlUseProxyMethodType, getUrlProxy: GetUrlProxyMethodType, fallbackAgent: AgentType, socketConnectionTimeout: number, ca: string[] | string | undefined);
|
||||
createConnection(configuration: ConnectionConfigurationType, callback: ConnectionCallbackType): void;
|
||||
}
|
||||
export default HttpsProxyAgent;
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const net_1 = __importDefault(require("net"));
|
||||
const tls_1 = __importDefault(require("tls"));
|
||||
const Agent_1 = __importDefault(require("./Agent"));
|
||||
class HttpsProxyAgent extends Agent_1.default {
|
||||
constructor(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca) {
|
||||
super(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca);
|
||||
this.protocol = 'https:';
|
||||
this.defaultPort = 443;
|
||||
}
|
||||
createConnection(configuration, callback) {
|
||||
const socket = net_1.default.connect(configuration.proxy.port, configuration.proxy.hostname);
|
||||
socket.on('error', (error) => {
|
||||
callback(error);
|
||||
});
|
||||
socket.once('data', (data) => {
|
||||
var _a;
|
||||
// Proxies with HTTPS as protocal are not allowed by parseProxyUrl(), so it should be safe to assume that the response is plain text
|
||||
const statusLine = data.toString().split('\r\n')[0];
|
||||
const statusLineExp = /^HTTP\/(\d)\.(\d) (\d{3}) ?(.*)$/;
|
||||
const statusCode = (_a = statusLineExp.exec(statusLine)) === null || _a === void 0 ? void 0 : _a[3];
|
||||
if (typeof statusCode === 'string' && Number(statusCode) >= 400) {
|
||||
const error = new Error(`Proxy server refused connecting to '${configuration.host}:${configuration.port}' (${statusLine})`);
|
||||
socket.destroy();
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
const secureSocket = tls_1.default.connect({
|
||||
...configuration.tls,
|
||||
socket,
|
||||
});
|
||||
callback(null, secureSocket);
|
||||
});
|
||||
let connectMessage = '';
|
||||
connectMessage += 'CONNECT ' + configuration.host + ':' + configuration.port + ' HTTP/1.1\r\n';
|
||||
connectMessage += 'Host: ' + configuration.host + ':' + configuration.port + '\r\n';
|
||||
if (configuration.proxy.authorization) {
|
||||
connectMessage += 'Proxy-Authorization: Basic ' + Buffer.from(configuration.proxy.authorization).toString('base64') + '\r\n';
|
||||
}
|
||||
connectMessage += '\r\n';
|
||||
socket.write(connectMessage);
|
||||
}
|
||||
}
|
||||
exports.default = HttpsProxyAgent;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export { default as Agent, } from './Agent';
|
||||
export { default as HttpProxyAgent, } from './HttpProxyAgent';
|
||||
export { default as HttpsProxyAgent, } from './HttpsProxyAgent';
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HttpsProxyAgent = exports.HttpProxyAgent = exports.Agent = void 0;
|
||||
var Agent_1 = require("./Agent");
|
||||
Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return __importDefault(Agent_1).default; } });
|
||||
var HttpProxyAgent_1 = require("./HttpProxyAgent");
|
||||
Object.defineProperty(exports, "HttpProxyAgent", { enumerable: true, get: function () { return __importDefault(HttpProxyAgent_1).default; } });
|
||||
var HttpsProxyAgent_1 = require("./HttpsProxyAgent");
|
||||
Object.defineProperty(exports, "HttpsProxyAgent", { enumerable: true, get: function () { return __importDefault(HttpsProxyAgent_1).default; } });
|
||||
Reference in New Issue
Block a user