@liflig/cdk 2.18.5 → 2.18.6
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/assets/cloudtrail-slack-integration-lambda/main.py +267 -0
- package/assets/pipeline-slack-notification-lambda/index.py +300 -0
- package/assets/prepare-cdk-source-lambda/index.py +159 -0
- package/assets/slack-alarm-lambda/index.py +103 -0
- package/lib/alarms/database-alarms.d.ts +125 -0
- package/lib/alarms/database-alarms.js +171 -0
- package/lib/alarms/index.d.ts +3 -0
- package/lib/alarms/index.js +10 -0
- package/lib/alarms/service-alarms.d.ts +145 -0
- package/lib/alarms/service-alarms.js +148 -0
- package/lib/alarms/ses-alarms.d.ts +67 -0
- package/lib/alarms/ses-alarms.js +49 -0
- package/lib/alarms/slack-alarm.d.ts +25 -0
- package/lib/alarms/slack-alarm.js +47 -0
- package/lib/bastion-host.d.ts +41 -0
- package/lib/bastion-host.js +86 -0
- package/lib/bin/cdk-create-snapshots.d.ts +2 -0
- package/lib/bin/fetch-pipeline-variables.d.ts +2 -0
- package/lib/build-artifacts/index.d.ts +68 -0
- package/lib/build-artifacts/index.js +118 -0
- package/lib/cdk-deploy/cdk-deploy.d.ts +63 -0
- package/lib/cdk-deploy/cdk-deploy.js +175 -0
- package/lib/cdk-deploy/index.d.ts +1 -0
- package/lib/cdk-deploy/index.js +6 -0
- package/lib/cdk-deploy/start-deploy-handler.d.ts +8 -0
- package/lib/cdk-deploy/start-deploy-handler.js +72 -0
- package/lib/cdk-deploy/status-handler.d.ts +6 -0
- package/lib/cdk-deploy/status-handler.js +83 -0
- package/lib/cdk-pipelines/cloud-assembly-lookup-handler.d.ts +6 -0
- package/lib/cdk-pipelines/cloud-assembly-lookup-handler.js +63 -0
- package/lib/cdk-pipelines/index.d.ts +3 -0
- package/lib/cdk-pipelines/index.js +10 -0
- package/lib/cdk-pipelines/liflig-cdk-pipeline.d.ts +110 -0
- package/lib/cdk-pipelines/liflig-cdk-pipeline.js +232 -0
- package/lib/cdk-pipelines/slack-notification.d.ts +51 -0
- package/lib/cdk-pipelines/slack-notification.js +54 -0
- package/lib/cdk-pipelines/variables.d.ts +15 -0
- package/lib/cdk-pipelines/variables.js +80 -0
- package/lib/cloudtrail-slack-integration/cloudtrail-slack-integration.d.ts +47 -0
- package/lib/cloudtrail-slack-integration/cloudtrail-slack-integration.js +211 -0
- package/lib/cloudtrail-slack-integration/index.d.ts +1 -0
- package/lib/cloudtrail-slack-integration/index.js +6 -0
- package/lib/configure-parameters/configure-parameters.d.ts +61 -0
- package/lib/configure-parameters/configure-parameters.js +94 -0
- package/lib/configure-parameters/index.d.ts +1 -0
- package/lib/configure-parameters/index.js +6 -0
- package/lib/cross-region-ssm-parameter.d.ts +13 -0
- package/lib/cross-region-ssm-parameter.js +46 -0
- package/lib/ecs/cluster.d.ts +25 -0
- package/lib/ecs/cluster.js +70 -0
- package/lib/ecs/fargate-service.d.ts +63 -0
- package/lib/ecs/fargate-service.js +98 -0
- package/lib/ecs/index.d.ts +3 -0
- package/lib/ecs/index.js +10 -0
- package/lib/ecs/listener-rule.d.ts +25 -0
- package/lib/ecs/listener-rule.js +27 -0
- package/lib/ecs-update-image/artifact-status.d.ts +39 -0
- package/lib/ecs-update-image/artifact-status.js +41 -0
- package/lib/ecs-update-image/ecs-update-image.d.ts +41 -0
- package/lib/ecs-update-image/ecs-update-image.js +98 -0
- package/lib/ecs-update-image/index.d.ts +3 -0
- package/lib/ecs-update-image/index.js +10 -0
- package/lib/ecs-update-image/start-deploy-handler.d.ts +6 -0
- package/lib/ecs-update-image/start-deploy-handler.js +104 -0
- package/lib/ecs-update-image/status-handler.d.ts +11 -0
- package/lib/ecs-update-image/status-handler.js +74 -0
- package/lib/ecs-update-image/tag.d.ts +47 -0
- package/lib/ecs-update-image/tag.js +67 -0
- package/lib/feature-flags.d.ts +18 -0
- package/lib/feature-flags.js +48 -0
- package/lib/griid/artefact-bucket.d.ts +7 -0
- package/lib/griid/artefact-bucket.js +30 -0
- package/lib/griid/index.d.ts +4 -0
- package/lib/griid/index.js +18 -0
- package/lib/hosted-zone-with-param.d.ts +29 -0
- package/lib/hosted-zone-with-param.js +65 -0
- package/lib/index.d.ts +32 -0
- package/lib/kinesis/index.d.ts +1 -0
- package/lib/kinesis/index.js +6 -0
- package/lib/kinesis/kinesis-to-datadog-stream.d.ts +28 -0
- package/lib/kinesis/kinesis-to-datadog-stream.js +126 -0
- package/lib/load-balancer/index.d.ts +1 -0
- package/lib/load-balancer/index.js +6 -0
- package/lib/load-balancer/load-balancer.d.ts +16 -0
- package/lib/load-balancer/load-balancer.js +60 -0
- package/lib/pipelines/conventions.d.ts +14 -0
- package/lib/pipelines/conventions.js +24 -0
- package/lib/pipelines/deploy-env.d.ts +18 -0
- package/lib/pipelines/deploy-env.js +96 -0
- package/lib/pipelines/index.d.ts +2 -0
- package/lib/pipelines/index.js +8 -0
- package/lib/pipelines/liflig-cdk-deployer-deps.d.ts +13 -0
- package/lib/pipelines/liflig-cdk-deployer-deps.js +35 -0
- package/lib/pipelines/pipeline.d.ts +78 -0
- package/lib/pipelines/pipeline.js +224 -0
- package/lib/platform/index.d.ts +1 -0
- package/lib/platform/index.js +7 -0
- package/lib/platform/platform.d.ts +37 -0
- package/lib/platform/platform.js +57 -0
- package/lib/rds/database.d.ts +49 -0
- package/lib/rds/database.js +60 -0
- package/lib/rds/index.d.ts +1 -0
- package/lib/rds/index.js +6 -0
- package/lib/ses/configurationsetdeliveryoptions/index.d.ts +26 -0
- package/lib/ses/configurationsetdeliveryoptions/index.js +48 -0
- package/lib/ses/configurationsetsnsdestination/handler.d.ts +17 -0
- package/lib/ses/configurationsetsnsdestination/handler.js +75 -0
- package/lib/ses/configurationsetsnsdestination/index.d.ts +29 -0
- package/lib/ses/configurationsetsnsdestination/index.js +75 -0
- package/lib/ses/index.d.ts +4 -0
- package/lib/ses/index.js +12 -0
- package/lib/ses/sesdomain/handler.d.ts +10 -0
- package/lib/ses/sesdomain/handler.js +82 -0
- package/lib/ses/sesdomain/index.d.ts +57 -0
- package/lib/ses/sesdomain/index.js +94 -0
- package/lib/ses/sesverifyemail/handler.d.ts +9 -0
- package/lib/ses/sesverifyemail/handler.js +25 -0
- package/lib/ses/sesverifyemail/index.d.ts +13 -0
- package/lib/ses/sesverifyemail/index.js +51 -0
- package/lib/snapshots.d.ts +4 -0
- package/lib/snapshots.js +214 -0
- package/lib/ssm-parameter-backed-resource.d.ts +45 -0
- package/lib/ssm-parameter-backed-resource.js +67 -0
- package/lib/ssm-parameter-reader.d.ts +21 -0
- package/lib/ssm-parameter-reader.js +48 -0
- package/lib/tags.d.ts +8 -0
- package/lib/tags.js +36 -0
- package/lib/utils.d.ts +2 -0
- package/lib/utils.js +17 -0
- package/lib/webapp/index.d.ts +3 -0
- package/lib/webapp/index.js +10 -0
- package/lib/webapp/monitor.d.ts +187 -0
- package/lib/webapp/monitor.js +156 -0
- package/lib/webapp/security-headers.d.ts +38 -0
- package/lib/webapp/security-headers.js +129 -0
- package/lib/webapp/webapp.d.ts +116 -0
- package/lib/webapp/webapp.js +118 -0
- package/lib/webapp-deploy-via-role.d.ts +25 -0
- package/lib/webapp-deploy-via-role.js +32 -0
- package/package.json +3 -2
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import * as cdk from "aws-cdk-lib";
|
|
2
|
+
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
|
|
3
|
+
import * as cognito from "aws-cdk-lib/aws-cognito";
|
|
4
|
+
import * as iam from "aws-cdk-lib/aws-iam";
|
|
5
|
+
import * as rum from "aws-cdk-lib/aws-rum";
|
|
6
|
+
import * as constructs from "constructs";
|
|
7
|
+
type CwRumTelemetries = ("http" | "performance" | "errors")[];
|
|
8
|
+
type EventsAlarm = {
|
|
9
|
+
/**
|
|
10
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
11
|
+
*/
|
|
12
|
+
action?: cloudwatch.IAlarmAction;
|
|
13
|
+
/**
|
|
14
|
+
* The threshold defined as the number of CloudWatch RUM events that determines if the alarm should trigger or not.
|
|
15
|
+
* @default 1000
|
|
16
|
+
*/
|
|
17
|
+
threshold?: number;
|
|
18
|
+
/**
|
|
19
|
+
* @default 1
|
|
20
|
+
*/
|
|
21
|
+
evaluationPeriods?: number;
|
|
22
|
+
/**
|
|
23
|
+
* @default cdk.Duration.minutes(1)
|
|
24
|
+
*/
|
|
25
|
+
period?: cdk.Duration;
|
|
26
|
+
/**
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
enableOkAlarm?: boolean;
|
|
30
|
+
};
|
|
31
|
+
type ErrorsAlarm = {
|
|
32
|
+
/**
|
|
33
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
34
|
+
*/
|
|
35
|
+
action?: cloudwatch.IAlarmAction;
|
|
36
|
+
/**
|
|
37
|
+
* The threshold defined as the number of JavaScript errors recorded by CloudWatch RUM that determines if the alarm should trigger or not.
|
|
38
|
+
* @default 0
|
|
39
|
+
*/
|
|
40
|
+
threshold?: number;
|
|
41
|
+
/**
|
|
42
|
+
* @default 1
|
|
43
|
+
*/
|
|
44
|
+
evaluationPeriods?: number;
|
|
45
|
+
/**
|
|
46
|
+
* @default cdk.Duration.minutes(1)
|
|
47
|
+
*/
|
|
48
|
+
period?: cdk.Duration;
|
|
49
|
+
/**
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
enableOkAlarms: boolean;
|
|
53
|
+
};
|
|
54
|
+
interface WebappMonitorProps {
|
|
55
|
+
/**
|
|
56
|
+
* The name of the CloudWatch RUM App Monitor.
|
|
57
|
+
*
|
|
58
|
+
* NOTE: This name needs to be unique within a given AWS region.
|
|
59
|
+
*/
|
|
60
|
+
appMonitorName: string;
|
|
61
|
+
/**
|
|
62
|
+
* The domain the web application to monitor is served on.
|
|
63
|
+
*
|
|
64
|
+
* Only web applications served on this domain can publish data to CloudWatch RUM.
|
|
65
|
+
*/
|
|
66
|
+
webappDomainName: string;
|
|
67
|
+
/**
|
|
68
|
+
* Which telemetries to allow CloudWatch RUM to collect.
|
|
69
|
+
*
|
|
70
|
+
* Currently these telemetries are supported:
|
|
71
|
+
* - "http" report the http fetch calles made by browser to CW RUM
|
|
72
|
+
* - "errors" report the js errors which occur, passed via rumConfig.recordError
|
|
73
|
+
* - "performance" report the app performance
|
|
74
|
+
*
|
|
75
|
+
* @default: ["errors", "http", "performance"]
|
|
76
|
+
*/
|
|
77
|
+
telemetries?: CwRumTelemetries;
|
|
78
|
+
/**
|
|
79
|
+
* The default CloudWatch alarm action to use.
|
|
80
|
+
*
|
|
81
|
+
* By default, an alarm is created for a high number of events being sent to CloudWatch RUM. This alarm action is used for the default alarm,
|
|
82
|
+
* and for other alarms if no other action is explicitly set when configuring or enabling alarms through this construct.
|
|
83
|
+
*
|
|
84
|
+
*/
|
|
85
|
+
defaultAlarmAction: cloudwatch.IAlarmAction;
|
|
86
|
+
/**
|
|
87
|
+
* Allow CloudWatch RUM to record custom events.
|
|
88
|
+
*
|
|
89
|
+
* These events need to be defined in and sent from your web application.
|
|
90
|
+
*
|
|
91
|
+
* @default false
|
|
92
|
+
*/
|
|
93
|
+
enableXRay?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Allow CloudWatch RUM to use cookies.
|
|
96
|
+
*
|
|
97
|
+
* CloudWatch RUM does not require cookies in order to record errors, but some features require cookies to be enabled.
|
|
98
|
+
* @default false
|
|
99
|
+
*/
|
|
100
|
+
enableCustomEvents?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Allow CloudWatch RUM to use cookies.
|
|
103
|
+
*
|
|
104
|
+
* CloudWatch RUM does not require cookies in order to record errors, but some features require cookies to be enabled.
|
|
105
|
+
*
|
|
106
|
+
* See: https://aws.amazon.com/blogs/mt/how-and-when-to-enable-session-cookies-with-amazon-cloudwatch-rum/
|
|
107
|
+
*
|
|
108
|
+
* NOTE: You'll likely need to introduce a cookie consent popup in your web application
|
|
109
|
+
* before enabling cookies in your client-side configuration.
|
|
110
|
+
*
|
|
111
|
+
* @default true
|
|
112
|
+
*/
|
|
113
|
+
allowCookies?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* The rate of client-side CloudWatch RUM sessions to sample.
|
|
116
|
+
*
|
|
117
|
+
* Values are between 0 and 1, where 1 is 100% of sessions.
|
|
118
|
+
*
|
|
119
|
+
* NOTE: You'll likely want to set this to a number below 1 in production environments with
|
|
120
|
+
* a lot of traffic.
|
|
121
|
+
*
|
|
122
|
+
* @default 1
|
|
123
|
+
*/
|
|
124
|
+
sessionSampleRate?: number;
|
|
125
|
+
/**
|
|
126
|
+
*
|
|
127
|
+
* Whether to store a copy of CloudWatch RUM events in CloudWatch Logs.
|
|
128
|
+
*
|
|
129
|
+
* Enabling this can improve the ergonomics of finding relevant CloudWatch RUM events compared to
|
|
130
|
+
* using the CloudWatch RUM console as it makes it possible to search using CloudWatch Logs Insights etc.
|
|
131
|
+
*
|
|
132
|
+
* @default false
|
|
133
|
+
*/
|
|
134
|
+
exportLogs?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Override top-level properties for the rum.CfnAppMonitor construct
|
|
137
|
+
*
|
|
138
|
+
* @default - no overrides are used.
|
|
139
|
+
*/
|
|
140
|
+
overrideAppMonitorProps?: Partial<rum.CfnAppMonitorProps>;
|
|
141
|
+
/**
|
|
142
|
+
* Override App Monitor configuration properties for the rum.CfnAppMonitor construct
|
|
143
|
+
*
|
|
144
|
+
* @default - no overrides are used.
|
|
145
|
+
*/
|
|
146
|
+
overrideAppMonitorConfiguration?: Partial<rum.CfnAppMonitor.AppMonitorConfigurationProperty>;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* A construct for creating a CloudWatch Real User Monitoring (RUM) App Monitor.
|
|
150
|
+
*
|
|
151
|
+
* An app monitor allows you to centrally collect and view client-side data (JavaScript and HTTP errors, performance metrics, etc.)
|
|
152
|
+
* recorded from a web application.
|
|
153
|
+
*
|
|
154
|
+
* NOTE: You'll need to add a JavaScript snippet to your web application and configure CloudWatch RUM using
|
|
155
|
+
* AWS's client-side SDK after deploying the construct to enable your web application to start collecting data.
|
|
156
|
+
* The App Monitor controls which CloudWatch RUM functionality the web application can use, and in order to
|
|
157
|
+
* leverage given functionality you'll need to configure it both in the App Monitor as well as in the
|
|
158
|
+
* configuration of the client-side SDK used by your web application.
|
|
159
|
+
*
|
|
160
|
+
*/
|
|
161
|
+
export declare class WebappMonitor extends constructs.Construct {
|
|
162
|
+
readonly identityPool: cognito.CfnIdentityPool;
|
|
163
|
+
readonly guestRole: iam.IRole;
|
|
164
|
+
readonly appMonitor: rum.CfnAppMonitor;
|
|
165
|
+
private readonly _webappDomainName;
|
|
166
|
+
private readonly _defaultAlarmAction;
|
|
167
|
+
private _eventsAlarm;
|
|
168
|
+
private _eventsAlarmId;
|
|
169
|
+
constructor(scope: constructs.Construct, id: string, props: WebappMonitorProps);
|
|
170
|
+
/**
|
|
171
|
+
*
|
|
172
|
+
* Configure an alarm used to notify on an unexpectedly high number of CloudWatch RUM events being recorded.
|
|
173
|
+
*
|
|
174
|
+
* This alarm is required when using this construct.
|
|
175
|
+
*
|
|
176
|
+
* @default - an alarm is created with sane defaults.
|
|
177
|
+
*
|
|
178
|
+
*/
|
|
179
|
+
configureEventsAlarm(props?: EventsAlarm): void;
|
|
180
|
+
private _createEventsAlarm;
|
|
181
|
+
/**
|
|
182
|
+
* Add an alarm that alerts on JavaScript errors
|
|
183
|
+
* sent to CloudWatch RUM.
|
|
184
|
+
*/
|
|
185
|
+
addErrorsAlarm(props?: ErrorsAlarm): void;
|
|
186
|
+
}
|
|
187
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebappMonitor = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
|
|
6
|
+
const cognito = require("aws-cdk-lib/aws-cognito");
|
|
7
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
8
|
+
const rum = require("aws-cdk-lib/aws-rum");
|
|
9
|
+
const constructs = require("constructs");
|
|
10
|
+
/**
|
|
11
|
+
* A construct for creating a CloudWatch Real User Monitoring (RUM) App Monitor.
|
|
12
|
+
*
|
|
13
|
+
* An app monitor allows you to centrally collect and view client-side data (JavaScript and HTTP errors, performance metrics, etc.)
|
|
14
|
+
* recorded from a web application.
|
|
15
|
+
*
|
|
16
|
+
* NOTE: You'll need to add a JavaScript snippet to your web application and configure CloudWatch RUM using
|
|
17
|
+
* AWS's client-side SDK after deploying the construct to enable your web application to start collecting data.
|
|
18
|
+
* The App Monitor controls which CloudWatch RUM functionality the web application can use, and in order to
|
|
19
|
+
* leverage given functionality you'll need to configure it both in the App Monitor as well as in the
|
|
20
|
+
* configuration of the client-side SDK used by your web application.
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
class WebappMonitor extends constructs.Construct {
|
|
24
|
+
constructor(scope, id, props) {
|
|
25
|
+
var _a, _b, _c, _d, _e;
|
|
26
|
+
super(scope, id);
|
|
27
|
+
this._eventsAlarmId = "EventsAlarm";
|
|
28
|
+
if (props.sessionSampleRate &&
|
|
29
|
+
(props.sessionSampleRate < 0 || props.sessionSampleRate > 1)) {
|
|
30
|
+
throw new Error("sessionSampleRate needs to be a number between 0 and 1");
|
|
31
|
+
}
|
|
32
|
+
this._webappDomainName = props.webappDomainName;
|
|
33
|
+
const appMonitorName = props.appMonitorName;
|
|
34
|
+
this.identityPool = new cognito.CfnIdentityPool(this, "RumIdentityPool", {
|
|
35
|
+
allowUnauthenticatedIdentities: true,
|
|
36
|
+
});
|
|
37
|
+
this.guestRole = new iam.Role(this, "RumRole", {
|
|
38
|
+
assumedBy: new iam.WebIdentityPrincipal("cognito-identity.amazonaws.com", {
|
|
39
|
+
StringEquals: {
|
|
40
|
+
"cognito-identity.amazonaws.com:aud": this.identityPool.ref,
|
|
41
|
+
},
|
|
42
|
+
"ForAnyValue:StringEquals": {
|
|
43
|
+
"cognito-identity.amazonaws.com:amr": "unauthenticated",
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
inlinePolicies: {
|
|
47
|
+
"allow-rum": new iam.PolicyDocument({
|
|
48
|
+
statements: [
|
|
49
|
+
new iam.PolicyStatement({
|
|
50
|
+
actions: ["rum:PutRumEvents"],
|
|
51
|
+
resources: [
|
|
52
|
+
cdk.Stack.of(this).formatArn({
|
|
53
|
+
service: "rum",
|
|
54
|
+
resource: "appmonitor",
|
|
55
|
+
resourceName: appMonitorName,
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
}),
|
|
59
|
+
],
|
|
60
|
+
}),
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
// attach role to identity pool
|
|
64
|
+
new cognito.CfnIdentityPoolRoleAttachment(this, "RoleAttachment", {
|
|
65
|
+
identityPoolId: this.identityPool.ref,
|
|
66
|
+
roles: {
|
|
67
|
+
unauthenticated: this.guestRole.roleArn,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
this.appMonitor = new rum.CfnAppMonitor(this, "AppMonitor", {
|
|
71
|
+
name: appMonitorName,
|
|
72
|
+
domain: props.webappDomainName,
|
|
73
|
+
cwLogEnabled: (_a = props.exportLogs) !== null && _a !== void 0 ? _a : false,
|
|
74
|
+
appMonitorConfiguration: {
|
|
75
|
+
enableXRay: (_b = props.enableXRay) !== null && _b !== void 0 ? _b : false,
|
|
76
|
+
allowCookies: (_c = props.allowCookies) !== null && _c !== void 0 ? _c : true,
|
|
77
|
+
telemetries: (_d = props.telemetries) !== null && _d !== void 0 ? _d : ["errors", "http", "performance"],
|
|
78
|
+
sessionSampleRate: (_e = props.sessionSampleRate) !== null && _e !== void 0 ? _e : 1,
|
|
79
|
+
identityPoolId: this.identityPool.ref,
|
|
80
|
+
guestRoleArn: this.guestRole.roleArn,
|
|
81
|
+
...props.overrideAppMonitorConfiguration,
|
|
82
|
+
},
|
|
83
|
+
customEvents: {
|
|
84
|
+
status: props.enableCustomEvents ? "ENABLED" : "DISABLED",
|
|
85
|
+
},
|
|
86
|
+
...props.overrideAppMonitorProps,
|
|
87
|
+
});
|
|
88
|
+
this._defaultAlarmAction = props.defaultAlarmAction;
|
|
89
|
+
this._eventsAlarm = this._createEventsAlarm();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
*
|
|
93
|
+
* Configure an alarm used to notify on an unexpectedly high number of CloudWatch RUM events being recorded.
|
|
94
|
+
*
|
|
95
|
+
* This alarm is required when using this construct.
|
|
96
|
+
*
|
|
97
|
+
* @default - an alarm is created with sane defaults.
|
|
98
|
+
*
|
|
99
|
+
*/
|
|
100
|
+
configureEventsAlarm(props) {
|
|
101
|
+
this.node.tryRemoveChild(this._eventsAlarmId);
|
|
102
|
+
this._eventsAlarm = this._createEventsAlarm(props);
|
|
103
|
+
}
|
|
104
|
+
_createEventsAlarm(props) {
|
|
105
|
+
var _a, _b, _c, _d, _e, _f;
|
|
106
|
+
const eventsAlarm = new cloudwatch.Metric({
|
|
107
|
+
metricName: "RumEventPayloadSize",
|
|
108
|
+
namespace: "AWS/RUM",
|
|
109
|
+
statistic: cloudwatch.Stats.SAMPLE_COUNT,
|
|
110
|
+
period: (_a = props === null || props === void 0 ? void 0 : props.period) !== null && _a !== void 0 ? _a : cdk.Duration.seconds(60),
|
|
111
|
+
dimensionsMap: {
|
|
112
|
+
application_name: this.appMonitor.name,
|
|
113
|
+
},
|
|
114
|
+
}).createAlarm(this, this._eventsAlarmId, {
|
|
115
|
+
alarmDescription: `A high number of events are being sent to CloudWatch RUM for app monitor '${this.appMonitor.name}'. This may lead to high costs, so you'll likely want to investigate this.`,
|
|
116
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
117
|
+
threshold: (_b = props === null || props === void 0 ? void 0 : props.threshold) !== null && _b !== void 0 ? _b : 1000,
|
|
118
|
+
evaluationPeriods: (_c = props === null || props === void 0 ? void 0 : props.evaluationPeriods) !== null && _c !== void 0 ? _c : 1,
|
|
119
|
+
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
|
|
120
|
+
});
|
|
121
|
+
// These alarms are mandatory as costs should be mandator to monitor
|
|
122
|
+
eventsAlarm.addAlarmAction((_d = props === null || props === void 0 ? void 0 : props.action) !== null && _d !== void 0 ? _d : this._defaultAlarmAction);
|
|
123
|
+
if ((_e = props === null || props === void 0 ? void 0 : props.enableOkAlarm) !== null && _e !== void 0 ? _e : false) {
|
|
124
|
+
eventsAlarm.addOkAction((_f = props === null || props === void 0 ? void 0 : props.action) !== null && _f !== void 0 ? _f : this._defaultAlarmAction);
|
|
125
|
+
}
|
|
126
|
+
return eventsAlarm;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Add an alarm that alerts on JavaScript errors
|
|
130
|
+
* sent to CloudWatch RUM.
|
|
131
|
+
*/
|
|
132
|
+
addErrorsAlarm(props) {
|
|
133
|
+
var _a, _b, _c, _d, _e, _f;
|
|
134
|
+
const errorsAlarm = new cloudwatch.Metric({
|
|
135
|
+
metricName: "JsErrorCount",
|
|
136
|
+
namespace: "AWS/RUM",
|
|
137
|
+
statistic: cloudwatch.Stats.SAMPLE_COUNT,
|
|
138
|
+
period: (_a = props === null || props === void 0 ? void 0 : props.period) !== null && _a !== void 0 ? _a : cdk.Duration.seconds(60),
|
|
139
|
+
dimensionsMap: {
|
|
140
|
+
application_name: this.appMonitor.name,
|
|
141
|
+
},
|
|
142
|
+
}).createAlarm(this, "RumJsErrorsAlarm", {
|
|
143
|
+
alarmDescription: `CloudWatch RUM has recorded JavaScript errors for app monitor '${this.appMonitor.name}' on domain '${this._webappDomainName}'`,
|
|
144
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
145
|
+
threshold: (_b = props === null || props === void 0 ? void 0 : props.threshold) !== null && _b !== void 0 ? _b : 0,
|
|
146
|
+
evaluationPeriods: (_c = props === null || props === void 0 ? void 0 : props.evaluationPeriods) !== null && _c !== void 0 ? _c : 1,
|
|
147
|
+
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
|
|
148
|
+
});
|
|
149
|
+
errorsAlarm.addAlarmAction((_d = props === null || props === void 0 ? void 0 : props.action) !== null && _d !== void 0 ? _d : this._defaultAlarmAction);
|
|
150
|
+
if ((_e = props === null || props === void 0 ? void 0 : props.enableOkAlarms) !== null && _e !== void 0 ? _e : false) {
|
|
151
|
+
errorsAlarm.addOkAction((_f = props === null || props === void 0 ? void 0 : props.action) !== null && _f !== void 0 ? _f : this._defaultAlarmAction);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.WebappMonitor = WebappMonitor;
|
|
156
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9uaXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93ZWJhcHAvbW9uaXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBa0M7QUFDbEMseURBQXdEO0FBQ3hELG1EQUFrRDtBQUNsRCwyQ0FBMEM7QUFDMUMsMkNBQTBDO0FBQzFDLHlDQUF3QztBQW1KeEM7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBYSxhQUFjLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFXckQsWUFDRSxLQUEyQixFQUMzQixFQUFVLEVBQ1YsS0FBeUI7O1FBRXpCLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFQVixtQkFBYyxHQUFHLGFBQWEsQ0FBQTtRQVNwQyxJQUNFLEtBQUssQ0FBQyxpQkFBaUI7WUFDdkIsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUMsRUFDNUQsQ0FBQztZQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsd0RBQXdELENBQUMsQ0FBQTtRQUMzRSxDQUFDO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQTtRQUUvQyxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFBO1FBRTNDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxpQkFBaUIsRUFBRTtZQUN2RSw4QkFBOEIsRUFBRSxJQUFJO1NBQ3JDLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDN0MsU0FBUyxFQUFFLElBQUksR0FBRyxDQUFDLG9CQUFvQixDQUNyQyxnQ0FBZ0MsRUFDaEM7Z0JBQ0UsWUFBWSxFQUFFO29CQUNaLG9DQUFvQyxFQUFFLElBQUksQ0FBQyxZ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LCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCJcbmltcG9ydCAqIGFzIGNvZ25pdG8gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jb2duaXRvXCJcbmltcG9ydCAqIGFzIGlhbSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiXG5pbXBvcnQgKiBhcyBydW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1ydW1cIlxuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tIFwiY29uc3RydWN0c1wiXG5cbnR5cGUgQ3dSdW1UZWxlbWV0cmllcyA9IChcImh0dHBcIiB8IFwicGVyZm9ybWFuY2VcIiB8IFwiZXJyb3JzXCIpW11cblxudHlwZSBFdmVudHNBbGFybSA9IHtcbiAgLyoqXG4gICAqIEFuIGFjdGlvbiB0byB1c2UgZm9yIENsb3VkV2F0Y2ggYWxhcm0gc3RhdGUgY2hhbmdlcyBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IGFjdGlvblxuICAgKi9cbiAgYWN0aW9uPzogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb25cbiAgLyoqXG4gICAqIFRoZSB0aHJlc2hvbGQgZGVmaW5lZCBhcyB0aGUgbnVtYmVyIG9mIENsb3VkV2F0Y2ggUlVNIGV2ZW50cyB0aGF0IGRldGVybWluZXMgaWYgdGhlIGFsYXJtIHNob3VsZCB0cmlnZ2VyIG9yIG5vdC5cbiAgICogQGRlZmF1bHQgMTAwMFxuICAgKi9cbiAgdGhyZXNob2xkPzogbnVtYmVyXG4gIC8qKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICBldmFsdWF0aW9uUGVyaW9kcz86IG51bWJlclxuICAvKipcbiAgICogQGRlZmF1bHQgY2RrLkR1cmF0aW9uLm1pbnV0ZXMoMSlcbiAgICovXG4gIHBlcmlvZD86IGNkay5EdXJhdGlvblxuICAvKipcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGVuYWJsZU9rQWxhcm0/OiBib29sZWFuXG59XG5cbnR5cGUgRXJyb3JzQWxhcm0gPSB7XG4gIC8qKlxuICAgKiBBbiBhY3Rpb24gdG8gdXNlIGZvciBDbG91ZFdhdGNoIGFsYXJtIHN0YXRlIGNoYW5nZXMgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBhY3Rpb25cbiAgICovXG4gIGFjdGlvbj86IGNsb3Vkd2F0Y2guSUFsYXJtQWN0aW9uXG4gIC8qKlxuICAgKiBUaGUgdGhyZXNob2xkIGRlZmluZWQgYXMgdGhlIG51bWJlciBvZiBKYXZhU2NyaXB0IGVycm9ycyByZWNvcmRlZCBieSBDbG91ZFdhdGNoIFJVTSB0aGF0IGRldGVybWluZXMgaWYgdGhlIGFsYXJtIHNob3VsZCB0cmlnZ2VyIG9yIG5vdC5cbiAgICogQGRlZmF1bHQgMFxuICAgKi9cbiAgdGhyZXNob2xkPzogbnVtYmVyXG4gIC8qKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICBldmFsdWF0aW9uUGVyaW9kcz86IG51bWJlclxuICAvKipcbiAgICogQGRlZmF1bHQgY2RrLkR1cmF0aW9uLm1pbnV0ZXMoMSlcbiAgICovXG4gIHBlcmlvZD86IGNkay5EdXJhdGlvblxuICAvKipcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGVuYWJsZU9rQWxhcm1zOiBib29sZWFuXG59XG5cbmludGVyZmFjZSBXZWJhcHBNb25pdG9yUHJvcHMge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIENsb3VkV2F0Y2ggUlVNIEFwcCBNb25pdG9yLlxuICAgKlxuICAgKiBOT1RFOiBUaGlzIG5hbWUgbmVlZHMgdG8gYmUgdW5pcXVlIHdpdGhpbiBhIGdpdmVuIEFXUyByZWdpb24uXG4gICAqL1xuICBhcHBNb25pdG9yTmFtZTogc3RyaW5nXG4gIC8qKlxuICAgKiBUaGUgZG9tYWluIHRoZSB3ZWIgYXBwbGljYXRpb24gdG8gbW9uaXRvciBpcyBzZXJ2ZWQgb24uXG4gICAqXG4gICAqIE9ubHkgd2ViIGFwcGxpY2F0aW9ucyBzZXJ2ZWQgb24gdGhpcyBkb21haW4gY2FuIHB1Ymxpc2ggZGF0YSB0byBDbG91ZFdhdGNoIFJVTS5cbiAgICovXG4gIHdlYmFwcERvbWFpbk5hbWU6IHN0cmluZ1xuICAvKipcbiAgICogV2hpY2ggdGVsZW1ldHJpZXMgdG8gYWxsb3cgQ2xvdWRXYXRjaCBSVU0gdG8gY29sbGVjdC5cbiAgICpcbiAgICogQ3VycmVudGx5IHRoZXNlIHRlbGVtZXRyaWVzIGFyZSBzdXBwb3J0ZWQ6XG4gICAqIC0gXCJodHRwXCIgcmVwb3J0IHRoZSBodHRwIGZldGNoIGNhbGxlcyBtYWRlIGJ5IGJyb3dzZXIgdG8gQ1cgUlVNXG4gICAqIC0gXCJlcnJvcnNcIiByZXBvcnQgdGhlIGpzIGVycm9ycyB3aGljaCBvY2N1ciwgcGFzc2VkIHZpYSBydW1Db25maWcucmVjb3JkRXJyb3JcbiAgICogLSBcInBlcmZvcm1hbmNlXCIgcmVwb3J0IHRoZSBhcHAgcGVyZm9ybWFuY2VcbiAgICpcbiAgICogQGRlZmF1bHQ6IFtcImVycm9yc1wiLCBcImh0dHBcIiwgXCJwZXJmb3JtYW5jZVwiXVxuICAgKi9cbiAgdGVsZW1ldHJpZXM/OiBDd1J1bVRlbGVtZXRyaWVzXG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBDbG91ZFdhdGNoIGFsYXJtIGFjdGlvbiB0byB1c2UuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGFuIGFsYXJtIGlzIGNyZWF0ZWQgZm9yIGEgaGlnaCBudW1iZXIgb2YgZXZlbnRzIGJlaW5nIHNlbnQgdG8gQ2xvdWRXYXRjaCBSVU0uIFRoaXMgYWxhcm0gYWN0aW9uIGlzIHVzZWQgZm9yIHRoZSBkZWZhdWx0IGFsYXJtLFxuICAgKiBhbmQgZm9yIG90aGVyIGFsYXJtcyBpZiBubyBvdGhlciBhY3Rpb24gaXMgZXhwbGljaXRseSBzZXQgd2hlbiBjb25maWd1cmluZyBvciBlbmFibGluZyBhbGFybXMgdGhyb3VnaCB0aGlzIGNvbnN0cnVjdC5cbiAgICpcbiAgICovXG4gIGRlZmF1bHRBbGFybUFjdGlvbjogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb25cbiAgLyoqXG4gICAqIEFsbG93IENsb3VkV2F0Y2ggUlVNIHRvIHJlY29yZCBjdXN0b20gZXZlbnRzLlxuICAgKlxuICAgKiBUaGVzZSBldmVudHMgbmVlZCB0byBiZSBkZWZpbmVkIGluIGFuZCBzZW50IGZyb20geW91ciB3ZWIgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBlbmFibGVYUmF5PzogYm9vbGVhblxuICAvKipcbiAgICogQWxsb3cgQ2xvdWRXYXRjaCBSVU0gdG8gdXNlIGNvb2tpZXMuXG4gICAqXG4gICAqIENsb3VkV2F0Y2ggUlVNIGRvZXMgbm90IHJlcXVpcmUgY29va2llcyBpbiBvcmRlciB0byByZWNvcmQgZXJyb3JzLCBidXQgc29tZSBmZWF0dXJlcyByZXF1aXJlIGNvb2tpZXMgdG8gYmUgZW5hYmxlZC5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGVuYWJsZUN1c3RvbUV2ZW50cz86IGJvb2xlYW5cbiAgLyoqXG4gICAqIEFsbG93IENsb3VkV2F0Y2ggUlVNIHRvIHVzZSBjb29raWVzLlxuICAgKlxuICAgKiBDbG91ZFdhdGNoIFJVTSBkb2VzIG5vdCByZXF1aXJlIGNvb2tpZXMgaW4gb3JkZXIgdG8gcmVjb3JkIGVycm9ycywgYnV0IHNvbWUgZmVhdHVyZXMgcmVxdWlyZSBjb29raWVzIHRvIGJlIGVuYWJsZWQuXG4gICAqXG4gICAqIFNlZTogaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9ibG9ncy9tdC9ob3ctYW5kLXdoZW4tdG8tZW5hYmxlLXNlc3Npb24tY29va2llcy13aXRoLWFtYXpvbi1jbG91ZHdhdGNoLXJ1bS9cbiAgICpcbiAgICogTk9URTogWW91J2xsIGxpa2VseSBuZWVkIHRvIGludHJvZHVjZSBhIGNvb2tpZSBjb25zZW50IHBvcHVwIGluIHlvdXIgd2ViIGFwcGxpY2F0aW9uXG4gICAqIGJlZm9yZSBlbmFibGluZyBjb29raWVzIGluIHlvdXIgY2xpZW50LXNpZGUgY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgYWxsb3dDb29raWVzPzogYm9vbGVhblxuICAvKipcbiAgICogVGhlIHJhdGUgb2YgY2xpZW50LXNpZGUgQ2xvdWRXYXRjaCBSVU0gc2Vzc2lvbnMgdG8gc2FtcGxlLlxuICAgKlxuICAgKiBWYWx1ZXMgYXJlIGJldHdlZW4gMCBhbmQgMSwgd2hlcmUgMSBpcyAxMDAlIG9mIHNlc3Npb25zLlxuICAgKlxuICAgKiBOT1RFOiBZb3UnbGwgbGlrZWx5IHdhbnQgdG8gc2V0IHRoaXMgdG8gYSBudW1iZXIgYmVsb3cgMSBpbiBwcm9kdWN0aW9uIGVudmlyb25tZW50cyB3aXRoXG4gICAqIGEgbG90IG9mIHRyYWZmaWMuXG4gICAqXG4gICAqIEBkZWZhdWx0IDFcbiAgICovXG4gIHNlc3Npb25TYW1wbGVSYXRlPzogbnVtYmVyXG4gIC8qKlxuICAgKlxuICAgKiBXaGV0aGVyIHRvIHN0b3JlIGEgY29weSBvZiBDbG91ZFdhdGNoIFJVTSBldmVudHMgaW4gQ2xvdWRXYXRjaCBMb2dzLlxuICAgKlxuICAgKiBFbmFibGluZyB0aGlzIGNhbiBpbXByb3ZlIHRoZSBlcmdvbm9taWNzIG9mIGZpbmRpbmcgcmVsZXZhbnQgQ2xvdWRXYXRjaCBSVU0gZXZlbnRzIGNvbXBhcmVkIHRvXG4gICAqIHVzaW5nIHRoZSBDbG91ZFdhdGNoIFJVTSBjb25zb2xlIGFzIGl0IG1ha2VzIGl0IHBvc3NpYmxlIHRvIHNlYXJjaCB1c2luZyBDbG91ZFdhdGNoIExvZ3MgSW5zaWdodHMgZXRjLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgZXhwb3J0TG9ncz86IGJvb2xlYW5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRvcC1sZXZlbCBwcm9wZXJ0aWVzIGZvciB0aGUgcnVtLkNmbkFwcE1vbml0b3IgY29uc3RydWN0XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gb3ZlcnJpZGVzIGFyZSB1c2VkLlxuICAgKi9cbiAgb3ZlcnJpZGVBcHBNb25pdG9yUHJvcHM/OiBQYXJ0aWFsPHJ1bS5DZm5BcHBNb25pdG9yUHJvcHM+XG4gIC8qKlxuICAgKiBPdmVycmlkZSBBcHAgTW9uaXRvciBjb25maWd1cmF0aW9uIHByb3BlcnRpZXMgZm9yIHRoZSBydW0uQ2ZuQXBwTW9uaXRvciBjb25zdHJ1Y3RcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBvdmVycmlkZXMgYXJlIHVzZWQuXG4gICAqL1xuICBvdmVycmlkZUFwcE1vbml0b3JDb25maWd1cmF0aW9uPzogUGFydGlhbDxydW0uQ2ZuQXBwTW9uaXRvci5BcHBNb25pdG9yQ29uZmlndXJhdGlvblByb3BlcnR5PlxufVxuXG4vKipcbiAqICBBIGNvbnN0cnVjdCBmb3IgY3JlYXRpbmcgYSBDbG91ZFdhdGNoIFJlYWwgVXNlciBNb25pdG9yaW5nIChSVU0pIEFwcCBNb25pdG9yLlxuICpcbiAqIEFuIGFwcCBtb25pdG9yIGFsbG93cyB5b3UgdG8gY2VudHJhbGx5IGNvbGxlY3QgYW5kIHZpZXcgY2xpZW50LXNpZGUgZGF0YSAoSmF2YVNjcmlwdCBhbmQgSFRUUCBlcnJvcnMsIHBlcmZvcm1hbmNlIG1ldHJpY3MsIGV0Yy4pXG4gKiByZWNvcmRlZCBmcm9tIGEgd2ViIGFwcGxpY2F0aW9uLlxuICpcbiAqIE5PVEU6IFlvdSdsbCBuZWVkIHRvIGFkZCBhIEphdmFTY3JpcHQgc25pcHBldCB0byB5b3VyIHdlYiBhcHBsaWNhdGlvbiBhbmQgY29uZmlndXJlIENsb3VkV2F0Y2ggUlVNIHVzaW5nXG4gKiBBV1MncyBjbGllbnQtc2lkZSBTREsgYWZ0ZXIgZGVwbG95aW5nIHRoZSBjb25zdHJ1Y3QgdG8gZW5hYmxlIHlvdXIgd2ViIGFwcGxpY2F0aW9uIHRvIHN0YXJ0IGNvbGxlY3RpbmcgZGF0YS5cbiAqIFRoZSBBcHAgTW9uaXRvciBjb250cm9scyB3aGljaCBDbG91ZFdhdGNoIFJVTSBmdW5jdGlvbmFsaXR5IHRoZSB3ZWIgYXBwbGljYXRpb24gY2FuIHVzZSwgYW5kIGluIG9yZGVyIHRvXG4gKiBsZXZlcmFnZSBnaXZlbiBmdW5jdGlvbmFsaXR5IHlvdSdsbCBuZWVkIHRvIGNvbmZpZ3VyZSBpdCBib3RoIGluIHRoZSBBcHAgTW9uaXRvciBhcyB3ZWxsIGFzIGluIHRoZVxuICogY29uZmlndXJhdGlvbiBvZiB0aGUgY2xpZW50LXNpZGUgU0RLIHVzZWQgYnkgeW91ciB3ZWIgYXBwbGljYXRpb24uXG4gKlxuICovXG5leHBvcnQgY2xhc3MgV2ViYXBwTW9uaXRvciBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgcmVhZG9ubHkgaWRlbnRpdHlQb29sOiBjb2duaXRvLkNmbklkZW50aXR5UG9vbFxuICByZWFkb25seSBndWVzdFJvbGU6IGlhbS5JUm9sZVxuICByZWFkb25seSBhcHBNb25pdG9yOiBydW0uQ2ZuQXBwTW9uaXRvclxuICBwcml2YXRlIHJlYWRvbmx5IF93ZWJhcHBEb21haW5OYW1lOiBzdHJpbmdcblxuICBwcml2YXRlIHJlYWRvbmx5IF9kZWZhdWx0QWxhcm1BY3Rpb246IGNsb3Vkd2F0Y2guSUFsYXJtQWN0aW9uXG5cbiAgcHJpdmF0ZSBfZXZlbnRzQWxhcm06IGNsb3Vkd2F0Y2guSUFsYXJtXG4gIHByaXZhdGUgX2V2ZW50c0FsYXJtSWQgPSBcIkV2ZW50c0FsYXJtXCJcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogY29uc3RydWN0cy5Db25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogV2ViYXBwTW9uaXRvclByb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBpZiAoXG4gICAgICBwcm9wcy5zZXNzaW9uU2FtcGxlUmF0ZSAmJlxuICAgICAgKHByb3BzLnNlc3Npb25TYW1wbGVSYXRlIDwgMCB8fCBwcm9wcy5zZXNzaW9uU2FtcGxlUmF0ZSA+IDEpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZXNzaW9uU2FtcGxlUmF0ZSBuZWVkcyB0byBiZSBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDFcIilcbiAgICB9XG5cbiAgICB0aGlzLl93ZWJhcHBEb21haW5OYW1lID0gcHJvcHMud2ViYXBwRG9tYWluTmFtZVxuXG4gICAgY29uc3QgYXBwTW9uaXRvck5hbWUgPSBwcm9wcy5hcHBNb25pdG9yTmFtZVxuXG4gICAgdGhpcy5pZGVudGl0eVBvb2wgPSBuZXcgY29nbml0by5DZm5JZGVudGl0eVBvb2wodGhpcywgXCJSdW1JZGVudGl0eVBvb2xcIiwge1xuICAgICAgYWxsb3dVbmF1dGhlbnRpY2F0ZWRJZGVudGl0aWVzOiB0cnVlLFxuICAgIH0pXG5cbiAgICB0aGlzLmd1ZXN0Um9sZSA9IG5ldyBpYW0uUm9sZSh0aGlzLCBcIlJ1bVJvbGVcIiwge1xuICAgICAgYXNzdW1lZEJ5OiBuZXcgaWFtLldlYklkZW50aXR5UHJpbmNpcGFsKFxuICAgICAgICBcImNvZ25pdG8taWRlbnRpdHkuYW1hem9uYXdzLmNvbVwiLFxuICAgICAgICB7XG4gICAgICAgICAgU3RyaW5nRXF1YWxzOiB7XG4gICAgICAgICAgICBcImNvZ25pdG8taWRlbnRpdHkuYW1hem9uYXdzLmNvbTphdWRcIjogdGhpcy5pZGVudGl0eVBvb2wucmVmLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgXCJGb3JBbnlWYWx1ZTpTdHJpbmdFcXVhbHNcIjoge1xuICAgICAgICAgICAgXCJjb2duaXRvLWlkZW50aXR5LmFtYXpvbmF3cy5jb206YW1yXCI6IFwidW5hdXRoZW50aWNhdGVkXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICksXG4gICAgICBpbmxpbmVQb2xpY2llczoge1xuICAgICAgICBcImFsbG93LXJ1bVwiOiBuZXcgaWFtLlBvbGljeURvY3VtZW50KHtcbiAgICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAgIGFjdGlvbnM6IFtcInJ1bTpQdXRSdW1FdmVudHNcIl0sXG4gICAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICAgIGNkay5TdGFjay5vZih0aGlzKS5mb3JtYXRBcm4oe1xuICAgICAgICAgICAgICAgICAgc2VydmljZTogXCJydW1cIixcbiAgICAgICAgICAgICAgICAgIHJlc291cmNlOiBcImFwcG1vbml0b3JcIixcbiAgICAgICAgICAgICAgICAgIHJlc291cmNlTmFtZTogYXBwTW9uaXRvck5hbWUsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIC8vIGF0dGFjaCByb2xlIHRvIGlkZW50aXR5IHBvb2xcbiAgICBuZXcgY29nbml0by5DZm5JZGVudGl0eVBvb2xSb2xlQXR0YWNobWVudCh0aGlzLCBcIlJvbGVBdHRhY2htZW50XCIsIHtcbiAgICAgIGlkZW50aXR5UG9vbElkOiB0aGlzLmlkZW50aXR5UG9vbC5yZWYsXG4gICAgICByb2xlczoge1xuICAgICAgICB1bmF1dGhlbnRpY2F0ZWQ6IHRoaXMuZ3Vlc3RSb2xlLnJvbGVBcm4sXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICB0aGlzLmFwcE1vbml0b3IgPSBuZXcgcnVtLkNmbkFwcE1vbml0b3IodGhpcywgXCJBcHBNb25pdG9yXCIsIHtcbiAgICAgIG5hbWU6IGFwcE1vbml0b3JOYW1lLFxuICAgICAgZG9tYWluOiBwcm9wcy53ZWJhcHBEb21haW5OYW1lLFxuICAgICAgY3dMb2dFbmFibGVkOiBwcm9wcy5leHBvcnRMb2dzID8/IGZhbHNlLFxuICAgICAgYXBwTW9uaXRvckNvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgZW5hYmxlWFJheTogcHJvcHMuZW5hYmxlWFJheSA/PyBmYWxzZSxcbiAgICAgICAgYWxsb3dDb29raWVzOiBwcm9wcy5hbGxvd0Nvb2tpZXMgPz8gdHJ1ZSxcbiAgICAgICAgdGVsZW1ldHJpZXM6IHByb3BzLnRlbGVtZXRyaWVzID8/IFtcImVycm9yc1wiLCBcImh0dHBcIiwgXCJwZXJmb3JtYW5jZVwiXSxcbiAgICAgICAgc2Vzc2lvblNhbXBsZVJhdGU6IHByb3BzLnNlc3Npb25TYW1wbGVSYXRlID8/IDEsXG4gICAgICAgIGlkZW50aXR5UG9vbElkOiB0aGlzLmlkZW50aXR5UG9vbC5yZWYsXG4gICAgICAgIGd1ZXN0Um9sZUFybjogdGhpcy5ndWVzdFJvbGUucm9sZUFybixcbiAgICAgICAgLi4ucHJvcHMub3ZlcnJpZGVBcHBNb25pdG9yQ29uZmlndXJhdGlvbixcbiAgICAgIH0sXG4gICAgICBjdXN0b21FdmVudHM6IHtcbiAgICAgICAgc3RhdHVzOiBwcm9wcy5lbmFibGVDdXN0b21FdmVudHMgPyBcIkVOQUJMRURcIiA6IFwiRElTQUJMRURcIixcbiAgICAgIH0sXG4gICAgICAuLi5wcm9wcy5vdmVycmlkZUFwcE1vbml0b3JQcm9wcyxcbiAgICB9KVxuXG4gICAgdGhpcy5fZGVmYXVsdEFsYXJtQWN0aW9uID0gcHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uXG4gICAgdGhpcy5fZXZlbnRzQWxhcm0gPSB0aGlzLl9jcmVhdGVFdmVudHNBbGFybSgpXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQ29uZmlndXJlIGFuIGFsYXJtIHVzZWQgdG8gbm90aWZ5IG9uIGFuIHVuZXhwZWN0ZWRseSBoaWdoIG51bWJlciBvZiBDbG91ZFdhdGNoIFJVTSBldmVudHMgYmVpbmcgcmVjb3JkZWQuXG4gICAqXG4gICAqIFRoaXMgYWxhcm0gaXMgcmVxdWlyZWQgd2hlbiB1c2luZyB0aGlzIGNvbnN0cnVjdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhbiBhbGFybSBpcyBjcmVhdGVkIHdpdGggc2FuZSBkZWZhdWx0cy5cbiAgICpcbiAgICovXG4gIGNvbmZpZ3VyZUV2ZW50c0FsYXJtKHByb3BzPzogRXZlbnRzQWxhcm0pIHtcbiAgICB0aGlzLm5vZGUudHJ5UmVtb3ZlQ2hpbGQodGhpcy5fZXZlbnRzQWxhcm1JZClcbiAgICB0aGlzLl9ldmVudHNBbGFybSA9IHRoaXMuX2NyZWF0ZUV2ZW50c0FsYXJtKHByb3BzKVxuICB9XG5cbiAgcHJpdmF0ZSBfY3JlYXRlRXZlbnRzQWxhcm0ocHJvcHM/OiBFdmVudHNBbGFybSk6IGNsb3Vkd2F0Y2guSUFsYXJtIHtcbiAgICBjb25zdCBldmVudHNBbGFybSA9IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICBtZXRyaWNOYW1lOiBcIlJ1bUV2ZW50UGF5bG9hZFNpemVcIixcbiAgICAgIG5hbWVzcGFjZTogXCJBV1MvUlVNXCIsXG4gICAgICBzdGF0aXN0aWM6IGNsb3Vkd2F0Y2guU3RhdHMuU0FNUExFX0NPVU5ULFxuICAgICAgcGVyaW9kOiBwcm9wcz8ucGVyaW9kID8/IGNkay5EdXJhdGlvbi5zZWNvbmRzKDYwKSxcbiAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgYXBwbGljYXRpb25fbmFtZTogdGhpcy5hcHBNb25pdG9yLm5hbWUsXG4gICAgICB9LFxuICAgIH0pLmNyZWF0ZUFsYXJtKHRoaXMsIHRoaXMuX2V2ZW50c0FsYXJtSWQsIHtcbiAgICAgIGFsYXJtRGVzY3JpcHRpb246IGBBIGhpZ2ggbnVtYmVyIG9mIGV2ZW50cyBhcmUgYmVpbmcgc2VudCB0byBDbG91ZFdhdGNoIFJVTSBmb3IgYXBwIG1vbml0b3IgJyR7dGhpcy5hcHBNb25pdG9yLm5hbWV9Jy4gVGhpcyBtYXkgbGVhZCB0byBoaWdoIGNvc3RzLCBzbyB5b3UnbGwgbGlrZWx5IHdhbnQgdG8gaW52ZXN0aWdhdGUgdGhpcy5gLFxuICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBjbG91ZHdhdGNoLkNvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fVEhSRVNIT0xELFxuICAgICAgdGhyZXNob2xkOiBwcm9wcz8udGhyZXNob2xkID8/IDEwMDAsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kczogcHJvcHM/LmV2YWx1YXRpb25QZXJpb2RzID8/IDEsXG4gICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuTk9UX0JSRUFDSElORyxcbiAgICB9KVxuXG4gICAgLy8gVGhlc2UgYWxhcm1zIGFyZSBtYW5kYXRvcnkgYXMgY29zdHMgc2hvdWxkIGJlIG1hbmRhdG9yIHRvIG1vbml0b3JcbiAgICBldmVudHNBbGFybS5hZGRBbGFybUFjdGlvbihwcm9wcz8uYWN0aW9uID8/IHRoaXMuX2RlZmF1bHRBbGFybUFjdGlvbilcbiAgICBpZiAocHJvcHM/LmVuYWJsZU9rQWxhcm0gPz8gZmFsc2UpIHtcbiAgICAgIGV2ZW50c0FsYXJtLmFkZE9rQWN0aW9uKHByb3BzPy5hY3Rpb24gPz8gdGhpcy5fZGVmYXVsdEFsYXJtQWN0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiBldmVudHNBbGFybVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBhbGFybSB0aGF0IGFsZXJ0cyBvbiBKYXZhU2NyaXB0IGVycm9yc1xuICAgKiBzZW50IHRvIENsb3VkV2F0Y2ggUlVNLlxuICAgKi9cbiAgYWRkRXJyb3JzQWxhcm0ocHJvcHM/OiBFcnJvcnNBbGFybSkge1xuICAgIGNvbnN0IGVycm9yc0FsYXJtID0gbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgIG1ldHJpY05hbWU6IFwiSnNFcnJvckNvdW50XCIsXG4gICAgICBuYW1lc3BhY2U6IFwiQVdTL1JVTVwiLFxuICAgICAgc3RhdGlzdGljOiBjbG91ZHdhdGNoLlN0YXRzLlNBTVBMRV9DT1VOVCxcbiAgICAgIHBlcmlvZDogcHJvcHM/LnBlcmlvZCA/PyBjZGsuRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIGFwcGxpY2F0aW9uX25hbWU6IHRoaXMuYXBwTW9uaXRvci5uYW1lLFxuICAgICAgfSxcbiAgICB9KS5jcmVhdGVBbGFybSh0aGlzLCBcIlJ1bUpzRXJyb3JzQWxhcm1cIiwge1xuICAgICAgYWxhcm1EZXNjcmlwdGlvbjogYENsb3VkV2F0Y2ggUlVNIGhhcyByZWNvcmRlZCBKYXZhU2NyaXB0IGVycm9ycyBmb3IgYXBwIG1vbml0b3IgJyR7dGhpcy5hcHBNb25pdG9yLm5hbWV9JyBvbiBkb21haW4gJyR7dGhpcy5fd2ViYXBwRG9tYWluTmFtZX0nYCxcbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgIHRocmVzaG9sZDogcHJvcHM/LnRocmVzaG9sZCA/PyAwLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IHByb3BzPy5ldmFsdWF0aW9uUGVyaW9kcyA/PyAxLFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YTogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk5PVF9CUkVBQ0hJTkcsXG4gICAgfSlcblxuICAgIGVycm9yc0FsYXJtLmFkZEFsYXJtQWN0aW9uKHByb3BzPy5hY3Rpb24gPz8gdGhpcy5fZGVmYXVsdEFsYXJtQWN0aW9uKVxuXG4gICAgaWYgKHByb3BzPy5lbmFibGVPa0FsYXJtcyA/PyBmYWxzZSkge1xuICAgICAgZXJyb3JzQWxhcm0uYWRkT2tBY3Rpb24ocHJvcHM/LmFjdGlvbiA/PyB0aGlzLl9kZWZhdWx0QWxhcm1BY3Rpb24pXG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as constructs from "constructs";
|
|
2
|
+
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
|
|
3
|
+
export type WebappSecurityHeadersProps = Partial<cloudfront.ResponseSecurityHeadersBehavior & {
|
|
4
|
+
contentSecurityPolicy?: cloudfront.ResponseSecurityHeadersBehavior["contentSecurityPolicy"] & {
|
|
5
|
+
/**
|
|
6
|
+
* Whether to only monitor the effects of the content security policy without actually blocking anything.
|
|
7
|
+
* @default false
|
|
8
|
+
*/
|
|
9
|
+
reportOnly?: boolean;
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
export interface ContentSecurityPolicyHeader {
|
|
13
|
+
baseUri?: string;
|
|
14
|
+
childSrc?: string;
|
|
15
|
+
defaultSrc?: string;
|
|
16
|
+
fontSrc?: string;
|
|
17
|
+
frameSrc?: string;
|
|
18
|
+
formAction?: string;
|
|
19
|
+
frameAncestors?: string;
|
|
20
|
+
imgSrc?: string;
|
|
21
|
+
manifestSrc?: string;
|
|
22
|
+
mediaSrc?: string;
|
|
23
|
+
objectSrc?: string;
|
|
24
|
+
scriptSrc?: string;
|
|
25
|
+
styleSrc?: string;
|
|
26
|
+
connectSrc?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Helper function that generates a string containing a Content Security Policy that can be
|
|
30
|
+
* used in a security header.
|
|
31
|
+
*
|
|
32
|
+
* NOTE: The string can be further extended using string concatenation for directives that aren't currently supported by the function.
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateContentSecurityPolicyHeader(headerOptions?: ContentSecurityPolicyHeader): string;
|
|
35
|
+
export declare class WebappSecurityHeaders extends constructs.Construct {
|
|
36
|
+
readonly responseHeadersPolicy: cloudfront.ResponseHeadersPolicy;
|
|
37
|
+
constructor(scope: constructs.Construct, id: string, props: WebappSecurityHeadersProps);
|
|
38
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebappSecurityHeaders = exports.generateContentSecurityPolicyHeader = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const constructs = require("constructs");
|
|
6
|
+
const cloudfront = require("aws-cdk-lib/aws-cloudfront");
|
|
7
|
+
function validateCspParam(param) {
|
|
8
|
+
if (param.indexOf('"') !== -1) {
|
|
9
|
+
throw Error('CSP override contains invalid character "');
|
|
10
|
+
}
|
|
11
|
+
if (param.indexOf(";") !== -1) {
|
|
12
|
+
throw Error("CSP override contains invalid character ;");
|
|
13
|
+
}
|
|
14
|
+
if (param.indexOf("\\") !== -1) {
|
|
15
|
+
throw Error("CSP override contains invalid character \\");
|
|
16
|
+
}
|
|
17
|
+
return param;
|
|
18
|
+
}
|
|
19
|
+
/* Replace all whitespace in a string with a single space */
|
|
20
|
+
function trim(value) {
|
|
21
|
+
return value.replace(/\s+/g, " ").trim();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Helper function that generates a string containing a Content Security Policy that can be
|
|
25
|
+
* used in a security header.
|
|
26
|
+
*
|
|
27
|
+
* NOTE: The string can be further extended using string concatenation for directives that aren't currently supported by the function.
|
|
28
|
+
*/
|
|
29
|
+
function generateContentSecurityPolicyHeader(headerOptions) {
|
|
30
|
+
const defaultValues = {
|
|
31
|
+
baseUri: "'self'",
|
|
32
|
+
childSrc: "'self'",
|
|
33
|
+
connectSrc: "'self' https:",
|
|
34
|
+
defaultSrc: "'none'",
|
|
35
|
+
fontSrc: "'self'",
|
|
36
|
+
formAction: "'none'",
|
|
37
|
+
frameAncestors: "'none'",
|
|
38
|
+
frameSrc: "'self'",
|
|
39
|
+
imgSrc: "'self' data:",
|
|
40
|
+
manifestSrc: "'self'",
|
|
41
|
+
mediaSrc: "'self'",
|
|
42
|
+
objectSrc: "'none'",
|
|
43
|
+
scriptSrc: "'self'",
|
|
44
|
+
styleSrc: "'self'",
|
|
45
|
+
};
|
|
46
|
+
const options = {
|
|
47
|
+
...defaultValues,
|
|
48
|
+
...headerOptions,
|
|
49
|
+
};
|
|
50
|
+
Object.values(options).forEach((v) => typeof v === "string" && validateCspParam(v));
|
|
51
|
+
let headerValue = "";
|
|
52
|
+
headerValue += `base-uri ${trim(options.baseUri)};`;
|
|
53
|
+
headerValue += `child-src ${trim(options.childSrc)};`;
|
|
54
|
+
headerValue += `connect-src ${trim(options.connectSrc)};`;
|
|
55
|
+
headerValue += `default-src ${trim(options.defaultSrc)};`;
|
|
56
|
+
headerValue += `font-src ${trim(options.fontSrc)};`;
|
|
57
|
+
headerValue += `frame-src ${trim(options.frameSrc)};`;
|
|
58
|
+
headerValue += `form-action ${trim(options.formAction)};`;
|
|
59
|
+
headerValue += `frame-ancestors ${trim(options.frameAncestors)};`;
|
|
60
|
+
headerValue += `img-src ${trim(options.imgSrc)};`;
|
|
61
|
+
headerValue += `manifest-src ${trim(options.manifestSrc)};`;
|
|
62
|
+
headerValue += `media-src ${trim(options.mediaSrc)};`;
|
|
63
|
+
headerValue += `object-src ${trim(options.objectSrc)};`;
|
|
64
|
+
headerValue += `script-src ${trim(options.scriptSrc)};`;
|
|
65
|
+
headerValue += `style-src ${trim(options.styleSrc)}`;
|
|
66
|
+
return trim(headerValue);
|
|
67
|
+
}
|
|
68
|
+
exports.generateContentSecurityPolicyHeader = generateContentSecurityPolicyHeader;
|
|
69
|
+
class WebappSecurityHeaders extends constructs.Construct {
|
|
70
|
+
constructor(scope, id, props) {
|
|
71
|
+
super(scope, id);
|
|
72
|
+
const { contentSecurityPolicy: contentSecurityPolicyOverride, ...overrides } = props;
|
|
73
|
+
const contentSecurityPolicyCustomHeader = contentSecurityPolicyOverride || {
|
|
74
|
+
reportOnly: false,
|
|
75
|
+
contentSecurityPolicy: generateContentSecurityPolicyHeader(),
|
|
76
|
+
override: true,
|
|
77
|
+
};
|
|
78
|
+
const defaultValues = {
|
|
79
|
+
contentTypeOptions: {
|
|
80
|
+
override: true,
|
|
81
|
+
},
|
|
82
|
+
referrerPolicy: {
|
|
83
|
+
override: true,
|
|
84
|
+
referrerPolicy: cloudfront.HeadersReferrerPolicy.SAME_ORIGIN,
|
|
85
|
+
},
|
|
86
|
+
frameOptions: {
|
|
87
|
+
frameOption: cloudfront.HeadersFrameOption.DENY,
|
|
88
|
+
override: true,
|
|
89
|
+
},
|
|
90
|
+
strictTransportSecurity: {
|
|
91
|
+
override: true,
|
|
92
|
+
accessControlMaxAge: cdk.Duration.days(182.5),
|
|
93
|
+
includeSubdomains: false,
|
|
94
|
+
preload: false,
|
|
95
|
+
},
|
|
96
|
+
xssProtection: {
|
|
97
|
+
override: true,
|
|
98
|
+
protection: true,
|
|
99
|
+
modeBlock: true,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
this.responseHeadersPolicy = new cloudfront.ResponseHeadersPolicy(this, "ResponseHeadersPolicy", {
|
|
103
|
+
securityHeadersBehavior: {
|
|
104
|
+
...defaultValues,
|
|
105
|
+
...overrides,
|
|
106
|
+
...(!contentSecurityPolicyCustomHeader.reportOnly && {
|
|
107
|
+
contentSecurityPolicy: {
|
|
108
|
+
contentSecurityPolicy: contentSecurityPolicyCustomHeader.contentSecurityPolicy,
|
|
109
|
+
override: contentSecurityPolicyCustomHeader.override,
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
},
|
|
113
|
+
...(contentSecurityPolicyCustomHeader.reportOnly && {
|
|
114
|
+
customHeadersBehavior: {
|
|
115
|
+
// Report only is not supported by securityHeadersBehavior in AWS and must be defined as custom header
|
|
116
|
+
customHeaders: [
|
|
117
|
+
{
|
|
118
|
+
header: "Content-Security-Policy-Report-Only",
|
|
119
|
+
value: contentSecurityPolicyCustomHeader.contentSecurityPolicy,
|
|
120
|
+
override: contentSecurityPolicyCustomHeader.override,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.WebappSecurityHeaders = WebappSecurityHeaders;
|
|
129
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHktaGVhZGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93ZWJhcHAvc2VjdXJpdHktaGVhZGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBa0M7QUFDbEMseUNBQXdDO0FBQ3hDLHlEQUF3RDtBQStCeEQsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFhO0lBQ3JDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlCLE1BQU0sS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUE7SUFDMUQsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlCLE1BQU0sS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUE7SUFDMUQsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQy9CLE1BQU0sS0FBSyxDQUFDLDRDQUE0QyxDQUFDLENBQUE7SUFDM0QsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFBO0FBQ2QsQ0FBQztBQUVELDREQUE0RDtBQUM1RCxTQUFTLElBQUksQ0FBQyxLQUFhO0lBQ3pCLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7QUFDMUMsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsbUNBQW1DLENBQ2pELGFBQTJDO0lBRTNDLE1BQU0sYUFBYSxHQUFHO1FBQ3BCLE9BQU8sRUFBRSxRQUFRO1FBQ2pCLFFBQVEsRUFBRSxRQUFRO1FBQ2xCLFVBQVUsRUFBRSxlQUFlO1FBQzNCLFVBQVUsRUFBRSxRQUFRO1FBQ3BCLE9BQU8sRUFBRSxRQUFRO1FBQ2pCLFVBQVUsRUFBRSxRQUFRO1FBQ3BCLGNBQWMsRUFB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KiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIGNsb3VkZnJvbnQgZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250XCJcblxuZXhwb3J0IHR5cGUgV2ViYXBwU2VjdXJpdHlIZWFkZXJzUHJvcHMgPSBQYXJ0aWFsPFxuICBjbG91ZGZyb250LlJlc3BvbnNlU2VjdXJpdHlIZWFkZXJzQmVoYXZpb3IgJiB7XG4gICAgY29udGVudFNlY3VyaXR5UG9saWN5PzogY2xvdWRmcm9udC5SZXNwb25zZVNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yW1wiY29udGVudFNlY3VyaXR5UG9saWN5XCJdICYge1xuICAgICAgLyoqXG4gICAgICAgKiBXaGV0aGVyIHRvIG9ubHkgbW9uaXRvciB0aGUgZWZmZWN0cyBvZiB0aGUgY29udGVudCBzZWN1cml0eSBwb2xpY3kgd2l0aG91dCBhY3R1YWxseSBibG9ja2luZyBhbnl0aGluZy5cbiAgICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICAgKi9cbiAgICAgIHJlcG9ydE9ubHk/OiBib29sZWFuXG4gICAgfVxuICB9XG4+XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGVudFNlY3VyaXR5UG9saWN5SGVhZGVyIHtcbiAgYmFzZVVyaT86IHN0cmluZ1xuICBjaGlsZFNyYz86IHN0cmluZ1xuICBkZWZhdWx0U3JjPzogc3RyaW5nXG4gIGZvbnRTcmM/OiBzdHJpbmdcbiAgZnJhbWVTcmM/OiBzdHJpbmdcbiAgZm9ybUFjdGlvbj86IHN0cmluZ1xuICBmcmFtZUFuY2VzdG9ycz86IHN0cmluZ1xuICBpbWdTcmM/OiBzdHJpbmdcbiAgbWFuaWZlc3RTcmM/OiBzdHJpbmdcbiAgbWVkaWFTcmM/OiBzdHJpbmdcbiAgb2JqZWN0U3JjPzogc3RyaW5nXG4gIHNjcmlwdFNyYz86IHN0cmluZ1xuICBzdHlsZVNyYz86IHN0cmluZ1xuICBjb25uZWN0U3JjPzogc3RyaW5nXG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ3NwUGFyYW0ocGFyYW06IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChwYXJhbS5pbmRleE9mKCdcIicpICE9PSAtMSkge1xuICAgIHRocm93IEVycm9yKCdDU1Agb3ZlcnJpZGUgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXIgXCInKVxuICB9XG5cbiAgaWYgKHBhcmFtLmluZGV4T2YoXCI7XCIpICE9PSAtMSkge1xuICAgIHRocm93IEVycm9yKFwiQ1NQIG92ZXJyaWRlIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVyIDtcIilcbiAgfVxuXG4gIGlmIChwYXJhbS5pbmRleE9mKFwiXFxcXFwiKSAhPT0gLTEpIHtcbiAgICB0aHJvdyBFcnJvcihcIkNTUCBvdmVycmlkZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlciBcXFxcXCIpXG4gIH1cblxuICByZXR1cm4gcGFyYW1cbn1cblxuLyogUmVwbGFjZSBhbGwgd2hpdGVzcGFjZSBpbiBhIHN0cmluZyB3aXRoIGEgc2luZ2xlIHNwYWNlICovXG5mdW5jdGlvbiB0cmltKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWUucmVwbGFjZSgvXFxzKy9nLCBcIiBcIikudHJpbSgpXG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBDb250ZW50IFNlY3VyaXR5IFBvbGljeSB0aGF0IGNhbiBiZVxuICogdXNlZCBpbiBhIHNlY3VyaXR5IGhlYWRlci5cbiAqXG4gKiBOT1RFOiBUaGUgc3RyaW5nIGNhbiBiZSBmdXJ0aGVyIGV4dGVuZGVkIHVzaW5nIHN0cmluZyBjb25jYXRlbmF0aW9uIGZvciBkaXJlY3RpdmVzIHRoYXQgYXJlbid0IGN1cnJlbnRseSBzdXBwb3J0ZWQgYnkgdGhlIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVDb250ZW50U2VjdXJpdHlQb2xpY3lIZWFkZXIoXG4gIGhlYWRlck9wdGlvbnM/OiBDb250ZW50U2VjdXJpdHlQb2xpY3lIZWFkZXIsXG4pIHtcbiAgY29uc3QgZGVmYXVsdFZhbHVlcyA9IHtcbiAgICBiYXNlVXJpOiBcIidzZWxmJ1wiLFxuICAgIGNoaWxkU3JjOiBcIidzZWxmJ1wiLFxuICAgIGNvbm5lY3RTcmM6IFwiJ3NlbGYnIGh0dHBzOlwiLFxuICAgIGRlZmF1bHRTcmM6IFwiJ25vbmUnXCIsXG4gICAgZm9udFNyYzogXCInc2VsZidcIixcbiAgICBmb3JtQWN0aW9uOiBcIidub25lJ1wiLFxuICAgIGZyYW1lQW5jZXN0b3JzOiBcIidub25lJ1wiLFxuICAgIGZyYW1lU3JjOiBcIidzZWxmJ1wiLFxuICAgIGltZ1NyYzogXCInc2VsZicgZGF0YTpcIixcbiAgICBtYW5pZmVzdFNyYzogXCInc2VsZidcIixcbiAgICBtZWRpYVNyYzogXCInc2VsZidcIixcbiAgICBvYmplY3RTcmM6IFwiJ25vbmUnXCIsXG4gICAgc2NyaXB0U3JjOiBcIidzZWxmJ1wiLFxuICAgIHN0eWxlU3JjOiBcIidzZWxmJ1wiLFxuICB9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAuLi5kZWZhdWx0VmFsdWVzLFxuICAgIC4uLmhlYWRlck9wdGlvbnMsXG4gIH1cblxuICBPYmplY3QudmFsdWVzKG9wdGlvbnMpLmZvckVhY2goXG4gICAgKHYpID0+IHR5cGVvZiB2ID09PSBcInN0cmluZ1wiICYmIHZhbGlkYXRlQ3NwUGFyYW0odiksXG4gIClcblxuICBsZXQgaGVhZGVyVmFsdWUgPSBcIlwiXG4gIGhlYWRlclZhbHVlICs9IGBiYXNlLXVyaSAke3RyaW0ob3B0aW9ucy5iYXNlVXJpKX07YFxuICBoZWFkZXJWYWx1ZSArPSBgY2hpbGQtc3JjICR7dHJpbShvcHRpb25zLmNoaWxkU3JjKX07YFxuICBoZWFkZXJWYWx1ZSArPSBgY29ubmVjdC1zcmMgJHt0cmltKG9wdGlvbnMuY29ubmVjdFNyYyl9O2BcbiAgaGVhZGVyVmFsdWUgKz0gYGRlZmF1bHQtc3JjICR7dHJpbShvcHRpb25zLmRlZmF1bHRTcmMpfTtgXG4gIGhlYWRlclZhbHVlICs9IGBmb250LXNyYyAke3RyaW0ob3B0aW9ucy5mb250U3JjKX07YFxuICBoZWFkZXJWYWx1ZSArPSBgZnJhbWUtc3JjICR7dHJpbShvcHRpb25zLmZyYW1lU3JjKX07YFxuICBoZWFkZXJWYWx1ZSArPSBgZm9ybS1hY3Rpb24gJHt0cmltKG9wdGlvbnMuZm9ybUFjdGlvbil9O2BcbiAgaGVhZGVyVmFsdWUgKz0gYGZyYW1lLWFuY2VzdG9ycyAke3RyaW0ob3B0aW9ucy5mcmFtZUFuY2VzdG9ycyl9O2BcbiAgaGVhZGVyVmFsdWUgKz0gYGltZy1zcmMgJHt0cmltKG9wdGlvbnMuaW1nU3JjKX07YFxuICBoZWFkZXJWYWx1ZSArPSBgbWFuaWZlc3Qtc3JjICR7dHJpbShvcHRpb25zLm1hbmlmZXN0U3JjKX07YFxuICBoZWFkZXJWYWx1ZSArPSBgbWVkaWEtc3JjICR7dHJpbShvcHRpb25zLm1lZGlhU3JjKX07YFxuICBoZWFkZXJWYWx1ZSArPSBgb2JqZWN0LXNyYyAke3RyaW0ob3B0aW9ucy5vYmplY3RTcmMpfTtgXG4gIGhlYWRlclZhbHVlICs9IGBzY3JpcHQtc3JjICR7dHJpbShvcHRpb25zLnNjcmlwdFNyYyl9O2BcbiAgaGVhZGVyVmFsdWUgKz0gYHN0eWxlLXNyYyAke3RyaW0ob3B0aW9ucy5zdHlsZVNyYyl9YFxuXG4gIHJldHVybiB0cmltKGhlYWRlclZhbHVlKVxufVxuZXhwb3J0IGNsYXNzIFdlYmFwcFNlY3VyaXR5SGVhZGVycyBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgcHVibGljIHJlYWRvbmx5IHJlc3BvbnNlSGVhZGVyc1BvbGljeTogY2xvdWRmcm9udC5SZXNwb25zZUhlYWRlcnNQb2xpY3lcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogY29uc3RydWN0cy5Db25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogV2ViYXBwU2VjdXJpdHlIZWFkZXJzUHJvcHMsXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIGNvbnN0IHtcbiAgICAgIGNvbnRlbnRTZWN1cml0eVBvbGljeTogY29udGVudFNlY3VyaXR5UG9saWN5T3ZlcnJpZGUsXG4gICAgICAuLi5vdmVycmlkZXNcbiAgICB9ID0gcHJvcHNcblxuICAgIGNvbnN0IGNvbnRlbnRTZWN1cml0eVBvbGljeUN1c3RvbUhlYWRlciA9IGNvbnRlbnRTZWN1cml0eVBvbGljeU92ZXJyaWRlIHx8IHtcbiAgICAgIHJlcG9ydE9ubHk6IGZhbHNlLFxuICAgICAgY29udGVudFNlY3VyaXR5UG9saWN5OiBnZW5lcmF0ZUNvbnRlbnRTZWN1cml0eVBvbGljeUhlYWRlcigpLFxuICAgICAgb3ZlcnJpZGU6IHRydWUsXG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdFZhbHVlczogT21pdDxcbiAgICAgIGNsb3VkZnJvbnQuUmVzcG9uc2VTZWN1cml0eUhlYWRlcnNCZWhhdmlvcixcbiAgICAgIFwiY29udGVudFNlY3VyaXR5UG9saWN5XCJcbiAgICA+ID0ge1xuICAgICAgY29udGVudFR5cGVPcHRpb25zOiB7XG4gICAgICAgIG92ZXJyaWRlOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIHJlZmVycmVyUG9saWN5OiB7XG4gICAgICAgIG92ZXJyaWRlOiB0cnVlLFxuICAgICAgICByZWZlcnJlclBvbGljeTogY2xvdWRmcm9udC5IZWFkZXJzUmVmZXJyZXJQb2xpY3kuU0FNRV9PUklHSU4sXG4gICAgICB9LFxuICAgICAgZnJhbWVPcHRpb25zOiB7XG4gICAgICAgIGZyYW1lT3B0aW9uOiBjbG91ZGZyb250LkhlYWRlcnNGcmFtZU9wdGlvbi5ERU5ZLFxuICAgICAgICBvdmVycmlkZTogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICBzdHJpY3RUcmFuc3BvcnRTZWN1cml0eToge1xuICAgICAgICBvdmVycmlkZTogdHJ1ZSxcbiAgICAgICAgYWNjZXNzQ29udHJvbE1heEFnZTogY2RrLkR1cmF0aW9uLmRheXMoMTgyLjUpLFxuICAgICAgICBpbmNsdWRlU3ViZG9tYWluczogZmFsc2UsXG4gICAgICAgIHByZWxvYWQ6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIHhzc1Byb3RlY3Rpb246IHtcbiAgICAgICAgb3ZlcnJpZGU6IHRydWUsXG4gICAgICAgIHByb3RlY3Rpb246IHRydWUsXG4gICAgICAgIG1vZGVCbG9jazogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgdGhpcy5yZXNwb25zZUhlYWRlcnNQb2xpY3kgPSBuZXcgY2xvdWRmcm9udC5SZXNwb25zZUhlYWRlcnNQb2xpY3koXG4gICAgICB0aGlzLFxuICAgICAgXCJSZXNwb25zZUhlYWRlcnNQb2xpY3lcIixcbiAgICAgIHtcbiAgICAgICAgc2VjdXJpdHlIZWFkZXJzQmVoYXZpb3I6IHtcbiAgICAgICAgICAuLi5kZWZhdWx0VmFsdWVzLFxuICAgICAgICAgIC4uLm92ZXJyaWRlcyxcbiAgICAgICAgICAuLi4oIWNvbnRlbnRTZWN1cml0eVBvbGljeUN1c3RvbUhlYWRlci5yZXBvcnRPbmx5ICYmIHtcbiAgICAgICAgICAgIGNvbnRlbnRTZWN1cml0eVBvbGljeToge1xuICAgICAgICAgICAgICBjb250ZW50U2VjdXJpdHlQb2xpY3k6XG4gICAgICAgICAgICAgICAgY29udGVudFNlY3VyaXR5UG9saWN5Q3VzdG9tSGVhZGVyLmNvbnRlbnRTZWN1cml0eVBvbGljeSxcbiAgICAgICAgICAgICAgb3ZlcnJpZGU6IGNvbnRlbnRTZWN1cml0eVBvbGljeUN1c3RvbUhlYWRlci5vdmVycmlkZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICAgIC4uLihjb250ZW50U2VjdXJpdHlQb2xpY3lDdXN0b21IZWFkZXIucmVwb3J0T25seSAmJiB7XG4gICAgICAgICAgY3VzdG9tSGVhZGVyc0JlaGF2aW9yOiB7XG4gICAgICAgICAgICAvLyBSZXBvcnQgb25seSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHNlY3VyaXR5SGVhZGVyc0JlaGF2aW9yIGluIEFXUyBhbmQgbXVzdCBiZSBkZWZpbmVkIGFzIGN1c3RvbSBoZWFkZXJcbiAgICAgICAgICAgIGN1c3RvbUhlYWRlcnM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGhlYWRlcjogXCJDb250ZW50LVNlY3VyaXR5LVBvbGljeS1SZXBvcnQtT25seVwiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBjb250ZW50U2VjdXJpdHlQb2xpY3lDdXN0b21IZWFkZXIuY29udGVudFNlY3VyaXR5UG9saWN5LFxuICAgICAgICAgICAgICAgIG92ZXJyaWRlOiBjb250ZW50U2VjdXJpdHlQb2xpY3lDdXN0b21IZWFkZXIub3ZlcnJpZGUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICApXG4gIH1cbn1cbiJdfQ==
|