"use strict"; var https = require('https'), crypto = require('crypto'); var Parse = require('parse/node').Parse; var OAuth = function (options) { if (!options) { throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'No options passed to OAuth'); } this.consumer_key = options.consumer_key; this.consumer_secret = options.consumer_secret; this.auth_token = options.auth_token; this.auth_token_secret = options.auth_token_secret; this.host = options.host; this.oauth_params = options.oauth_params || {}; }; OAuth.prototype.send = function (method, path, params, body) { var request = this.buildRequest(method, path, params, body); // Encode the body properly, the current Parse Implementation don't do it properly return new Promise(function (resolve, reject) { var httpRequest = https.request(request, function (res) { var data = ''; res.on('data', function (chunk) { data += chunk; }); res.on('end', function () { data = JSON.parse(data); resolve(data); }); }).on('error', function () { reject('Failed to make an OAuth request'); }); if (request.body) { httpRequest.write(request.body); } httpRequest.end(); }); }; OAuth.prototype.buildRequest = function (method, path, params, body) { if (path.indexOf('/') != 0) { path = '/' + path; } if (params && Object.keys(params).length > 0) { path += '?' + OAuth.buildParameterString(params); } var request = { host: this.host, path: path, method: method.toUpperCase() }; var oauth_params = this.oauth_params || {}; oauth_params.oauth_consumer_key = this.consumer_key; if (this.auth_token) { oauth_params['oauth_token'] = this.auth_token; } request = OAuth.signRequest(request, oauth_params, this.consumer_secret, this.auth_token_secret); if (body && Object.keys(body).length > 0) { request.body = OAuth.buildParameterString(body); } return request; }; OAuth.prototype.get = function (path, params) { return this.send('GET', path, params); }; OAuth.prototype.post = function (path, params, body) { return this.send('POST', path, params, body); }; /* Proper string %escape encoding */ OAuth.encode = function (str) { // discuss at: http://phpjs.org/functions/rawurlencode/ // original by: Brett Zamir (http://brett-zamir.me) // input by: travc // input by: Brett Zamir (http://brett-zamir.me) // input by: Michael Grier // input by: Ratheous // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // bugfixed by: Brett Zamir (http://brett-zamir.me) // bugfixed by: Joris // reimplemented by: Brett Zamir (http://brett-zamir.me) // reimplemented by: Brett Zamir (http://brett-zamir.me) // note: This reflects PHP 5.3/6.0+ behavior // note: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on // note: pages served as UTF-8 // example 1: rawurlencode('Kevin van Zonneveld!'); // returns 1: 'Kevin%20van%20Zonneveld%21' // example 2: rawurlencode('http://kevin.vanzonneveld.net/'); // returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F' // example 3: rawurlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'); // returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a' str = (str + '').toString(); // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); }; OAuth.signatureMethod = 'HMAC-SHA1'; OAuth.version = '1.0'; /* Generate a nonce */ OAuth.nonce = function () { var text = ''; var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for (var i = 0; i < 30; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; }; OAuth.buildParameterString = function (obj) { // Sort keys and encode values if (obj) { var keys = Object.keys(obj).sort(); // Map key=value, join them by & return keys.map(function (key) { return key + '=' + OAuth.encode(obj[key]); }).join('&'); } return ''; }; /* Build the signature string from the object */ OAuth.buildSignatureString = function (method, url, parameters) { return [method.toUpperCase(), OAuth.encode(url), OAuth.encode(parameters)].join('&'); }; /* Retuns encoded HMAC-SHA1 from key and text */ OAuth.signature = function (text, key) { crypto = require('crypto'); return OAuth.encode(crypto.createHmac('sha1', key).update(text).digest('base64')); }; OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_token_secret) { oauth_parameters = oauth_parameters || {}; // Set default values if (!oauth_parameters.oauth_nonce) { oauth_parameters.oauth_nonce = OAuth.nonce(); } if (!oauth_parameters.oauth_timestamp) { oauth_parameters.oauth_timestamp = Math.floor(new Date().getTime() / 1000); } if (!oauth_parameters.oauth_signature_method) { oauth_parameters.oauth_signature_method = OAuth.signatureMethod; } if (!oauth_parameters.oauth_version) { oauth_parameters.oauth_version = OAuth.version; } if (!auth_token_secret) { auth_token_secret = ''; } // Force GET method if unset if (!request.method) { request.method = 'GET'; } // Collect all the parameters in one signatureParameters object var signatureParams = {}; var parametersToMerge = [request.params, request.body, oauth_parameters]; for (var i in parametersToMerge) { var parameters = parametersToMerge[i]; for (var k in parameters) { signatureParams[k] = parameters[k]; } } // Create a string based on the parameters var parameterString = OAuth.buildParameterString(signatureParams); // Build the signature string var url = 'https://' + request.host + '' + request.path; var signatureString = OAuth.buildSignatureString(request.method, url, parameterString); // Hash the signature string var signatureKey = [OAuth.encode(consumer_secret), OAuth.encode(auth_token_secret)].join('&'); var signature = OAuth.signature(signatureString, signatureKey); // Set the signature in the params oauth_parameters.oauth_signature = signature; if (!request.headers) { request.headers = {}; } // Set the authorization header var authHeader = Object.keys(oauth_parameters).sort().map(function (key) { var value = oauth_parameters[key]; return key + '="' + value + '"'; }).join(', '); request.headers.Authorization = 'OAuth ' + authHeader; // Set the content type header request.headers['Content-Type'] = 'application/x-www-form-urlencoded'; return request; }; module.exports = OAuth; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJjcnlwdG8iLCJQYXJzZSIsIk9BdXRoIiwib3B0aW9ucyIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiY29uc3VtZXJfa2V5IiwiY29uc3VtZXJfc2VjcmV0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiaG9zdCIsIm9hdXRoX3BhcmFtcyIsInByb3RvdHlwZSIsInNlbmQiLCJtZXRob2QiLCJwYXRoIiwicGFyYW1zIiwiYm9keSIsInJlcXVlc3QiLCJidWlsZFJlcXVlc3QiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImh0dHBSZXF1ZXN0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJ3cml0ZSIsImVuZCIsImluZGV4T2YiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYnVpbGRQYXJhbWV0ZXJTdHJpbmciLCJ0b1VwcGVyQ2FzZSIsIm9hdXRoX2NvbnN1bWVyX2tleSIsInNpZ25SZXF1ZXN0IiwiZ2V0IiwicG9zdCIsImVuY29kZSIsInN0ciIsInRvU3RyaW5nIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicmVwbGFjZSIsInNpZ25hdHVyZU1ldGhvZCIsInZlcnNpb24iLCJub25jZSIsInRleHQiLCJwb3NzaWJsZSIsImkiLCJjaGFyQXQiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJvYmoiLCJzb3J0IiwibWFwIiwia2V5Iiwiam9pbiIsImJ1aWxkU2lnbmF0dXJlU3RyaW5nIiwidXJsIiwicGFyYW1ldGVycyIsInNpZ25hdHVyZSIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJkaWdlc3QiLCJvYXV0aF9wYXJhbWV0ZXJzIiwib2F1dGhfbm9uY2UiLCJvYXV0aF90aW1lc3RhbXAiLCJEYXRlIiwiZ2V0VGltZSIsIm9hdXRoX3NpZ25hdHVyZV9tZXRob2QiLCJvYXV0aF92ZXJzaW9uIiwic2lnbmF0dXJlUGFyYW1zIiwicGFyYW1ldGVyc1RvTWVyZ2UiLCJrIiwicGFyYW1ldGVyU3RyaW5nIiwic2lnbmF0dXJlU3RyaW5nIiwic2lnbmF0dXJlS2V5Iiwib2F1dGhfc2lnbmF0dXJlIiwiaGVhZGVycyIsImF1dGhIZWFkZXIiLCJ2YWx1ZSIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvT0F1dGgxQ2xpZW50LmpzIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG52YXIgT0F1dGggPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnTm8gb3B0aW9ucyBwYXNzZWQgdG8gT0F1dGgnKTtcbiAgfVxuICB0aGlzLmNvbnN1bWVyX2tleSA9IG9wdGlvbnMuY29uc3VtZXJfa2V5O1xuICB0aGlzLmNvbnN1bWVyX3NlY3JldCA9IG9wdGlvbnMuY29uc3VtZXJfc2VjcmV0O1xuICB0aGlzLmF1dGhfdG9rZW4gPSBvcHRpb25zLmF1dGhfdG9rZW47XG4gIHRoaXMuYXV0aF90b2tlbl9zZWNyZXQgPSBvcHRpb25zLmF1dGhfdG9rZW5fc2VjcmV0O1xuICB0aGlzLmhvc3QgPSBvcHRpb25zLmhvc3Q7XG4gIHRoaXMub2F1dGhfcGFyYW1zID0gb3B0aW9ucy5vYXV0aF9wYXJhbXMgfHwge307XG59O1xuXG5PQXV0aC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhdGgsIHBhcmFtcywgYm9keSkge1xuICB2YXIgcmVxdWVzdCA9IHRoaXMuYnVpbGRSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgcGFyYW1zLCBib2R5KTtcbiAgLy8gRW5jb2RlIHRoZSBib2R5IHByb3Blcmx5LCB0aGUgY3VycmVudCBQYXJzZSBJbXBsZW1lbnRhdGlvbiBkb24ndCBkbyBpdCBwcm9wZXJseVxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciBodHRwUmVxdWVzdCA9IGh0dHBzXG4gICAgICAucmVxdWVzdChyZXF1ZXN0LCBmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgIHZhciBkYXRhID0gJyc7XG4gICAgICAgIHJlcy5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bms7XG4gICAgICAgIH0pO1xuICAgICAgICByZXMub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAub24oJ2Vycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICByZWplY3QoJ0ZhaWxlZCB0byBtYWtlIGFuIE9BdXRoIHJlcXVlc3QnKTtcbiAgICAgIH0pO1xuICAgIGlmIChyZXF1ZXN0LmJvZHkpIHtcbiAgICAgIGh0dHBSZXF1ZXN0LndyaXRlKHJlcXVlc3QuYm9keSk7XG4gICAgfVxuICAgIGh0dHBSZXF1ZXN0LmVuZCgpO1xuICB9KTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5idWlsZFJlcXVlc3QgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpIHtcbiAgaWYgKHBhdGguaW5kZXhPZignLycpICE9IDApIHtcbiAgICBwYXRoID0gJy8nICsgcGF0aDtcbiAgfVxuICBpZiAocGFyYW1zICYmIE9iamVjdC5rZXlzKHBhcmFtcykubGVuZ3RoID4gMCkge1xuICAgIHBhdGggKz0gJz8nICsgT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcocGFyYW1zKTtcbiAgfVxuXG4gIHZhciByZXF1ZXN0ID0ge1xuICAgIGhvc3Q6IHRoaXMuaG9zdCxcbiAgICBwYXRoOiBwYXRoLFxuICAgIG1ldGhvZDogbWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gIH07XG5cbiAgdmFyIG9hdXRoX3BhcmFtcyA9IHRoaXMub2F1dGhfcGFyYW1zIHx8IHt9O1xuICBvYXV0aF9wYXJhbXMub2F1dGhfY29uc3VtZXJfa2V5ID0gdGhpcy5jb25zdW1lcl9rZXk7XG4gIGlmICh0aGlzLmF1dGhfdG9rZW4pIHtcbiAgICBvYXV0aF9wYXJhbXNbJ29hdXRoX3Rva2VuJ10gPSB0aGlzLmF1dGhfdG9rZW47XG4gIH1cblxuICByZXF1ZXN0ID0gT0F1dGguc2lnblJlcXVlc3QocmVxdWVzdCwgb2F1dGhfcGFyYW1zLCB0aGlzLmNvbnN1bWVyX3NlY3JldCwgdGhpcy5hdXRoX3Rva2VuX3NlY3JldCk7XG5cbiAgaWYgKGJvZHkgJiYgT2JqZWN0LmtleXMoYm9keSkubGVuZ3RoID4gMCkge1xuICAgIHJlcXVlc3QuYm9keSA9IE9BdXRoLmJ1aWxkUGFyYW1ldGVyU3RyaW5nKGJvZHkpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxuT0F1dGgucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChwYXRoLCBwYXJhbXMpIHtcbiAgcmV0dXJuIHRoaXMuc2VuZCgnR0VUJywgcGF0aCwgcGFyYW1zKTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5wb3N0ID0gZnVuY3Rpb24gKHBhdGgsIHBhcmFtcywgYm9keSkge1xuICByZXR1cm4gdGhpcy5zZW5kKCdQT1NUJywgcGF0aCwgcGFyYW1zLCBib2R5KTtcbn07XG5cbi8qXG5cdFByb3BlciBzdHJpbmcgJWVzY2FwZSBlbmNvZGluZ1xuKi9cbk9BdXRoLmVuY29kZSA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgLy8gICAgICAgZGlzY3VzcyBhdDogaHR0cDovL3BocGpzLm9yZy9mdW5jdGlvbnMvcmF3dXJsZW5jb2RlL1xuICAvLyAgICAgIG9yaWdpbmFsIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiB0cmF2Y1xuICAvLyAgICAgICAgIGlucHV0IGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiBNaWNoYWVsIEdyaWVyXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IFJhdGhlb3VzXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEtldmluIHZhbiBab25uZXZlbGQgKGh0dHA6Ly9rZXZpbi52YW56b25uZXZlbGQubmV0KVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBKb3Jpc1xuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgICAgICBub3RlOiBUaGlzIHJlZmxlY3RzIFBIUCA1LjMvNi4wKyBiZWhhdmlvclxuICAvLyAgICAgICAgICAgICBub3RlOiBQbGVhc2UgYmUgYXdhcmUgdGhhdCB0aGlzIGZ1bmN0aW9uIGV4cGVjdHMgdG8gZW5jb2RlIGludG8gVVRGLTggZW5jb2RlZCBzdHJpbmdzLCBhcyBmb3VuZCBvblxuICAvLyAgICAgICAgICAgICBub3RlOiBwYWdlcyBzZXJ2ZWQgYXMgVVRGLThcbiAgLy8gICAgICAgIGV4YW1wbGUgMTogcmF3dXJsZW5jb2RlKCdLZXZpbiB2YW4gWm9ubmV2ZWxkIScpO1xuICAvLyAgICAgICAgcmV0dXJucyAxOiAnS2V2aW4lMjB2YW4lMjBab25uZXZlbGQlMjEnXG4gIC8vICAgICAgICBleGFtcGxlIDI6IHJhd3VybGVuY29kZSgnaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQvJyk7XG4gIC8vICAgICAgICByZXR1cm5zIDI6ICdodHRwJTNBJTJGJTJGa2V2aW4udmFuem9ubmV2ZWxkLm5ldCUyRidcbiAgLy8gICAgICAgIGV4YW1wbGUgMzogcmF3dXJsZW5jb2RlKCdodHRwOi8vd3d3Lmdvb2dsZS5ubC9zZWFyY2g/cT1waHAuanMmaWU9dXRmLTgmb2U9dXRmLTgmYXE9dCZybHM9Y29tLnVidW50dTplbi1VUzp1bm9mZmljaWFsJmNsaWVudD1maXJlZm94LWEnKTtcbiAgLy8gICAgICAgIHJldHVybnMgMzogJ2h0dHAlM0ElMkYlMkZ3d3cuZ29vZ2xlLm5sJTJGc2VhcmNoJTNGcSUzRHBocC5qcyUyNmllJTNEdXRmLTglMjZvZSUzRHV0Zi04JTI2YXElM0R0JTI2cmxzJTNEY29tLnVidW50dSUzQWVuLVVTJTNBdW5vZmZpY2lhbCUyNmNsaWVudCUzRGZpcmVmb3gtYSdcblxuICBzdHIgPSAoc3RyICsgJycpLnRvU3RyaW5nKCk7XG5cbiAgLy8gVGlsZGUgc2hvdWxkIGJlIGFsbG93ZWQgdW5lc2NhcGVkIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiBQSFAgKGFzIHJlZmxlY3RlZCBiZWxvdyksIGJ1dCBpZiB5b3Ugd2FudCB0byByZWZsZWN0IGN1cnJlbnRcbiAgLy8gUEhQIGJlaGF2aW9yLCB5b3Ugd291bGQgbmVlZCB0byBhZGQgXCIucmVwbGFjZSgvfi9nLCAnJTdFJyk7XCIgdG8gdGhlIGZvbGxvd2luZy5cbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpXG4gICAgLnJlcGxhY2UoLyEvZywgJyUyMScpXG4gICAgLnJlcGxhY2UoLycvZywgJyUyNycpXG4gICAgLnJlcGxhY2UoL1xcKC9nLCAnJTI4JylcbiAgICAucmVwbGFjZSgvXFwpL2csICclMjknKVxuICAgIC5yZXBsYWNlKC9cXCovZywgJyUyQScpO1xufTtcblxuT0F1dGguc2lnbmF0dXJlTWV0aG9kID0gJ0hNQUMtU0hBMSc7XG5PQXV0aC52ZXJzaW9uID0gJzEuMCc7XG5cbi8qXG5cdEdlbmVyYXRlIGEgbm9uY2VcbiovXG5PQXV0aC5ub25jZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRleHQgPSAnJztcbiAgdmFyIHBvc3NpYmxlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5JztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDMwOyBpKyspIHRleHQgKz0gcG9zc2libGUuY2hhckF0KE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aCkpO1xuXG4gIHJldHVybiB0ZXh0O1xufTtcblxuT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcgPSBmdW5jdGlvbiAob2JqKSB7XG4gIC8vIFNvcnQga2V5cyBhbmQgZW5jb2RlIHZhbHVlc1xuICBpZiAob2JqKSB7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopLnNvcnQoKTtcblxuICAgIC8vIE1hcCBrZXk9dmFsdWUsIGpvaW4gdGhlbSBieSAmXG4gICAgcmV0dXJuIGtleXNcbiAgICAgIC5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4ga2V5ICsgJz0nICsgT0F1dGguZW5jb2RlKG9ialtrZXldKTtcbiAgICAgIH0pXG4gICAgICAuam9pbignJicpO1xuICB9XG5cbiAgcmV0dXJuICcnO1xufTtcblxuLypcblx0QnVpbGQgdGhlIHNpZ25hdHVyZSBzdHJpbmcgZnJvbSB0aGUgb2JqZWN0XG4qL1xuXG5PQXV0aC5idWlsZFNpZ25hdHVyZVN0cmluZyA9IGZ1bmN0aW9uIChtZXRob2QsIHVybCwgcGFyYW1ldGVycykge1xuICByZXR1cm4gW21ldGhvZC50b1VwcGVyQ2FzZSgpLCBPQXV0aC5lbmNvZGUodXJsKSwgT0F1dGguZW5jb2RlKHBhcmFtZXRlcnMpXS5qb2luKCcmJyk7XG59O1xuXG4vKlxuXHRSZXR1bnMgZW5jb2RlZCBITUFDLVNIQTEgZnJvbSBrZXkgYW5kIHRleHRcbiovXG5PQXV0aC5zaWduYXR1cmUgPSBmdW5jdGlvbiAodGV4dCwga2V5KSB7XG4gIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuICByZXR1cm4gT0F1dGguZW5jb2RlKGNyeXB0by5jcmVhdGVIbWFjKCdzaGExJywga2V5KS51cGRhdGUodGV4dCkuZGlnZXN0KCdiYXNlNjQnKSk7XG59O1xuXG5PQXV0aC5zaWduUmVxdWVzdCA9IGZ1bmN0aW9uIChyZXF1ZXN0LCBvYXV0aF9wYXJhbWV0ZXJzLCBjb25zdW1lcl9zZWNyZXQsIGF1dGhfdG9rZW5fc2VjcmV0KSB7XG4gIG9hdXRoX3BhcmFtZXRlcnMgPSBvYXV0aF9wYXJhbWV0ZXJzIHx8IHt9O1xuXG4gIC8vIFNldCBkZWZhdWx0IHZhbHVlc1xuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfbm9uY2UpIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX25vbmNlID0gT0F1dGgubm9uY2UoKTtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdGltZXN0YW1wKSB7XG4gICAgb2F1dGhfcGFyYW1ldGVycy5vYXV0aF90aW1lc3RhbXAgPSBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gIH1cbiAgaWYgKCFvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3NpZ25hdHVyZV9tZXRob2QpIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3NpZ25hdHVyZV9tZXRob2QgPSBPQXV0aC5zaWduYXR1cmVNZXRob2Q7XG4gIH1cbiAgaWYgKCFvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3ZlcnNpb24pIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3ZlcnNpb24gPSBPQXV0aC52ZXJzaW9uO1xuICB9XG5cbiAgaWYgKCFhdXRoX3Rva2VuX3NlY3JldCkge1xuICAgIGF1dGhfdG9rZW5fc2VjcmV0ID0gJyc7XG4gIH1cbiAgLy8gRm9yY2UgR0VUIG1ldGhvZCBpZiB1bnNldFxuICBpZiAoIXJlcXVlc3QubWV0aG9kKSB7XG4gICAgcmVxdWVzdC5tZXRob2QgPSAnR0VUJztcbiAgfVxuXG4gIC8vIENvbGxlY3QgIGFsbCB0aGUgcGFyYW1ldGVycyBpbiBvbmUgc2lnbmF0dXJlUGFyYW1ldGVycyBvYmplY3RcbiAgdmFyIHNpZ25hdHVyZVBhcmFtcyA9IHt9O1xuICB2YXIgcGFyYW1ldGVyc1RvTWVyZ2UgPSBbcmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QuYm9keSwgb2F1dGhfcGFyYW1ldGVyc107XG4gIGZvciAodmFyIGkgaW4gcGFyYW1ldGVyc1RvTWVyZ2UpIHtcbiAgICB2YXIgcGFyYW1ldGVycyA9IHBhcmFtZXRlcnNUb01lcmdlW2ldO1xuICAgIGZvciAodmFyIGsgaW4gcGFyYW1ldGVycykge1xuICAgICAgc2lnbmF0dXJlUGFyYW1zW2tdID0gcGFyYW1ldGVyc1trXTtcbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgYSBzdHJpbmcgYmFzZWQgb24gdGhlIHBhcmFtZXRlcnNcbiAgdmFyIHBhcmFtZXRlclN0cmluZyA9IE9BdXRoLmJ1aWxkUGFyYW1ldGVyU3RyaW5nKHNpZ25hdHVyZVBhcmFtcyk7XG5cbiAgLy8gQnVpbGQgdGhlIHNpZ25hdHVyZSBzdHJpbmdcbiAgdmFyIHVybCA9ICdodHRwczovLycgKyByZXF1ZXN0Lmhvc3QgKyAnJyArIHJlcXVlc3QucGF0aDtcblxuICB2YXIgc2lnbmF0dXJlU3RyaW5nID0gT0F1dGguYnVpbGRTaWduYXR1cmVTdHJpbmcocmVxdWVzdC5tZXRob2QsIHVybCwgcGFyYW1ldGVyU3RyaW5nKTtcbiAgLy8gSGFzaCB0aGUgc2lnbmF0dXJlIHN0cmluZ1xuICB2YXIgc2lnbmF0dXJlS2V5ID0gW09BdXRoLmVuY29kZShjb25zdW1lcl9zZWNyZXQpLCBPQXV0aC5lbmNvZGUoYXV0aF90b2tlbl9zZWNyZXQpXS5qb2luKCcmJyk7XG5cbiAgdmFyIHNpZ25hdHVyZSA9IE9BdXRoLnNpZ25hdHVyZShzaWduYXR1cmVTdHJpbmcsIHNpZ25hdHVyZUtleSk7XG5cbiAgLy8gU2V0IHRoZSBzaWduYXR1cmUgaW4gdGhlIHBhcmFtc1xuICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3NpZ25hdHVyZSA9IHNpZ25hdHVyZTtcbiAgaWYgKCFyZXF1ZXN0LmhlYWRlcnMpIHtcbiAgICByZXF1ZXN0LmhlYWRlcnMgPSB7fTtcbiAgfVxuXG4gIC8vIFNldCB0aGUgYXV0aG9yaXphdGlvbiBoZWFkZXJcbiAgdmFyIGF1dGhIZWFkZXIgPSBPYmplY3Qua2V5cyhvYXV0aF9wYXJhbWV0ZXJzKVxuICAgIC5zb3J0KClcbiAgICAubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHZhciB2YWx1ZSA9IG9hdXRoX3BhcmFtZXRlcnNba2V5XTtcbiAgICAgIHJldHVybiBrZXkgKyAnPVwiJyArIHZhbHVlICsgJ1wiJztcbiAgICB9KVxuICAgIC5qb2luKCcsICcpO1xuXG4gIHJlcXVlc3QuaGVhZGVycy5BdXRob3JpemF0aW9uID0gJ09BdXRoICcgKyBhdXRoSGVhZGVyO1xuXG4gIC8vIFNldCB0aGUgY29udGVudCB0eXBlIGhlYWRlclxuICByZXF1ZXN0LmhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc7XG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBPQXV0aDtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJQSxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxPQUFPLENBQUM7RUFDMUJDLE1BQU0sR0FBR0QsT0FBTyxDQUFDLFFBQVEsQ0FBQztBQUM1QixJQUFJRSxLQUFLLEdBQUdGLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQ0UsS0FBSztBQUV2QyxJQUFJQyxLQUFLLEdBQUcsU0FBQUEsQ0FBVUMsT0FBTyxFQUFFO0VBQzdCLElBQUksQ0FBQ0EsT0FBTyxFQUFFO0lBQ1osTUFBTSxJQUFJRixLQUFLLENBQUNHLEtBQUssQ0FBQ0gsS0FBSyxDQUFDRyxLQUFLLENBQUNDLHFCQUFxQixFQUFFLDRCQUE0QixDQUFDO0VBQ3hGO0VBQ0EsSUFBSSxDQUFDQyxZQUFZLEdBQUdILE9BQU8sQ0FBQ0csWUFBWTtFQUN4QyxJQUFJLENBQUNDLGVBQWUs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