@financialforcedev/orizuru-auth
Version:
Salesforce authentication for Heroku Node applications.
117 lines • 14.7 kB
JavaScript
;
/*
* Copyright (c) 2019, FinancialForce.com, inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
const __1 = require("../..");
const userinfo_1 = require("../userInfo/userinfo");
const accessToken_1 = require("./common/accessToken");
const fail_1 = require("./common/fail");
const instanceUrlRegex = new RegExp('(https:\/\/[^\/]*)');
/**
* Returns an express middleware that validates the OpenID Connect access token
* passed in an HTTP Authorization header and if successful sets the user object onto
* the request object.
*
* @fires EVENT_TOKEN_VALIDATED, EVENT_DENIED
* @param app The Orizuru server instance.
* @param [provider] The name of the auth provider. Defaults to 'salesforce'.
* @param [opts] The optional parameters used when requesting user information.
* @returns An express middleware that validates an access token.
*/
function createMiddleware(app, provider, opts) {
const internalProvider = provider || 'salesforce';
const _a = opts || accessToken_1.DEFAULT_MIDDLEWARE_OPTIONS, { setTokenOnContext } = _a, userInfoOptions = __rest(_a, ["setTokenOnContext"]);
const requestUserInfo = userinfo_1.createUserInfoRequester(app.options.authProvider[internalProvider]);
return async function validateToken(req, res, next) {
try {
const accessToken = accessToken_1.extractAccessToken(req);
const userInfo = await requestUserInfo(accessToken, userInfoOptions);
setUserOnRequest(app, req, userInfo);
accessToken_1.setAccessTokenOnRequest(req, accessToken, setTokenOnContext);
setInstanceUrlOnRequest(req, userInfo);
next();
}
catch (error) {
fail_1.fail(app, error, req, res, next);
}
};
}
exports.createMiddleware = createMiddleware;
/**
* Sets the user on the Orizuru context.
*
* @fires EVENT_TOKEN_VALIDATED
* @param app The Orizuru server instance.
* @param req The HTTP request.
* @param userInfo The user information.
*/
function setUserOnRequest(app, req, userInfo) {
const user = {
username: userInfo.preferred_username
};
if (userInfo.organization_id && typeof userInfo.organization_id === 'string') {
user.organizationId = userInfo.organization_id;
}
const orizuru = req.orizuru || {};
orizuru.user = user;
req.orizuru = orizuru;
app.emit(__1.EVENT_TOKEN_VALIDATED, `Token validated for user (${user.username}) [${req.ip}].`);
}
/**
* Sets the Salesforce instance URL on the Orizuru context.
*
* @param req The HTTP request.
* @param userInfo The user information.
*/
function setInstanceUrlOnRequest(req, userInfo) {
if (!userInfo.urls) {
return;
}
const orizuru = req.orizuru;
orizuru.salesforce = orizuru.salesforce || {};
const urls = Object.values(userInfo.urls);
while (urls.length) {
const url = urls.shift();
const regexResults = instanceUrlRegex.exec(url);
if (regexResults) {
orizuru.salesforce.instanceUrl = regexResults[0];
break;
}
}
req.orizuru = orizuru;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW5WYWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW5kZXgvbWlkZGxld2FyZS90b2tlblZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRzs7Ozs7Ozs7Ozs7OztBQVFILDZCQUE4RjtBQUU5RixtREFBK0Q7QUFDL0Qsc0RBQWtJO0FBQ2xJLHdDQUFxQztBQUVyQyxNQUFNLGdCQUFnQixHQUFHLElBQUksTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFFMUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQWdCLGdCQUFnQixDQUFDLEdBQW9CLEVBQUUsUUFBaUIsRUFBRSxJQUEwQztJQUVuSCxNQUFNLGdCQUFnQixHQUFHLFFBQVEsSUFBSSxZQUFZLENBQUM7SUFDbEQsTUFBTSxxREFBOEUsRUFBOUUsRUFBRSxpQkFBaUIsT0FBMkQsRUFBekQsbURBQXlELENBQUM7SUFFckYsTUFBTSxlQUFlLEdBQUcsa0NBQXVCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0lBRTVGLE9BQU8sS0FBSyxVQUFVLGFBQWEsQ0FBQyxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCO1FBRWxGLElBQUk7WUFFSCxNQUFNLFdBQVcsR0FBRyxnQ0FBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QyxNQUFNLFFBQVEsR0FBRyxNQUFNLGVBQWUsQ0FBQyxXQUFXLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFDckUsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUNyQyxxQ0FBdUIsQ0FBQyxHQUFHLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFDN0QsdUJBQXVCLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBRXZDLElBQUksRUFBRSxDQUFDO1NBRVA7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNmLFdBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDakM7SUFFRixDQUFDLENBQUM7QUFFSCxDQUFDO0FBekJELDRDQXlCQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLGdCQUFnQixDQUFDLEdBQW9CLEVBQUUsR0FBWSxFQUFFLFFBQXVDO0lBRXBHLE1BQU0sSUFBSSxHQUFtQjtRQUM1QixRQUFRLEVBQUUsUUFBUSxDQUFDLGtCQUFrQjtLQUNyQyxDQUFDO0lBRUYsSUFBSSxRQUFRLENBQUMsZUFBZSxJQUFJLE9BQU8sUUFBUSxDQUFDLGVBQWUsS0FBSyxRQUFRLEVBQUU7UUFDN0UsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDO0tBQy9DO0lBRUQsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFDbEMsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDcEIsR0FBRyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFFdEIsR0FBRyxDQUFDLElBQUksQ0FBQyx5QkFBcUIsRUFBRSw2QkFBNkIsSUFBSSxDQUFDLFFBQVEsTUFBTSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUU3RixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLHVCQUF1QixDQUFDLEdBQVksRUFBRSxRQUF1QztJQUVyRixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRTtRQUNuQixPQUFPO0tBQ1A7SUFFRCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsT0FBUSxDQUFDO0lBQzdCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7SUFFOUMsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUMsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFO1FBRW5CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUV6QixNQUFNLFlBQVksR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEQsSUFBSSxZQUFZLEVBQUU7WUFDakIsT0FBTyxDQUFDLFVBQVUsQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pELE1BQU07U0FDTjtLQUVEO0lBRUQsR0FBRyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7QUFFdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTksIEZpbmFuY2lhbEZvcmNlLmNvbSwgaW5jXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXG4gKiAgIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAtIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqIC0gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICogLSBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBGaW5hbmNpYWxGb3JjZS5jb20sIGluYyBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcbiAqICAgICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcbiAqICAgICAgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORFxuICogIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVNcbiAqICBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTFxuICogIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLFxuICogIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EU1xuICogIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWVxuICogIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuICogIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbi8qKlxuICogQG1vZHVsZSBtaWRkbGV3YXJlL3Rva2VuVmFsaWRhdG9yXG4gKi9cblxuaW1wb3J0IHsgTmV4dEZ1bmN0aW9uLCBSZXF1ZXN0LCBSZXF1ZXN0SGFuZGxlciwgUmVzcG9uc2UgfSBmcm9tICdAZmluYW5jaWFsZm9yY2VkZXYvb3JpenVydSc7XG5cbmltcG9ydCB7IEVWRU5UX1RPS0VOX1ZBTElEQVRFRCwgT3BlbklEVG9rZW5XaXRoU3RhbmRhcmRDbGFpbXMsIFVzZXJJbmZvT3B0aW9ucyB9IGZyb20gJy4uLy4uJztcbmltcG9ydCB7IFNhbGVzZm9yY2VVc2VyIH0gZnJvbSAnLi4vY2xpZW50L3NhbGVzZm9yY2UnO1xuaW1wb3J0IHsgY3JlYXRlVXNlckluZm9SZXF1ZXN0ZXIgfSBmcm9tICcuLi91c2VySW5mby91c2VyaW5mbyc7XG5pbXBvcnQgeyBERUZBVUxUX01JRERMRVdBUkVfT1BUSU9OUywgZXh0cmFjdEFjY2Vzc1Rva2VuLCBNaWRkbGV3YXJlT3B0aW9ucywgc2V0QWNjZXNzVG9rZW5PblJlcXVlc3QgfSBmcm9tICcuL2NvbW1vbi9hY2Nlc3NUb2tlbic7XG5pbXBvcnQgeyBmYWlsIH0gZnJvbSAnLi9jb21tb24vZmFpbCc7XG5cbmNvbnN0IGluc3RhbmNlVXJsUmVnZXggPSBuZXcgUmVnRXhwKCcoaHR0cHM6XFwvXFwvW15cXC9dKiknKTtcblxuLyoqXG4gKiBSZXR1cm5zIGFuIGV4cHJlc3MgbWlkZGxld2FyZSB0aGF0IHZhbGlkYXRlcyB0aGUgT3BlbklEIENvbm5lY3QgYWNjZXNzIHRva2VuXG4gKiBwYXNzZWQgaW4gYW4gSFRUUCBBdXRob3JpemF0aW9uIGhlYWRlciBhbmQgaWYgc3VjY2Vzc2Z1bCBzZXRzIHRoZSB1c2VyIG9iamVjdCBvbnRvXG4gKiB0aGUgcmVxdWVzdCBvYmplY3QuXG4gKlxuICogQGZpcmVzIEVWRU5UX1RPS0VOX1ZBTElEQVRFRCwgRVZFTlRfREVOSUVEXG4gKiBAcGFyYW0gYXBwIFRoZSBPcml6dXJ1IHNlcnZlciBpbnN0YW5jZS5cbiAqIEBwYXJhbSBbcHJvdmlkZXJdIFRoZSBuYW1lIG9mIHRoZSBhdXRoIHByb3ZpZGVyLiBEZWZhdWx0cyB0byAnc2FsZXNmb3JjZScuXG4gKiBAcGFyYW0gW29wdHNdIFRoZSBvcHRpb25hbCBwYXJhbWV0ZXJzIHVzZWQgd2hlbiByZXF1ZXN0aW5nIHVzZXIgaW5mb3JtYXRpb24uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzIG1pZGRsZXdhcmUgdGhhdCB2YWxpZGF0ZXMgYW4gYWNjZXNzIHRva2VuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWlkZGxld2FyZShhcHA6IE9yaXp1cnUuSVNlcnZlciwgcHJvdmlkZXI/OiBzdHJpbmcsIG9wdHM/OiBNaWRkbGV3YXJlT3B0aW9ucyAmIFVzZXJJbmZvT3B0aW9ucyk6IFJlcXVlc3RIYW5kbGVyIHtcblxuXHRjb25zdCBpbnRlcm5hbFByb3ZpZGVyID0gcHJvdmlkZXIgfHwgJ3NhbGVzZm9yY2UnO1xuXHRjb25zdCB7IHNldFRva2VuT25Db250ZXh0LCAuLi51c2VySW5mb09wdGlvbnMgfSA9IG9wdHMgfHwgREVGQVVMVF9NSURETEVXQVJFX09QVElPTlM7XG5cblx0Y29uc3QgcmVxdWVzdFVzZXJJbmZvID0gY3JlYXRlVXNlckluZm9SZXF1ZXN0ZXIoYXBwLm9wdGlvbnMuYXV0aFByb3ZpZGVyW2ludGVybmFsUHJvdmlkZXJdKTtcblxuXHRyZXR1cm4gYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVUb2tlbihyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikge1xuXG5cdFx0dHJ5IHtcblxuXHRcdFx0Y29uc3QgYWNjZXNzVG9rZW4gPSBleHRyYWN0QWNjZXNzVG9rZW4ocmVxKTtcblx0XHRcdGNvbnN0IHVzZXJJbmZvID0gYXdhaXQgcmVxdWVzdFVzZXJJbmZvKGFjY2Vzc1Rva2VuLCB1c2VySW5mb09wdGlvbnMpO1xuXHRcdFx0c2V0VXNlck9uUmVxdWVzdChhcHAsIHJlcSwgdXNlckluZm8pO1xuXHRcdFx0c2V0QWNjZXNzVG9rZW5PblJlcXVlc3QocmVxLCBhY2Nlc3NUb2tlbiwgc2V0VG9rZW5PbkNvbnRleHQpO1xuXHRcdFx0c2V0SW5zdGFuY2VVcmxPblJlcXVlc3QocmVxLCB1c2VySW5mbyk7XG5cblx0XHRcdG5leHQoKTtcblxuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRmYWlsKGFwcCwgZXJyb3IsIHJlcSwgcmVzLCBuZXh0KTtcblx0XHR9XG5cblx0fTtcblxufVxuXG4vKipcbiAqIFNldHMgdGhlIHVzZXIgb24gdGhlIE9yaXp1cnUgY29udGV4dC5cbiAqXG4gKiBAZmlyZXMgRVZFTlRfVE9LRU5fVkFMSURBVEVEXG4gKiBAcGFyYW0gYXBwIFRoZSBPcml6dXJ1IHNlcnZlciBpbnN0YW5jZS5cbiAqIEBwYXJhbSByZXEgVGhlIEhUVFAgcmVxdWVzdC5cbiAqIEBwYXJhbSB1c2VySW5mbyBUaGUgdXNlciBpbmZvcm1hdGlvbi5cbiAqL1xuZnVuY3Rpb24gc2V0VXNlck9uUmVxdWVzdChhcHA6IE9yaXp1cnUuSVNlcnZlciwgcmVxOiBSZXF1ZXN0LCB1c2VySW5mbzogT3BlbklEVG9rZW5XaXRoU3RhbmRhcmRDbGFpbXMpIHtcblxuXHRjb25zdCB1c2VyOiBTYWxlc2ZvcmNlVXNlciA9IHtcblx0XHR1c2VybmFtZTogdXNlckluZm8ucHJlZmVycmVkX3VzZXJuYW1lXG5cdH07XG5cblx0aWYgKHVzZXJJbmZvLm9yZ2FuaXphdGlvbl9pZCAmJiB0eXBlb2YgdXNlckluZm8ub3JnYW5pemF0aW9uX2lkID09PSAnc3RyaW5nJykge1xuXHRcdHVzZXIub3JnYW5pemF0aW9uSWQgPSB1c2VySW5mby5vcmdhbml6YXRpb25faWQ7XG5cdH1cblxuXHRjb25zdCBvcml6dXJ1ID0gcmVxLm9yaXp1cnUgfHwge307XG5cdG9yaXp1cnUudXNlciA9IHVzZXI7XG5cdHJlcS5vcml6dXJ1ID0gb3JpenVydTtcblxuXHRhcHAuZW1pdChFVkVOVF9UT0tFTl9WQUxJREFURUQsIGBUb2tlbiB2YWxpZGF0ZWQgZm9yIHVzZXIgKCR7dXNlci51c2VybmFtZX0pIFske3JlcS5pcH1dLmApO1xuXG59XG5cbi8qKlxuICogU2V0cyB0aGUgU2FsZXNmb3JjZSBpbnN0YW5jZSBVUkwgb24gdGhlIE9yaXp1cnUgY29udGV4dC5cbiAqXG4gKiBAcGFyYW0gcmVxIFRoZSBIVFRQIHJlcXVlc3QuXG4gKiBAcGFyYW0gdXNlckluZm8gVGhlIHVzZXIgaW5mb3JtYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHNldEluc3RhbmNlVXJsT25SZXF1ZXN0KHJlcTogUmVxdWVzdCwgdXNlckluZm86IE9wZW5JRFRva2VuV2l0aFN0YW5kYXJkQ2xhaW1zKSB7XG5cblx0aWYgKCF1c2VySW5mby51cmxzKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Y29uc3Qgb3JpenVydSA9IHJlcS5vcml6dXJ1ITtcblx0b3JpenVydS5zYWxlc2ZvcmNlID0gb3JpenVydS5zYWxlc2ZvcmNlIHx8IHt9O1xuXG5cdGNvbnN0IHVybHMgPSBPYmplY3QudmFsdWVzKHVzZXJJbmZvLnVybHMpO1xuXHR3aGlsZSAodXJscy5sZW5ndGgpIHtcblxuXHRcdGNvbnN0IHVybCA9IHVybHMuc2hpZnQoKTtcblxuXHRcdGNvbnN0IHJlZ2V4UmVzdWx0cyA9IGluc3RhbmNlVXJsUmVnZXguZXhlYyh1cmwpO1xuXHRcdGlmIChyZWdleFJlc3VsdHMpIHtcblx0XHRcdG9yaXp1cnUuc2FsZXNmb3JjZS5pbnN0YW5jZVVybCA9IHJlZ2V4UmVzdWx0c1swXTtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHR9XG5cblx0cmVxLm9yaXp1cnUgPSBvcml6dXJ1O1xuXG59XG4iXX0=