@infoxchange/make-it-so 2.10.0-internal-testing-vdt-199-add-oidc-auth.8 → 2.10.0-internal-testing-vdt-199-add-oidc-auth-3.1

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.
Files changed (25) hide show
  1. package/README.md +24 -2
  2. package/dist/cdk-constructs/CloudFrontOidcAuth/auth-check.d.ts.map +1 -0
  3. package/dist/cdk-constructs/CloudFrontOidcAuth/auth-route.d.ts.map +1 -0
  4. package/dist/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/auth-route.js +2 -5
  5. package/dist/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/index.d.ts +1 -1
  6. package/dist/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/index.d.ts.map +1 -1
  7. package/dist/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/index.js +5 -3
  8. package/dist/cdk-constructs/index.d.ts +1 -1
  9. package/dist/cdk-constructs/index.js +1 -1
  10. package/package.json +2 -3
  11. package/src/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/auth-check.ts +12 -5
  12. package/src/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/auth-route.ts +9 -14
  13. package/src/cdk-constructs/CloudFrontOidcAuth/cloudfront.d.ts +245 -0
  14. package/src/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/index.ts +21 -12
  15. package/src/cdk-constructs/index.ts +1 -1
  16. package/dist/cdk-constructs/CloudWatchOidcAuth/auth-check.d.ts.map +0 -1
  17. package/dist/cdk-constructs/CloudWatchOidcAuth/auth-route.d.ts.map +0 -1
  18. package/dist/lib/utils/source-code.d.ts +0 -2
  19. package/dist/lib/utils/source-code.d.ts.map +0 -1
  20. package/dist/lib/utils/source-code.js +0 -1
  21. package/src/cdk-constructs/CloudWatchOidcAuth/cloudfront.d.ts +0 -243
  22. package/src/lib/utils/source-code.ts +0 -0
  23. /package/dist/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/auth-check.d.ts +0 -0
  24. /package/dist/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/auth-check.js +0 -0
  25. /package/dist/cdk-constructs/{CloudWatchOidcAuth → CloudFrontOidcAuth}/auth-route.d.ts +0 -0
package/README.md CHANGED
@@ -13,8 +13,6 @@ npm --save-dev @infoxchange/make-it-so
13
13
  yarn add --dev @infoxchange/make-it-so
