raindancers-cloudfront 0.0.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.
- package/LICENSE +202 -0
- package/README.md +176 -0
- package/lib/bicep/deploy/deploy.d.ts +46 -0
- package/lib/bicep/deploy/deploy.js +123 -0
- package/lib/bicep/deploy/index.d.ts +3 -0
- package/lib/bicep/deploy/index.js +20 -0
- package/lib/bicep/deploy/template.d.ts +75 -0
- package/lib/bicep/deploy/template.js +364 -0
- package/lib/bicep/deploy/templateBuilder.d.ts +16 -0
- package/lib/bicep/deploy/templateBuilder.js +35 -0
- package/lib/bicep/index.d.ts +3 -0
- package/lib/bicep/index.js +40 -0
- package/lib/bicep/patterns/azureAdApplicationFederated.d.ts +58 -0
- package/lib/bicep/patterns/azureAdApplicationFederated.js +317 -0
- package/lib/bicep/patterns/index.d.ts +1 -0
- package/lib/bicep/patterns/index.js +18 -0
- package/lib/bicep/resources/azure/appServicePlan.d.ts +11 -0
- package/lib/bicep/resources/azure/appServicePlan.js +24 -0
- package/lib/bicep/resources/azure/applicationInsights.d.ts +13 -0
- package/lib/bicep/resources/azure/applicationInsights.js +27 -0
- package/lib/bicep/resources/azure/deploymentScript.d.ts +16 -0
- package/lib/bicep/resources/azure/deploymentScript.js +43 -0
- package/lib/bicep/resources/azure/functionApp.d.ts +20 -0
- package/lib/bicep/resources/azure/functionApp.js +54 -0
- package/lib/bicep/resources/azure/index.d.ts +8 -0
- package/lib/bicep/resources/azure/index.js +25 -0
- package/lib/bicep/resources/azure/logAnalyticsWorkspace.d.ts +11 -0
- package/lib/bicep/resources/azure/logAnalyticsWorkspace.js +26 -0
- package/lib/bicep/resources/azure/managedIdentity.d.ts +13 -0
- package/lib/bicep/resources/azure/managedIdentity.js +24 -0
- package/lib/bicep/resources/azure/roleAssignment.d.ts +18 -0
- package/lib/bicep/resources/azure/roleAssignment.js +34 -0
- package/lib/bicep/resources/azure/storageAccount.d.ts +11 -0
- package/lib/bicep/resources/azure/storageAccount.js +28 -0
- package/lib/bicep/resources/graph/appRoleAssignment.d.ts +25 -0
- package/lib/bicep/resources/graph/appRoleAssignment.js +33 -0
- package/lib/bicep/resources/graph/application.d.ts +51 -0
- package/lib/bicep/resources/graph/application.js +88 -0
- package/lib/bicep/resources/graph/bicepConstruct.d.ts +14 -0
- package/lib/bicep/resources/graph/bicepConstruct.js +29 -0
- package/lib/bicep/resources/graph/existingServicePrincipal.d.ts +19 -0
- package/lib/bicep/resources/graph/existingServicePrincipal.js +26 -0
- package/lib/bicep/resources/graph/federatedIdentityCredential.d.ts +29 -0
- package/lib/bicep/resources/graph/federatedIdentityCredential.js +31 -0
- package/lib/bicep/resources/graph/group.d.ts +26 -0
- package/lib/bicep/resources/graph/group.js +31 -0
- package/lib/bicep/resources/graph/index.d.ts +8 -0
- package/lib/bicep/resources/graph/index.js +25 -0
- package/lib/bicep/resources/graph/servicePrincipal.d.ts +22 -0
- package/lib/bicep/resources/graph/servicePrincipal.js +27 -0
- package/lib/bicep/resources/graph/types/index.d.ts +1 -0
- package/lib/bicep/resources/graph/types/index.js +18 -0
- package/lib/bicep/resources/graph/types/permissions.d.ts +54 -0
- package/lib/bicep/resources/graph/types/permissions.js +73 -0
- package/lib/bicep/resources/index.d.ts +2 -0
- package/lib/bicep/resources/index.js +39 -0
- package/lib/cloudfront/auth/authLambdaFunctions.d.ts +20 -0
- package/lib/cloudfront/auth/authLambdaFunctions.js +159 -0
- package/lib/cloudfront/auth/authSecretManager.d.ts +19 -0
- package/lib/cloudfront/auth/authSecretManager.js +92 -0
- package/lib/cloudfront/auth/cognitoAuthSecretManager.d.ts +20 -0
- package/lib/cloudfront/auth/cognitoAuthSecretManager.js +93 -0
- package/lib/cloudfront/auth/index.d.ts +3 -0
- package/lib/cloudfront/auth/index.js +20 -0
- package/lib/cloudfront/authSecurityTable.d.ts +10 -0
- package/lib/cloudfront/authSecurityTable.js +78 -0
- package/lib/cloudfront/cloudfront-functions/function-composer.d.ts +21 -0
- package/lib/cloudfront/cloudfront-functions/function-composer.js +132 -0
- package/lib/cloudfront/cloudfrontCertificate.d.ts +40 -0
- package/lib/cloudfront/cloudfrontCertificate.js +116 -0
- package/lib/cloudfront/cloudfrontWebAcl.d.ts +72 -0
- package/lib/cloudfront/cloudfrontWebAcl.js +249 -0
- package/lib/cloudfront/countries.d.ts +260 -0
- package/lib/cloudfront/countries.js +263 -0
- package/lib/cloudfront/deployment/viteFrontendDeployment.d.ts +12 -0
- package/lib/cloudfront/deployment/viteFrontendDeployment.js +63 -0
- package/lib/cloudfront/index.d.ts +11 -0
- package/lib/cloudfront/index.js +28 -0
- package/lib/cloudfront/jwtDecoder.d.ts +5 -0
- package/lib/cloudfront/jwtDecoder.js +57 -0
- package/lib/cloudfront/logging/auditLogArchive.d.ts +18 -0
- package/lib/cloudfront/logging/auditLogArchive.js +205 -0
- package/lib/cloudfront/logging/index.d.ts +1 -0
- package/lib/cloudfront/logging/index.js +18 -0
- package/lib/cloudfront/oauthEdgeRole.d.ts +9 -0
- package/lib/cloudfront/oauthEdgeRole.js +56 -0
- package/lib/cloudfront/patterns/authInfrastructure.d.ts +34 -0
- package/lib/cloudfront/patterns/authInfrastructure.js +140 -0
- package/lib/cloudfront/patterns/cognito-secured-cloudfront.d.ts +36 -0
- package/lib/cloudfront/patterns/cognito-secured-cloudfront.js +285 -0
- package/lib/cloudfront/patterns/cognitoAuthInfrastructure.d.ts +28 -0
- package/lib/cloudfront/patterns/cognitoAuthInfrastructure.js +157 -0
- package/lib/cloudfront/patterns/index.d.ts +4 -0
- package/lib/cloudfront/patterns/index.js +21 -0
- package/lib/cloudfront/patterns/securedCloudFront.d.ts +73 -0
- package/lib/cloudfront/patterns/securedCloudFront.js +416 -0
- package/lib/cloudfront/ssmCrossRegionWriter.d.ts +9 -0
- package/lib/cloudfront/ssmCrossRegionWriter.js +65 -0
- package/lib/cloudfront/syncSecretToKvs.d.ts +9 -0
- package/lib/cloudfront/syncSecretToKvs.js +89 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +19 -0
- package/package.json +105 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as core from 'aws-cdk-lib';
|
|
2
|
+
import { aws_cloudfront as cloudfront, aws_secretsmanager as secretsmanager, aws_kms as kms, aws_iam as iam } from 'aws-cdk-lib';
|
|
3
|
+
import * as constructs from 'constructs';
|
|
4
|
+
import { AuthSecurityTable } from '../authSecurityTable';
|
|
5
|
+
export declare enum Extension {
|
|
6
|
+
REQUIRE_AUTH = "REQUIRE_AUTH",
|
|
7
|
+
REQUIRE_TLS_13 = "REQUIRE_TLS_13",
|
|
8
|
+
REWRITE_TO_INDEX_HTML = "REWRITE_TO_INDEX_HTML"
|
|
9
|
+
}
|
|
10
|
+
export declare enum RoleMatchMode {
|
|
11
|
+
OR = "OR",
|
|
12
|
+
AND = "AND"
|
|
13
|
+
}
|
|
14
|
+
export interface ExtensionConfig<TRole extends string = string> {
|
|
15
|
+
readonly requiredRoles?: readonly TRole[];
|
|
16
|
+
readonly roleMatchMode?: RoleMatchMode;
|
|
17
|
+
}
|
|
18
|
+
export interface AddBehaviorOptions<TRole extends string = string> {
|
|
19
|
+
readonly extensions?: Extension[];
|
|
20
|
+
readonly extensionConfig?: ExtensionConfig<TRole>;
|
|
21
|
+
readonly behaviorOptions?: Omit<cloudfront.BehaviorOptions, 'origin'>;
|
|
22
|
+
}
|
|
23
|
+
export interface CloudFrontWithAzureAuthSplitProps<TRole extends string = string> {
|
|
24
|
+
readonly defaultBehavior: Omit<cloudfront.BehaviorOptions, 'functionAssociations'>;
|
|
25
|
+
readonly additionalBehaviors?: Record<string, Omit<cloudfront.BehaviorOptions, 'edgeLambdas'>>;
|
|
26
|
+
readonly domainNames: string[];
|
|
27
|
+
readonly certificate: any;
|
|
28
|
+
readonly redirectUri?: string;
|
|
29
|
+
readonly webAclId?: string;
|
|
30
|
+
readonly hmacSecretRotationSchedule?: core.Duration;
|
|
31
|
+
readonly securityAlertsTopicArn?: string;
|
|
32
|
+
readonly sessionRevocationTopicArn?: string;
|
|
33
|
+
readonly autoRevokeOnReuse?: boolean;
|
|
34
|
+
readonly jwtClaimsWhitelist?: string[];
|
|
35
|
+
readonly auditLogRetentionDays?: number;
|
|
36
|
+
readonly auditArchiveRetentionDays?: number;
|
|
37
|
+
readonly authSsmParamPrefix: string;
|
|
38
|
+
readonly authRegion: string;
|
|
39
|
+
readonly createOAuthCallback?: boolean;
|
|
40
|
+
readonly defaultExtensions?: Extension[];
|
|
41
|
+
readonly defaultExtensionConfig?: ExtensionConfig<TRole>;
|
|
42
|
+
readonly defaultRootObject?: string;
|
|
43
|
+
readonly errorResponsePagePath?: string;
|
|
44
|
+
readonly enableUserInfoInjection?: boolean;
|
|
45
|
+
readonly userInfoNameFields?: string[];
|
|
46
|
+
}
|
|
47
|
+
export declare class SecuredCloudFront<TRole extends string = string> extends constructs.Construct {
|
|
48
|
+
readonly distribution: cloudfront.Distribution;
|
|
49
|
+
readonly configSecret: secretsmanager.ISecret;
|
|
50
|
+
readonly secretArn: string;
|
|
51
|
+
readonly kmsKey: kms.IKey;
|
|
52
|
+
readonly authSecurityTable: AuthSecurityTable;
|
|
53
|
+
readonly auditLogArchive: any;
|
|
54
|
+
readonly lambdaEdgeRole: iam.Role;
|
|
55
|
+
private readonly authCheckFunction;
|
|
56
|
+
private readonly userInfoFunction?;
|
|
57
|
+
private readonly functionComposer;
|
|
58
|
+
private readonly composedFunctions;
|
|
59
|
+
private lastCreatedFunction;
|
|
60
|
+
private readonly tlsOriginRequestPolicy;
|
|
61
|
+
private readonly tenantId;
|
|
62
|
+
private readonly clientId;
|
|
63
|
+
private readonly redirectUri;
|
|
64
|
+
private readonly kvs;
|
|
65
|
+
constructor(scope: constructs.Construct, id: string, props: CloudFrontWithAzureAuthSplitProps<TRole>);
|
|
66
|
+
addBehavior(pathPattern: string, origin: cloudfront.IOrigin, options?: AddBehaviorOptions<TRole> | cloudfront.BehaviorOptions, applyAuth?: boolean): void;
|
|
67
|
+
private buildFunctionAssociations;
|
|
68
|
+
private generateFunctionCacheKey;
|
|
69
|
+
private generateFunctionId;
|
|
70
|
+
private determineRedirectUri;
|
|
71
|
+
private loadAndReplaceAuthCheckCode;
|
|
72
|
+
private loadAndReplaceUserInfoCode;
|
|
73
|
+
}
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SecuredCloudFront = exports.RoleMatchMode = exports.Extension = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const core = __importStar(require("aws-cdk-lib"));
|
|
41
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
42
|
+
const constructs = __importStar(require("constructs"));
|
|
43
|
+
const function_composer_1 = require("../cloudfront-functions/function-composer");
|
|
44
|
+
var Extension;
|
|
45
|
+
(function (Extension) {
|
|
46
|
+
Extension["REQUIRE_AUTH"] = "REQUIRE_AUTH";
|
|
47
|
+
Extension["REQUIRE_TLS_13"] = "REQUIRE_TLS_13";
|
|
48
|
+
Extension["REWRITE_TO_INDEX_HTML"] = "REWRITE_TO_INDEX_HTML";
|
|
49
|
+
})(Extension || (exports.Extension = Extension = {}));
|
|
50
|
+
var RoleMatchMode;
|
|
51
|
+
(function (RoleMatchMode) {
|
|
52
|
+
RoleMatchMode["OR"] = "OR";
|
|
53
|
+
RoleMatchMode["AND"] = "AND";
|
|
54
|
+
})(RoleMatchMode || (exports.RoleMatchMode = RoleMatchMode = {}));
|
|
55
|
+
class SecuredCloudFront extends constructs.Construct {
|
|
56
|
+
constructor(scope, id, props) {
|
|
57
|
+
super(scope, id);
|
|
58
|
+
const redirectUri = this.determineRedirectUri(props.redirectUri, props.domainNames);
|
|
59
|
+
const p = props.authSsmParamPrefix;
|
|
60
|
+
const configSecretArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/configSecretArn`);
|
|
61
|
+
const kmsKeyArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/kmsKeyArn`);
|
|
62
|
+
const authTableArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/authTableArn`);
|
|
63
|
+
const kvsArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/kvsArn`);
|
|
64
|
+
const tenantId = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/tenantId`);
|
|
65
|
+
const clientId = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/clientId`);
|
|
66
|
+
const oauth2CallbackRoleName = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/oauth2CallbackRoleName`);
|
|
67
|
+
this.configSecret = aws_cdk_lib_1.aws_secretsmanager.Secret.fromSecretCompleteArn(this, 'ImportedSecret', configSecretArn);
|
|
68
|
+
this.kmsKey = aws_cdk_lib_1.aws_kms.Key.fromKeyArn(this, 'ImportedKey', kmsKeyArn);
|
|
69
|
+
this.authSecurityTable = { table: { tableArn: authTableArn } };
|
|
70
|
+
this.auditLogArchive = null;
|
|
71
|
+
this.secretArn = configSecretArn;
|
|
72
|
+
this.lambdaEdgeRole = new aws_cdk_lib_1.aws_iam.Role(this, 'LambdaEdgeRole', {
|
|
73
|
+
roleName: oauth2CallbackRoleName,
|
|
74
|
+
assumedBy: new aws_cdk_lib_1.aws_iam.CompositePrincipal(new aws_cdk_lib_1.aws_iam.ServicePrincipal('lambda.amazonaws.com'), new aws_cdk_lib_1.aws_iam.ServicePrincipal('edgelambda.amazonaws.com')),
|
|
75
|
+
managedPolicies: [
|
|
76
|
+
aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
// we need to add these directly, rather than use grant methods, to avoid circular dependnacies.
|
|
80
|
+
this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
81
|
+
effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
|
|
82
|
+
actions: ['secretsmanager:GetSecretValue', 'secretsmanager:DescribeSecret'],
|
|
83
|
+
resources: [configSecretArn],
|
|
84
|
+
}));
|
|
85
|
+
this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
86
|
+
effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
|
|
87
|
+
actions: ['kms:Decrypt'],
|
|
88
|
+
resources: [kmsKeyArn],
|
|
89
|
+
}));
|
|
90
|
+
this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
91
|
+
effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
|
|
92
|
+
actions: ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:Query', 'dynamodb:Scan', 'dynamodb:UpdateItem', 'dynamodb:DeleteItem'],
|
|
93
|
+
resources: [authTableArn],
|
|
94
|
+
}));
|
|
95
|
+
this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
96
|
+
effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
|
|
97
|
+
actions: ['sts:GetWebIdentityToken'],
|
|
98
|
+
resources: ['*'],
|
|
99
|
+
}));
|
|
100
|
+
const kvs = aws_cdk_lib_1.aws_cloudfront.KeyValueStore.fromKeyValueStoreArn(this, 'KVS', kvsArn);
|
|
101
|
+
this.kvs = kvs;
|
|
102
|
+
this.tenantId = tenantId;
|
|
103
|
+
this.clientId = clientId;
|
|
104
|
+
this.redirectUri = redirectUri;
|
|
105
|
+
const configPyContent = `# Generated configuration
|
|
106
|
+
import json
|
|
107
|
+
import boto3
|
|
108
|
+
import os
|
|
109
|
+
import logging
|
|
110
|
+
|
|
111
|
+
logger = logging.getLogger()
|
|
112
|
+
|
|
113
|
+
# Secret name and region - these must be concrete values, not CloudFormation tokens
|
|
114
|
+
# The secret name is constructed from the domain name
|
|
115
|
+
CONFIG_SECRET_NAME = 'cloudfront-auth-config-${props.domainNames[0]}'
|
|
116
|
+
CONFIG_REGION = '${props.authRegion}'
|
|
117
|
+
|
|
118
|
+
def get_config():
|
|
119
|
+
logger.info(f'Attempting to load config from Secrets Manager')
|
|
120
|
+
logger.info(f'CONFIG_SECRET_NAME: {CONFIG_SECRET_NAME}')
|
|
121
|
+
logger.info(f'CONFIG_REGION: {CONFIG_REGION}')
|
|
122
|
+
try:
|
|
123
|
+
client = boto3.client('secretsmanager', region_name=CONFIG_REGION)
|
|
124
|
+
response = client.get_secret_value(SecretId=CONFIG_SECRET_NAME)
|
|
125
|
+
return json.loads(response['SecretString'])
|
|
126
|
+
except Exception as e:
|
|
127
|
+
logger.error(f'Failed to get secret. Name="{CONFIG_SECRET_NAME}", Region="{CONFIG_REGION}"')
|
|
128
|
+
logger.error(f'Error: {str(e)}')
|
|
129
|
+
raise
|
|
130
|
+
`;
|
|
131
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'edge-auth-'));
|
|
132
|
+
const configPyPath = path.join(tempDir, 'config_generated.py');
|
|
133
|
+
fs.writeFileSync(configPyPath, configPyContent);
|
|
134
|
+
const oauthCallbackFunction = new aws_cdk_lib_1.aws_cloudfront.experimental.EdgeFunction(this, 'OAuthCallback', {
|
|
135
|
+
runtime: aws_cdk_lib_1.aws_lambda.Runtime.PYTHON_3_11,
|
|
136
|
+
handler: 'oauth-callback.lambda_handler',
|
|
137
|
+
code: aws_cdk_lib_1.aws_lambda.Code.fromAsset(path.join(__dirname, '../lambda/edge-auth'), {
|
|
138
|
+
bundling: {
|
|
139
|
+
image: aws_cdk_lib_1.aws_lambda.Runtime.PYTHON_3_11.bundlingImage,
|
|
140
|
+
command: [
|
|
141
|
+
'bash', '-c',
|
|
142
|
+
'pip install -r requirements.txt -t /asset-output && ' +
|
|
143
|
+
'cp -r . /asset-output && ' +
|
|
144
|
+
'cp /tmp/config_generated.py /asset-output/config_generated.py',
|
|
145
|
+
],
|
|
146
|
+
volumes: [
|
|
147
|
+
{
|
|
148
|
+
hostPath: configPyPath,
|
|
149
|
+
containerPath: '/tmp/config_generated.py',
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
}),
|
|
154
|
+
timeout: core.Duration.seconds(30),
|
|
155
|
+
memorySize: 128,
|
|
156
|
+
role: this.lambdaEdgeRole,
|
|
157
|
+
});
|
|
158
|
+
const authCheckCode = this.loadAndReplaceAuthCheckCode(tenantId, clientId, redirectUri);
|
|
159
|
+
this.authCheckFunction = new aws_cdk_lib_1.aws_cloudfront.Function(this, 'AuthCheck', {
|
|
160
|
+
code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(authCheckCode),
|
|
161
|
+
runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
|
|
162
|
+
keyValueStore: kvs,
|
|
163
|
+
comment: 'verifies tokens',
|
|
164
|
+
});
|
|
165
|
+
this.lastCreatedFunction = this.authCheckFunction;
|
|
166
|
+
// Create user info endpoint function if enabled
|
|
167
|
+
if (props.enableUserInfoInjection !== false) {
|
|
168
|
+
if (!props.userInfoNameFields || props.userInfoNameFields.length === 0) {
|
|
169
|
+
throw new Error('userInfoNameFields must be provided when enableUserInfoInjection is true');
|
|
170
|
+
}
|
|
171
|
+
const userInfoCode = this.loadAndReplaceUserInfoCode(props.userInfoNameFields);
|
|
172
|
+
this.userInfoFunction = new aws_cdk_lib_1.aws_cloudfront.Function(this, 'UserInfoEndpoint', {
|
|
173
|
+
code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(userInfoCode),
|
|
174
|
+
runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
|
|
175
|
+
keyValueStore: kvs,
|
|
176
|
+
comment: 'Returns user info JSON from JWT',
|
|
177
|
+
});
|
|
178
|
+
this.userInfoFunction.node.addDependency(this.authCheckFunction);
|
|
179
|
+
this.lastCreatedFunction = this.userInfoFunction;
|
|
180
|
+
}
|
|
181
|
+
const additionalBehaviors = {};
|
|
182
|
+
if (props.createOAuthCallback !== false) {
|
|
183
|
+
additionalBehaviors['/oauth2/callback'] = {
|
|
184
|
+
origin: props.defaultBehavior.origin,
|
|
185
|
+
viewerProtocolPolicy: aws_cdk_lib_1.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
186
|
+
...props.additionalBehaviors?.['/oauth2/callback'],
|
|
187
|
+
edgeLambdas: [{
|
|
188
|
+
functionVersion: oauthCallbackFunction.currentVersion,
|
|
189
|
+
eventType: aws_cdk_lib_1.aws_cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
|
|
190
|
+
}],
|
|
191
|
+
cachePolicy: props.additionalBehaviors?.['/oauth2/callback']?.cachePolicy ?? new aws_cdk_lib_1.aws_cloudfront.CachePolicy(this, 'CallbackCachePolicy', {
|
|
192
|
+
cachePolicyName: `${core.Stack.of(this).stackName}-oauth-callback`,
|
|
193
|
+
comment: 'Cache policy for OAuth callback with state cookie forwarding',
|
|
194
|
+
defaultTtl: core.Duration.seconds(0),
|
|
195
|
+
minTtl: core.Duration.seconds(0),
|
|
196
|
+
maxTtl: core.Duration.seconds(1),
|
|
197
|
+
cookieBehavior: aws_cdk_lib_1.aws_cloudfront.CacheCookieBehavior.allowList('oauth_state'),
|
|
198
|
+
headerBehavior: aws_cdk_lib_1.aws_cloudfront.CacheHeaderBehavior.none(),
|
|
199
|
+
queryStringBehavior: aws_cdk_lib_1.aws_cloudfront.CacheQueryStringBehavior.all(),
|
|
200
|
+
enableAcceptEncodingGzip: false,
|
|
201
|
+
enableAcceptEncodingBrotli: false,
|
|
202
|
+
}),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (props.additionalBehaviors) {
|
|
206
|
+
Object.entries(props.additionalBehaviors).forEach(([pathPattern, behavior]) => {
|
|
207
|
+
if (pathPattern !== '/oauth2/callback') {
|
|
208
|
+
additionalBehaviors[pathPattern] = behavior;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
// Origin request policy that forwards CloudFront-Viewer-TLS header (required for REQUIRE_TLS_13)
|
|
213
|
+
this.tlsOriginRequestPolicy = new aws_cdk_lib_1.aws_cloudfront.OriginRequestPolicy(this, 'TlsOriginRequestPolicy', {
|
|
214
|
+
headerBehavior: aws_cdk_lib_1.aws_cloudfront.OriginRequestHeaderBehavior.allowList('CloudFront-Viewer-TLS'),
|
|
215
|
+
cookieBehavior: aws_cdk_lib_1.aws_cloudfront.OriginRequestCookieBehavior.none(),
|
|
216
|
+
queryStringBehavior: aws_cdk_lib_1.aws_cloudfront.OriginRequestQueryStringBehavior.none(),
|
|
217
|
+
});
|
|
218
|
+
// Initialize function composer
|
|
219
|
+
this.functionComposer = new function_composer_1.FunctionComposer();
|
|
220
|
+
this.composedFunctions = new Map();
|
|
221
|
+
this.distribution = new aws_cdk_lib_1.aws_cloudfront.Distribution(this, 'Distribution', {
|
|
222
|
+
httpVersion: aws_cdk_lib_1.aws_cloudfront.HttpVersion.HTTP2_AND_3,
|
|
223
|
+
minimumProtocolVersion: aws_cdk_lib_1.aws_cloudfront.SecurityPolicyProtocol.TLS_V1_2_2025,
|
|
224
|
+
defaultBehavior: (() => {
|
|
225
|
+
const defaultBuilt = this.buildFunctionAssociations(props.defaultExtensions, props.defaultExtensionConfig);
|
|
226
|
+
return {
|
|
227
|
+
...props.defaultBehavior,
|
|
228
|
+
functionAssociations: defaultBuilt?.functionAssociations,
|
|
229
|
+
originRequestPolicy: defaultBuilt?.originRequestPolicy,
|
|
230
|
+
};
|
|
231
|
+
})(),
|
|
232
|
+
additionalBehaviors: additionalBehaviors,
|
|
233
|
+
domainNames: props.domainNames,
|
|
234
|
+
certificate: props.certificate,
|
|
235
|
+
webAclId: props.webAclId,
|
|
236
|
+
defaultRootObject: props.defaultRootObject ?? 'index.html',
|
|
237
|
+
errorResponses: [
|
|
238
|
+
{
|
|
239
|
+
httpStatus: 403,
|
|
240
|
+
responseHttpStatus: 200,
|
|
241
|
+
responsePagePath: props.errorResponsePagePath ?? '/error.html',
|
|
242
|
+
ttl: core.Duration.minutes(5),
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
httpStatus: 404,
|
|
246
|
+
responseHttpStatus: 200,
|
|
247
|
+
responsePagePath: props.errorResponsePagePath ?? '/error.html',
|
|
248
|
+
ttl: core.Duration.minutes(5),
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
httpStatus: 500,
|
|
252
|
+
responseHttpStatus: 200,
|
|
253
|
+
responsePagePath: props.errorResponsePagePath ?? '/error.html',
|
|
254
|
+
ttl: core.Duration.seconds(10),
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
httpStatus: 502,
|
|
258
|
+
responseHttpStatus: 200,
|
|
259
|
+
responsePagePath: props.errorResponsePagePath ?? '/error.html',
|
|
260
|
+
ttl: core.Duration.seconds(10),
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
httpStatus: 503,
|
|
264
|
+
responseHttpStatus: 200,
|
|
265
|
+
responsePagePath: props.errorResponsePagePath ?? '/error.html',
|
|
266
|
+
ttl: core.Duration.seconds(10),
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
httpStatus: 504,
|
|
270
|
+
responseHttpStatus: 200,
|
|
271
|
+
responsePagePath: props.errorResponsePagePath ?? '/error.html',
|
|
272
|
+
ttl: core.Duration.seconds(10),
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
});
|
|
276
|
+
// Add /userinfo behavior if user info endpoint is enabled
|
|
277
|
+
if (this.userInfoFunction) {
|
|
278
|
+
this.distribution.addBehavior('/userinfo', props.defaultBehavior.origin, {
|
|
279
|
+
viewerProtocolPolicy: aws_cdk_lib_1.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
280
|
+
functionAssociations: [
|
|
281
|
+
{
|
|
282
|
+
function: this.userInfoFunction,
|
|
283
|
+
eventType: aws_cdk_lib_1.aws_cloudfront.FunctionEventType.VIEWER_REQUEST,
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
cachePolicy: aws_cdk_lib_1.aws_cloudfront.CachePolicy.CACHING_DISABLED,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
addBehavior(pathPattern, origin, options = {}, applyAuth) {
|
|
291
|
+
// Support legacy signature: addBehavior(path, behaviorOptions, applyAuth)
|
|
292
|
+
if ('origin' in options || 'viewerProtocolPolicy' in options) {
|
|
293
|
+
const behaviorOptions = options;
|
|
294
|
+
const shouldApplyAuth = applyAuth !== false;
|
|
295
|
+
if (shouldApplyAuth) {
|
|
296
|
+
const functionAssociations = [
|
|
297
|
+
...(behaviorOptions.functionAssociations || []),
|
|
298
|
+
{
|
|
299
|
+
function: this.authCheckFunction,
|
|
300
|
+
eventType: aws_cdk_lib_1.aws_cloudfront.FunctionEventType.VIEWER_REQUEST,
|
|
301
|
+
},
|
|
302
|
+
];
|
|
303
|
+
this.distribution.addBehavior(pathPattern, origin, {
|
|
304
|
+
...behaviorOptions,
|
|
305
|
+
functionAssociations: functionAssociations,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
this.distribution.addBehavior(pathPattern, origin, behaviorOptions);
|
|
310
|
+
}
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
// New signature: addBehavior(path, origin, AddBehaviorOptions)
|
|
314
|
+
const addBehaviorOptions = options;
|
|
315
|
+
const built = this.buildFunctionAssociations(addBehaviorOptions.extensions, addBehaviorOptions.extensionConfig);
|
|
316
|
+
this.distribution.addBehavior(pathPattern, origin, {
|
|
317
|
+
...addBehaviorOptions.behaviorOptions,
|
|
318
|
+
functionAssociations: built?.functionAssociations ?? addBehaviorOptions.behaviorOptions?.functionAssociations,
|
|
319
|
+
originRequestPolicy: built?.originRequestPolicy ?? addBehaviorOptions.behaviorOptions?.originRequestPolicy,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
buildFunctionAssociations(extensions, config) {
|
|
323
|
+
if (!extensions || extensions.length === 0) {
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
// Generate cache key for this combination of extensions + config
|
|
327
|
+
const cacheKey = this.generateFunctionCacheKey(extensions, config);
|
|
328
|
+
// Check if we already created this function
|
|
329
|
+
let func = this.composedFunctions.get(cacheKey);
|
|
330
|
+
if (!func) {
|
|
331
|
+
// Generate combined function code with Azure AD configuration
|
|
332
|
+
const code = this.functionComposer.compose(extensions, config, {
|
|
333
|
+
tenantId: this.tenantId,
|
|
334
|
+
clientId: this.clientId,
|
|
335
|
+
redirectUri: this.redirectUri,
|
|
336
|
+
});
|
|
337
|
+
// Create CloudFront Function
|
|
338
|
+
const functionId = this.generateFunctionId(extensions, config);
|
|
339
|
+
// Add KVS if auth extension is included
|
|
340
|
+
const functionProps = extensions.includes(Extension.REQUIRE_AUTH)
|
|
341
|
+
? {
|
|
342
|
+
code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(code),
|
|
343
|
+
runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
|
|
344
|
+
comment: `Combined: ${extensions.join(', ')}`,
|
|
345
|
+
keyValueStore: this.kvs,
|
|
346
|
+
}
|
|
347
|
+
: {
|
|
348
|
+
code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(code),
|
|
349
|
+
runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
|
|
350
|
+
comment: `Combined: ${extensions.join(', ')}`,
|
|
351
|
+
};
|
|
352
|
+
func = new aws_cdk_lib_1.aws_cloudfront.Function(this, functionId, functionProps);
|
|
353
|
+
if (this.lastCreatedFunction) {
|
|
354
|
+
func.node.addDependency(this.lastCreatedFunction);
|
|
355
|
+
}
|
|
356
|
+
this.lastCreatedFunction = func;
|
|
357
|
+
this.composedFunctions.set(cacheKey, func);
|
|
358
|
+
}
|
|
359
|
+
const result = {
|
|
360
|
+
functionAssociations: [{
|
|
361
|
+
function: func,
|
|
362
|
+
eventType: aws_cdk_lib_1.aws_cloudfront.FunctionEventType.VIEWER_REQUEST,
|
|
363
|
+
}],
|
|
364
|
+
};
|
|
365
|
+
if (extensions.includes(Extension.REQUIRE_TLS_13)) {
|
|
366
|
+
result.originRequestPolicy = this.tlsOriginRequestPolicy;
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
generateFunctionCacheKey(extensions, config) {
|
|
371
|
+
const parts = [extensions.sort().join(',')];
|
|
372
|
+
if (config?.requiredRoles) {
|
|
373
|
+
parts.push([...config.requiredRoles].sort().join(','));
|
|
374
|
+
}
|
|
375
|
+
if (config?.roleMatchMode && config.roleMatchMode !== RoleMatchMode.OR) {
|
|
376
|
+
parts.push(config.roleMatchMode);
|
|
377
|
+
}
|
|
378
|
+
return parts.join('|');
|
|
379
|
+
}
|
|
380
|
+
generateFunctionId(extensions, config) {
|
|
381
|
+
const extensionPart = extensions.map(e => e.replace('REQUIRE_', '')).join('');
|
|
382
|
+
if (config?.requiredRoles && config.requiredRoles.length > 0) {
|
|
383
|
+
const roleHash = config.requiredRoles.join('').replace(/[^a-zA-Z0-9]/g, '').substring(0, 8);
|
|
384
|
+
const modePart = config.roleMatchMode && config.roleMatchMode !== RoleMatchMode.OR ? config.roleMatchMode : '';
|
|
385
|
+
return `ComposedFunction${extensionPart}${roleHash}${modePart}`;
|
|
386
|
+
}
|
|
387
|
+
return `ComposedFunction${extensionPart}`;
|
|
388
|
+
}
|
|
389
|
+
determineRedirectUri(redirectUri, domainNames) {
|
|
390
|
+
if (redirectUri) {
|
|
391
|
+
return redirectUri;
|
|
392
|
+
}
|
|
393
|
+
if (!domainNames || domainNames.length === 0) {
|
|
394
|
+
throw new Error('Either redirectUri or domainNames must be provided');
|
|
395
|
+
}
|
|
396
|
+
return `https://${domainNames[0]}/oauth2/callback`;
|
|
397
|
+
}
|
|
398
|
+
loadAndReplaceAuthCheckCode(tenantId, clientId, redirectUri) {
|
|
399
|
+
const codePath = path.join(__dirname, '../cloudfront-functions/auth-check.js');
|
|
400
|
+
let code = fs.readFileSync(codePath, 'utf-8');
|
|
401
|
+
code = code.replace('TENANT_ID_PLACEHOLDER', tenantId);
|
|
402
|
+
code = code.replace('CLIENT_ID_PLACEHOLDER', clientId);
|
|
403
|
+
code = code.replace('REDIRECT_URI_PLACEHOLDER', redirectUri);
|
|
404
|
+
return code;
|
|
405
|
+
}
|
|
406
|
+
loadAndReplaceUserInfoCode(nameFields) {
|
|
407
|
+
const codePath = path.join(__dirname, '../cloudfront-functions/userinfo-endpoint.js');
|
|
408
|
+
let code = fs.readFileSync(codePath, 'utf-8');
|
|
409
|
+
// Replace the nameFields array with the provided fields
|
|
410
|
+
const nameFieldsJson = JSON.stringify(nameFields);
|
|
411
|
+
code = code.replace("var nameFields = ['key1', 'key2', 'key3'];", `var nameFields = ${nameFieldsJson};`);
|
|
412
|
+
return code;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
exports.SecuredCloudFront = SecuredCloudFront;
|
|
416
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJlZENsb3VkRnJvbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xvdWRmcm9udC9wYXR0ZXJucy9zZWN1cmVkQ2xvdWRGcm9udC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQUM3QixrREFBb0M7QUFDcEMsNkNBT3FCO0FBQ3JCLHVEQUF5QztBQUV6QyxpRkFBNkU7QUFFN0UsSUFBWSxTQUlYO0FBSkQsV0FBWSxTQUFTO0lBQ25CLDBDQUE2QixDQUFBO0lBQzdCLDhDQUFpQyxDQUFBO0lBQ2pDLDREQUErQyxDQUFBO0FBQ2pELENBQUMsRUFKVyxTQUFTLHlCQUFULFNBQVMsUUFJcEI7QUFFRCxJQUFZLGFBR1g7QUFIRCxXQUFZLGFBQWE7SUFDdkIsMEJBQVMsQ0FBQTtJQUNULDRCQUFXLENBQUE7QUFDYixDQUFDLEVBSFcsYUFBYSw2QkFBYixhQUFhLFFBR3hCO0FBc0NELE1BQWEsaUJBQWlELFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFvQnhGLFlBQVksS0FBMkIsRUFBRSxFQUFVLEVBQUUsS0FBK0M7UUFDbEcsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFcEYsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQ25DLE1BQU0sZUFBZSxHQUFHLHFCQUFHLENBQUMsZUFBZSxDQUFDLHVCQUF1QixDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNsRyxNQUFNLFNBQVMsR0FBRyxxQkFBRyxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLEVB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cyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgY29yZSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQge1xuICBhd3NfY2xvdWRmcm9udCBhcyBjbG91ZGZyb250LFxuICBhd3Nfc2VjcmV0c21hbmFnZXIgYXMgc2VjcmV0c21hbmFnZXIsXG4gIGF3c19rbXMgYXMga21zLFxuICBhd3NfaWFtIGFzIGlhbSxcbiAgYXdzX2xhbWJkYSBhcyBsYW1iZGEsXG4gIGF3c19zc20gYXMgc3NtLFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQXV0aFNlY3VyaXR5VGFibGUgfSBmcm9tICcuLi9hdXRoU2VjdXJpdHlUYWJsZSc7XG5pbXBvcnQgeyBGdW5jdGlvbkNvbXBvc2VyIH0gZnJvbSAnLi4vY2xvdWRmcm9udC1mdW5jdGlvbnMvZnVuY3Rpb24tY29tcG9zZXInO1xuXG5leHBvcnQgZW51bSBFeHRlbnNpb24ge1xuICBSRVFVSVJFX0FVVEggPSAnUkVRVUlSRV9BVVRIJyxcbiAgUkVRVUlSRV9UTFNfMTMgPSAnUkVRVUlSRV9UTFNfMTMnLFxuICBSRVdSSVRFX1RPX0lOREVYX0hUTUwgPSAnUkVXUklURV9UT19JTkRFWF9IVE1MJyxcbn1cblxuZXhwb3J0IGVudW0gUm9sZU1hdGNoTW9kZSB7XG4gIE9SID0gJ09SJyxcbiAgQU5EID0gJ0FORCcsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0ZW5zaW9uQ29uZmlnPFRSb2xlIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG4gIHJlYWRvbmx5IHJlcXVpcmVkUm9sZXM/OiByZWFkb25seSBUUm9sZVtdO1xuICByZWFkb25seSByb2xlTWF0Y2hNb2RlPzogUm9sZU1hdGNoTW9kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZGRCZWhhdmlvck9wdGlvbnM8VFJvbGUgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+IHtcbiAgcmVhZG9ubHkgZXh0ZW5zaW9ucz86IEV4dGVuc2lvbltdO1xuICByZWFkb25seSBleHRlbnNpb25Db25maWc/OiBFeHRlbnNpb25Db25maWc8VFJvbGU+O1xuICByZWFkb25seSBiZWhhdmlvck9wdGlvbnM/OiBPbWl0PGNsb3VkZnJvbnQuQmVoYXZpb3JPcHRpb25zLCAnb3JpZ2luJz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xvdWRGcm9udFdpdGhBenVyZUF1dGhTcGxpdFByb3BzPFRSb2xlIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG4gIHJlYWRvbmx5IGRlZmF1bHRCZWhhdmlvcjogT21pdDxjbG91ZGZyb250LkJlaGF2aW9yT3B0aW9ucywgJ2Z1bmN0aW9uQXNzb2NpYXRpb25zJz47XG4gIHJlYWRvbmx5IGFkZGl0aW9uYWxCZWhhdmlvcnM/OiBSZWNvcmQ8c3RyaW5nLCBPbWl0PGNsb3VkZnJvbnQuQmVoYXZpb3JPcHRpb25zLCAnZWRnZUxhbWJkYXMnPj47XG4gIHJlYWRvbmx5IGRvbWFpbk5hbWVzOiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgY2VydGlmaWNhdGU6IGFueTtcbiAgcmVhZG9ubHkgcmVkaXJlY3RVcmk/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdlYkFjbElkPzogc3RyaW5nO1xuICByZWFkb25seSBobWFjU2VjcmV0Um90YXRpb25TY2hlZHVsZT86IGNvcmUuRHVyYXRpb247XG4gIHJlYWRvbmx5IHNlY3VyaXR5QWxlcnRzVG9waWNBcm4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNlc3Npb25SZXZvY2F0aW9uVG9waWNBcm4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGF1dG9SZXZva2VPblJldXNlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgand0Q2xhaW1zV2hpdGVsaXN0Pzogc3RyaW5nW107XG4gIHJlYWRvbmx5IGF1ZGl0TG9nUmV0ZW50aW9uRGF5cz86IG51bWJlcjtcbiAgcmVhZG9ubHkgYXVkaXRBcmNoaXZlUmV0ZW50aW9uRGF5cz86IG51bWJlcjtcbiAgcmVhZG9ubHkgYXV0aFNzbVBhcmFtUHJlZml4OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGF1dGhSZWdpb246IHN0cmluZztcbiAgcmVhZG9ubHkgY3JlYXRlT0F1dGhDYWxsYmFjaz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRlZmF1bHRFeHRlbnNpb25zPzogRXh0ZW5zaW9uW107XG4gIHJlYWRvbmx5IGRlZmF1bHRFeHRlbnNpb25Db25maWc/OiBFeHRlbnNpb25Db25maWc8VFJvbGU+O1xuICByZWFkb25seSBkZWZhdWx0Um9vdE9iamVjdD86IHN0cmluZztcbiAgcmVhZG9ubHkgZXJyb3JSZXNwb25zZVBhZ2VQYXRoPzogc3RyaW5nO1xuICByZWFkb25seSBlbmFibGVVc2VySW5mb0luamVjdGlvbj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHVzZXJJbmZvTmFtZUZpZWxkcz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY2xhc3MgU2VjdXJlZENsb3VkRnJvbnQ8VFJvbGUgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+IGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3Qge1xuXG4gIHB1YmxpYyByZWFkb25seSBkaXN0cmlidXRpb246IGNsb3VkZnJvbnQuRGlzdHJpYnV0aW9uO1xuICBwdWJsaWMgcmVhZG9ubHkgY29uZmlnU2VjcmV0OiBzZWNyZXRzbWFuYWdlci5JU2VjcmV0O1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0QXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBrbXNLZXk6IGttcy5JS2V5O1xuICBwdWJsaWMgcmVhZG9ubHkgYXV0aFNlY3VyaXR5VGFibGU6IEF1dGhTZWN1cml0eVRhYmxlO1xuICBwdWJsaWMgcmVhZG9ubHkgYXVkaXRMb2dBcmNoaXZlOiBhbnk7XG4gIHB1YmxpYyByZWFkb25seSBsYW1iZGFFZGdlUm9sZTogaWFtLlJvbGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXV0aENoZWNrRnVuY3Rpb246IGNsb3VkZnJvbnQuRnVuY3Rpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgdXNlckluZm9GdW5jdGlvbj86IGNsb3VkZnJvbnQuRnVuY3Rpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgZnVuY3Rpb25Db21wb3NlcjogRnVuY3Rpb25Db21wb3NlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21wb3NlZEZ1bmN0aW9uczogTWFwPHN0cmluZywgY2xvdWRmcm9udC5GdW5jdGlvbj47XG4gIHByaXZhdGUgbGFzdENyZWF0ZWRGdW5jdGlvbjogY2xvdWRmcm9udC5GdW5jdGlvbiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSB0bHNPcmlnaW5SZXF1ZXN0UG9saWN5OiBjbG91ZGZyb250Lk9yaWdpblJlcXVlc3RQb2xpY3k7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGVuYW50SWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnRJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZGlyZWN0VXJpOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkga3ZzOiBjbG91ZGZyb250LklLZXlWYWx1ZVN0b3JlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENsb3VkRnJvbnRXaXRoQXp1cmVBdXRoU3BsaXRQcm9wczxUUm9sZT4pIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgcmVkaXJlY3RVcmkgPSB0aGlzLmRldGVybWluZVJlZGlyZWN0VXJpKHByb3BzLnJlZGlyZWN0VXJpLCBwcm9wcy5kb21haW5OYW1lcyk7XG5cbiAgICBjb25zdCBwID0gcHJvcHMuYXV0aFNzbVBhcmFtUHJlZml4O1xuICAgIGNvbnN0IGNvbmZpZ1NlY3JldEFybiA9IHNzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgYCR7cH0vY29uZmlnU2VjcmV0QXJuYCk7XG4gICAgY29uc3Qga21zS2V5QXJuID0gc3NtLlN0cmluZ1BhcmFtZXRlci52YWx1ZUZvclN0cmluZ1BhcmFtZXRlcih0aGlzLCBgJHtwfS9rbXNLZXlBcm5gKTtcbiAgICBjb25zdCBhdXRoVGFibGVBcm4gPSBzc20uU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKHRoaXMsIGAke3B9L2F1dGhUYWJsZUFybmApO1xuICAgIGNvbnN0IGt2c0FybiA9IHNzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgYCR7cH0va3ZzQXJuYCk7XG4gICAgY29uc3QgdGVuYW50SWQgPSBzc20uU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKHRoaXMsIGAke3B9L3RlbmFudElkYCk7XG4gICAgY29uc3QgY2xpZW50SWQgPSBzc20uU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKHRoaXMsIGAke3B9L2NsaWVudElkYCk7XG4gICAgY29uc3Qgb2F1dGgyQ2FsbGJhY2tSb2xlTmFtZSA9IHNzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgYCR7cH0vb2F1dGgyQ2FsbGJhY2tSb2xlTmFtZWApO1xuXG4gICAgdGhpcy5jb25maWdTZWNyZXQgPSBzZWNyZXRzbWFuYWdlci5TZWNyZXQuZnJvbVNlY3JldENvbXBsZXRlQXJuKHRoaXMsICdJbXBvcnRlZFNlY3JldCcsIGNvbmZpZ1NlY3JldEFybik7XG4gICAgdGhpcy5rbXNLZXkgPSBrbXMuS2V5LmZyb21LZXlBcm4odGhpcywgJ0ltcG9ydGVkS2V5Jywga21zS2V5QXJuKTtcbiAgICB0aGlzLmF1dGhTZWN1cml0eVRhYmxlID0geyB0YWJsZTogeyB0YWJsZUFybjogYXV0aFRhYmxlQXJuIH0gfSBhcyBhbnk7XG4gICAgdGhpcy5hdWRpdExvZ0FyY2hpdmUgPSBudWxsO1xuICAgIHRoaXMuc2VjcmV0QXJuID0gY29uZmlnU2VjcmV0QXJuO1xuXG4gICAgdGhpcy5sYW1iZGFFZGdlUm9sZSA9IG5ldyBpYW0uUm9sZSh0aGlzLCAnTGFtYmRhRWRnZVJvbGUnLCB7XG4gICAgICByb2xlTmFtZTogb2F1dGgyQ2FsbGJhY2tSb2xlTmFtZSxcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5Db21wb3NpdGVQcmluY2lwYWwoXG4gICAgICAgIG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnbGFtYmRhLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgICAgbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdlZGdlbGFtYmRhLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgICksXG4gICAgICBtYW5hZ2VkUG9saWNpZXM6IFtcbiAgICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJyksXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgLy8gd2UgbmVlZCB0byBhZGQgdGhlc2UgZGlyZWN0bHksIHJhdGhlciB0aGFuIHVzZSBncmFudCBtZXRob2RzLCB0byBhdm9pZCBjaXJjdWxhciBkZXBlbmRuYWNpZXMuXG4gICAgdGhpcy5sYW1iZGFFZGdlUm9sZS5hZGRUb1BvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICBhY3Rpb25zOiBbJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJywgJ3NlY3JldHNtYW5hZ2VyOkRlc2NyaWJlU2VjcmV0J10sXG4gICAgICByZXNvdXJjZXM6IFtjb25maWdTZWNyZXRBcm5dLFxuICAgIH0pKTtcblxuICAgIHRoaXMubGFtYmRhRWRnZVJvbGUuYWRkVG9Qb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogWydrbXM6RGVjcnlwdCddLFxuICAgICAgcmVzb3VyY2VzOiBba21zS2V5QXJuXSxcbiAgICB9KSk7XG5cbiAgICB0aGlzLmxhbWJkYUVkZ2VSb2xlLmFkZFRvUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgIGFjdGlvbnM6IFsnZHluYW1vZGI6R2V0SXRlbScsICdkeW5hbW9kYjpQdXRJdGVtJywgJ2R5bmFtb2RiOlF1ZXJ5JywgJ2R5bmFtb2RiOlNjYW4nLCAnZHluYW1vZGI6VXBkYXRlSXRlbScsICdkeW5hbW9kYjpEZWxldGVJdGVtJ10sXG4gICAgICByZXNvdXJjZXM6IFthdXRoVGFibGVBcm5dLFxuICAgIH0pKTtcblxuICAgIHRoaXMubGFtYmRhRWRnZVJvbGUuYWRkVG9Qb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogWydzdHM6R2V0V2ViSWRlbnRpdHlUb2tlbiddLFxuICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBrdnMgPSBjbG91ZGZyb250LktleVZhbHVlU3RvcmUuZnJvbUtleVZhbHVlU3RvcmVBcm4odGhpcywgJ0tWUycsIGt2c0Fybik7XG4gICAgdGhpcy5rdnMgPSBrdnM7XG4gICAgdGhpcy50ZW5hbnRJZCA9IHRlbmFudElkO1xuICAgIHRoaXMuY2xpZW50SWQgPSBjbGllbnRJZDtcbiAgICB0aGlzLnJlZGlyZWN0VXJpID0gcmVkaXJlY3RVcmk7XG5cbiAgICBjb25zdCBjb25maWdQeUNvbnRlbnQgPSBgIyBHZW5lcmF0ZWQgY29uZmlndXJhdGlvblxuaW1wb3J0IGpzb25cbmltcG9ydCBib3RvM1xuaW1wb3J0IG9zXG5pbXBvcnQgbG9nZ2luZ1xuXG5sb2dnZXIgPSBsb2dnaW5nLmdldExvZ2dlcigpXG5cbiMgU2VjcmV0IG5hbWUgYW5kIHJlZ2lvbiAtIHRoZXNlIG11c3QgYmUgY29uY3JldGUgdmFsdWVzLCBub3QgQ2xvdWRGb3JtYXRpb24gdG9rZW5zXG4jIFRoZSBzZWNyZXQgbmFtZSBpcyBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBkb21haW4gbmFtZVxuQ09ORklHX1NFQ1JFVF9OQU1FID0gJ2Nsb3VkZnJvbnQtYXV0aC1jb25maWctJHtwcm9wcy5kb21haW5OYW1lc1swXX0nXG5DT05GSUdfUkVHSU9OID0gJyR7cHJvcHMuYXV0aFJlZ2lvbn0nXG5cbmRlZiBnZXRfY29uZmlnKCk6XG4gICAgbG9nZ2VyLmluZm8oZidBdHRlbXB0aW5nIHRvIGxvYWQgY29uZmlnIGZyb20gU2VjcmV0cyBNYW5hZ2VyJylcbiAgICBsb2dnZXIuaW5mbyhmJ0NPTkZJR19TRUNSRVRfTkFNRToge0NPTkZJR19TRUNSRVRfTkFNRX0nKVxuICAgIGxvZ2dlci5pbmZvKGYnQ09ORklHX1JFR0lPTjoge0NPTkZJR19SRUdJT059JylcbiAgICB0cnk6XG4gICAgICAgIGNsaWVudCA9IGJvdG8zLmNsaWVudCgnc2VjcmV0c21hbmFnZXInLCByZWdpb25fbmFtZT1DT05GSUdfUkVHSU9OKVxuICAgICAgICByZXNwb25zZSA9IGNsaWVudC5nZXRfc2VjcmV0X3ZhbHVlKFNlY3JldElkPUNPTkZJR19TRUNSRVRfTkFNRSlcbiAgICAgICAgcmV0dXJuIGpzb24ubG9hZHMocmVzcG9uc2VbJ1NlY3JldFN0cmluZyddKVxuICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTpcbiAgICAgICAgbG9nZ2VyLmVycm9yKGYnRmFpbGVkIHRvIGdldCBzZWNyZXQuIE5hbWU9XCJ7Q09ORklHX1NFQ1JFVF9OQU1FfVwiLCBSZWdpb249XCJ7Q09ORklHX1JFR0lPTn1cIicpXG4gICAgICAgIGxvZ2dlci5lcnJvcihmJ0Vycm9yOiB7c3RyKGUpfScpXG4gICAgICAgIHJhaXNlXG5gO1xuXG4gICAgY29uc3QgdGVtcERpciA9IGZzLm1rZHRlbXBTeW5jKHBhdGguam9pbihvcy50bXBkaXIoKSwgJ2VkZ2UtYXV0aC0nKSk7XG4gICAgY29uc3QgY29uZmlnUHlQYXRoID0gcGF0aC5qb2luKHRlbXBEaXIsICdjb25maWdfZ2VuZXJhdGVkLnB5Jyk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhjb25maWdQeVBhdGgsIGNvbmZpZ1B5Q29udGVudCk7XG5cbiAgICBjb25zdCBvYXV0aENhbGxiYWNrRnVuY3Rpb24gPSBuZXcgY2xvdWRmcm9udC5leHBlcmltZW50YWwuRWRnZUZ1bmN0aW9uKHRoaXMsICdPQXV0aENhbGxiYWNrJywge1xuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfMTEsXG4gICAgICBoYW5kbGVyOiAnb2F1dGgtY2FsbGJhY2subGFtYmRhX2hhbmRsZXInLFxuICAgICAgY29kZTogbGFtYmRhLkNvZGUuZnJvbUFzc2V0KHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi9sYW1iZGEvZWRnZS1hdXRoJyksIHtcbiAgICAgICAgYnVuZGxpbmc6IHtcbiAgICAgICAgICBpbWFnZTogbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfMTEuYnVuZGxpbmdJbWFnZSxcbiAgICAgICAgICBjb21tYW5kOiBbXG4gICAgICAgICAgICAnYmFzaCcsICctYycsXG4gICAgICAgICAgICAncGlwIGluc3RhbGwgLXIgcmVxdWlyZW1lbnRzLnR4dCAtdCAvYXNzZXQtb3V0cHV0ICYmICcgK1xuICAgICAgICAgICAgJ2NwIC1yIC4gL2Fzc2V0LW91dHB1dCAmJiAnICtcbiAgICAgICAgICAgICdjcCAvdG1wL2NvbmZpZ19nZW5lcmF0ZWQucHkgL2Fzc2V0LW91dHB1dC9jb25maWdfZ2VuZXJhdGVkLnB5JyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHZvbHVtZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaG9zdFBhdGg6IGNvbmZpZ1B5UGF0aCxcbiAgICAgICAgICAgICAgY29udGFpbmVyUGF0aDogJy90bXAvY29uZmlnX2dlbmVyYXRlZC5weScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIHRpbWVvdXQ6IGNvcmUuRHVyYXRpb24uc2Vjb25kcygzMCksXG4gICAgICBtZW1vcnlTaXplOiAxMjgsXG4gICAgICByb2xlOiB0aGlzLmxhbWJkYUVkZ2VSb2xlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYXV0aENoZWNrQ29kZSA9IHRoaXMubG9hZEFuZFJlcGxhY2VBdXRoQ2hlY2tDb2RlKFxuICAgICAgdGVuYW50SWQsXG4gICAgICBjbGllbnRJZCxcbiAgICAgIHJlZGlyZWN0VXJpLFxuICAgICk7XG5cbiAgICB0aGlzLmF1dGhDaGVja0Z1bmN0aW9uID0gbmV3IGNsb3VkZnJvbnQuRnVuY3Rpb24odGhpcywgJ0F1dGhDaGVjaycsIHtcbiAgICAgIGNvZGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25Db2RlLmZyb21JbmxpbmUoYXV0aENoZWNrQ29kZSksXG4gICAgICBydW50aW1lOiBjbG91ZGZyb250LkZ1bmN0aW9uUnVudGltZS5KU18yXzAsXG4gICAgICBrZXlWYWx1ZVN0b3JlOiBrdnMsXG4gICAgICBjb21tZW50OiAndmVyaWZpZXMgdG9rZW5zJyxcbiAgICB9KTtcbiAgICB0aGlzLmxhc3RDcmVhdGVkRnVuY3Rpb24gPSB0aGlzLmF1dGhDaGVja0Z1bmN0aW9uO1xuXG4gICAgLy8gQ3JlYXRlIHVzZXIgaW5mbyBlbmRwb2ludCBmdW5jdGlvbiBpZiBlbmFibGVkXG4gICAgaWYgKHByb3BzLmVuYWJsZVVzZXJJbmZvSW5qZWN0aW9uICE9PSBmYWxzZSkge1xuICAgICAgaWYgKCFwcm9wcy51c2VySW5mb05hbWVGaWVsZHMgfHwgcHJvcHMudXNlckluZm9OYW1lRmllbGRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZXJJbmZvTmFtZUZpZWxkcyBtdXN0IGJlIHByb3ZpZGVkIHdoZW4gZW5hYmxlVXNlckluZm9JbmplY3Rpb24gaXMgdHJ1ZScpO1xuICAgICAgfVxuICAgICAgY29uc3QgdXNlckluZm9Db2RlID0gdGhpcy5sb2FkQW5kUmVwbGFjZVVzZXJJbmZvQ29kZShwcm9wcy51c2VySW5mb05hbWVGaWVsZHMpO1xuICAgICAgdGhpcy51c2VySW5mb0Z1bmN0aW9uID0gbmV3IGNsb3VkZnJvbnQuRnVuY3Rpb24odGhpcywgJ1VzZXJJbmZvRW5kcG9pbnQnLCB7XG4gICAgICAgIGNvZGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25Db2RlLmZyb21JbmxpbmUodXNlckluZm9Db2RlKSxcbiAgICAgICAgcnVudGltZTogY2xvdWRmcm9udC5GdW5jdGlvblJ1bnRpbWUuSlNfMl8wLFxuICAgICAgICBrZXlWYWx1ZVN0b3JlOiBrdnMsXG4gICAgICAgIGNvbW1lbnQ6ICdSZXR1cm5zIHVzZXIgaW5mbyBKU09OIGZyb20gSldUJyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy51c2VySW5mb0Z1bmN0aW9uLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLmF1dGhDaGVja0Z1bmN0aW9uKTtcbiAgICAgIHRoaXMubGFzdENyZWF0ZWRGdW5jdGlvbiA9IHRoaXMudXNlckluZm9GdW5jdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBhZGRpdGlvbmFsQmVoYXZpb3JzOiBSZWNvcmQ8c3RyaW5nLCBjbG91ZGZyb250LkJlaGF2aW9yT3B0aW9ucz4gPSB7fTtcblxuICAgIGlmIChwcm9wcy5jcmVhdGVPQXV0aENhbGxiYWNrICE9PSBmYWxzZSkge1xuICAgICAgYWRkaXRpb25hbEJlaGF2aW9yc1snL29hdXRoMi9jYWxsYmFjayddID0ge1xuICAgICAgICBvcmlnaW46IHByb3BzLmRlZmF1bHRCZWhhdmlvci5vcmlnaW4sXG4gICAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBjbG91ZGZyb250LlZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgICAuLi5wcm9wcy5hZGRpdGlvbmFsQmVoYXZpb3JzPy5bJy9vYXV0aDIvY2FsbGJhY2snXSxcbiAgICAgICAgZWRnZUxhbWJkYXM6IFt7XG4gICAgICAgICAgZnVuY3Rpb25WZXJzaW9uOiBvYXV0aENhbGxiYWNrRnVuY3Rpb24uY3VycmVudFZlcnNpb24sXG4gICAgICAgICAgZXZlbnRUeXBlOiBjbG91ZGZyb250LkxhbWJkYUVkZ2VFdmVudFR5cGUuVklFV0VSX1JFUVVFU1QsXG4gICAgICAgIH1dLFxuICAgICAgICBjYWNoZVBvbGljeTogcHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycz8uWycvb2F1dGgyL2NhbGxiYWNrJ10/LmNhY2hlUG9saWN5ID8/IG5ldyBjbG91ZGZyb250LkNhY2hlUG9saWN5KHRoaXMsICdDYWxsYmFja0NhY2hlUG9saWN5Jywge1xuICAgICAgICAgIGNhY2hlUG9saWN5TmFtZTogYCR7Y29yZS5TdGFjay5vZih0aGlzKS5zdGFja05hbWV9LW9hdXRoLWNhbGxiYWNrYCxcbiAgICAgICAgICBjb21tZW50OiAnQ2FjaGUgcG9saWN5IGZvciBPQXV0aCBjYWxsYmFjayB3aXRoIHN0YXRlIGNvb2tpZSBmb3J3YXJkaW5nJyxcbiAgICAgICAgICBkZWZhdWx0VHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMCksXG4gICAgICAgICAgbWluVHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMCksXG4gICAgICAgICAgbWF4VHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMSksXG4gICAgICAgICAgY29va2llQmVoYXZpb3I6IGNsb3VkZnJvbnQuQ2FjaGVDb29raWVCZWhhdmlvci5hbGxvd0xpc3QoJ29hdXRoX3N0YXRlJyksXG4gICAgICAgICAgaGVhZGVyQmVoYXZpb3I6IGNsb3VkZnJvbnQuQ2FjaGVIZWFkZXJCZWhhdmlvci5ub25lKCksXG4gICAgICAgICAgcXVlcnlTdHJpbmdCZWhhdmlvcjogY2xvdWRmcm9udC5DYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IuYWxsKCksXG4gICAgICAgICAgZW5hYmxlQWNjZXB0RW5jb2RpbmdHemlwOiBmYWxzZSxcbiAgICAgICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0Jyb3RsaTogZmFsc2UsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycykge1xuICAgICAgT2JqZWN0LmVudHJpZXMocHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycykuZm9yRWFjaCgoW3BhdGhQYXR0ZXJuLCBiZWhhdmlvcl0pID0+IHtcbiAgICAgICAgaWYgKHBhdGhQYXR0ZXJuICE9PSAnL29hdXRoMi9jYWxsYmFjaycpIHtcbiAgICAgICAgICBhZGRpdGlvbmFsQmVoYXZpb3JzW3BhdGhQYXR0ZXJuXSA9IGJlaGF2aW9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBPcmlnaW4gcmVxdWVzdCBwb2xpY3kgdGhhdCBmb3J3YXJkcyBDbG91ZEZyb250LVZpZXdlci1UTFMgaGVhZGVyIChyZXF1aXJlZCBmb3IgUkVRVUlSRV9UTFNfMTMpXG4gICAgdGhpcy50bHNPcmlnaW5SZXF1ZXN0UG9saWN5ID0gbmV3IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdFBvbGljeSh0aGlzLCAnVGxzT3JpZ2luUmVxdWVzdFBvbGljeScsIHtcbiAgICAgIGhlYWRlckJlaGF2aW9yOiBjbG91ZGZyb250Lk9yaWdpblJlcXVlc3RIZWFkZXJCZWhhdmlvci5hbGxvd0xpc3QoJ0Nsb3VkRnJvbnQtVmlld2VyLVRMUycpLFxuICAgICAgY29va2llQmVoYXZpb3I6IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdENvb2tpZUJlaGF2aW9yLm5vbmUoKSxcbiAgICAgIHF1ZXJ5U3RyaW5nQmVoYXZpb3I6IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdFF1ZXJ5U3RyaW5nQmVoYXZpb3Iubm9uZSgpLFxuICAgIH0pO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBmdW5jdGlvbiBjb21wb3NlclxuICAgIHRoaXMuZnVuY3Rpb25Db21wb3NlciA9IG5ldyBGdW5jdGlvbkNvbXBvc2VyKCk7XG4gICAgdGhpcy5jb21wb3NlZEZ1bmN0aW9ucyA9IG5ldyBNYXAoKTtcblxuICAgIHRoaXMuZGlzdHJpYnV0aW9uID0gbmV3IGNsb3VkZnJvbnQuRGlzdHJpYnV0aW9uKHRoaXMsICdEaXN0cmlidXRpb24nLCB7XG4gICAgICBodHRwVmVyc2lvbjogY2xvdWRmcm9udC5IdHRwVmVyc2lvbi5IVFRQMl9BTkRfMyxcbiAgICAgIG1pbmltdW1Qcm90b2NvbFZlcnNpb246IGNsb3VkZnJvbnQuU2VjdXJpdHlQb2xpY3lQcm90b2NvbC5UTFNfVjFfMl8yMDI1LFxuICAgICAgZGVmYXVsdEJlaGF2aW9yOiAoKCkgPT4ge1xuICAgICAgICBjb25zdCBkZWZhdWx0QnVpbHQgPSB0aGlzLmJ1aWxkRnVuY3Rpb25Bc3NvY2lhdGlvbnMocHJvcHMuZGVmYXVsdEV4dGVuc2lvbnMsIHByb3BzLmRlZmF1bHRFeHRlbnNpb25Db25maWcpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnByb3BzLmRlZmF1bHRCZWhhdmlvcixcbiAgICAgICAgICBmdW5jdGlvbkFzc29jaWF0aW9uczogZGVmYXVsdEJ1aWx0Py5mdW5jdGlvbkFzc29jaWF0aW9ucyxcbiAgICAgICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiBkZWZhdWx0QnVpbHQ/Lm9yaWdpblJlcXVlc3RQb2xpY3ksXG4gICAgICAgIH07XG4gICAgICB9KSgpLFxuICAgICAgYWRkaXRpb25hbEJlaGF2aW9yczogYWRkaXRpb25hbEJlaGF2aW9ycyxcbiAgICAgIGRvbWFpbk5hbWVzOiBwcm9wcy5kb21haW5OYW1lcyxcbiAgICAgIGNlcnRpZmljYXRlOiBwcm9wcy5jZXJ0aWZpY2F0ZSxcbiAgICAgIHdlYkFjbElkOiBwcm9wcy53ZWJBY2xJZCxcbiAgICAgIGRlZmF1bHRSb290T2JqZWN0OiBwcm9wcy5kZWZhdWx0Um9vdE9iamVjdCA/PyAnaW5kZXguaHRtbCcsXG4gICAgICBlcnJvclJlc3BvbnNlczogW1xuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNDAzLFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNDA0LFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNTAwLFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5zZWNvbmRzKDEwKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGh0dHBTdGF0dXM6IDUwMixcbiAgICAgICAgICByZXNwb25zZUh0dHBTdGF0dXM6IDIwMCxcbiAgICAgICAgICByZXNwb25zZVBhZ2VQYXRoOiBwcm9wcy5lcnJvclJlc3BvbnNlUGFnZVBhdGggPz8gJy9lcnJvci5odG1sJyxcbiAgICAgICAgICB0dGw6IGNvcmUuRHVyYXRpb24uc2Vjb25kcygxMCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBodHRwU3RhdHVzOiA1MDMsXG4gICAgICAgICAgcmVzcG9uc2VIdHRwU3RhdHVzOiAyMDAsXG4gICAgICAgICAgcmVzcG9uc2VQYWdlUGF0aDogcHJvcHMuZXJyb3JSZXNwb25zZVBhZ2VQYXRoID8/ICcvZXJyb3IuaHRtbCcsXG4gICAgICAgICAgdHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMTApLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNTA0LFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5zZWNvbmRzKDEwKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICAvLyBBZGQgL3VzZXJpbmZvIGJlaGF2aW9yIGlmIHVzZXIgaW5mbyBlbmRwb2ludCBpcyBlbmFibGVkXG4gICAgaWYgKHRoaXMudXNlckluZm9GdW5jdGlvbikge1xuICAgICAgdGhpcy5kaXN0cmlidXRpb24uYWRkQmVoYXZpb3IoJy91c2VyaW5mbycsIHByb3BzLmRlZmF1bHRCZWhhdmlvci5vcmlnaW4sIHtcbiAgICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IGNsb3VkZnJvbnQuVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICAgIGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgZnVuY3Rpb246IHRoaXMudXNlckluZm9GdW5jdGlvbixcbiAgICAgICAgICAgIGV2ZW50VHlwZTogY2xvdWRmcm9udC5GdW5jdGlvbkV2ZW50VHlwZS5WSUVXRVJfUkVRVUVTVCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBjYWNoZVBvbGljeTogY2xvdWRmcm9udC5DYWNoZVBvbGljeS5DQUNISU5HX0RJU0FCTEVELFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFkZEJlaGF2aW9yKFxuICAgIHBhdGhQYXR0ZXJuOiBzdHJpbmcsXG4gICAgb3JpZ2luOiBjbG91ZGZyb250LklPcmlnaW4sXG4gICAgb3B0aW9uczogQWRkQmVoYXZpb3JPcHRpb25zPFRSb2xlPiB8IGNsb3VkZnJvbnQuQmVoYXZpb3JPcHRpb25zID0ge30sXG4gICAgYXBwbHlBdXRoPzogYm9vbGVhbixcbiAgKTogdm9pZCB7XG4gICAgLy8gU3VwcG9ydCBsZWdhY3kgc2lnbmF0dXJlOiBhZGRCZWhhdmlvcihwYXRoLCBiZWhhdmlvck9wdGlvbnMsIGFwcGx5QXV0aClcbiAgICBpZiAoJ29yaWdpbicgaW4gb3B0aW9ucyB8fCAndmlld2VyUHJvdG9jb2xQb2xpY3knIGluIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IGJlaGF2aW9yT3B0aW9ucyA9IG9wdGlvbnMgYXMgY2xvdWRmcm9udC5CZWhhdmlvck9wdGlvbnM7XG4gICAgICBjb25zdCBzaG91bGRBcHBseUF1dGggPSBhcHBseUF1dGggIT09IGZhbHNlO1xuXG4gICAgICBpZiAoc2hvdWxkQXBwbHlBdXRoKSB7XG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBjbG91ZGZyb250LkZ1bmN0aW9uQXNzb2NpYXRpb25bXSA9IFtcbiAgICAgICAgICAuLi4oYmVoYXZpb3JPcHRpb25zLmZ1bmN0aW9uQXNzb2NpYXRpb25zIHx8IFtdKSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBmdW5jdGlvbjogdGhpcy5hdXRoQ2hlY2tGdW5jdGlvbixcbiAgICAgICAgICAgIGV2ZW50VHlwZTogY2xvdWRmcm9udC5GdW5jdGlvbkV2ZW50VHlwZS5WSUVXRVJfUkVRVUVTVCxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihwYXRoUGF0dGVybiwgb3JpZ2luLCB7XG4gICAgICAgICAgLi4uYmVoYXZpb3JPcHRpb25zLFxuICAgICAgICAgIGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBmdW5jdGlvbkFzc29jaWF0aW9ucyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihwYXRoUGF0dGVybiwgb3JpZ2luLCBiZWhhdmlvck9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE5ldyBzaWduYXR1cmU6IGFkZEJlaGF2aW9yKHBhdGgsIG9yaWdpbiwgQWRkQmVoYXZpb3JPcHRpb25zKVxuICAgIGNvbnN0IGFkZEJlaGF2aW9yT3B0aW9ucyA9IG9wdGlvbnMgYXMgQWRkQmVoYXZpb3JPcHRpb25zPFRSb2xlPjtcblxuICAgIGNvbnN0IGJ1aWx0ID0gdGhpcy5idWlsZEZ1bmN0aW9uQXNzb2NpYXRpb25zKFxuICAgICAgYWRkQmVoYXZpb3JPcHRpb25zLmV4dGVuc2lvbnMsXG4gICAgICBhZGRCZWhhdmlvck9wdGlvbnMuZXh0ZW5zaW9uQ29uZmlnLFxuICAgICk7XG5cbiAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihwYXRoUGF0dGVybiwgb3JpZ2luLCB7XG4gICAgICAuLi5hZGRCZWhhdmlvck9wdGlvbnMuYmVoYXZpb3JPcHRpb25zLFxuICAgICAgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IGJ1aWx0Py5mdW5jdGlvbkFzc29jaWF0aW9ucyA/PyBhZGRCZWhhdmlvck9wdGlvbnMuYmVoYXZpb3JPcHRpb25zPy5mdW5jdGlvbkFzc29jaWF0aW9ucyxcbiAgICAgIG9yaWdpblJlcXVlc3RQb2xpY3k6IGJ1aWx0Py5vcmlnaW5SZXF1ZXN0UG9saWN5ID8/IGFkZEJlaGF2aW9yT3B0aW9ucy5iZWhhdmlvck9wdGlvbnM/Lm9yaWdpblJlcXVlc3RQb2xpY3ksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRnVuY3Rpb25Bc3NvY2lhdGlvbnMoXG4gICAgZXh0ZW5zaW9ucz86IEV4dGVuc2lvbltdLFxuICAgIGNvbmZpZz86IEV4dGVuc2lvbkNvbmZpZzxUUm9sZT4sXG4gICk6IHsgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IGNsb3VkZnJvbnQuRnVuY3Rpb25Bc3NvY2lhdGlvbltdOyBvcmlnaW5SZXF1ZXN0UG9saWN5PzogY2xvdWRmcm9udC5PcmlnaW5SZXF1ZXN0UG9saWN5IH0gfCB1bmRlZmluZWQge1xuICAgIGlmICghZXh0ZW5zaW9ucyB8fCBleHRlbnNpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBjYWNoZSBrZXkgZm9yIHRoaXMgY29tYmluYXRpb24gb2YgZXh0ZW5zaW9ucyArIGNvbmZpZ1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gdGhpcy5nZW5lcmF0ZUZ1bmN0aW9uQ2FjaGVLZXkoZXh0ZW5zaW9ucywgY29uZmlnKTtcblxuICAgIC8vIENoZWNrIGlmIHdlIGFscmVhZHkgY3JlYXRlZCB0aGlzIGZ1bmN0aW9uXG4gICAgbGV0IGZ1bmMgPSB0aGlzLmNvbXBvc2VkRnVuY3Rpb25zLmdldChjYWNoZUtleSk7XG4gICAgaWYgKCFmdW5jKSB7XG4gICAgICAvLyBHZW5lcmF0ZSBjb21iaW5lZCBmdW5jdGlvbiBjb2RlIHdpdGggQXp1cmUgQUQgY29uZmlndXJhdGlvblxuICAgICAgY29uc3QgY29kZSA9IHRoaXMuZnVuY3Rpb25Db21wb3Nlci5jb21wb3NlKGV4dGVuc2lvbnMsIGNvbmZpZywge1xuICAgICAgICB0ZW5hbnRJZDogdGhpcy50ZW5hbnRJZCxcbiAgICAgICAgY2xpZW50SWQ6IHRoaXMuY2xpZW50SWQsXG4gICAgICAgIHJlZGlyZWN0VXJpOiB0aGlzLnJlZGlyZWN0VXJpLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIENyZWF0ZSBDbG91ZEZyb250IEZ1bmN0aW9uXG4gICAgICBjb25zdCBmdW5jdGlvbklkID0gdGhpcy5nZW5lcmF0ZUZ1bmN0aW9uSWQoZXh0ZW5zaW9ucywgY29uZmlnKTtcblxuICAgICAgLy8gQWRkIEtWUyBpZiBhdXRoIGV4dGVuc2lvbiBpcyBpbmNsdWRlZFxuICAgICAgY29uc3QgZnVuY3Rpb25Qcm9wcyA9IGV4dGVuc2lvbnMuaW5jbHVkZXMoRXh0ZW5zaW9uLlJFUVVJUkVfQVVUSClcbiAgICAgICAgPyB7XG4gICAgICAgICAgY29kZTogY2xvdWRmcm9udC5GdW5jdGlvbkNvZGUuZnJvbUlubGluZShjb2RlKSxcbiAgICAgICAgICBydW50aW1lOiBjbG91ZGZyb250LkZ1bmN0aW9uUnVudGltZS5KU18yXzAsXG4gICAgICAgICAgY29tbWVudDogYENvbWJpbmVkOiAke2V4dGVuc2lvbnMuam9pbignLCAnKX1gLFxuICAgICAgICAgIGtleVZhbHVlU3RvcmU6IHRoaXMua3ZzLFxuICAgICAgICB9XG4gICAgICAgIDoge1xuICAgICAgICAgIGNvZGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25Db2RlLmZyb21JbmxpbmUoY29kZSksXG4gICAgICAgICAgcnVudGltZTogY2xvdWRmcm9udC5GdW5jdGlvblJ1bnRpbWUuSlNfMl8wLFxuICAgICAgICAgIGNvbW1lbnQ6IGBDb21iaW5lZDogJHtleHRlbnNpb25zLmpvaW4oJywgJyl9YCxcbiAgICAgICAgfTtcblxuICAgICAgZnVuYyA9IG5ldyBjbG91ZGZyb250LkZ1bmN0aW9uKHRoaXMsIGZ1bmN0aW9uSWQsIGZ1bmN0aW9uUHJvcHMpO1xuXG4gICAgICBpZiAodGhpcy5sYXN0Q3JlYXRlZEZ1bmN0aW9uKSB7XG4gICAgICAgIGZ1bmMubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMubGFzdENyZWF0ZWRGdW5jdGlvbik7XG4gICAgICB9XG4gICAgICB0aGlzLmxhc3RDcmVhdGVkRnVuY3Rpb24gPSBmdW5jO1xuXG4gICAgICB0aGlzLmNvbXBvc2VkRnVuY3Rpb25zLnNldChjYWNoZUtleSwgZnVuYyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0OiB7IGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBjbG91ZGZyb250LkZ1bmN0aW9uQXNzb2NpYXRpb25bXTsgb3JpZ2luUmVxdWVzdFBvbGljeT86IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdFBvbGljeSB9ID0ge1xuICAgICAgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IFt7XG4gICAgICAgIGZ1bmN0aW9uOiBmdW5jLFxuICAgICAgICBldmVudFR5cGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25FdmVudFR5cGUuVklFV0VSX1JFUVVFU1QsXG4gICAgICB9XSxcbiAgICB9O1xuXG4gICAgaWYgKGV4dGVuc2lvbnMuaW5jbHVkZXMoRXh0ZW5zaW9uLlJFUVVJUkVfVExTXzEzKSkge1xuICAgICAgcmVzdWx0Lm9yaWdpblJlcXVlc3RQb2xpY3kgPSB0aGlzLnRsc09yaWdpblJlcXVlc3RQb2xpY3k7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgZ2VuZXJhdGVGdW5jdGlvbkNhY2hlS2V5KGV4dGVuc2lvbnM6IEV4dGVuc2lvbltdLCBjb25maWc/OiBFeHRlbnNpb25Db25maWc8VFJvbGU+KTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJ0cyA9IFtleHRlbnNpb25zLnNvcnQoKS5qb2luKCcsJyldO1xuICAgIGlmIChjb25maWc/LnJlcXVpcmVkUm9sZXMpIHtcbiAgICAgIHBhcnRzLnB1c2goWy4uLmNvbmZpZy5yZXF1aXJlZFJvbGVzXS5zb3J0KCkuam9pbignLCcpKTtcbiAgICB9XG4gICAgaWYgKGNvbmZpZz8ucm9sZU1hdGNoTW9kZSAmJiBjb25maWcucm9sZU1hdGNoTW9kZSAhPT0gUm9sZU1hdGNoTW9kZS5PUikge1xuICAgICAgcGFydHMucHVzaChjb25maWcucm9sZU1hdGNoTW9kZSk7XG4gICAgfVxuICAgIHJldHVybiBwYXJ0cy5qb2luKCd8Jyk7XG4gIH1cblxuICBwcml2YXRlIGdlbmVyYXRlRnVuY3Rpb25JZChleHRlbnNpb25zOiBFeHRlbnNpb25bXSwgY29uZmlnPzogRXh0ZW5zaW9uQ29uZmlnPFRSb2xlPik6IHN0cmluZyB7XG4gICAgY29uc3QgZXh0ZW5zaW9uUGFydCA9IGV4dGVuc2lvbnMubWFwKGUgPT4gZS5yZXBsYWNlKCdSRVFVSVJFXycsICcnKSkuam9pbignJyk7XG4gICAgaWYgKGNvbmZpZz8ucmVxdWlyZWRSb2xlcyAmJiBjb25maWcucmVxdWlyZWRSb2xlcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCByb2xlSGFzaCA9IGNvbmZpZy5yZXF1aXJlZFJvbGVzLmpvaW4oJycpLnJlcGxhY2UoL1teYS16QS1aMC05XS9nLCAnJykuc3Vic3RyaW5nKDAsIDgpO1xuICAgICAgY29uc3QgbW9kZVBhcnQgPSBjb25maWcucm9sZU1hdGNoTW9kZSAmJiBjb25maWcucm9sZU1hdGNoTW9kZSAhPT0gUm9sZU1hdGNoTW9kZS5PUiA/IGNvbmZpZy5yb2xlTWF0Y2hNb2RlIDogJyc7XG4gICAgICByZXR1cm4gYENvbXBvc2VkRnVuY3Rpb24ke2V4dGVuc2lvblBhcnR9JHtyb2xlSGFzaH0ke21vZGVQYXJ0fWA7XG4gICAgfVxuICAgIHJldHVybiBgQ29tcG9zZWRGdW5jdGlvbiR7ZXh0ZW5zaW9uUGFydH1gO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXRlcm1pbmVSZWRpcmVjdFVyaShyZWRpcmVjdFVyaT86IHN0cmluZywgZG9tYWluTmFtZXM/OiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgaWYgKHJlZGlyZWN0VXJpKSB7XG4gICAgICByZXR1cm4gcmVkaXJlY3RVcmk7XG4gICAgfVxuICAgIGlmICghZG9tYWluTmFtZXMgfHwgZG9tYWluTmFtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciByZWRpcmVjdFVyaSBvciBkb21haW5OYW1lcyBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gICAgfVxuICAgIHJldHVybiBgaHR0cHM6Ly8ke2RvbWFpbk5hbWVzWzBdfS9vYXV0aDIvY2FsbGJhY2tgO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkQW5kUmVwbGFjZUF1dGhDaGVja0NvZGUodGVuYW50SWQ6IHN0cmluZywgY2xpZW50SWQ6IHN0cmluZywgcmVkaXJlY3RVcmk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29kZVBhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vY2xvdWRmcm9udC1mdW5jdGlvbnMvYXV0aC1jaGVjay5qcycpO1xuICAgIGxldCBjb2RlID0gZnMucmVhZEZpbGVTeW5jKGNvZGVQYXRoLCAndXRmLTgnKTtcbiAgICBjb2RlID0gY29kZS5yZXBsYWNlKCdURU5BTlRfSURfUExBQ0VIT0xERVInLCB0ZW5hbnRJZCk7XG4gICAgY29kZSA9IGNvZGUucmVwbGFjZSgnQ0xJRU5UX0lEX1BMQUNFSE9MREVSJywgY2xpZW50SWQpO1xuICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UoJ1JFRElSRUNUX1VSSV9QTEFDRUhPTERFUicsIHJlZGlyZWN0VXJpKTtcbiAgICByZXR1cm4gY29kZTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEFuZFJlcGxhY2VVc2VySW5mb0NvZGUobmFtZUZpZWxkczogc3RyaW5nW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvZGVQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL2Nsb3VkZnJvbnQtZnVuY3Rpb25zL3VzZXJpbmZvLWVuZHBvaW50LmpzJyk7XG4gICAgbGV0IGNvZGUgPSBmcy5yZWFkRmlsZVN5bmMoY29kZVBhdGgsICd1dGYtOCcpO1xuXG4gICAgLy8gUmVwbGFjZSB0aGUgbmFtZUZpZWxkcyBhcnJheSB3aXRoIHRoZSBwcm92aWRlZCBmaWVsZHNcbiAgICBjb25zdCBuYW1lRmllbGRzSnNvbiA9IEpTT04uc3RyaW5naWZ5KG5hbWVGaWVsZHMpO1xuICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UoXG4gICAgICBcInZhciBuYW1lRmllbGRzID0gWydrZXkxJywgJ2tleTInLCAna2V5MyddO1wiLFxuICAgICAgYHZhciBuYW1lRmllbGRzID0gJHtuYW1lRmllbGRzSnNvbn07YCxcbiAgICApO1xuXG4gICAgcmV0dXJuIGNvZGU7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as constructs from 'constructs';
|
|
2
|
+
export interface SsmCrossRegionWriterProps {
|
|
3
|
+
readonly prefix: string;
|
|
4
|
+
readonly region: string;
|
|
5
|
+
readonly params: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export declare class SsmCrossRegionWriter extends constructs.Construct {
|
|
8
|
+
constructor(scope: constructs.Construct, id: string, props: SsmCrossRegionWriterProps);
|
|
9
|
+
}
|