quidproquo-deploy-awscdk 0.0.82 → 0.0.84

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.
@@ -31,6 +31,7 @@ const path_1 = __importDefault(require("path"));
31
31
  const aws_cdk_lib_1 = require("aws-cdk-lib");
32
32
  const cdk = __importStar(require("aws-cdk-lib"));
33
33
  const quidproquo_webserver_1 = require("quidproquo-webserver");
34
+ const securityHeaders_1 = require("./utils/securityHeaders");
34
35
  const quidproquo_actionprocessor_awslambda_1 = require("quidproquo-actionprocessor-awslambda");
35
36
  const QpqConstructBlock_1 = require("../../../base/QpqConstructBlock");
36
37
  const qpqDeployAwsCdkUtils = __importStar(require("../../../../utils"));
@@ -105,7 +106,6 @@ class QpqWebserverWebEntryConstruct extends QpqConstructBlock_1.QpqConstructBloc
105
106
  enableAcceptEncodingGzip: true,
106
107
  enableAcceptEncodingBrotli: true,
107
108
  });
108
- const mustRevalidate = false;
109
109
  const responseHeaderPolicy = new aws_cdk_lib_1.aws_cloudfront.ResponseHeadersPolicy(this, `dist-rhp`, {
110
110
  responseHeadersPolicyName: this.resourceName(props.webEntryConfig.name),
111
111
  customHeadersBehavior: {
@@ -117,6 +117,7 @@ class QpqWebserverWebEntryConstruct extends QpqConstructBlock_1.QpqConstructBloc
117
117
  },
118
118
  ],
119
119
  },
120
+ securityHeadersBehavior: (0, securityHeaders_1.convertSecurityHeadersFromQpqSecurityHeaders)(quidproquo_webserver_1.qpqWebServerUtils.getBaseDomainName(props.qpqConfig), props.webEntryConfig.securityHeaders),
120
121
  });
121
122
  // Create a CloudFront distribution using the S3 bucket as the origin
122
123
  const distributionOrigin = new aws_cdk_lib_1.aws_cloudfront_origins.S3Origin(originBucket);
@@ -159,15 +160,15 @@ class QpqWebserverWebEntryConstruct extends QpqConstructBlock_1.QpqConstructBloc
159
160
  // if we have some ~ Build the edge lambdas and deploy