14
14
  ```
15
15
 
16
-
17
-
18
16
  ## Features
19
17
 
20
18
  ### deployConfig
@@ -292,6 +290,30 @@ const vpcDetails = new IxVpcDetails(scope, "VpcDetails");
292
290
 
293
291
  </details>
294
292
 
293
+ <details>
294
+ <summary><strong>CloudFrontOidcAuth</strong> - Adds OIDC authentication to a CloudFront distribution.</summary>
295
+
296
+ ```typescript
297
+ import { CloudWatchOidcAuth } from "@infoxchange/make-it-so/cdk-constructs";
298
+
299
+ // You first create an instance of CloudFrontOidcAuth
300
+ const auth = new CloudFrontOidcAuth(stack, "CloudFrontOidcAuth", {
301
+ oidcIssuerUrl: "https://your-oidc-server.com/path/",
302
+ oidcClientId: "your-client-id",
303
+ oidcScope: "email",
304
+ });
305
+
306
+ // Then you apply it to the a CloudFront backed site when it's created
307
+ const site = new IxStaticSite(stack, "IxStaticSite", {
308
+ path: "path/to/site/files",
309
+ cdk: {
310
+ distribution: auth.addToDistributionDefinition(stack, {
311
+ distributionDefinition: {},
312
+ }),
313
+ },
314
+ });
315
+ ```
316
+
295
317
  ## Full Example
296
318
 
297
319
  To deploy a Next.js based site you would include a `sst.config.ts` file at the root of repo with contents like this:
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-check.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudFrontOidcAuth/auth-check.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-route.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudFrontOidcAuth/auth-route.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,OAAO,4CAiCnB,CAAC"}
@@ -24,8 +24,7 @@ export const handler = addRequiredContext(AuthHandler({
24
24
  issuer: await Issuer.discover(oidcIssuerConfigUrl.href),
25
25
  clientID: oidcClientId,
26
26
  scope: oidcScope,
27
- onSuccess: async (tokenset, client) => {
28
- console.log("🟣", client);
27
+ onSuccess: async (tokenset) => {
29
28
  // Payload to include in the token
30
29
  const payload = {
31
30
  userID: tokenset.claims().sub,
@@ -52,11 +51,9 @@ export const handler = addRequiredContext(AuthHandler({
52
51
  }));
53
52
  function addRequiredContext(handler) {
54
53
  return async function (...args) {
55
- const [event, context] = args;
54
+ const [event] = args;
56
55
  // Used by AuthHandler to create callback url sent to oidc server
57
56
  event.requestContext.domainName = event.headers["x-forwarded-host"];
58
- console.log("🟢 event", event);
59
- console.log("🔵 context", context);
60
57
  return await handler(...args);
61
58
  };
62
59
  }
@@ -10,7 +10,7 @@ type Props = {
10
10
  oidcClientId: string;
11
11
  oidcScope: string;
12
12
  };
13
- export declare class CloudWatchOidcAuth extends Construct {
13
+ export declare class CloudFrontOidcAuth extends Construct {
14
14
  readonly oidcIssuerUrl: string;
15
15
  readonly oidcClientId: string;
16
16
  readonly oidcScope: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudWatchOidcAuth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AASvC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAI1E,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,KAAK,WAAW,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9D,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAER,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;IAQhE,2BAA2B,CACzB,iBAAiB,SAAS,4BAA4B,EAEtD,KAAK,EAAE,cAAc,EACrB,EACE,sBAAsB,EACtB,MAAgB,GACjB,EAAE;QAAE,sBAAsB,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAuC5E,OAAO,CAAC,sBAAsB;IAyH9B,OAAO,CAAC,sBAAsB;CA0E/B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudFrontOidcAuth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AASvC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAI1E,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,KAAK,WAAW,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9D,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAER,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;IAQhE,2BAA2B,CACzB,iBAAiB,SAAS,4BAA4B,EAEtD,KAAK,EAAE,cAAc,EACrB,EACE,sBAAsB,EACtB,MAAgB,GACjB,EAAE;QAAE,sBAAsB,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAuC5E,OAAO,CAAC,sBAAsB;IA8H9B,OAAO,CAAC,sBAAsB;CA8E/B"}
@@ -9,7 +9,7 @@ import { Config as SSTInternalConfig } from "sst/config.js";
9
9
  import CloudFrontOrigins from "aws-cdk-lib/aws-cloudfront-origins";
10
10
  import path from "node:path";
11
11
  import fs from "node:fs";
12
- export class CloudWatchOidcAuth extends Construct {
12
+ export class CloudFrontOidcAuth extends Construct {
13
13
  oidcIssuerUrl;
14
14
  oidcClientId;
15
15
  oidcScope;
@@ -126,7 +126,9 @@ export class CloudWatchOidcAuth extends Construct {
126
126
  }
127
127
  fn.addEnvironment("NODE_OPTIONS", "--require=@aws-sdk/signature-v4-crt");
128
128
  const authCheckFunction = new CloudFront.Function(scope, `${this.id}AuthCheckFunction`, {
129
- code: CloudFront.FunctionCode.fromInline(fs.readFileSync(path.join(import.meta.dirname, "auth-check.js"), "utf8").replace("__placeholder-for-jwt-secret-key__", key)),
129
+ code: CloudFront.FunctionCode.fromInline(fs
130
+ .readFileSync(path.join(import.meta.dirname, "auth-check.js"), "utf8")
131
+ .replace("__placeholder-for-jwt-secret-key__", key)),
130
132
  runtime: CloudFront.FunctionRuntime.JS_2_0,
131
133
  keyValueStore: cfKeyValueStore,
132
134
  });
@@ -172,7 +174,7 @@ export class CloudWatchOidcAuth extends Construct {
172
174
  origin: new CloudFrontOrigins.HttpOrigin(CDK.Fn.parseDomainName(authRouteFunctionUrl.url)),
173
175
  allowedMethods: CloudFront.AllowedMethods.ALLOW_ALL,
174
176
  cachePolicy: new CloudFront.CachePolicy(scope, `${this.id}AllowAllCookiesPolicy`, {
175
- cachePolicyName: "AllowAllCookiesPolicy",
177
+ cachePolicyName: `${this.id}-AllowAllCookiesPolicy`,
176
178
  comment: "Cache policy that forwards all cookies",
177
179
  defaultTtl: CDK.Duration.seconds(1),
178
180
  minTtl: CDK.Duration.seconds(1),
@@ -6,5 +6,5 @@ export * from "./IxStaticSite.js";
6
6
  export * from "./IxElasticache.js";
7
7
  export * from "./IxApi.js";
8
8
  export * from "./IxQuicksightWorkspace.js";
9
- export * from "./CloudWatchOidcAuth/index.js";
9
+ export * from "./CloudFrontOidcAuth/index.js";
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -6,4 +6,4 @@ export * from "./IxStaticSite.js";
6
6
  export * from "./IxElasticache.js";
7
7
  export * from "./IxApi.js";
8
8
  export * from "./IxQuicksightWorkspace.js";
9
- export * from "./CloudWatchOidcAuth/index.js";
9
+ export * from "./CloudFrontOidcAuth/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infoxchange/make-it-so",
3
- "version": "2.10.0-internal-testing-vdt-199-add-oidc-auth.8",
3
+ "version": "2.10.0-internal-testing-vdt-199-add-oidc-auth-3.1",
4
4
  "description": "Makes deploying services to IX infra easy",
5
5
  "repository": "github:infoxchange/make-it-so",
6
6
  "type": "module",
@@ -30,6 +30,7 @@
30
30
  "@commitlint/prompt-cli": "^19.3.1",
31
31
  "@eslint/js": "^9.3.0",
32
32
  "@tsconfig/node21": "^21.0.3",
33
+ "@types/aws-cloudfront-function": "^1.0.6",
33
34
  "@types/jsonwebtoken": "^9.0.10",
34
35
  "aws-cdk-lib": "2.142.1",
35
36
  "constructs": "^10.3.0",
@@ -51,8 +52,6 @@
51
52
  "sst": "^2.0.0"
52
53
  },
53
54
  "dependencies": {
54
- "@aws-sdk/client-lambda": "^3.920.0",
55
- "@types/aws-cloudfront-function": "^1.0.6",
56
55
  "jsonwebtoken": "^9.0.2",
57
56
  "zod": "^3.24.2"
58
57
  }
@@ -72,7 +72,13 @@ function _constantTimeEquals(a: string, b: string) {
72
72
  return 0 === xor;
73
73
  }
74
74
 
75
- function _verify(input: string, key: string, method: string, type: string, signature: string) {
75
+ function _verify(
76
+ input: string,
77
+ key: string,
78
+ method: string,
79
+ type: string,
80
+ signature: string,
81
+ ) {
76
82
  if (type === "hmac") {
77
83
  return _constantTimeEquals(signature, _sign(input, key, method));
78
84
  } else {
@@ -97,7 +103,8 @@ async function handler(event: AWSCloudFrontFunction.Event) {
97
103
  throw new Error("Error retrieving JWT secret key");
98
104
  }
99
105
 
100
- const jwtToken = request.cookies["auth-token"] && request.cookies["auth-token"].value;
106
+ const jwtToken =
107
+ request.cookies["auth-token"] && request.cookies["auth-token"].value;
101
108
 
102
109
  if (!jwtToken) {
103
110
  log("Error: No JWT in the cookies");
@@ -130,18 +137,18 @@ const log: typeof console.log = function () {
130
137
 
131
138
  // CloudFront Function runtime only prints first argument passed to console.log so add other args to the first one if given.
132
139
  // eslint-disable-next-line prefer-rest-params -- We can't use spread or rest parameters in CloudFront Functions
133
- let message = arguments[0]
140
+ let message = arguments[0];
134
141
  if (arguments.length > 1) {
135
142
  const otherArgs = [];
136
143
  for (let i = 1; i < arguments.length; i++) {
137
144
  // eslint-disable-next-line prefer-rest-params
138
- otherArgs[i-1] = arguments[i];
145
+ otherArgs[i - 1] = arguments[i];
139
146
  }
140
147
 
141
148
  message += " - additional args: " + JSON.stringify(otherArgs);
142
149
  }
143
150
  console.log(message);
144
- }
151
+ };
145
152
 
146
153
  // This serves no purpose other than to make TypeScript and eslint happy by showing that that handler is used. We can't
147
154
  // export handler as an alterative because CloudFront Functions don't support exports.
@@ -30,8 +30,7 @@ export const handler = addRequiredContext(
30
30
  issuer: await Issuer.discover(oidcIssuerConfigUrl.href),
31
31
  clientID: oidcClientId,
32
32
  scope: oidcScope,
33
- onSuccess: async (tokenset, client) => {
34
- console.log("🟣", client);
33
+ onSuccess: async (tokenset) => {
35
34
  // Payload to include in the token
36
35
  const payload = {
37
36
  userID: tokenset.claims().sub,
@@ -39,14 +38,10 @@ export const handler = addRequiredContext(
39
38
  const expiresInMs = 1000 * 60 * 60;
40
39
 
41
40
  // Create the token
42
- const token = jwt.sign(
43
- payload,
44
- jwtSecret,
45
- {
46
- algorithm: "HS256",
47
- expiresIn: expiresInMs / 1000,
48
- }
49
- );
41
+ const token = jwt.sign(payload, jwtSecret, {
42
+ algorithm: "HS256",
43
+ expiresIn: expiresInMs / 1000,
44
+ });
50
45
  const expiryDate = new Date(Date.now() + expiresInMs);
51
46
  return {
52
47
  statusCode: 302,
@@ -63,13 +58,13 @@ export const handler = addRequiredContext(
63
58
  }),
64
59
  );
65
60
 
66
- function addRequiredContext(handler: ReturnType<typeof AuthHandler>): ReturnType<typeof AuthHandler> {
61
+ function addRequiredContext(
62
+ handler: ReturnType<typeof AuthHandler>,
63
+ ): ReturnType<typeof AuthHandler> {
67
64
  return async function (...args) {
68
- const [event, context] = args;
65
+ const [event] = args;
69
66
  // Used by AuthHandler to create callback url sent to oidc server
70
67
  event.requestContext.domainName = event.headers["x-forwarded-host"];
71
- console.log("🟢 event", event)
72
- console.log("🔵 context", context)
73
68
 
74
69
  return await handler(...args);
75
70
  };
@@ -0,0 +1,245 @@
1
+ // NOTE: once this is no longer needed we can remove typeRoots from tsconfig.json as well
2
+
3
+ // This is a copy of @types/aws-cloudfront-function but with optional kvsId in kvs() function. We can't just modify the
4
+ // kvs type since we can't modify the default export without messing up the rest of the types. Which is why we
5
+ // unfortunately have to duplicate the whole file here.
6
+ // But once https://github.com/DefinitelyTyped/DefinitelyTyped/issues/73959 is sorted we can get rid of this.
7
+
8
+ declare namespace AWSCloudFrontFunction {
9
+ interface Event {
10
+ version: "1.0";
11
+ context: Context;
12
+ viewer: Viewer;
13
+ request: Request;
14
+ response: Response;
15
+ }
16
+
17
+ interface Context {
18
+ distributionDomainName: string;
19
+ distributionId: string;
20
+ eventType: "viewer-request" | "viewer-response";
21
+ requestId: string;
22
+ }
23
+
24
+ interface Viewer {
25
+ ip: string;
26
+ }
27
+
28
+ interface Request {
29
+ method: string;
30
+ uri: string;
31
+ querystring: ValueObject;
32
+ headers: ValueObject;
33
+ cookies: ValueObject;
34
+ }
35
+
36
+ interface Response {
37
+ statusCode: number;
38
+ statusDescription?: string;
39
+ headers?: ValueObject;
40
+ cookies?: ResponseCookie;
41
+ body?: string | ResponseBody;
42
+ }
43
+
44
+ interface ResponseBody {
45
+ data: string;
46
+ encoding: "text" | "base64";
47
+ }
48
+
49
+ interface ValueObject {
50
+ [name: string]: {
51
+ value: string;
52
+ multiValue?: Array<{
53
+ value: string;
54
+ }>;
55
+ };
56
+ }
57
+
58
+ interface ResponseCookie {
59
+ [name: string]: {
60
+ value: string;
61
+ attributes: string;
62
+ multiValue?: Array<{
63
+ value: string;
64
+ attributes: string;
65
+ }>;
66
+ };
67
+ }
68
+ }
69
+
70
+ declare module "cloudfront" {
71
+ /**
72
+ * Retrieves a reference to a CloudFront Key-Value Store (KVS) by its ID.
73
+ * @param kvsId The identifier of the KVS to use.
74
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-custom-methods.html
75
+ */
76
+ function kvs(kvsId?: string): KVStore;
77
+
78
+ interface KVStore {
79
+ /**
80
+ * Retrieve a value from the store.
81
+ * @param key Key to retrieve.
82
+ * @throws If key does not exist.
83
+ */
84
+ get(key: string): Promise<string>;
85
+ get(key: string, options: { format: "string" }): Promise<string>;
86
+ get(key: string, options: { format: "bytes" }): Promise<Uint8Array>;
87
+ get(key: string, options: { format: "json" }): Promise<unknown>;
88
+
89
+ /**
90
+ * Check if the key exists in the store.
91
+ * @param key Key to check.
92
+ */
93
+ exists(key: string): Promise<boolean>;
94
+
95
+ /**
96
+ * Retrieve metadata about the key-value store.
97
+ */
98
+ meta(): Promise<{
99
+ creationDateTime: string;
100
+ lastUpdatedDateTime: string;
101
+ keyCount: number;
102
+ }>;
103
+ }
104
+
105
+ interface OriginAccessControlConfig {
106
+ enabled: boolean;
107
+ signingBehavior: "always" | "never" | "no-override";
108
+ signingProtocol: "sigv4";
109
+ originType: "s3" | "mediapackagev2" | "mediastore" | "lambda";
110
+ }
111
+
112
+ interface OriginShield {
113
+ enabled: boolean;
114
+ region: string;
115
+ }
116
+
117
+ interface Timeouts {
118
+ /**
119
+ * Max time (seconds) to wait for a response or next packet. (1–60)
120
+ */
121
+ readTimeout?: number;
122
+
123
+ /**
124
+ * Max time (seconds) to keep the connection alive after response. (1–60)
125
+ */
126
+ keepAliveTimeout?: number;
127
+
128
+ /**
129
+ * Max time (seconds) to wait for connection establishment. (1–10)
130
+ */
131
+ connectionTimeout?: number;
132
+ }
133
+
134
+ interface CustomOriginConfig {
135
+ /**
136
+ * Port number of the origin. e.g., 80 or 443
137
+ */
138
+ port: number;
139
+
140
+ /**
141
+ * Protocol used to connect. Must be "http" or "https"
142
+ */
143
+ protocol: "http" | "https";
144
+
145
+ /**
146
+ * Minimum TLS/SSL version to use for HTTPS connections.
147
+ */
148
+ sslProtocols: Array<"SSLv3" | "TLSv1" | "TLSv1.1" | "TLSv1.2">;
149
+ }
150
+
151
+ interface UpdateRequestOriginParams {
152
+ /**
153
+ * New origin's domain name. Optional if reusing existing origin's domain.
154
+ */
155
+ domainName?: string;
156
+
157
+ /**
158
+ * Path prefix to append when forwarding request to origin.
159
+ */
160
+ originPath?: string;
161
+
162
+ /**
163
+ * Override or clear custom headers for the origin request.
164
+ */
165
+ customHeaders?: Record<string, string>;
166
+
167
+ /**
168
+ * Number of connection attempts (1–3).
169
+ */
170
+ connectionAttempts?: number;
171
+
172
+ /**
173
+ * Origin Shield configuration. Enables shield layer if specified.
174
+ */
175
+ originShield?: OriginShield;
176
+
177
+ /**
178
+ * Origin Access Control (OAC) configuration.
179
+ */
180
+ originAccessControlConfig?: OriginAccessControlConfig;
181
+
182
+ /**
183
+ * Response and connection timeout configurations.
184
+ */
185
+ timeouts?: Timeouts;
186
+
187
+ /**
188
+ * Settings for non-S3 origins or S3 with static website hosting.
189
+ */
190
+ customOriginConfig?: CustomOriginConfig;
191
+ }
192
+
193
+ /**
194
+ * Mutates the current request’s origin.
195
+ * You can specify a new origin (e.g., S3 or ALB), change custom headers, enable OAC, or enable Origin Shield.
196
+ * Missing fields will inherit values from the assigned origin.
197
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/helper-functions-origin-modification.html#update-request-origin-helper-function
198
+ */
199
+ function updateRequestOrigin(params: UpdateRequestOriginParams): void;
200
+
201
+ /**
202
+ * Switches to another origin already defined in the distribution by origin ID.
203
+ * This is more efficient than defining a new one via `updateRequestOrigin()`.
204
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/helper-functions-origin-modification.html#select-request-origin-id-helper-function
205
+ */
206
+ function selectRequestOriginById(originId: string): void;
207
+
208
+ interface CreateRequestOriginGroupParams {
209
+ /**
210
+ * Two origin IDs to form an origin group.
211
+ * The first is primary; the second is used for failover.
212
+ */
213
+ originIds: [string, string];
214
+
215
+ /**
216
+ * Failover selection strategy: default or media-quality-score.
217
+ */
218
+ selectionCriteria?: "default" | "media-quality-score";
219
+
220
+ /**
221
+ * List of status codes that trigger failover to the secondary origin.
222
+ */
223
+ failoverCriteria: {
224
+ statusCodes: number[];
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Creates a new origin group for failover logic.
230
+ * The origin group can be referenced later via origin ID.
231
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/helper-functions-origin-modification.html#create-request-origin-group-helper-function
232
+ */
233
+ function createRequestOriginGroup(
234
+ params: CreateRequestOriginGroupParams,
235
+ ): void;
236
+
237
+ const cf: {
238
+ kvs: typeof kvs;
239
+ updateRequestOrigin: typeof updateRequestOrigin;
240
+ selectRequestOriginById: typeof selectRequestOriginById;
241
+ createRequestOriginGroup: typeof createRequestOriginGroup;
242
+ };
243
+
244
+ export default cf;
245
+ }
@@ -24,7 +24,7 @@ type Props = {
24
24
  oidcScope: string;
25
25
  };
26
26
 
27
- export class CloudWatchOidcAuth extends Construct {
27
+ export class CloudFrontOidcAuth extends Construct {
28
28
  readonly oidcIssuerUrl: string;
29
29
  readonly oidcClientId: string;
30
30
  readonly oidcScope: string;
@@ -192,7 +192,12 @@ export class CloudWatchOidcAuth extends Construct {
192
192
  `${this.id}AuthCheckFunction`,
193
193
  {
194
194
  code: CloudFront.FunctionCode.fromInline(
195
- fs.readFileSync(path.join(import.meta.dirname, "auth-check.js"), "utf8").replace("__placeholder-for-jwt-secret-key__", key),
195
+ fs
196
+ .readFileSync(
197
+ path.join(import.meta.dirname, "auth-check.js"),
198
+ "utf8",
199
+ )
200
+ .replace("__placeholder-for-jwt-secret-key__", key),
196
201
  ),
197
202
  runtime: CloudFront.FunctionRuntime.JS_2_0,
198
203
  keyValueStore: cfKeyValueStore,
@@ -210,16 +215,20 @@ export class CloudWatchOidcAuth extends Construct {
210
215
  jwtSecret: SecretsManager.Secret,
211
216
  prefix: string,
212
217
  ): CloudFront.BehaviorOptions {
213
- const authRouteFunction = new SST.Function(scope, `${this.id}AuthRouteFunction`, {
214
- runtime: "nodejs20.x",
215
- handler: path.join(import.meta.dirname, "auth-route.handler"),
216
- environment: {
217
- OIDC_ISSUER_URL: this.oidcIssuerUrl,
218
- OIDC_CLIENT_ID: this.oidcClientId,
219
- OIDC_SCOPE: this.oidcScope,
220
- JWT_SECRET: jwtSecret.secretValue.toString(),
218
+ const authRouteFunction = new SST.Function(
219
+ scope,
220
+ `${this.id}AuthRouteFunction`,
221
+ {
222
+ runtime: "nodejs20.x",
223
+ handler: path.join(import.meta.dirname, "auth-route.handler"),
224
+ environment: {
225
+ OIDC_ISSUER_URL: this.oidcIssuerUrl,
226
+ OIDC_CLIENT_ID: this.oidcClientId,
227
+ OIDC_SCOPE: this.oidcScope,
228
+ JWT_SECRET: jwtSecret.secretValue.toString(),
229
+ },
221
230
  },
222
- });
231
+ );
223
232
 
224
233
  // authRouteFunction uses SST's AuthHandler construct which is normally run inside a lambda that's
225
234
  // created by SST's Auth construct. AuthHandler expects certain environment variables to be set
@@ -258,7 +267,7 @@ export class CloudWatchOidcAuth extends Construct {
258
267
  scope,
259
268
  `${this.id}AllowAllCookiesPolicy`,
260
269
  {
261
- cachePolicyName: "AllowAllCookiesPolicy",
270
+ cachePolicyName: `${this.id}-AllowAllCookiesPolicy`,
262
271
  comment: "Cache policy that forwards all cookies",
263
272
  defaultTtl: CDK.Duration.seconds(1),
264
273
  minTtl: CDK.Duration.seconds(1),
@@ -6,4 +6,4 @@ export * from "./IxStaticSite.js";
6
6
  export * from "./IxElasticache.js";
7
7
  export * from "./IxApi.js";
8
8
  export * from "./IxQuicksightWorkspace.js";
9
- export * from "./CloudWatchOidcAuth/index.js";
9
+ export * from "./CloudFrontOidcAuth/index.js";
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-check.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudWatchOidcAuth/auth-check.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-route.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudWatchOidcAuth/auth-route.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,OAAO,4CAsCnB,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=source-code.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"source-code.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/source-code.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export {};
@@ -1,243 +0,0 @@
1
- // NOTE: once this is no longer needed we can remove typeRoots from tsconfig.json as well
2
-
3
- // This is a copy of @types/aws-cloudfront-function but with optional kvsId in kvs() function. We can't just modify the
4
- // kvs type since we can't modify the default export without messing up the rest of the types. Which is why we
5
- // unfortunately have to duplicate the whole file here.
6
- // But once https://github.com/DefinitelyTyped/DefinitelyTyped/issues/73959 is sorted we can get rid of this.
7
-
8
- declare namespace AWSCloudFrontFunction {
9
- interface Event {
10
- version: "1.0";
11
- context: Context;
12
- viewer: Viewer;
13
- request: Request;
14
- response: Response;
15
- }
16
-
17
- interface Context {
18
- distributionDomainName: string;
19
- distributionId: string;
20
- eventType: "viewer-request" | "viewer-response";
21
- requestId: string;
22
- }
23
-
24
- interface Viewer {
25
- ip: string;
26
- }
27
-
28
- interface Request {
29
- method: string;
30
- uri: string;
31
- querystring: ValueObject;
32
- headers: ValueObject;
33
- cookies: ValueObject;
34
- }
35
-
36
- interface Response {
37
- statusCode: number;
38
- statusDescription?: string;
39
- headers?: ValueObject;
40
- cookies?: ResponseCookie;
41
- body?: string | ResponseBody;
42
- }
43
-
44
- interface ResponseBody {
45
- data: string;
46
- encoding: "text" | "base64";
47
- }
48
-
49
- interface ValueObject {
50
- [name: string]: {
51
- value: string;
52
- multiValue?: Array<{
53
- value: string;
54
- }>;
55
- };
56
- }
57
-
58
- interface ResponseCookie {
59
- [name: string]: {
60
- value: string;
61
- attributes: string;
62
- multiValue?: Array<{
63
- value: string;
64
- attributes: string;
65
- }>;
66
- };
67
- }
68
- }
69
-
70
- declare module "cloudfront" {
71
- /**
72
- * Retrieves a reference to a CloudFront Key-Value Store (KVS) by its ID.
73
- * @param kvsId The identifier of the KVS to use.
74
- * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-custom-methods.html
75
- */
76
- function kvs(kvsId?: string): KVStore;
77
-
78
- interface KVStore {
79
- /**
80
- * Retrieve a value from the store.
81
- * @param key Key to retrieve.
82
- * @throws If key does not exist.
83
- */
84
- get(key: string): Promise<string>;
85
- get(key: string, options: { format: "string" }): Promise<string>;
86
- get(key: string, options: { format: "bytes" }): Promise<Uint8Array>;
87
- get(key: string, options: { format: "json" }): Promise<unknown>;
88
-
89
- /**
90
- * Check if the key exists in the store.
91
- * @param key Key to check.
92
- */
93
- exists(key: string): Promise<boolean>;
94
-
95
- /**
96
- * Retrieve metadata about the key-value store.
97
- */
98
- meta(): Promise<{
99
- creationDateTime: string;
100
- lastUpdatedDateTime: string;
101
- keyCount: number;
102
- }>;
103
- }
104
-
105
- interface OriginAccessControlConfig {
106
- enabled: boolean;
107
- signingBehavior: "always" | "never" | "no-override";
108
- signingProtocol: "sigv4";
109
- originType: "s3" | "mediapackagev2" | "mediastore" | "lambda";
110
- }
111
-
112
- interface OriginShield {
113
- enabled: boolean;
114
- region: string;
115
- }
116
-
117
- interface Timeouts {
118
- /**
119
- * Max time (seconds) to wait for a response or next packet. (1–60)
120
- */
121
- readTimeout?: number;
122
-
123
- /**
124
- * Max time (seconds) to keep the connection alive after response. (1–60)
125
- */
126
- keepAliveTimeout?: number;
127
-
128
- /**
129
- * Max time (seconds) to wait for connection establishment. (1–10)
130
- */
131
- connectionTimeout?: number;
132
- }
133
-
134
- interface CustomOriginConfig {
135
- /**
136
- * Port number of the origin. e.g., 80 or 443
137
- */
138
- port: number;
139
-
140
- /**
141
- * Protocol used to connect. Must be "http" or "https"
142
- */
143
- protocol: "http" | "https";
144
-
145
- /**
146
- * Minimum TLS/SSL version to use for HTTPS connections.
147
- */
148
- sslProtocols: Array<"SSLv3" | "TLSv1" | "TLSv1.1" | "TLSv1.2">;
149
- }
150
-
151
- interface UpdateRequestOriginParams {
152
- /**
153
- * New origin's domain name. Optional if reusing existing origin's domain.
154
- */
155
- domainName?: string;
156
-
157
- /**
158
- * Path prefix to append when forwarding request to origin.
159
- */
160
- originPath?: string;
161
-
162
- /**
163
- * Override or clear custom headers for the origin request.
164
- */
165
- customHeaders?: Record<string, string>;
166
-
167
- /**
168
- * Number of connection attempts (1–3).
169
- */
170
- connectionAttempts?: number;
171
-
172
- /**
173
- * Origin Shield configuration. Enables shield layer if specified.
174
- */
175
- originShield?: OriginShield;
176
-
177
- /**
178
- * Origin Access Control (OAC) configuration.
179
- */
180
- originAccessControlConfig?: OriginAccessControlConfig;
181
-
182
- /**
183
- * Response and connection timeout configurations.
184
- */
185
- timeouts?: Timeouts;
186
-
187
- /**
188
- * Settings for non-S3 origins or S3 with static website hosting.
189
- */
190
- customOriginConfig?: CustomOriginConfig;
191
- }
192
-
193
- /**
194
- * Mutates the current request’s origin.
195
- * You can specify a new origin (e.g., S3 or ALB), change custom headers, enable OAC, or enable Origin Shield.
196
- * Missing fields will inherit values from the assigned origin.
197
- * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/helper-functions-origin-modification.html#update-request-origin-helper-function
198
- */
199
- function updateRequestOrigin(params: UpdateRequestOriginParams): void;
200
-
201
- /**
202
- * Switches to another origin already defined in the distribution by origin ID.
203
- * This is more efficient than defining a new one via `updateRequestOrigin()`.
204
- * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/helper-functions-origin-modification.html#select-request-origin-id-helper-function
205
- */
206
- function selectRequestOriginById(originId: string): void;
207
-
208
- interface CreateRequestOriginGroupParams {
209
- /**
210
- * Two origin IDs to form an origin group.
211
- * The first is primary; the second is used for failover.
212
- */
213
- originIds: [string, string];
214
-
215
- /**
216
- * Failover selection strategy: default or media-quality-score.
217
- */
218
- selectionCriteria?: "default" | "media-quality-score";
219
-
220
- /**
221
- * List of status codes that trigger failover to the secondary origin.
222
- */
223
- failoverCriteria: {
224
- statusCodes: number[];
225
- };
226
- }
227
-
228
- /**
229
- * Creates a new origin group for failover logic.
230
- * The origin group can be referenced later via origin ID.
231
- * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/helper-functions-origin-modification.html#create-request-origin-group-helper-function
232
- */
233
- function createRequestOriginGroup(params: CreateRequestOriginGroupParams): void;
234
-
235
- const cf: {
236
- kvs: typeof kvs;
237
- updateRequestOrigin: typeof updateRequestOrigin;
238
- selectRequestOriginById: typeof selectRequestOriginById;
239
- createRequestOriginGroup: typeof createRequestOriginGroup;
240
- };
241
-
242
- export default cf;
243
- }
File without changes