"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCanonicalCustomHostUrl = getCanonicalCustomHostUrl; exports.resolveCustomHosts = resolveCustomHosts; var _fs = require("fs"); var _lodash = require("lodash"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ function getCanonicalCustomHostUrl(url) { const port = getActualPort(url.protocol, url.port); return `${url.protocol}//${url.hostname}:${port}`; } const ErrorPrefix = 'In configuration xpack.actions.customHosts,'; const ValidProtocols = new Set(['https:', 'smtp:']); const ProtocolsForSmtp = new Set(['smtp:']); // converts the custom host data in config, for ease of use, and to perform // validation we can't do in config-schema, since the cloud validation can't // do these sorts of validations function resolveCustomHosts(logger, config) { const result = (0, _lodash.cloneDeep)(config); if (!result.customHostSettings) { return result; } const savedSettings = []; for (const customHostSetting of result.customHostSettings) { const originalUrl = customHostSetting.url; let parsedUrl; try { parsedUrl = new URL(originalUrl); } catch (err) { logger.warn(`${ErrorPrefix} invalid URL "${originalUrl}", ignoring; error: ${err.message}`); continue; } customHostSetting.url = getCanonicalCustomHostUrl(parsedUrl); if (!ValidProtocols.has(parsedUrl.protocol)) { logger.warn(`${ErrorPrefix} unsupported protocol used in URL "${originalUrl}", ignoring`); continue; } const port = getActualPort(parsedUrl.protocol, parsedUrl.port); if (!port) { logger.warn(`${ErrorPrefix} unable to determine port for URL "${originalUrl}", ignoring`); continue; } if (parsedUrl.username || parsedUrl.password) { logger.warn(`${ErrorPrefix} URL "${originalUrl}" contains authentication information which will be ignored, but should be removed from the configuration`); } if (parsedUrl.hash) { logger.warn(`${ErrorPrefix} URL "${originalUrl}" contains hash information which will be ignored`); } if (parsedUrl.pathname && parsedUrl.pathname !== '/') { logger.warn(`${ErrorPrefix} URL "${originalUrl}" contains path information which will be ignored`); } if (!ProtocolsForSmtp.has(parsedUrl.protocol) && customHostSetting.smtp) { logger.warn(`${ErrorPrefix} URL "${originalUrl}" contains smtp properties but does not use smtp; ignoring smtp properties`); delete customHostSetting.smtp; } // read the specified ca files, add their content to certificateAuthoritiesData if (customHostSetting.ssl) { var _customHostSetting$ss; let files = ((_customHostSetting$ss = customHostSetting.ssl) === null || _customHostSetting$ss === void 0 ? void 0 : _customHostSetting$ss.certificateAuthoritiesFiles) || []; if (typeof files === 'string') { files = [files]; } for (const file of files) { const contents = getFileContents(logger, file); if (contents) { appendToCertificateAuthoritiesData(customHostSetting, contents); } } } const customSmtpSettings = customHostSetting.smtp; if (customSmtpSettings) { if (customSmtpSettings.requireTLS && customSmtpSettings.ignoreTLS) { logger.warn(`${ErrorPrefix} URL "${originalUrl}" cannot have both requireTLS and ignoreTLS set to true; using requireTLS: true and ignoreTLS: false`); customSmtpSettings.requireTLS = true; customSmtpSettings.ignoreTLS = false; } } savedSettings.push(customHostSetting); } // check to see if there are any dups on the url const existingUrls = new Set(); for (const customHostSetting of savedSettings) { const url = customHostSetting.url; if (existingUrls.has(url)) { logger.warn(`${ErrorPrefix} multiple URLs match the canonical url "${url}"; only the first will be used`); // mark this entry to be able to delete it after processing them all customHostSetting.url = ''; } existingUrls.add(url); } // remove the settings we want to skip result.customHostSettings = savedSettings.filter(setting => setting.url !== ''); return result; } function appendToCertificateAuthoritiesData(customHost, cert) { const ssl = customHost.ssl; if (ssl) { if (!ssl.certificateAuthoritiesData) { ssl.certificateAuthoritiesData = cert; } else { ssl.certificateAuthoritiesData += '\n' + cert; } } } function getFileContents(logger, fileName) { try { return (0, _fs.readFileSync)(fileName, 'utf8'); } catch (err) { logger.warn(`error reading file "${fileName}" specified in xpack.actions.customHosts, ignoring: ${err.message}`); return; } } // 0 isn't a valid port, so result can be checked as falsy function getActualPort(protocol, port) { if (port !== '') { const portNumber = parseInt(port, 10); if (isNaN(portNumber)) { return 0; } return portNumber; } // from https://nodejs.org/dist/latest-v14.x/docs/api/url.html#url_url_port if (protocol === 'http:') return 80; if (protocol === 'https:') return 443; if (protocol === 'smtp:') return 25; return 0; }