@jaypie/constructs 1.2.29 → 1.2.31

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.
@@ -7,7 +7,7 @@ export { JaypieCertificate, JaypieCertificateProps } from "./JaypieCertificate";
7
7
  export { JaypieDatadogBucket, JaypieDatadogBucketProps, } from "./JaypieDatadogBucket";
8
8
  export { JaypieDatadogForwarder, JaypieDatadogForwarderProps, } from "./JaypieDatadogForwarder";
9
9
  export { JaypieDatadogSecret } from "./JaypieDatadogSecret";
10
- export { JaypieDistribution, JaypieDistributionProps, } from "./JaypieDistribution";
10
+ export { JaypieDistribution, JaypieDistributionProps, SecurityHeadersOverrides, } from "./JaypieDistribution";
11
11
  export { JaypieDnsRecord, JaypieDnsRecordProps } from "./JaypieDnsRecord";
12
12
  export { JaypieDynamoDb, JaypieDynamoDbProps } from "./JaypieDynamoDb";
13
13
  export type { IndexDefinition } from "@jaypie/fabric";
@@ -7,6 +7,14 @@ import * as s3 from "aws-cdk-lib/aws-s3";
7
7
  import { LambdaDestination } from "aws-cdk-lib/aws-s3-notifications";
8
8
  import { Construct } from "constructs";
9
9
  import { HostConfig } from "./helpers";
