UNPKG

aws-api-gateway-client

Version:
291 lines (212 loc) 36.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _axios = _interopRequireDefault(require("axios")); var _axiosRetry = _interopRequireDefault(require("axios-retry")); var _sha = _interopRequireDefault(require("crypto-js/sha256")); var _encHex = _interopRequireDefault(require("crypto-js/enc-hex")); var _hmacSha = _interopRequireDefault(require("crypto-js/hmac-sha256")); var _url = _interopRequireDefault(require("url")); var _utils = _interopRequireDefault(require("./utils")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var sigV4ClientFactory = {}; sigV4ClientFactory.newClient = function (config) { var AWS_SHA_256 = 'AWS4-HMAC-SHA256'; var AWS4_REQUEST = 'aws4_request'; var AWS4 = 'AWS4'; var X_AMZ_DATE = 'x-amz-date'; var X_AMZ_SECURITY_TOKEN = 'x-amz-security-token'; var HOST = 'host'; var AUTHORIZATION = 'Authorization'; function hash(value) { return (0, _sha["default"])(value); // eslint-disable-line } function hexEncode(value) { return value.toString(_encHex["default"]); } function hmac(secret, value) { return (0, _hmacSha["default"])(value, secret, { asBytes: true }); // eslint-disable-line } function buildCanonicalRequest(method, path, queryParams, headers, payload) { return method + '\n' + buildCanonicalUri(path) + '\n' + buildCanonicalQueryString(queryParams) + '\n' + buildCanonicalHeaders(headers) + '\n' + buildCanonicalSignedHeaders(headers) + '\n' + hexEncode(hash(payload)); } function hashCanonicalRequest(request) { return hexEncode(hash(request)); } function buildCanonicalUri(uri) { return encodeURI(uri); } function buildCanonicalQueryString(queryParams) { if (Object.keys(queryParams).length < 1) { return ''; } var sortedQueryParams = []; for (var property in queryParams) { if (Object.prototype.hasOwnProperty.call(queryParams, property)) { sortedQueryParams.push(property); } } sortedQueryParams.sort(); var canonicalQueryString = ''; for (var i = 0; i < sortedQueryParams.length; i++) { canonicalQueryString += sortedQueryParams[i] + '=' + fixedEncodeURIComponent(queryParams[sortedQueryParams[i]]) + '&'; } return canonicalQueryString.substr(0, canonicalQueryString.length - 1); } function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { return '%' + c.charCodeAt(0).toString(16); }); } function buildCanonicalHeaders(headers) { var canonicalHeaders = ''; var sortedKeys = []; for (var property in headers) { if (Object.prototype.hasOwnProperty.call(headers, property)) { sortedKeys.push(property); } } sortedKeys.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }); for (var i = 0; i < sortedKeys.length; i++) { canonicalHeaders += sortedKeys[i].toLowerCase() + ':' + headers[sortedKeys[i]] + '\n'; } return canonicalHeaders; } function buildCanonicalSignedHeaders(headers) { var sortedKeys = []; for (var property in headers) { if (Object.prototype.hasOwnProperty.call(headers, property)) { sortedKeys.push(property.toLowerCase()); } } sortedKeys.sort(); return sortedKeys.join(';'); } function buildStringToSign(datetime, credentialScope, hashedCanonicalRequest) { return AWS_SHA_256 + '\n' + datetime + '\n' + credentialScope + '\n' + hashedCanonicalRequest; } function buildCredentialScope(datetime, region, service) { return datetime.substr(0, 8) + '/' + region + '/' + service + '/' + AWS4_REQUEST; } function calculateSigningKey(secretKey, datetime, region, service) { return hmac(hmac(hmac(hmac(AWS4 + secretKey, datetime.substr(0, 8)), region), service), AWS4_REQUEST); } function calculateSignature(key, stringToSign) { return hexEncode(hmac(key, stringToSign)); } function buildAuthorizationHeader(accessKey, credentialScope, headers, signature) { return AWS_SHA_256 + ' Credential=' + accessKey + '/' + credentialScope + ', SignedHeaders=' + buildCanonicalSignedHeaders(headers) + ', Signature=' + signature; } var awsSigV4Client = {}; if (config.accessKey === undefined || config.secretKey === undefined) { return awsSigV4Client; } awsSigV4Client.accessKey = _utils["default"].assertDefined(config.accessKey, 'accessKey'); awsSigV4Client.secretKey = _utils["default"].assertDefined(config.secretKey, 'secretKey'); awsSigV4Client.sessionToken = config.sessionToken; awsSigV4Client.serviceName = _utils["default"].assertDefined(config.serviceName, 'serviceName'); awsSigV4Client.region = _utils["default"].assertDefined(config.region, 'region'); awsSigV4Client.endpoint = _utils["default"].assertDefined(config.endpoint, 'endpoint'); awsSigV4Client.retries = config.retries; awsSigV4Client.retryCondition = config.retryCondition; awsSigV4Client.retryDelay = config.retryDelay; awsSigV4Client.host = config.host; awsSigV4Client.makeRequest = function (request) { var verb = _utils["default"].assertDefined(request.verb, 'verb'); var path = _utils["default"].assertDefined(request.path, 'path'); var queryParams = _utils["default"].copy(request.queryParams); var timeout = _utils["default"].copy(request.timeout); if (queryParams === undefined) { queryParams = {}; } if (timeout === undefined) { timeout = 0; } var headers = _utils["default"].copy(request.headers); if (headers === undefined) { headers = {}; } // If the user has not specified an override for Content type the use default if (headers['Content-Type'] === undefined) { headers['Content-Type'] = config.defaultContentType; } // If the user has not specified an override for Accept type the use default if (headers['Accept'] === undefined) { headers['Accept'] = config.defaultAcceptType; } var body = _utils["default"].copy(request.body); // stringify request body if content type is JSON if (body && headers['Content-Type'] && headers['Content-Type'] === 'application/json') { body = JSON.stringify(body); } // If there is no body remove the content-type header so it is not included in SigV4 calculation if (body === '' || body === undefined || body === null) { delete headers['Content-Type']; } var datetime = new Date(new Date().getTime() + config.systemClockOffset).toISOString().replace(/\.\d{3}Z$/, 'Z').replace(/[:-]|\.\d{3}/g, ''); headers[X_AMZ_DATE] = datetime; if (awsSigV4Client.host) { headers[HOST] = awsSigV4Client.host; } else { var parser = _url["default"].parse(awsSigV4Client.endpoint); headers[HOST] = parser.hostname; } var canonicalRequest = buildCanonicalRequest(verb, path, queryParams, headers, body); var hashedCanonicalRequest = hashCanonicalRequest(canonicalRequest); var credentialScope = buildCredentialScope(datetime, awsSigV4Client.region, awsSigV4Client.serviceName); var stringToSign = buildStringToSign(datetime, credentialScope, hashedCanonicalRequest); var signingKey = calculateSigningKey(awsSigV4Client.secretKey, datetime, awsSigV4Client.region, awsSigV4Client.serviceName); var signature = calculateSignature(signingKey, stringToSign); headers[AUTHORIZATION] = buildAuthorizationHeader(awsSigV4Client.accessKey, credentialScope, headers, signature); if (awsSigV4Client.sessionToken !== undefined && awsSigV4Client.sessionToken !== '') { headers[X_AMZ_SECURITY_TOKEN] = awsSigV4Client.sessionToken; } delete headers[HOST]; var url = config.endpoint + path; var queryString = buildCanonicalQueryString(queryParams); if (queryString !== '') { url += '?' + queryString; } // Need to re-attach Content-Type if it is not specified at this point if (headers['Content-Type'] === undefined) { headers['Content-Type'] = config.defaultContentType; } var signedRequest = { headers: headers, timeout: timeout, data: body, method: verb, url: url }; if (config.retries !== undefined) { signedRequest.baseURL = url; var client = _axios["default"].create(signedRequest); // Allow user configurable delay, or built-in exponential delay var retryDelay = function retryDelay() { return 0; }; if (config.retryDelay === 'exponential') { retryDelay = _axiosRetry["default"].exponentialDelay; } else if (typeof config.retryDelay === 'number') { retryDelay = function retryDelay() { return parseInt(config.retryDelay); }; } else if (typeof config.retryDelay === 'function') { retryDelay = config.retryDelay; } (0, _axiosRetry["default"])(client, _objectSpread(_objectSpread({}, config), {}, { retryCondition: config.retryCondition, retryDelay: retryDelay })); return client.request(signedRequest); } return (0, _axios["default"])(signedRequest); }; return awsSigV4Client; }; var _default = sigV4ClientFactory; exports["default"] = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvYXBpR2F0ZXdheUNvcmUvc2lnVjRDbGllbnQuanMiXSwibmFtZXMiOlsic2lnVjRDbGllbnRGYWN0b3J5IiwibmV3Q2xpZW50IiwiY29uZmlnIiwiQVdTX1NIQV8yNTYiLCJBV1M0X1JFUVVFU1QiLCJBV1M0IiwiWF9BTVpfREFURSIsIlhfQU1aX1NFQ1VSSVRZX1RPS0VOIiwiSE9TVCIsIkFVVEhPUklaQVRJT04iLCJoYXNoIiwidmFsdWUiLCJoZXhFbmNvZGUiLCJ0b1N0cmluZyIsImVuY0hleCIsImhtYWMiLCJzZWNyZXQiLCJhc0J5dGVzIiwiYnVpbGRDYW5vbmljYWxSZXF1ZXN0IiwibWV0aG9kIiwicGF0aCIsInF1ZXJ5UGFyYW1zIiwiaGVhZGVycyIsInBheWxvYWQiLCJidWlsZENhbm9uaWNhbFVyaSIsImJ1aWxkQ2Fub25pY2FsUXVlcnlTdHJpbmciLCJidWlsZENhbm9uaWNhbEhlYWRlcnMiLCJidWlsZENhbm9uaWNhbFNpZ25lZEhlYWRlcnMiLCJoYXNoQ2Fub25pY2FsUmVxdWVzdCIsInJlcXVlc3QiLCJ1cmkiLCJlbmNvZGVVUkkiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwic29ydGVkUXVlcnlQYXJhbXMiLCJwcm9wZXJ0eSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInB1c2giLCJzb3J0IiwiY2Fub25pY2FsUXVlcnlTdHJpbmciLCJpIiwiZml4ZWRFbmNvZGVVUklDb21wb25lbnQiLCJzdWJzdHIiLCJzdHIiLCJlbmNvZGVVUklDb21wb25lbnQiLCJyZXBsYWNlIiwiYyIsImNoYXJDb2RlQXQiLCJjYW5vbmljYWxIZWFkZXJzIiwic29ydGVkS2V5cyIsImEiLCJiIiwidG9Mb3dlckNhc2UiLCJsb2NhbGVDb21wYXJlIiwiam9pbiIsImJ1aWxkU3RyaW5nVG9TaWduIiwiZGF0ZXRpbWUiLCJjcmVkZW50aWFsU2NvcGUiLCJoYXNoZWRDYW5vbmljYWxSZXF1ZXN0IiwiYnVpbGRDcmVkZW50aWFsU2NvcGUiLCJyZWdpb24iLCJzZXJ2aWNlIiwiY2FsY3VsYXRlU2lnbmluZ0tleSIsInNlY3JldEtleSIsImNhbGN1bGF0ZVNpZ25hdHVyZSIsImtleSIsInN0cmluZ1RvU2lnbiIsImJ1aWxkQXV0aG9yaXphdGlvbkhlYWRlciIsImFjY2Vzc0tleSIsInNpZ25hdHVyZSIsImF3c1NpZ1Y0Q2xpZW50IiwidW5kZWZpbmVkIiwidXRpbHMiLCJhc3NlcnREZWZpbmVkIiwic2Vzc2lvblRva2VuIiwic2VydmljZU5hbWUiLCJlbmRwb2ludCIsInJldHJpZXMiLCJyZXRyeUNvbmRpdGlvbiIsInJldHJ5RGVsYXkiLCJob3N0IiwibWFrZVJlcXVlc3QiLCJ2ZXJiIiwiY29weSIsInRpbWVvdXQiLCJkZWZhdWx0Q29udGVudFR5cGUiLCJkZWZhdWx0QWNjZXB0VHlwZSIsImJvZHkiLCJKU09OIiwic3RyaW5naWZ5IiwiRGF0ZSIsImdldFRpbWUiLCJzeXN0ZW1DbG9ja09mZnNldCIsInRvSVNPU3RyaW5nIiwicGFyc2VyIiwidXJsUGFyc2VyIiwicGFyc2UiLCJob3N0bmFtZSIsImNhbm9uaWNhbFJlcXVlc3QiLCJzaWduaW5nS2V5IiwidXJsIiwicXVlcnlTdHJpbmciLCJzaWduZWRSZXF1ZXN0IiwiZGF0YSIsImJhc2VVUkwiLCJjbGllbnQiLCJheGlvcyIsImNyZWF0ZSIsImF4aW9zUmV0cnkiLCJleHBvbmVudGlhbERlbGF5IiwicGFyc2VJbnQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBZUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLElBQU1BLGtCQUFrQixHQUFHLEVBQTNCOztBQUNBQSxrQkFBa0IsQ0FBQ0MsU0FBbkIsR0FBK0IsVUFBU0MsTUFBVCxFQUFpQjtBQUM5QyxNQUFJQyxXQUFXLEdBQUcsa0JBQWxCO0FBQ0EsTUFBSUMsWUFBWSxHQUFHLGNBQW5CO0FBQ0EsTUFBSUMsSUFBSSxHQUFHLE1BQVg7QUFDQSxNQUFJQyxVQUFVLEdB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USxDQUFDL0csTUFBTSxDQUFDZ0YsVUFBUixDQUFkO0FBQUEsU0FBYjtBQUNELE9BRk0sTUFFQSxJQUFJLE9BQU9oRixNQUFNLENBQUNnRixVQUFkLEtBQTZCLFVBQWpDLEVBQTZDO0FBQ2xEQSxRQUFBQSxVQUFVLEdBQUdoRixNQUFNLENBQUNnRixVQUFwQjtBQUNEOztBQUVELGtDQUFXMEIsTUFBWCxrQ0FDSzFHLE1BREw7QUFFRStFLFFBQUFBLGNBQWMsRUFBRS9FLE1BQU0sQ0FBQytFLGNBRnpCO0FBR0VDLFFBQUFBLFVBQVUsRUFBVkE7QUFIRjtBQUtBLGFBQU8wQixNQUFNLENBQUMvRSxPQUFQLENBQWU0RSxhQUFmLENBQVA7QUFDRDs7QUFFRCxXQUFPLHVCQUFNQSxhQUFOLENBQVA7QUFDRCxHQXRIRDs7QUF3SEEsU0FBT2hDLGNBQVA7QUFDRCxDQWhRRDs7ZUFrUWV6RSxrQiIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAxMC0yMDE2IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKS5cbiAqIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIEEgY29weSBvZiB0aGUgTGljZW5zZSBpcyBsb2NhdGVkIGF0XG4gKlxuICogIGh0dHA6Ly9hd3MuYW1hem9uLmNvbS9hcGFjaGUyLjBcbiAqXG4gKiBvciBpbiB0aGUgXCJsaWNlbnNlXCIgZmlsZSBhY2NvbXBhbnlpbmcgdGhpcyBmaWxlLiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWRcbiAqIG9uIGFuIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlclxuICogZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmdcbiAqIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IGF4aW9zUmV0cnkgZnJvbSAnYXhpb3MtcmV0cnknO1xuaW1wb3J0IFNIQTI1NiBmcm9tICdjcnlwdG8tanMvc2hhMjU2JztcbmltcG9ydCBlbmNIZXggZnJvbSAnY3J5cHRvLWpzL2VuYy1oZXgnO1xuaW1wb3J0IEhtYWNTSEEyNTYgZnJvbSAnY3J5cHRvLWpzL2htYWMtc2hhMjU2JztcbmltcG9ydCB1cmxQYXJzZXIgZnJvbSAndXJsJztcbmltcG9ydCB1dGlscyBmcm9tICcuL3V0aWxzJztcblxuY29uc3Qgc2lnVjRDbGllbnRGYWN0b3J5ID0ge307XG5zaWdWNENsaWVudEZhY3RvcnkubmV3Q2xpZW50ID0gZnVuY3Rpb24oY29uZmlnKSB7XG4gIGxldCBBV1NfU0hBXzI1NiA9ICdBV1M0LUhNQUMtU0hBMjU2JztcbiAgbGV0IEFXUzRfUkVRVUVTVCA9ICdhd3M0X3JlcXVlc3QnO1xuICBsZXQgQVdTNCA9ICdBV1M0JztcbiAgbGV0IFhfQU1aX0RBVEUgPSAneC1hbXotZGF0ZSc7XG4gIGxldCBYX0FNWl9TRUNVUklUWV9UT0tFTiA9ICd4LWFtei1zZWN1cml0eS10b2tlbic7XG4gIGxldCBIT1NUID0gJ2hvc3QnO1xuICBsZXQgQVVUSE9SSVpBVElPTiA9ICdBdXRob3JpemF0aW9uJztcblxuICBmdW5jdGlvbiBoYXNoKHZhbHVlKSB7XG4gICAgcmV0dXJuIFNIQTI1Nih2YWx1ZSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgfVxuXG4gIGZ1bmN0aW9uIGhleEVuY29kZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZyhlbmNIZXgpO1xuICB9XG5cbiAgZnVuY3Rpb24gaG1hYyhzZWNyZXQsIHZhbHVlKSB7XG4gICAgcmV0dXJuIEhtYWNTSEEyNTYodmFsdWUsIHNlY3JldCwge2FzQnl0ZXM6IHRydWV9KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDYW5vbmljYWxSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgcXVlcnlQYXJhbXMsIGhlYWRlcnMsIHBheWxvYWQpIHtcbiAgICByZXR1cm4gbWV0aG9kICsgJ1xcbicgK1xuICAgICAgYnVpbGRDYW5vbmljYWxVcmkocGF0aCkgKyAnXFxuJyArXG4gICAgICBidWlsZENhbm9uaWNhbFF1ZXJ5U3RyaW5nKHF1ZXJ5UGFyYW1zKSArICdcXG4nICtcbiAgICAgIGJ1aWxkQ2Fub25pY2FsSGVhZGVycyhoZWFkZXJzKSArICdcXG4nICtcbiAgICAgIGJ1aWxkQ2Fub25pY2FsU2lnbmVkSGVhZGVycyhoZWFkZXJzKSArICdcXG4nICtcbiAgICAgIGhleEVuY29kZShoYXNoKHBheWxvYWQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc2hDYW5vbmljYWxSZXF1ZXN0KHJlcXVlc3QpIHtcbiAgICByZXR1cm4gaGV4RW5jb2RlKGhhc2gocmVxdWVzdCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDYW5vbmljYWxVcmkodXJpKSB7XG4gICAgcmV0dXJuIGVuY29kZVVSSSh1cmkpO1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDYW5vbmljYWxRdWVyeVN0cmluZyhxdWVyeVBhcmFtcykge1xuICAgIGlmIChPYmplY3Qua2V5cyhxdWVyeVBhcmFtcykubGVuZ3RoIDwgMSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIGxldCBzb3J0ZWRRdWVyeVBhcmFtcyA9IFtdO1xuICAgIGZvciAobGV0IHByb3BlcnR5IGluIHF1ZXJ5UGFyYW1zKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHF1ZXJ5UGFyYW1zLCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgc29ydGVkUXVlcnlQYXJhbXMucHVzaChwcm9wZXJ0eSk7XG4gICAgICB9XG4gICAgfVxuICAgIHNvcnRlZFF1ZXJ5UGFyYW1zLnNvcnQoKTtcblxuICAgIGxldCBjYW5vbmljYWxRdWVyeVN0cmluZyA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc29ydGVkUXVlcnlQYXJhbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNhbm9uaWNhbFF1ZXJ5U3RyaW5nICs9IHNvcnRlZFF1ZXJ5UGFyYW1zW2ldXG4gICAgICAgICsgJz0nICsgZml4ZWRFbmNvZGVVUklDb21wb25lbnQocXVlcnlQYXJhbXNbc29ydGVkUXVlcnlQYXJhbXNbaV1dKSArICcmJztcbiAgICB9XG4gICAgcmV0dXJuIGNhbm9uaWNhbFF1ZXJ5U3RyaW5nLnN1YnN0cigwLCBjYW5vbmljYWxRdWVyeVN0cmluZy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpeGVkRW5jb2RlVVJJQ29tcG9uZW50KHN0cikge1xuICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoc3RyKS5yZXBsYWNlKC9bIScoKSpdL2csIGZ1bmN0aW9uKGMpIHtcbiAgICAgIHJldHVybiAnJScgKyBjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDYW5vbmljYWxIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICBsZXQgY2Fub25pY2FsSGVhZGVycyA9ICcnO1xuICAgIGxldCBzb3J0ZWRLZXlzID0gW107XG4gICAgZm9yIChsZXQgcHJvcGVydHkgaW4gaGVhZGVycykge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChoZWFkZXJzLCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgc29ydGVkS2V5cy5wdXNoKHByb3BlcnR5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgc29ydGVkS2V5cy5zb3J0KChhLCBiKSA9PiBhLnRvTG93ZXJDYXNlKCkubG9jYWxlQ29tcGFyZShiLnRvTG93ZXJDYXNlKCkpKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc29ydGVkS2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgY2Fub25pY2FsSGVhZGVycyArPSBzb3J0ZWRLZXlzW2ldLnRvTG93ZXJDYXNlKCkgKyAnOicgKyBoZWFkZXJzW3NvcnRlZEtleXNbaV1dICsgJ1xcbic7XG4gICAgfVxuICAgIHJldHVybiBjYW5vbmljYWxIZWFkZXJzO1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDYW5vbmljYWxTaWduZWRIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICBsZXQgc29ydGVkS2V5cyA9IFtdO1xuICAgIGZvciAobGV0IHByb3BlcnR5IGluIGhlYWRlcnMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaGVhZGVycywgcHJvcGVydHkpKSB7XG4gICAgICAgIHNvcnRlZEtleXMucHVzaChwcm9wZXJ0eS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgc29ydGVkS2V5cy5zb3J0KCk7XG5cbiAgICByZXR1cm4gc29ydGVkS2V5cy5qb2luKCc7Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsZFN0cmluZ1RvU2lnbihkYXRldGltZSwgY3JlZGVudGlhbFNjb3BlLCBoYXNoZWRDYW5vbmljYWxSZXF1ZXN0KSB7XG4gICAgcmV0dXJuIEFXU19TSEFfMjU2ICsgJ1xcbicgK1xuICAgICAgZGF0ZXRpbWUgKyAnXFxuJyArXG4gICAgICBjcmVkZW50aWFsU2NvcGUgKyAnXFxuJyArXG4gICAgICBoYXNoZWRDYW5vbmljYWxSZXF1ZXN0O1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDcmVkZW50aWFsU2NvcGUoZGF0ZXRpbWUsIHJlZ2lvbiwgc2VydmljZSkge1xuICAgIHJldHVybiBkYXRldGltZS5zdWJzdHIoMCwgOCkgKyAnLycgKyByZWdpb24gKyAnLycgKyBzZXJ2aWNlICsgJy8nICsgQVdTNF9SRVFVRVNUO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FsY3VsYXRlU2lnbmluZ0tleShzZWNyZXRLZXksIGRhdGV0aW1lLCByZWdpb24sIHNlcnZpY2UpIHtcbiAgICByZXR1cm4gaG1hYyhobWFjKGhtYWMoXG4gICAgICBobWFjKEFXUzQgKyBzZWNyZXRLZXksIGRhdGV0aW1lLnN1YnN0cigwLCA4KSksXG4gICAgICByZWdpb25cbiAgICApLCBzZXJ2aWNlKSwgQVdTNF9SRVFVRVNUKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbGN1bGF0ZVNpZ25hdHVyZShrZXksIHN0cmluZ1RvU2lnbikge1xuICAgIHJldHVybiBoZXhFbmNvZGUoaG1hYyhrZXksIHN0cmluZ1RvU2lnbikpO1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRBdXRob3JpemF0aW9uSGVhZGVyKGFjY2Vzc0tleSwgY3JlZGVudGlhbFNjb3BlLCBoZWFkZXJzLCBzaWduYXR1cmUpIHtcbiAgICByZXR1cm4gQVdTX1NIQV8yNTYgKyAnIENyZWRlbnRpYWw9JyArIGFjY2Vzc0tleSArICcvJyArIGNyZWRlbnRpYWxTY29wZVxuICAgICAgKyAnLCBTaWduZWRIZWFkZXJzPScgKyBidWlsZENhbm9uaWNhbFNpZ25lZEhlYWRlcnMoaGVhZGVycykgKyAnLCBTaWduYXR1cmU9JyArIHNpZ25hdHVyZTtcbiAgfVxuXG4gIGxldCBhd3NTaWdWNENsaWVudCA9IHsgfTtcbiAgaWYgKGNvbmZpZy5hY2Nlc3NLZXkgPT09IHVuZGVmaW5lZCB8fCBjb25maWcuc2VjcmV0S2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYXdzU2lnVjRDbGllbnQ7XG4gIH1cbiAgYXdzU2lnVjRDbGllbnQuYWNjZXNzS2V5ID0gdXRpbHMuYXNzZXJ0RGVmaW5lZChjb25maWcuYWNjZXNzS2V5LCAnYWNjZXNzS2V5Jyk7XG4gIGF3c1NpZ1Y0Q2xpZW50LnNlY3JldEtleSA9IHV0aWxzLmFzc2VydERlZmluZWQoY29uZmlnLnNlY3JldEtleSwgJ3NlY3JldEtleScpO1xuICBhd3NTaWdWNENsaWVudC5zZXNzaW9uVG9rZW4gPSBjb25maWcuc2Vzc2lvblRva2VuO1xuICBhd3NTaWdWNENsaWVudC5zZXJ2aWNlTmFtZSA9IHV0aWxzLmFzc2VydERlZmluZWQoY29uZmlnLnNlcnZpY2VOYW1lLCAnc2VydmljZU5hbWUnKTtcbiAgYXdzU2lnVjRDbGllbnQucmVnaW9uID0gdXRpbHMuYXNzZXJ0RGVmaW5lZChjb25maWcucmVnaW9uLCAncmVnaW9uJyk7XG4gIGF3c1NpZ1Y0Q2xpZW50LmVuZHBvaW50ID0gdXRpbHMuYXNzZXJ0RGVmaW5lZChjb25maWcuZW5kcG9pbnQsICdlbmRwb2ludCcpO1xuICBhd3NTaWdWNENsaWVudC5yZXRyaWVzID0gY29uZmlnLnJldHJpZXM7XG4gIGF3c1NpZ1Y0Q2xpZW50LnJldHJ5Q29uZGl0aW9uID0gY29uZmlnLnJldHJ5Q29uZGl0aW9uO1xuICBhd3NTaWdWNENsaWVudC5yZXRyeURlbGF5ID0gY29uZmlnLnJldHJ5RGVsYXk7XG4gIGF3c1NpZ1Y0Q2xpZW50Lmhvc3QgPSBjb25maWcuaG9zdDtcblxuICBhd3NTaWdWNENsaWVudC5tYWtlUmVxdWVzdCA9IGZ1bmN0aW9uKHJlcXVlc3QpIHtcbiAgICBsZXQgdmVyYiA9IHV0aWxzLmFzc2VydERlZmluZWQocmVxdWVzdC52ZXJiLCAndmVyYicpO1xuICAgIGxldCBwYXRoID0gdXRpbHMuYXNzZXJ0RGVmaW5lZChyZXF1ZXN0LnBhdGgsICdwYXRoJyk7XG4gICAgbGV0IHF1ZXJ5UGFyYW1zID0gdXRpbHMuY29weShyZXF1ZXN0LnF1ZXJ5UGFyYW1zKTtcbiAgICBsZXQgdGltZW91dCA9IHV0aWxzLmNvcHkocmVxdWVzdC50aW1lb3V0KTtcblxuICAgIGlmIChxdWVyeVBhcmFtcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBxdWVyeVBhcmFtcyA9IHt9O1xuICAgIH1cblxuICAgIGlmICh0aW1lb3V0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRpbWVvdXQgPSAwO1xuICAgIH1cbiAgICBsZXQgaGVhZGVycyA9IHV0aWxzLmNvcHkocmVxdWVzdC5oZWFkZXJzKTtcbiAgICBpZiAoaGVhZGVycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBoZWFkZXJzID0ge307XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHVzZXIgaGFzIG5vdCBzcGVjaWZpZWQgYW4gb3ZlcnJpZGUgZm9yIENvbnRlbnQgdHlwZSB0aGUgdXNlIGRlZmF1bHRcbiAgICBpZiAoaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPT09IHVuZGVmaW5lZCkge1xuICAgICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSBjb25maWcuZGVmYXVsdENvbnRlbnRUeXBlO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSB1c2VyIGhhcyBub3Qgc3BlY2lmaWVkIGFuIG92ZXJyaWRlIGZvciBBY2NlcHQgdHlwZSB0aGUgdXNlIGRlZmF1bHRcbiAgICBpZiAoaGVhZGVyc1snQWNjZXB0J10gPT09IHVuZGVmaW5lZCkge1xuICAgICAgaGVhZGVyc1snQWNjZXB0J10gPSBjb25maWcuZGVmYXVsdEFjY2VwdFR5cGU7XG4gICAgfVxuXG4gICAgbGV0IGJvZHkgPSB1dGlscy5jb3B5KHJlcXVlc3QuYm9keSk7XG5cbiAgICAvLyBzdHJpbmdpZnkgcmVxdWVzdCBib2R5IGlmIGNvbnRlbnQgdHlwZSBpcyBKU09OXG4gICAgaWYgKGJvZHkgJiYgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gJiYgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPT09ICdhcHBsaWNhdGlvbi9qc29uJykge1xuICAgICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHkpO1xuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGlzIG5vIGJvZHkgcmVtb3ZlIHRoZSBjb250ZW50LXR5cGUgaGVhZGVyIHNvIGl0IGlzIG5vdCBpbmNsdWRlZCBpbiBTaWdWNCBjYWxjdWxhdGlvblxuICAgIGlmIChib2R5ID09PSAnJyB8fCBib2R5ID09PSB1bmRlZmluZWQgfHwgYm9keSA9PT0gbnVsbCkge1xuICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIH1cblxuICAgIGxldCBkYXRldGltZSA9IG5ldyBEYXRlKG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgY29uZmlnLnN5c3RlbUNsb2NrT2Zmc2V0KS50b0lTT1N0cmluZygpXG4gICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcLlxcZHszfVokLywgJ1onKS5yZXBsYWNlKC9bOi1dfFxcLlxcZHszfS9nLCAnJyk7XG4gICAgaGVhZGVyc1tYX0FNWl9EQVRFXSA9IGRhdGV0aW1lO1xuXG4gICAgaWYgKGF3c1NpZ1Y0Q2xpZW50Lmhvc3QpIHtcbiAgICAgIGhlYWRlcnNbSE9TVF0gPSBhd3NTaWdWNENsaWVudC5ob3N0O1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcGFyc2VyID0gdXJsUGFyc2VyLnBhcnNlKGF3c1NpZ1Y0Q2xpZW50LmVuZHBvaW50KTtcbiAgICAgIGhlYWRlcnNbSE9TVF0gPSBwYXJzZXIuaG9zdG5hbWU7XG4gICAgfVxuXG4gICAgbGV0IGNhbm9uaWNhbFJlcXVlc3QgPSBidWlsZENhbm9uaWNhbFJlcXVlc3QodmVyYiwgcGF0aCwgcXVlcnlQYXJhbXMsIGhlYWRlcnMsIGJvZHkpO1xuICAgIGxldCBoYXNoZWRDYW5vbmljYWxSZXF1ZXN0ID0gaGFzaENhbm9uaWNhbFJlcXVlc3QoY2Fub25pY2FsUmVxdWVzdCk7XG4gICAgbGV0IGNyZWRlbnRpYWxTY29wZSA9IGJ1aWxkQ3JlZGVudGlhbFNjb3BlKFxuICAgICAgZGF0ZXRpbWUsXG4gICAgICBhd3NTaWdWNENsaWVudC5yZWdpb24sXG4gICAgICBhd3NTaWdWNENsaWVudC5zZXJ2aWNlTmFtZVxuICAgICk7XG4gICAgbGV0IHN0cmluZ1RvU2lnbiA9IGJ1aWxkU3RyaW5nVG9TaWduKGRhdGV0aW1lLCBjcmVkZW50aWFsU2NvcGUsIGhhc2hlZENhbm9uaWNhbFJlcXVlc3QpO1xuICAgIGxldCBzaWduaW5nS2V5ID0gY2FsY3VsYXRlU2lnbmluZ0tleShcbiAgICAgIGF3c1NpZ1Y0Q2xpZW50LnNlY3JldEtleSxcbiAgICAgIGRhdGV0aW1lLFxuICAgICAgYXdzU2lnVjRDbGllbnQucmVnaW9uLFxuICAgICAgYXdzU2lnVjRDbGllbnQuc2VydmljZU5hbWVcbiAgICApO1xuICAgIGxldCBzaWduYXR1cmUgPSBjYWxjdWxhdGVTaWduYXR1cmUoc2lnbmluZ0tleSwgc3RyaW5nVG9TaWduKTtcbiAgICBoZWFkZXJzW0FVVEhPUklaQVRJT05dID0gYnVpbGRBdXRob3JpemF0aW9uSGVhZGVyKFxuICAgICAgYXdzU2lnVjRDbGllbnQuYWNjZXNzS2V5LFxuICAgICAgY3JlZGVudGlhbFNjb3BlLFxuICAgICAgaGVhZGVycyxcbiAgICAgIHNpZ25hdHVyZVxuICAgICk7XG4gICAgaWYgKGF3c1NpZ1Y0Q2xpZW50LnNlc3Npb25Ub2tlbiAhPT0gdW5kZWZpbmVkICYmIGF3c1NpZ1Y0Q2xpZW50LnNlc3Npb25Ub2tlbiAhPT0gJycpIHtcbiAgICAgIGhlYWRlcnNbWF9BTVpfU0VDVVJJVFlfVE9LRU5dID0gYXdzU2lnVjRDbGllbnQuc2Vzc2lvblRva2VuO1xuICAgIH1cbiAgICBkZWxldGUgaGVhZGVyc1tIT1NUXTtcblxuICAgIGxldCB1cmwgPSBjb25maWcuZW5kcG9pbnQgKyBwYXRoO1xuICAgIGxldCBxdWVyeVN0cmluZyA9IGJ1aWxkQ2Fub25pY2FsUXVlcnlTdHJpbmcocXVlcnlQYXJhbXMpO1xuICAgIGlmIChxdWVyeVN0cmluZyAhPT0gJycpIHtcbiAgICAgIHVybCArPSAnPycgKyBxdWVyeVN0cmluZztcbiAgICB9XG5cbiAgICAvLyBOZWVkIHRvIHJlLWF0dGFjaCBDb250ZW50LVR5cGUgaWYgaXQgaXMgbm90IHNwZWNpZmllZCBhdCB0aGlzIHBvaW50XG4gICAgaWYgKGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gY29uZmlnLmRlZmF1bHRDb250ZW50VHlwZTtcbiAgICB9XG5cbiAgICBsZXQgc2lnbmVkUmVxdWVzdCA9IHtcbiAgICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgICB0aW1lb3V0OiB0aW1lb3V0LFxuICAgICAgZGF0YTogYm9keSxcbiAgICAgIG1ldGhvZDogdmVyYixcbiAgICAgIHVybCxcbiAgICB9O1xuICAgIGlmIChjb25maWcucmV0cmllcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBzaWduZWRSZXF1ZXN0LmJhc2VVUkwgPSB1cmw7XG4gICAgICBsZXQgY2xpZW50ID0gYXhpb3MuY3JlYXRlKHNpZ25lZFJlcXVlc3QpO1xuXG4gICAgICAvLyBBbGxvdyB1c2VyIGNvbmZpZ3VyYWJsZSBkZWxheSwgb3IgYnVpbHQtaW4gZXhwb25lbnRpYWwgZGVsYXlcbiAgICAgIGxldCByZXRyeURlbGF5ID0gKCkgPT4gMDtcbiAgICAgIGlmIChjb25maWcucmV0cnlEZWxheSA9PT0gJ2V4cG9uZW50aWFsJykge1xuICAgICAgICByZXRyeURlbGF5ID0gYXhpb3NSZXRyeS5leHBvbmVudGlhbERlbGF5O1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY29uZmlnLnJldHJ5RGVsYXkgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHJ5RGVsYXkgPSAoKSA9PiBwYXJzZUludChjb25maWcucmV0cnlEZWxheSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBjb25maWcucmV0cnlEZWxheSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXRyeURlbGF5ID0gY29uZmlnLnJldHJ5RGVsYXk7XG4gICAgICB9XG5cbiAgICAgIGF4aW9zUmV0cnkoY2xpZW50LCB7XG4gICAgICAgIC4uLmNvbmZpZyxcbiAgICAgICAgcmV0cnlDb25kaXRpb246IGNvbmZpZy5yZXRyeUNvbmRpdGlvbixcbiAgICAgICAgcmV0cnlEZWxheSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGNsaWVudC5yZXF1ZXN0KHNpZ25lZFJlcXVlc3QpO1xuICAgIH1cblxuICAgIHJldHVybiBheGlvcyhzaWduZWRSZXF1ZXN0KTtcbiAgfTtcblxuICByZXR1cm4gYXdzU2lnVjRDbGllbnQ7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBzaWdWNENsaWVudEZhY3Rvcnk7XG4iXX0=