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(e) { return e && e.__esModule ? e : { default: e }; } // 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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdHlwZXMiLCJyZXF1aXJlIiwiX2Nla0VudHJ5IiwiX2tleUNyeXB0byIsIl9kYXRhVHlwZSIsIl9yZXF1ZXN0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9ycGNyZXF1ZXN0UGF5bG9hZCIsIl9wYWNrZXQiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJnZXRQYXJhbWV0ZXJFbmNyeXB0aW9uTWV0YWRhdGEiLCJjb25uZWN0aW9uIiwicmVxdWVzdCIsImNhbGxiYWNrIiwiY3J5cHRvTWV0YWRhdGFMb2FkZWQiLCJtZXRhZGF0YVJlcXVlc3QiLCJSZXF1ZXN0IiwiZXJyb3IiLCJkZWNyeXB0U3ltbWV0cmljS2V5UHJvbWlzZXMiLCJjZWtMaXN0IiwicGFyYW1Db3VudCIsImNvbHVtbnMiLCJyZXN1bHRSb3dzIiwiaXNGaXJzdFJlY29yZFNldCIsInNvbWUiLCJjb2wiLCJtZXRhZGF0YSIsImNvbE5hbWUiLCJjdXJyZW50T3JkaW5hbCIsIkRlc2NyaWJlUGFyYW1ldGVyRW5jcnlwdGlvblJlc3VsdFNldDEiLCJLZXlPcmRpbmFsIiwidmFsdWUiLCJjZWtFbnRyeSIsIkNFS0VudHJ5Iiwib3JkaW5hbCIsImFkZCIsIkVuY3J5cHRlZEtleSIsIkRiSWQiLCJLZXlJZCIsIktleVZlcnNpb24iLCJLZXlNZFZlcnNpb24iLCJLZXlQYXRoIiwiUHJvdmlkZXJOYW1lIiwiS2V5RW5jcnlwdGlvbkFsZ29yaXRobSIsInBhcmFtTmFtZSIsIkRlc2NyaWJlUGFyYW1ldGVyRW5jcnlwdGlvblJlc3VsdFNldDIiLCJQYXJhbWV0ZXJOYW1lIiwicGFyYW1JbmRleCIsInBhcmFtZXRlcnMiLCJmaW5kSW5kZXgiLCJwYXJhbSIsIm5hbWUiLCJjZWtPcmRpbmFsIiwiQ29sdW1uRW5jcnlwdGlvbktleU9yZGluYWwiLCJsZW5ndGgiLCJFcnJvciIsImVuY1R5cGUiLCJDb2x1bW5FbmNyeXRpb25UeXBlIiwiU1FMU2VydmVyRW5jcnlwdGlvblR5cGUiLCJQbGFpblRleHQiLCJjcnlwdG9NZXRhZGF0YSIsImNpcGhlckFsZ29yaXRobUlkIiwiQ29sdW1uRW5jcnlwdGlvbkFsZ29yaXRobSIsImVuY3J5cHRpb25UeXBlIiwibm9ybWFsaXphdGlvblJ1bGVWZXJzaW9uIiwiQnVmZmVyIiwiZnJvbSIsIk5vcm1hbGl6YXRpb25SdWxlVmVyc2lvbiIsInB1c2giLCJkZWNyeXB0U3ltbWV0cmljS2V5IiwiY29uZmlnIiwib3B0aW9ucyIsImZvcmNlRW5jcnlwdCIsInNxbFRleHRPclByb2NlZHVyZSIsIlByb21pc2UiLCJhbGwiLCJ0aGVuIiwicHJvY2VzcyIsIm5leHRUaWNrIiwiYWRkUGFyYW1ldGVyIiwiVFlQRVMiLCJOVmFyQ2hhciIsIm1ha2VQYXJhbXNQYXJhbWV0ZXIiLCJvbiIsIm1ha2VSZXF1ZXN0IiwiVFlQRSIsIlJQQ19SRVFVRVNUIiwiUnBjUmVxdWVzdFBheWxvYWQiLCJjdXJyZW50VHJhbnNhY3Rpb25EZXNjcmlwdG9yIiwiZGF0YWJhc2VDb2xsYXRpb24iLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Fsd2F5cy1lbmNyeXB0ZWQvZ2V0LXBhcmFtZXRlci1lbmNyeXB0aW9uLW1ldGFkYXRhLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgY29kZSBpcyBiYXNlZCBvbiB0aGUgYG1zc3FsLWpkYmNgIGxpYnJhcnkgcHVibGlzaGVkIHVuZGVyIHRoZSBjb25kaXRpb25zIG9mIE1JVCBsaWNlbnNlLlxuLy8gQ29weXJpZ2h0IChjKSAyMDE5IE1pY3Jvc29mdCBDb3Jwb3JhdGlvblxuXG5pbXBvcnQgeyBTUUxTZXJ2ZXJFbmNyeXB0aW9uVHlwZSwgdHlwZSBDcnlwdG9NZXRhZGF0YSwgRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MSwgRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MiB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgQ0VLRW50cnkgfSBmcm9tICcuL2Nlay1lbnRyeSc7XG5pbXBvcnQgeyBkZWNyeXB0U3ltbWV0cmljS2V5IH0gZnJvbSAnLi9rZXktY3J5cHRvJztcbmltcG9ydCB7IHR5cGVCeU5hbWUgYXMgVFlQRVMsIHR5cGUgUGFyYW1ldGVyIH0gZnJvbSAnLi4vZGF0YS10eXBlJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4uL3JlcXVlc3QnO1xuaW1wb3J0IENvbm5lY3Rpb24gZnJvbSAnLi4vY29ubmVjdGlvbic7XG5pbXBvcnQgUnBjUmVxdWVzdFBheWxvYWQgZnJvbSAnLi4vcnBjcmVxdWVzdC1wYXlsb2FkJztcbmltcG9ydCB7IFRZUEUgfSBmcm9tICcuLi9wYWNrZXQnO1xuXG5leHBvcnQgY29uc3QgZ2V0UGFyYW1ldGVyRW5jcnlwdGlvbk1ldGFkYXRhID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlcXVlc3Q6IFJlcXVlc3QsIGNhbGxiYWNrOiAoZXJyb3I/OiBFcnJvcikgPT4gdm9pZCkgPT4ge1xuICBpZiAocmVxdWVzdC5jcnlwdG9NZXRhZGF0YUxvYWRlZCA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBjYWxsYmFjaygpO1xuICB9XG5cbiAgY29uc3QgbWV0YWRhdGFSZXF1ZXN0ID0gbmV3IFJlcXVlc3QoJ3NwX2Rlc2NyaWJlX3BhcmFtZXRlcl9lbmNyeXB0aW9uJywgKGVycm9yKSA9PiB7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZXJyb3IpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY3J5cHRTeW1tZXRyaWNLZXlQcm9taXNlczogUHJvbWlzZTx2b2lkPltdID0gW107XG4gICAgY29uc3QgY2VrTGlzdDogQ0VLRW50cnlbXSA9IFtdO1xuICAgIGxldCBwYXJhbUNvdW50ID0gMDtcblxuICAgIGZvciAoY29uc3QgY29sdW1ucyBvZiByZXN1bHRSb3dzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpc0ZpcnN0UmVjb3JkU2V0ID0gY29sdW1ucy5zb21lKChjb2w6IGFueSkgPT4gKGNvbCAmJiBjb2wubWV0YWRhdGEgJiYgY29sLm1ldGFkYXRhLmNvbE5hbWUpID09PSAnZGF0YWJhc2VfaWQnKTtcbiAgICAgICAgaWYgKGlzRmlyc3RSZWNvcmRTZXQgPT09IHRydWUpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50T3JkaW5hbCA9IGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MS5LZXlPcmRpbmFsXS52YWx1ZTtcbiAgICAgICAgICBsZXQgY2VrRW50cnk6IENFS0VudHJ5O1xuICAgICAgICAgIGlmICghY2VrTGlzdFtjdXJyZW50T3JkaW5hbF0pIHtcbiAgICAgICAgICAgIGNla0VudHJ5ID0gbmV3IENFS0VudHJ5KGN1cnJlbnRPcmRpbmFsKTtcbiAgICAgICAgICAgIGNla0xpc3RbY2VrRW50cnkub3JkaW5hbF0gPSBjZWtFbnRyeTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2VrRW50cnkgPSBjZWtMaXN0W2N1cnJlbnRPcmRpbmFsXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2VrRW50cnkuYWRkKGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MS5FbmNyeXB0ZWRLZXldLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zW0Rlc2NyaWJlUGFyYW1ldGVyRW5jcnlwdGlvblJlc3VsdFNldDEuRGJJZF0udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MS5LZXlJZF0udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MS5LZXlWZXJzaW9uXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLktleU1kVmVyc2lvbl0udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MS5LZXlQYXRoXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQxLlByb3ZpZGVyTmFtZV0udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0MS5LZXlFbmNyeXB0aW9uQWxnb3JpdGhtXS52YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFyYW1Db3VudCsrO1xuICAgICAgICAgIGNvbnN0IHBhcmFtTmFtZTogc3RyaW5nID0gY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQyLlBhcmFtZXRlck5hbWVdLnZhbHVlO1xuICAgICAgICAgIGNvbnN0IHBhcmFtSW5kZXg6IG51bWJlciA9IHJlcXVlc3QucGFyYW1ldGVycy5maW5kSW5kZXgoKHBhcmFtOiBQYXJhbWV0ZXIpID0+IHBhcmFtTmFtZSA9PT0gYEAke3BhcmFtLm5hbWV9YCk7XG4gICAgICAgICAgY29uc3QgY2VrT3JkaW5hbDogbnVtYmVyID0gY29sdW1uc1tEZXNjcmliZVBhcmFtZXRlckVuY3J5cHRpb25SZXN1bHRTZXQyLkNvbHVtbkVuY3J5cHRpb25LZXlPcmRpbmFsXS52YWx1ZTtcbiAgICAgICAgICBjb25zdCBjZWtFbnRyeTogQ0VLRW50cnkgPSBjZWtMaXN0W2Nla09yZGluYWxdO1xuXG4gICAgICAgICAgaWYgKGNla0VudHJ5ICYmIGNla0xpc3QubGVuZ3RoIDwgY2VrT3JkaW5hbCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcihgSW50ZXJuYWwgZXJyb3IuIFRoZSByZWZlcmVuY2VkIGNvbHVtbiBlbmNyeXB0aW9uIGtleSBvcmRpbmFsIFwiJHtjZWtPcmRpbmFsfVwiIGlzIG1pc3NpbmcgaW4gdGhlIGVuY3J5cHRpb24gbWV0YWRhdGEgcmV0dXJuZWQgYnkgc3BfZGVzY3JpYmVfcGFyYW1ldGVyX2VuY3J5cHRpb24uIE1heCBvcmRpbmFsIGlzIFwiJHtjZWtMaXN0Lmxlbmd0aH1cIi5gKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZW5jVHlwZSA9IGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0Mi5Db2x1bW5FbmNyeXRpb25UeXBlXS52YWx1ZTtcbiAgICAgICAgICBpZiAoU1FMU2VydmVyRW5jcnlwdGlvblR5cGUuUGxhaW5UZXh0ICE9PSBlbmNUeXBlKSB7XG4gICAgICAgICAgICByZXF1ZXN0LnBhcmFtZXRlcnNbcGFyYW1JbmRleF0uY3J5cHRvTWV0YWRhdGEgPSB7XG4gICAgICAgICAgICAgIGNla0VudHJ5OiBjZWtFbnRyeSxcbiAgICAgICAgICAgICAgb3JkaW5hbDogY2VrT3JkaW5hbCxcbiAgICAgICAgICAgICAgY2lwaGVyQWxnb3JpdGhtSWQ6IGNvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0Mi5Db2x1bW5FbmNyeXB0aW9uQWxnb3JpdGhtXS52YWx1ZSxcbiAgICAgICAgICAgICAgZW5jcnlwdGlvblR5cGU6IGVuY1R5cGUsXG4gICAgICAgICAgICAgIG5vcm1hbGl6YXRpb25SdWxlVmVyc2lvbjogQnVmZmVyLmZyb20oW2NvbHVtbnNbRGVzY3JpYmVQYXJhbWV0ZXJFbmNyeXB0aW9uUmVzdWx0U2V0Mi5Ob3JtYWxpemF0aW9uUnVsZVZlcnNpb25dLnZhbHVlXSksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGVjcnlwdFN5bW1ldHJpY0tleVByb21pc2VzLnB1c2goZGVjcnlwdFN5bW1ldHJpY0tleShyZXF1ZXN0LnBhcmFtZXRlcnNbcGFyYW1JbmRleF0uY3J5cHRvTWV0YWRhdGEgYXMgQ3J5cHRvTWV0YWRhdGEsIGNvbm5lY3Rpb24uY29uZmlnLm9wdGlvbnMpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlcXVlc3QucGFyYW1ldGVyc1twYXJhbUluZGV4XS5mb3JjZUVuY3J5cHQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoYENhbm5vdCBleGVjdXRlIHN0YXRlbWVudCBvciBwcm9jZWR1cmUgJHtyZXF1ZXN0LnNxbFRleHRPclByb2NlZHVyZX0gYmVjYXVzZSBGb3JjZSBFbmNyeXB0aW9uIHdhcyBzZXQgYXMgdHJ1ZSBmb3IgcGFyYW1ldGVyICR7cGFyYW1JbmRleCArIDF9IGFuZCB0aGUgZGF0YWJhc2UgZXhwZWN0cyB0aGlzIHBhcmFtZXRlciB0byBiZSBzZW50IGFzIHBsYWludGV4dC4gVGhpcyBtYXkgYmUgZHVlIHRvIGEgY29uZmlndXJhdGlvbiBlcnJvci5gKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcihgSW50ZXJuYWwgZXJyb3IuIFVuYWJsZSB0byBwYXJzZSBwYXJhbWV0ZXIgZW5jcnlwdGlvbiBtZXRhZGF0YSBpbiBzdGF0ZW1lbnQgb3IgcHJvY2VkdXJlIFwiJHtyZXF1ZXN0LnNxbFRleHRPclByb2NlZHVyZX1cImApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1Db3VudCAhPT0gcmVxdWVzdC5wYXJhbWV0ZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcihgSW50ZXJuYWwgZXJyb3IuIE1ldGFkYXRhIGZvciBzb21lIHBhcmFtZXRlcnMgaW4gc3RhdGVtZW50IG9yIHByb2NlZHVyZSBcIiR7cmVxdWVzdC5zcWxUZXh0T3JQcm9jZWR1cmV9XCIgaXMgbWlzc2luZyBpbiB0aGUgcmVzdWx0c2V0IHJldHVybmVkIGJ5IHNwX2Rlc2NyaWJlX3BhcmFtZXRlcl9lbmNyeXB0aW9uLmApKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoZGVjcnlwdFN5bW1ldHJpY0tleVByb21pc2VzKS50aGVuKCgpID0+IHtcbiAgICAgIHJlcXVlc3QuY3J5cHRvTWV0YWRhdGFMb2FkZWQgPSB0cnVlO1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjYWxsYmFjayk7XG4gICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGNhbGxiYWNrLCBlcnJvcik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIG1ldGFkYXRhUmVxdWVzdC5hZGRQYXJhbWV0ZXIoJ3RzcWwnLCBUWVBFUy5OVmFyQ2hhciwgcmVxdWVzdC5zcWxUZXh0T3JQcm9jZWR1cmUpO1xuICBpZiAocmVxdWVzdC5wYXJhbWV0ZXJzLmxlbmd0aCkge1xuICAgIG1ldGFkYXRhUmVxdWVzdC5hZGRQYXJhbWV0ZXIoJ3BhcmFtcycsIFRZUEVTLk5WYXJDaGFyLCBtZXRhZGF0YVJlcXVlc3QubWFrZVBhcmFtc1BhcmFtZXRlcihyZXF1ZXN0LnBhcmFtZXRlcnMpKTtcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdFJvd3M6IGFueVtdID0gW107XG5cbiAgbWV0YWRhdGFSZXF1ZXN0Lm9uKCdyb3cnLCAoY29sdW1uczogYW55KSA9PiB7XG4gICAgcmVzdWx0Um93cy5wdXNoKGNvbHVtbnMpO1xuICB9KTtcblxuICBjb25uZWN0aW9uLm1ha2VSZXF1ZXN0KG1ldGFkYXRhUmVxdWVzdCwgVFlQRS5SUENfUkVRVUVTVCwgbmV3IFJwY1JlcXVlc3RQYXlsb2FkKG1ldGFkYXRhUmVxdWVzdC5zcWxUZXh0T3JQcm9jZWR1cmUhLCBtZXRhZGF0YVJlcXVlc3QucGFyYW1ldGVycywgY29ubmVjdGlvbi5jdXJyZW50VHJhbnNhY3Rpb25EZXNjcmlwdG9yKCksIGNvbm5lY3Rpb24uY29uZmlnLm9wdGlvbnMsIGNvbm5lY3Rpb24uZGF0YWJhc2VDb2xsYXRpb24pKTtcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBLElBQUFBLE1BQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLFNBQUEsR0FBQUQsT0FBQTtBQUNB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