UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

152 lines 20.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CredentialPlugins = void 0; const util_1 = require("util"); const provider_caching_1 = require("./provider-caching"); const api_1 = require("../../../../@aws-cdk/tmp-toolkit-helpers/src/api"); const logging_1 = require("../../logging"); const util_2 = require("../../util"); const plugin_1 = require("../plugin/plugin"); /** * Cache for credential providers. * * Given an account and an operating mode (read or write) will return an * appropriate credential provider for credentials for the given account. The * credential provider will be cached so that multiple AWS clients for the same * environment will not make multiple network calls to obtain credentials. * * Will use default credentials if they are for the right account; otherwise, * all loaded credential provider plugins will be tried to obtain credentials * for the given account. */ class CredentialPlugins { constructor(host) { this.cache = {}; this.host = host ?? plugin_1.PluginHost.instance; } async fetchCredentialsFor(awsAccountId, mode) { const key = `${awsAccountId}-${mode}`; if (!(key in this.cache)) { this.cache[key] = await this.lookupCredentials(awsAccountId, mode); } return this.cache[key]; } get availablePluginNames() { return this.host.credentialProviderSources.map((s) => s.name); } async lookupCredentials(awsAccountId, mode) { const triedSources = []; // Otherwise, inspect the various credential sources we have for (const source of this.host.credentialProviderSources) { let available; try { available = await source.isAvailable(); } catch (e) { // This shouldn't happen, but let's guard against it anyway (0, logging_1.warning)(`Uncaught exception in ${source.name}: ${(0, util_2.formatErrorMessage)(e)}`); available = false; } if (!available) { (0, logging_1.debug)('Credentials source %s is not available, ignoring it.', source.name); continue; } triedSources.push(source); let canProvide; try { canProvide = await source.canProvideCredentials(awsAccountId); } catch (e) { // This shouldn't happen, but let's guard against it anyway (0, logging_1.warning)(`Uncaught exception in ${source.name}: ${(0, util_2.formatErrorMessage)(e)}`); canProvide = false; } if (!canProvide) { continue; } (0, logging_1.debug)(`Using ${source.name} credentials for account ${awsAccountId}`); return { credentials: await v3ProviderFromPlugin(() => source.getProvider(awsAccountId, mode, { supportsV3Providers: true, })), pluginName: source.name, }; } return undefined; } } exports.CredentialPlugins = CredentialPlugins; /** * Take a function that calls the plugin, and turn it into an SDKv3-compatible credential provider. * * What we will do is the following: * * - Query the plugin and see what kind of result it gives us. * - If the result is self-refreshing or doesn't need refreshing, we turn it into an SDKv3 provider * and return it directly. * * If the underlying return value is a provider, we will make it a caching provider * (because we can't know if it will cache by itself or not). * * If the underlying return value is a static credential, caching isn't relevant. * * If the underlying return value is V2 credentials, those have caching built-in. * - If the result is a static credential that expires, we will wrap it in an SDKv3 provider * that will query the plugin again when the credential expires. */ async function v3ProviderFromPlugin(producer) { const initial = await producer(); if (isV3Provider(initial)) { // Already a provider, make caching return (0, provider_caching_1.makeCachingProvider)(initial); } else if (isV3Credentials(initial) && initial.expiration === undefined) { // Static credentials that don't need refreshing nor caching return () => Promise.resolve(initial); } else if (isV3Credentials(initial) && initial.expiration !== undefined) { // Static credentials that do need refreshing and caching return refreshFromPluginProvider(initial, producer); } else if (isV2Credentials(initial)) { // V2 credentials that refresh and cache themselves return v3ProviderFromV2Credentials(initial); } else { throw new api_1.AuthenticationError(`Plugin returned a value that doesn't resemble AWS credentials: ${(0, util_1.inspect)(initial)}`); } } /** * Converts a V2 credential into a V3-compatible provider */ function v3ProviderFromV2Credentials(x) { return async () => { // Get will fetch or refresh as necessary await x.getPromise(); return { accessKeyId: x.accessKeyId, secretAccessKey: x.secretAccessKey, sessionToken: x.sessionToken, expiration: x.expireTime ?? undefined, }; }; } function refreshFromPluginProvider(current, producer) { return async () => { if ((0, provider_caching_1.credentialsAboutToExpire)(current)) { const newCreds = await producer(); if (!isV3Credentials(newCreds)) { throw new api_1.AuthenticationError(`Plugin initially returned static V3 credentials but now returned something else: ${(0, util_1.inspect)(newCreds)}`); } current = newCreds; } return current; }; } function isV3Provider(x) { return typeof x === 'function'; } function isV2Credentials(x) { return !!(x && typeof x === 'object' && x.getPromise); } function isV3Credentials(x) { return !!(x && typeof x === 'object' && x.accessKeyId && !isV2Credentials(x)); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlZGVudGlhbC1wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3JlZGVudGlhbC1wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtCQUErQjtBQUcvQix5REFBbUY7QUFDbkYsMEVBQXVGO0FBQ3ZGLDJDQUErQztBQUMvQyxxQ0FBZ0Q7QUFFaEQsNkNBQThDO0FBRTlDOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBYSxpQkFBaUI7SUFJNUIsWUFBWSxJQUFpQjtRQUhaLFVBQUssR0FBZ0UsRUFBRSxDQUFDO1FBSXZGLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLG1CQUFVLENBQUMsUUFBUSxDQUFDO0lBQzFDLENBQUM7SUFFTSxLQUFLLENBQUMsbUJBQW1CLENBQUMsWUFBb0IsRUFBRSxJQUFVO1FBQy9ELE1BQU0sR0FBRyxHQUFHLEdBQUcsWUFBWSxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNyRSxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFXLG9CQUFvQjtRQUM3QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxZQUFvQixFQUFFLElBQVU7UUFDOUQsTUFBTSxZQUFZLEdBQStCLEVBQUUsQ0FBQztRQUNwRCw0REFBNEQ7UUFDNUQsS0FBSyxNQUFNLE1B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QU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluc3BlY3QgfSBmcm9tICd1dGlsJztcbmltcG9ydCB0eXBlIHsgQ3JlZGVudGlhbFByb3ZpZGVyU291cmNlLCBGb3JSZWFkaW5nLCBGb3JXcml0aW5nLCBQbHVnaW5Qcm92aWRlclJlc3VsdCwgU0RLdjJDb21wYXRpYmxlQ3JlZGVudGlhbHMsIFNES3YzQ29tcGF0aWJsZUNyZWRlbnRpYWxQcm92aWRlciwgU0RLdjNDb21wYXRpYmxlQ3JlZGVudGlhbHMgfSBmcm9tICdAYXdzLWNkay9jbGktcGx1Z2luLWNvbnRyYWN0JztcbmltcG9ydCB0eXBlIHsgQXdzQ3JlZGVudGlhbElkZW50aXR5LCBBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlciB9IGZyb20gJ0BzbWl0aHkvdHlwZXMnO1xuaW1wb3J0IHsgY3JlZGVudGlhbHNBYm91dFRvRXhwaXJlLCBtYWtlQ2FjaGluZ1Byb3ZpZGVyIH0gZnJvbSAnLi9wcm92aWRlci1jYWNoaW5nJztcbmltcG9ydCB7IEF1dGhlbnRpY2F0aW9uRXJyb3IgfSBmcm9tICcuLi8uLi8uLi8uLi9AYXdzLWNkay90bXAtdG9vbGtpdC1oZWxwZXJzL3NyYy9hcGknO1xuaW1wb3J0IHsgZGVidWcsIHdhcm5pbmcgfSBmcm9tICcuLi8uLi9sb2dnaW5nJztcbmltcG9ydCB7IGZvcm1hdEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHR5cGUgeyBNb2RlIH0gZnJvbSAnLi4vcGx1Z2luL21vZGUnO1xuaW1wb3J0IHsgUGx1Z2luSG9zdCB9IGZyb20gJy4uL3BsdWdpbi9wbHVnaW4nO1xuXG4vKipcbiAqIENhY2hlIGZvciBjcmVkZW50aWFsIHByb3ZpZGVycy5cbiAqXG4gKiBHaXZlbiBhbiBhY2NvdW50IGFuZCBhbiBvcGVyYXRpbmcgbW9kZSAocmVhZCBvciB3cml0ZSkgd2lsbCByZXR1cm4gYW5cbiAqIGFwcHJvcHJpYXRlIGNyZWRlbnRpYWwgcHJvdmlkZXIgZm9yIGNyZWRlbnRpYWxzIGZvciB0aGUgZ2l2ZW4gYWNjb3VudC4gVGhlXG4gKiBjcmVkZW50aWFsIHByb3ZpZGVyIHdpbGwgYmUgY2FjaGVkIHNvIHRoYXQgbXVsdGlwbGUgQVdTIGNsaWVudHMgZm9yIHRoZSBzYW1lXG4gKiBlbnZpcm9ubWVudCB3aWxsIG5vdCBtYWtlIG11bHRpcGxlIG5ldHdvcmsgY2FsbHMgdG8gb2J0YWluIGNyZWRlbnRpYWxzLlxuICpcbiAqIFdpbGwgdXNlIGRlZmF1bHQgY3JlZGVudGlhbHMgaWYgdGhleSBhcmUgZm9yIHRoZSByaWdodCBhY2NvdW50OyBvdGhlcndpc2UsXG4gKiBhbGwgbG9hZGVkIGNyZWRlbnRpYWwgcHJvdmlkZXIgcGx1Z2lucyB3aWxsIGJlIHRyaWVkIHRvIG9idGFpbiBjcmVkZW50aWFsc1xuICogZm9yIHRoZSBnaXZlbiBhY2NvdW50LlxuICovXG5leHBvcnQgY2xhc3MgQ3JlZGVudGlhbFBsdWdpbnMge1xuICBwcml2YXRlIHJlYWRvbmx5IGNhY2hlOiB7IFtrZXk6IHN0cmluZ106IFBsdWdpbkNyZWRlbnRpYWxzRmV0Y2hSZXN1bHQgfCB1bmRlZmluZWQgfSA9IHt9O1xuICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IFBsdWdpbkhvc3Q7XG5cbiAgY29uc3RydWN0b3IoaG9zdD86IFBsdWdpbkhvc3QpIHtcbiAgICB0aGlzLmhvc3QgPSBob3N0ID8/IFBsdWdpbkhvc3QuaW5zdGFuY2U7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZmV0Y2hDcmVkZW50aWFsc0Zvcihhd3NBY2NvdW50SWQ6IHN0cmluZywgbW9kZTogTW9kZSk6IFByb21pc2U8UGx1Z2luQ3JlZGVudGlhbHNGZXRjaFJlc3VsdCB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IGtleSA9IGAke2F3c0FjY291bnRJZH0tJHttb2RlfWA7XG4gICAgaWYgKCEoa2V5IGluIHRoaXMuY2FjaGUpKSB7XG4gICAgICB0aGlzLmNhY2hlW2tleV0gPSBhd2FpdCB0aGlzLmxvb2t1cENyZWRlbnRpYWxzKGF3c0FjY291bnRJZCwgbW9kZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhY2hlW2tleV07XG4gIH1cblxuICBwdWJsaWMgZ2V0IGF2YWlsYWJsZVBsdWdpbk5hbWVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5ob3N0LmNyZWRlbnRpYWxQcm92aWRlclNvdXJjZXMubWFwKChzKSA9PiBzLm5hbWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsb29rdXBDcmVkZW50aWFscyhhd3NBY2NvdW50SWQ6IHN0cmluZywgbW9kZTogTW9kZSk6IFByb21pc2U8UGx1Z2luQ3JlZGVudGlhbHNGZXRjaFJlc3VsdCB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHRyaWVkU291cmNlczogQ3JlZGVudGlhbFByb3ZpZGVyU291cmNlW10gPSBbXTtcbiAgICAvLyBPdGhlcndpc2UsIGluc3BlY3QgdGhlIHZhcmlvdXMgY3JlZGVudGlhbCBzb3VyY2VzIHdlIGhhdmVcbiAgICBmb3IgKGNvbnN0IHNvdXJjZSBvZiB0aGlzLmhvc3QuY3JlZGVudGlhbFByb3ZpZGVyU291cmNlcykge1xuICAgICAgbGV0IGF2YWlsYWJsZTogYm9vbGVhbjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF2YWlsYWJsZSA9IGF3YWl0IHNvdXJjZS5pc0F2YWlsYWJsZSgpO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIC8vIFRoaXMgc2hvdWxkbid0IGhhcHBlbiwgYnV0IGxldCdzIGd1YXJkIGFnYWluc3QgaXQgYW55d2F5XG4gICAgICAgIHdhcm5pbmcoYFVuY2F1Z2h0IGV4Y2VwdGlvbiBpbiAke3NvdXJjZS5uYW1lfTogJHtmb3JtYXRFcnJvck1lc3NhZ2UoZSl9YCk7XG4gICAgICAgIGF2YWlsYWJsZSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWF2YWlsYWJsZSkge1xuICAgICAgICBkZWJ1ZygnQ3JlZGVudGlhbHMgc291cmNlICVzIGlzIG5vdCBhdmFpbGFibGUsIGlnbm9yaW5nIGl0LicsIHNvdXJjZS5uYW1lKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0cmllZFNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgICAgbGV0IGNhblByb3ZpZGU6IGJvb2xlYW47XG4gICAgICB0cnkge1xuICAgICAgICBjYW5Qcm92aWRlID0gYXdhaXQgc291cmNlLmNhblByb3ZpZGVDcmVkZW50aWFscyhhd3NBY2NvdW50SWQpO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIC8vIFRoaXMgc2hvdWxkbid0IGhhcHBlbiwgYnV0IGxldCdzIGd1YXJkIGFnYWluc3QgaXQgYW55d2F5XG4gICAgICAgIHdhcm5pbmcoYFVuY2F1Z2h0IGV4Y2VwdGlvbiBpbiAke3NvdXJjZS5uYW1lfTogJHtmb3JtYXRFcnJvck1lc3NhZ2UoZSl9YCk7XG4gICAgICAgIGNhblByb3ZpZGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICghY2FuUHJvdmlkZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGRlYnVnKGBVc2luZyAke3NvdXJjZS5uYW1lfSBjcmVkZW50aWFscyBmb3IgYWNjb3VudCAke2F3c0FjY291bnRJZH1gKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY3JlZGVudGlhbHM6IGF3YWl0IHYzUHJvdmlkZXJGcm9tUGx1Z2luKCgpID0+IHNvdXJjZS5nZXRQcm92aWRlcihhd3NBY2NvdW50SWQsIG1vZGUgYXMgRm9yUmVhZGluZyB8IEZvcldyaXRpbmcsIHtcbiAgICAgICAgICBzdXBwb3J0c1YzUHJvdmlkZXJzOiB0cnVlLFxuICAgICAgICB9KSksXG4gICAgICAgIHBsdWdpbk5hbWU6IHNvdXJjZS5uYW1lLFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc3VsdCBmcm9tIHRyeWluZyB0byBmZXRjaCBjcmVkZW50aWFscyBmcm9tIHRoZSBQbHVnaW4gaG9zdFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBsdWdpbkNyZWRlbnRpYWxzRmV0Y2hSZXN1bHQge1xuICAvKipcbiAgICogU0RLLXYzIGNvbXBhdGlibGUgY3JlZGVudGlhbCBwcm92aWRlclxuICAgKi9cbiAgcmVhZG9ubHkgY3JlZGVudGlhbHM6IEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHBsdWdpbiB0aGF0IHN1Y2Nlc3NmdWxseSBwcm92aWRlZCBjcmVkZW50aWFsc1xuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luTmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRha2UgYSBmdW5jdGlvbiB0aGF0IGNhbGxzIHRoZSBwbHVnaW4sIGFuZCB0dXJuIGl0IGludG8gYW4gU0RLdjMtY29tcGF0aWJsZSBjcmVkZW50aWFsIHByb3ZpZGVyLlxuICpcbiAqIFdoYXQgd2Ugd2lsbCBkbyBpcyB0aGUgZm9sbG93aW5nOlxuICpcbiAqIC0gUXVlcnkgdGhlIHBsdWdpbiBhbmQgc2VlIHdoYXQga2luZCBvZiByZXN1bHQgaXQgZ2l2ZXMgdXMuXG4gKiAtIElmIHRoZSByZXN1bHQgaXMgc2VsZi1yZWZyZXNoaW5nIG9yIGRvZXNuJ3QgbmVlZCByZWZyZXNoaW5nLCB3ZSB0dXJuIGl0IGludG8gYW4gU0RLdjMgcHJvdmlkZXJcbiAqICAgYW5kIHJldHVybiBpdCBkaXJlY3RseS5cbiAqICAgKiBJZiB0aGUgdW5kZXJseWluZyByZXR1cm4gdmFsdWUgaXMgYSBwcm92aWRlciwgd2Ugd2lsbCBtYWtlIGl0IGEgY2FjaGluZyBwcm92aWRlclxuICogICAgIChiZWNhdXNlIHdlIGNhbid0IGtub3cgaWYgaXQgd2lsbCBjYWNoZSBieSBpdHNlbGYgb3Igbm90KS5cbiAqICAgKiBJZiB0aGUgdW5kZXJseWluZyByZXR1cm4gdmFsdWUgaXMgYSBzdGF0aWMgY3JlZGVudGlhbCwgY2FjaGluZyBpc24ndCByZWxldmFudC5cbiAqICAgKiBJZiB0aGUgdW5kZXJseWluZyByZXR1cm4gdmFsdWUgaXMgVjIgY3JlZGVudGlhbHMsIHRob3NlIGhhdmUgY2FjaGluZyBidWlsdC1pbi5cbiAqIC0gSWYgdGhlIHJlc3VsdCBpcyBhIHN0YXRpYyBjcmVkZW50aWFsIHRoYXQgZXhwaXJlcywgd2Ugd2lsbCB3cmFwIGl0IGluIGFuIFNES3YzIHByb3ZpZGVyXG4gKiAgIHRoYXQgd2lsbCBxdWVyeSB0aGUgcGx1Z2luIGFnYWluIHdoZW4gdGhlIGNyZWRlbnRpYWwgZXhwaXJlcy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdjNQcm92aWRlckZyb21QbHVnaW4ocHJvZHVjZXI6ICgpID0+IFByb21pc2U8UGx1Z2luUHJvdmlkZXJSZXN1bHQ+KTogUHJvbWlzZTxBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcj4ge1xuICBjb25zdCBpbml0aWFsID0gYXdhaXQgcHJvZHVjZXIoKTtcblxuICBpZiAoaXNWM1Byb3ZpZGVyKGluaXRpYWwpKSB7XG4gICAgLy8gQWxyZWFkeSBhIHByb3ZpZGVyLCBtYWtlIGNhY2hpbmdcbiAgICByZXR1cm4gbWFrZUNhY2hpbmdQcm92aWRlcihpbml0aWFsKTtcbiAgfSBlbHNlIGlmIChpc1YzQ3JlZGVudGlhbHMoaW5pdGlhbCkgJiYgaW5pdGlhbC5leHBpcmF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBTdGF0aWMgY3JlZGVudGlhbHMgdGhhdCBkb24ndCBuZWVkIHJlZnJlc2hpbmcgbm9yIGNhY2hpbmdcbiAgICByZXR1cm4gKCkgPT4gUHJvbWlzZS5yZXNvbHZlKGluaXRpYWwpO1xuICB9IGVsc2UgaWYgKGlzVjNDcmVkZW50aWFscyhpbml0aWFsKSAmJiBpbml0aWFsLmV4cGlyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIFN0YXRpYyBjcmVkZW50aWFscyB0aGF0IGRvIG5lZWQgcmVmcmVzaGluZyBhbmQgY2FjaGluZ1xuICAgIHJldHVybiByZWZyZXNoRnJvbVBsdWdpblByb3ZpZGVyKGluaXRpYWwsIHByb2R1Y2VyKTtcbiAgfSBlbHNlIGlmIChpc1YyQ3JlZGVudGlhbHMoaW5pdGlhbCkpIHtcbiAgICAvLyBWMiBjcmVkZW50aWFscyB0aGF0IHJlZnJlc2ggYW5kIGNhY2hlIHRoZW1zZWx2ZXNcbiAgICByZXR1cm4gdjNQcm92aWRlckZyb21WMkNyZWRlbnRpYWxzKGluaXRpYWwpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBBdXRoZW50aWNhdGlvbkVycm9yKGBQbHVnaW4gcmV0dXJuZWQgYSB2YWx1ZSB0aGF0IGRvZXNuJ3QgcmVzZW1ibGUgQVdTIGNyZWRlbnRpYWxzOiAke2luc3BlY3QoaW5pdGlhbCl9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIFYyIGNyZWRlbnRpYWwgaW50byBhIFYzLWNvbXBhdGlibGUgcHJvdmlkZXJcbiAqL1xuZnVuY3Rpb24gdjNQcm92aWRlckZyb21WMkNyZWRlbnRpYWxzKHg6IFNES3YyQ29tcGF0aWJsZUNyZWRlbnRpYWxzKTogQXdzQ3JlZGVudGlhbElkZW50aXR5UHJvdmlkZXIge1xuICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgIC8vIEdldCB3aWxsIGZldGNoIG9yIHJlZnJlc2ggYXMgbmVjZXNzYXJ5XG4gICAgYXdhaXQgeC5nZXRQcm9taXNlKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzS2V5SWQ6IHguYWNjZXNzS2V5SWQsXG4gICAgICBzZWNyZXRBY2Nlc3NLZXk6IHguc2VjcmV0QWNjZXNzS2V5LFxuICAgICAgc2Vzc2lvblRva2VuOiB4LnNlc3Npb25Ub2tlbixcbiAgICAgIGV4cGlyYXRpb246IHguZXhwaXJlVGltZSA/PyB1bmRlZmluZWQsXG4gICAgfTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVmcmVzaEZyb21QbHVnaW5Qcm92aWRlcihjdXJyZW50OiBBd3NDcmVkZW50aWFsSWRlbnRpdHksIHByb2R1Y2VyOiAoKSA9PiBQcm9taXNlPFBsdWdpblByb3ZpZGVyUmVzdWx0Pik6IEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyIHtcbiAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICBpZiAoY3JlZGVudGlhbHNBYm91dFRvRXhwaXJlKGN1cnJlbnQpKSB7XG4gICAgICBjb25zdCBuZXdDcmVkcyA9IGF3YWl0IHByb2R1Y2VyKCk7XG4gICAgICBpZiAoIWlzVjNDcmVkZW50aWFscyhuZXdDcmVkcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEF1dGhlbnRpY2F0aW9uRXJyb3IoYFBsdWdpbiBpbml0aWFsbHkgcmV0dXJuZWQgc3RhdGljIFYzIGNyZWRlbnRpYWxzIGJ1dCBub3cgcmV0dXJuZWQgc29tZXRoaW5nIGVsc2U6ICR7aW5zcGVjdChuZXdDcmVkcyl9YCk7XG4gICAgICB9XG4gICAgICBjdXJyZW50ID0gbmV3Q3JlZHM7XG4gICAgfVxuICAgIHJldHVybiBjdXJyZW50O1xuICB9O1xufVxuXG5mdW5jdGlvbiBpc1YzUHJvdmlkZXIoeDogUGx1Z2luUHJvdmlkZXJSZXN1bHQpOiB4IGlzIFNES3YzQ29tcGF0aWJsZUNyZWRlbnRpYWxQcm92aWRlciB7XG4gIHJldHVybiB0eXBlb2YgeCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNWMkNyZWRlbnRpYWxzKHg6IFBsdWdpblByb3ZpZGVyUmVzdWx0KTogeCBpcyBTREt2MkNvbXBhdGlibGVDcmVkZW50aWFscyB7XG4gIHJldHVybiAhISh4ICYmIHR5cGVvZiB4ID09PSAnb2JqZWN0JyAmJiAoeCBhcyBTREt2MkNvbXBhdGlibGVDcmVkZW50aWFscykuZ2V0UHJvbWlzZSk7XG59XG5cbmZ1bmN0aW9uIGlzVjNDcmVkZW50aWFscyh4OiBQbHVnaW5Qcm92aWRlclJlc3VsdCk6IHggaXMgU0RLdjNDb21wYXRpYmxlQ3JlZGVudGlhbHMge1xuICByZXR1cm4gISEoeCAmJiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeC5hY2Nlc3NLZXlJZCAmJiAhaXNWMkNyZWRlbnRpYWxzKHgpKTtcbn1cbiJdfQ==