UNPKG

27.1 kBJavaScriptView Raw
1"use strict";
2var _a;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.SecretValue = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const cx_api_1 = require("@aws-cdk/cx-api");
8const cfn_dynamic_reference_1 = require("./cfn-dynamic-reference");
9const cfn_resource_1 = require("./cfn-resource");
10const feature_flags_1 = require("./feature-flags");
11const cfn_reference_1 = require("./private/cfn-reference");
12const intrinsic_1 = require("./private/intrinsic");
13const token_1 = require("./token");
14/**
15 * Work with secret values in the CDK
16 *
17 * Constructs that need secrets will declare parameters of type `SecretValue`.
18 *
19 * The actual values of these secrets should not be committed to your
20 * repository, or even end up in the synthesized CloudFormation template. Instead, you should
21 * store them in an external system like AWS Secrets Manager or SSM Parameter
22 * Store, and you can reference them by calling `SecretValue.secretsManager()` or
23 * `SecretValue.ssmSecure()`.
24 *
25 * You can use `SecretValue.unsafePlainText()` to construct a `SecretValue` from a
26 * literal string, but doing so is highly discouraged.
27 *
28 * To make sure secret values don't accidentally end up in readable parts
29 * of your infrastructure definition (such as the environment variables
30 * of an AWS Lambda Function, where everyone who can read the function
31 * definition has access to the secret), using secret values directly is not
32 * allowed. You must pass them to constructs that accept `SecretValue`
33 * properties, which are guaranteed to use the value only in CloudFormation
34 * properties that are write-only.
35 *
36 * If you are sure that what you are doing is safe, you can call
37 * `secretValue.unsafeUnwrap()` to access the protected string of the secret
38 * value.
39 *
40 * (If you are writing something like an AWS Lambda Function and need to access
41 * a secret inside it, make the API call to `GetSecretValue` directly inside
42 * your Lamba's code, instead of using environment variables.)
43 */
44class SecretValue extends intrinsic_1.Intrinsic {
45 /**
46 * Construct a SecretValue (do not use!)
47 *
48 * Do not use the constructor directly: use one of the factory functions on the class
49 * instead.
50 */
51 constructor(protectedValue, options) {
52 super(protectedValue, options);
53 try {
54 jsiiDeprecationWarnings._aws_cdk_core_IntrinsicProps(options);
55 }
56 catch (error) {
57 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
58 Error.captureStackTrace(error, SecretValue);
59 }
60 throw error;
61 }
62 this.rawValue = protectedValue;
63 }
64 /**
65 * Test whether an object is a SecretValue
66 */
67 static isSecretValue(x) {
68 return typeof x === 'object' && x && x[SECRET_VALUE_SYM];
69 }
70 /**
71 * Construct a literal secret value for use with secret-aware constructs
72 *
73 * Do not use this method for any secrets that you care about! The value
74 * will be visible to anyone who has access to the CloudFormation template
75 * (via the AWS Console, SDKs, or CLI).
76 *
77 * The only reasonable use case for using this method is when you are testing.
78 *
79 * @deprecated Use `unsafePlainText()` instead.
80 */
81 static plainText(secret) {
82 try {
83 jsiiDeprecationWarnings.print("@aws-cdk/core.SecretValue#plainText", "Use `unsafePlainText()` instead.");
84 }
85 catch (error) {
86 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
87 Error.captureStackTrace(error, this.plainText);
88 }
89 throw error;
90 }
91 return new SecretValue(secret);
92 }
93 /**
94 * Construct a literal secret value for use with secret-aware constructs
95 *
96 * Do not use this method for any secrets that you care about! The value
97 * will be visible to anyone who has access to the CloudFormation template
98 * (via the AWS Console, SDKs, or CLI).
99 *
100 * The only reasonable use case for using this method is when you are testing.
101 */
102 static unsafePlainText(secret) {
103 return new SecretValue(secret);
104 }
105 /**
106 * Creates a `SecretValue` with a value which is dynamically loaded from AWS Secrets Manager.
107 * @param secretId The ID or ARN of the secret
108 * @param options Options
109 */
110 static secretsManager(secretId, options = {}) {
111 try {
112 jsiiDeprecationWarnings._aws_cdk_core_SecretsManagerSecretOptions(options);
113 }
114 catch (error) {
115 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
116 Error.captureStackTrace(error, this.secretsManager);
117 }
118 throw error;
119 }
120 if (!secretId) {
121 throw new Error('secretId cannot be empty');
122 }
123 if (!token_1.Token.isUnresolved(secretId) && !secretId.startsWith('arn:') && secretId.includes(':')) {
124 throw new Error(`secret id "${secretId}" is not an ARN but contains ":"`);
125 }
126 if (options.versionStage && options.versionId) {
127 throw new Error(`verionStage: '${options.versionStage}' and versionId: '${options.versionId}' were both provided but only one is allowed`);
128 }
129 const parts = [
130 secretId,
131 'SecretString',
132 options.jsonField || '',
133 options.versionStage || '',
134 options.versionId || '',
135 ];
136 const dyref = new cfn_dynamic_reference_1.CfnDynamicReference(cfn_dynamic_reference_1.CfnDynamicReferenceService.SECRETS_MANAGER, parts.join(':'));
137 return this.cfnDynamicReference(dyref);
138 }
139 /**
140 * Use a secret value stored from a Systems Manager (SSM) parameter.
141 *
142 * @param parameterName The name of the parameter in the Systems Manager
143 * Parameter Store. The parameter name is case-sensitive.
144 *
145 * @param version An integer that specifies the version of the parameter to
146 * use. If you don't specify the exact version, AWS CloudFormation uses the
147 * latest version of the parameter.
148 */
149 static ssmSecure(parameterName, version) {
150 return this.cfnDynamicReference(new cfn_dynamic_reference_1.CfnDynamicReference(cfn_dynamic_reference_1.CfnDynamicReferenceService.SSM_SECURE, version ? `${parameterName}:${version}` : parameterName));
151 }
152 /**
153 * Obtain the secret value through a CloudFormation dynamic reference.
154 *
155 * If possible, use `SecretValue.ssmSecure` or `SecretValue.secretsManager` directly.
156 *
157 * @param ref The dynamic reference to use.
158 */
159 static cfnDynamicReference(ref) {
160 try {
161 jsiiDeprecationWarnings._aws_cdk_core_CfnDynamicReference(ref);
162 }
163 catch (error) {
164 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
165 Error.captureStackTrace(error, this.cfnDynamicReference);
166 }
167 throw error;
168 }
169 return new SecretValue(ref);
170 }
171 /**
172 * Obtain the secret value through a CloudFormation parameter.
173 *
174 * Generally, this is not a recommended approach. AWS Secrets Manager is the
175 * recommended way to reference secrets.
176 *
177 * @param param The CloudFormation parameter to use.
178 */
179 static cfnParameter(param) {
180 try {
181 jsiiDeprecationWarnings._aws_cdk_core_CfnParameter(param);
182 }
183 catch (error) {
184 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
185 Error.captureStackTrace(error, this.cfnParameter);
186 }
187 throw error;
188 }
189 if (!param.noEcho) {
190 throw new Error('CloudFormation parameter must be configured with "NoEcho"');
191 }
192 return new SecretValue(param.value);
193 }
194 /**
195 * Use a resource's output as secret value
196 */
197 static resourceAttribute(attr) {
198 const resolved = token_1.Tokenization.reverseCompleteString(attr);
199 if (!resolved || !cfn_reference_1.CfnReference.isCfnReference(resolved) || !cfn_resource_1.CfnResource.isCfnResource(resolved.target)) {
200 throw new Error('SecretValue.resourceAttribute() must be used with a resource attribute');
201 }
202 return new SecretValue(attr);
203 }
204 /**
205 * Disable usage protection on this secret
206 *
207 * Call this to indicate that you want to use the secret value held by this
208 * object in an unchecked way. If you don't call this method, using the secret
209 * value directly in a string context or as a property value somewhere will
210 * produce an error.
211 *
212 * This method has 'unsafe' in the name on purpose! Make sure that the
213 * construct property you are using the returned value in is does not end up
214 * in a place in your AWS infrastructure where it could be read by anyone
215 * unexpected.
216 *
217 * When in doubt, don't call this method and only pass the object to constructs that
218 * accept `SecretValue` parameters.
219 */
220 unsafeUnwrap() {
221 return token_1.Token.asString(this.rawValue);
222 }
223 /**
224 * Resolve the secret
225 *
226 * If the feature flag is not set, resolve as normal. Otherwise, throw a descriptive
227 * error that the usage guard is missing.
228 */
229 resolve(context) {
230 try {
231 jsiiDeprecationWarnings._aws_cdk_core_IResolveContext(context);
232 }
233 catch (error) {
234 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
235 Error.captureStackTrace(error, this.resolve);
236 }
237 throw error;
238 }
239 if (feature_flags_1.FeatureFlags.of(context.scope).isEnabled(cx_api_1.CHECK_SECRET_USAGE)) {
240 throw new Error(`Synthing a secret value to ${context.documentPath.join('/')}. Using a SecretValue here risks exposing your secret. Only pass SecretValues to constructs that accept a SecretValue property, or call AWS Secrets Manager directly in your runtime code. Call 'secretValue.unsafeUnwrap()' if you understand and accept the risks.`);
241 }
242 return super.resolve(context);
243 }
244}
245exports.SecretValue = SecretValue;
246_a = JSII_RTTI_SYMBOL_1;
247SecretValue[_a] = { fqn: "@aws-cdk/core.SecretValue", version: "1.204.0" };
248const SECRET_VALUE_SYM = Symbol.for('@aws-cdk/core.SecretValue');
249Object.defineProperty(SecretValue.prototype, SECRET_VALUE_SYM, {
250 value: true,
251 configurable: false,
252 enumerable: false,
253 writable: false,
254});
255//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjcmV0LXZhbHVlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2VjcmV0LXZhbHVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDRDQUFxRDtBQUNyRCxtRUFBMEY7QUFFMUYsaURBQTZDO0FBQzdDLG1EQUErQztBQUMvQywyREFBdUQ7QUFDdkQsbURBQWdFO0FBRWhFLG1DQUE4QztBQUU5Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFDSCxNQUFhLFdBQVksU0FBUSxxQkFBUztJQTJIeEM7Ozs7O09BS0c7SUFDSCxZQUFZLGNBQW1CLEVBQUUsT0FBd0I7UUFDdkQsS0FBSyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQzs7Ozs7OytDQWxJdEIsV0FBVzs7OztRQW1JcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxjQUFjLENBQUM7S0FDaEM7SUFuSUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsYUFBYSxDQUFDLENBQU07UUFDaEMsT0FBTyxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQzFEO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBYzs7Ozs7Ozs7OztRQUNwQyxPQUFPLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQ2hDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQWM7UUFDMUMsT0FBTyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUNoQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsY0FBYyxDQUFDLFFBQWdCLEVBQUUsVUFBdUMsRUFBRTs7Ozs7Ozs7OztRQUN0RixJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1NBQzdDO1FBRUQsSUFBSSxDQUFDLGFBQUss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QUFDO0tBQy9COztBQXZLSCxrQ0F3S0M7OztBQWlDRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUMsQ0FBQztBQUVqRSxNQUFNLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7SUFDN0QsS0FBSyxFQUFFLElBQUk7SUFDWCxZQUFZLEVBQUUsS0FBSztJQUNuQixVQUFVLEVBQUUsS0FBSztJQUNqQixRQUFRLEVBQUUsS0FBSztDQUNoQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDSEVDS19TRUNSRVRfVVNBR0UgfSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0IHsgQ2ZuRHluYW1pY1JlZmVyZW5jZSwgQ2ZuRHluYW1pY1JlZmVyZW5jZVNlcnZpY2UgfSBmcm9tICcuL2Nmbi1keW5hbWljLXJlZmVyZW5jZSc7XG5pbXBvcnQgeyBDZm5QYXJhbWV0ZXIgfSBmcm9tICcuL2Nmbi1wYXJhbWV0ZXInO1xuaW1wb3J0IHsgQ2ZuUmVzb3VyY2UgfSBmcm9tICcuL2Nmbi1yZXNvdXJjZSc7XG5pbXBvcnQgeyBGZWF0dXJlRmxhZ3MgfSBmcm9tICcuL2ZlYXR1cmUtZmxhZ3MnO1xuaW1wb3J0IHsgQ2ZuUmVmZXJlbmNlIH0gZnJvbSAnLi9wcml2YXRlL2Nmbi1yZWZlcmVuY2UnO1xuaW1wb3J0IHsgSW50cmluc2ljLCBJbnRyaW5zaWNQcm9wcyB9IGZyb20gJy4vcHJpdmF0ZS9pbnRyaW5zaWMnO1xuaW1wb3J0IHsgSVJlc29sdmVDb250ZXh0IH0gZnJvbSAnLi9yZXNvbHZhYmxlJztcbmltcG9ydCB7IFRva2VuLCBUb2tlbml6YXRpb24gfSBmcm9tICcuL3Rva2VuJztcblxuLyoqXG4gKiBXb3JrIHdpdGggc2VjcmV0IHZhbHVlcyBpbiB0aGUgQ0RLXG4gKlxuICogQ29uc3RydWN0cyB0aGF0IG5lZWQgc2VjcmV0cyB3aWxsIGRlY2xhcmUgcGFyYW1ldGVycyBvZiB0eXBlIGBTZWNyZXRWYWx1ZWAuXG4gKlxuICogVGhlIGFjdHVhbCB2YWx1ZXMgb2YgdGhlc2Ugc2VjcmV0cyBzaG91bGQgbm90IGJlIGNvbW1pdHRlZCB0byB5b3VyXG4gKiByZXBvc2l0b3J5LCBvciBldmVuIGVuZCB1cCBpbiB0aGUgc3ludGhlc2l6ZWQgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUuIEluc3RlYWQsIHlvdSBzaG91bGRcbiAqIHN0b3JlIHRoZW0gaW4gYW4gZXh0ZXJuYWwgc3lzdGVtIGxpa2UgQVdTIFNlY3JldHMgTWFuYWdlciBvciBTU00gUGFyYW1ldGVyXG4gKiBTdG9yZSwgYW5kIHlvdSBjYW4gcmVmZXJlbmNlIHRoZW0gYnkgY2FsbGluZyBgU2VjcmV0VmFsdWUuc2VjcmV0c01hbmFnZXIoKWAgb3JcbiAqIGBTZWNyZXRWYWx1ZS5zc21TZWN1cmUoKWAuXG4gKlxuICogWW91IGNhbiB1c2UgYFNlY3JldFZhbHVlLnVuc2FmZVBsYWluVGV4dCgpYCB0byBjb25zdHJ1Y3QgYSBgU2VjcmV0VmFsdWVgIGZyb20gYVxuICogbGl0ZXJhbCBzdHJpbmcsIGJ1dCBkb2luZyBzbyBpcyBoaWdobHkgZGlzY291cmFnZWQuXG4gKlxuICogVG8gbWFrZSBzdXJlIHNlY3JldCB2YWx1ZXMgZG9uJ3QgYWNjaWRlbnRhbGx5IGVuZCB1cCBpbiByZWFkYWJsZSBwYXJ0c1xuICogb2YgeW91ciBpbmZyYXN0cnVjdHVyZSBkZWZpbml0aW9uIChzdWNoIGFzIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXNcbiAqIG9mIGFuIEFXUyBMYW1iZGEgRnVuY3Rpb24sIHdoZXJlIGV2ZXJ5b25lIHdobyBjYW4gcmVhZCB0aGUgZnVuY3Rpb25cbiAqIGRlZmluaXRpb24gaGFzIGFjY2VzcyB0byB0aGUgc2VjcmV0KSwgdXNpbmcgc2VjcmV0IHZhbHVlcyBkaXJlY3RseSBpcyBub3RcbiAqIGFsbG93ZWQuIFlvdSBtdXN0IHBhc3MgdGhlbSB0byBjb25zdHJ1Y3RzIHRoYXQgYWNjZXB0IGBTZWNyZXRWYWx1ZWBcbiAqIHByb3BlcnRpZXMsIHdoaWNoIGFyZSBndWFyYW50ZWVkIHRvIHVzZSB0aGUgdmFsdWUgb25seSBpbiBDbG91ZEZvcm1hdGlvblxuICogcHJvcGVydGllcyB0aGF0IGFyZSB3cml0ZS1vbmx5LlxuICpcbiAqIElmIHlvdSBhcmUgc3VyZSB0aGF0IHdoYXQgeW91IGFyZSBkb2luZyBpcyBzYWZlLCB5b3UgY2FuIGNhbGxcbiAqIGBzZWNyZXRWYWx1ZS51bnNhZmVVbndyYXAoKWAgdG8gYWNjZXNzIHRoZSBwcm90ZWN0ZWQgc3RyaW5nIG9mIHRoZSBzZWNyZXRcbiAqIHZhbHVlLlxuICpcbiAqIChJZiB5b3UgYXJlIHdyaXRpbmcgc29tZXRoaW5nIGxpa2UgYW4gQVdTIExhbWJkYSBGdW5jdGlvbiBhbmQgbmVlZCB0byBhY2Nlc3NcbiAqIGEgc2VjcmV0IGluc2lkZSBpdCwgbWFrZSB0aGUgQVBJIGNhbGwgdG8gYEdldFNlY3JldFZhbHVlYCBkaXJlY3RseSBpbnNpZGVcbiAqIHlvdXIgTGFtYmEncyBjb2RlLCBpbnN0ZWFkIG9mIHVzaW5nIGVudmlyb25tZW50IHZhcmlhYmxlcy4pXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWNyZXRWYWx1ZSBleHRlbmRzIEludHJpbnNpYyB7XG4gIC8qKlxuICAgKiBUZXN0IHdoZXRoZXIgYW4gb2JqZWN0IGlzIGEgU2VjcmV0VmFsdWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaXNTZWNyZXRWYWx1ZSh4OiBhbnkpOiB4IGlzIFNlY3JldFZhbHVlIHtcbiAgICByZXR1cm4gdHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggJiYgeFtTRUNSRVRfVkFMVUVfU1lNXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBsaXRlcmFsIHNlY3JldCB2YWx1ZSBmb3IgdXNlIHdpdGggc2VjcmV0LWF3YXJlIGNvbnN0cnVjdHNcbiAgICpcbiAgICogRG8gbm90IHVzZSB0aGlzIG1ldGhvZCBmb3IgYW55IHNlY3JldHMgdGhhdCB5b3UgY2FyZSBhYm91dCEgVGhlIHZhbHVlXG4gICAqIHdpbGwgYmUgdmlzaWJsZSB0byBhbnlvbmUgd2hvIGhhcyBhY2Nlc3MgdG8gdGhlIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlXG4gICAqICh2aWEgdGhlIEFXUyBDb25zb2xlLCBTREtzLCBvciBDTEkpLlxuICAgKlxuICAgKiBUaGUgb25seSByZWFzb25hYmxlIHVzZSBjYXNlIGZvciB1c2luZyB0aGlzIG1ldGhvZCBpcyB3aGVuIHlvdSBhcmUgdGVzdGluZy5cbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGB1bnNhZmVQbGFpblRleHQoKWAgaW5zdGVhZC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcGxhaW5UZXh0KHNlY3JldDogc3RyaW5nKTogU2VjcmV0VmFsdWUge1xuICAgIHJldHVybiBuZXcgU2VjcmV0VmFsdWUoc2VjcmV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBsaXRlcmFsIHNlY3JldCB2YWx1ZSBmb3IgdXNlIHdpdGggc2VjcmV0LWF3YXJlIGNvbnN0cnVjdHNcbiAgICpcbiAgICogRG8gbm90IHVzZSB0aGlzIG1ldGhvZCBmb3IgYW55IHNlY3JldHMgdGhhdCB5b3UgY2FyZSBhYm91dCEgVGhlIHZhbHVlXG4gICAqIHdpbGwgYmUgdmlzaWJsZSB0byBhbnlvbmUgd2hvIGhhcyBhY2Nlc3MgdG8gdGhlIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlXG4gICAqICh2aWEgdGhlIEFXUyBDb25zb2xlLCBTREtzLCBvciBDTEkpLlxuICAgKlxuICAgKiBUaGUgb25seSByZWFzb25hYmxlIHVzZSBjYXNlIGZvciB1c2luZyB0aGlzIG1ldGhvZCBpcyB3aGVuIHlvdSBhcmUgdGVzdGluZy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgdW5zYWZlUGxhaW5UZXh0KHNlY3JldDogc3RyaW5nKTogU2VjcmV0VmFsdWUge1xuICAgIHJldHVybiBuZXcgU2VjcmV0VmFsdWUoc2VjcmV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgYFNlY3JldFZhbHVlYCB3aXRoIGEgdmFsdWUgd2hpY2ggaXMgZHluYW1pY2FsbHkgbG9hZGVkIGZyb20gQVdTIFNlY3JldHMgTWFuYWdlci5cbiAgICogQHBhcmFtIHNlY3JldElkIFRoZSBJRCBvciBBUk4gb2YgdGhlIHNlY3JldFxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHNlY3JldHNNYW5hZ2VyKHNlY3JldElkOiBzdHJpbmcsIG9wdGlvbnM6IFNlY3JldHNNYW5hZ2VyU2VjcmV0T3B0aW9ucyA9IHt9KTogU2VjcmV0VmFsdWUge1xuICAgIGlmICghc2VjcmV0SWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2VjcmV0SWQgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQoc2VjcmV0SWQpICYmICFzZWNyZXRJZC5zdGFydHNXaXRoKCdhcm46JykgJiYgc2VjcmV0SWQuaW5jbHVkZXMoJzonKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBzZWNyZXQgaWQgXCIke3NlY3JldElkfVwiIGlzIG5vdCBhbiBBUk4gYnV0IGNvbnRhaW5zIFwiOlwiYCk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMudmVyc2lvblN0YWdlICYmIG9wdGlvbnMudmVyc2lvbklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHZlcmlvblN0YWdlOiAnJHtvcHRpb25zLnZlcnNpb25TdGFnZX0nIGFuZCB2ZXJzaW9uSWQ6ICcke29wdGlvbnMudmVyc2lvbklkfScgd2VyZSBib3RoIHByb3ZpZGVkIGJ1dCBvbmx5IG9uZSBpcyBhbGxvd2VkYCk7XG4gICAgfVxuXG4gICAgY29uc3QgcGFydHMgPSBbXG4gICAgICBzZWNyZXRJZCxcbiAgICAgICdTZWNyZXRTdHJpbmcnLFxuICAgICAgb3B0aW9ucy5qc29uRmllbGQgfHwgJycsXG4gICAgICBvcHRpb25zLnZlcnNpb25TdGFnZSB8fCAnJyxcbiAgICAgIG9wdGlvbnMudmVyc2lvbklkIHx8ICcnLFxuICAgIF07XG5cbiAgICBjb25zdCBkeXJlZiA9IG5ldyBDZm5EeW5hbWljUmVmZXJlbmNlKENmbkR5bmFtaWNSZWZlcmVuY2VTZXJ2aWNlLlNFQ1JFVFNfTUFOQUdFUiwgcGFydHMuam9pbignOicpKTtcbiAgICByZXR1cm4gdGhpcy5jZm5EeW5hbWljUmVmZXJlbmNlKGR5cmVmKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2UgYSBzZWNyZXQgdmFsdWUgc3RvcmVkIGZyb20gYSBTeXN0ZW1zIE1hbmFnZXIgKFNTTSkgcGFyYW1ldGVyLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZSBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGluIHRoZSBTeXN0ZW1zIE1hbmFnZXJcbiAgICogUGFyYW1ldGVyIFN0b3JlLiBUaGUgcGFyYW1ldGVyIG5hbWUgaXMgY2FzZS1zZW5zaXRpdmUuXG4gICAqXG4gICAqIEBwYXJhbSB2ZXJzaW9uIEFuIGludGVnZXIgdGhhdCBzcGVjaWZpZXMgdGhlIHZlcnNpb24gb2YgdGhlIHBhcmFtZXRlciB0b1xuICAgKiB1c2UuIElmIHlvdSBkb24ndCBzcGVjaWZ5IHRoZSBleGFjdCB2ZXJzaW9uLCBBV1MgQ2xvdWRGb3JtYXRpb24gdXNlcyB0aGVcbiAgICogbGF0ZXN0IHZlcnNpb24gb2YgdGhlIHBhcmFtZXRlci5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc3NtU2VjdXJlKHBhcmFtZXRlck5hbWU6IHN0cmluZywgdmVyc2lvbj86IHN0cmluZyk6IFNlY3JldFZhbHVlIHtcbiAgICByZXR1cm4gdGhpcy5jZm5EeW5hbWljUmVmZXJlbmNlKFxuICAgICAgbmV3IENmbkR5bmFtaWNSZWZlcmVuY2UoQ2ZuRHluYW1pY1JlZmVyZW5jZVNlcnZpY2UuU1NNX1NFQ1VSRSxcbiAgICAgICAgdmVyc2lvbiA/IGAke3BhcmFtZXRlck5hbWV9OiR7dmVyc2lvbn1gIDogcGFyYW1ldGVyTmFtZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9idGFpbiB0aGUgc2VjcmV0IHZhbHVlIHRocm91Z2ggYSBDbG91ZEZvcm1hdGlvbiBkeW5hbWljIHJlZmVyZW5jZS5cbiAgICpcbiAgICogSWYgcG9zc2libGUsIHVzZSBgU2VjcmV0VmFsdWUuc3NtU2VjdXJlYCBvciBgU2VjcmV0VmFsdWUuc2VjcmV0c01hbmFnZXJgIGRpcmVjdGx5LlxuICAgKlxuICAgKiBAcGFyYW0gcmVmIFRoZSBkeW5hbWljIHJlZmVyZW5jZSB0byB1c2UuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNmbkR5bmFtaWNSZWZlcmVuY2UocmVmOiBDZm5EeW5hbWljUmVmZXJlbmNlKSB7XG4gICAgcmV0dXJuIG5ldyBTZWNyZXRWYWx1ZShyZWYpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9idGFpbiB0aGUgc2VjcmV0IHZhbHVlIHRocm91Z2ggYSBDbG91ZEZvcm1hdGlvbiBwYXJhbWV0ZXIuXG4gICAqXG4gICAqIEdlbmVyYWxseSwgdGhpcyBpcyBub3QgYSByZWNvbW1lbmRlZCBhcHByb2FjaC4gQVdTIFNlY3JldHMgTWFuYWdlciBpcyB0aGVcbiAgICogcmVjb21tZW5kZWQgd2F5IHRvIHJlZmVyZW5jZSBzZWNyZXRzLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW0gVGhlIENsb3VkRm9ybWF0aW9uIHBhcmFtZXRlciB0byB1c2UuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNmblBhcmFtZXRlcihwYXJhbTogQ2ZuUGFyYW1ldGVyKSB7XG4gICAgaWYgKCFwYXJhbS5ub0VjaG8pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2xvdWRGb3JtYXRpb24gcGFyYW1ldGVyIG11c3QgYmUgY29uZmlndXJlZCB3aXRoIFwiTm9FY2hvXCInKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFNlY3JldFZhbHVlKHBhcmFtLnZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2UgYSByZXNvdXJjZSdzIG91dHB1dCBhcyBzZWNyZXQgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVzb3VyY2VBdHRyaWJ1dGUoYXR0cjogc3RyaW5nKSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSBUb2tlbml6YXRpb24ucmV2ZXJzZUNvbXBsZXRlU3RyaW5nKGF0dHIpO1xuICAgIGlmICghcmVzb2x2ZWQgfHwgIUNmblJlZmVyZW5jZS5pc0NmblJlZmVyZW5jZShyZXNvbHZlZCkgfHwgIUNmblJlc291cmNlLmlzQ2ZuUmVzb3VyY2UocmVzb2x2ZWQudGFyZ2V0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZWNyZXRWYWx1ZS5yZXNvdXJjZUF0dHJpYnV0ZSgpIG11c3QgYmUgdXNlZCB3aXRoIGEgcmVzb3VyY2UgYXR0cmlidXRlJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBTZWNyZXRWYWx1ZShhdHRyKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgcmF3VmFsdWU6IGFueTtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgU2VjcmV0VmFsdWUgKGRvIG5vdCB1c2UhKVxuICAgKlxuICAgKiBEbyBub3QgdXNlIHRoZSBjb25zdHJ1Y3RvciBkaXJlY3RseTogdXNlIG9uZSBvZiB0aGUgZmFjdG9yeSBmdW5jdGlvbnMgb24gdGhlIGNsYXNzXG4gICAqIGluc3RlYWQuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWRWYWx1ZTogYW55LCBvcHRpb25zPzogSW50cmluc2ljUHJvcHMpIHtcbiAgICBzdXBlcihwcm90ZWN0ZWRWYWx1ZSwgb3B0aW9ucyk7XG4gICAgdGhpcy5yYXdWYWx1ZSA9IHByb3RlY3RlZFZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc2FibGUgdXNhZ2UgcHJvdGVjdGlvbiBvbiB0aGlzIHNlY3JldFxuICAgKlxuICAgKiBDYWxsIHRoaXMgdG8gaW5kaWNhdGUgdGhhdCB5b3Ugd2FudCB0byB1c2UgdGhlIHNlY3JldCB2YWx1ZSBoZWxkIGJ5IHRoaXNcbiAgICogb2JqZWN0IGluIGFuIHVuY2hlY2tlZCB3YXkuIElmIHlvdSBkb24ndCBjYWxsIHRoaXMgbWV0aG9kLCB1c2luZyB0aGUgc2VjcmV0XG4gICAqIHZhbHVlIGRpcmVjdGx5IGluIGEgc3RyaW5nIGNvbnRleHQgb3IgYXMgYSBwcm9wZXJ0eSB2YWx1ZSBzb21ld2hlcmUgd2lsbFxuICAgKiBwcm9kdWNlIGFuIGVycm9yLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBoYXMgJ3Vuc2FmZScgaW4gdGhlIG5hbWUgb24gcHVycG9zZSEgTWFrZSBzdXJlIHRoYXQgdGhlXG4gICAqIGNvbnN0cnVjdCBwcm9wZXJ0eSB5b3UgYXJlIHVzaW5nIHRoZSByZXR1cm5lZCB2YWx1ZSBpbiBpcyBkb2VzIG5vdCBlbmQgdXBcbiAgICogaW4gYSBwbGFjZSBpbiB5b3VyIEFXUyBpbmZyYXN0cnVjdHVyZSB3aGVyZSBpdCBjb3VsZCBiZSByZWFkIGJ5IGFueW9uZVxuICAgKiB1bmV4cGVjdGVkLlxuICAgKlxuICAgKiBXaGVuIGluIGRvdWJ0LCBkb24ndCBjYWxsIHRoaXMgbWV0aG9kIGFuZCBvbmx5IHBhc3MgdGhlIG9iamVjdCB0byBjb25zdHJ1Y3RzIHRoYXRcbiAgICogYWNjZXB0IGBTZWNyZXRWYWx1ZWAgcGFyYW1ldGVycy5cbiAgICovXG4gIHB1YmxpYyB1bnNhZmVVbndyYXAoKSB7XG4gICAgcmV0dXJuIFRva2VuLmFzU3RyaW5nKHRoaXMucmF3VmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIHNlY3JldFxuICAgKlxuICAgKiBJZiB0aGUgZmVhdHVyZSBmbGFnIGlzIG5vdCBzZXQsIHJlc29sdmUgYXMgbm9ybWFsLiBPdGhlcndpc2UsIHRocm93IGEgZGVzY3JpcHRpdmVcbiAgICogZXJyb3IgdGhhdCB0aGUgdXNhZ2UgZ3VhcmQgaXMgbWlzc2luZy5cbiAgICovXG4gIHB1YmxpYyByZXNvbHZlKGNvbnRleHQ6IElSZXNvbHZlQ29udGV4dCkge1xuICAgIGlmIChGZWF0dXJlRmxhZ3Mub2YoY29udGV4dC5zY29wZSkuaXNFbmFibGVkKENIRUNLX1NFQ1JFVF9VU0FHRSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFN5bnRoaW5nIGEgc2VjcmV0IHZhbHVlIHRvICR7Y29udGV4dC5kb2N1bWVudFBhdGguam9pbignLycpfS4gVXNpbmcgYSBTZWNyZXRWYWx1ZSBoZXJlIHJpc2tzIGV4cG9zaW5nIHlvdXIgc2VjcmV0LiBPbmx5IHBhc3MgU2VjcmV0VmFsdWVzIHRvIGNvbnN0cnVjdHMgdGhhdCBhY2NlcHQgYSBTZWNyZXRWYWx1ZSBwcm9wZXJ0eSwgb3IgY2FsbCBBV1MgU2VjcmV0cyBNYW5hZ2VyIGRpcmVjdGx5IGluIHlvdXIgcnVudGltZSBjb2RlLiBDYWxsICdzZWNyZXRWYWx1ZS51bnNhZmVVbndyYXAoKScgaWYgeW91IHVuZGVyc3RhbmQgYW5kIGFjY2VwdCB0aGUgcmlza3MuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBzdXBlci5yZXNvbHZlKGNvbnRleHQpO1xuICB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgcmVmZXJlbmNpbmcgYSBzZWNyZXQgdmFsdWUgZnJvbSBTZWNyZXRzIE1hbmFnZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VjcmV0c01hbmFnZXJTZWNyZXRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgc2VjcmV0IHZlcnNpb24gdGhhdCB5b3Ugd2FudCB0byByZXRyaWV2ZSBieSB0aGUgc3RhZ2luZyBsYWJlbCBhdHRhY2hlZCB0byB0aGUgdmVyc2lvbi5cbiAgICpcbiAgICogQ2FuIHNwZWNpZnkgYXQgbW9zdCBvbmUgb2YgYHZlcnNpb25JZGAgYW5kIGB2ZXJzaW9uU3RhZ2VgLlxuICAgKlxuICAgKiBAZGVmYXVsdCBBV1NDVVJSRU5UXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uU3RhZ2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHZlcnNpb24gb2YgdGhlIHNlY3JldCB5b3Ugd2FudCB0byB1c2UuXG4gICAqXG4gICAqIENhbiBzcGVjaWZ5IGF0IG1vc3Qgb25lIG9mIGB2ZXJzaW9uSWRgIGFuZCBgdmVyc2lvblN0YWdlYC5cbiAgICpcbiAgICogQGRlZmF1bHQgQVdTQ1VSUkVOVFxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbklkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUga2V5IG9mIGEgSlNPTiBmaWVsZCB0byByZXRyaWV2ZS4gVGhpcyBjYW4gb25seSBiZSB1c2VkIGlmIHRoZSBzZWNyZXRcbiAgICogc3RvcmVzIGEgSlNPTiBvYmplY3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcmV0dXJucyBhbGwgdGhlIGNvbnRlbnQgc3RvcmVkIGluIHRoZSBTZWNyZXRzIE1hbmFnZXIgc2VjcmV0LlxuICAgKi9cbiAgcmVhZG9ubHkganNvbkZpZWxkPzogc3RyaW5nO1xufVxuXG5jb25zdCBTRUNSRVRfVkFMVUVfU1lNID0gU3ltYm9sLmZvcignQGF3cy1jZGsvY29yZS5TZWNyZXRWYWx1ZScpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoU2VjcmV0VmFsdWUucHJvdG90eXBlLCBTRUNSRVRfVkFMVUVfU1lNLCB7XG4gIHZhbHVlOiB0cnVlLFxuICBjb25maWd1cmFibGU6IGZhbHNlLFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgd3JpdGFibGU6IGZhbHNlLFxufSk7Il19
\No newline at end of file