verdaccio
Version:
A lightweight private npm proxy registry
175 lines (171 loc) • 28.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.listenDefaultCallback = listenDefaultCallback;
exports.startVerdaccio = startVerdaccio;
var _constants = _interopRequireDefault(require("constants"));
var _fs = _interopRequireDefault(require("fs"));
var _http = _interopRequireDefault(require("http"));
var _https = _interopRequireDefault(require("https"));
var _lodash = require("lodash");
var _url = _interopRequireDefault(require("url"));
var _index = _interopRequireDefault(require("../api/index"));
var _utils = require("./cli/utils");
var _constants2 = require("./constants");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const logger = require('./logger');
function displayExperimentsInfoBox(experiments) {
const experimentList = Object.keys(experiments);
if (experimentList.length >= 1) {
logger.logger.warn('⚠️ experiments are enabled, it is recommended do not use experiments in production, comment out the experiments section to disable this warning');
experimentList.forEach(experiment => {
logger.logger.warn(` - support for ${experiment} ${experiments[experiment] ? 'is enabled' : ' is disabled'}`);
});
}
}
/**
* Trigger the server after configuration has been loaded.
* @param {Object} config
* @param {Object} cliArguments
* @param {String} configPath
* @param {String} pkgVersion
* @param {String} pkgName
* @deprecated use runServer instead
*/
function startVerdaccio(config, cliListen, configPath, pkgVersion, pkgName, callback) {
if ((0, _lodash.isObject)(config) === false) {
throw new Error(_constants2.API_ERROR.CONFIG_BAD_FORMAT);
}
if ('experiments' in config) {
displayExperimentsInfoBox(config.experiments);
}
(0, _index.default)(config).then(app => {
const addresses = (0, _utils.getListListenAddresses)(cliListen, config.listen);
if (addresses.length > 1) {
process.emitWarning('multiple listen addresses are deprecated, please use only one');
}
addresses.forEach(function (addr) {
let webServer;
if (addr.proto === 'https') {
webServer = handleHTTPS(app, configPath, config);
} else {
// http
webServer = _http.default.createServer(app);
}
if (config.server && typeof config.server.keepAliveTimeout !== 'undefined' && config.server.keepAliveTimeout !== 'null') {
// library definition for node is not up to date (doesn't contain recent 8.0 changes)
webServer.keepAliveTimeout = config.server.keepAliveTimeout * 1000;
}
unlinkAddressPath(addr);
callback(webServer, addr, pkgName, pkgVersion);
});
});
}
function unlinkAddressPath(addr) {
if (addr.path && _fs.default.existsSync(addr.path)) {
_fs.default.unlinkSync(addr.path);
}
}
function logHTTPSWarning(storageLocation) {
logger.logger.fatal(['You have enabled HTTPS and need to specify either ', ' "https.key" and "https.cert" or ', ' "https.pfx" and optionally "https.passphrase" ', 'to run https server', '',
// commands are borrowed from node.js docs
'To quickly create self-signed certificate, use:', ' $ openssl genrsa -out ' + (0, _utils.resolveConfigPath)(storageLocation, _constants2.keyPem) + ' 2048', ' $ openssl req -new -sha256 -key ' + (0, _utils.resolveConfigPath)(storageLocation, _constants2.keyPem) + ' -out ' + (0, _utils.resolveConfigPath)(storageLocation, _constants2.csrPem), ' $ openssl x509 -req -in ' + (0, _utils.resolveConfigPath)(storageLocation, _constants2.csrPem) + ' -signkey ' + (0, _utils.resolveConfigPath)(storageLocation, _constants2.keyPem) + ' -out ' + (0, _utils.resolveConfigPath)(storageLocation, _constants2.certPem), '', 'And then add to config file (' + storageLocation + '):', ' https:', ` key: ${(0, _utils.resolveConfigPath)(storageLocation, _constants2.keyPem)}`, ` cert: ${(0, _utils.resolveConfigPath)(storageLocation, _constants2.certPem)}`].join('\n'));
process.exit(2);
}
function handleHTTPS(app, configPath, config) {
try {
let httpsOptions = {
secureOptions: _constants.default.SSL_OP_NO_SSLv2 | _constants.default.SSL_OP_NO_SSLv3 // disable insecure SSLv2 and SSLv3
};
const keyCertConfig = config.https;
const pfxConfig = config.https;
// https must either have key and cert or a pfx and (optionally) a passphrase
if (!(keyCertConfig.key && keyCertConfig.cert || pfxConfig.pfx)) {
logHTTPSWarning(configPath);
}
if (pfxConfig.pfx) {
const {
pfx,
passphrase
} = pfxConfig;
httpsOptions = (0, _lodash.assign)(httpsOptions, {
pfx: _fs.default.readFileSync(pfx),
passphrase: passphrase || ''
});
} else {
const {
key,
cert,
ca
} = keyCertConfig;
httpsOptions = (0, _lodash.assign)(httpsOptions, _objectSpread({
key: _fs.default.readFileSync(key),
cert: _fs.default.readFileSync(cert)
}, ca && {
ca: _fs.default.readFileSync(ca)
}));
}
return _https.default.createServer(httpsOptions, app);
} catch (err) {
// catch errors related to certificate loading
logger.logger.fatal({
err: err
}, 'cannot create server: @{err.message}');
process.exit(2);
}
}
/**
*
* @param webServer
* @param addr
* @param pkgName
* @param pkgVersion
* @deprecated use initServer instead
*/
function listenDefaultCallback(webServer, addr, pkgName, pkgVersion) {
const server = webServer.listen(addr.port || addr.path, addr.host, () => {
// send a message for tests
if ((0, _lodash.isFunction)(process.send)) {
process.send({
verdaccio_started: true
});
}
}).on('error', function (err) {
logger.logger.fatal({
err: err
}, 'cannot create server: @{err.message}');
process.exit(2);
});
function handleShutdownGracefully() {
logger.logger.fatal('received shutdown signal - closing server gracefully...');
server.close(() => {
logger.logger.info('server closed.');
process.exit(0);
});
}
// handle shutdown signals nicely when environment says so
if (process.env.VERDACCIO_HANDLE_KILL_SIGNALS === 'true') {
process.on('SIGINT', handleShutdownGracefully);
process.on('SIGTERM', handleShutdownGracefully);
process.on('SIGHUP', handleShutdownGracefully);
}
logger.logger.warn({
addr: addr.path ? _url.default.format({
protocol: 'unix',
pathname: addr.path
}) : _url.default.format({
protocol: addr.proto,
hostname: addr.host,
port: addr.port,
pathname: '/'
}),
version: pkgName + '/' + pkgVersion
}, 'http address - @{addr} - @{version}');
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29uc3RhbnRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZnMiLCJfaHR0cCIsIl9odHRwcyIsIl9sb2Rhc2giLCJfdXJsIiwiX2luZGV4IiwiX3V0aWxzIiwiX2NvbnN0YW50czIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJvd25LZXlzIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJfdG9Qcm9wZXJ0eUtleSIsInZhbHVlIiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJpIiwiX3RvUHJpbWl0aXZlIiwiU3ltYm9sIiwidG9QcmltaXRpdmUiLCJjYWxsIiwiVHlwZUVycm9yIiwiU3RyaW5nIiwiTnVtYmVyIiwibG9nZ2VyIiwiZGlzcGxheUV4cGVyaW1lbnRzSW5mb0JveCIsImV4cGVyaW1lbnRzIiwiZXhwZXJpbWVudExpc3QiLCJ3YXJuIiwiZXhwZXJpbWVudCIsInN0YXJ0VmVyZGFjY2lvIiwiY29uZmlnIiwiY2xpTGlzdGVuIiwiY29uZmlnUGF0aCIsInBrZ1ZlcnNpb24iLCJwa2dOYW1lIiwiY2FsbGJhY2siLCJpc09iamVjdCIsIkVycm9yIiwiQVBJX0VSUk9SIiwiQ09ORklHX0JBRF9GT1JNQVQiLCJlbmRQb2ludEFQSSIsInRoZW4iLCJhcHAiLCJhZGRyZXNzZXMiLCJnZXRMaXN0TGlzdGVuQWRkcmVzc2VzIiwibGlzdGVuIiwicHJvY2VzcyIsImVtaXRXYXJuaW5nIiwiYWRkciIsIndlYlNlcnZlciIsInByb3RvIiwiaGFuZGxlSFRUUFMiLCJodHRwIiwiY3JlYXRlU2VydmVyIiwic2VydmVyIiwia2VlcEFsaXZlVGltZW91dCIsInVubGlua0FkZHJlc3NQYXRoIiwicGF0aCIsImZzIiwiZXhpc3RzU3luYyIsInVubGlua1N5bmMiLCJsb2dIVFRQU1dhcm5pbmciLCJzdG9yYWdlTG9jYXRpb24iLCJmYXRhbCIsInJlc29sdmVDb25maWdQYXRoIiwia2V5UGVtIiwiY3NyUGVtIiwiY2VydFBlbSIsImpvaW4iLCJleGl0IiwiaHR0cHNPcHRpb25zIiwic2VjdXJlT3B0aW9ucyIsImNvbnN0YW50cyIsIlNTTF9PUF9OT19TU0x2MiIsIlNTTF9PUF9OT19TU0x2MyIsImtleUNlcnRDb25maWciLCJodHRwcyIsInBmeENvbmZpZyIsImtleSIsImNlcnQiLCJwZngiLCJwYXNzcGhyYXNlIiwiYXNzaWduIiwicmVhZEZpbGVTeW5jIiwiY2EiLCJlcnIiLCJsaXN0ZW5EZWZhdWx0Q2FsbGJhY2siLCJwb3J0IiwiaG9zdCIsImlzRnVuY3Rpb24iLCJzZW5kIiwidmVyZGFjY2lvX3N0YXJ0ZWQiLCJvbiIsImhhbmRsZVNodXRkb3duR3JhY2VmdWxseSIsImNsb3NlIiwiaW5mbyIsImVudiIsIlZFUkRBQ0NJT19IQU5ETEVfS0lMTF9TSUdOQUxTIiwiVVJMIiwiZm9ybWF0IiwicHJvdG9jb2wiLCJwYXRobmFtZSIsImhvc3RuYW1lIiwidmVyc2lvbiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvYm9vdHN0cmFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjb25zdGFudHMgZnJvbSAnY29uc3RhbnRzJztcbmltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgQXBwbGljYXRpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgaHR0cCBmcm9tICdodHRwJztcbmltcG9ydCBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgeyBhc3NpZ24sIGlzRnVuY3Rpb24sIGlzT2JqZWN0IH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBVUkwgZnJvbSAndXJsJztcblxuaW1wb3J0IHsgQ2FsbGJhY2ssIENvbmZpZ1dpdGhIdHRwcywgSHR0cHNDb25mS2V5Q2VydCwgSHR0cHNDb25mUGZ4IH0gZnJvbSAnQHZlcmRhY2Npby90eXBlcyc7XG5cbmltcG9ydCBlbmRQb2ludEFQSSBmcm9tICcuLi9hcGkvaW5kZXgnO1xuaW1wb3J0IHsgZ2V0TGlzdExpc3RlbkFkZHJlc3NlcywgcmVzb2x2ZUNvbmZpZ1BhdGggfSBmcm9tICcuL2NsaS91dGlscyc7XG5pbXBvcnQgeyBBUElfRVJST1IsIGNlcnRQZW0sIGNzclBlbSwga2V5UGVtIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCcuL2xvZ2dlcicpO1xuXG5mdW5jdGlvbiBkaXNwbGF5RXhwZXJpbWVudHNJbmZvQm94KGV4cGVyaW1lbnRzKSB7XG4gIGNvbnN0IGV4cGVyaW1lbnRMaXN0ID0gT2JqZWN0LmtleXMoZXhwZXJpbWVudHMpO1xuICBpZiAoZXhwZXJpbWVudExpc3QubGVuZ3RoID49IDEpIHtcbiAgICBsb2dnZXIubG9nZ2VyLndhcm4oXG4gICAgICAn4pqg77iPICBleHBlcmltZW50cyBhcmUgZW5hYmxlZCwgaXQgaXMgcmVjb21tZW5kZWQgZG8gbm90IHVzZSBleHBlcmltZW50cyBpbiBwcm9kdWN0aW9uLCBjb21tZW50IG91dCB0aGUgZXhwZXJpbWVudHMgc2VjdGlvbiB0byBkaXNhYmxlIHRoaXMgd2FybmluZydcbiAgICApO1xuICAgIGV4cGVyaW1lbnRMaXN0LmZvckVhY2goKGV4cGVyaW1lbnQpID0+IHtcbiAgICAgIGxvZ2dlci5sb2dnZXIud2FybihcbiAgICAgICAgYCAtIHN1cHBvcnQgZm9yICR7ZXhwZXJpbWVudH0gJHtleHBlcmltZW50c1tleHBlcmltZW50XSA/ICdpcyBlbmFibGVkJyA6ICcgaXMgZGlzYWJsZWQnfWBcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBUcmlnZ2VyIHRoZSBzZXJ2ZXIgYWZ0ZXIgY29uZmlndXJhdGlvbiBoYXMgYmVlbiBsb2FkZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge09iamVjdH0gY2xpQXJndW1lbnRzXG4gKiBAcGFyYW0ge1N0cmluZ30gY29uZmlnUGF0aFxuICogQHBhcmFtIHtTdHJpbmd9IHBrZ1ZlcnNpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSBwa2dOYW1lXG4gKiBAZGVwcmVjYXRlZCB1c2UgcnVuU2VydmVyIGluc3RlYWRcbiAqL1xuZnVuY3Rpb24gc3RhcnRWZXJkYWNjaW8oXG4gIGNvbmZpZzogYW55LFxuICBjbGlMaXN0ZW46IHN0cmluZyxcbiAgY29uZmlnUGF0aDogc3RyaW5nLFxuICBwa2dWZXJzaW9uOiBzdHJpbmcsXG4gIHBrZ05hbWU6IHN0cmluZyxcbiAgY2FsbGJhY2s6IENhbGxiYWNrXG4pOiB2b2lkIHtcbiAgaWYgKGlzT2JqZWN0KGNvbmZpZykgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKEFQSV9FUlJPUi5DT05GSUdfQkFEX0ZPUk1BVCk7XG4gIH1cblxuICBpZiAoJ2V4cGVyaW1lbnRzJyBpbiBjb25maWcpIHtcbiAgICBkaXNwbGF5RXhwZXJpbWVudHNJbmZvQm94KGNvbmZpZy5leHBlcmltZW50cyk7XG4gIH1cblxuICBlbmRQb2ludEFQSShjb25maWcpLnRoZW4oKGFwcCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGFkZHJlc3NlcyA9IGdldExpc3RMaXN0ZW5BZGRyZXNzZXMoY2xpTGlzdGVuLCBjb25maWcubGlzdGVuKTtcblxuICAgIGlmIChhZGRyZXNzZXMubGVuZ3RoID4gMSkge1xuICAgICAgcHJvY2Vzcy5lbWl0V2FybmluZygnbXVsdGlwbGUgbGlzdGVuIGFkZHJlc3NlcyBhcmUgZGVwcmVjYXRlZCwgcGxlYXNlIHVzZSBvbmx5IG9uZScpO1xuICAgIH1cblxuICAgIGFkZHJlc3Nlcy5mb3JFYWNoKGZ1bmN0aW9uIChhZGRyKTogdm9pZCB7XG4gICAgICBsZXQgd2ViU2VydmVyO1xuICAgICAgaWYgKGFkZHIucHJvdG8gPT09ICdodHRwcycpIHtcbiAgICAgICAgd2ViU2VydmVyID0gaGFuZGxlSFRUUFMoYXBwLCBjb25maWdQYXRoLCBjb25maWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gaHR0cFxuICAgICAgICB3ZWJTZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhcHApO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICBjb25maWcuc2VydmVyICYmXG4gICAgICAgIHR5cGVvZiBjb25maWcuc2VydmVyLmtlZXBBbGl2ZVRpbWVvdXQgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIGNvbmZpZy5zZXJ2ZXIua2VlcEFsaXZlVGltZW91dCAhPT0gJ251bGwnXG4gICAgICApIHtcbiAgICAgICAgLy8gbGlicmFyeSBkZWZpbml0aW9uIGZvciBub2RlIGlzIG5vdCB1cCB0byBkYXRlIChkb2Vzbid0IGNvbnRhaW4gcmVjZW50IDguMCBjaGFuZ2VzKVxuICAgICAgICB3ZWJTZXJ2ZXIua2VlcEFsaXZlVGltZW91dCA9IGNvbmZpZy5zZXJ2ZXIua2VlcEFsaXZlVGltZW91dCAqIDEwMDA7XG4gICAgICB9XG4gICAgICB1bmxpbmtBZGRyZXNzUGF0aChhZGRyKTtcblxuICAgICAgY2FsbGJhY2sod2ViU2VydmVyLCBhZGRyLCBwa2dOYW1lLCBwa2dWZXJzaW9uKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHVubGlua0FkZHJlc3NQYXRoKGFkZHIpIHtcbiAgaWYgKGFkZHIucGF0aCAmJiBmcy5leGlzdHNTeW5jKGFkZHIucGF0aCkpIHtcbiAgICBmcy51bmxpbmtTeW5jKGFkZHIucGF0aCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9nSFRUUFNXYXJuaW5nKHN0b3JhZ2VMb2NhdGlvbikge1xuICBsb2dnZXIubG9nZ2VyLmZhdGFsKFxuICAgIFtcbiAgICAgICdZb3UgaGF2ZSBlbmFibGVkIEhUVFBTIGFuZCBuZWVkIHRvIHNwZWNpZnkgZWl0aGVyICcsXG4gICAgICAnICAgIFwiaHR0cHMua2V5XCIgYW5kIFwiaHR0cHMuY2VydFwiIG9yICcsXG4gICAgICAnICAgIFwiaHR0cHMucGZ4XCIgYW5kIG9wdGlvbmFsbHkgXCJodHRwcy5wYXNzcGhyYXNlXCIgJyxcbiAgICAgICd0byBydW4gaHR0cHMgc2VydmVyJyxcbiAgICAgICcnLFxuICAgICAgLy8gY29tbWFuZHMgYXJlIGJvcnJvd2VkIGZyb20gbm9kZS5qcyBkb2NzXG4gICAgICAnVG8gcXVpY2tseSBjcmVhdGUgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUsIHVzZTonLFxuICAgICAgJyAkIG9wZW5zc2wgZ2VucnNhIC1vdXQgJyArIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwga2V5UGVtKSArICcgMjA0OCcsXG4gICAgICAnICQgb3BlbnNzbCByZXEgLW5ldyAtc2hhMjU2IC1rZXkgJyArXG4gICAgICAgIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwga2V5UGVtKSArXG4gICAgICAgICcgLW91dCAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjc3JQZW0pLFxuICAgICAgJyAkIG9wZW5zc2wgeDUwOSAtcmVxIC1pbiAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjc3JQZW0pICtcbiAgICAgICAgJyAtc2lnbmtleSAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBrZXlQZW0pICtcbiAgICAgICAgJyAtb3V0ICcgK1xuICAgICAgICByZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGNlcnRQZW0pLFxuICAgICAgJycsXG4gICAgICAnQW5kIHRoZW4gYWRkIHRvIGNvbmZpZyBmaWxlICgnICsgc3RvcmFnZUxvY2F0aW9uICsgJyk6JyxcbiAgICAgICcgIGh0dHBzOicsXG4gICAgICBgICAgIGtleTogJHtyZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGtleVBlbSl9YCxcbiAgICAgIGAgICAgY2VydDogJHtyZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGNlcnRQZW0pfWAsXG4gICAgXS5qb2luKCdcXG4nKVxuICApO1xuICBwcm9jZXNzLmV4aXQoMik7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUhUVFBTKFxuICBhcHA6IGV4cHJlc3MuQXBwbGljYXRpb24sXG4gIGNvbmZpZ1BhdGg6IHN0cmluZyxcbiAgY29uZmlnOiBDb25maWdXaXRoSHR0cHNcbik6IGh0dHBzLlNlcnZlciB7XG4gIHRyeSB7XG4gICAgbGV0IGh0dHBzT3B0aW9ucyA9IHtcbiAgICAgIHNlY3VyZU9wdGlvbnM6IGNvbnN0YW50cy5TU0xfT1BfTk9fU1NMdjIgfCBjb25zdGFudHMuU1NMX09QX05PX1NTTHYzLCAvLyBkaXNhYmxlIGluc2VjdXJlIFNTTHYyIGFuZCBTU0x2M1xuICAgIH07XG5cbiAgICBjb25zdCBrZXlDZXJ0Q29uZmlnID0gY29uZmlnLmh0dHBzIGFzIEh0dHBzQ29uZktleUNlcnQ7XG4gICAgY29uc3QgcGZ4Q29uZmlnID0gY29uZmlnLmh0dHBzIGFzIEh0dHBzQ29uZlBmeDtcblxuICAgIC8vIGh0dHBzIG11c3QgZWl0aGVyIGhhdmUga2V5IGFuZCBjZXJ0IG9yIGEgcGZ4IGFuZCAob3B0aW9uYWxseSkgYSBwYXNzcGhyYXNlXG4gICAgaWYgKCEoKGtleUNlcnRDb25maWcua2V5ICYmIGtleUNlcnRDb25maWcuY2VydCkgfHwgcGZ4Q29uZmlnLnBmeCkpIHtcbiAgICAgIGxvZ0hUVFBTV2FybmluZyhjb25maWdQYXRoKTtcbiAgICB9XG5cbiAgICBpZiAocGZ4Q29uZmlnLnBmeCkge1xuICAgICAgY29uc3QgeyBwZngsIHBhc3NwaHJhc2UgfSA9IHBmeENvbmZpZztcbiAgICAgIGh0dHBzT3B0aW9ucyA9IGFzc2lnbihodHRwc09wdGlvbnMsIHtcbiAgICAgICAgcGZ4OiBmcy5yZWFkRmlsZVN5bmMocGZ4KSxcbiAgICAgICAgcGFzc3BocmFzZTogcGFzc3BocmFzZSB8fCAnJyxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IGtleSwgY2VydCwgY2EgfSA9IGtleUNlcnRDb25maWc7XG4gICAgICBodHRwc09wdGlvbnMgPSBhc3NpZ24oaHR0cHNPcHRpb25zLCB7XG4gICAgICAgIGtleTogZnMucmVhZEZpbGVTeW5jKGtleSksXG4gICAgICAgIGNlcnQ6IGZzLnJlYWRGaWxlU3luYyhjZXJ0KSxcbiAgICAgICAgLi4uKGNhICYmIHtcbiAgICAgICAgICBjYTogZnMucmVhZEZpbGVTeW5jKGNhKSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGh0dHBzLmNyZWF0ZVNlcnZlcihodHRwc09wdGlvbnMsIGFwcCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIGNhdGNoIGVycm9ycyByZWxhdGVkIHRvIGNlcnRpZmljYXRlIGxvYWRpbmdcbiAgICBsb2dnZXIubG9nZ2VyLmZhdGFsKHsgZXJyOiBlcnIgfSwgJ2Nhbm5vdCBjcmVhdGUgc2VydmVyOiBAe2Vyci5tZXNzYWdlfScpO1xuICAgIHByb2Nlc3MuZXhpdCgyKTtcbiAgfVxufVxuLyoqXG4gKlxuICogQHBhcmFtIHdlYlNlcnZlclxuICogQHBhcmFtIGFkZHJcbiAqIEBwYXJhbSBwa2dOYW1lXG4gKiBAcGFyYW0gcGtnVmVyc2lvblxuICogQGRlcHJlY2F0ZWQgdXNlIGluaXRTZXJ2ZXIgaW5zdGVhZFxuICovXG5mdW5jdGlvbiBsaXN0ZW5EZWZhdWx0Q2FsbGJhY2soXG4gIHdlYlNlcnZlcjogQXBwbGljYXRpb24sXG4gIGFkZHI6IGFueSxcbiAgcGtnTmFtZTogc3RyaW5nLFxuICBwa2dWZXJzaW9uOiBzdHJpbmdcbik6IHZvaWQge1xuICBjb25zdCBzZXJ2ZXIgPSB3ZWJTZXJ2ZXJcbiAgICAubGlzdGVuKGFkZHIucG9ydCB8fCBhZGRyLnBhdGgsIGFkZHIuaG9zdCwgKCk6IHZvaWQgPT4ge1xuICAgICAgLy8gc2VuZCBhIG1lc3NhZ2UgZm9yIHRlc3RzXG4gICAgICBpZiAoaXNGdW5jdGlvbihwcm9jZXNzLnNlbmQpKSB7XG4gICAgICAgIHByb2Nlc3Muc2VuZCh7XG4gICAgICAgICAgdmVyZGFjY2lvX3N0YXJ0ZWQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pXG4gICAgLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpOiB2b2lkIHtcbiAgICAgIGxvZ2dlci5sb2dnZXIuZmF0YWwoeyBlcnI6IGVyciB9LCAnY2Fubm90IGNyZWF0ZSBzZXJ2ZXI6IEB7ZXJyLm1lc3NhZ2V9Jyk7XG4gICAgICBwcm9jZXNzLmV4aXQoMik7XG4gICAgfSk7XG5cbiAgZnVuY3Rpb24gaGFuZGxlU2h1dGRvd25HcmFjZWZ1bGx5KCkge1xuICAgIGxvZ2dlci5sb2dnZXIuZmF0YWwoJ3JlY2VpdmVkIHNodXRkb3duIHNpZ25hbCAtIGNsb3Npbmcgc2VydmVyIGdyYWNlZnVsbHkuLi4nKTtcbiAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgbG9nZ2VyLmxvZ2dlci5pbmZvKCdzZXJ2ZXIgY2xvc2VkLicpO1xuICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gaGFuZGxlIHNodXRkb3duIHNpZ25hbHMgbmljZWx5IHdoZW4gZW52aXJvbm1lbnQgc2F5cyBzb1xuICBpZiAocHJvY2Vzcy5lbnYuVkVSREFDQ0lPX0hBTkRMRV9LSUxMX1NJR05BTFMgPT09ICd0cnVlJykge1xuICAgIHByb2Nlc3Mub24oJ1NJR0lOVCcsIGhhbmRsZVNodXRkb3duR3JhY2VmdWxseSk7XG4gICAgcHJvY2Vzcy5vbignU0lHVEVSTScsIGhhbmRsZVNodXRkb3duR3JhY2VmdWxseSk7XG4gICAgcHJvY2Vzcy5vbignU0lHSFVQJywgaGFuZGxlU2h1dGRvd25HcmFjZWZ1bGx5KTtcbiAgfVxuXG4gIGxvZ2dlci5sb2dnZXIud2FybihcbiAgICB7XG4gICAgICBhZGRyOiBhZGRyLnBhdGhcbiAgICAgICAgPyBVUkwuZm9ybWF0KHtcbiAgICAgICAgICAgIHByb3RvY29sOiAndW5peCcsXG4gICAgICAgICAgICBwYXRobmFtZTogYWRkci5wYXRoLFxuICAgICAgICAgIH0pXG4gICAgICAgIDogVVJMLmZvcm1hdCh7XG4gICAgICAgICAgICBwcm90b2NvbDogYWRkci5wcm90byxcbiAgICAgICAgICAgIGhvc3RuYW1lOiBhZGRyLmhvc3QsXG4gICAgICAgICAgICBwb3J0OiBhZGRyLnBvcnQsXG4gICAgICAgICAgICBwYXRobmFtZTogJy8nLFxuICAgICAgICAgIH0pLFxuICAgICAgdmVyc2lvbjogcGtnTmFtZSArICcvJyArIHBrZ1ZlcnNpb24sXG4gICAgfSxcbiAgICAnaHR0cCBhZGRyZXNzIC0gQHthZGRyfSAtIEB7dmVyc2lvbn0nXG4gICk7XG59XG5cbmV4cG9ydCB7IHN0YXJ0VmVyZGFjY2lvLCBsaXN0ZW5EZWZhdWx0Q2FsbGJhY2sgfTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLElBQUFBLFVBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUdBLElBQUFDLEdBQUEsR0FBQUYsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFFLEtBQUEsR0FBQUgsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFHLE1BQUEsR0FBQUosc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFJLE9BQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLElBQUEsR0FBQU4sc0JBQUEsQ0FBQUMsT0FBQTtBQUlBLElBQUFNLE1BQUEsR0FBQVAsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFPLE1BQUEsR0FBQVAsT0FBQTtBQUNBLElBQUFRLFdBQUEsR0FBQVIsT0FBQTtBQUFpRSxTQUFBRCx1QkFBQVUsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtB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WEMsaUJBQWlCLEVBQUU7TUFDckIsQ0FBQyxDQUFDO0lBQ0o7RUFDRixDQUFDLENBQUMsQ0FDREMsRUFBRSxDQUFDLE9BQU8sRUFBRSxVQUFVUCxHQUFHLEVBQVE7SUFDaEM5RCxNQUFNLENBQUNBLE1BQU0sQ0FBQ3dDLEtBQUssQ0FBQztNQUFFc0IsR0FBRyxFQUFFQTtJQUFJLENBQUMsRUFBRSxzQ0FBc0MsQ0FBQztJQUN6RXZDLE9BQU8sQ0FBQ3VCLElBQUksQ0FBQyxDQUFDLENBQUM7RUFDakIsQ0FBQyxDQUFDO0VBRUosU0FBU3dCLHdCQUF3QkEsQ0FBQSxFQUFHO0lBQ2xDdEUsTUFBTSxDQUFDQSxNQUFNLENBQUN3QyxLQUFLLENBQUMseURBQXlELENBQUM7SUFDOUVULE1BQU0sQ0FBQ3dDLEtBQUssQ0FBQyxNQUFNO01BQ2pCdkUsTUFBTSxDQUFDQSxNQUFNLENBQUN3RSxJQUFJLENBQUMsZ0JBQWdCLENBQUM7TUFDcENqRCxPQUFPLENBQUN1QixJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2pCLENBQUMsQ0FBQztFQUNKOztFQUVBO0VBQ0EsSUFBSXZCLE9BQU8sQ0FBQ2tELEdBQUcsQ0FBQ0MsNkJBQTZCLEtBQUssTUFBTSxFQUFFO0lBQ3hEbkQsT0FBTyxDQUFDOEMsRUFBRSxDQUFDLFFBQVEsRUFBRUMsd0JBQXdCLENBQUM7SUFDOUMvQyxPQUFPLENBQUM4QyxFQUFFLENBQUMsU0FBUyxFQUFFQyx3QkFBd0IsQ0FBQztJQUMvQy9DLE9BQU8sQ0FBQzhDLEVBQUUsQ0FBQyxRQUFRLEVBQUVDLHdCQUF3QixDQUFDO0VBQ2hEO0VBRUF0RSxNQUFNLENBQUNBLE1BQU0sQ0FBQ0ksSUFBSSxDQUNoQjtJQUNFcUIsSUFBSSxFQUFFQSxJQUFJLENBQUNTLElBQUksR0FDWHlDLFlBQUcsQ0FBQ0MsTUFBTSxDQUFDO01BQ1RDLFFBQVEsRUFBRSxNQUFNO01BQ2hCQyxRQUFRLEVBQUVyRCxJQUFJLENBQUNTO0lBQ2pCLENBQUMsQ0FBQyxHQUNGeUMsWUFBRyxDQUFDQyxNQUFNLENBQUM7TUFDVEMsUUFBUSxFQUFFcEQsSUFBSSxDQUFDRSxLQUFLO01BQ3BCb0QsUUFBUSxFQUFFdEQsSUFBSSxDQUFDd0MsSUFBSTtNQUNuQkQsSUFBSSxFQUFFdkMsSUFBSSxDQUFDdUMsSUFBSTtNQUNmYyxRQUFRLEVBQUU7SUFDWixDQUFDLENBQUM7SUFDTkUsT0FBTyxFQUFFckUsT0FBTyxHQUFHLEdBQUcsR0FBR0Q7RUFDM0IsQ0FBQyxFQUNELHFDQUNGLENBQUM7QUFDSCIsImlnbm9yZUxpc3QiOltdfQ==
;