10
+ export interface SecurityHeadersOverrides {
11
+ contentSecurityPolicy?: string;
12
+ frameOption?: cloudfront.HeadersFrameOption;
13
+ hstsIncludeSubdomains?: boolean;
14
+ hstsMaxAge?: number;
15
+ permissionsPolicy?: string;
16
+ referrerPolicy?: cloudfront.HeadersReferrerPolicy;
17
+ }
10
18
  export interface JaypieDistributionProps extends Omit<cloudfront.DistributionProps, "certificate" | "defaultBehavior" | "logBucket"> {
11
19
  /**
12
20
  * SSL certificate for the CloudFront distribution
@@ -73,6 +81,19 @@ export interface JaypieDistributionProps extends Omit<cloudfront.DistributionPro
73
81
  * @max Duration.seconds(120)
74
82
  */
75
83
  originReadTimeout?: Duration;
84
+ /**
85
+ * Full override for the response headers policy.
86
+ * When provided, bypasses all default security header logic.
87
+ */
88
+ responseHeadersPolicy?: cloudfront.IResponseHeadersPolicy;
89
+ /**
90
+ * Security headers configuration.
91
+ * - true/undefined: apply sensible defaults (HSTS, X-Frame-Options, CSP, etc.)
92
+ * - false: disable security headers entirely
93
+ * - SecurityHeadersOverrides object: merge overrides with defaults
94
+ * @default true
95
+ */
96
+ securityHeaders?: boolean | SecurityHeadersOverrides;
76
97
  /**
77
98
  * Role tag for tagging resources
78
99
  * @default CDK.ROLE.HOSTING
@@ -94,6 +115,7 @@ export declare class JaypieDistribution extends Construct implements cloudfront.
94
115
  readonly functionUrl?: lambda.FunctionUrl;
95
116
  readonly host?: string;
96
117
  readonly logBucket?: s3.IBucket;
118
+ readonly responseHeadersPolicy?: cloudfront.IResponseHeadersPolicy;
97
119
  constructor(scope: Construct, id: string, props: JaypieDistributionProps);
98
120
  private isIOrigin;
99
121
  private isIFunctionUrl;
@@ -8,19 +8,11 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
8
8
  * - `undefined`: No GSIs (default)
9
9
  * - Array of IndexDefinition: Use the specified indexes
10
10
  *
11
- * Use `JaypieDynamoDb.DEFAULT_INDEXES` for the standard Jaypie GSIs.
12
- *
13
11
  * @example
14
12
  * // No GSIs (default)
15
13
  * new JaypieDynamoDb(this, "myTable");
16
14
  *
17
15
  * @example
18
- * // With default Jaypie indexes
19
- * new JaypieDynamoDb(this, "myTable", {
20
- * indexes: JaypieDynamoDb.DEFAULT_INDEXES,
21
- * });
22
- *
23
- * @example
24
16
  * // With custom indexes
25
17
  * new JaypieDynamoDb(this, "myTable", {
26
18
  * indexes: [
@@ -73,12 +65,6 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
73
65
  * const table = new JaypieDynamoDb(this, "myApp");
74
66
  *
75
67
  * @example
76
- * // With default Jaypie indexes
77
- * const table = new JaypieDynamoDb(this, "myApp", {
78
- * indexes: JaypieDynamoDb.DEFAULT_INDEXES,
79
- * });
80
- *
81
- * @example
82
68
  * // With explicit table name (overrides CDK-generated name)
83
69
  * const table = new JaypieDynamoDb(this, "MyTable", {
84
70
  * tableName: "custom-table-name",
@@ -89,11 +75,6 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
89
75
  * });
90
76
  */
91
77
  export declare class JaypieDynamoDb extends Construct implements dynamodb.ITableV2 {
92
- /**
93
- * Default Jaypie GSI definitions from @jaypie/fabric.
94
- * Pass to `indexes` prop to create all standard GSIs.
95
- */
96
- static readonly DEFAULT_INDEXES: IndexDefinition[];
97
78
  private readonly _table;
98
79
  constructor(scope: Construct, id: string, props?: JaypieDynamoDbProps);
99
80
  /**
@@ -98,6 +98,11 @@ export declare const CDK: {
98
98
  PROJECT: {
99
99
  INFRASTRUCTURE: string;
100
100
  };
101
+ SECURITY_HEADERS: {
102
+ CONTENT_SECURITY_POLICY: string;
103
+ HSTS_MAX_AGE: number;
104
+ PERMISSIONS_POLICY: string;
105
+ };
101
106
  ROLE: {
102
107
  API: string;
103
108
  DEPLOY: string;
@@ -7,7 +7,7 @@ export { JaypieCertificate, JaypieCertificateProps } from "./JaypieCertificate";
7
7
  export { JaypieDatadogBucket, JaypieDatadogBucketProps, } from "./JaypieDatadogBucket";
8
8
  export { JaypieDatadogForwarder, JaypieDatadogForwarderProps, } from "./JaypieDatadogForwarder";
9
9
  export { JaypieDatadogSecret } from "./JaypieDatadogSecret";
10
- export { JaypieDistribution, JaypieDistributionProps, } from "./JaypieDistribution";
10
+ export { JaypieDistribution, JaypieDistributionProps, SecurityHeadersOverrides, } from "./JaypieDistribution";
11
11
  export { JaypieDnsRecord, JaypieDnsRecordProps } from "./JaypieDnsRecord";
12
12
  export { JaypieDynamoDb, JaypieDynamoDbProps } from "./JaypieDynamoDb";
13
13
  export type { IndexDefinition } from "@jaypie/fabric";
package/dist/esm/index.js CHANGED
@@ -25,7 +25,7 @@ import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
25
25
  import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
26
26
  import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
27
27
  import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
28
- import { DEFAULT_INDEXES, generateIndexName, DEFAULT_SORT_KEY } from '@jaypie/fabric';
28
+ import { generateIndexName, DEFAULT_SORT_KEY } from '@jaypie/fabric';
29
29
  import { Nextjs } from 'cdk-nextjs-standalone';
30
30
  import * as path from 'path';
31
31
  import { Trail, ReadWriteType } from 'aws-cdk-lib/aws-cloudtrail';
@@ -135,6 +135,11 @@ const CDK$2 = {
135
135
  PROJECT: {
136
136
  INFRASTRUCTURE: "infrastructure",
137
137
  },
138
+ SECURITY_HEADERS: {
139
+ CONTENT_SECURITY_POLICY: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-ancestors 'none'; base-uri 'self'; form-action 'self';",
140
+ HSTS_MAX_AGE: 63072000, // 2 years
141
+ PERMISSIONS_POLICY: "camera=(), microphone=(), geolocation=(), payment=()",
142
+ },
138
143
  ROLE: {
139
144
  API: "api",
140
145
  DEPLOY: "deploy",
@@ -2330,7 +2335,7 @@ class JaypieDatadogSecret extends JaypieEnvSecret {
2330
2335
  class JaypieDistribution extends Construct {
2331
2336
  constructor(scope, id, props) {
2332
2337
  super(scope, id);
2333
- const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), roleTag = CDK$2.ROLE.API, streaming = false, zone: propsZone, ...distributionProps } = props;
2338
+ const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), responseHeadersPolicy: responseHeadersPolicyProp, roleTag = CDK$2.ROLE.API, securityHeaders: securityHeadersProp, streaming = false, zone: propsZone, ...distributionProps } = props;
2334
2339
  // Validate environment variables
2335
2340
  if (process.env.CDK_ENV_API_SUBDOMAIN &&
2336
2341
  !isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
@@ -2412,6 +2417,72 @@ class JaypieDistribution extends Construct {
2412
2417
  handler.addEnvironment("PROJECT_BASE_URL", `https://${host}`);
2413
2418
  }
2414
2419
  }
2420
+ // Resolve response headers policy for security headers
2421
+ let resolvedResponseHeadersPolicy;
2422
+ if (responseHeadersPolicyProp) {
2423
+ resolvedResponseHeadersPolicy = responseHeadersPolicyProp;
2424
+ }
2425
+ else if (securityHeadersProp !== false) {
2426
+ const overrides = typeof securityHeadersProp === "object" ? securityHeadersProp : {};
2427
+ resolvedResponseHeadersPolicy = new cloudfront.ResponseHeadersPolicy(this, "SecurityHeaders", {
2428
+ customHeadersBehavior: {
2429
+ customHeaders: [
2430
+ {
2431
+ header: "Cache-Control",
2432
+ override: true,
2433
+ value: "no-store, no-cache, must-revalidate, proxy-revalidate",
2434
+ },
2435
+ {
2436
+ header: "Cross-Origin-Embedder-Policy",
2437
+ override: true,
2438
+ value: "unsafe-none",
2439
+ },
2440
+ {
2441
+ header: "Cross-Origin-Opener-Policy",
2442
+ override: true,
2443
+ value: "same-origin",
2444
+ },
2445
+ {
2446
+ header: "Cross-Origin-Resource-Policy",
2447
+ override: true,
2448
+ value: "same-origin",
2449
+ },
2450
+ {
2451
+ header: "Permissions-Policy",
2452
+ override: true,
2453
+ value: overrides.permissionsPolicy ??
2454
+ CDK$2.SECURITY_HEADERS.PERMISSIONS_POLICY,
2455
+ },
2456
+ ],
2457
+ },
2458
+ removeHeaders: ["Server"],
2459
+ securityHeadersBehavior: {
2460
+ contentSecurityPolicy: {
2461
+ contentSecurityPolicy: overrides.contentSecurityPolicy ??
2462
+ CDK$2.SECURITY_HEADERS.CONTENT_SECURITY_POLICY,
2463
+ override: true,
2464
+ },
2465
+ contentTypeOptions: { override: true },
2466
+ frameOptions: {
2467
+ frameOption: overrides.frameOption ?? cloudfront.HeadersFrameOption.DENY,
2468
+ override: true,
2469
+ },
2470
+ referrerPolicy: {
2471
+ referrerPolicy: overrides.referrerPolicy ??
2472
+ cloudfront.HeadersReferrerPolicy
2473
+ .STRICT_ORIGIN_WHEN_CROSS_ORIGIN,
2474
+ override: true,
2475
+ },
2476
+ strictTransportSecurity: {
2477
+ accessControlMaxAge: Duration.seconds(overrides.hstsMaxAge ?? CDK$2.SECURITY_HEADERS.HSTS_MAX_AGE),
2478
+ includeSubdomains: overrides.hstsIncludeSubdomains ?? true,
2479
+ override: true,
2480
+ preload: true,
2481
+ },
2482
+ },
2483
+ });
2484
+ }
2485
+ this.responseHeadersPolicy = resolvedResponseHeadersPolicy;
2415
2486
  // Build default behavior
2416
2487
  let defaultBehavior;
2417
2488
  if (propsDefaultBehavior) {
@@ -2423,6 +2494,9 @@ class JaypieDistribution extends Construct {
2423
2494
  cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED,
2424
2495
  origin,
2425
2496
  originRequestPolicy: cloudfront.OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER,
2497
+ ...(resolvedResponseHeadersPolicy
2498
+ ? { responseHeadersPolicy: resolvedResponseHeadersPolicy }
2499
+ : {}),
2426
2500
  viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
2427
2501
  };
2428
2502
  }
@@ -2730,12 +2804,6 @@ function indexesToGsi(indexes) {
2730
2804
  * const table = new JaypieDynamoDb(this, "myApp");
2731
2805
  *
2732
2806
  * @example
2733
- * // With default Jaypie indexes
2734
- * const table = new JaypieDynamoDb(this, "myApp", {
2735
- * indexes: JaypieDynamoDb.DEFAULT_INDEXES,
2736
- * });
2737
- *
2738
- * @example
2739
2807
  * // With explicit table name (overrides CDK-generated name)
2740
2808
  * const table = new JaypieDynamoDb(this, "MyTable", {
2741
2809
  * tableName: "custom-table-name",
@@ -2874,11 +2942,6 @@ class JaypieDynamoDb extends Construct {
2874
2942
  return this._table.metricUserErrors(props);
2875
2943
  }
2876
2944
  }
2877
- /**
2878
- * Default Jaypie GSI definitions from @jaypie/fabric.
2879
- * Pass to `indexes` prop to create all standard GSIs.
2880
- */
2881
- JaypieDynamoDb.DEFAULT_INDEXES = DEFAULT_INDEXES;
2882
2945
 
2883
2946
  class JaypieEventsRule extends Construct {
2884
2947
  /**