@infoxchange/make-it-so-sst-v2 1.0.0-internal-testing-disambiguate-release-id-bc6e5bb.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.
- package/.editorconfig +16 -0
- package/LICENSE +21 -0
- package/README.md +377 -0
- package/commitlint.config.ts +14 -0
- package/dist/cdk-constructs/IxApi.d.ts +12 -0
- package/dist/cdk-constructs/IxApi.d.ts.map +1 -0
- package/dist/cdk-constructs/IxApi.js +56 -0
- package/dist/cdk-constructs/IxBucket.d.ts +9 -0
- package/dist/cdk-constructs/IxBucket.d.ts.map +1 -0
- package/dist/cdk-constructs/IxBucket.js +22 -0
- package/dist/cdk-constructs/IxCertificate.d.ts +16 -0
- package/dist/cdk-constructs/IxCertificate.d.ts.map +1 -0
- package/dist/cdk-constructs/IxCertificate.js +26 -0
- package/dist/cdk-constructs/IxDnsRecord.d.ts +23 -0
- package/dist/cdk-constructs/IxDnsRecord.d.ts.map +1 -0
- package/dist/cdk-constructs/IxDnsRecord.js +43 -0
- package/dist/cdk-constructs/IxElasticache.d.ts +17 -0
- package/dist/cdk-constructs/IxElasticache.d.ts.map +1 -0
- package/dist/cdk-constructs/IxElasticache.js +70 -0
- package/dist/cdk-constructs/IxNextjsSite.d.ts +16 -0
- package/dist/cdk-constructs/IxNextjsSite.d.ts.map +1 -0
- package/dist/cdk-constructs/IxNextjsSite.js +38 -0
- package/dist/cdk-constructs/IxQuicksightWorkspace.d.ts +17 -0
- package/dist/cdk-constructs/IxQuicksightWorkspace.d.ts.map +1 -0
- package/dist/cdk-constructs/IxQuicksightWorkspace.js +29 -0
- package/dist/cdk-constructs/IxSESIdentity.d.ts +12 -0
- package/dist/cdk-constructs/IxSESIdentity.d.ts.map +1 -0
- package/dist/cdk-constructs/IxSESIdentity.js +45 -0
- package/dist/cdk-constructs/IxStaticSite.d.ts +17 -0
- package/dist/cdk-constructs/IxStaticSite.d.ts.map +1 -0
- package/dist/cdk-constructs/IxStaticSite.js +38 -0
- package/dist/cdk-constructs/IxVpcDetails.d.ts +12 -0
- package/dist/cdk-constructs/IxVpcDetails.d.ts.map +1 -0
- package/dist/cdk-constructs/IxVpcDetails.js +26 -0
- package/dist/cdk-constructs/IxWebsiteRedirect.d.ts +35 -0
- package/dist/cdk-constructs/IxWebsiteRedirect.d.ts.map +1 -0
- package/dist/cdk-constructs/IxWebsiteRedirect.js +72 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-check-handler-body.d.ts +2 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-check-handler-body.d.ts.map +1 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-check-handler-body.js +130 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-route.d.ts +2 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-route.d.ts.map +1 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-route.js +59 -0
- package/dist/cdk-constructs/SiteOidcAuth/index.d.ts +197 -0
- package/dist/cdk-constructs/SiteOidcAuth/index.d.ts.map +1 -0
- package/dist/cdk-constructs/SiteOidcAuth/index.js +188 -0
- package/dist/cdk-constructs/index.d.ts +11 -0
- package/dist/cdk-constructs/index.d.ts.map +1 -0
- package/dist/cdk-constructs/index.js +10 -0
- package/dist/deployConfig.d.ts +72 -0
- package/dist/deployConfig.d.ts.map +1 -0
- package/dist/deployConfig.js +78 -0
- package/dist/lib/auth/index.d.ts +2 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +1 -0
- package/dist/lib/auth/oidc.d.ts +26 -0
- package/dist/lib/auth/oidc.d.ts.map +1 -0
- package/dist/lib/auth/oidc.js +48 -0
- package/dist/lib/proxy/fetch.d.ts +4 -0
- package/dist/lib/proxy/fetch.d.ts.map +1 -0
- package/dist/lib/proxy/fetch.js +31 -0
- package/dist/lib/proxy/index.d.ts +2 -0
- package/dist/lib/proxy/index.d.ts.map +1 -0
- package/dist/lib/proxy/index.js +1 -0
- package/dist/lib/site/support.d.ts +71 -0
- package/dist/lib/site/support.d.ts.map +1 -0
- package/dist/lib/site/support.js +262 -0
- package/dist/lib/utils/hash.d.ts +2 -0
- package/dist/lib/utils/hash.d.ts.map +1 -0
- package/dist/lib/utils/hash.js +13 -0
- package/dist/lib/utils/objects.d.ts +4 -0
- package/dist/lib/utils/objects.d.ts.map +1 -0
- package/dist/lib/utils/objects.js +7 -0
- package/eslint.config.js +11 -0
- package/package.json +66 -0
- package/src/cdk-constructs/IxApi.ts +81 -0
- package/src/cdk-constructs/IxBucket.ts +35 -0
- package/src/cdk-constructs/IxCertificate.ts +54 -0
- package/src/cdk-constructs/IxDnsRecord.ts +79 -0
- package/src/cdk-constructs/IxElasticache.ts +106 -0
- package/src/cdk-constructs/IxNextjsSite.ts +72 -0
- package/src/cdk-constructs/IxQuicksightWorkspace.ts +54 -0
- package/src/cdk-constructs/IxSESIdentity.ts +70 -0
- package/src/cdk-constructs/IxStaticSite.ts +69 -0
- package/src/cdk-constructs/IxVpcDetails.ts +38 -0
- package/src/cdk-constructs/IxWebsiteRedirect.ts +133 -0
- package/src/cdk-constructs/SiteOidcAuth/auth-check-handler-body.ts +168 -0
- package/src/cdk-constructs/SiteOidcAuth/auth-route.ts +71 -0
- package/src/cdk-constructs/SiteOidcAuth/index.ts +299 -0
- package/src/cdk-constructs/index.ts +10 -0
- package/src/deployConfig.ts +87 -0
- package/src/lib/auth/index.ts +1 -0
- package/src/lib/auth/oidc.ts +73 -0
- package/src/lib/proxy/fetch.ts +41 -0
- package/src/lib/proxy/index.ts +1 -0
- package/src/lib/site/support.ts +439 -0
- package/src/lib/utils/hash.ts +14 -0
- package/src/lib/utils/objects.ts +19 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Based off: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/example_cloudfront_functions_kvs_jwt_verify_section.html
|
|
2
|
+
// Note that as a CloudFront Function, this code has limitations compared to a Lambda@Edge function. For example, no
|
|
3
|
+
// external libraries can be used, and the runtime is more limited. Because SST v2's SsrSite construct uses JS v1.0
|
|
4
|
+
// runtime for CloudFront Functions, this code must also be compatible with that runtime. Also this is used in the body
|
|
5
|
+
// of a function where the variables event and request are already defined.
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires -- v1 runtime for CloudFront Functions do not support import statements
|
|
7
|
+
const crypto = require("crypto");
|
|
8
|
+
const jwtSecret = "__placeholder-for-jwt-secret__";
|
|
9
|
+
const authRoutePrefix = "__placeholder-for-auth-route-prefix__";
|
|
10
|
+
// Set to true to enable console logging
|
|
11
|
+
const loggingEnabled = false;
|
|
12
|
+
// Simple logger that can be enabled/disabled via the loggingEnabled variable.
|
|
13
|
+
const log = function () {
|
|
14
|
+
if (!loggingEnabled)
|
|
15
|
+
return;
|
|
16
|
+
// CloudFront Function runtime only prints first argument passed to console.log so add other args to the first one if given.
|
|
17
|
+
// eslint-disable-next-line prefer-rest-params -- We can't use spread or rest parameters in CloudFront Functions
|
|
18
|
+
let message = arguments[0];
|
|
19
|
+
if (arguments.length > 1) {
|
|
20
|
+
const otherArgs = [];
|
|
21
|
+
for (let i = 1; i < arguments.length; i++) {
|
|
22
|
+
// eslint-disable-next-line prefer-rest-params
|
|
23
|
+
otherArgs[i - 1] = arguments[i];
|
|
24
|
+
}
|
|
25
|
+
message += " - additional args: " + JSON.stringify(otherArgs);
|
|
26
|
+
}
|
|
27
|
+
console.log(message);
|
|
28
|
+
};
|
|
29
|
+
//Response when JWT is not valid.
|
|
30
|
+
const redirectResponse = {
|
|
31
|
+
statusCode: 302,
|
|
32
|
+
headers: {
|
|
33
|
+
location: { value: `${authRoutePrefix}/oidc/authorize` },
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
// Takes a JWT token to decode and throws an error if invalid
|
|
37
|
+
function jwtDecode(token, key, noVerify) {
|
|
38
|
+
// check segments
|
|
39
|
+
const segments = token.split(".");
|
|
40
|
+
if (segments.length !== 3) {
|
|
41
|
+
throw new Error("Not enough or too many segments");
|
|
42
|
+
}
|
|
43
|
+
// All segment should be base64
|
|
44
|
+
const headerSeg = segments[0];
|
|
45
|
+
const payloadSeg = segments[1];
|
|
46
|
+
const signatureSeg = segments[2];
|
|
47
|
+
// base64 decode and parse JSON
|
|
48
|
+
const payload = JSON.parse(_base64urlDecode(payloadSeg));
|
|
49
|
+
if (noVerify) {
|
|
50
|
+
return payload;
|
|
51
|
+
}
|
|
52
|
+
const signingMethod = "sha256";
|
|
53
|
+
const signingType = "hmac";
|
|
54
|
+
// Verify signature. `sign` will return base64 string.
|
|
55
|
+
const signingInput = [headerSeg, payloadSeg].join(".");
|
|
56
|
+
if (!_verify(signingInput, key, signingMethod, signingType, signatureSeg)) {
|
|
57
|
+
throw new Error("Signature verification failed");
|
|
58
|
+
}
|
|
59
|
+
// Support for nbf and exp claims.
|
|
60
|
+
// According to the RFC, they should be in seconds.
|
|
61
|
+
if (payload.nbf && Date.now() < payload.nbf * 1000) {
|
|
62
|
+
throw new Error("Token not yet active");
|
|
63
|
+
}
|
|
64
|
+
if (payload.exp && Date.now() > payload.exp * 1000) {
|
|
65
|
+
throw new Error("Token expired");
|
|
66
|
+
}
|
|
67
|
+
return payload;
|
|
68
|
+
}
|
|
69
|
+
// Function to ensure a constant time comparison to prevent timing side channels.
|
|
70
|
+
function _constantTimeEquals(a, b) {
|
|
71
|
+
if (a.length != b.length) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
let xor = 0;
|
|
75
|
+
for (let i = 0; i < a.length; i++) {
|
|
76
|
+
xor |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
77
|
+
}
|
|
78
|
+
return 0 === xor;
|
|
79
|
+
}
|
|
80
|
+
// Verifies some input matches an expected signature.
|
|
81
|
+
function _verify(input, key, method, type, signature) {
|
|
82
|
+
if (type === "hmac") {
|
|
83
|
+
return _constantTimeEquals(signature, _sign(input, key, method));
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
throw new Error("Algorithm type not recognized");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Signs some input with a key and method.
|
|
90
|
+
function _sign(input, key, method) {
|
|
91
|
+
return crypto.createHmac(method, key).update(input).digest("base64url");
|
|
92
|
+
}
|
|
93
|
+
// Very annoying that we have to implement this ourselves but it seems like the v1 runtime does not have atob/btoa or
|
|
94
|
+
// Buffer available.
|
|
95
|
+
function _base64urlDecode(str) {
|
|
96
|
+
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
97
|
+
while (str.length % 4)
|
|
98
|
+
str += "=";
|
|
99
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
100
|
+
let output = "";
|
|
101
|
+
let bc = 0, bs = 0, buffer, i = 0;
|
|
102
|
+
for (; i < str.length; i++) {
|
|
103
|
+
buffer = chars.indexOf(str.charAt(i));
|
|
104
|
+
if (buffer === -1)
|
|
105
|
+
continue;
|
|
106
|
+
bs = (bs << 6) | buffer;
|
|
107
|
+
bc += 6;
|
|
108
|
+
if (bc >= 8) {
|
|
109
|
+
bc -= 8;
|
|
110
|
+
output += String.fromCharCode((bs >> bc) & 0xff);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return output;
|
|
114
|
+
}
|
|
115
|
+
const jwtToken = request.cookies["auth-token"] && request.cookies["auth-token"].value;
|
|
116
|
+
if (!jwtToken) {
|
|
117
|
+
log("Error: No JWT in the cookies");
|
|
118
|
+
// @ts-expect-error -- This code is added to a function body so we can use return here but typescript doesn't know that.
|
|
119
|
+
return redirectResponse;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
jwtDecode(jwtToken, jwtSecret);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
log(e);
|
|
126
|
+
// @ts-expect-error -- This code is added to a function body so we can use return here but typescript doesn't know that.
|
|
127
|
+
return redirectResponse;
|
|
128
|
+
}
|
|
129
|
+
log("Valid JWT token");
|
|
130
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-route.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/SiteOidcAuth/auth-route.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,OAAO,4CAiCnB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { AuthHandler, OidcAdapter } from "sst/node/auth";
|
|
2
|
+
import { Issuer } from "openid-client";
|
|
3
|
+
import jwt from "jsonwebtoken";
|
|
4
|
+
const oidcClientId = process.env.OIDC_CLIENT_ID;
|
|
5
|
+
if (!oidcClientId) {
|
|
6
|
+
throw new Error("OIDC_CLIENT_ID not set");
|
|
7
|
+
}
|
|
8
|
+
const oidcIssuerUrl = process.env.OIDC_ISSUER_URL;
|
|
9
|
+
if (!oidcIssuerUrl) {
|
|
10
|
+
throw new Error("OIDC_ISSUER_URL not set");
|
|
11
|
+
}
|
|
12
|
+
const oidcScope = process.env.OIDC_SCOPE;
|
|
13
|
+
if (!oidcScope) {
|
|
14
|
+
throw new Error("OIDC_SCOPE not set");
|
|
15
|
+
}
|
|
16
|
+
const jwtSecret = process.env.JWT_SECRET;
|
|
17
|
+
if (!jwtSecret) {
|
|
18
|
+
throw new Error("JWT_SECRET not set");
|
|
19
|
+
}
|
|
20
|
+
const oidcIssuerConfigUrl = new URL(`${process.env.OIDC_ISSUER_URL?.replace(/\/$/, "")}/.well-known/openid-configuration`);
|
|
21
|
+
export const handler = addRequiredContext(AuthHandler({
|
|
22
|
+
providers: {
|
|
23
|
+
oidc: OidcAdapter({
|
|
24
|
+
issuer: await Issuer.discover(oidcIssuerConfigUrl.href),
|
|
25
|
+
clientID: oidcClientId,
|
|
26
|
+
scope: oidcScope,
|
|
27
|
+
onSuccess: async (tokenset) => {
|
|
28
|
+
// Payload to include in the token
|
|
29
|
+
const payload = {
|
|
30
|
+
userID: tokenset.claims().sub,
|
|
31
|
+
};
|
|
32
|
+
const expiresInMs = 1000 * 60 * 60;
|
|
33
|
+
// Create the token
|
|
34
|
+
const token = jwt.sign(payload, jwtSecret, {
|
|
35
|
+
algorithm: "HS256",
|
|
36
|
+
expiresIn: expiresInMs / 1000,
|
|
37
|
+
});
|
|
38
|
+
const expiryDate = new Date(Date.now() + expiresInMs);
|
|
39
|
+
return {
|
|
40
|
+
statusCode: 302,
|
|
41
|
+
headers: {
|
|
42
|
+
location: "/",
|
|
43
|
+
},
|
|
44
|
+
cookies: [
|
|
45
|
+
`auth-token=${token}; HttpOnly; SameSite=None; Secure; Path=/; Expires=${expiryDate}`,
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
},
|
|
51
|
+
}));
|
|
52
|
+
function addRequiredContext(handler) {
|
|
53
|
+
return async function (...args) {
|
|
54
|
+
const [event] = args;
|
|
55
|
+
// Used by AuthHandler to create callback url sent to oidc server
|
|
56
|
+
event.requestContext.domainName = event.headers["x-forwarded-host"];
|
|
57
|
+
return await handler(...args);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import CloudFront from "aws-cdk-lib/aws-cloudfront";
|
|
3
|
+
import CDK from "aws-cdk-lib";
|
|
4
|
+
import * as SST from "sst/constructs";
|
|
5
|
+
import type { ExtendedNextjsSiteProps, ExtendedStaticSiteProps } from "../../lib/site/support.js";
|
|
6
|
+
type ConstructScope = ConstructorParameters<typeof Construct>[0];
|
|
7
|
+
type ConstructId = ConstructorParameters<typeof Construct>[1];
|
|
8
|
+
export type Props = {
|
|
9
|
+
oidcIssuerUrl: string;
|
|
10
|
+
oidcClientId: string;
|
|
11
|
+
oidcScope: string;
|
|
12
|
+
};
|
|
13
|
+
export type AddToSiteProps = {
|
|
14
|
+
prefix?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare class SiteOidcAuth extends Construct {
|
|
17
|
+
readonly oidcIssuerUrl: string;
|
|
18
|
+
readonly oidcClientId: string;
|
|
19
|
+
readonly oidcScope: string;
|
|
20
|
+
readonly id: string;
|
|
21
|
+
constructor(scope: ConstructScope, id: ConstructId, props: Props);
|
|
22
|
+
addToStaticSiteProps<SiteProps extends ExtendedStaticSiteProps>(scope: ConstructScope, siteProps: SiteProps, { prefix }?: AddToSiteProps): SiteProps & {
|
|
23
|
+
cdk: {
|
|
24
|
+
distribution: {
|
|
25
|
+
additionalBehaviors: Record<string, CloudFront.BehaviorOptions>;
|
|
26
|
+
defaultBehavior: {
|
|
27
|
+
functionAssociations: CloudFront.FunctionAssociation[];
|
|
28
|
+
allowedMethods?: CloudFront.AllowedMethods | undefined;
|
|
29
|
+
cachedMethods?: CloudFront.CachedMethods | undefined;
|
|
30
|
+
cachePolicy?: CloudFront.ICachePolicy | undefined;
|
|
31
|
+
compress?: boolean | undefined;
|
|
32
|
+
originRequestPolicy?: CloudFront.IOriginRequestPolicy | undefined;
|
|
33
|
+
realtimeLogConfig?: CloudFront.IRealtimeLogConfig | undefined;
|
|
34
|
+
responseHeadersPolicy?: CloudFront.IResponseHeadersPolicy | undefined;
|
|
35
|
+
smoothStreaming?: boolean | undefined;
|
|
36
|
+
viewerProtocolPolicy?: CloudFront.ViewerProtocolPolicy | undefined;
|
|
37
|
+
edgeLambdas?: CloudFront.EdgeLambda[] | undefined;
|
|
38
|
+
trustedKeyGroups?: CloudFront.IKeyGroup[] | undefined;
|
|
39
|
+
origin?: CloudFront.IOrigin | undefined;
|
|
40
|
+
};
|
|
41
|
+
} | {
|
|
42
|
+
additionalBehaviors: Record<string, CloudFront.BehaviorOptions>;
|
|
43
|
+
defaultBehavior: {
|
|
44
|
+
functionAssociations: CloudFront.FunctionAssociation[];
|
|
45
|
+
allowedMethods?: CloudFront.AllowedMethods | undefined;
|
|
46
|
+
cachedMethods?: CloudFront.CachedMethods | undefined;
|
|
47
|
+
cachePolicy?: CloudFront.ICachePolicy | undefined;
|
|
48
|
+
compress?: boolean | undefined;
|
|
49
|
+
originRequestPolicy?: CloudFront.IOriginRequestPolicy | undefined;
|
|
50
|
+
realtimeLogConfig?: CloudFront.IRealtimeLogConfig | undefined;
|
|
51
|
+
responseHeadersPolicy?: CloudFront.IResponseHeadersPolicy | undefined;
|
|
52
|
+
smoothStreaming?: boolean | undefined;
|
|
53
|
+
viewerProtocolPolicy?: CloudFront.ViewerProtocolPolicy | undefined;
|
|
54
|
+
edgeLambdas?: CloudFront.EdgeLambda[] | undefined;
|
|
55
|
+
trustedKeyGroups?: CloudFront.IKeyGroup[] | undefined;
|
|
56
|
+
origin?: CloudFront.IOrigin | undefined;
|
|
57
|
+
};
|
|
58
|
+
distributionDomainName: string;
|
|
59
|
+
distributionId: string;
|
|
60
|
+
grant(identity: CDK.aws_iam.IGrantable, ...actions: string[]): CDK.aws_iam.Grant;
|
|
61
|
+
grantCreateInvalidation(identity: CDK.aws_iam.IGrantable): CDK.aws_iam.Grant;
|
|
62
|
+
stack: CDK.Stack;
|
|
63
|
+
env: CDK.ResourceEnvironment;
|
|
64
|
+
applyRemovalPolicy(policy: CDK.RemovalPolicy): void;
|
|
65
|
+
node: import("constructs").Node;
|
|
66
|
+
} | {
|
|
67
|
+
additionalBehaviors: Record<string, CloudFront.BehaviorOptions>;
|
|
68
|
+
defaultBehavior: {
|
|
69
|
+
functionAssociations: CloudFront.FunctionAssociation[];
|
|
70
|
+
allowedMethods?: CloudFront.AllowedMethods | undefined;
|
|
71
|
+
cachedMethods?: CloudFront.CachedMethods | undefined;
|
|
72
|
+
cachePolicy?: CloudFront.ICachePolicy | undefined;
|
|
73
|
+
compress?: boolean | undefined;
|
|
74
|
+
originRequestPolicy?: CloudFront.IOriginRequestPolicy | undefined;
|
|
75
|
+
realtimeLogConfig?: CloudFront.IRealtimeLogConfig | undefined;
|
|
76
|
+
responseHeadersPolicy?: CloudFront.IResponseHeadersPolicy | undefined;
|
|
77
|
+
smoothStreaming?: boolean | undefined;
|
|
78
|
+
viewerProtocolPolicy?: CloudFront.ViewerProtocolPolicy | undefined;
|
|
79
|
+
edgeLambdas?: CloudFront.EdgeLambda[] | undefined;
|
|
80
|
+
trustedKeyGroups?: CloudFront.IKeyGroup[] | undefined;
|
|
81
|
+
origin?: CloudFront.IOrigin | undefined;
|
|
82
|
+
};
|
|
83
|
+
certificate?: CDK.aws_certificatemanager.ICertificate | undefined;
|
|
84
|
+
comment?: string | undefined;
|
|
85
|
+
defaultRootObject?: string | undefined;
|
|
86
|
+
domainNames?: string[] | undefined;
|
|
87
|
+
enabled?: boolean | undefined;
|
|
88
|
+
enableIpv6?: boolean | undefined;
|
|
89
|
+
enableLogging?: boolean | undefined;
|
|
90
|
+
geoRestriction?: CloudFront.GeoRestriction | undefined;
|
|
91
|
+
httpVersion?: CloudFront.HttpVersion | undefined;
|
|
92
|
+
logBucket?: CDK.aws_s3.IBucket | undefined;
|
|
93
|
+
logIncludesCookies?: boolean | undefined;
|
|
94
|
+
logFilePrefix?: string | undefined;
|
|
95
|
+
priceClass?: CloudFront.PriceClass | undefined;
|
|
96
|
+
webAclId?: string | undefined;
|
|
97
|
+
errorResponses?: CloudFront.ErrorResponse[] | undefined;
|
|
98
|
+
minimumProtocolVersion?: CloudFront.SecurityPolicyProtocol | undefined;
|
|
99
|
+
sslSupportMethod?: CloudFront.SSLMethod | undefined;
|
|
100
|
+
publishAdditionalMetrics?: boolean | undefined;
|
|
101
|
+
};
|
|
102
|
+
id?: string | undefined;
|
|
103
|
+
bucket?: CDK.aws_s3.IBucket | CDK.aws_s3.BucketProps | undefined;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
addToSsrSiteProps<SiteProps extends ExtendedNextjsSiteProps>(scope: ConstructScope, siteProps: SiteProps, { prefix }?: AddToSiteProps): SiteProps & {
|
|
107
|
+
cdk: {
|
|
108
|
+
distribution: {
|
|
109
|
+
additionalBehaviors: Record<string, CloudFront.BehaviorOptions>;
|
|
110
|
+
defaultBehavior?: (Omit<CloudFront.BehaviorOptions, "origin"> & {
|
|
111
|
+
origin?: CloudFront.IOrigin | undefined;
|
|
112
|
+
}) | undefined;
|
|
113
|
+
certificate?: CDK.aws_certificatemanager.ICertificate | undefined;
|
|
114
|
+
comment?: string | undefined;
|
|
115
|
+
defaultRootObject?: string | undefined;
|
|
116
|
+
domainNames?: string[] | undefined;
|
|
117
|
+
enabled?: boolean | undefined;
|
|
118
|
+
enableIpv6?: boolean | undefined;
|
|
119
|
+
enableLogging?: boolean | undefined;
|
|
120
|
+
geoRestriction?: CloudFront.GeoRestriction | undefined;
|
|
121
|
+
httpVersion?: CloudFront.HttpVersion | undefined;
|
|
122
|
+
logBucket?: CDK.aws_s3.IBucket | undefined;
|
|
123
|
+
logIncludesCookies?: boolean | undefined;
|
|
124
|
+
logFilePrefix?: string | undefined;
|
|
125
|
+
priceClass?: CloudFront.PriceClass | undefined;
|
|
126
|
+
webAclId?: string | undefined;
|
|
127
|
+
errorResponses?: CloudFront.ErrorResponse[] | undefined;
|
|
128
|
+
minimumProtocolVersion?: CloudFront.SecurityPolicyProtocol | undefined;
|
|
129
|
+
sslSupportMethod?: CloudFront.SSLMethod | undefined;
|
|
130
|
+
publishAdditionalMetrics?: boolean | undefined;
|
|
131
|
+
};
|
|
132
|
+
id?: string | undefined;
|
|
133
|
+
bucket?: CDK.aws_s3.IBucket | CDK.aws_s3.BucketProps | undefined;
|
|
134
|
+
s3Origin?: CDK.aws_cloudfront_origins.S3OriginProps | undefined;
|
|
135
|
+
serverCachePolicy?: CloudFront.ICachePolicy | undefined;
|
|
136
|
+
responseHeadersPolicy?: CloudFront.IResponseHeadersPolicy | undefined;
|
|
137
|
+
viewerProtocolPolicy?: CloudFront.ViewerProtocolPolicy | undefined;
|
|
138
|
+
server?: (Pick<CDK.aws_lambda.FunctionProps, "vpc" | "layers" | "vpcSubnets" | "securityGroups" | "allowAllOutbound" | "allowPublicSubnet" | "architecture" | "logRetention"> & Pick<SST.FunctionProps, "copyFiles">) | undefined;
|
|
139
|
+
transform?: ((args: {
|
|
140
|
+
cloudFrontFunctions?: Record<string, {
|
|
141
|
+
constructId: string;
|
|
142
|
+
injections: string[];
|
|
143
|
+
}> | undefined;
|
|
144
|
+
edgeFunctions?: Record<string, {
|
|
145
|
+
constructId: string;
|
|
146
|
+
function: import("sst/constructs/EdgeFunction.js").EdgeFunctionProps;
|
|
147
|
+
}> | undefined;
|
|
148
|
+
origins: Record<string, {
|
|
149
|
+
type: "function";
|
|
150
|
+
constructId: string;
|
|
151
|
+
function: import("sst/constructs/SsrFunction.js").SsrFunctionProps;
|
|
152
|
+
injections?: string[] | undefined;
|
|
153
|
+
streaming?: boolean | undefined;
|
|
154
|
+
} | {
|
|
155
|
+
type: "image-optimization-function";
|
|
156
|
+
function: CDK.aws_lambda.FunctionProps;
|
|
157
|
+
} | {
|
|
158
|
+
type: "s3";
|
|
159
|
+
originPath?: string | undefined;
|
|
160
|
+
copy: {
|
|
161
|
+
from: string;
|
|
162
|
+
to: string;
|
|
163
|
+
cached: boolean;
|
|
164
|
+
versionedSubDir?: string | undefined;
|
|
165
|
+
}[];
|
|
166
|
+
} | {
|
|
167
|
+
type: "group";
|
|
168
|
+
primaryOriginName: string;
|
|
169
|
+
fallbackOriginName: string;
|
|
170
|
+
fallbackStatusCodes?: number[] | undefined;
|
|
171
|
+
}>;
|
|
172
|
+
edge: boolean;
|
|
173
|
+
behaviors: {
|
|
174
|
+
cacheType: "server" | "static";
|
|
175
|
+
pattern?: string | undefined;
|
|
176
|
+
origin: string;
|
|
177
|
+
allowedMethods?: CloudFront.AllowedMethods | undefined;
|
|
178
|
+
cfFunction?: string | undefined;
|
|
179
|
+
edgeFunction?: string | undefined;
|
|
180
|
+
}[];
|
|
181
|
+
errorResponses?: CloudFront.ErrorResponse[] | undefined;
|
|
182
|
+
serverCachePolicy?: {
|
|
183
|
+
allowedHeaders?: string[] | undefined;
|
|
184
|
+
} | undefined;
|
|
185
|
+
buildId?: string | undefined;
|
|
186
|
+
}) => void) | undefined;
|
|
187
|
+
revalidation?: Pick<CDK.aws_lambda.FunctionProps, "vpc" | "vpcSubnets"> | undefined;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
private createJwtSecret;
|
|
191
|
+
private getFunctionAssociation;
|
|
192
|
+
private getAuthCheckHandlerBodyCode;
|
|
193
|
+
private convertToCloudFrontFunctionCompatibleCode;
|
|
194
|
+
private getAuthBehaviorOptions;
|
|
195
|
+
}
|
|
196
|
+
export {};
|
|
197
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/SiteOidcAuth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,UAAU,MAAM,4BAA4B,CAAC;AACpD,OAAO,GAAG,MAAM,aAAa,CAAC;AAE9B,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AAOtC,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,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,MAAM,MAAM,KAAK,GAAG;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAIjD,qBAAa,YAAa,SAAQ,SAAS;IACzC,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,oBAAoB,CAAC,SAAS,SAAS,uBAAuB,EAC5D,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,SAAS,EACpB,EAAE,MAA+B,EAAE,GAAE,cAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4C1D,iBAAiB,CAAC,SAAS,SAAS,uBAAuB,EACzD,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,SAAS,EACpB,EAAE,MAA+B,EAAE,GAAE,cAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuC1D,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,sBAAsB;IA8B9B,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yCAAyC;IAgBjD,OAAO,CAAC,sBAAsB;CAkF/B"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import SecretsManager from "aws-cdk-lib/aws-secretsmanager";
|
|
3
|
+
import CloudFront from "aws-cdk-lib/aws-cloudfront";
|
|
4
|
+
import CDK from "aws-cdk-lib";
|
|
5
|
+
import Lambda from "aws-cdk-lib/aws-lambda";
|
|
6
|
+
import * as SST from "sst/constructs";
|
|
7
|
+
import { isCDKConstruct } from "sst/constructs/Construct.js";
|
|
8
|
+
import { Config as SSTInternalConfig } from "sst/config.js";
|
|
9
|
+
import CloudFrontOrigins from "aws-cdk-lib/aws-cloudfront-origins";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import { transformSync } from "esbuild";
|
|
13
|
+
const defaultAuthRoutePrefix = "/auth";
|
|
14
|
+
export class SiteOidcAuth extends Construct {
|
|
15
|
+
oidcIssuerUrl;
|
|
16
|
+
oidcClientId;
|
|
17
|
+
oidcScope;
|
|
18
|
+
id;
|
|
19
|
+
constructor(scope, id, props) {
|
|
20
|
+
super(scope, id);
|
|
21
|
+
this.oidcIssuerUrl = props.oidcIssuerUrl;
|
|
22
|
+
this.oidcClientId = props.oidcClientId;
|
|
23
|
+
this.oidcScope = props.oidcScope;
|
|
24
|
+
this.id = id;
|
|
25
|
+
}
|
|
26
|
+
addToStaticSiteProps(scope, siteProps, { prefix = defaultAuthRoutePrefix } = {}) {
|
|
27
|
+
prefix = prefix.replace(/\/$/, ""); // Remove trailing slash from prefix if it has one
|
|
28
|
+
const behaviourName = `${prefix.replace(/^\//g, "")}/*`;
|
|
29
|
+
const distribution = siteProps.cdk?.distribution;
|
|
30
|
+
if (isCDKConstruct(distribution)) {
|
|
31
|
+
throw new Error(`CDK Construct for distribution is not supported when adding CloudFront OIDC Auth behavior for prefix ${prefix}`);
|
|
32
|
+
}
|
|
33
|
+
const updatedSiteProps = {
|
|
34
|
+
...siteProps,
|
|
35
|
+
cdk: {
|
|
36
|
+
...siteProps.cdk,
|
|
37
|
+
distribution: {
|
|
38
|
+
...siteProps.cdk?.distribution,
|
|
39
|
+
additionalBehaviors: distribution?.additionalBehaviors ?? {},
|
|
40
|
+
defaultBehavior: {
|
|
41
|
+
...distribution?.defaultBehavior,
|
|
42
|
+
functionAssociations: distribution?.defaultBehavior?.functionAssociations ?? [],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
if (updatedSiteProps.cdk.distribution.additionalBehaviors[behaviourName]) {
|
|
48
|
+
throw new Error(`Behavior for prefix ${prefix} already exists in distribution definition`);
|
|
49
|
+
}
|
|
50
|
+
const jwtSecret = this.createJwtSecret();
|
|
51
|
+
updatedSiteProps.cdk.distribution.defaultBehavior.functionAssociations.push(this.getFunctionAssociation(scope, jwtSecret, prefix));
|
|
52
|
+
updatedSiteProps.cdk.distribution.additionalBehaviors[behaviourName] =
|
|
53
|
+
this.getAuthBehaviorOptions(scope, jwtSecret, prefix);
|
|
54
|
+
return updatedSiteProps;
|
|
55
|
+
}
|
|
56
|
+
addToSsrSiteProps(scope, siteProps, { prefix = defaultAuthRoutePrefix } = {}) {
|
|
57
|
+
prefix = prefix.replace(/\/$/, ""); // Remove trailing slash from prefix if it has one
|
|
58
|
+
const behaviourName = `${prefix.replace(/^\//g, "")}/*`;
|
|
59
|
+
const updatedSiteProps = {
|
|
60
|
+
...siteProps,
|
|
61
|
+
cdk: {
|
|
62
|
+
...siteProps.cdk,
|
|
63
|
+
distribution: {
|
|
64
|
+
...siteProps.cdk?.distribution,
|
|
65
|
+
additionalBehaviors: siteProps.cdk?.distribution?.additionalBehaviors ?? {},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
if (updatedSiteProps.cdk.distribution.additionalBehaviors[behaviourName]) {
|
|
70
|
+
throw new Error(`Behavior for prefix ${prefix} already exists in distribution definition`);
|
|
71
|
+
}
|
|
72
|
+
const jwtSecret = this.createJwtSecret();
|
|
73
|
+
updatedSiteProps.cdk.transform = (plan) => {
|
|
74
|
+
siteProps?.cdk?.transform?.(plan);
|
|
75
|
+
plan.cloudFrontFunctions?.serverCfFunction.injections.push(this.convertToCloudFrontFunctionCompatibleCode(this.getAuthCheckHandlerBodyCode(jwtSecret, prefix)));
|
|
76
|
+
};
|
|
77
|
+
updatedSiteProps.cdk.distribution.additionalBehaviors[behaviourName] =
|
|
78
|
+
this.getAuthBehaviorOptions(scope, jwtSecret, prefix);
|
|
79
|
+
return updatedSiteProps;
|
|
80
|
+
}
|
|
81
|
+
createJwtSecret() {
|
|
82
|
+
return new SecretsManager.Secret(this, `${this.id}JwtSecret`, {
|
|
83
|
+
description: "JWT Signing Secret",
|
|
84
|
+
generateSecretString: {
|
|
85
|
+
passwordLength: 32,
|
|
86
|
+
excludePunctuation: true,
|
|
87
|
+
includeSpace: false,
|
|
88
|
+
requireEachIncludedType: true,
|
|
89
|
+
},
|
|
90
|
+
// Secret is only used for sessions so it's safe to delete on stack removal
|
|
91
|
+
removalPolicy: CDK.RemovalPolicy.DESTROY,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Get the CloudFront Function Association for auth checking
|
|
95
|
+
// Roughly based off https://github.com/sst/v2/blob/4283d706f251724308b397996ff307929bf3a976/packages/sst/src/constructs/SsrSite.ts#L941
|
|
96
|
+
getFunctionAssociation(scope, jwtSecret, authRoutePrefix) {
|
|
97
|
+
const authCheckFunction = new CloudFront.Function(scope, `${this.id}AuthCheckFunction`, {
|
|
98
|
+
code: CloudFront.FunctionCode.fromInline(this.convertToCloudFrontFunctionCompatibleCode(`function handler(event) {
|
|
99
|
+
var request = event.request;
|
|
100
|
+
${this.getAuthCheckHandlerBodyCode(jwtSecret, authRoutePrefix)}
|
|
101
|
+
return request;
|
|
102
|
+
}`, { minify: true })),
|
|
103
|
+
// We could specify the JS v2.0 runtime here but for SSR sites SST does the function creation and that currently
|
|
104
|
+
// uses JS v1.0 so no point using v2.0 here as the code has to be compatible with v1.0 anyway.
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
function: authCheckFunction,
|
|
108
|
+
eventType: CloudFront.FunctionEventType.VIEWER_REQUEST,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
getAuthCheckHandlerBodyCode(jwtSecret, authRoutePrefix) {
|
|
112
|
+
return (fs
|
|
113
|
+
.readFileSync(path.join(import.meta.dirname, "auth-check-handler-body.js"), "utf8")
|
|
114
|
+
.replace("__placeholder-for-jwt-secret__", jwtSecret.secretValue.toString())
|
|
115
|
+
.replace("__placeholder-for-auth-route-prefix__", authRoutePrefix)
|
|
116
|
+
// When typescript builds the make-it-so code including "auth-check-handler-body.ts" it will add "export {}" to
|
|
117
|
+
// the end of the file if it's not already a module. This will cause a syntax error in CloudFront Functions so we
|
|
118
|
+
// remove it here.
|
|
119
|
+
.replace(/export {};\s*$/g, ""));
|
|
120
|
+
}
|
|
121
|
+
convertToCloudFrontFunctionCompatibleCode(sourceCode, esbuildOptions) {
|
|
122
|
+
// ESBuild doesn't currently support transforming const/let to var, which is required for CloudFront Functions
|
|
123
|
+
// JS runtime 1.0.
|
|
124
|
+
sourceCode = sourceCode
|
|
125
|
+
.replaceAll(/const /g, "var ")
|
|
126
|
+
.replaceAll(/let /g, "var ");
|
|
127
|
+
return transformSync(sourceCode, {
|
|
128
|
+
target: "es5",
|
|
129
|
+
...esbuildOptions,
|
|
130
|
+
}).code;
|
|
131
|
+
}
|
|
132
|
+
// Get the behavior options for the auth route
|
|
133
|
+
getAuthBehaviorOptions(scope, jwtSecret, prefix) {
|
|
134
|
+
const authRouteFunction = new SST.Function(scope, `${this.id}AuthRouteFunction`, {
|
|
135
|
+
runtime: "nodejs20.x",
|
|
136
|
+
handler: path.join(import.meta.dirname, "auth-route.handler"),
|
|
137
|
+
environment: {
|
|
138
|
+
OIDC_ISSUER_URL: this.oidcIssuerUrl,
|
|
139
|
+
OIDC_CLIENT_ID: this.oidcClientId,
|
|
140
|
+
OIDC_SCOPE: this.oidcScope,
|
|
141
|
+
JWT_SECRET: jwtSecret.secretValue.toString(),
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
// authRouteFunction uses SST's AuthHandler construct which is normally run inside a lambda that's
|
|
145
|
+
// created by SST's Auth construct. AuthHandler expects certain environment variables to be set
|
|
146
|
+
// by the Auth construct so we have to set them ourselves here to keep it happy.
|
|
147
|
+
const envVarName = SSTInternalConfig.envFor({
|
|
148
|
+
type: "Auth",
|
|
149
|
+
id: "id", // It seems like the env var will still be found no matter what this value is
|
|
150
|
+
prop: "prefix",
|
|
151
|
+
});
|
|
152
|
+
authRouteFunction.addEnvironment(envVarName, prefix);
|
|
153
|
+
const authRouteFunctionUrl = authRouteFunction.addFunctionUrl({
|
|
154
|
+
authType: Lambda.FunctionUrlAuthType.NONE,
|
|
155
|
+
});
|
|
156
|
+
const forwardHostHeaderCfFunction = new CloudFront.Function(scope, `${this.id}ForwardHostHeaderFunction`, {
|
|
157
|
+
code: CloudFront.FunctionCode.fromInline(this.convertToCloudFrontFunctionCompatibleCode(`function handler(event) {
|
|
158
|
+
const request = event.request;
|
|
159
|
+
request.headers["x-forwarded-host"] = { value: request.headers.host.value };
|
|
160
|
+
return request;
|
|
161
|
+
}`, { minify: true })),
|
|
162
|
+
runtime: CloudFront.FunctionRuntime.JS_2_0,
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
origin: new CloudFrontOrigins.HttpOrigin(CDK.Fn.parseDomainName(authRouteFunctionUrl.url)),
|
|
166
|
+
allowedMethods: CloudFront.AllowedMethods.ALLOW_ALL,
|
|
167
|
+
cachePolicy: new CloudFront.CachePolicy(scope, `${this.id}AllowAllCookiesPolicy`, {
|
|
168
|
+
cachePolicyName: `${this.id}-AllowAllCookiesPolicy`,
|
|
169
|
+
comment: "Cache policy that forwards all cookies",
|
|
170
|
+
defaultTtl: CDK.Duration.seconds(1),
|
|
171
|
+
minTtl: CDK.Duration.seconds(1),
|
|
172
|
+
maxTtl: CDK.Duration.seconds(1),
|
|
173
|
+
cookieBehavior: CloudFront.CacheCookieBehavior.all(),
|
|
174
|
+
headerBehavior: CloudFront.CacheHeaderBehavior.allowList("X-Forwarded-Host"),
|
|
175
|
+
queryStringBehavior: CloudFront.CacheQueryStringBehavior.all(),
|
|
176
|
+
enableAcceptEncodingGzip: true,
|
|
177
|
+
enableAcceptEncodingBrotli: true,
|
|
178
|
+
}),
|
|
179
|
+
viewerProtocolPolicy: CloudFront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
180
|
+
functionAssociations: [
|
|
181
|
+
{
|
|
182
|
+
function: forwardHostHeaderCfFunction,
|
|
183
|
+
eventType: CloudFront.FunctionEventType.VIEWER_REQUEST,
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./IxVpcDetails.js";
|
|
2
|
+
export * from "./IxCertificate.js";
|
|
3
|
+
export * from "./IxDnsRecord.js";
|
|
4
|
+
export * from "./IxSESIdentity.js";
|
|
5
|
+
export * from "./IxNextjsSite.js";
|
|
6
|
+
export * from "./IxStaticSite.js";
|
|
7
|
+
export * from "./IxElasticache.js";
|
|
8
|
+
export * from "./IxApi.js";
|
|
9
|
+
export * from "./IxQuicksightWorkspace.js";
|
|
10
|
+
export * from "./SiteOidcAuth/index.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./IxVpcDetails.js";
|
|
2
|
+
export * from "./IxCertificate.js";
|
|
3
|
+
export * from "./IxDnsRecord.js";
|
|
4
|
+
export * from "./IxSESIdentity.js";
|
|
5
|
+
export * from "./IxNextjsSite.js";
|
|
6
|
+
export * from "./IxStaticSite.js";
|
|
7
|
+
export * from "./IxElasticache.js";
|
|
8
|
+
export * from "./IxApi.js";
|
|
9
|
+
export * from "./IxQuicksightWorkspace.js";
|
|
10
|
+
export * from "./SiteOidcAuth/index.js";
|