160
161
  if (seos.length > 0) {
161
162
  const seoEntryBuildPath = quidproquo_webserver_1.qpqWebServerUtils.getWebEntrySeoFullPath(props.qpqConfig, props.webEntryConfig);
162
- const edgeFunctionVR = new aws_cdk_lib_1.aws_cloudfront.experimental.EdgeFunction(this, `SEO-${props.webEntryConfig.name}-VR`, {
163
- functionName: this.resourceName(`SEO-VR-${props.webEntryConfig.name}`),
163
+ const edgeFunctionVR = new aws_cdk_lib_1.aws_cloudfront.experimental.EdgeFunction(this, `SEO-VR`, {
164
+ functionName: this.qpqResourceName(props.webEntryConfig.name, 'SEO-VR'),
164
165
  timeout: cdk.Duration.seconds(5),
165
166
  runtime: aws_cdk_lib_1.aws_lambda.Runtime.NODEJS_18_X,
166
167
  code: aws_cdk_lib_1.aws_lambda.Code.fromAsset(path_1.default.join(seoEntryBuildPath, 'lambdaEventViewerRequest')),
167
168
  handler: 'index.executeEventViewerRequest',
168
169
  });
169
- const edgeFunctionOR = new aws_cdk_lib_1.aws_cloudfront.experimental.EdgeFunction(this, `SEO-${props.webEntryConfig.name}-OR`, {
170
- functionName: this.resourceName(`SEO-OR-${props.webEntryConfig.name}`),
170
+ const edgeFunctionOR = new aws_cdk_lib_1.aws_cloudfront.experimental.EdgeFunction(this, `SEO-OR`, {
171
+ functionName: this.qpqResourceName(props.webEntryConfig.name, 'SEO-OR'),
171
172
  timeout: cdk.Duration.seconds(30),
172
173
  runtime: aws_cdk_lib_1.aws_lambda.Runtime.NODEJS_18_X,
173
174
  memorySize: 1024,
@@ -223,6 +224,7 @@ class QpqWebserverWebEntryConstruct extends QpqConstructBlock_1.QpqConstructBloc
223
224
  },
224
225
  ],
225
226
  },
227
+ securityHeadersBehavior: (0, securityHeaders_1.convertSecurityHeadersFromQpqSecurityHeaders)(quidproquo_webserver_1.qpqWebServerUtils.getBaseDomainName(props.qpqConfig), props.webEntryConfig.securityHeaders),
226
228
  });
227
229
  props.webEntryConfig.ignoreCache.forEach((pathPattern) => {
228
230
  distribution.addBehavior(pathPattern, distributionOrigin, {
@@ -0,0 +1,10 @@
1
+ import { aws_cloudfront } from 'aws-cdk-lib';
2
+ import { ResponseSecurityHeaders, ResponseHeadersStrictTransportSecurity, ResponseHeadersContentSecurityPolicy, ResponseHeadersContentTypeOptions, ResponseHeadersFrameOptions, ResponseHeadersReferrerPolicy, ResponseHeadersXSSProtection, ContentSecurityPolicyEntry } from 'quidproquo-webserver';
3
+ export declare const convertStrictTransportSecurity: (strictTransportSecurity?: ResponseHeadersStrictTransportSecurity) => aws_cloudfront.ResponseHeadersStrictTransportSecurity | undefined;
4
+ export declare const convertContentSecurityPolicyEntryToString: (baseDomain: string, contentSecurityPolicyEntry: ContentSecurityPolicyEntry) => string;
5
+ export declare const convertContentSecurityPolicy: (baseDomain: string, contentSecurityPolicy?: ResponseHeadersContentSecurityPolicy) => aws_cloudfront.ResponseHeadersContentSecurityPolicy | undefined;
6
+ export declare const convertContentTypeOptions: (contentTypeOptions?: ResponseHeadersContentTypeOptions) => aws_cloudfront.ResponseHeadersContentTypeOptions | undefined;
7
+ export declare const convertFrameOptions: (frameOptions?: ResponseHeadersFrameOptions) => aws_cloudfront.ResponseHeadersFrameOptions | undefined;
8
+ export declare const convertReferrerPolicy: (referrerPolicy?: ResponseHeadersReferrerPolicy) => aws_cloudfront.ResponseHeadersReferrerPolicy | undefined;
9
+ export declare const convertXssProtection: (xssProtection?: ResponseHeadersXSSProtection) => aws_cloudfront.ResponseHeadersXSSProtection | undefined;
10
+ export declare const convertSecurityHeadersFromQpqSecurityHeaders: (baseDomain: string, securityHeaders?: ResponseSecurityHeaders) => aws_cloudfront.ResponseSecurityHeadersBehavior;
@@ -0,0 +1,154 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.convertSecurityHeadersFromQpqSecurityHeaders = exports.convertXssProtection = exports.convertReferrerPolicy = exports.convertFrameOptions = exports.convertContentTypeOptions = exports.convertContentSecurityPolicy = exports.convertContentSecurityPolicyEntryToString = exports.convertStrictTransportSecurity = void 0;
27
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
28
+ const cdk = __importStar(require("aws-cdk-lib"));
29
+ const quidproquo_webserver_1 = require("quidproquo-webserver");
30
+ const convertStrictTransportSecurity = (strictTransportSecurity) => {
31
+ if (!strictTransportSecurity) {
32
+ return {
33
+ override: true,
34
+ accessControlMaxAge: cdk.Duration.hours(1),
35
+ includeSubdomains: true,
36
+ preload: true,
37
+ };
38
+ }
39
+ return {
40
+ accessControlMaxAge: cdk.Duration.seconds(strictTransportSecurity.accessControlMaxAgeInSeconds),
41
+ override: strictTransportSecurity.override,
42
+ includeSubdomains: strictTransportSecurity.includeSubdomains,
43
+ preload: strictTransportSecurity.preload,
44
+ };
45
+ };
46
+ exports.convertStrictTransportSecurity = convertStrictTransportSecurity;
47
+ const convertContentSecurityPolicyEntryToString = (baseDomain, contentSecurityPolicyEntry) => {
48
+ if (typeof contentSecurityPolicyEntry === 'string') {
49
+ return contentSecurityPolicyEntry;
50
+ }
51
+ // Otherwise its a QpqServiceContentSecurityPolicy
52
+ const scsp = contentSecurityPolicyEntry;
53
+ const domain = scsp.domain || baseDomain;
54
+ if (scsp.service) {
55
+ return `${scsp.api}.${scsp.service}.${domain}`;
56
+ }
57
+ return `${scsp.api}.${domain}`;
58
+ };
59
+ exports.convertContentSecurityPolicyEntryToString = convertContentSecurityPolicyEntryToString;
60
+ const convertContentSecurityPolicy = (baseDomain, contentSecurityPolicy) => {
61
+ if (!contentSecurityPolicy) {
62
+ return {
63
+ contentSecurityPolicy: "default-src 'self'; object-src 'none'",
64
+ override: true,
65
+ };
66
+ }
67
+ return {
68
+ contentSecurityPolicy: Object.keys(contentSecurityPolicy.contentSecurityPolicy)
69
+ .map((directive) => [
70
+ directive,
71
+ ...contentSecurityPolicy.contentSecurityPolicy[directive].map((cspe) => (0, exports.convertContentSecurityPolicyEntryToString)(baseDomain, cspe)),
72
+ ].join(' '))
73
+ .join('; '),
74
+ override: contentSecurityPolicy.override,
75
+ };
76
+ };
77
+ exports.convertContentSecurityPolicy = convertContentSecurityPolicy;
78
+ const convertContentTypeOptions = (contentTypeOptions) => {
79
+ if (!contentTypeOptions) {
80
+ return {
81
+ override: true,
82
+ };
83
+ }
84
+ return {
85
+ override: contentTypeOptions.override,
86
+ };
87
+ };
88
+ exports.convertContentTypeOptions = convertContentTypeOptions;
89
+ const convertFrameOptions = (frameOptions) => {
90
+ if (!frameOptions) {
91
+ return {
92
+ frameOption: aws_cdk_lib_1.aws_cloudfront.HeadersFrameOption.DENY,
93
+ override: true,
94
+ };
95
+ }
96
+ const frameOptionMap = {
97
+ [quidproquo_webserver_1.HeadersFrameOption.DENY]: aws_cdk_lib_1.aws_cloudfront.HeadersFrameOption.DENY,
98
+ [quidproquo_webserver_1.HeadersFrameOption.SAMEORIGIN]: aws_cdk_lib_1.aws_cloudfront.HeadersFrameOption.SAMEORIGIN,
99
+ };
100
+ return {
101
+ frameOption: frameOptionMap[frameOptions.frameOption],
102
+ override: frameOptions.override,
103
+ };
104
+ };
105
+ exports.convertFrameOptions = convertFrameOptions;
106
+ const convertReferrerPolicy = (referrerPolicy) => {
107
+ if (!referrerPolicy) {
108
+ return {
109
+ referrerPolicy: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
110
+ override: true,
111
+ };
112
+ }
113
+ const referrerPolicyMap = {
114
+ [quidproquo_webserver_1.HeadersReferrerPolicy.NO_REFERRER]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.NO_REFERRER,
115
+ [quidproquo_webserver_1.HeadersReferrerPolicy.NO_REFERRER_WHEN_DOWNGRADE]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.NO_REFERRER_WHEN_DOWNGRADE,
116
+ [quidproquo_webserver_1.HeadersReferrerPolicy.ORIGIN]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.ORIGIN,
117
+ [quidproquo_webserver_1.HeadersReferrerPolicy.ORIGIN_WHEN_CROSS_ORIGIN]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.ORIGIN_WHEN_CROSS_ORIGIN,
118
+ [quidproquo_webserver_1.HeadersReferrerPolicy.SAME_ORIGIN]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.SAME_ORIGIN,
119
+ [quidproquo_webserver_1.HeadersReferrerPolicy.STRICT_ORIGIN]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.STRICT_ORIGIN,
120
+ [quidproquo_webserver_1.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
121
+ [quidproquo_webserver_1.HeadersReferrerPolicy.UNSAFE_URL]: aws_cdk_lib_1.aws_cloudfront.HeadersReferrerPolicy.UNSAFE_URL,
122
+ };
123
+ return {
124
+ referrerPolicy: referrerPolicyMap[referrerPolicy.referrerPolicy],
125
+ override: referrerPolicy.override,
126
+ };
127
+ };
128
+ exports.convertReferrerPolicy = convertReferrerPolicy;
129
+ const convertXssProtection = (xssProtection) => {
130
+ if (!xssProtection) {
131
+ return {
132
+ protection: true,
133
+ modeBlock: true,
134
+ override: true,
135
+ };
136
+ }
137
+ return {
138
+ protection: xssProtection.protection,
139
+ modeBlock: xssProtection.modeBlock,
140
+ override: xssProtection.override,
141
+ };
142
+ };
143
+ exports.convertXssProtection = convertXssProtection;
144
+ const convertSecurityHeadersFromQpqSecurityHeaders = (baseDomain, securityHeaders) => {
145
+ return {
146
+ contentSecurityPolicy: (0, exports.convertContentSecurityPolicy)(baseDomain, securityHeaders === null || securityHeaders === void 0 ? void 0 : securityHeaders.contentSecurityPolicy),
147
+ contentTypeOptions: (0, exports.convertContentTypeOptions)(securityHeaders === null || securityHeaders === void 0 ? void 0 : securityHeaders.contentTypeOptions),
148
+ frameOptions: (0, exports.convertFrameOptions)(securityHeaders === null || securityHeaders === void 0 ? void 0 : securityHeaders.frameOptions),
149
+ referrerPolicy: (0, exports.convertReferrerPolicy)(securityHeaders === null || securityHeaders === void 0 ? void 0 : securityHeaders.referrerPolicy),
150
+ xssProtection: (0, exports.convertXssProtection)(securityHeaders === null || securityHeaders === void 0 ? void 0 : securityHeaders.xssProtection),
151
+ strictTransportSecurity: (0, exports.convertStrictTransportSecurity)(securityHeaders === null || securityHeaders === void 0 ? void 0 : securityHeaders.strictTransportSecurity),
152
+ };
153
+ };
154
+ exports.convertSecurityHeadersFromQpqSecurityHeaders = convertSecurityHeadersFromQpqSecurityHeaders;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-deploy-awscdk",
3
- "version": "0.0.82",
3
+ "version": "0.0.84",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.js",
@@ -19,6 +19,8 @@ import {
19
19
  qpqHeaderIsBot,
20
20
  } from 'quidproquo-webserver';
21
21
 
22
+ import { convertSecurityHeadersFromQpqSecurityHeaders } from './utils/securityHeaders';
23
+
22
24
  import { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';
23
25
 
24
26
  import { QpqConstructBlock, QpqConstructBlockProps } from '../../../base/QpqConstructBlock';
@@ -128,8 +130,6 @@ export class QpqWebserverWebEntryConstruct extends QpqConstructBlock {
128
130
  enableAcceptEncodingBrotli: true,
129
131
  });
130
132
 
131
- const mustRevalidate = false;
132
-
133
133
  const responseHeaderPolicy = new aws_cloudfront.ResponseHeadersPolicy(this, `dist-rhp`, {
134
134
  responseHeadersPolicyName: this.resourceName(props.webEntryConfig.name),
135
135
  customHeadersBehavior: {
@@ -143,6 +143,10 @@ export class QpqWebserverWebEntryConstruct extends QpqConstructBlock {
143
143
  },
144
144
  ],
145
145
  },
146
+ securityHeadersBehavior: convertSecurityHeadersFromQpqSecurityHeaders(
147
+ qpqWebServerUtils.getBaseDomainName(props.qpqConfig),
148
+ props.webEntryConfig.securityHeaders,
149
+ ),
146
150
  });
147
151
 
148
152
  // Create a CloudFront distribution using the S3 bucket as the origin
@@ -214,33 +218,25 @@ export class QpqWebserverWebEntryConstruct extends QpqConstructBlock {
214
218
  props.webEntryConfig,
215
219
  );
216
220
 
217
- const edgeFunctionVR = new aws_cloudfront.experimental.EdgeFunction(
218
- this,
219
- `SEO-${props.webEntryConfig.name}-VR`,
220
- {
221
- functionName: this.resourceName(`SEO-VR-${props.webEntryConfig.name}`),
222
- timeout: cdk.Duration.seconds(5),
223
- runtime: aws_lambda.Runtime.NODEJS_18_X,
224
-
225
- code: aws_lambda.Code.fromAsset(path.join(seoEntryBuildPath, 'lambdaEventViewerRequest')),
226
- handler: 'index.executeEventViewerRequest',
227
- },
228
- );
221
+ const edgeFunctionVR = new aws_cloudfront.experimental.EdgeFunction(this, `SEO-VR`, {
222
+ functionName: this.qpqResourceName(props.webEntryConfig.name, 'SEO-VR'),
223
+ timeout: cdk.Duration.seconds(5),
224
+ runtime: aws_lambda.Runtime.NODEJS_18_X,
229
225
 
230
- const edgeFunctionOR = new aws_cloudfront.experimental.EdgeFunction(
231
- this,
232
- `SEO-${props.webEntryConfig.name}-OR`,
233
- {
234
- functionName: this.resourceName(`SEO-OR-${props.webEntryConfig.name}`),
235
- timeout: cdk.Duration.seconds(30),
236
- runtime: aws_lambda.Runtime.NODEJS_18_X,
226
+ code: aws_lambda.Code.fromAsset(path.join(seoEntryBuildPath, 'lambdaEventViewerRequest')),
227
+ handler: 'index.executeEventViewerRequest',
228
+ });
237
229
 
238
- memorySize: 1024,
230
+ const edgeFunctionOR = new aws_cloudfront.experimental.EdgeFunction(this, `SEO-OR`, {
231
+ functionName: this.qpqResourceName(props.webEntryConfig.name, 'SEO-OR'),
232
+ timeout: cdk.Duration.seconds(30),
233
+ runtime: aws_lambda.Runtime.NODEJS_18_X,
239
234
 
240
- code: aws_lambda.Code.fromAsset(path.join(seoEntryBuildPath, 'lambdaEventOriginRequest')),
241
- handler: 'index.executeEventOriginRequest',
242
- },
243
- );
235
+ memorySize: 1024,
236
+
237
+ code: aws_lambda.Code.fromAsset(path.join(seoEntryBuildPath, 'lambdaEventOriginRequest')),
238
+ handler: 'index.executeEventOriginRequest',
239
+ });
244
240
 
245
241
  const grantables = qpqDeployAwsCdkUtils.getQqpGrantableResources(
246
242
  this,
@@ -307,6 +303,10 @@ export class QpqWebserverWebEntryConstruct extends QpqConstructBlock {
307
303
  },
308
304
  ],
309
305
  },
306
+ securityHeadersBehavior: convertSecurityHeadersFromQpqSecurityHeaders(
307
+ qpqWebServerUtils.getBaseDomainName(props.qpqConfig),
308
+ props.webEntryConfig.securityHeaders,
309
+ ),
310
310
  },
311
311
  );
312
312
 
@@ -0,0 +1,183 @@
1
+ import { aws_cloudfront } from 'aws-cdk-lib';
2
+ import * as cdk from 'aws-cdk-lib';
3
+
4
+ import {
5
+ ResponseSecurityHeaders,
6
+ ResponseHeadersStrictTransportSecurity,
7
+ ResponseHeadersContentSecurityPolicy,
8
+ ResponseHeadersContentTypeOptions,
9
+ ResponseHeadersFrameOptions,
10
+ HeadersFrameOption,
11
+ HeadersReferrerPolicy,
12
+ ResponseHeadersReferrerPolicy,
13
+ ResponseHeadersXSSProtection,
14
+ ContentSecurityPolicyEntry,
15
+ QpqServiceContentSecurityPolicy,
16
+ } from 'quidproquo-webserver';
17
+
18
+ export const convertStrictTransportSecurity = (
19
+ strictTransportSecurity?: ResponseHeadersStrictTransportSecurity,
20
+ ): aws_cloudfront.ResponseHeadersStrictTransportSecurity | undefined => {
21
+ if (!strictTransportSecurity) {
22
+ return {
23
+ override: true,
24
+ accessControlMaxAge: cdk.Duration.hours(1),
25
+ includeSubdomains: true,
26
+ preload: true,
27
+ };
28
+ }
29
+
30
+ return {
31
+ accessControlMaxAge: cdk.Duration.seconds(strictTransportSecurity.accessControlMaxAgeInSeconds),
32
+ override: strictTransportSecurity.override,
33
+ includeSubdomains: strictTransportSecurity.includeSubdomains,
34
+ preload: strictTransportSecurity.preload,
35
+ };
36
+ };
37
+
38
+ export const convertContentSecurityPolicyEntryToString = (
39
+ baseDomain: string,
40
+ contentSecurityPolicyEntry: ContentSecurityPolicyEntry,
41
+ ): string => {
42
+ if (typeof contentSecurityPolicyEntry === 'string') {
43
+ return contentSecurityPolicyEntry;
44
+ }
45
+
46
+ // Otherwise its a QpqServiceContentSecurityPolicy
47
+ const scsp: QpqServiceContentSecurityPolicy = contentSecurityPolicyEntry;
48
+ const domain = scsp.domain || baseDomain;
49
+
50
+ if (scsp.service) {
51
+ return `${scsp.api}.${scsp.service}.${domain}`;
52
+ }
53
+
54
+ return `${scsp.api}.${domain}`;
55
+ };
56
+
57
+ export const convertContentSecurityPolicy = (
58
+ baseDomain: string,
59
+ contentSecurityPolicy?: ResponseHeadersContentSecurityPolicy,
60
+ ): aws_cloudfront.ResponseHeadersContentSecurityPolicy | undefined => {
61
+ if (!contentSecurityPolicy) {
62
+ return {
63
+ contentSecurityPolicy: "default-src 'self'; object-src 'none'",
64
+ override: true,
65
+ };
66
+ }
67
+
68
+ return {
69
+ contentSecurityPolicy: Object.keys(contentSecurityPolicy.contentSecurityPolicy)
70
+ .map((directive) =>
71
+ [
72
+ directive,
73
+ ...contentSecurityPolicy.contentSecurityPolicy[directive].map((cspe) =>
74
+ convertContentSecurityPolicyEntryToString(baseDomain, cspe),
75
+ ),
76
+ ].join(' '),
77
+ )
78
+ .join('; '),
79
+ override: contentSecurityPolicy.override,
80
+ };
81
+ };
82
+
83
+ export const convertContentTypeOptions = (
84
+ contentTypeOptions?: ResponseHeadersContentTypeOptions,
85
+ ): aws_cloudfront.ResponseHeadersContentTypeOptions | undefined => {
86
+ if (!contentTypeOptions) {
87
+ return {
88
+ override: true,
89
+ };
90
+ }
91
+
92
+ return {
93
+ override: contentTypeOptions.override,
94
+ };
95
+ };
96
+
97
+ export const convertFrameOptions = (
98
+ frameOptions?: ResponseHeadersFrameOptions,
99
+ ): aws_cloudfront.ResponseHeadersFrameOptions | undefined => {
100
+ if (!frameOptions) {
101
+ return {
102
+ frameOption: aws_cloudfront.HeadersFrameOption.DENY,
103
+ override: true,
104
+ };
105
+ }
106
+
107
+ const frameOptionMap = {
108
+ [HeadersFrameOption.DENY]: aws_cloudfront.HeadersFrameOption.DENY,
109
+ [HeadersFrameOption.SAMEORIGIN]: aws_cloudfront.HeadersFrameOption.SAMEORIGIN,
110
+ };
111
+
112
+ return {
113
+ frameOption: frameOptionMap[frameOptions.frameOption],
114
+ override: frameOptions.override,
115
+ };
116
+ };
117
+
118
+ export const convertReferrerPolicy = (
119
+ referrerPolicy?: ResponseHeadersReferrerPolicy,
120
+ ): aws_cloudfront.ResponseHeadersReferrerPolicy | undefined => {
121
+ if (!referrerPolicy) {
122
+ return {
123
+ referrerPolicy: aws_cloudfront.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
124
+ override: true,
125
+ };
126
+ }
127
+
128
+ const referrerPolicyMap = {
129
+ [HeadersReferrerPolicy.NO_REFERRER]: aws_cloudfront.HeadersReferrerPolicy.NO_REFERRER,
130
+ [HeadersReferrerPolicy.NO_REFERRER_WHEN_DOWNGRADE]:
131
+ aws_cloudfront.HeadersReferrerPolicy.NO_REFERRER_WHEN_DOWNGRADE,
132
+ [HeadersReferrerPolicy.ORIGIN]: aws_cloudfront.HeadersReferrerPolicy.ORIGIN,
133
+ [HeadersReferrerPolicy.ORIGIN_WHEN_CROSS_ORIGIN]:
134
+ aws_cloudfront.HeadersReferrerPolicy.ORIGIN_WHEN_CROSS_ORIGIN,
135
+ [HeadersReferrerPolicy.SAME_ORIGIN]: aws_cloudfront.HeadersReferrerPolicy.SAME_ORIGIN,
136
+ [HeadersReferrerPolicy.STRICT_ORIGIN]: aws_cloudfront.HeadersReferrerPolicy.STRICT_ORIGIN,
137
+ [HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN]:
138
+ aws_cloudfront.HeadersReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
139
+ [HeadersReferrerPolicy.UNSAFE_URL]: aws_cloudfront.HeadersReferrerPolicy.UNSAFE_URL,
140
+ };
141
+
142
+ return {
143
+ referrerPolicy: referrerPolicyMap[referrerPolicy.referrerPolicy],
144
+ override: referrerPolicy.override,
145
+ };
146
+ };
147
+
148
+ export const convertXssProtection = (
149
+ xssProtection?: ResponseHeadersXSSProtection,
150
+ ): aws_cloudfront.ResponseHeadersXSSProtection | undefined => {
151
+ if (!xssProtection) {
152
+ return {
153
+ protection: true,
154
+ modeBlock: true,
155
+ override: true,
156
+ };
157
+ }
158
+
159
+ return {
160
+ protection: xssProtection.protection,
161
+ modeBlock: xssProtection.modeBlock,
162
+ override: xssProtection.override,
163
+ };
164
+ };
165
+
166
+ export const convertSecurityHeadersFromQpqSecurityHeaders = (
167
+ baseDomain: string,
168
+ securityHeaders?: ResponseSecurityHeaders,
169
+ ): aws_cloudfront.ResponseSecurityHeadersBehavior => {
170
+ return {
171
+ contentSecurityPolicy: convertContentSecurityPolicy(
172
+ baseDomain,
173
+ securityHeaders?.contentSecurityPolicy,
174
+ ),
175
+ contentTypeOptions: convertContentTypeOptions(securityHeaders?.contentTypeOptions),
176
+ frameOptions: convertFrameOptions(securityHeaders?.frameOptions),
177
+ referrerPolicy: convertReferrerPolicy(securityHeaders?.referrerPolicy),
178
+ xssProtection: convertXssProtection(securityHeaders?.xssProtection),
179
+ strictTransportSecurity: convertStrictTransportSecurity(
180
+ securityHeaders?.strictTransportSecurity,
181
+ ),
182
+ };
183
+ };