UNPKG

tedious

Version:

A TDS driver, for connecting to MS SQLServer databases.

90 lines (88 loc) 20.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getParameterEncryptionMetadata = void 0; var _types = require("./types"); var _cekEntry = require("./cek-entry"); var _keyCrypto = require("./key-crypto"); var _dataType = require("../data-type"); var _request = _interopRequireDefault(require("../request")); var _rpcrequestPayload = _interopRequireDefault(require("../rpcrequest-payload")); var _packet = require("../packet"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // This code is based on the `mssql-jdbc` library published under the conditions of MIT license. // Copyright (c) 2019 Microsoft Corporation const getParameterEncryptionMetadata = (connection, request, callback) => { if (request.cryptoMetadataLoaded === true) { return callback(); } const metadataRequest = new _request.default('sp_describe_parameter_encryption', error => { if (error) { return callback(error); } const decryptSymmetricKeyPromises = []; const cekList = []; let paramCount = 0; for (const columns of resultRows) { try { const isFirstRecordSet = columns.some(col => (col && col.metadata && col.metadata.colName) === 'database_id'); if (isFirstRecordSet === true) { const currentOrdinal = columns[_types.DescribeParameterEncryptionResultSet1.KeyOrdinal].value; let cekEntry; if (!cekList[currentOrdinal]) { cekEntry = new _cekEntry.CEKEntry(currentOrdinal); cekList[cekEntry.ordinal] = cekEntry; } else { cekEntry = cekList[currentOrdinal]; } cekEntry.add(columns[_types.DescribeParameterEncryptionResultSet1.EncryptedKey].value, columns[_types.DescribeParameterEncryptionResultSet1.DbId].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyId].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyVersion].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyMdVersion].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyPath].value, columns[_types.DescribeParameterEncryptionResultSet1.ProviderName].value, columns[_types.DescribeParameterEncryptionResultSet1.KeyEncryptionAlgorithm].value); } else { paramCount++; const paramName = columns[_types.DescribeParameterEncryptionResultSet2.ParameterName].value; const paramIndex = request.parameters.findIndex(param => paramName === `@${param.name}`); const cekOrdinal = columns[_types.DescribeParameterEncryptionResultSet2.ColumnEncryptionKeyOrdinal].value; const cekEntry = cekList[cekOrdinal]; if (cekEntry && cekList.length < cekOrdinal) { return callback(new Error(`Internal error. The referenced column encryption key ordinal "${cekOrdinal}" is missing in the encryption metadata returned by sp_describe_parameter_encryption. Max ordinal is "${cekList.length}".`)); } const encType = columns[_types.DescribeParameterEncryptionResultSet2.ColumnEncrytionType].value; if (_types.SQLServerEncryptionType.PlainText !== encType) { request.parameters[paramIndex].cryptoMetadata = { cekEntry: cekEntry, ordinal: cekOrdinal, cipherAlgorithmId: columns[_types.DescribeParameterEncryptionResultSet2.ColumnEncryptionAlgorithm].value, encryptionType: encType, normalizationRuleVersion: Buffer.from([columns[_types.DescribeParameterEncryptionResultSet2.NormalizationRuleVersion].value]) }; decryptSymmetricKeyPromises.push((0, _keyCrypto.decryptSymmetricKey)(request.parameters[paramIndex].cryptoMetadata, connection.config.options)); } else if (request.parameters[paramIndex].forceEncrypt === true) { return callback(new Error(`Cannot execute statement or procedure ${request.sqlTextOrProcedure} because Force Encryption was set as true for parameter ${paramIndex + 1} and the database expects this parameter to be sent as plaintext. This may be due to a configuration error.`)); } } } catch { return callback(new Error(`Internal error. Unable to parse parameter encryption metadata in statement or procedure "${request.sqlTextOrProcedure}"`)); } } if (paramCount !== request.parameters.length) { return callback(new Error(`Internal error. Metadata for some parameters in statement or procedure "${request.sqlTextOrProcedure}" is missing in the resultset returned by sp_describe_parameter_encryption.`)); } return Promise.all(decryptSymmetricKeyPromises).then(() => { request.cryptoMetadataLoaded = true; process.nextTick(callback); }, error => { process.nextTick(callback, error); }); }); metadataRequest.addParameter('tsql', _dataType.typeByName.NVarChar, request.sqlTextOrProcedure); if (request.parameters.length) { metadataRequest.addParameter('params', _dataType.typeByName.NVarChar, metadataRequest.makeParamsParameter(request.parameters)); } const resultRows = []; metadataRequest.on('row', columns => { resultRows.push(columns); }); connection.makeRequest(metadataRequest, _packet.TYPE.RPC_REQUEST, new _rpcrequestPayload.default(metadataRequest.sqlTextOrProcedure, metadataRequest.parameters, connection.currentTransactionDescriptor(), connection.config.options, connection.databaseCollation)); }; exports.getParameterEncryptionMetadata = getParameterEncryptionMetadata; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdHlwZXMiLCJyZXF1aXJlIiwiX2Nla0VudHJ5IiwiX2tleUNyeXB0byIsIl9kYXRhVHlwZSIsIl9yZXF1ZXN0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9ycGNyZXF1ZXN0UGF5bG9hZCIsIl9wYWNrZXQiLCJvYmoiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImdldFBhcmFtZXRlckVuY3J5cHRpb25NZXRhZGF0YSIsImNvbm5lY3Rpb24iLCJyZXF1ZXN0IiwiY2FsbGJhY2siLCJjcnlwdG9NZXRhZGF0YUxvYWRlZCIsIm1ldGFkYXRhUmVxdWVzdCIsIlJlcXVlc3QiLCJlcnJvciIsImRlY3J5cHRTeW1tZXRyaWNLZXlQcm9taXNlcyIsImNla0xpc3QiLCJwYXJhbUNvdW50IiwiY29sdW1ucyIsInJlc3VsdFJvd3MiLCJpc0ZpcnN0UmVjb3JkU2V0Iiwic29tZSIsImNvbCIsIm1ldGFkYXRhIiwiY29sTmFtZSIsImN1cnJlbnRPcmRpbmFsIiwiRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MSIsIktleU9yZGluYWwiLCJ2YWx1ZSIsImNla0VudHJ5IiwiQ0VLRW50cnkiLCJvcmRpbmFsIiwiYWRkIiwiRW5jcnlwdGVkS2V5IiwiRGJJZCIsIktleUlkIiwiS2V5VmVyc2lvbiIsIktleU1kVmVyc2lvbiIsIktleVBhdGgiLCJQcm92aWRlck5hbWUiLCJLZXlFbmNyeXB0aW9uQWxnb3JpdGhtIiwicGFyYW1OYW1lIiwiRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MiIsIlBhcmFtZXRlck5hbWUiLCJwYXJhbUluZGV4IiwicGFyYW1ldGVycyIsImZpbmRJbmRleCIsInBhcmFtIiwibmFtZSIsImNla09yZGluYWwiLCJDb2x1bW5FbmNyeXB0aW9uS2V5T3JkaW5hbCIsImxlbmd0aCIsIkVycm9yIiwiZW5jVHlwZSIsIkNvbHVtbkVuY3J5dGlvblR5cGUiLCJTUUxTZXJ2ZXJFbmNyeXB0aW9uVHlwZSIsIlBsYWluVGV4dCIsImNyeXB0b01ldGFkYXRhIiwiY2lwaGVyQWxnb3JpdGhtSWQiLCJDb2x1bW5FbmNyeXB0aW9uQWxnb3JpdGhtIiwiZW5jcnlwdGlvblR5cGUiLCJub3JtYWxpemF0aW9uUnVsZVZlcnNpb24iLCJCdWZmZXIiLCJmcm9tIiwiTm9ybWFsaXphdGlvblJ1bGVWZXJzaW9uIiwicHVzaCIsImRlY3J5cHRTeW1tZXRyaWNLZXkiLCJjb25maWciLCJvcHRpb25zIiwiZm9yY2VFbmNyeXB0Iiwic3FsVGV4dE9yUHJvY2VkdXJlIiwiUHJvbWlzZSIsImFsbCIsInRoZW4iLCJwcm9jZXNzIiwibmV4dFRpY2siLCJhZGRQYXJhbWV0ZXIiLCJUWVBFUyIsIk5WYXJDaGFyIiwibWFrZVBhcmFtc1BhcmFtZXRlciIsIm9uIiwibWFrZVJlcXVlc3QiLCJUWVBFIiwiUlBDX1JFUVVFU1QiLCJScGNSZXF1ZXN0UGF5bG9hZCIsImN1cnJlbnRUcmFuc2FjdGlvbkRlc2NyaXB0b3IiLCJkYXRhYmFzZUNvbGxhdGlvbiIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvYWx3YXlzLWVuY3J5cHRlZC9nZXQtcGFyYW1ldGVyLWVuY3J5cHRpb24tbWV0YWRhdGEudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhpcyBjb2RlIGlzIGJhc2VkIG9uIHRoZSBgbXNzcWwtamRiY2AgbGlicmFyeSBwdWJsaXNoZWQgdW5kZXIgdGhlIGNvbmRpdGlvbnMgb2YgTUlUIGxpY2Vuc2UuXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTkgTWljcm9zb2Z0IENvcnBvcmF0aW9uXG5cbmltcG9ydCB7IFNRTFNlcnZlckVuY3J5cHRpb25UeXBlLCB0eXBlIENyeXB0b01ldGFkYXRhLCBEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLCBEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQyIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBDRUtFbnRyeSB9IGZyb20gJy4vY2VrLWVudHJ5JztcbmltcG9ydCB7IGRlY3J5cHRTeW1tZXRyaWNLZXkgfSBmcm9tICcuL2tleS1jcnlwdG8nO1xuaW1wb3J0IHsgdHlwZUJ5TmFtZSBhcyBUWVBFUywgdHlwZSBQYXJhbWV0ZXIgfSBmcm9tICcuLi9kYXRhLXR5cGUnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vcmVxdWVzdCc7XG5pbXBvcnQgQ29ubmVjdGlvbiBmcm9tICcuLi9jb25uZWN0aW9uJztcbmltcG9ydCBScGNSZXF1ZXN0UGF5bG9hZCBmcm9tICcuLi9ycGNyZXF1ZXN0LXBheWxvYWQnO1xuaW1wb3J0IHsgVFlQRSB9IGZyb20gJy4uL3BhY2tldCc7XG5cbmV4cG9ydCBjb25zdCBnZXRQYXJhbWV0ZXJFbmNyeXB0aW9uTWV0YWRhdGEgPSAoY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgcmVxdWVzdDogUmVxdWVzdCwgY2FsbGJhY2s6IChlcnJvcj86IEVycm9yKSA9PiB2b2lkKSA9PiB7XG4gIGlmIChyZXF1ZXN0LmNyeXB0b01ldGFkYXRhTG9hZGVkID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gIH1cblxuICBjb25zdCBtZXRhZGF0YVJlcXVlc3QgPSBuZXcgUmVxdWVzdCgnc3BfZGVzY3JpYmVfcGFyYW1ldGVyX2VuY3J5cHRpb24nLCAoZXJyb3IpID0+IHtcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnJvcik7XG4gICAgfVxuXG4gICAgY29uc3QgZGVjcnlwdFN5bW1ldHJpY0tleVByb21pc2VzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcbiAgICBjb25zdCBjZWtMaXN0OiBDRUtFbnRyeVtdID0gW107XG4gICAgbGV0IHBhcmFtQ291bnQgPSAwO1xuXG4gICAgZm9yIChjb25zdCBjb2x1bW5zIG9mIHJlc3VsdFJvd3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGlzRmlyc3RSZWNvcmRTZXQgPSBjb2x1bW5zLnNvbWUoKGNvbDogYW55KSA9PiAoY29sICYmIGNvbC5tZXRhZGF0YSAmJiBjb2wubWV0YWRhdGEuY29sTmFtZSkgPT09ICdkYXRhYmFzZV9pZCcpO1xuICAgICAgICBpZiAoaXNGaXJzdFJlY29yZFNldCA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRPcmRpbmFsID0gY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLktleU9yZGluYWxdLnZhbHVlO1xuICAgICAgICAgIGxldCBjZWtFbnRyeTogQ0VLRW50cnk7XG4gICAgICAgICAgaWYgKCFjZWtMaXN0W2N1cnJlbnRPcmRpbmFsXSkge1xuICAgICAgICAgICAgY2VrRW50cnkgPSBuZXcgQ0VLRW50cnkoY3VycmVudE9yZGluYWwpO1xuICAgICAgICAgICAgY2VrTGlzdFtjZWtFbnRyeS5vcmRpbmFsXSA9IGNla0VudHJ5O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjZWtFbnRyeSA9IGNla0xpc3RbY3VycmVudE9yZGluYWxdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjZWtFbnRyeS5hZGQoY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLkVuY3J5cHRlZEtleV0udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MS5EYklkXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLktleUlkXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLktleVZlcnNpb25dLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zW0Rlc2NyaWJlUGFyYW1ldGVyRW5jcnlwdGlvblJlc3VsdFNldDEuS2V5TWRWZXJzaW9uXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLktleVBhdGhdLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zW0Rlc2NyaWJlUGFyYW1ldGVyRW5jcnlwdGlvblJlc3VsdFNldDEuUHJvdmlkZXJOYW1lXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLktleUVuY3J5cHRpb25BbGdvcml0aG1dLnZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYXJhbUNvdW50Kys7XG4gICAgICAgICAgY29uc3QgcGFyYW1OYW1lOiBzdHJpbmcgPSBjb2x1bW5zW0Rlc2NyaWJlUGFyYW1ldGVyRW5jcnlwdGlvblJlc3VsdFNldDIuUGFyYW1ldGVyTmFtZV0udmFsdWU7XG4gICAgICAgICAgY29uc3QgcGFyYW1JbmRleDogbnVtYmVyID0gcmVxdWVzdC5wYXJhbWV0ZXJzLmZpbmRJbmRleCgocGFyYW06IFBhcmFtZXRlcikgPT4gcGFyYW1OYW1lID09PSBgQCR7cGFyYW0ubmFtZX1gKTtcbiAgICAgICAgICBjb25zdCBjZWtPcmRpbmFsOiBudW1iZXIgPSBjb2x1bW5zW0Rlc2NyaWJlUGFyYW1ldGVyRW5jcnlwdGlvblJlc3VsdFNldDIuQ29sdW1uRW5jcnlwdGlvbktleU9yZGluYWxdLnZhbHVlO1xuICAgICAgICAgIGNvbnN0IGNla0VudHJ5OiBDRUtFbnRyeSA9IGNla0xpc3RbY2VrT3JkaW5hbF07XG5cbiAgICAgICAgICBpZiAoY2VrRW50cnkgJiYgY2VrTGlzdC5sZW5ndGggPCBjZWtPcmRpbmFsKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKGBJbnRlcm5hbCBlcnJvci4gVGhlIHJlZmVyZW5jZWQgY29sdW1uIGVuY3J5cHRpb24ga2V5IG9yZGluYWwgXCIke2Nla09yZGluYWx9XCIgaXMgbWlzc2luZyBpbiB0aGUgZW5jcnlwdGlvbiBtZXRhZGF0YSByZXR1cm5lZCBieSBzcF9kZXNjcmliZV9wYXJhbWV0ZXJfZW5jcnlwdGlvbi4gTWF4IG9yZGluYWwgaXMgXCIke2Nla0xpc3QubGVuZ3RofVwiLmApKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbmNUeXBlID0gY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQyLkNvbHVtbkVuY3J5dGlvblR5cGVdLnZhbHVlO1xuICAgICAgICAgIGlmIChTUUxTZXJ2ZXJFbmNyeXB0aW9uVHlwZS5QbGFpblRleHQgIT09IGVuY1R5cGUpIHtcbiAgICAgICAgICAgIHJlcXVlc3QucGFyYW1ldGVyc1twYXJhbUluZGV4XS5jcnlwdG9NZXRhZGF0YSA9IHtcbiAgICAgICAgICAgICAgY2VrRW50cnk6IGNla0VudHJ5LFxuICAgICAgICAgICAgICBvcmRpbmFsOiBjZWtPcmRpbmFsLFxuICAgICAgICAgICAgICBjaXBoZXJBbGdvcml0aG1JZDogY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQyLkNvbHVtbkVuY3J5cHRpb25BbGdvcml0aG1dLnZhbHVlLFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uVHlwZTogZW5jVHlwZSxcbiAgICAgICAgICAgICAgbm9ybWFsaXphdGlvblJ1bGVWZXJzaW9uOiBCdWZmZXIuZnJvbShbY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQyLk5vcm1hbGl6YXRpb25SdWxlVmVyc2lvbl0udmFsdWVdKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkZWNyeXB0U3ltbWV0cmljS2V5UHJvbWlzZXMucHVzaChkZWNyeXB0U3ltbWV0cmljS2V5KHJlcXVlc3QucGFyYW1ldGVyc1twYXJhbUluZGV4XS5jcnlwdG9NZXRhZGF0YSBhcyBDcnlwdG9NZXRhZGF0YSwgY29ubmVjdGlvbi5jb25maWcub3B0aW9ucykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdC5wYXJhbWV0ZXJzW3BhcmFtSW5kZXhdLmZvcmNlRW5jcnlwdCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcihgQ2Fubm90IGV4ZWN1dGUgc3RhdGVtZW50IG9yIHByb2NlZHVyZSAke3JlcXVlc3Quc3FsVGV4dE9yUHJvY2VkdXJlfSBiZWNhdXNlIEZvcmNlIEVuY3J5cHRpb24gd2FzIHNldCBhcyB0cnVlIGZvciBwYXJhbWV0ZXIgJHtwYXJhbUluZGV4ICsgMX0gYW5kIHRoZSBkYXRhYmFzZSBleHBlY3RzIHRoaXMgcGFyYW1ldGVyIHRvIGJlIHNlbnQgYXMgcGxhaW50ZXh0LiBUaGlzIG1heSBiZSBkdWUgdG8gYSBjb25maWd1cmF0aW9uIGVycm9yLmApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKGBJbnRlcm5hbCBlcnJvci4gVW5hYmxlIHRvIHBhcnNlIHBhcmFtZXRlciBlbmNyeXB0aW9uIG1ldGFkYXRhIGluIHN0YXRlbWVudCBvciBwcm9jZWR1cmUgXCIke3JlcXVlc3Quc3FsVGV4dE9yUHJvY2VkdXJlfVwiYCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbUNvdW50ICE9PSByZXF1ZXN0LnBhcmFtZXRlcnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKGBJbnRlcm5hbCBlcnJvci4gTWV0YWRhdGEgZm9yIHNvbWUgcGFyYW1ldGVycyBpbiBzdGF0ZW1lbnQgb3IgcHJvY2VkdXJlIFwiJHtyZXF1ZXN0LnNxbFRleHRPclByb2NlZHVyZX1cIiBpcyBtaXNzaW5nIGluIHRoZSByZXN1bHRzZXQgcmV0dXJuZWQgYnkgc3BfZGVzY3JpYmVfcGFyYW1ldGVyX2VuY3J5cHRpb24uYCkpO1xuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLmFsbChkZWNyeXB0U3ltbWV0cmljS2V5UHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgcmVxdWVzdC5jcnlwdG9NZXRhZGF0YUxvYWRlZCA9IHRydWU7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGNhbGxiYWNrKTtcbiAgICB9LCAoZXJyb3IpID0+IHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY2FsbGJhY2ssIGVycm9yKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgbWV0YWRhdGFSZXF1ZXN0LmFkZFBhcmFtZXRlcigndHNxbCcsIFRZUEVTLk5WYXJDaGFyLCByZXF1ZXN0LnNxbFRleHRPclByb2NlZHVyZSk7XG4gIGlmIChyZXF1ZXN0LnBhcmFtZXRlcnMubGVuZ3RoKSB7XG4gICAgbWV0YWRhdGFSZXF1ZXN0LmFkZFBhcmFtZXRlcigncGFyYW1zJywgVFlQRVMuTlZhckNoYXIsIG1ldGFkYXRhUmVxdWVzdC5tYWtlUGFyYW1zUGFyYW1ldGVyKHJlcXVlc3QucGFyYW1ldGVycykpO1xuICB9XG5cbiAgY29uc3QgcmVzdWx0Um93czogYW55W10gPSBbXTtcblxuICBtZXRhZGF0YVJlcXVlc3Qub24oJ3JvdycsIChjb2x1bW5zOiBhbnkpID0+IHtcbiAgICByZXN1bHRSb3dzLnB1c2goY29sdW1ucyk7XG4gIH0pO1xuXG4gIGNvbm5lY3Rpb24ubWFrZVJlcXVlc3QobWV0YWRhdGFSZXF1ZXN0LCBUWVBFLlJQQ19SRVFVRVNULCBuZXcgUnBjUmVxdWVzdFBheWxvYWQobWV0YWRhdGFSZXF1ZXN0LnNxbFRleHRPclByb2NlZHVyZSEsIG1ldGFkYXRhUmVxdWVzdC5wYXJhbWV0ZXJzLCBjb25uZWN0aW9uLmN1cnJlbnRUcmFuc2FjdGlvbkRlc2NyaXB0b3IoKSwgY29ubmVjdGlvbi5jb25maWcub3B0aW9ucywgY29ubmVjdGlvbi5kYXRhYmFzZUNvbGxhdGlvbikpO1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0EsSUFBQUEsTUFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsU0FBQSxHQUFBRCxPQUFBO0FB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