@liflig/cdk 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,15 @@
1
1
  /**
2
2
  * This lambda verifies credentials:
3
- * - Against Cognito user pool if request uses Bearer token
3
+ * - Against Cognito user pool if request uses access token in Bearer authorization header
4
4
  * - Against credentials saved in Secret Manager if request uses basic auth (and if secret exists)
5
5
  *
6
- * Expects the following environment variables
6
+ * Expects the following environment variables:
7
7
  * - USER_POOL_ID
8
8
  * - BASIC_AUTH_CREDENTIALS_SECRET_NAME (optional)
9
- * - Secret value should follow this format: `{"username":"<username>","password":"<password>"}`.
10
- * A different format with an array of pre-encoded credentials is also supported - see docs for
11
- * the `CognitoUserPoolOrBasicAuthAuthorizerProps` on the `ApiGateway` construct.
9
+ * - Name of secret in AWS Secrets Manager that stores basic auth credentials. See
10
+ * `BasicAuthAuthorizerProps` on the `ApiGateway` construct for the supported formats.
12
11
  * - REQUIRED_SCOPE (optional)
13
- * - Set this to require that the bearer token payload contains the given scope
12
+ * - Set this to require that the access token payload contains the given scope
14
13
  */
15
14
  import { SecretsManager } from "@aws-sdk/client-secrets-manager";
16
15
  import { CognitoJwtVerifier } from "aws-jwt-verify";
