UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

135 lines 20.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PatchedSharedIniFileCredentials = void 0; const AWS = require("aws-sdk"); /** * Hack-fix * * There are a number of issues in the upstream version of SharedIniFileCredentials * that need fixing: * * 1. The upstream aws-sdk does not support the 'credential_source' option. Meaning credentials * for assume-role cannot be fetched using EC2/ESC metadata. * * 2. The upstream aws-sdk does not support SSO profiles as the source of RoleProfiles, * because it will always use the `SharedIniFileCredentials` provider to load * source credentials, but in order to support SSO profiles you must use a * separate class (`SsoCredentials). */ class PatchedSharedIniFileCredentials extends AWS.SharedIniFileCredentials { loadRoleProfile(creds, roleProfile, callback) { // Need to duplicate the whole implementation here -- the function is long and has been written in // such a way that there are no small monkey patches possible. if (this.disableAssumeRole) { throw AWS.util.error(new Error('Role assumption profiles are disabled. ' + 'Failed to load profile ' + this.profile + ' from ' + creds.filename), { code: 'SharedIniFileCredentialsProviderFailure' }); } var self = this; var roleArn = roleProfile.role_arn; var roleSessionName = roleProfile.role_session_name; var externalId = roleProfile.external_id; var mfaSerial = roleProfile.mfa_serial; var sourceProfile = roleProfile.source_profile; var credentialSource = roleProfile.credential_source; if (!!sourceProfile === !!credentialSource) { throw AWS.util.error(new Error(`When using 'role_arn' in profile ('${this.profile}'), you must also configure exactly one of 'source_profile' or 'credential_source'`), { code: 'SharedIniFileCredentialsProviderFailure' }); } // Confirmed this against AWS CLI behavior -- the region must be in the assumED profile, // otherwise `us-east-1`. From the upstream comment in `aws-sdk-js`: // -------- comment from aws-sdk-js ------------------- // Experimentation shows that the AWS CLI (tested at version 1.18.136) // ignores the following potential sources of a region for the purposes of // this AssumeRole call: // // - The [default] profile // - The AWS_REGION environment variable // // Ignoring the [default] profile for the purposes of AssumeRole is arguably // a bug in the CLI since it does use the [default] region for service // calls... but right now we're matching behavior of the other tool. // ------------------------------------------------- const region = roleProfile?.region ?? 'us-east-1'; const stsCreds = sourceProfile ? this.sourceProfileCredentials(sourceProfile, creds) : this.credentialSourceCredentials(credentialSource); this.roleArn = roleArn; var sts = new AWS.STS({ credentials: stsCreds, region, httpOptions: this.httpOptions, }); var roleParams = { RoleArn: roleArn, RoleSessionName: roleSessionName || 'aws-sdk-js-' + Date.now(), }; if (externalId) { roleParams.ExternalId = externalId; } if (mfaSerial && self.tokenCodeFn) { roleParams.SerialNumber = mfaSerial; self.tokenCodeFn(mfaSerial, function (err, token) { if (err) { var message; if (err instanceof Error) { message = err.message; } else { message = err; } callback(AWS.util.error(new Error('Error fetching MFA token: ' + message), { code: 'SharedIniFileCredentialsProviderFailure' })); return; } roleParams.TokenCode = token; sts.assumeRole(roleParams, callback); }); return; } sts.assumeRole(roleParams, callback); } sourceProfileCredentials(sourceProfile, profiles) { var sourceProfileExistanceTest = profiles[sourceProfile]; if (typeof sourceProfileExistanceTest !== 'object') { throw AWS.util.error(new Error('source_profile ' + sourceProfile + ' using profile ' + this.profile + ' does not exist'), { code: 'SharedIniFileCredentialsProviderFailure' }); } // We need to do a manual check here if the source profile (providing the // credentials for the AssumeRole) is an SSO profile. That's because // `SharedIniFileCredentials` itself doesn't support providing credentials from // arbitrary profiles, only for StaticCredentials and AssumeRole type // profiles; if it's an SSO profile you need to instantiate a special // Credential Provider for that. // // --- // // An SSO profile can be configured in 2 ways (put all the info in the profile // section, or put half of it in an `[sso-session]` block), but in both cases // the primary profile block must have the `sso_account_id` key if (sourceProfileExistanceTest.sso_account_id) { return new AWS.SsoCredentials({ profile: sourceProfile }); } return new PatchedSharedIniFileCredentials(AWS.util.merge(this.options || {}, { profile: sourceProfile, preferStaticCredentials: true, })); } // the aws-sdk for js does not support 'credential_source' (https://github.com/aws/aws-sdk-js/issues/1916) // so unfortunately we need to implement this ourselves. credentialSourceCredentials(sourceCredential) { // see https://docs.aws.amazon.com/credref/latest/refdocs/setting-global-credential_source.html switch (sourceCredential) { case 'Environment': { return new AWS.EnvironmentCredentials('AWS'); } case 'Ec2InstanceMetadata': { return new AWS.EC2MetadataCredentials(); } case 'EcsContainer': { return new AWS.ECSCredentials(); } default: { throw new Error(`credential_source ${sourceCredential} in profile ${this.profile} is unsupported. choose one of [Environment, Ec2InstanceMetadata, EcsContainer]`); } } } } exports.PatchedSharedIniFileCredentials = PatchedSharedIniFileCredentials; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLXNkay1pbmlmaWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYXdzLXNkay1pbmlmaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtCQUErQjtBQUUvQjs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBYSwrQkFBZ0MsU0FBUSxHQUFHLENBQUMsd0JBQXdCO0lBU3hFLGVBQWUsQ0FDcEIsS0FBNkMsRUFDN0MsV0FBbUMsRUFDbkMsUUFBMkM7UUFFM0Msa0dBQWtHO1FBQ2xHLDhEQUE4RDtRQUU5RCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixNQUFPLEdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUMzQixJQUFJLEtBQUssQ0FBQyx5Q0FBeUM7Z0JBQ3pDLHlCQUF5QixHQUFHLElBQUksQ0FBQyxPQUFPO2dCQUN4QyxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUNwQyxFQUFFLElBQUksRUFBRSx5Q0FBeUMsRUFBRSxDQUNwRCxDQUFDO1NBQ0g7UUFFRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUM7UUFDaEIsSUFBSSxPQUFPLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQztRQUNuQyxJQUFJLGVBQWUsR0FBRyxXQUFXLENBQUMsaUJBQWlCLENBQUM7UUFDcEQsSUFBSSxVQUFVLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQztRQUN6QyxJQUFJLFNBQVMsR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDO1FBQ3ZDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUM7UUFDL0MsSUFBSSxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsaUJBQWlCLENBQUM7UUFFckQsSUFBSSxDQUFDLENBQUMsYUFBYSxLQUFLLENBQUMsQ0FBQyxnQkFBZ0IsRUFBRTtZQUMxQyxNQUFPLEdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUMzQixJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsSUFBSSxDQUFDLE9BQU8sb0ZBQW9G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QzdFLCtEQUErRDtRQUMvRCxJQUFJLDBCQUEwQixDQUFDLGNBQWMsRUFBRTtZQUM3QyxPQUFPLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsQ0FBQyxDQUFDO1NBQzNEO1FBRUQsT0FBTyxJQUFJLCtCQUErQixDQUN2QyxHQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLEVBQUUsRUFBRTtZQUMxQyxPQUFPLEVBQUUsYUFBYTtZQUN0Qix1QkFBdUIsRUFBRSxJQUFJO1NBQzlCLENBQUMsQ0FDSCxDQUFDO0lBRUosQ0FBQztJQUVELDBHQUEwRztJQUMxRyx3REFBd0Q7SUFDaEQsMkJBQTJCLENBQUMsZ0JBQXdCO1FBQzFELCtGQUErRjtRQUMvRixRQUFRLGdCQUFnQixFQUFFO1lBQ3hCLEtBQUssYUFBYSxDQUFDLENBQUM7Z0JBQ2xCLE9BQU8sSUFBSSxHQUFHLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDOUM7WUFDRCxLQUFLLHFCQUFxQixDQUFDLENBQUM7Z0JBQzFCLE9BQU8sSUFBSSxHQUFHLENBQUMsc0JBQXNCLEVBQUUsQ0FBQzthQUN6QztZQUNELEtBQUssY0FBYyxDQUFDLENBQUM7Z0JBQ25CLE9BQU8sSUFBSSxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDakM7WUFDRCxPQUFPLENBQUMsQ0FBQztnQkFDUCxNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixnQkFBZ0IsZUFBZSxJQUFJLENBQUMsT0FBTyxpRkFBaUYsQ0FBQyxDQUFDO2FBQ3BLO1NBQ0Y7SUFFSCxDQUFDO0NBQ0Y7QUE5SkQsMEVBOEpDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgQVdTIGZyb20gJ2F3cy1zZGsnO1xuXG4vKipcbiAqIEhhY2stZml4XG4gKlxuICogVGhlcmUgYXJlIGEgbnVtYmVyIG9mIGlzc3VlcyBpbiB0aGUgdXBzdHJlYW0gdmVyc2lvbiBvZiBTaGFyZWRJbmlGaWxlQ3JlZGVudGlhbHNcbiAqIHRoYXQgbmVlZCBmaXhpbmc6XG4gKlxuICogMS4gVGhlIHVwc3RyZWFtIGF3cy1zZGsgZG9lcyBub3Qgc3VwcG9ydCB0aGUgJ2NyZWRlbnRpYWxfc291cmNlJyBvcHRpb24uIE1lYW5pbmcgY3JlZGVudGlhbHNcbiAqICAgIGZvciBhc3N1bWUtcm9sZSBjYW5ub3QgYmUgZmV0Y2hlZCB1c2luZyBFQzIvRVNDIG1ldGFkYXRhLlxuICpcbiAqIDIuIFRoZSB1cHN0cmVhbSBhd3Mtc2RrIGRvZXMgbm90IHN1cHBvcnQgU1NPIHByb2ZpbGVzIGFzIHRoZSBzb3VyY2Ugb2YgUm9sZVByb2ZpbGVzLFxuICogICAgYmVjYXVzZSBpdCB3aWxsIGFsd2F5cyB1c2UgdGhlIGBTaGFyZWRJbmlGaWxlQ3JlZGVudGlhbHNgIHByb3ZpZGVyIHRvIGxvYWRcbiAqICAgIHNvdXJjZSBjcmVkZW50aWFscywgYnV0IGluIG9yZGVyIHRvIHN1cHBvcnQgU1NPIHByb2ZpbGVzIHlvdSBtdXN0IHVzZSBhXG4gKiAgICBzZXBhcmF0ZSBjbGFzcyAoYFNzb0NyZWRlbnRpYWxzKS5cbiAqL1xuZXhwb3J0IGNsYXNzIFBhdGNoZWRTaGFyZWRJbmlGaWxlQ3JlZGVudGlhbHMgZXh0ZW5kcyBBV1MuU2hhcmVkSW5pRmlsZUNyZWRlbnRpYWxzIHtcbiAgZGVjbGFyZSBwcml2YXRlIHByb2ZpbGU6IHN0cmluZztcbiAgZGVjbGFyZSBwcml2YXRlIGZpbGVuYW1lOiBzdHJpbmc7XG4gIGRlY2xhcmUgcHJpdmF0ZSBkaXNhYmxlQXNzdW1lUm9sZTogYm9vbGVhbjtcbiAgZGVjbGFyZSBwcml2YXRlIG9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGRlY2xhcmUgcHJpdmF0ZSByb2xlQXJuOiBzdHJpbmc7XG4gIGRlY2xhcmUgcHJpdmF0ZSBodHRwT3B0aW9ucz86IEFXUy5IVFRQT3B0aW9ucztcbiAgZGVjbGFyZSBwcml2YXRlIHRva2VuQ29kZUZuPzogKG1mYVNlcmlhbDogc3RyaW5nLCBjYWxsYmFjazogKGVycj86IEVycm9yLCB0b2tlbj86IHN0cmluZykgPT4gdm9pZCkgPT4gdm9pZDtcblxuICBwdWJsaWMgbG9hZFJvbGVQcm9maWxlKFxuICAgIGNyZWRzOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PixcbiAgICByb2xlUHJvZmlsZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICBjYWxsYmFjazogKGVycj86IEVycm9yLCBkYXRhPzogYW55KSA9PiB2b2lkKSB7XG5cbiAgICAvLyBOZWVkIHRvIGR1cGxpY2F0ZSB0aGUgd2hvbGUgaW1wbGVtZW50YXRpb24gaGVyZSAtLSB0aGUgZnVuY3Rpb24gaXMgbG9uZyBhbmQgaGFzIGJlZW4gd3JpdHRlbiBpblxuICAgIC8vIHN1Y2ggYSB3YXkgdGhhdCB0aGVyZSBhcmUgbm8gc21hbGwgbW9ua2V5IHBhdGNoZXMgcG9zc2libGUuXG5cbiAgICBpZiAodGhpcy5kaXNhYmxlQXNzdW1lUm9sZSkge1xuICAgICAgdGhyb3cgKEFXUyBhcyBhbnkpLnV0aWwuZXJyb3IoXG4gICAgICAgIG5ldyBFcnJvcignUm9sZSBhc3N1bXB0aW9uIHByb2ZpbGVzIGFyZSBkaXNhYmxlZC4gJyArXG4gICAgICAgICAgICAgICAgICAnRmFpbGVkIHRvIGxvYWQgcHJvZmlsZSAnICsgdGhpcy5wcm9maWxlICtcbiAgICAgICAgICAgICAgICAgICcgZnJvbSAnICsgY3JlZHMuZmlsZW5hbWUpLFxuICAgICAgICB7IGNvZGU6ICdTaGFyZWRJbmlGaWxlQ3JlZGVudGlhbHNQcm92aWRlckZhaWx1cmUnIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgcm9sZUFybiA9IHJvbGVQcm9maWxlLnJvbGVfYXJuO1xuICAgIHZhciByb2xlU2Vzc2lvbk5hbWUgPSByb2xlUHJvZmlsZS5yb2xlX3Nlc3Npb25fbmFtZTtcbiAgICB2YXIgZXh0ZXJuYWxJZCA9IHJvbGVQcm9maWxlLmV4dGVybmFsX2lkO1xuICAgIHZhciBtZmFTZXJpYWwgPSByb2xlUHJvZmlsZS5tZmFfc2VyaWFsO1xuICAgIHZhciBzb3VyY2VQcm9maWxlID0gcm9sZVByb2ZpbGUuc291cmNlX3Byb2ZpbGU7XG4gICAgdmFyIGNyZWRlbnRpYWxTb3VyY2UgPSByb2xlUHJvZmlsZS5jcmVkZW50aWFsX3NvdXJjZTtcblxuICAgIGlmICghIXNvdXJjZVByb2ZpbGUgPT09ICEhY3JlZGVudGlhbFNvdXJjZSkge1xuICAgICAgdGhyb3cgKEFXUyBhcyBhbnkpLnV0aWwuZXJyb3IoXG4gICAgICAgIG5ldyBFcnJvcihgV2hlbiB1c2luZyAncm9sZV9hcm4nIGluIHByb2ZpbGUgKCcke3RoaXMucHJvZmlsZX0nKSwgeW91IG11c3QgYWxzbyBjb25maWd1cmUgZXhhY3RseSBvbmUgb2YgJ3NvdXJjZV9wcm9maWxlJyBvciAnY3JlZGVudGlhbF9zb3VyY2UnYCksXG4gICAgICAgIHsgY29kZTogJ1NoYXJlZEluaUZpbGVDcmVkZW50aWFsc1Byb3ZpZGVyRmFpbHVyZScgfSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gQ29uZmlybWVkIHRoaXMgYWdhaW5zdCBBV1MgQ0xJIGJlaGF2aW9yIC0tIHRoZSByZWdpb24gbXVzdCBiZSBpbiB0aGUgYXNzdW1FRCBwcm9maWxlLFxuICAgIC8vIG90aGVyd2lzZSBgdXMtZWFzdC0xYC4gRnJvbSB0aGUgdXBzdHJlYW0gY29tbWVudCBpbiBgYXdzLXNkay1qc2A6XG4gICAgLy8gLS0tLS0tLS0gY29tbWVudCBmcm9tIGF3cy1zZGstanMgLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEV4cGVyaW1lbnRhdGlvbiBzaG93cyB0aGF0IHRoZSBBV1MgQ0xJICh0ZXN0ZWQgYXQgdmVyc2lvbiAxLjE4LjEzNilcbiAgICAvLyBpZ25vcmVzIHRoZSBmb2xsb3dpbmcgcG90ZW50aWFsIHNvdXJjZXMgb2YgYSByZWdpb24gZm9yIHRoZSBwdXJwb3NlcyBvZlxuICAgIC8vIHRoaXMgQXNzdW1lUm9sZSBjYWxsOlxuICAgIC8vXG4gICAgLy8gLSBUaGUgW2RlZmF1bHRdIHByb2ZpbGVcbiAgICAvLyAtIFRoZSBBV1NfUkVHSU9OIGVudmlyb25tZW50IHZhcmlhYmxlXG4gICAgLy9cbiAgICAvLyBJZ25vcmluZyB0aGUgW2RlZmF1bHRdIHByb2ZpbGUgZm9yIHRoZSBwdXJwb3NlcyBvZiBBc3N1bWVSb2xlIGlzIGFyZ3VhYmx5XG4gICAgLy8gYSBidWcgaW4gdGhlIENMSSBzaW5jZSBpdCBkb2VzIHVzZSB0aGUgW2RlZmF1bHRdIHJlZ2lvbiBmb3Igc2VydmljZVxuICAgIC8vIGNhbGxzLi4uIGJ1dCByaWdodCBub3cgd2UncmUgbWF0Y2hpbmcgYmVoYXZpb3Igb2YgdGhlIG90aGVyIHRvb2wuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgY29uc3QgcmVnaW9uID0gcm9sZVByb2ZpbGU/LnJlZ2lvbiA/PyAndXMtZWFzdC0xJztcblxuICAgIGNvbnN0IHN0c0NyZWRzID0gc291cmNlUHJvZmlsZSA/IHRoaXMuc291cmNlUHJvZmlsZUNyZWRlbnRpYWxzKHNvdXJjZVByb2ZpbGUsIGNyZWRzKSA6IHRoaXMuY3JlZGVudGlhbFNvdXJjZUNyZWRlbnRpYWxzKGNyZWRlbnRpYWxTb3VyY2UpO1xuXG4gICAgdGhpcy5yb2xlQXJuID0gcm9sZUFybjtcbiAgICB2YXIgc3RzID0gbmV3IEFXUy5TVFMoe1xuICAgICAgY3JlZGVudGlhbHM6IHN0c0NyZWRzLFxuICAgICAgcmVnaW9uLFxuICAgICAgaHR0cE9wdGlvbnM6IHRoaXMuaHR0cE9wdGlvbnMsXG4gICAgfSk7XG5cbiAgICB2YXIgcm9sZVBhcmFtczogQVdTLlNUUy5Bc3N1bWVSb2xlUmVxdWVzdCA9IHtcbiAgICAgIFJvbGVBcm46IHJvbGVBcm4sXG4gICAgICBSb2xlU2Vzc2lvbk5hbWU6IHJvbGVTZXNzaW9uTmFtZSB8fCAnYXdzLXNkay1qcy0nICsgRGF0ZS5ub3coKSxcbiAgICB9O1xuXG4gICAgaWYgKGV4dGVybmFsSWQpIHtcbiAgICAgIHJvbGVQYXJhbXMuRXh0ZXJuYWxJZCA9IGV4dGVybmFsSWQ7XG4gICAgfVxuXG4gICAgaWYgKG1mYVNlcmlhbCAmJiBzZWxmLnRva2VuQ29kZUZuKSB7XG4gICAgICByb2xlUGFyYW1zLlNlcmlhbE51bWJlciA9IG1mYVNlcmlhbDtcbiAgICAgIHNlbGYudG9rZW5Db2RlRm4obWZhU2VyaWFsLCBmdW5jdGlvbihlcnIsIHRva2VuKSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICB2YXIgbWVzc2FnZTtcbiAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnIubWVzc2FnZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FsbGJhY2soXG4gICAgICAgICAgICAoQVdTIGFzIGFueSkudXRpbC5lcnJvcihcbiAgICAgICAgICAgICAgbmV3IEVycm9yKCdFcnJvciBmZXRjaGluZyBNRkEgdG9rZW46ICcgKyBtZXNzYWdlKSxcbiAgICAgICAgICAgICAgeyBjb2RlOiAnU2hhcmVkSW5pRmlsZUNyZWRlbnRpYWxzUHJvdmlkZXJGYWlsdXJlJyB9LFxuICAgICAgICAgICAgKSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcm9sZVBhcmFtcy5Ub2tlbkNvZGUgPSB0b2tlbjtcbiAgICAgICAgc3RzLmFzc3VtZVJvbGUocm9sZVBhcmFtcywgY2FsbGJhY2spO1xuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN0cy5hc3N1bWVSb2xlKHJvbGVQYXJhbXMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHByaXZhdGUgc291cmNlUHJvZmlsZUNyZWRlbnRpYWxzKHNvdXJjZVByb2ZpbGU6IHN0cmluZywgcHJvZmlsZXM6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KSB7XG4gICAgdmFyIHNvdXJjZVByb2ZpbGVFeGlzdGFuY2VUZXN0ID0gcHJvZmlsZXNbc291cmNlUHJvZmlsZV07XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZVByb2ZpbGVFeGlzdGFuY2VUZXN0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgKEFXUyBhcyBhbnkpLnV0aWwuZXJyb3IoXG4gICAgICAgIG5ldyBFcnJvcignc291cmNlX3Byb2ZpbGUgJyArIHNvdXJjZVByb2ZpbGUgKyAnIHVzaW5nIHByb2ZpbGUgJ1xuICAgICAgICAgICsgdGhpcy5wcm9maWxlICsgJyBkb2VzIG5vdCBleGlzdCcpLFxuICAgICAgICB7IGNvZGU6ICdTaGFyZWRJbmlGaWxlQ3JlZGVudGlhbHNQcm92aWRlckZhaWx1cmUnIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFdlIG5lZWQgdG8gZG8gYSBtYW51YWwgY2hlY2sgaGVyZSBpZiB0aGUgc291cmNlIHByb2ZpbGUgKHByb3ZpZGluZyB0aGVcbiAgICAvLyBjcmVkZW50aWFscyBmb3IgdGhlIEFzc3VtZVJvbGUpIGlzIGFuIFNTTyBwcm9maWxlLiBUaGF0J3MgYmVjYXVzZVxuICAgIC8vIGBTaGFyZWRJbmlGaWxlQ3JlZGVudGlhbHNgIGl0c2VsZiBkb2Vzbid0IHN1cHBvcnQgcHJvdmlkaW5nIGNyZWRlbnRpYWxzIGZyb21cbiAgICAvLyBhcmJpdHJhcnkgcHJvZmlsZXMsIG9ubHkgZm9yIFN0YXRpY0NyZWRlbnRpYWxzIGFuZCBBc3N1bWVSb2xlIHR5cGVcbiAgICAvLyBwcm9maWxlczsgaWYgaXQncyBhbiBTU08gcHJvZmlsZSB5b3UgbmVlZCB0byBpbnN0YW50aWF0ZSBhIHNwZWNpYWxcbiAgICAvLyBDcmVkZW50aWFsIFByb3ZpZGVyIGZvciB0aGF0LlxuICAgIC8vXG4gICAgLy8gLS0tXG4gICAgLy9cbiAgICAvLyBBbiBTU08gcHJvZmlsZSBjYW4gYmUgY29uZmlndXJlZCBpbiAyIHdheXMgKHB1dCBhbGwgdGhlIGluZm8gaW4gdGhlIHByb2ZpbGVcbiAgICAvLyBzZWN0aW9uLCBvciBwdXQgaGFsZiBvZiBpdCBpbiBhbiBgW3Nzby1zZXNzaW9uXWAgYmxvY2spLCBidXQgaW4gYm90aCBjYXNlc1xuICAgIC8vIHRoZSBwcmltYXJ5IHByb2ZpbGUgYmxvY2sgbXVzdCBoYXZlIHRoZSBgc3NvX2FjY291bnRfaWRgIGtleVxuICAgIGlmIChzb3VyY2VQcm9maWxlRXhpc3RhbmNlVGVzdC5zc29fYWNjb3VudF9pZCkge1xuICAgICAgcmV0dXJuIG5ldyBBV1MuU3NvQ3JlZGVudGlhbHMoeyBwcm9maWxlOiBzb3VyY2VQcm9maWxlIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUGF0Y2hlZFNoYXJlZEluaUZpbGVDcmVkZW50aWFscyhcbiAgICAgIChBV1MgYXMgYW55KS51dGlsLm1lcmdlKHRoaXMub3B0aW9ucyB8fCB7fSwge1xuICAgICAgICBwcm9maWxlOiBzb3VyY2VQcm9maWxlLFxuICAgICAgICBwcmVmZXJTdGF0aWNDcmVkZW50aWFsczogdHJ1ZSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgfVxuXG4gIC8vIHRoZSBhd3Mtc2RrIGZvciBqcyBkb2VzIG5vdCBzdXBwb3J0ICdjcmVkZW50aWFsX3NvdXJjZScgKGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1qcy9pc3N1ZXMvMTkxNilcbiAgLy8gc28gdW5mb3J0dW5hdGVseSB3ZSBuZWVkIHRvIGltcGxlbWVudCB0aGlzIG91cnNlbHZlcy5cbiAgcHJpdmF0ZSBjcmVkZW50aWFsU291cmNlQ3JlZGVudGlhbHMoc291cmNlQ3JlZGVudGlhbDogc3RyaW5nKSB7XG4gICAgLy8gc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jcmVkcmVmL2xhdGVzdC9yZWZkb2NzL3NldHRpbmctZ2xvYmFsLWNyZWRlbnRpYWxfc291cmNlLmh0bWxcbiAgICBzd2l0Y2ggKHNvdXJjZUNyZWRlbnRpYWwpIHtcbiAgICAgIGNhc2UgJ0Vudmlyb25tZW50Jzoge1xuICAgICAgICByZXR1cm4gbmV3IEFXUy5FbnZpcm9ubWVudENyZWRlbnRpYWxzKCdBV1MnKTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0VjMkluc3RhbmNlTWV0YWRhdGEnOiB7XG4gICAgICAgIHJldHVybiBuZXcgQVdTLkVDMk1ldGFkYXRhQ3JlZGVudGlhbHMoKTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0Vjc0NvbnRhaW5lcic6IHtcbiAgICAgICAgcmV0dXJuIG5ldyBBV1MuRUNTQ3JlZGVudGlhbHMoKTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjcmVkZW50aWFsX3NvdXJjZSAke3NvdXJjZUNyZWRlbnRpYWx9IGluIHByb2ZpbGUgJHt0aGlzLnByb2ZpbGV9IGlzIHVuc3VwcG9ydGVkLiBjaG9vc2Ugb25lIG9mIFtFbnZpcm9ubWVudCwgRWMySW5zdGFuY2VNZXRhZGF0YSwgRWNzQ29udGFpbmVyXWApO1xuICAgICAgfVxuICAgIH1cblxuICB9XG59XG4iXX0=