UNPKG

kwikid-forms

Version:

KwikID's JSON Configuration based Forms Renderer and Builder

251 lines 36.2 kB
import { __awaiter, __decorate } from "tslib"; /* eslint-disable no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */ import axios from "axios"; import { decryptWithAES, encryptWithAES, isNotEmptyValue, logMethod } from "kwikid-toolkit"; import { Observable } from "rxjs"; import { v4 as uuidv4 } from "uuid"; import { resolveFormsStorageConfig, resolveFormsStorageString } from "../helpers/forms-storage.helper"; export class KwikIDFormViewApiService { constructor() { this.bytecode = [0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38]; this.reduxData = {}; this.userConfig = undefined; } setStorageContext(reduxData = {}, userConfig) { this.reduxData = reduxData !== null && reduxData !== void 0 ? reduxData : {}; this.userConfig = userConfig; } /** Fresh config from host utilityFlags / formsStorage on every resolve. */ getStorageConfig() { return resolveFormsStorageConfig(this.userConfig); } // Function to derive logic from data dataDerivativeLogic(data) { if (isNotEmptyValue(data)) { const dataString = JSON.stringify(data); const charCounts = {}; const targetCharacters = ["a", "i", "p", "t"]; // Count occurrences of target characters in the data string for (const char of dataString) { if (targetCharacters.includes(char)) { charCounts[char] = (charCounts[char] || 0) + 1; } } // Construct the output string based on the character counts const outputString = targetCharacters .map((char) => char + (charCounts[char] || 0)) .join(""); return outputString; } return undefined; } // Function to preprocess header data preProcessHeader(headerData, isVerifySignature) { if (!headerData) { headerData = {}; } if (!headerData.headers) { headerData.headers = {}; } // Generate a unique identifier if signature verification is required if (isVerifySignature) { headerData.headers.xrid = uuidv4(); } const sessionId = resolveFormsStorageString("session_id", this.reduxData, this.getStorageConfig()); if (sessionId) { headerData.headers.ses = sessionId; } return headerData; } // Function to verify the signature verifySignature(data, header, url, isVerifySignature) { return new Promise((resolve, reject) => { // Check if the signature is disabled if (!isVerifySignature) { resolve(true); } else if (!data) { // Check if data is invalid resolve(true); } else if (isVerifySignature && header && !(header === null || header === void 0 ? void 0 : header.sig)) { // Check if the signature is missing in headers when authentication is not skipped reject(false); } else if (isVerifySignature && header && (header === null || header === void 0 ? void 0 : header.sig)) { // Verify the signature when public key and header with signature are present and authentication is not skipped // Extract the signature and decode it let signature = header.sig.split(".")[0]; const rawSignature = atob(signature); // Split the decoded signature to get the parts signature = rawSignature.split(".")[0]; const exp = `${rawSignature.split(".")[1]}000`; // Expiration time in milliseconds const iat = `${rawSignature.split(".")[2]}000`; // Issued at time in milliseconds // Check if the signature is valid if (signature) { // Check if the current time is before the expiration time const dateValue = new Date().valueOf(); const dateCheck = dateValue < parseInt(exp, 10); // Check if the signature matches the data const res = signature === data; // Resolve the promise if the signature is valid and the date check passes if (res && dateCheck) { resolve(res); } else { // Reject the promise if the signature is invalid or the date check fails reject(res); } } else { // Reject the promise if the signature is not in the required format reject(false); } } else { // Resolve the promise if the signature is missing in headers resolve(true); } }); } // Function to perform POST request post(url, body, headerData, isEncrypt = false, isDecrypt = false, isVerifySignature = false, isSkipHeaderAlteration = false) { let preProcessedHeader = headerData; // Preprocess header data unless instructed to skip if (!isSkipHeaderAlteration) { preProcessedHeader = this.preProcessHeader(headerData, isVerifySignature); } else { preProcessedHeader.observe = "response"; } // Encrypt body if required if (isEncrypt) { body = encryptWithAES(JSON.stringify(body)); } return new Observable((subscriber) => { axios.post(url, body, headerData).then((res) => __awaiter(this, void 0, void 0, function* () { let { data } = res; // Decrypt response if required if (data && isDecrypt) { const encryptedResponse = data; const decryptedResponse = yield decryptWithAES(encryptedResponse); data = JSON.parse(decryptedResponse); res.data = data; } // Verify signature and handle response this.verifySignature(this.dataDerivativeLogic(data), res === null || res === void 0 ? void 0 : res.headers, url, isVerifySignature) .then((verification) => { subscriber.next(res); subscriber.complete(); }) .catch((err) => { subscriber.error(err === null || err === void 0 ? void 0 : err.response); }); }), (err) => __awaiter(this, void 0, void 0, function* () { var _a, _b; let data = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data; // Decrypt error response if required if (data && isDecrypt) { const encryptedResponse = data; const decryptedResponse = yield decryptWithAES(encryptedResponse); data = JSON.parse(decryptedResponse); err.response.data = data; } // Verify signature and handle response this.verifySignature(this.dataDerivativeLogic(data), (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.headers, url, isVerifySignature) .then((verification) => { subscriber.error(err === null || err === void 0 ? void 0 : err.response); }) .catch((err) => { subscriber.error(err === null || err === void 0 ? void 0 : err.response); }); })); }); } // Function to perform GET request get(url, headerData = undefined, isDecrypt = false, isVerifySignature = false, isSkipHeaderAlteration = false) { let preProcessedHeader = headerData; // Preprocess header data unless instructed to skip if (!isSkipHeaderAlteration) { preProcessedHeader = this.preProcessHeader(headerData, isVerifySignature); } else { preProcessedHeader.observe = "response"; } return new Observable((subscriber) => { axios.get(url, preProcessedHeader).then((res) => __awaiter(this, void 0, void 0, function* () { let { data } = res; // Decrypt response if required if (isDecrypt) { const encryptedResponse = data; const decryptedResponse = yield decryptWithAES(encryptedResponse); data = JSON.parse(decryptedResponse); res.data = data; } // Verify signature and handle response this.verifySignature(this.dataDerivativeLogic(data), res === null || res === void 0 ? void 0 : res.headers, url, isVerifySignature) .then((verification) => { subscriber.next(res); subscriber.complete(); }) .catch((err) => { subscriber.error(err === null || err === void 0 ? void 0 : err.response); }); }), (err) => __awaiter(this, void 0, void 0, function* () { var _a, _b; let data = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data; // Decrypt error response if required if (data && isDecrypt) { const encryptedResponse = data; const decryptedResponse = yield decryptWithAES(encryptedResponse); data = JSON.parse(decryptedResponse); err.response.data = data; } // Verify signature and handle response this.verifySignature(this.dataDerivativeLogic(data), (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.headers, url, isVerifySignature) .then((verification) => { subscriber.error(err === null || err === void 0 ? void 0 : err.response); }) .catch((err) => { subscriber.error(err === null || err === void 0 ? void 0 : err.response); }); })); }); } // Function to execute API call based on method type executeApiCall(url, method, body, headers, isEncrypt, isDecrypt, isVerifySignature) { return new Promise((resolve) => { if (method === "GET") { this.get(url, { headers }, isDecrypt, isVerifySignature).subscribe((res) => { resolve(res); }, (err) => { resolve(err); }); } else { this.post(url, body, { headers }, isEncrypt, isDecrypt, isVerifySignature).subscribe((res) => { resolve(res); }, (err) => { resolve(err); }); } }); } } __decorate([ logMethod ], KwikIDFormViewApiService.prototype, "dataDerivativeLogic", null); __decorate([ logMethod ], KwikIDFormViewApiService.prototype, "preProcessHeader", null); __decorate([ logMethod ], KwikIDFormViewApiService.prototype, "verifySignature", null); __decorate([ logMethod ], KwikIDFormViewApiService.prototype, "post", null); __decorate([ logMethod ], KwikIDFormViewApiService.prototype, "get", null); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS12aWV3LmFwaS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva3dpa2lkLWZvcm1zL3NyYy9saWIvcmVuZGVyZXIvZm9ybS12aWV3L2Zvcm0tdmlldy5hcGkuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsbUNBQW1DO0FBQ25DLHNEQUFzRDtBQUN0RCxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTyxFQUNMLGNBQWMsRUFDZCxjQUFjLEVBQ2QsZUFBZSxFQUNmLFNBQVMsRUFDVixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLEVBQUUsSUFBSSxNQUFNLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUVMLHlCQUF5QixFQUN6Qix5QkFBeUIsRUFDMUIsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6QyxNQUFNLE9BQU8sd0JBQXdCO0lBQXJDO1FBQ1UsYUFBUSxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTVELGNBQVMsR0FBNEIsRUFBRSxDQUFDO1FBRXhDLGVBQVUsR0FBUSxTQUFTLENBQUM7SUEyVHRDLENBQUM7SUF6VEMsaUJBQWlCLENBQ2YsWUFBcUMsRUFBRSxFQUN2QyxVQUFnQjtRQUVoQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsYUFBVCxTQUFTLGNBQVQsU0FBUyxHQUFJLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBRUQsMkVBQTJFO0lBQ25FLGdCQUFnQjtRQUN0QixPQUFPLHlCQUF5QixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJ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QyxFQUNELENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ04sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNmLENBQUMsQ0FDRixDQUFDO2FBQ0g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTFTQztJQURDLFNBQVM7bUVBcUJUO0FBSUQ7SUFEQyxTQUFTO2dFQXdCVDtBQUlEO0lBREMsU0FBUzsrREFrRFQ7QUFJRDtJQURDLFNBQVM7b0RBK0VUO0FBSUQ7SUFEQyxTQUFTO21EQXdFVCIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmltcG9ydCBheGlvcyBmcm9tIFwiYXhpb3NcIjtcbmltcG9ydCB7XG4gIGRlY3J5cHRXaXRoQUVTLFxuICBlbmNyeXB0V2l0aEFFUyxcbiAgaXNOb3RFbXB0eVZhbHVlLFxuICBsb2dNZXRob2Rcbn0gZnJvbSBcImt3aWtpZC10b29sa2l0XCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQge1xuICBGb3Jtc1N0b3JhZ2VDb25maWcsXG4gIHJlc29sdmVGb3Jtc1N0b3JhZ2VDb25maWcsXG4gIHJlc29sdmVGb3Jtc1N0b3JhZ2VTdHJpbmdcbn0gZnJvbSBcIi4uL2hlbHBlcnMvZm9ybXMtc3RvcmFnZS5oZWxwZXJcIjtcblxuZXhwb3J0IGNsYXNzIEt3aWtJREZvcm1WaWV3QXBpU2VydmljZSB7XG4gIHByaXZhdGUgYnl0ZWNvZGUgPSBbMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOF07XG5cbiAgcHJpdmF0ZSByZWR1eERhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgcHJpdmF0ZSB1c2VyQ29uZmlnOiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgc2V0U3RvcmFnZUNvbnRleHQoXG4gICAgcmVkdXhEYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9LFxuICAgIHVzZXJDb25maWc/OiBhbnlcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5yZWR1eERhdGEgPSByZWR1eERhdGEgPz8ge307XG4gICAgdGhpcy51c2VyQ29uZmlnID0gdXNlckNvbmZpZztcbiAgfVxuXG4gIC8qKiBGcmVzaCBjb25maWcgZnJvbSBob3N0IHV0aWxpdHlGbGFncyAvIGZvcm1zU3RvcmFnZSBvbiBldmVyeSByZXNvbHZlLiAqL1xuICBwcml2YXRlIGdldFN0b3JhZ2VDb25maWcoKTogRm9ybXNTdG9yYWdlQ29uZmlnIHtcbiAgICByZXR1cm4gcmVzb2x2ZUZvcm1zU3RvcmFnZUNvbmZpZyh0aGlzLnVzZXJDb25maWcpO1xuICB9XG5cbiAgLy8gRnVuY3Rpb24gdG8gZGVyaXZlIGxvZ2ljIGZyb20gZGF0YVxuICBAbG9nTWV0aG9kXG4gIGRhdGFEZXJpdmF0aXZlTG9naWMoZGF0YSkge1xuICAgIGlmIChpc05vdEVtcHR5VmFsdWUoZGF0YSkpIHtcbiAgICAgIGNvbnN0IGRhdGFTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICAgIGNvbnN0IGNoYXJDb3VudHMgPSB7fTtcbiAgICAgIGNvbnN0IHRhcmdldENoYXJhY3RlcnMgPSBbXCJhXCIsIFwiaVwiLCBcInBcIiwgXCJ0XCJdO1xuXG4gICAgICAvLyBDb3VudCBvY2N1cnJlbmNlcyBvZiB0YXJnZXQgY2hhcmFjdGVycyBpbiB0aGUgZGF0YSBzdHJpbmdcbiAgICAgIGZvciAoY29uc3QgY2hhciBvZiBkYXRhU3RyaW5nKSB7XG4gICAgICAgIGlmICh0YXJnZXRDaGFyYWN0ZXJzLmluY2x1ZGVzKGNoYXIpKSB7XG4gICAgICAgICAgY2hhckNvdW50c1tjaGFyXSA9IChjaGFyQ291bnRzW2NoYXJdIHx8IDApICsgMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDb25zdHJ1Y3QgdGhlIG91dHB1dCBzdHJpbmcgYmFzZWQgb24gdGhlIGNoYXJhY3RlciBjb3VudHNcbiAgICAgIGNvbnN0IG91dHB1dFN0cmluZyA9IHRhcmdldENoYXJhY3RlcnNcbiAgICAgICAgLm1hcCgoY2hhcikgPT4gY2hhciArIChjaGFyQ291bnRzW2NoYXJdIHx8IDApKVxuICAgICAgICAuam9pbihcIlwiKTtcbiAgICAgIHJldHVybiBvdXRwdXRTdHJpbmc7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBGdW5jdGlvbiB0byBwcmVwcm9jZXNzIGhlYWRlciBkYXRhXG4gIEBsb2dNZXRob2RcbiAgcHJlUHJvY2Vzc0hlYWRlcihoZWFkZXJEYXRhOiBhbnksIGlzVmVyaWZ5U2lnbmF0dXJlOiBib29sZWFuKTogYW55IHtcbiAgICBpZiAoIWhlYWRlckRhdGEpIHtcbiAgICAgIGhlYWRlckRhdGEgPSB7fTtcbiAgICB9XG4gICAgaWYgKCFoZWFkZXJEYXRhLmhlYWRlcnMpIHtcbiAgICAgIGhlYWRlckRhdGEuaGVhZGVycyA9IHt9O1xuICAgIH1cblxuICAgIC8vIEdlbmVyYXRlIGEgdW5pcXVlIGlkZW50aWZpZXIgaWYgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBpcyByZXF1aXJlZFxuICAgIGlmIChpc1ZlcmlmeVNpZ25hdHVyZSkge1xuICAgICAgaGVhZGVyRGF0YS5oZWFkZXJzLnhyaWQgPSB1dWlkdjQoKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZXNzaW9uSWQgPSByZXNvbHZlRm9ybXNTdG9yYWdlU3RyaW5nKFxuICAgICAgXCJzZXNzaW9uX2lkXCIsXG4gICAgICB0aGlzLnJlZHV4RGF0YSxcbiAgICAgIHRoaXMuZ2V0U3RvcmFnZUNvbmZpZygpXG4gICAgKTtcbiAgICBpZiAoc2Vzc2lvbklkKSB7XG4gICAgICBoZWFkZXJEYXRhLmhlYWRlcnMuc2VzID0gc2Vzc2lvbklkO1xuICAgIH1cblxuICAgIHJldHVybiBoZWFkZXJEYXRhO1xuICB9XG5cbiAgLy8gRnVuY3Rpb24gdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmVcbiAgQGxvZ01ldGhvZFxuICB2ZXJpZnlTaWduYXR1cmUoZGF0YSwgaGVhZGVyLCB1cmwsIGlzVmVyaWZ5U2lnbmF0dXJlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIENoZWNrIGlmIHRoZSBzaWduYXR1cmUgaXMgZGlzYWJsZWRcbiAgICAgIGlmICghaXNWZXJpZnlTaWduYXR1cmUpIHtcbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAoIWRhdGEpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgZGF0YSBpcyBpbnZhbGlkXG4gICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGlzVmVyaWZ5U2lnbmF0dXJlICYmIGhlYWRlciAmJiAhaGVhZGVyPy5zaWcpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHNpZ25hdHVyZSBpcyBtaXNzaW5nIGluIGhlYWRlcnMgd2hlbiBhdXRoZW50aWNhdGlvbiBpcyBub3Qgc2tpcHBlZFxuICAgICAgICByZWplY3QoZmFsc2UpO1xuICAgICAgfSBlbHNlIGlmIChpc1ZlcmlmeVNpZ25hdHVyZSAmJiBoZWFkZXIgJiYgaGVhZGVyPy5zaWcpIHtcbiAgICAgICAgLy8gVmVyaWZ5IHRoZSBzaWduYXR1cmUgd2hlbiBwdWJsaWMga2V5IGFuZCBoZWFkZXIgd2l0aCBzaWduYXR1cmUgYXJlIHByZXNlbnQgYW5kIGF1dGhlbnRpY2F0aW9uIGlzIG5vdCBza2lwcGVkXG5cbiAgICAgICAgLy8gRXh0cmFjdCB0aGUgc2lnbmF0dXJlIGFuZCBkZWNvZGUgaXRcbiAgICAgICAgbGV0IHNpZ25hdHVyZSA9IGhlYWRlci5zaWcuc3BsaXQoXCIuXCIpWzBdO1xuICAgICAgICBjb25zdCByYXdTaWduYXR1cmUgPSBhdG9iKHNpZ25hdHVyZSk7XG5cbiAgICAgICAgLy8gU3BsaXQgdGhlIGRlY29kZWQgc2lnbmF0dXJlIHRvIGdldCB0aGUgcGFydHNcbiAgICAgICAgc2lnbmF0dXJlID0gcmF3U2lnbmF0dXJlLnNwbGl0KFwiLlwiKVswXTtcbiAgICAgICAgY29uc3QgZXhwID0gYCR7cmF3U2lnbmF0dXJlLnNwbGl0KFwiLlwiKVsxXX0wMDBgOyAvLyBFeHBpcmF0aW9uIHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gICAgICAgIGNvbnN0IGlhdCA9IGAke3Jhd1NpZ25hdHVyZS5zcGxpdChcIi5cIilbMl19MDAwYDsgLy8gSXNzdWVkIGF0IHRpbWUgaW4gbWlsbGlzZWNvbmRzXG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHNpZ25hdHVyZSBpcyB2YWxpZFxuICAgICAgICBpZiAoc2lnbmF0dXJlKSB7XG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGN1cnJlbnQgdGltZSBpcyBiZWZvcmUgdGhlIGV4cGlyYXRpb24gdGltZVxuICAgICAgICAgIGNvbnN0IGRhdGVWYWx1ZSA9IG5ldyBEYXRlKCkudmFsdWVPZigpO1xuICAgICAgICAgIGNvbnN0IGRhdGVDaGVjayA9IGRhdGVWYWx1ZSA8IHBhcnNlSW50KGV4cCwgMTApO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzIHRoZSBkYXRhXG4gICAgICAgICAgY29uc3QgcmVzID0gc2lnbmF0dXJlID09PSBkYXRhO1xuXG4gICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgcHJvbWlzZSBpZiB0aGUgc2lnbmF0dXJlIGlzIHZhbGlkIGFuZCB0aGUgZGF0ZSBjaGVjayBwYXNzZXNcbiAgICAgICAgICBpZiAocmVzICYmIGRhdGVDaGVjaykge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZWplY3QgdGhlIHByb21pc2UgaWYgdGhlIHNpZ25hdHVyZSBpcyBpbnZhbGlkIG9yIHRoZSBkYXRlIGNoZWNrIGZhaWxzXG4gICAgICAgICAgICByZWplY3QocmVzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVqZWN0IHRoZSBwcm9taXNlIGlmIHRoZSBzaWduYXR1cmUgaXMgbm90IGluIHRoZSByZXF1aXJlZCBmb3JtYXRcblxuICAgICAgICAgIHJlamVjdChmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlc29sdmUgdGhlIHByb21pc2UgaWYgdGhlIHNpZ25hdHVyZSBpcyBtaXNzaW5nIGluIGhlYWRlcnNcbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZ1bmN0aW9uIHRvIHBlcmZvcm0gUE9TVCByZXF1ZXN0XG4gIEBsb2dNZXRob2RcbiAgcG9zdChcbiAgICB1cmwsXG4gICAgYm9keSxcbiAgICBoZWFkZXJEYXRhLFxuICAgIGlzRW5jcnlwdCA9IGZhbHNlLFxuICAgIGlzRGVjcnlwdCA9IGZhbHNlLFxuICAgIGlzVmVyaWZ5U2lnbmF0dXJlID0gZmFsc2UsXG4gICAgaXNTa2lwSGVhZGVyQWx0ZXJhdGlvbiA9IGZhbHNlXG4gICkge1xuICAgIGxldCBwcmVQcm9jZXNzZWRIZWFkZXIgPSBoZWFkZXJEYXRhO1xuXG4gICAgLy8gUHJlcHJvY2VzcyBoZWFkZXIgZGF0YSB1bmxlc3MgaW5zdHJ1Y3RlZCB0byBza2lwXG4gICAgaWYgKCFpc1NraXBIZWFkZXJBbHRlcmF0aW9uKSB7XG4gICAgICBwcmVQcm9jZXNzZWRIZWFkZXIgPSB0aGlzLnByZVByb2Nlc3NIZWFkZXIoaGVhZGVyRGF0YSwgaXNWZXJpZnlTaWduYXR1cmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcmVQcm9jZXNzZWRIZWFkZXIub2JzZXJ2ZSA9IFwicmVzcG9uc2VcIjtcbiAgICB9XG5cbiAgICAvLyBFbmNyeXB0IGJvZHkgaWYgcmVxdWlyZWRcbiAgICBpZiAoaXNFbmNyeXB0KSB7XG4gICAgICBib2R5ID0gZW5jcnlwdFdpdGhBRVMoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgoc3Vic2NyaWJlcikgPT4ge1xuICAgICAgYXhpb3MucG9zdCh1cmwsIGJvZHksIGhlYWRlckRhdGEpLnRoZW4oXG4gICAgICAgIGFzeW5jIChyZXMpID0+IHtcbiAgICAgICAgICBsZXQgeyBkYXRhIH0gPSByZXM7XG5cbiAgICAgICAgICAvLyBEZWNyeXB0IHJlc3BvbnNlIGlmIHJlcXVpcmVkXG4gICAgICAgICAgaWYgKGRhdGEgJiYgaXNEZWNyeXB0KSB7XG4gICAgICAgICAgICBjb25zdCBlbmNyeXB0ZWRSZXNwb25zZSA9IGRhdGE7XG4gICAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRSZXNwb25zZSA9IGF3YWl0IGRlY3J5cHRXaXRoQUVTKGVuY3J5cHRlZFJlc3BvbnNlKTtcbiAgICAgICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRlY3J5cHRlZFJlc3BvbnNlKTtcbiAgICAgICAgICAgIHJlcy5kYXRhID0gZGF0YTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBWZXJpZnkgc2lnbmF0dXJlIGFuZCBoYW5kbGUgcmVzcG9uc2VcbiAgICAgICAgICB0aGlzLnZlcmlmeVNpZ25hdHVyZShcbiAgICAgICAgICAgIHRoaXMuZGF0YURlcml2YXRpdmVMb2dpYyhkYXRhKSxcbiAgICAgICAgICAgIHJlcz8uaGVhZGVycyxcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHZlcmlmaWNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQocmVzKTtcbiAgICAgICAgICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKGVycikgPT4ge1xuICAgICAgICAgIGxldCBkYXRhID0gZXJyPy5yZXNwb25zZT8uZGF0YTtcblxuICAgICAgICAgIC8vIERlY3J5cHQgZXJyb3IgcmVzcG9uc2UgaWYgcmVxdWlyZWRcbiAgICAgICAgICBpZiAoZGF0YSAmJiBpc0RlY3J5cHQpIHtcbiAgICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZFJlc3BvbnNlID0gZGF0YTtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZFJlc3BvbnNlID0gYXdhaXQgZGVjcnlwdFdpdGhBRVMoZW5jcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGVjcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZXJyLnJlc3BvbnNlLmRhdGEgPSBkYXRhO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFZlcmlmeSBzaWduYXR1cmUgYW5kIGhhbmRsZSByZXNwb25zZVxuICAgICAgICAgIHRoaXMudmVyaWZ5U2lnbmF0dXJlKFxuICAgICAgICAgICAgdGhpcy5kYXRhRGVyaXZhdGl2ZUxvZ2ljKGRhdGEpLFxuICAgICAgICAgICAgZXJyPy5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHZlcmlmaWNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLmVycm9yKGVycj8ucmVzcG9uc2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZ1bmN0aW9uIHRvIHBlcmZvcm0gR0VUIHJlcXVlc3RcbiAgQGxvZ01ldGhvZFxuICBnZXQoXG4gICAgdXJsLFxuICAgIGhlYWRlckRhdGEgPSB1bmRlZmluZWQsXG4gICAgaXNEZWNyeXB0ID0gZmFsc2UsXG4gICAgaXNWZXJpZnlTaWduYXR1cmUgPSBmYWxzZSxcbiAgICBpc1NraXBIZWFkZXJBbHRlcmF0aW9uID0gZmFsc2VcbiAgKSB7XG4gICAgbGV0IHByZVByb2Nlc3NlZEhlYWRlciA9IGhlYWRlckRhdGE7XG5cbiAgICAvLyBQcmVwcm9jZXNzIGhlYWRlciBkYXRhIHVubGVzcyBpbnN0cnVjdGVkIHRvIHNraXBcbiAgICBpZiAoIWlzU2tpcEhlYWRlckFsdGVyYXRpb24pIHtcbiAgICAgIHByZVByb2Nlc3NlZEhlYWRlciA9IHRoaXMucHJlUHJvY2Vzc0hlYWRlcihoZWFkZXJEYXRhLCBpc1ZlcmlmeVNpZ25hdHVyZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZVByb2Nlc3NlZEhlYWRlci5vYnNlcnZlID0gXCJyZXNwb25zZVwiO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgoc3Vic2NyaWJlcikgPT4ge1xuICAgICAgYXhpb3MuZ2V0KHVybCwgcHJlUHJvY2Vzc2VkSGVhZGVyKS50aGVuKFxuICAgICAgICBhc3luYyAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICBsZXQgeyBkYXRhIH0gPSByZXM7XG5cbiAgICAgICAgICAvLyBEZWNyeXB0IHJlc3BvbnNlIGlmIHJlcXVpcmVkXG4gICAgICAgICAgaWYgKGlzRGVjcnlwdCkge1xuICAgICAgICAgICAgY29uc3QgZW5jcnlwdGVkUmVzcG9uc2UgPSBkYXRhO1xuICAgICAgICAgICAgY29uc3QgZGVjcnlwdGVkUmVzcG9uc2UgPSBhd2FpdCBkZWNyeXB0V2l0aEFFUyhlbmNyeXB0ZWRSZXNwb25zZSk7XG4gICAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkZWNyeXB0ZWRSZXNwb25zZSk7XG4gICAgICAgICAgICByZXMuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gVmVyaWZ5IHNpZ25hdHVyZSBhbmQgaGFuZGxlIHJlc3BvbnNlXG4gICAgICAgICAgdGhpcy52ZXJpZnlTaWduYXR1cmUoXG4gICAgICAgICAgICB0aGlzLmRhdGFEZXJpdmF0aXZlTG9naWMoZGF0YSksXG4gICAgICAgICAgICByZXM/LmhlYWRlcnMsXG4gICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICBpc1ZlcmlmeVNpZ25hdHVyZVxuICAgICAgICAgIClcbiAgICAgICAgICAgIC50aGVuKCh2ZXJpZmljYXRpb246IGFueSkgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQocmVzKTtcbiAgICAgICAgICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKGVycikgPT4ge1xuICAgICAgICAgIGxldCBkYXRhID0gZXJyPy5yZXNwb25zZT8uZGF0YTtcblxuICAgICAgICAgIC8vIERlY3J5cHQgZXJyb3IgcmVzcG9uc2UgaWYgcmVxdWlyZWRcbiAgICAgICAgICBpZiAoZGF0YSAmJiBpc0RlY3J5cHQpIHtcbiAgICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZFJlc3BvbnNlID0gZGF0YTtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZFJlc3BvbnNlID0gYXdhaXQgZGVjcnlwdFdpdGhBRVMoZW5jcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGVjcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZXJyLnJlc3BvbnNlLmRhdGEgPSBkYXRhO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFZlcmlmeSBzaWduYXR1cmUgYW5kIGhhbmRsZSByZXNwb25zZVxuICAgICAgICAgIHRoaXMudmVyaWZ5U2lnbmF0dXJlKFxuICAgICAgICAgICAgdGhpcy5kYXRhRGVyaXZhdGl2ZUxvZ2ljKGRhdGEpLFxuICAgICAgICAgICAgZXJyPy5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHZlcmlmaWNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLmVycm9yKGVycj8ucmVzcG9uc2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZ1bmN0aW9uIHRvIGV4ZWN1dGUgQVBJIGNhbGwgYmFzZWQgb24gbWV0aG9kIHR5cGVcbiAgZXhlY3V0ZUFwaUNhbGwoXG4gICAgdXJsLFxuICAgIG1ldGhvZCxcbiAgICBib2R5LFxuICAgIGhlYWRlcnMsXG4gICAgaXNFbmNyeXB0LFxuICAgIGlzRGVjcnlwdCxcbiAgICBpc1ZlcmlmeVNpZ25hdHVyZVxuICApIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIGlmIChtZXRob2QgPT09IFwiR0VUXCIpIHtcbiAgICAgICAgdGhpcy5nZXQodXJsLCB7IGhlYWRlcnMgfSwgaXNEZWNyeXB0LCBpc1ZlcmlmeVNpZ25hdHVyZSkuc3Vic2NyaWJlKFxuICAgICAgICAgIChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucG9zdChcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgYm9keSxcbiAgICAgICAgICB7IGhlYWRlcnMgfSxcbiAgICAgICAgICBpc0VuY3J5cHQsXG4gICAgICAgICAgaXNEZWNyeXB0LFxuICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICkuc3Vic2NyaWJlKFxuICAgICAgICAgIChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIl19