@sap-cloud-sdk/core
Version:
SAP Cloud SDK for JavaScript core
155 lines • 7.2 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.urlAndAgent = exports.getUrlProtocol = exports.getAgentConfig = void 0;
var https_1 = __importDefault(require("https"));
var http_1 = __importDefault(require("http"));
var util_1 = require("@sap-cloud-sdk/util");
var scp_cf_1 = require("../connectivity/scp-cf");
var proxy_util_1 = require("./proxy-util");
var logger = (0, util_1.createLogger)({
package: 'core',
messageContext: 'http-agent'
});
/**
* Returns the http or https-agent config depending on the destination URL.
* If the destination contains a proxy configuration, the agent will be a proxy-agent.
* If not it will be the default http-agent coming from node.
* @param destination - determining which kind of configuration is returned
* @returns The http or http-agent configuration.
*/
function getAgentConfig(destination) {
var agentType = destination.proxyConfiguration
? AgentType.PROXY
: AgentType.DEFAULT;
// eslint-disable-next-line @typescript-eslint/no-shadow
var certificateOptions = getCertificateOption(destination);
if (agentType === AgentType.PROXY) {
return createProxyAgent(destination, certificateOptions);
}
return createDefaultAgent(destination, certificateOptions);
}
exports.getAgentConfig = getAgentConfig;
var AgentType;
(function (AgentType) {
AgentType[AgentType["DEFAULT"] = 0] = "DEFAULT";
AgentType[AgentType["PROXY"] = 1] = "PROXY";
})(AgentType || (AgentType = {}));
function createProxyAgent(destination, options) {
if (!destination.proxyConfiguration) {
throw new Error("The destination proxy configuration: ".concat(destination.proxyConfiguration, " is undefined."));
}
return (0, proxy_util_1.proxyAgent)(destination, options);
}
var trustAllOptions = function (destination) {
return function (options) {
return (0, util_1.assoc)('rejectUnauthorized', !destination.isTrustingAllCertificates, options);
};
};
var certificateOptions = function (destination) {
return function (options) {
if (destination.keyStoreName && destination.keyStorePassword) {
var certificate = selectCertificate(destination);
logger.debug("Certificate with name \"".concat(certificate.name, "\" selected."));
return __assign(__assign({}, options), { pfx: Buffer.from(certificate.content, 'base64'), passphrase: destination.keyStorePassword });
}
return options;
};
};
/**
* @hidden
* The http agents (proxy and default) use node tls for the certificate handling. This method creates the options with the pfx and passphrase.
* https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options
* @param destination - Destination object
* @returns Options, which can be used later by tls.createSecureContext() e.g. pfx and passphrase or an empty object, if the protocol is not 'https:' or no client information are in the definition.
*/
function getCertificateOption(destination) {
// http case: no certificate needed
if ((0, scp_cf_1.getProtocolOrDefault)(destination) === scp_cf_1.Protocol.HTTP) {
if (destination.isTrustingAllCertificates) {
logger.warn('"isTrustingAllCertificates" is not available for HTTP.');
}
return {};
}
// https case: get certificate options
if (destination.isTrustingAllCertificates) {
logger.warn('"isTrustingAllCertificates" property in the provided destination is set to "true". This is highly discouraged in production.');
}
var options = trustAllOptions(destination)({});
return certificateOptions(destination)(options);
}
var supportedCertificateFormats = ['p12', 'pfx'];
function hasSupportedFormat(certificate) {
var certificateFormat = (0, util_1.last)(certificate.name.split('.'));
if (certificateFormat) {
return supportedCertificateFormats.includes(certificateFormat);
}
return false;
}
function selectCertificate(destination) {
var certificate = destination.certificates.find(function (c) { return c.name === destination.keyStoreName; });
if (!certificate) {
throw Error("No certificate with name ".concat(destination.keyStoreName, " could be found on the destination!"));
}
if (!hasSupportedFormat(certificate)) {
var format = (0, util_1.last)(certificate.name.split('.'));
throw Error("The format of the provided certificate '".concat(certificate.name, "' is not supported. Supported formats are: ").concat(supportedCertificateFormats.join(', '), ". ").concat(format && ['jks', 'keystore'].includes(format)
? "You can convert Java Keystores (.jks, .keystore) into PKCS#12 keystores using the JVM's keytool CLI: keytool -importkeystore -srckeystore your-keystore.jks -destkeystore your-keystore.p12 -deststoretype pkcs12"
: ''));
}
return certificate;
}
// eslint-disable-next-line valid-jsdoc
/**
* @hidden
* See https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener for details on the possible options
*/
function createDefaultAgent(destination, options) {
if ((0, scp_cf_1.getProtocolOrDefault)(destination) === scp_cf_1.Protocol.HTTPS) {
return { httpsAgent: new https_1.default.Agent(options) };
}
return { httpAgent: new http_1.default.Agent(options) };
}
/**
* @deprecated Since v1.5.1. use getProtocolOrDefault instead
* Takes the destination URL and return everything before the `://`.
* @param destination - URL of this destination is parsed
* @returns The protocol either `undefined` if no `://` is found or anything before the delimiter.
*/
function getUrlProtocol(destination) {
if (destination.url) {
var urlParts = destination.url.toLowerCase().split('://');
if (urlParts.length > 1) {
return urlParts[0];
}
}
}
exports.getUrlProtocol = getUrlProtocol;
/**
* Builds part of the request config containing the URL and if needed proxy agents or normal http agents.
* Considers the `no_proxy` environment variable together with the `targetUri`.
* @param targetUri - Used as baseURL in request config.
* @returns HttpRequestConfig containing baseUrl and http(s) agents.
*/
function urlAndAgent(targetUri) {
var destination = { url: targetUri, proxyType: 'Internet' };
if ((0, proxy_util_1.proxyStrategy)(destination) === proxy_util_1.ProxyStrategy.INTERNET_PROXY) {
destination = (0, proxy_util_1.addProxyConfigurationInternet)(destination);
}
return __assign({ url: destination.url }, getAgentConfig(destination));
}
exports.urlAndAgent = urlAndAgent;
//# sourceMappingURL=http-agent.js.map
;