@@ -19,7 +18,7 @@ export const handler = async (event) => {
19
18
  if (!authHeader) {
20
19
  return { isAuthorized: false };
21
20
  }
22
- const expectedBasicAuthHeaders = await getExpectedBasicAuthHeaders();
21
+ const expectedBasicAuthCredentials = await getExpectedBasicAuthCredentials();
23
22
  if (authHeader.startsWith("Bearer ")) {
24
23
  const result = await verifyAccessToken(authHeader.substring(7)); // substring(7) == after 'Bearer '
25
24
  switch (result) {
@@ -36,19 +35,20 @@ export const handler = async (event) => {
36
35
  isAuthorized: true,
37
36
  context: {
38
37
  clientId: result.client_id,
39
- internalAuthorizationHeader: expectedBasicAuthHeaders?.[0],
38
+ internalAuthorizationHeader: expectedBasicAuthCredentials?.[0]?.basicAuthHeader,
40
39
  },
41
40
  };
42
41
  }
43
42
  }
44
43
  else if (authHeader.startsWith("Basic ") &&
45
- expectedBasicAuthHeaders !== undefined) {
46
- for (const expectedHeader of expectedBasicAuthHeaders) {
47
- if (authHeader === expectedHeader) {
44
+ expectedBasicAuthCredentials !== undefined) {
45
+ for (const expected of expectedBasicAuthCredentials) {
46
+ if (authHeader === expected.basicAuthHeader) {
48
47
  return {
49
48
  isAuthorized: true,
50
49
  context: {
51
- internalAuthorizationHeader: expectedHeader,
50
+ username: expected.username,
51
+ internalAuthorizationHeader: expected.basicAuthHeader,
52
52
  },
53
53
  };
54
54
  }
@@ -109,27 +109,25 @@ export const dependencies = {
109
109
  createSecretsManager: () => new SecretsManager(),
110
110
  };
111
111
  /** Cache this value, so that subsequent lambda invocations don't have to refetch. */
112
- let cachedBasicAuthHeaders = undefined;
112
+ let cachedBasicAuthCredentials = undefined;
113
113
  /**
114
- * Returns an array of allowed basic auth headers, to support credential secrets with multiple
115
- * values (see `BasicAuthAuthorizerProps` on the `ApiGateway` construct for more on this).
114
+ * Returns an array, to support credential secrets with multiple values (see
115
+ * `BasicAuthAuthorizerProps` on the `ApiGateway` construct for more on this).
116
116
  */
117
- async function getExpectedBasicAuthHeaders() {
118
- if (cachedBasicAuthHeaders === undefined) {
117
+ async function getExpectedBasicAuthCredentials() {
118
+ if (cachedBasicAuthCredentials === undefined) {
119
119
  const secretName = process.env["BASIC_AUTH_CREDENTIALS_SECRET_NAME"];
120
120
  if (!secretName) {
121
121
  return undefined;
122
122
  }
123
- cachedBasicAuthHeaders = await getSecretAsBasicAuthHeaders(secretName);
123
+ cachedBasicAuthCredentials = await getBasicAuthCredentialsSecret(secretName);
124
124
  }
125
- return cachedBasicAuthHeaders;
125
+ return cachedBasicAuthCredentials;
126
126
  }
127
- async function getSecretAsBasicAuthHeaders(secretName) {
127
+ async function getBasicAuthCredentialsSecret(secretName) {
128
128
  const secret = await getSecretValue(secretName);
129
- if (isSingleUsernameAndPassword(secret)) {
130
- const header = "Basic " +
131
- Buffer.from(`${secret.username}:${secret.password}`).toString("base64");
132
- return [header];
129
+ if (isUsernameAndPasswordObject(secret)) {
130
+ return [encodeBasicAuthCredentials(secret)];
133
131
  }
134
132
  // See `BasicAuthAuthorizerProps` on the `ApiGateway` construct for an explanation of the formats
135
133
  // we parse here
@@ -142,8 +140,11 @@ async function getSecretAsBasicAuthHeaders(secretName) {
142
140
  console.error(`Failed to parse credentials array in secret '${secretName}' as JSON`, e);
143
141
  throw new Error();
144
142
  }
143
+ if (isArrayOfUsernameAndPasswordObjects(credentialsArray)) {
144
+ return credentialsArray.map(encodeBasicAuthCredentials);
145
+ }
145
146
  if (isStringArray(credentialsArray)) {
146
- return credentialsArray.map((encodedCredential) => `Basic ${encodedCredential}`);
147
+ return credentialsArray.map(parseEncodedBasicAuthCredentials);
147
148
  }
148
149
  }
149
150
  console.error(`Basic auth credentials secret did not follow any expected format (secret name: '${secretName}')`);
@@ -160,11 +161,16 @@ async function getSecretValue(secretName) {
160
161
  return JSON.parse(secret.SecretString);
161
162
  }
162
163
  catch (e) {
163
- console.error(`Failed to parse secret '${secretName}' as JSON`, e);
164
+ console.error(`Failed to parse secret '${secretName}' as JSON:`, e);
164
165
  throw new Error();
165
166
  }
166
167
  }
167
- function isSingleUsernameAndPassword(value) {
168
+ function encodeBasicAuthCredentials(credentials) {
169
+ const basicAuthHeader = "Basic " +
170
+ Buffer.from(`${credentials.username}:${credentials.password}`).toString("base64");
171
+ return { basicAuthHeader, username: credentials.username };
172
+ }
173
+ function isUsernameAndPasswordObject(value) {
168
174
  return (typeof value === "object" &&
169
175
  value !== null &&
170
176
  "username" in value &&
@@ -172,6 +178,17 @@ function isSingleUsernameAndPassword(value) {
172
178
  "password" in value &&
173
179
  typeof value.password === "string");
174
180
  }
181
+ function isArrayOfUsernameAndPasswordObjects(value) {
182
+ if (!Array.isArray(value)) {
183
+ return false;
184
+ }
185
+ for (const element of value) {
186
+ if (!isUsernameAndPasswordObject(element)) {
187
+ return false;
188
+ }
189
+ }
190
+ return true;
191
+ }
175
192
  function hasCredentialsKeyWithStringValue(value) {
176
193
  return (typeof value === "object" &&
177
194
  value !== null &&
@@ -189,8 +206,33 @@ function isStringArray(value) {
189
206
  }
190
207
  return true;
191
208
  }
209
+ /**
210
+ * We want to return the requesting username as a context variable in
211
+ * {@link AuthorizerResult.context}, for API Gateway access logs and parameter mapping. So if the
212
+ * basic auth credentials secret is stored as pre-encoded base64 strings, we need to parse them to
213
+ * get the username.
214
+ */
215
+ function parseEncodedBasicAuthCredentials(encodedCredentials) {
216
+ let decodedCredentials;
217
+ try {
218
+ decodedCredentials = Buffer.from(encodedCredentials, "base64").toString();
219
+ }
220
+ catch (e) {
221
+ console.error("Basic auth credentials secret could not be decoded as base64:", e);
222
+ throw new Error();
223
+ }
224
+ const usernameAndPassword = decodedCredentials.split(":", 2);
225
+ if (usernameAndPassword.length !== 2) {
226
+ console.error("Basic auth credentials secret could not be decoded as 'username:password'");
227
+ throw new Error();
228
+ }
229
+ return {
230
+ basicAuthHeader: `Basic ${encodedCredentials}`,
231
+ username: usernameAndPassword[0],
232
+ };
233
+ }
192
234
  export function clearCache() {
193
235
  cachedTokenVerifier = undefined;
194
- cachedBasicAuthHeaders = undefined;
236
+ cachedBasicAuthCredentials = undefined;
195
237
  }
196
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29nbml0by11c2VyLXBvb2wtb3ItYmFzaWMtYXV0aC1hdXRob3JpemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS1nYXRld2F5L2F1dGhvcml6ZXItbGFtYmRhcy9jb2duaXRvLXVzZXItcG9vbC1vci1iYXNpYy1hdXRoLWF1dGhvcml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQU1ILE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQTtBQUNoRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQTBCbkQsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFDMUIsS0FBeUMsRUFDZCxFQUFFO0lBQzdCLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFBO0lBQy9DLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixPQUFPLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxDQUFBO0lBQ2hDLENBQUM7SUFFRCxNQUFNLHdCQUF3QixHQUFHLE1BQU0sMkJBQTJCLEVBQUUsQ0FBQTtJQUVwRSxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUNyQyxNQUFNLE1BQU0sR0FBRyxNQUFNLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQSxDQUFDLGtDQUFrQztRQUNsRyxRQUFRLE1BQU0sRUFBRSxDQUFDO1lBQ2YsS0FBSyxTQUFTO2dCQUNaLE9BQU8sRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLENBQUE7WUFDaEMsS0FBSyxTQUFTO2dCQUNaLHdGQUF3RjtnQkFDeEYscUZBQXFGO2dCQUNyRix5RkFBeUY7Z0JBQ3pGLHFFQUFxRTtnQkFDckUsTUFBTSxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQTtZQUNqQztn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SUFFZCxPQUFPLENBQ0wsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN6QixLQUFLLEtBQUssSUFBSTtRQUNkLGFBQWEsSUFBSSxLQUFLO1FBQ3RCLE9BQU8sS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLENBQ3RDLENBQUE7QUFDSCxDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsS0FBYztJQUNuQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzFCLE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELEtBQUssTUFBTSxPQUFPLElBQUksS0FBSyxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNoQyxPQUFPLEtBQUssQ0FBQTtRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVU7SUFDeEIsbUJBQW1CLEdBQUcsU0FBUyxDQUFBO0lBQy9CLHNCQUFzQixHQUFHLFNBQVMsQ0FBQTtBQUNwQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGlzIGxhbWJkYSB2ZXJpZmllcyBjcmVkZW50aWFsczpcbiAqIC0gQWdhaW5zdCBDb2duaXRvIHVzZXIgcG9vbCBpZiByZXF1ZXN0IHVzZXMgQmVhcmVyIHRva2VuXG4gKiAtIEFnYWluc3QgY3JlZGVudGlhbHMgc2F2ZWQgaW4gU2VjcmV0IE1hbmFnZXIgaWYgcmVxdWVzdCB1c2VzIGJhc2ljIGF1dGggKGFuZCBpZiBzZWNyZXQgZXhpc3RzKVxuICpcbiAqIEV4cGVjdHMgdGhlIGZvbGxvd2luZyBlbnZpcm9ubWVudCB2YXJpYWJsZXNcbiAqIC0gVVNFUl9QT09MX0lEXG4gKiAtIEJBU0lDX0FVVEhfQ1JFREVOVElBTFNfU0VDUkVUX05BTUUgKG9wdGlvbmFsKVxuICogICAtIFNlY3JldCB2YWx1ZSBzaG91bGQgZm9sbG93IHRoaXMgZm9ybWF0OiBge1widXNlcm5hbWVcIjpcIjx1c2VybmFtZT5cIixcInBhc3N3b3JkXCI6XCI8cGFzc3dvcmQ+XCJ9YC5cbiAqICAgICBBIGRpZmZlcmVudCBmb3JtYXQgd2l0aCBhbiBhcnJheSBvZiBwcmUtZW5jb2RlZCBjcmVkZW50aWFscyBpcyBhbHNvIHN1cHBvcnRlZCAtIHNlZSBkb2NzIGZvclxuICogICAgIHRoZSBgQ29nbml0b1VzZXJQb29sT3JCYXNpY0F1dGhBdXRob3JpemVyUHJvcHNgIG9uIHRoZSBgQXBpR2F0ZXdheWAgY29uc3RydWN0LlxuICogLSBSRVFVSVJFRF9TQ09QRSAob3B0aW9uYWwpXG4gKiAgIC0gU2V0IHRoaXMgdG8gcmVxdWlyZSB0aGF0IHRoZSBiZWFyZXIgdG9rZW4gcGF5bG9hZCBjb250YWlucyB0aGUgZ2l2ZW4gc2NvcGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIEFQSUdhdGV3YXlSZXF1ZXN0QXV0aG9yaXplckV2ZW50VjIsXG4gIEFQSUdhdGV3YXlTaW1wbGVBdXRob3JpemVyUmVzdWx0LFxufSBmcm9tIFwiYXdzLWxhbWJkYVwiXG5pbXBvcnQgeyBTZWNyZXRzTWFuYWdlciB9IGZyb20gXCJAYXdzLXNkay9jbGllbnQtc2VjcmV0cy1tYW5hZ2VyXCJcbmltcG9ydCB7IENvZ25pdG9Kd3RWZXJpZmllciB9IGZyb20gXCJhd3Mtand0LXZlcmlmeVwiXG5pbXBvcnQgdHlwZSB7IENvZ25pdG9BY2Nlc3NUb2tlblBheWxvYWQgfSBmcm9tIFwiYXdzLWp3dC12ZXJpZnkvand0LW1vZGVsXCJcblxudHlwZSBBdXRob3JpemVyUmVzdWx0ID0gQVBJR2F0ZXdheVNpbXBsZUF1dGhvcml6ZXJSZXN1bHQgJiB7XG4gIC8qKlxuICAgKiBSZXR1cm5pbmcgYSBjb250ZXh0IG9iamVjdCBmcm9tIG91ciBhdXRob3JpemVyIGFsbG93cyBvdXIgQVBJIEdhdGV3YXkgdG8gYWNjZXNzIHRoZXNlIHZhcmlhYmxlc1xuICAgKiB2aWEgYCR7Y29udGV4dC5hdXRob3JpemVyLjxwcm9wZXJ0eT59YC5cbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwaWdhdGV3YXkvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2h0dHAtYXBpLWxvZ2dpbmctdmFyaWFibGVzLmh0bWxcbiAgICovXG4gIGNvbnRleHQ/OiB7XG4gICAgLyoqXG4gICAgICogSWYgdGhlIHRva2VuIGlzIHZlcmlmaWVkLCB3ZSByZXR1cm4gdGhlIGF1dGggY2xpZW50IElEIGZyb20gdGhlIHRva2VuJ3MgY2xhaW1zIGFzIGEgY29udGV4dFxuICAgICAqIHZhcmlhYmxlIChuYW1lZCBgYXV0aG9yaXplci5jbGllbnRJZGApLiBZb3UgY2FuIHRoZW4gdXNlIHRoaXMgZm9yIHBhcmFtZXRlciBtYXBwaW5nIG9uIHRoZVxuICAgICAqIEFQSSBHYXRld2F5IChzZWUgYEFsYkludGVncmF0aW9uUHJvcHMubWFwUGFyYW1ldGVyc2Agb24gdGhlIGBBcGlHYXRld2F5YCBjb25zdHJ1Y3QpLCBpZiBmb3JcbiAgICAgKiBleGFtcGxlIHlvdSB3YW50IHRvIGZvcndhcmQgdGhpcyB0byB0aGUgYmFja2VuZCBpbnRlZ3JhdGlvbi5cbiAgICAgKi9cbiAgICBjbGllbnRJZD86IHN0cmluZ1xuICAgIC8qKlxuICAgICAqIFNlZSBgQ29nbml0b1VzZXJQb29sQXV0aG9yaXplclByb3BzLmJhc2ljQXV0aEZvckludGVybmFsQXV0aG9yaXphdGlvbmAgaW4gdGhlIGBBcGlHYXRld2F5YFxuICAgICAqIGNvbnN0cnVjdCAod2UgcHJvdmlkZSB0aGUgc2FtZSBjb250ZXh0IHZhcmlhYmxlIGhlcmUgYXMgaW4gdGhlIENvZ25pdG8gVXNlciBQb29sIGF1dGhvcml6ZXIsXG4gICAgICogdXNpbmcgdGhlIGNyZWRlbnRpYWxzIGZyb20gQkFTSUNfQVVUSF9DUkVERU5USUFMU19TRUNSRVRfTkFNRSkuXG4gICAgICovXG4gICAgaW50ZXJuYWxBdXRob3JpemF0aW9uSGVhZGVyPzogc3RyaW5nXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGhhbmRsZXIgPSBhc3luYyAoXG4gIGV2ZW50OiBBUElHYXRld2F5UmVxdWVzdEF1dGhvcml6ZXJFdmVudFYyLFxuKTogUHJvbWlzZTxBdXRob3JpemVyUmVzdWx0PiA9PiB7XG4gIGNvbnN0IGF1dGhIZWFkZXIgPSBldmVudC5oZWFkZXJzPy5hdXRob3JpemF0aW9uXG4gIGlmICghYXV0aEhlYWRlcikge1xuICAgIHJldHVybiB7IGlzQXV0aG9yaXplZDogZmFsc2UgfVxuICB9XG5cbiAgY29uc3QgZXhwZWN0ZWRCYXNpY0F1dGhIZWFkZXJzID0gYXdhaXQgZ2V0RXhwZWN0ZWRCYXNpY0F1dGhIZWFkZXJzKClcblxuICBpZiAoYXV0aEhlYWRlci5zdGFydHNXaXRoKFwiQmVhcmVyIFwiKSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZlcmlmeUFjY2Vzc1Rva2VuKGF1dGhIZWFkZXIuc3Vic3RyaW5nKDcpKSAvLyBzdWJzdHJpbmcoNykgPT0gYWZ0ZXIgJ0JlYXJlciAnXG4gICAgc3dpdGNoIChyZXN1bHQpIHtcbiAgICAgIGNhc2UgXCJJTlZBTElEXCI6XG4gICAgICAgIHJldHVybiB7IGlzQXV0aG9yaXplZDogZmFsc2UgfVxuICAgICAgY2FzZSBcIkVYUElSRURcIjpcbiAgICAgICAgLy8gV2Ugd2FudCB0byByZXR1cm4gNDAxIFVuYXV0aG9yaXplZCBmb3IgZXhwaXJlZCB0b2tlbnMsIHNvIHRoZSBjbGllbnQga25vd3MgdG8gcmVmcmVzaFxuICAgICAgICAvLyB0aGVpciB0b2tlbiB3aGVuIHJlY2VpdmluZyB0aGlzIHN0YXR1cyBjb2RlLiBBUEkgR2F0ZXdheSBhdXRob3JpemVyIGxhbWJkYXMgcmV0dXJuXG4gICAgICAgIC8vIDQwMyBGb3JiaWRkZW4gZm9yIHtpc0F1dGhvcml6ZWQ6IGZhbHNlfSwgYnV0IHRoZXJlIGlzIGEgd2F5IHRvIHJldHVybiA0MDE6IHRocm93aW5nIGFuXG4gICAgICAgIC8vIGVycm9yIHdpdGggdGhpcyBleGFjdCBzdHJpbmcuIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS83MTk2NTg5MFxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmF1dGhvcml6ZWRcIilcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaXNBdXRob3JpemVkOiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgIGNsaWVudElkOiByZXN1bHQuY2xpZW50X2lkLFxuICAgICAgICAgICAgaW50ZXJuYWxBdXRob3JpemF0aW9uSGVhZGVyOiBleHBlY3RlZEJhc2ljQXV0aEhlYWRlcnM/LlswXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKFxuICAgIGF1dGhIZWFkZXIuc3RhcnRzV2l0aChcIkJhc2ljIFwiKSAmJlxuICAgIGV4cGVjdGVkQmFzaWNBdXRoSGVhZGVycyAhPT0gdW5kZWZpbmVkXG4gICkge1xuICAgIGZvciAoY29uc3QgZXhwZWN0ZWRIZWFkZXIgb2YgZXhwZWN0ZWRCYXNpY0F1dGhIZWFkZXJzKSB7XG4gICAgICBpZiAoYXV0aEhlYWRlciA9PT0gZXhwZWN0ZWRIZWFkZXIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpc0F1dGhvcml6ZWQ6IHRydWUsXG4gICAgICAgICAgY29udGV4dDoge1xuICAgICAgICAgICAgaW50ZXJuYWxBdXRob3JpemF0aW9uSGVhZGVyOiBleHBlY3RlZEhlYWRlcixcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGlzQXV0aG9yaXplZDogZmFsc2UgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiB7IGlzQXV0aG9yaXplZDogZmFsc2UgfVxuICB9XG59XG5cbi8qKiBEZWNvZGVzIGFuZCB2ZXJpZmllcyB0aGUgZ2l2ZW4gdG9rZW4gYWdhaW5zdCBDb2duaXRvLiAqL1xuYXN5bmMgZnVuY3Rpb24gdmVyaWZ5QWNjZXNzVG9rZW4oXG4gIHRva2VuOiBzdHJpbmcsXG4pOiBQcm9taXNlPENvZ25pdG9BY2Nlc3NUb2tlblBheWxvYWQgfCBcIkVYUElSRURcIiB8IFwiSU5WQUxJRFwiPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgdG9rZW5WZXJpZmllciA9IGdldFRva2VuVmVyaWZpZXIoKVxuICAgIC8vIE11c3QgYXdhaXQgaGVyZSBpbnN0ZWFkIG9mIHJldHVybmluZyB0aGUgcHJvbWlzZSBkaXJlY3RseSwgc28gdGhhdCBlcnJvcnMgY2FuIGJlIGNhdWdodCBpblxuICAgIC8vIHRoaXMgZnVuY3Rpb25cbiAgICByZXR1cm4gYXdhaXQgdG9rZW5WZXJpZmllci52ZXJpZnkodG9rZW4pXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBJZiB0aGUgSldUIGhhcyBleHBpcmVkLCBhd3Mtand0LXZlcmlmeSB0aHJvd3MgdGhpcyBlcnJvcjpcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYXdzbGFicy9hd3Mtand0LXZlcmlmeS9ibG9iLzhkOGY3MTRkNzI4MTkxM2VjZDY2MDE0N2Y1YzMwMzExNDc5NjAxYzEvc3JjL2p3dC50cyNMMTk3XG4gICAgLy8gV2UgY2FuJ3QgY2hlY2sgaW5zdGFuY2VvZiBvbiB0aGF0IGVycm9yIGNsYXNzLCBzaW5jZSBpdCdzIG5vdCBleHBvcnRlZCwgc28gdGhpcyBpcyB0aGUgbmV4dFxuICAgIC8vIGJlc3QgdGhpbmcuXG4gICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciAmJiBlLm1lc3NhZ2U/LmluY2x1ZGVzKFwiVG9rZW4gZXhwaXJlZFwiKSkge1xuICAgICAgcmV0dXJuIFwiRVhQSVJFRFwiXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBcIklOVkFMSURcIlxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgdHlwZSBUb2tlblZlcmlmaWVyID0ge1xuICB2ZXJpZnk6IChhY2Nlc3NUb2tlbjogc3RyaW5nKSA9PiBQcm9taXNlPENvZ25pdG9BY2Nlc3NUb2tlblBheWxvYWQ+XG59XG5cbi8qKlxuICogV2UgY2FjaGUgdGhlIHZlcmlmaWVyIGluIHRoaXMgZ2xvYmFsIHZhcmlhYmxlLCBzbyB0aGF0IHN1YnNlcXVlbnQgaW52b2NhdGlvbnMgb2YgYSBob3QgbGFtYmRhXG4gKiB3aWxsIHJlLXVzZSB0aGlzLlxuICovXG5sZXQgY2FjaGVkVG9rZW5WZXJpZmllcjogVG9rZW5WZXJpZmllciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZFxuXG5mdW5jdGlvbiBnZXRUb2tlblZlcmlmaWVyKCk6IFRva2VuVmVyaWZpZXIge1xuICBpZiAoY2FjaGVkVG9rZW5WZXJpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY2FjaGVkVG9rZW5WZXJpZmllciA9IGRlcGVuZGVuY2llcy5jcmVhdGVUb2tlblZlcmlmaWVyKClcbiAgfVxuICByZXR1cm4gY2FjaGVkVG9rZW5WZXJpZmllclxufVxuXG4vKiogRm9yIG92ZXJyaWRpbmcgZGVwZW5kZW5jeSBjcmVhdGlvbiBpbiB0ZXN0cy4gKi9cbmV4cG9ydCBjb25zdCBkZXBlbmRlbmNpZXMgPSB7XG4gIGNyZWF0ZVRva2VuVmVyaWZpZXI6ICgpOiBUb2tlblZlcmlmaWVyID0+IHtcbiAgICBjb25zdCB1c2VyUG9vbElkID0gcHJvY2Vzcy5lbnZbXCJVU0VSX1BPT0xfSURcIl1cbiAgICBpZiAoIXVzZXJQb29sSWQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJVU0VSX1BPT0xfSUQgZW52IHZhcmlhYmxlIGlzIG5vdCBkZWZpbmVkXCIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKVxuICAgIH1cblxuICAgIHJldHVybiBDb2duaXRvSnd0VmVyaWZpZXIuY3JlYXRlKHtcbiAgICAgIHVzZXJQb29sSWQsXG4gICAgICB0b2tlblVzZTogXCJhY2Nlc3NcIixcbiAgICAgIGNsaWVudElkOiBudWxsLFxuICAgICAgc2NvcGU6IHByb2Nlc3MuZW52LlJFUVVJUkVEX1NDT1BFIHx8IHVuZGVmaW5lZCwgLy8gYHx8IHVuZGVmaW5lZGAgdG8gZGlzY2FyZCBlbXB0eSBzdHJpbmdcbiAgICB9KVxuICB9LFxuICBjcmVhdGVTZWNyZXRzTWFuYWdlcjogKCkgPT4gbmV3IFNlY3JldHNNYW5hZ2VyKCksXG59XG5cbi8qKiBDYWNoZSB0aGlzIHZhbHVlLCBzbyB0aGF0IHN1YnNlcXVlbnQgbGFtYmRhIGludm9jYXRpb25zIGRvbid0IGhhdmUgdG8gcmVmZXRjaC4gKi9cbmxldCBjYWNoZWRCYXNpY0F1dGhIZWFkZXJzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZFxuXG4vKipcbiAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsb3dlZCBiYXNpYyBhdXRoIGhlYWRlcnMsIHRvIHN1cHBvcnQgY3JlZGVudGlhbCBzZWNyZXRzIHdpdGggbXVsdGlwbGVcbiAqIHZhbHVlcyAoc2VlIGBCYXNpY0F1dGhBdXRob3JpemVyUHJvcHNgIG9uIHRoZSBgQXBpR2F0ZXdheWAgY29uc3RydWN0IGZvciBtb3JlIG9uIHRoaXMpLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRFeHBlY3RlZEJhc2ljQXV0aEhlYWRlcnMoKTogUHJvbWlzZTxzdHJpbmdbXSB8IHVuZGVmaW5lZD4ge1xuICBpZiAoY2FjaGVkQmFzaWNBdXRoSGVhZGVycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3Qgc2VjcmV0TmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkID1cbiAgICAgIHByb2Nlc3MuZW52W1wiQkFTSUNfQVVUSF9DUkVERU5USUFMU19TRUNSRVRfTkFNRVwiXVxuICAgIGlmICghc2VjcmV0TmFtZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGNhY2hlZEJhc2ljQXV0aEhlYWRlcnMgPSBhd2FpdCBnZXRTZWNyZXRBc0Jhc2ljQXV0aEhlYWRlcnMoc2VjcmV0TmFtZSlcbiAgfVxuXG4gIHJldHVybiBjYWNoZWRCYXNpY0F1dGhIZWFkZXJzXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFNlY3JldEFzQmFzaWNBdXRoSGVhZGVycyhcbiAgc2VjcmV0TmFtZTogc3RyaW5nLFxuKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICBjb25zdCBzZWNyZXQgPSBhd2FpdCBnZXRTZWNyZXRWYWx1ZShzZWNyZXROYW1lKVxuXG4gIGlmIChpc1NpbmdsZVVzZXJuYW1lQW5kUGFzc3dvcmQoc2VjcmV0KSkge1xuICAgIGNvbnN0IGhlYWRlciA9XG4gICAgICBcIkJhc2ljIFwiICtcbiAgICAgIEJ1ZmZlci5mcm9tKGAke3NlY3JldC51c2VybmFtZX06JHtzZWNyZXQucGFzc3dvcmR9YCkudG9TdHJpbmcoXCJiYXNlNjRcIilcbiAgICByZXR1cm4gW2hlYWRlcl1cbiAgfVxuXG4gIC8vIFNlZSBgQmFzaWNBdXRoQXV0aG9yaXplclByb3BzYCBvbiB0aGUgYEFwaUdhdGV3YXlgIGNvbnN0cnVjdCBmb3IgYW4gZXhwbGFuYXRpb24gb2YgdGhlIGZvcm1hdHNcbiAgLy8gd2UgcGFyc2UgaGVyZVxuICBpZiAoaGFzQ3JlZGVudGlhbHNLZXlXaXRoU3RyaW5nVmFsdWUoc2VjcmV0KSkge1xuICAgIGxldCBjcmVkZW50aWFsc0FycmF5OiB1bmtub3duXG4gICAgdHJ5IHtcbiAgICAgIGNyZWRlbnRpYWxzQXJyYXkgPSBKU09OLnBhcnNlKHNlY3JldC5jcmVkZW50aWFscylcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIHBhcnNlIGNyZWRlbnRpYWxzIGFycmF5IGluIHNlY3JldCAnJHtzZWNyZXROYW1lfScgYXMgSlNPTmAsXG4gICAgICAgIGUsXG4gICAgICApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKVxuICAgIH1cblxuICAgIGlmIChpc1N0cmluZ0FycmF5KGNyZWRlbnRpYWxzQXJyYXkpKSB7XG4gICAgICByZXR1cm4gY3JlZGVudGlhbHNBcnJheS5tYXAoXG4gICAgICAgIChlbmNvZGVkQ3JlZGVudGlhbCkgPT4gYEJhc2ljICR7ZW5jb2RlZENyZWRlbnRpYWx9YCxcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBjb25zb2xlLmVycm9yKFxuICAgIGBCYXNpYyBhdXRoIGNyZWRlbnRpYWxzIHNlY3JldCBkaWQgbm90IGZvbGxvdyBhbnkgZXhwZWN0ZWQgZm9ybWF0IChzZWNyZXQgbmFtZTogJyR7c2VjcmV0TmFtZX0nKWAsXG4gIClcbiAgdGhyb3cgbmV3IEVycm9yKClcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0U2VjcmV0VmFsdWUoc2VjcmV0TmFtZTogc3RyaW5nKTogUHJvbWlzZTx1bmtub3duPiB7XG4gIGNvbnN0IGNsaWVudCA9IGRlcGVuZGVuY2llcy5jcmVhdGVTZWNyZXRzTWFuYWdlcigpXG4gIGNvbnN0IHNlY3JldCA9IGF3YWl0IGNsaWVudC5nZXRTZWNyZXRWYWx1ZSh7IFNlY3JldElkOiBzZWNyZXROYW1lIH0pXG5cbiAgaWYgKCFzZWNyZXQuU2VjcmV0U3RyaW5nKSB7XG4gICAgY29uc29sZS5lcnJvcihgU2VjcmV0IHZhbHVlIG5vdCBmb3VuZCBmb3IgJyR7c2VjcmV0TmFtZX0nYClcbiAgICB0aHJvdyBuZXcgRXJyb3IoKVxuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShzZWNyZXQuU2VjcmV0U3RyaW5nKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHBhcnNlIHNlY3JldCAnJHtzZWNyZXROYW1lfScgYXMgSlNPTmAsIGUpXG4gICAgdGhyb3cgbmV3IEVycm9yKClcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1NpbmdsZVVzZXJuYW1lQW5kUGFzc3dvcmQoXG4gIHZhbHVlOiB1bmtub3duLFxuKTogdmFsdWUgaXMgeyB1c2VybmFtZTogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH0ge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgIHZhbHVlICE9PSBudWxsICYmXG4gICAgXCJ1c2VybmFtZVwiIGluIHZhbHVlICYmXG4gICAgdHlwZW9mIHZhbHVlLnVzZXJuYW1lID09PSBcInN0cmluZ1wiICYmXG4gICAgXCJwYXNzd29yZFwiIGluIHZhbHVlICYmXG4gICAgdHlwZW9mIHZhbHVlLnBhc3N3b3JkID09PSBcInN0cmluZ1wiXG4gIClcbn1cblxuZnVuY3Rpb24gaGFzQ3JlZGVudGlhbHNLZXlXaXRoU3RyaW5nVmFsdWUoXG4gIHZhbHVlOiB1bmtub3duLFxuKTogdmFsdWUgaXMgeyBjcmVkZW50aWFsczogc3RyaW5nIH0ge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgIHZhbHVlICE9PSBudWxsICYmXG4gICAgXCJjcmVkZW50aWFsc1wiIGluIHZhbHVlICYmXG4gICAgdHlwZW9mIHZhbHVlLmNyZWRlbnRpYWxzID09PSBcInN0cmluZ1wiXG4gIClcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmdBcnJheSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIHN0cmluZ1tdIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgZm9yIChjb25zdCBlbGVtZW50IG9mIHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiBlbGVtZW50ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJDYWNoZSgpIHtcbiAgY2FjaGVkVG9rZW5WZXJpZmllciA9IHVuZGVmaW5lZFxuICBjYWNoZWRCYXNpY0F1dGhIZWFkZXJzID0gdW5kZWZpbmVkXG59XG4iXX0=
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29nbml0by11c2VyLXBvb2wtb3ItYmFzaWMtYXV0aC1hdXRob3JpemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS1nYXRld2F5L2F1dGhvcml6ZXItbGFtYmRhcy9jb2duaXRvLXVzZXItcG9vbC1vci1iYXNpYy1hdXRoLWF1dGhvcml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7OztHQVlHO0FBTUgsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFBO0FBQ2hFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBbUNuRCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUMxQixLQUF5QyxFQUNkLEVBQUU7SUFDN0IsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUE7SUFDL0MsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLE9BQU8sRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLENBQUE7SUFDaEMsQ0FBQztJQUVELE1BQU0sNEJBQTRCLEdBQUcsTUFBTSwrQkFBK0IsRUFBRSxDQUFBO0lBRTVFLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sTUFBTSxHQUFHLE1BQU0saUJBQWlCLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLENBQUMsa0NBQWtDO1FBQ2xHLFFBQVEsTUFBTSxFQUFFLENBQUM7WUFDZixLQUFLLFNBQVM7Z0JBQ1osT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsQ0FBQTtZQUNoQyxLQUFLLFNBQVM7Z0JBQ1osd0ZBQXdGO2dCQUN4RixxRkFBcUY7Z0JBQ3JGLHlGQUF5RjtnQkFDekYscUVBQXFFO2dCQUNyRSxNQUFNLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFBO1lBQ2pDO2dC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Q0FBQTtBQUNiLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsZ0NBQWdDLENBQ3ZDLGtCQUEwQjtJQUUxQixJQUFJLGtCQUEwQixDQUFBO0lBQzlCLElBQUksQ0FBQztRQUNILGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUE7SUFDM0UsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDWCxPQUFPLENBQUMsS0FBSyxDQUNYLCtEQUErRCxFQUMvRCxDQUFDLENBQ0YsQ0FBQTtRQUNELE1BQU0sSUFBSSxLQUFLLEVBQUUsQ0FBQTtJQUNuQixDQUFDO0lBRUQsTUFBTSxtQkFBbUIsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQzVELElBQUksbUJBQW1CLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3JDLE9BQU8sQ0FBQyxLQUFLLENBQ1gsMkVBQTJFLENBQzVFLENBQUE7UUFDRCxNQUFNLElBQUksS0FBSyxFQUFFLENBQUE7SUFDbkIsQ0FBQztJQUVELE9BQU87UUFDTCxlQUFlLEVBQUUsU0FBUyxrQkFBa0IsRUFBRTtRQUM5QyxRQUFRLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO0tBQ2pDLENBQUE7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVU7SUFDeEIsbUJBQW1CLEdBQUcsU0FBUyxDQUFBO0lBQy9CLDBCQUEwQixHQUFHLFNBQVMsQ0FBQTtBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGlzIGxhbWJkYSB2ZXJpZmllcyBjcmVkZW50aWFsczpcbiAqIC0gQWdhaW5zdCBDb2duaXRvIHVzZXIgcG9vbCBpZiByZXF1ZXN0IHVzZXMgYWNjZXNzIHRva2VuIGluIEJlYXJlciBhdXRob3JpemF0aW9uIGhlYWRlclxuICogLSBBZ2FpbnN0IGNyZWRlbnRpYWxzIHNhdmVkIGluIFNlY3JldCBNYW5hZ2VyIGlmIHJlcXVlc3QgdXNlcyBiYXNpYyBhdXRoIChhbmQgaWYgc2VjcmV0IGV4aXN0cylcbiAqXG4gKiBFeHBlY3RzIHRoZSBmb2xsb3dpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzOlxuICogLSBVU0VSX1BPT0xfSURcbiAqIC0gQkFTSUNfQVVUSF9DUkVERU5USUFMU19TRUNSRVRfTkFNRSAob3B0aW9uYWwpXG4gKiAgIC0gTmFtZSBvZiBzZWNyZXQgaW4gQVdTIFNlY3JldHMgTWFuYWdlciB0aGF0IHN0b3JlcyBiYXNpYyBhdXRoIGNyZWRlbnRpYWxzLiBTZWVcbiAqICAgICBgQmFzaWNBdXRoQXV0aG9yaXplclByb3BzYCBvbiB0aGUgYEFwaUdhdGV3YXlgIGNvbnN0cnVjdCBmb3IgdGhlIHN1cHBvcnRlZCBmb3JtYXRzLlxuICogLSBSRVFVSVJFRF9TQ09QRSAob3B0aW9uYWwpXG4gKiAgIC0gU2V0IHRoaXMgdG8gcmVxdWlyZSB0aGF0IHRoZSBhY2Nlc3MgdG9rZW4gcGF5bG9hZCBjb250YWlucyB0aGUgZ2l2ZW4gc2NvcGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIEFQSUdhdGV3YXlSZXF1ZXN0QXV0aG9yaXplckV2ZW50VjIsXG4gIEFQSUdhdGV3YXlTaW1wbGVBdXRob3JpemVyUmVzdWx0LFxufSBmcm9tIFwiYXdzLWxhbWJkYVwiXG5pbXBvcnQgeyBTZWNyZXRzTWFuYWdlciB9IGZyb20gXCJAYXdzLXNkay9jbGllbnQtc2VjcmV0cy1tYW5hZ2VyXCJcbmltcG9ydCB7IENvZ25pdG9Kd3RWZXJpZmllciB9IGZyb20gXCJhd3Mtand0LXZlcmlmeVwiXG5pbXBvcnQgdHlwZSB7IENvZ25pdG9BY2Nlc3NUb2tlblBheWxvYWQgfSBmcm9tIFwiYXdzLWp3dC12ZXJpZnkvand0LW1vZGVsXCJcblxudHlwZSBBdXRob3JpemVyUmVzdWx0ID0gQVBJR2F0ZXdheVNpbXBsZUF1dGhvcml6ZXJSZXN1bHQgJiB7XG4gIC8qKlxuICAgKiBSZXR1cm5pbmcgYSBjb250ZXh0IG9iamVjdCBmcm9tIG91ciBhdXRob3JpemVyIGFsbG93cyBvdXIgQVBJIEdhdGV3YXkgdG8gYWNjZXNzIHRoZXNlIHZhcmlhYmxlc1xuICAgKiB2aWEgYCR7Y29udGV4dC5hdXRob3JpemVyLjxwcm9wZXJ0eT59YC5cbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwaWdhdGV3YXkvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2h0dHAtYXBpLXBhcmFtZXRlci1tYXBwaW5nLmh0bWxcbiAgICovXG4gIGNvbnRleHQ/OiB7XG4gICAgLyoqXG4gICAgICogSWYgdGhlIHJlcXVlc3QgdXNlZCBhbiBhY2Nlc3MgdG9rZW4sIGFuZCB0aGUgdG9rZW4gd2FzIHZlcmlmaWVkLCB3ZSByZXR1cm4gdGhlIGF1dGggY2xpZW50IElEXG4gICAgICogZnJvbSB0aGUgdG9rZW4ncyBjbGFpbXMgaW4gdGhpcyBjb250ZXh0IHZhcmlhYmxlIChuYW1lZCBgYXV0aG9yaXplci5jbGllbnRJZGApLiBXZSB1c2UgdGhpc1xuICAgICAqIHRvIGluY2x1ZGUgdGhlIHJlcXVlc3RpbmcgY2xpZW50IGluIHRoZSBBUEkgR2F0ZXdheSBhY2Nlc3MgbG9ncyAoc2VlIGBkZWZhdWx0QWNjZXNzTG9nRm9ybWF0YFxuICAgICAqIGluIG91ciBgQXBpR2F0ZXdheWAgY29uc3RydWN0KS4gWW91IGNhbiBhbHNvIHVzZSB0aGlzIHdoZW4gbWFwcGluZyBwYXJhbWV0ZXJzIHRvIHRoZSBiYWNrZW5kXG4gICAgICogaW50ZWdyYXRpb24gKHNlZSBgQWxiSW50ZWdyYXRpb25Qcm9wcy5tYXBQYXJhbWV0ZXJzYCBvbiB0aGUgYEFwaUdhdGV3YXlgIGNvbnN0cnVjdCkuXG4gICAgICovXG4gICAgY2xpZW50SWQ/OiBzdHJpbmdcbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVxdWVzdCB1c2VkIEJhc2ljIEF1dGgsIGFuZCB0aGUgY3JlZGVudGlhbHMgd2VyZSB2ZXJpZmllZCwgd2UgcmV0dXJuIHRoZSB1c2VybmFtZVxuICAgICAqIHRoYXQgd2FzIHVzZWQgaW4gdGhpcyBjb250ZXh0IHZhcmlhYmxlIChuYW1lZCBgYXV0aG9yaXplci51c2VybmFtZWApLiBXZSB1c2UgdGhpcyB0byBpbmNsdWRlXG4gICAgICogdGhlIHJlcXVlc3RpbmcgdXNlciBpbiB0aGUgQVBJIEdhdGV3YXkgYWNjZXNzIGxvZ3MgKHNlZSBgZGVmYXVsdEFjY2Vzc0xvZ0Zvcm1hdGAgaW4gb3VyXG4gICAgICogYEFwaUdhdGV3YXlgIGNvbnN0cnVjdCkuIFlvdSBjYW4gYWxzbyB1c2UgdGhpcyB3aGVuIG1hcHBpbmcgcGFyYW1ldGVycyB0byB0aGUgYmFja2VuZFxuICAgICAqIGludGVncmF0aW9uIChzZWUgYEFsYkludGVncmF0aW9uUHJvcHMubWFwUGFyYW1ldGVyc2Agb24gdGhlIGBBcGlHYXRld2F5YCBjb25zdHJ1Y3QpLlxuICAgICAqL1xuICAgIHVzZXJuYW1lPzogc3RyaW5nXG4gICAgLyoqXG4gICAgICogU2VlIGBDb2duaXRvVXNlclBvb2xBdXRob3JpemVyUHJvcHMuYmFzaWNBdXRoRm9ySW50ZXJuYWxBdXRob3JpemF0aW9uYCBvbiB0aGUgYEFwaUdhdGV3YXlgXG4gICAgICogY29uc3RydWN0ICh3ZSBwcm92aWRlIHRoZSBzYW1lIGNvbnRleHQgdmFyaWFibGUgaGVyZSBhcyBpbiB0aGUgQ29nbml0byBVc2VyIFBvb2wgYXV0aG9yaXplcixcbiAgICAgKiB1c2luZyB0aGUgY3JlZGVudGlhbHMgZnJvbSBCQVNJQ19BVVRIX0NSRURFTlRJQUxTX1NFQ1JFVF9OQU1FKS5cbiAgICAgKi9cbiAgICBpbnRlcm5hbEF1dGhvcml6YXRpb25IZWFkZXI/OiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaGFuZGxlciA9IGFzeW5jIChcbiAgZXZlbnQ6IEFQSUdhdGV3YXlSZXF1ZXN0QXV0aG9yaXplckV2ZW50VjIsXG4pOiBQcm9taXNlPEF1dGhvcml6ZXJSZXN1bHQ+ID0+IHtcbiAgY29uc3QgYXV0aEhlYWRlciA9IGV2ZW50LmhlYWRlcnM/LmF1dGhvcml6YXRpb25cbiAgaWYgKCFhdXRoSGVhZGVyKSB7XG4gICAgcmV0dXJuIHsgaXNBdXRob3JpemVkOiBmYWxzZSB9XG4gIH1cblxuICBjb25zdCBleHBlY3RlZEJhc2ljQXV0aENyZWRlbnRpYWxzID0gYXdhaXQgZ2V0RXhwZWN0ZWRCYXNpY0F1dGhDcmVkZW50aWFscygpXG5cbiAgaWYgKGF1dGhIZWFkZXIuc3RhcnRzV2l0aChcIkJlYXJlciBcIikpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlBY2Nlc3NUb2tlbihhdXRoSGVhZGVyLnN1YnN0cmluZyg3KSkgLy8gc3Vic3RyaW5nKDcpID09IGFmdGVyICdCZWFyZXIgJ1xuICAgIHN3aXRjaCAocmVzdWx0KSB7XG4gICAgICBjYXNlIFwiSU5WQUxJRFwiOlxuICAgICAgICByZXR1cm4geyBpc0F1dGhvcml6ZWQ6IGZhbHNlIH1cbiAgICAgIGNhc2UgXCJFWFBJUkVEXCI6XG4gICAgICAgIC8vIFdlIHdhbnQgdG8gcmV0dXJuIDQwMSBVbmF1dGhvcml6ZWQgZm9yIGV4cGlyZWQgdG9rZW5zLCBzbyB0aGUgY2xpZW50IGtub3dzIHRvIHJlZnJlc2hcbiAgICAgICAgLy8gdGhlaXIgdG9rZW4gd2hlbiByZWNlaXZpbmcgdGhpcyBzdGF0dXMgY29kZS4gQVBJIEdhdGV3YXkgYXV0aG9yaXplciBsYW1iZGFzIHJldHVyblxuICAgICAgICAvLyA0MDMgRm9yYmlkZGVuIGZvciB7aXNBdXRob3JpemVkOiBmYWxzZX0sIGJ1dCB0aGVyZSBpcyBhIHdheSB0byByZXR1cm4gNDAxOiB0aHJvd2luZyBhblxuICAgICAgICAvLyBlcnJvciB3aXRoIHRoaXMgZXhhY3Qgc3RyaW5nLiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNzE5NjU4OTBcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5hdXRob3JpemVkXCIpXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGlzQXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICBjbGllbnRJZDogcmVzdWx0LmNsaWVudF9pZCxcbiAgICAgICAgICAgIGludGVybmFsQXV0aG9yaXphdGlvbkhlYWRlcjpcbiAgICAgICAgICAgICAgZXhwZWN0ZWRCYXNpY0F1dGhDcmVkZW50aWFscz8uWzBdPy5iYXNpY0F1dGhIZWFkZXIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChcbiAgICBhdXRoSGVhZGVyLnN0YXJ0c1dpdGgoXCJCYXNpYyBcIikgJiZcbiAgICBleHBlY3RlZEJhc2ljQXV0aENyZWRlbnRpYWxzICE9PSB1bmRlZmluZWRcbiAgKSB7XG4gICAgZm9yIChjb25zdCBleHBlY3RlZCBvZiBleHBlY3RlZEJhc2ljQXV0aENyZWRlbnRpYWxzKSB7XG4gICAgICBpZiAoYXV0aEhlYWRlciA9PT0gZXhwZWN0ZWQuYmFzaWNBdXRoSGVhZGVyKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaXNBdXRob3JpemVkOiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgIHVzZXJuYW1lOiBleHBlY3RlZC51c2VybmFtZSxcbiAgICAgICAgICAgIGludGVybmFsQXV0aG9yaXphdGlvbkhlYWRlcjogZXhwZWN0ZWQuYmFzaWNBdXRoSGVhZGVyLFxuICAgICAgICAgIH0sXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgaXNBdXRob3JpemVkOiBmYWxzZSB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHsgaXNBdXRob3JpemVkOiBmYWxzZSB9XG4gIH1cbn1cblxuLyoqIERlY29kZXMgYW5kIHZlcmlmaWVzIHRoZSBnaXZlbiB0b2tlbiBhZ2FpbnN0IENvZ25pdG8uICovXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlBY2Nlc3NUb2tlbihcbiAgdG9rZW46IHN0cmluZyxcbik6IFByb21pc2U8Q29nbml0b0FjY2Vzc1Rva2VuUGF5bG9hZCB8IFwiRVhQSVJFRFwiIHwgXCJJTlZBTElEXCI+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB0b2tlblZlcmlmaWVyID0gZ2V0VG9rZW5WZXJpZmllcigpXG4gICAgLy8gTXVzdCBhd2FpdCBoZXJlIGluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSBwcm9taXNlIGRpcmVjdGx5LCBzbyB0aGF0IGVycm9ycyBjYW4gYmUgY2F1Z2h0IGluXG4gICAgLy8gdGhpcyBmdW5jdGlvblxuICAgIHJldHVybiBhd2FpdCB0b2tlblZlcmlmaWVyLnZlcmlmeSh0b2tlbilcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIElmIHRoZSBKV1QgaGFzIGV4cGlyZWQsIGF3cy1qd3QtdmVyaWZ5IHRocm93cyB0aGlzIGVycm9yOlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3NsYWJzL2F3cy1qd3QtdmVyaWZ5L2Jsb2IvOGQ4ZjcxNGQ3MjgxOTEzZWNkNjYwMTQ3ZjVjMzAzMTE0Nzk2MDFjMS9zcmMvand0LnRzI0wxOTdcbiAgICAvLyBXZSBjYW4ndCBjaGVjayBpbnN0YW5jZW9mIG9uIHRoYXQgZXJyb3IgY2xhc3MsIHNpbmNlIGl0J3Mgbm90IGV4cG9ydGVkLCBzbyB0aGlzIGlzIHRoZSBuZXh0XG4gICAgLy8gYmVzdCB0aGluZy5cbiAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yICYmIGUubWVzc2FnZT8uaW5jbHVkZXMoXCJUb2tlbiBleHBpcmVkXCIpKSB7XG4gICAgICByZXR1cm4gXCJFWFBJUkVEXCJcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFwiSU5WQUxJRFwiXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB0eXBlIFRva2VuVmVyaWZpZXIgPSB7XG4gIHZlcmlmeTogKGFjY2Vzc1Rva2VuOiBzdHJpbmcpID0+IFByb21pc2U8Q29nbml0b0FjY2Vzc1Rva2VuUGF5bG9hZD5cbn1cblxuLyoqXG4gKiBXZSBjYWNoZSB0aGUgdmVyaWZpZXIgaW4gdGhpcyBnbG9iYWwgdmFyaWFibGUsIHNvIHRoYXQgc3Vic2VxdWVudCBpbnZvY2F0aW9ucyBvZiBhIGhvdCBsYW1iZGFcbiAqIHdpbGwgcmUtdXNlIHRoaXMuXG4gKi9cbmxldCBjYWNoZWRUb2tlblZlcmlmaWVyOiBUb2tlblZlcmlmaWVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG5cbmZ1bmN0aW9uIGdldFRva2VuVmVyaWZpZXIoKTogVG9rZW5WZXJpZmllciB7XG4gIGlmIChjYWNoZWRUb2tlblZlcmlmaWVyID09PSB1bmRlZmluZWQpIHtcbiAgICBjYWNoZWRUb2tlblZlcmlmaWVyID0gZGVwZW5kZW5jaWVzLmNyZWF0ZVRva2VuVmVyaWZpZXIoKVxuICB9XG4gIHJldHVybiBjYWNoZWRUb2tlblZlcmlmaWVyXG59XG5cbi8qKiBGb3Igb3ZlcnJpZGluZyBkZXBlbmRlbmN5IGNyZWF0aW9uIGluIHRlc3RzLiAqL1xuZXhwb3J0IGNvbnN0IGRlcGVuZGVuY2llcyA9IHtcbiAgY3JlYXRlVG9rZW5WZXJpZmllcjogKCk6IFRva2VuVmVyaWZpZXIgPT4ge1xuICAgIGNvbnN0IHVzZXJQb29sSWQgPSBwcm9jZXNzLmVudltcIlVTRVJfUE9PTF9JRFwiXVxuICAgIGlmICghdXNlclBvb2xJZCkge1xuICAgICAgY29uc29sZS5lcnJvcihcIlVTRVJfUE9PTF9JRCBlbnYgdmFyaWFibGUgaXMgbm90IGRlZmluZWRcIilcbiAgICAgIHRocm93IG5ldyBFcnJvcigpXG4gICAgfVxuXG4gICAgcmV0dXJuIENvZ25pdG9Kd3RWZXJpZmllci5jcmVhdGUoe1xuICAgICAgdXNlclBvb2xJZCxcbiAgICAgIHRva2VuVXNlOiBcImFjY2Vzc1wiLFxuICAgICAgY2xpZW50SWQ6IG51bGwsXG4gICAgICBzY29wZTogcHJvY2Vzcy5lbnYuUkVRVUlSRURfU0NPUEUgfHwgdW5kZWZpbmVkLCAvLyBgfHwgdW5kZWZpbmVkYCB0byBkaXNjYXJkIGVtcHR5IHN0cmluZ1xuICAgIH0pXG4gIH0sXG4gIGNyZWF0ZVNlY3JldHNNYW5hZ2VyOiAoKSA9PiBuZXcgU2VjcmV0c01hbmFnZXIoKSxcbn1cblxudHlwZSBFeHBlY3RlZEJhc2ljQXV0aENyZWRlbnRpYWxzID0ge1xuICBiYXNpY0F1dGhIZWFkZXI6IHN0cmluZ1xuICB1c2VybmFtZTogc3RyaW5nXG59XG5cbi8qKiBDYWNoZSB0aGlzIHZhbHVlLCBzbyB0aGF0IHN1YnNlcXVlbnQgbGFtYmRhIGludm9jYXRpb25zIGRvbid0IGhhdmUgdG8gcmVmZXRjaC4gKi9cbmxldCBjYWNoZWRCYXNpY0F1dGhDcmVkZW50aWFsczogRXhwZWN0ZWRCYXNpY0F1dGhDcmVkZW50aWFsc1tdIHwgdW5kZWZpbmVkID1cbiAgdW5kZWZpbmVkXG5cbi8qKlxuICogUmV0dXJucyBhbiBhcnJheSwgdG8gc3VwcG9ydCBjcmVkZW50aWFsIHNlY3JldHMgd2l0aCBtdWx0aXBsZSB2YWx1ZXMgKHNlZVxuICogYEJhc2ljQXV0aEF1dGhvcml6ZXJQcm9wc2Agb24gdGhlIGBBcGlHYXRld2F5YCBjb25zdHJ1Y3QgZm9yIG1vcmUgb24gdGhpcykuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldEV4cGVjdGVkQmFzaWNBdXRoQ3JlZGVudGlhbHMoKTogUHJvbWlzZTxcbiAgRXhwZWN0ZWRCYXNpY0F1dGhDcmVkZW50aWFsc1tdIHwgdW5kZWZpbmVkXG4+IHtcbiAgaWYgKGNhY2hlZEJhc2ljQXV0aENyZWRlbnRpYWxzID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBzZWNyZXROYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQgPVxuICAgICAgcHJvY2Vzcy5lbnZbXCJCQVNJQ19BVVRIX0NSRURFTlRJQUxTX1NFQ1JFVF9OQU1FXCJdXG4gICAgaWYgKCFzZWNyZXROYW1lKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgY2FjaGVkQmFzaWNBdXRoQ3JlZGVudGlhbHMgPSBhd2FpdCBnZXRCYXNpY0F1dGhDcmVkZW50aWFsc1NlY3JldChzZWNyZXROYW1lKVxuICB9XG5cbiAgcmV0dXJuIGNhY2hlZEJhc2ljQXV0aENyZWRlbnRpYWxzXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEJhc2ljQXV0aENyZWRlbnRpYWxzU2VjcmV0KFxuICBzZWNyZXROYW1lOiBzdHJpbmcsXG4pOiBQcm9taXNlPEV4cGVjdGVkQmFzaWNBdXRoQ3JlZGVudGlhbHNbXT4ge1xuICBjb25zdCBzZWNyZXQgPSBhd2FpdCBnZXRTZWNyZXRWYWx1ZShzZWNyZXROYW1lKVxuXG4gIGlmIChpc1VzZXJuYW1lQW5kUGFzc3dvcmRPYmplY3Qoc2VjcmV0KSkge1xuICAgIHJldHVybiBbZW5jb2RlQmFzaWNBdXRoQ3JlZGVudGlhbHMoc2VjcmV0KV1cbiAgfVxuXG4gIC8vIFNlZSBgQmFzaWNBdXRoQXV0aG9yaXplclByb3BzYCBvbiB0aGUgYEFwaUdhdGV3YXlgIGNvbnN0cnVjdCBmb3IgYW4gZXhwbGFuYXRpb24gb2YgdGhlIGZvcm1hdHNcbiAgLy8gd2UgcGFyc2UgaGVyZVxuICBpZiAoaGFzQ3JlZGVudGlhbHNLZXlXaXRoU3RyaW5nVmFsdWUoc2VjcmV0KSkge1xuICAgIGxldCBjcmVkZW50aWFsc0FycmF5OiB1bmtub3duXG4gICAgdHJ5IHtcbiAgICAgIGNyZWRlbnRpYWxzQXJyYXkgPSBKU09OLnBhcnNlKHNlY3JldC5jcmVkZW50aWFscylcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIHBhcnNlIGNyZWRlbnRpYWxzIGFycmF5IGluIHNlY3JldCAnJHtzZWNyZXROYW1lfScgYXMgSlNPTmAsXG4gICAgICAgIGUsXG4gICAgICApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKVxuICAgIH1cblxuICAgIGlmIChpc0FycmF5T2ZVc2VybmFtZUFuZFBhc3N3b3JkT2JqZWN0cyhjcmVkZW50aWFsc0FycmF5KSkge1xuICAgICAgcmV0dXJuIGNyZWRlbnRpYWxzQXJyYXkubWFwKGVuY29kZUJhc2ljQXV0aENyZWRlbnRpYWxzKVxuICAgIH1cblxuICAgIGlmIChpc1N0cmluZ0FycmF5KGNyZWRlbnRpYWxzQXJyYXkpKSB7XG4gICAgICByZXR1cm4gY3JlZGVudGlhbHNBcnJheS5tYXAocGFyc2VFbmNvZGVkQmFzaWNBdXRoQ3JlZGVudGlhbHMpXG4gICAgfVxuICB9XG5cbiAgY29uc29sZS5lcnJvcihcbiAgICBgQmFzaWMgYXV0aCBjcmVkZW50aWFscyBzZWNyZXQgZGlkIG5vdCBmb2xsb3cgYW55IGV4cGVjdGVkIGZvcm1hdCAoc2VjcmV0IG5hbWU6ICcke3NlY3JldE5hbWV9JylgLFxuICApXG4gIHRocm93IG5ldyBFcnJvcigpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFNlY3JldFZhbHVlKHNlY3JldE5hbWU6IHN0cmluZyk6IFByb21pc2U8dW5rbm93bj4ge1xuICBjb25zdCBjbGllbnQgPSBkZXBlbmRlbmNpZXMuY3JlYXRlU2VjcmV0c01hbmFnZXIoKVxuICBjb25zdCBzZWNyZXQgPSBhd2FpdCBjbGllbnQuZ2V0U2VjcmV0VmFsdWUoeyBTZWNyZXRJZDogc2VjcmV0TmFtZSB9KVxuXG4gIGlmICghc2VjcmV0LlNlY3JldFN0cmluZykge1xuICAgIGNvbnNvbGUuZXJyb3IoYFNlY3JldCB2YWx1ZSBub3QgZm91bmQgZm9yICcke3NlY3JldE5hbWV9J2ApXG4gICAgdGhyb3cgbmV3IEVycm9yKClcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2Uoc2VjcmV0LlNlY3JldFN0cmluZylcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwYXJzZSBzZWNyZXQgJyR7c2VjcmV0TmFtZX0nIGFzIEpTT046YCwgZSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoKVxuICB9XG59XG5cbmZ1bmN0aW9uIGVuY29kZUJhc2ljQXV0aENyZWRlbnRpYWxzKGNyZWRlbnRpYWxzOiB7XG4gIHVzZXJuYW1lOiBzdHJpbmdcbiAgcGFzc3dvcmQ6IHN0cmluZ1xufSk6IEV4cGVjdGVkQmFzaWNBdXRoQ3JlZGVudGlhbHMge1xuICBjb25zdCBiYXNpY0F1dGhIZWFkZXIgPVxuICAgIFwiQmFzaWMgXCIgK1xuICAgIEJ1ZmZlci5mcm9tKGAke2NyZWRlbnRpYWxzLnVzZXJuYW1lfToke2NyZWRlbnRpYWxzLnBhc3N3b3JkfWApLnRvU3RyaW5nKFxuICAgICAgXCJiYXNlNjRcIixcbiAgICApXG5cbiAgcmV0dXJuIHsgYmFzaWNBdXRoSGVhZGVyLCB1c2VybmFtZTogY3JlZGVudGlhbHMudXNlcm5hbWUgfVxufVxuXG5mdW5jdGlvbiBpc1VzZXJuYW1lQW5kUGFzc3dvcmRPYmplY3QoXG4gIHZhbHVlOiB1bmtub3duLFxuKTogdmFsdWUgaXMgeyB1c2VybmFtZTogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH0ge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgIHZhbHVlICE9PSBudWxsICYmXG4gICAgXCJ1c2VybmFtZVwiIGluIHZhbHVlICYmXG4gICAgdHlwZW9mIHZhbHVlLnVzZXJuYW1lID09PSBcInN0cmluZ1wiICYmXG4gICAgXCJwYXNzd29yZFwiIGluIHZhbHVlICYmXG4gICAgdHlwZW9mIHZhbHVlLnBhc3N3b3JkID09PSBcInN0cmluZ1wiXG4gIClcbn1cblxuZnVuY3Rpb24gaXNBcnJheU9mVXNlcm5hbWVBbmRQYXNzd29yZE9iamVjdHMoXG4gIHZhbHVlOiB1bmtub3duLFxuKTogdmFsdWUgaXMgeyB1c2VybmFtZTogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH1bXSB7XG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiB2YWx1ZSkge1xuICAgIGlmICghaXNVc2VybmFtZUFuZFBhc3N3b3JkT2JqZWN0KGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBoYXNDcmVkZW50aWFsc0tleVdpdGhTdHJpbmdWYWx1ZShcbiAgdmFsdWU6IHVua25vd24sXG4pOiB2YWx1ZSBpcyB7IGNyZWRlbnRpYWxzOiBzdHJpbmcgfSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICBcImNyZWRlbnRpYWxzXCIgaW4gdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUuY3JlZGVudGlhbHMgPT09IFwic3RyaW5nXCJcbiAgKVxufVxuXG5mdW5jdGlvbiBpc1N0cmluZ0FycmF5KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgc3RyaW5nW10ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIGVsZW1lbnQgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogV2Ugd2FudCB0byByZXR1cm4gdGhlIHJlcXVlc3RpbmcgdXNlcm5hbWUgYXMgYSBjb250ZXh0IHZhcmlhYmxlIGluXG4gKiB7QGxpbmsgQXV0aG9yaXplclJlc3VsdC5jb250ZXh0fSwgZm9yIEFQSSBHYXRld2F5IGFjY2VzcyBsb2dzIGFuZCBwYXJhbWV0ZXIgbWFwcGluZy4gU28gaWYgdGhlXG4gKiBiYXNpYyBhdXRoIGNyZWRlbnRpYWxzIHNlY3JldCBpcyBzdG9yZWQgYXMgcHJlLWVuY29kZWQgYmFzZTY0IHN0cmluZ3MsIHdlIG5lZWQgdG8gcGFyc2UgdGhlbSB0b1xuICogZ2V0IHRoZSB1c2VybmFtZS5cbiAqL1xuZnVuY3Rpb24gcGFyc2VFbmNvZGVkQmFzaWNBdXRoQ3JlZGVudGlhbHMoXG4gIGVuY29kZWRDcmVkZW50aWFsczogc3RyaW5nLFxuKTogRXhwZWN0ZWRCYXNpY0F1dGhDcmVkZW50aWFscyB7XG4gIGxldCBkZWNvZGVkQ3JlZGVudGlhbHM6IHN0cmluZ1xuICB0cnkge1xuICAgIGRlY29kZWRDcmVkZW50aWFscyA9IEJ1ZmZlci5mcm9tKGVuY29kZWRDcmVkZW50aWFscywgXCJiYXNlNjRcIikudG9TdHJpbmcoKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgIFwiQmFzaWMgYXV0aCBjcmVkZW50aWFscyBzZWNyZXQgY291bGQgbm90IGJlIGRlY29kZWQgYXMgYmFzZTY0OlwiLFxuICAgICAgZSxcbiAgICApXG4gICAgdGhyb3cgbmV3IEVycm9yKClcbiAgfVxuXG4gIGNvbnN0IHVzZXJuYW1lQW5kUGFzc3dvcmQgPSBkZWNvZGVkQ3JlZGVudGlhbHMuc3BsaXQoXCI6XCIsIDIpXG4gIGlmICh1c2VybmFtZUFuZFBhc3N3b3JkLmxlbmd0aCAhPT0gMikge1xuICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICBcIkJhc2ljIGF1dGggY3JlZGVudGlhbHMgc2VjcmV0IGNvdWxkIG5vdCBiZSBkZWNvZGVkIGFzICd1c2VybmFtZTpwYXNzd29yZCdcIixcbiAgICApXG4gICAgdGhyb3cgbmV3IEVycm9yKClcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYmFzaWNBdXRoSGVhZGVyOiBgQmFzaWMgJHtlbmNvZGVkQ3JlZGVudGlhbHN9YCxcbiAgICB1c2VybmFtZTogdXNlcm5hbWVBbmRQYXNzd29yZFswXSxcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJDYWNoZSgpIHtcbiAgY2FjaGVkVG9rZW5WZXJpZmllciA9IHVuZGVmaW5lZFxuICBjYWNoZWRCYXNpY0F1dGhDcmVkZW50aWFscyA9IHVuZGVmaW5lZFxufVxuIl19
@@ -280,8 +280,8 @@ export type AuthorizationProps<AuthScopesT extends string = string> =
280
280
  type: "IAM";
281
281
  }
282
282
  /**
283
- * Creates a custom authorizer lambda which reads `Authorization: Bearer <token>` header and
284
- * verifies the token against a Cognito user pool.
283
+ * Creates a custom authorizer lambda which reads `Authorization: Bearer <access token>` header
284
+ * and verifies the token against a Cognito user pool.
285
285
  */
286
286
  | ({
287
287
  type: "COGNITO_USER_POOL";
@@ -295,8 +295,8 @@ export type AuthorizationProps<AuthScopesT extends string = string> =
295
295
  } & BasicAuthAuthorizerProps)
296
296
  /**
297
297
  * Creates a custom authorizer lambda which allows both:
298
- * - `Authorization: Bearer <token>` header, for which the token is checked against the given
299
- * Cognito user pool
298
+ * - `Authorization: Bearer <access token>` header, for which the token is checked against the
299
+ * given Cognito user pool
300
300
  * - `Authorization: Basic <base64-encoded credentials>` header, for which the credentials are
301
301
  * checked against the credentials from the given basic auth secret name
302
302
  *
@@ -308,7 +308,7 @@ export type AuthorizationProps<AuthScopesT extends string = string> =
308
308
  export type CognitoUserPoolAuthorizerProps<AuthScopesT extends string = string> = {
309
309
  userPool: IUserPool;
310
310
  /**
311
- * Verifies that token claims contain the given scope.
311
+ * Verifies that access token claims contain the given scope.
312
312
  *
313
313
  * When defined as part of a resource server, scopes are on the format:
314
314
  * `{resource server identifier}/{scope name}`, e.g. `external/view_users`.
@@ -349,59 +349,44 @@ export type CognitoUserPoolAuthorizerProps<AuthScopesT extends string = string>
349
349
  };
350
350
  export type BasicAuthAuthorizerProps = {
351
351
  /**
352
- * Name of secret in AWS Secrets Manager that stores basic auth credentials. The secret value
353
- * should follow this format:
354
- * ```json
355
- * { "username": "<username>", "password": "<password>" }
356
- * ```
357
- *
358
- * The following format is also supported:
359
- * ```json
360
- * { "credentials": "[\"<encoded-credential-1>\",\"<encoded-credential-2>\"]" }
361
- * ```
362
- * ...consisting of:
363
- * - A single key, `credentials`
364
- * - With a _string_ value
365
- * - Which is a stringified, escaped JSON array of base64-encoded credentials
366
- * - In which each element is encoded from `<username>:<password>`
367
- *
368
- * If the secret is on this format, the authorizer will match the request's Authorization header
369
- * against any one of these encoded credentials.
370
- *
371
- * The reason that this second format stores stringified JSON _inside_ JSON, is due to a
372
- * limitation in Liflig's `load-secrets` library, which only allows storing strings values.
352
+ * Name of secret in AWS Secrets Manager that stores basic auth credentials.
353
+ *
354
+ * The following formats are supported for the secret value:
355
+ * - Single username and password:
356
+ * ```json
357
+ * { "username": "<username>", "password": "<password>" }
358
+ * ```
359
+ * - Array of username + password objects:
360
+ * ```json
361
+ * { "credentials": "[{\"username\":\"<user-1>\",\"password\":\"password-1\"},{\"username\":\"<user-2>\",\"password\":\"<password-2>\"}]" }
362
+ * ```
363
+ * - The value of the `credentials` field is a string, with a stringified, escaped JSON array of
364
+ * objects with `username` and `password` fields.
365
+ * - The reason that this second format stores stringified JSON _inside_ JSON, is due to a
366
+ * limitation in Liflig's `load-secrets` library, which only allows storing string values.
367
+ * - Array of base64-encoded credentials:
368
+ * ```json
369
+ * { "credentials": "[\"<encoded-credential-1>\",\"<encoded-credential-2>\"]" }
370
+ * ```
371
+ * - Each element is encoded from `<username>:<password>`.
372
+ * - The array is stringified for the same reason as above.
373
+ *
374
+ * If the secret uses one of the array formats, the authorizer will match the request's
375
+ * Authorization header against any one of the credentials.
373
376
  */
374
377
  credentialsSecretName: string;
375
378
  };
376
379
  export type CognitoUserPoolOrBasicAuthAuthorizerProps<AuthScopesT extends string = string> = {
377
380
  userPool: IUserPool;
378
381
  /**
379
- * Name of secret in AWS Secrets Manager that stores basic auth credentials. The secret value
380
- * should follow this format:
381
- * ```json
382
- * { "username": "<username>", "password": "<password>" }
383
- * ```
384
- *
385
- * The following format is also supported:
386
- * ```json
387
- * { "credentials": "[\"<encoded-credential-1>\",\"<encoded-credential-2>\"]" }
388
- * ```
389
- * ...consisting of:
390
- * - A single key, `credentials`
391
- * - With a _string_ value
392
- * - Which is a stringified, escaped JSON array of base64-encoded credentials
393
- * - In which each element is encoded from `<username>:<password>`
394
- *
395
- * If the secret is on this format, the authorizer will match the request's Authorization header
396
- * against any one of these encoded credentials.
382
+ * Name of secret in AWS Secrets Manager that stores basic auth credentials.
397
383
  *
398
- * The reason that this second format stores stringified JSON _inside_ JSON, is due to a
399
- * limitation in Liflig's `load-secrets` library, which only allows storing strings values.
384
+ * See {@link BasicAuthAuthorizerProps.credentialsSecretName} for the supported formats.
400
385
  */
401
386
  basicAuthCredentialsSecretName?: string;
402
387
  /**
403
- * Verifies that token claims contain the given scope. Only applicable for `Bearer` token requests
404
- * checked against the Cognito User Pool (not applicable for basic auth).
388
+ * Verifies that access token claims contain the given scope. Only applicable for requests that
389
+ * use `Authorization: Bearer <access token>` (not applicable for basic auth).
405
390
  *
406
391
  * When defined as part of a resource server, scopes are on the format:
407
392
  * `{resource server identifier}/{scope name}`, e.g. `external/view_users`.