raindancers-cloudfront 0.0.0
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/LICENSE +202 -0
- package/README.md +176 -0
- package/lib/bicep/deploy/deploy.d.ts +46 -0
- package/lib/bicep/deploy/deploy.js +123 -0
- package/lib/bicep/deploy/index.d.ts +3 -0
- package/lib/bicep/deploy/index.js +20 -0
- package/lib/bicep/deploy/template.d.ts +75 -0
- package/lib/bicep/deploy/template.js +364 -0
- package/lib/bicep/deploy/templateBuilder.d.ts +16 -0
- package/lib/bicep/deploy/templateBuilder.js +35 -0
- package/lib/bicep/index.d.ts +3 -0
- package/lib/bicep/index.js +40 -0
- package/lib/bicep/patterns/azureAdApplicationFederated.d.ts +58 -0
- package/lib/bicep/patterns/azureAdApplicationFederated.js +317 -0
- package/lib/bicep/patterns/index.d.ts +1 -0
- package/lib/bicep/patterns/index.js +18 -0
- package/lib/bicep/resources/azure/appServicePlan.d.ts +11 -0
- package/lib/bicep/resources/azure/appServicePlan.js +24 -0
- package/lib/bicep/resources/azure/applicationInsights.d.ts +13 -0
- package/lib/bicep/resources/azure/applicationInsights.js +27 -0
- package/lib/bicep/resources/azure/deploymentScript.d.ts +16 -0
- package/lib/bicep/resources/azure/deploymentScript.js +43 -0
- package/lib/bicep/resources/azure/functionApp.d.ts +20 -0
- package/lib/bicep/resources/azure/functionApp.js +54 -0
- package/lib/bicep/resources/azure/index.d.ts +8 -0
- package/lib/bicep/resources/azure/index.js +25 -0
- package/lib/bicep/resources/azure/logAnalyticsWorkspace.d.ts +11 -0
- package/lib/bicep/resources/azure/logAnalyticsWorkspace.js +26 -0
- package/lib/bicep/resources/azure/managedIdentity.d.ts +13 -0
- package/lib/bicep/resources/azure/managedIdentity.js +24 -0
- package/lib/bicep/resources/azure/roleAssignment.d.ts +18 -0
- package/lib/bicep/resources/azure/roleAssignment.js +34 -0
- package/lib/bicep/resources/azure/storageAccount.d.ts +11 -0
- package/lib/bicep/resources/azure/storageAccount.js +28 -0
- package/lib/bicep/resources/graph/appRoleAssignment.d.ts +25 -0
- package/lib/bicep/resources/graph/appRoleAssignment.js +33 -0
- package/lib/bicep/resources/graph/application.d.ts +51 -0
- package/lib/bicep/resources/graph/application.js +88 -0
- package/lib/bicep/resources/graph/bicepConstruct.d.ts +14 -0
- package/lib/bicep/resources/graph/bicepConstruct.js +29 -0
- package/lib/bicep/resources/graph/existingServicePrincipal.d.ts +19 -0
- package/lib/bicep/resources/graph/existingServicePrincipal.js +26 -0
- package/lib/bicep/resources/graph/federatedIdentityCredential.d.ts +29 -0
- package/lib/bicep/resources/graph/federatedIdentityCredential.js +31 -0
- package/lib/bicep/resources/graph/group.d.ts +26 -0
- package/lib/bicep/resources/graph/group.js +31 -0
- package/lib/bicep/resources/graph/index.d.ts +8 -0
- package/lib/bicep/resources/graph/index.js +25 -0
- package/lib/bicep/resources/graph/servicePrincipal.d.ts +22 -0
- package/lib/bicep/resources/graph/servicePrincipal.js +27 -0
- package/lib/bicep/resources/graph/types/index.d.ts +1 -0
- package/lib/bicep/resources/graph/types/index.js +18 -0
- package/lib/bicep/resources/graph/types/permissions.d.ts +54 -0
- package/lib/bicep/resources/graph/types/permissions.js +73 -0
- package/lib/bicep/resources/index.d.ts +2 -0
- package/lib/bicep/resources/index.js +39 -0
- package/lib/cloudfront/auth/authLambdaFunctions.d.ts +20 -0
- package/lib/cloudfront/auth/authLambdaFunctions.js +159 -0
- package/lib/cloudfront/auth/authSecretManager.d.ts +19 -0
- package/lib/cloudfront/auth/authSecretManager.js +92 -0
- package/lib/cloudfront/auth/cognitoAuthSecretManager.d.ts +20 -0
- package/lib/cloudfront/auth/cognitoAuthSecretManager.js +93 -0
- package/lib/cloudfront/auth/index.d.ts +3 -0
- package/lib/cloudfront/auth/index.js +20 -0
- package/lib/cloudfront/authSecurityTable.d.ts +10 -0
- package/lib/cloudfront/authSecurityTable.js +78 -0
- package/lib/cloudfront/cloudfront-functions/function-composer.d.ts +21 -0
- package/lib/cloudfront/cloudfront-functions/function-composer.js +132 -0
- package/lib/cloudfront/cloudfrontCertificate.d.ts +40 -0
- package/lib/cloudfront/cloudfrontCertificate.js +116 -0
- package/lib/cloudfront/cloudfrontWebAcl.d.ts +72 -0
- package/lib/cloudfront/cloudfrontWebAcl.js +249 -0
- package/lib/cloudfront/countries.d.ts +260 -0
- package/lib/cloudfront/countries.js +263 -0
- package/lib/cloudfront/deployment/viteFrontendDeployment.d.ts +12 -0
- package/lib/cloudfront/deployment/viteFrontendDeployment.js +63 -0
- package/lib/cloudfront/index.d.ts +11 -0
- package/lib/cloudfront/index.js +28 -0
- package/lib/cloudfront/jwtDecoder.d.ts +5 -0
- package/lib/cloudfront/jwtDecoder.js +57 -0
- package/lib/cloudfront/logging/auditLogArchive.d.ts +18 -0
- package/lib/cloudfront/logging/auditLogArchive.js +205 -0
- package/lib/cloudfront/logging/index.d.ts +1 -0
- package/lib/cloudfront/logging/index.js +18 -0
- package/lib/cloudfront/oauthEdgeRole.d.ts +9 -0
- package/lib/cloudfront/oauthEdgeRole.js +56 -0
- package/lib/cloudfront/patterns/authInfrastructure.d.ts +34 -0
- package/lib/cloudfront/patterns/authInfrastructure.js +140 -0
- package/lib/cloudfront/patterns/cognito-secured-cloudfront.d.ts +36 -0
- package/lib/cloudfront/patterns/cognito-secured-cloudfront.js +285 -0
- package/lib/cloudfront/patterns/cognitoAuthInfrastructure.d.ts +28 -0
- package/lib/cloudfront/patterns/cognitoAuthInfrastructure.js +157 -0
- package/lib/cloudfront/patterns/index.d.ts +4 -0
- package/lib/cloudfront/patterns/index.js +21 -0
- package/lib/cloudfront/patterns/securedCloudFront.d.ts +73 -0
- package/lib/cloudfront/patterns/securedCloudFront.js +416 -0
- package/lib/cloudfront/ssmCrossRegionWriter.d.ts +9 -0
- package/lib/cloudfront/ssmCrossRegionWriter.js +65 -0
- package/lib/cloudfront/syncSecretToKvs.d.ts +9 -0
- package/lib/cloudfront/syncSecretToKvs.js +89 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +19 -0
- package/package.json +105 -0
|
@@ -0,0 +1,132 @@
|
|
|
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 () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FunctionComposer = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const securedCloudFront_1 = require("../patterns/securedCloudFront");
|
|
40
|
+
/**
|
|
41
|
+
* Generates a combined CloudFront Function from modular check functions
|
|
42
|
+
* based on requested extensions
|
|
43
|
+
*/
|
|
44
|
+
class FunctionComposer {
|
|
45
|
+
constructor() {
|
|
46
|
+
this.modulesDir = path.join(__dirname, 'modules');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Generate combined function code based on requested extensions
|
|
50
|
+
*/
|
|
51
|
+
compose(extensions, config, composerConfig) {
|
|
52
|
+
const parts = [];
|
|
53
|
+
// Always include shared utilities
|
|
54
|
+
parts.push(this.loadModule('shared-utils.js'));
|
|
55
|
+
// Include required check modules
|
|
56
|
+
const checks = [];
|
|
57
|
+
if (extensions.includes(securedCloudFront_1.Extension.REWRITE_TO_INDEX_HTML)) {
|
|
58
|
+
parts.push(this.loadModule('url-rewrite.js'));
|
|
59
|
+
checks.push('rewrite');
|
|
60
|
+
}
|
|
61
|
+
if (extensions.includes(securedCloudFront_1.Extension.REQUIRE_TLS_13)) {
|
|
62
|
+
parts.push(this.loadModule('tls-check.js'));
|
|
63
|
+
checks.push('tls');
|
|
64
|
+
}
|
|
65
|
+
if (extensions.includes(securedCloudFront_1.Extension.REQUIRE_AUTH)) {
|
|
66
|
+
const isCognito = composerConfig?.cognitoDomain !== undefined;
|
|
67
|
+
let authModule = this.loadModule(isCognito ? 'cognito-auth-check.js' : 'auth-check.js');
|
|
68
|
+
if (composerConfig) {
|
|
69
|
+
if (composerConfig.cognitoDomain) {
|
|
70
|
+
authModule = authModule.replace(/COGNITO_DOMAIN_PLACEHOLDER/g, composerConfig.cognitoDomain);
|
|
71
|
+
}
|
|
72
|
+
if (composerConfig.tenantId) {
|
|
73
|
+
authModule = authModule.replace(/TENANT_ID_PLACEHOLDER/g, composerConfig.tenantId);
|
|
74
|
+
}
|
|
75
|
+
if (composerConfig.clientId) {
|
|
76
|
+
authModule = authModule.replace(/CLIENT_ID_PLACEHOLDER/g, composerConfig.clientId);
|
|
77
|
+
}
|
|
78
|
+
if (composerConfig.redirectUri) {
|
|
79
|
+
authModule = authModule.replace(/REDIRECT_URI_PLACEHOLDER/g, composerConfig.redirectUri);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
parts.push(authModule);
|
|
83
|
+
checks.push('auth');
|
|
84
|
+
}
|
|
85
|
+
// Generate handler function
|
|
86
|
+
parts.push(this.generateHandler(checks, config));
|
|
87
|
+
const code = parts.join('\n\n');
|
|
88
|
+
const sizeKB = Buffer.byteLength(code, 'utf-8') / 1024;
|
|
89
|
+
if (sizeKB > 10) {
|
|
90
|
+
throw new Error(`CloudFront Function exceeds 10KB limit: ${sizeKB.toFixed(2)}KB (extensions: ${extensions.join(', ')})`);
|
|
91
|
+
}
|
|
92
|
+
return code;
|
|
93
|
+
}
|
|
94
|
+
loadModule(filename) {
|
|
95
|
+
const filePath = path.join(this.modulesDir, filename);
|
|
96
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
97
|
+
return content
|
|
98
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // block comments
|
|
99
|
+
.replace(/^\s*\/\/.*$/gm, '') // line comments (whole-line only)
|
|
100
|
+
.replace(/^\s*\n/gm, '') // blank lines
|
|
101
|
+
.replace(/function handler\(event\) \{[\s\S]*?\n\}/g, '')
|
|
102
|
+
.replace(/async function handler\(event\) \{[\s\S]*?\n\}/g, '');
|
|
103
|
+
}
|
|
104
|
+
generateHandler(checks, config) {
|
|
105
|
+
const hasAuth = checks.includes('auth');
|
|
106
|
+
const lines = [
|
|
107
|
+
'// Generated handler function',
|
|
108
|
+
hasAuth ? 'async function handler(event) {' : 'function handler(event) {',
|
|
109
|
+
' var decodedPayload = null;',
|
|
110
|
+
'',
|
|
111
|
+
];
|
|
112
|
+
// Add TLS check
|
|
113
|
+
if (checks.includes('tls')) {
|
|
114
|
+
lines.push(' // TLS 1.3 enforcement', ' var tlsResult = checkTLS(event);', ' if (tlsResult) return tlsResult;', '');
|
|
115
|
+
}
|
|
116
|
+
// Add auth check (with optional role checking built-in)
|
|
117
|
+
if (hasAuth) {
|
|
118
|
+
const requiredRoles = config?.requiredRoles ? config.requiredRoles : [];
|
|
119
|
+
const matchMode = config?.roleMatchMode || securedCloudFront_1.RoleMatchMode.OR;
|
|
120
|
+
const rolesJson = JSON.stringify(requiredRoles);
|
|
121
|
+
lines.push(' // Authentication check', ` var requiredRoles = ${rolesJson};`, ` var matchMode = '${matchMode}';`, ' var authResult = await checkAuth(event, decodedPayload, requiredRoles, matchMode);', ' if (!authResult.pass) return authResult.response;', ' decodedPayload = authResult.payload;', '', ' // Inject Azure AD JWT for AssumeRoleWithWebIdentity (Azure only)', ' if (typeof injectAzureToken === \'function\') {', ' event.request = injectAzureToken(event.request, event.request.cookies);', ' }', '');
|
|
122
|
+
}
|
|
123
|
+
// Add URL rewrite after auth so originalPath is saved correctly
|
|
124
|
+
if (checks.includes('rewrite')) {
|
|
125
|
+
lines.push(' rewriteToIndex(event);', '');
|
|
126
|
+
}
|
|
127
|
+
lines.push(' // All checks passed', ' return event.request;', '}');
|
|
128
|
+
return lines.join('\n');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.FunctionComposer = FunctionComposer;
|
|
132
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb24tY29tcG9zZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xvdWRmcm9udC9jbG91ZGZyb250LWZ1bmN0aW9ucy9mdW5jdGlvbi1jb21wb3Nlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsMkNBQTZCO0FBQzdCLHFFQUEwRjtBQVMxRjs7O0dBR0c7QUFDSCxNQUFhLGdCQUFnQjtJQUczQjtRQUNFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksT0FBTyxDQUFDLFVBQXVCLEVBQUUsTUFBd0IsRUFBRSxjQUErQjtRQUMvRixNQUFNLEtBQUssR0FBYSxFQUFFLENBQUM7UUFFM0Isa0NBQWtDO1FBQ2xDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7UUFFL0MsaUNBQWlDO1FBQ2pDLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUU1QixJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsNkJBQVMsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLENBQUM7WUFDekQsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztZQUM5QyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pCLENBQUM7UUFFRCxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsNkJBQVMsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQ2xELEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sQ0FBQyxJQUFJLENBQUMs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S0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQixDQUFDO0NBQ0Y7QUFwSUQsNENBb0lDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IEV4dGVuc2lvbiwgRXh0ZW5zaW9uQ29uZmlnLCBSb2xlTWF0Y2hNb2RlIH0gZnJvbSAnLi4vcGF0dGVybnMvc2VjdXJlZENsb3VkRnJvbnQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvc2VyQ29uZmlnIHtcbiAgcmVhZG9ubHkgdGVuYW50SWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvZ25pdG9Eb21haW4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNsaWVudElkPzogc3RyaW5nO1xuICByZWFkb25seSByZWRpcmVjdFVyaT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBjb21iaW5lZCBDbG91ZEZyb250IEZ1bmN0aW9uIGZyb20gbW9kdWxhciBjaGVjayBmdW5jdGlvbnNcbiAqIGJhc2VkIG9uIHJlcXVlc3RlZCBleHRlbnNpb25zXG4gKi9cbmV4cG9ydCBjbGFzcyBGdW5jdGlvbkNvbXBvc2VyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBtb2R1bGVzRGlyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5tb2R1bGVzRGlyID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ21vZHVsZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBjb21iaW5lZCBmdW5jdGlvbiBjb2RlIGJhc2VkIG9uIHJlcXVlc3RlZCBleHRlbnNpb25zXG4gICAqL1xuICBwdWJsaWMgY29tcG9zZShleHRlbnNpb25zOiBFeHRlbnNpb25bXSwgY29uZmlnPzogRXh0ZW5zaW9uQ29uZmlnLCBjb21wb3NlckNvbmZpZz86IENvbXBvc2VyQ29uZmlnKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIEFsd2F5cyBpbmNsdWRlIHNoYXJlZCB1dGlsaXRpZXNcbiAgICBwYXJ0cy5wdXNoKHRoaXMubG9hZE1vZHVsZSgnc2hhcmVkLXV0aWxzLmpzJykpO1xuXG4gICAgLy8gSW5jbHVkZSByZXF1aXJlZCBjaGVjayBtb2R1bGVzXG4gICAgY29uc3QgY2hlY2tzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKGV4dGVuc2lvbnMuaW5jbHVkZXMoRXh0ZW5zaW9uLlJFV1JJVEVfVE9fSU5ERVhfSFRNTCkpIHtcbiAgICAgIHBhcnRzLnB1c2godGhpcy5sb2FkTW9kdWxlKCd1cmwtcmV3cml0ZS5qcycpKTtcbiAgICAgIGNoZWNrcy5wdXNoKCdyZXdyaXRlJyk7XG4gICAgfVxuXG4gICAgaWYgKGV4dGVuc2lvbnMuaW5jbHVkZXMoRXh0ZW5zaW9uLlJFUVVJUkVfVExTXzEzKSkge1xuICAgICAgcGFydHMucHVzaCh0aGlzLmxvYWRNb2R1bGUoJ3Rscy1jaGVjay5qcycpKTtcbiAgICAgIGNoZWNrcy5wdXNoKCd0bHMnKTtcbiAgICB9XG5cbiAgICBpZiAoZXh0ZW5zaW9ucy5pbmNsdWRlcyhFeHRlbnNpb24uUkVRVUlSRV9BVVRIKSkge1xuICAgICAgY29uc3QgaXNDb2duaXRvID0gY29tcG9zZXJDb25maWc/LmNvZ25pdG9Eb21haW4gIT09IHVuZGVmaW5lZDtcbiAgICAgIGxldCBhdXRoTW9kdWxlID0gdGhpcy5sb2FkTW9kdWxlKGlzQ29nbml0byA/ICdjb2duaXRvLWF1dGgtY2hlY2suanMnIDogJ2F1dGgtY2hlY2suanMnKTtcbiAgICAgIGlmIChjb21wb3NlckNvbmZpZykge1xuICAgICAgICBpZiAoY29tcG9zZXJDb25maWcuY29nbml0b0RvbWFpbikge1xuICAgICAgICAgIGF1dGhNb2R1bGUgPSBhdXRoTW9kdWxlLnJlcGxhY2UoL0NPR05JVE9fRE9NQUlOX1BMQUNFSE9MREVSL2csIGNvbXBvc2VyQ29uZmlnLmNvZ25pdG9Eb21haW4pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb21wb3NlckNvbmZpZy50ZW5hbnRJZCkge1xuICAgICAgICAgIGF1dGhNb2R1bGUgPSBhdXRoTW9kdWxlLnJlcGxhY2UoL1RFTkFOVF9JRF9QTEFDRUhPTERFUi9nLCBjb21wb3NlckNvbmZpZy50ZW5hbnRJZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBvc2VyQ29uZmlnLmNsaWVudElkKSB7XG4gICAgICAgICAgYXV0aE1vZHVsZSA9IGF1dGhNb2R1bGUucmVwbGFjZSgvQ0xJRU5UX0lEX1BMQUNFSE9MREVSL2csIGNvbXBvc2VyQ29uZmlnLmNsaWVudElkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tcG9zZXJDb25maWcucmVkaXJlY3RVcmkpIHtcbiAgICAgICAgICBhdXRoTW9kdWxlID0gYXV0aE1vZHVsZS5yZXBsYWNlKC9SRURJUkVDVF9VUklfUExBQ0VIT0xERVIvZywgY29tcG9zZXJDb25maWcucmVkaXJlY3RVcmkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwYXJ0cy5wdXNoKGF1dGhNb2R1bGUpO1xuICAgICAgY2hlY2tzLnB1c2goJ2F1dGgnKTtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBoYW5kbGVyIGZ1bmN0aW9uXG4gICAgcGFydHMucHVzaCh0aGlzLmdlbmVyYXRlSGFuZGxlcihjaGVja3MsIGNvbmZpZykpO1xuXG4gICAgY29uc3QgY29kZSA9IHBhcnRzLmpvaW4oJ1xcblxcbicpO1xuICAgIGNvbnN0IHNpemVLQiA9IEJ1ZmZlci5ieXRlTGVuZ3RoKGNvZGUsICd1dGYtOCcpIC8gMTAyNDtcblxuICAgIGlmIChzaXplS0IgPiAxMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbG91ZEZyb250IEZ1bmN0aW9uIGV4Y2VlZHMgMTBLQiBsaW1pdDogJHtzaXplS0IudG9GaXhlZCgyKX1LQiAoZXh0ZW5zaW9uczogJHtleHRlbnNpb25zLmpvaW4oJywgJyl9KWApO1xuICAgIH1cblxuICAgIHJldHVybiBjb2RlO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkTW9kdWxlKGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKHRoaXMubW9kdWxlc0RpciwgZmlsZW5hbWUpO1xuICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsICd1dGYtOCcpO1xuXG4gICAgcmV0dXJuIGNvbnRlbnRcbiAgICAgIC5yZXBsYWNlKC9cXC9cXCpbXFxzXFxTXSo/XFwqXFwvL2csICcnKSAvLyBibG9jayBjb21tZW50c1xuICAgICAgLnJlcGxhY2UoL15cXHMqXFwvXFwvLiokL2dtLCAnJykgLy8gbGluZSBjb21tZW50cyAod2hvbGUtbGluZSBvbmx5KVxuICAgICAgLnJlcGxhY2UoL15cXHMqXFxuL2dtLCAnJykgLy8gYmxhbmsgbGluZXNcbiAgICAgIC5yZXBsYWNlKC9mdW5jdGlvbiBoYW5kbGVyXFwoZXZlbnRcXCkgXFx7W1xcc1xcU10qP1xcblxcfS9nLCAnJylcbiAgICAgIC5yZXBsYWNlKC9hc3luYyBmdW5jdGlvbiBoYW5kbGVyXFwoZXZlbnRcXCkgXFx7W1xcc1xcU10qP1xcblxcfS9nLCAnJyk7XG4gIH1cblxuICBwcml2YXRlIGdlbmVyYXRlSGFuZGxlcihjaGVja3M6IHN0cmluZ1tdLCBjb25maWc/OiBFeHRlbnNpb25Db25maWcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGhhc0F1dGggPSBjaGVja3MuaW5jbHVkZXMoJ2F1dGgnKTtcbiAgICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXG4gICAgICAnLy8gR2VuZXJhdGVkIGhhbmRsZXIgZnVuY3Rpb24nLFxuICAgICAgaGFzQXV0aCA/ICdhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7JyA6ICdmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7JyxcbiAgICAgICcgIHZhciBkZWNvZGVkUGF5bG9hZCA9IG51bGw7JyxcbiAgICAgICcnLFxuICAgIF07XG5cbiAgICAvLyBBZGQgVExTIGNoZWNrXG4gICAgaWYgKGNoZWNrcy5pbmNsdWRlcygndGxzJykpIHtcbiAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgICcgIC8vIFRMUyAxLjMgZW5mb3JjZW1lbnQnLFxuICAgICAgICAnICB2YXIgdGxzUmVzdWx0ID0gY2hlY2tUTFMoZXZlbnQpOycsXG4gICAgICAgICcgIGlmICh0bHNSZXN1bHQpIHJldHVybiB0bHNSZXN1bHQ7JyxcbiAgICAgICAgJycsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEFkZCBhdXRoIGNoZWNrICh3aXRoIG9wdGlvbmFsIHJvbGUgY2hlY2tpbmcgYnVpbHQtaW4pXG4gICAgaWYgKGhhc0F1dGgpIHtcbiAgICAgIGNvbnN0IHJlcXVpcmVkUm9sZXMgPSBjb25maWc/LnJlcXVpcmVkUm9sZXMgPyBjb25maWcucmVxdWlyZWRSb2xlcyA6IFtdO1xuICAgICAgY29uc3QgbWF0Y2hNb2RlID0gY29uZmlnPy5yb2xlTWF0Y2hNb2RlIHx8IFJvbGVNYXRjaE1vZGUuT1I7XG4gICAgICBjb25zdCByb2xlc0pzb24gPSBKU09OLnN0cmluZ2lmeShyZXF1aXJlZFJvbGVzKTtcblxuICAgICAgbGluZXMucHVzaChcbiAgICAgICAgJyAgLy8gQXV0aGVudGljYXRpb24gY2hlY2snLFxuICAgICAgICBgICB2YXIgcmVxdWlyZWRSb2xlcyA9ICR7cm9sZXNKc29ufTtgLFxuICAgICAgICBgICB2YXIgbWF0Y2hNb2RlID0gJyR7bWF0Y2hNb2RlfSc7YCxcbiAgICAgICAgJyAgdmFyIGF1dGhSZXN1bHQgPSBhd2FpdCBjaGVja0F1dGgoZXZlbnQsIGRlY29kZWRQYXlsb2FkLCByZXF1aXJlZFJvbGVzLCBtYXRjaE1vZGUpOycsXG4gICAgICAgICcgIGlmICghYXV0aFJlc3VsdC5wYXNzKSByZXR1cm4gYXV0aFJlc3VsdC5yZXNwb25zZTsnLFxuICAgICAgICAnICBkZWNvZGVkUGF5bG9hZCA9IGF1dGhSZXN1bHQucGF5bG9hZDsnLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgLy8gSW5qZWN0IEF6dXJlIEFEIEpXVCBmb3IgQXNzdW1lUm9sZVdpdGhXZWJJZGVudGl0eSAoQXp1cmUgb25seSknLFxuICAgICAgICAnICBpZiAodHlwZW9mIGluamVjdEF6dXJlVG9rZW4gPT09IFxcJ2Z1bmN0aW9uXFwnKSB7JyxcbiAgICAgICAgJyAgICBldmVudC5yZXF1ZXN0ID0gaW5qZWN0QXp1cmVUb2tlbihldmVudC5yZXF1ZXN0LCBldmVudC5yZXF1ZXN0LmNvb2tpZXMpOycsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gQWRkIFVSTCByZXdyaXRlIGFmdGVyIGF1dGggc28gb3JpZ2luYWxQYXRoIGlzIHNhdmVkIGNvcnJlY3RseVxuICAgIGlmIChjaGVja3MuaW5jbHVkZXMoJ3Jld3JpdGUnKSkge1xuICAgICAgbGluZXMucHVzaChcbiAgICAgICAgJyAgcmV3cml0ZVRvSW5kZXgoZXZlbnQpOycsXG4gICAgICAgICcnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsaW5lcy5wdXNoKFxuICAgICAgJyAgLy8gQWxsIGNoZWNrcyBwYXNzZWQnLFxuICAgICAgJyAgcmV0dXJuIGV2ZW50LnJlcXVlc3Q7JyxcbiAgICAgICd9JyxcbiAgICApO1xuXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { aws_route53 as route53, aws_certificatemanager as acm } from 'aws-cdk-lib';
|
|
2
|
+
import * as constructs from 'constructs';
|
|
3
|
+
/**
|
|
4
|
+
* Properties for CloudFrontCertificate construct.
|
|
5
|
+
*/
|
|
6
|
+
export interface CloudFrontCertificateProps {
|
|
7
|
+
/** Domain name for the certificate (e.g., 'example.com' or '*.example.com') */
|
|
8
|
+
readonly domainName: string;
|
|
9
|
+
/** Route53 hosted zone for DNS validation */
|
|
10
|
+
readonly hostedZone: route53.IHostedZone;
|
|
11
|
+
/** Optional subject alternative names */
|
|
12
|
+
readonly subjectAlternativeNames?: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates an ACM certificate in us-east-1 for use with CloudFront.
|
|
16
|
+
*
|
|
17
|
+
* CloudFront requires certificates to be in us-east-1 region.
|
|
18
|
+
* This construct uses a custom resource to create the certificate
|
|
19
|
+
* in us-east-1 regardless of the stack's region.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const cert = new CloudFrontCertificate(this, 'Certificate', {
|
|
24
|
+
* domainName: 'example.com',
|
|
25
|
+
* hostedZone: zone,
|
|
26
|
+
* subjectAlternativeNames: ['*.example.com'],
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* new cloudfront.Distribution(this, 'Distribution', {
|
|
30
|
+
* certificate: cert.certificate,
|
|
31
|
+
* domainNames: ['example.com'],
|
|
32
|
+
* // ...
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class CloudFrontCertificate extends constructs.Construct {
|
|
37
|
+
/** The ACM certificate in us-east-1 */
|
|
38
|
+
readonly certificate: acm.ICertificate;
|
|
39
|
+
constructor(scope: constructs.Construct, id: string, props: CloudFrontCertificateProps);
|
|
40
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
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 () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CloudFrontCertificate = void 0;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const core = __importStar(require("aws-cdk-lib"));
|
|
39
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
40
|
+
const constructs = __importStar(require("constructs"));
|
|
41
|
+
/**
|
|
42
|
+
* Creates an ACM certificate in us-east-1 for use with CloudFront.
|
|
43
|
+
*
|
|
44
|
+
* CloudFront requires certificates to be in us-east-1 region.
|
|
45
|
+
* This construct uses a custom resource to create the certificate
|
|
46
|
+
* in us-east-1 regardless of the stack's region.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const cert = new CloudFrontCertificate(this, 'Certificate', {
|
|
51
|
+
* domainName: 'example.com',
|
|
52
|
+
* hostedZone: zone,
|
|
53
|
+
* subjectAlternativeNames: ['*.example.com'],
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* new cloudfront.Distribution(this, 'Distribution', {
|
|
57
|
+
* certificate: cert.certificate,
|
|
58
|
+
* domainNames: ['example.com'],
|
|
59
|
+
* // ...
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
class CloudFrontCertificate extends constructs.Construct {
|
|
64
|
+
constructor(scope, id, props) {
|
|
65
|
+
super(scope, id);
|
|
66
|
+
const certLogGroup = new aws_cdk_lib_1.aws_logs.LogGroup(this, 'CertificateFunctionLogGroup', {
|
|
67
|
+
retention: aws_cdk_lib_1.aws_logs.RetentionDays.ONE_WEEK,
|
|
68
|
+
});
|
|
69
|
+
const certFunction = new aws_cdk_lib_1.aws_lambda.SingletonFunction(this, 'CertificateFunction', {
|
|
70
|
+
uuid: 'cloudfront-certificate-us-east-1',
|
|
71
|
+
runtime: aws_cdk_lib_1.aws_lambda.Runtime.PYTHON_3_12,
|
|
72
|
+
handler: 'index.handler',
|
|
73
|
+
code: aws_cdk_lib_1.aws_lambda.Code.fromAsset(path.join(__dirname, 'lambda', 'certificate')),
|
|
74
|
+
timeout: core.Duration.minutes(15),
|
|
75
|
+
logGroup: certLogGroup,
|
|
76
|
+
});
|
|
77
|
+
certFunction.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
78
|
+
actions: [
|
|
79
|
+
'acm:RequestCertificate',
|
|
80
|
+
'acm:DescribeCertificate',
|
|
81
|
+
'acm:DeleteCertificate',
|
|
82
|
+
'acm:AddTagsToCertificate',
|
|
83
|
+
],
|
|
84
|
+
resources: ['*'],
|
|
85
|
+
}));
|
|
86
|
+
certFunction.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
87
|
+
actions: [
|
|
88
|
+
'route53:GetChange',
|
|
89
|
+
'route53:ListHostedZones',
|
|
90
|
+
],
|
|
91
|
+
resources: ['*'],
|
|
92
|
+
}));
|
|
93
|
+
certFunction.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
|
|
94
|
+
actions: [
|
|
95
|
+
'route53:ChangeResourceRecordSets',
|
|
96
|
+
],
|
|
97
|
+
resources: [props.hostedZone.hostedZoneArn],
|
|
98
|
+
}));
|
|
99
|
+
const provider = new aws_cdk_lib_1.custom_resources.Provider(this, 'CertificateProvider', {
|
|
100
|
+
onEventHandler: certFunction,
|
|
101
|
+
});
|
|
102
|
+
const resource = new core.CustomResource(this, 'CertificateResource', {
|
|
103
|
+
resourceType: 'Custom::CloudFrontCertificateInUsEast1',
|
|
104
|
+
serviceToken: provider.serviceToken,
|
|
105
|
+
properties: {
|
|
106
|
+
DomainName: props.domainName,
|
|
107
|
+
SubjectAlternativeNames: props.subjectAlternativeNames || [],
|
|
108
|
+
HostedZoneId: props.hostedZone.hostedZoneId,
|
|
109
|
+
Region: 'us-east-1',
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
this.certificate = aws_cdk_lib_1.aws_certificatemanager.Certificate.fromCertificateArn(this, 'Certificate', resource.getAttString('CertificateArn'));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.CloudFrontCertificate = CloudFrontCertificate;
|
|
116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRmcm9udENlcnRpZmljYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nsb3VkZnJvbnQvY2xvdWRmcm9udENlcnRpZmljYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUE2QjtBQUM3QixrREFBb0M7QUFDcEMsNkNBT3FCO0FBQ3JCLHVEQUF5QztBQWN6Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsTUFBYSxxQkFBc0IsU0FBUSxVQUFVLENBQUMsU0FBUztJQUk3RCxZQUFZLEtBQTJCLEVBQUUsRUFBVSxFQUFFLEtBQWlDO1FBQ3BGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxZQUFZLEdBQUcsSUFBSSxzQkFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsNkJBQTZCLEVBQUU7WUFDMUUsU0FBUyxFQUFFLHNCQUFJLENBQUMsYUFBYSxDQUFDLFFBQVE7U0FDdkMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxZQUFZLEdBQUcsSUFBSSx3QkFBTSxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxxQkFBcUIsRUFBRTtZQUM3RSxJQUFJLEVBQUUsa0NBQWtDO1lBQ3hDLE9BQU8sRUFBRSx3QkFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXO1lBQ25DLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLElBQUksRUFBRSx3QkFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQzFFLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDbEMsUUFBUSxFQUFFLFlBQVk7U0FDdkIsQ0FBQyxDQUFDO1FBRUgsWUFBWSxDQUFDLGVBQWUsQ0FBQyxJQUFJLHFCQUFHLENBQUMsZUFBZSxDQUFDO1lBQ25ELE9BQU8sRUFBRTtnQkFDUCx3QkFBd0I7Z0JBQ3hCLHlCQUF5QjtnQkFDekIsdUJBQXVCO2dCQUN2QiwwQkFBMEI7YUFDM0I7WUFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7U0FDakIsQ0FBQyxDQUFDLENBQUM7UUFFSixZQUFZLENBQUMsZUFBZSxDQUFDLElBQUkscUJBQUcsQ0FBQyxlQUFlLENBQUM7WUFDbkQsT0FBTyxFQUFFO2dCQUNQLG1CQUFtQjtnQkFDbkIseUJBQXlCO2FBQzFCO1lBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO1NBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBRUosWUFBWSxDQUFDLGVBQWUsQ0FBQyxJQUFJLHFCQUFHLENBQUMsZUFBZSxDQUFDO1lBQ25ELE9BQU8sRUFBRTtnQkFDUCxrQ0FBa0M7YUFDbkM7WUFDRCxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztTQUM1QyxDQUFDLENBQUMsQ0FBQztRQUVKLE1BQU0sUUFBUSxHQUFHLElBQUksOEJBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFO1lBQzVELGNBQWMsRUFBRSxZQUFZO1NBQzdCLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUscUJBQXFCLEVBQUU7WUFDcEUsWUFBWSxFQUFFLHdDQUF3QztZQUN0RCxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVk7WUFDbkMsVUFBVSxFQUFFO2dCQUNWLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtnQkFDNUIsdUJBQXVCLEVBQUUsS0FBSyxDQUFDLHVCQUF1QixJQUFJLEVBQUU7Z0JBQzVELFlBQVksRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLFlBQVk7Z0JBQzNDLE1BQU0sRUFBRSxXQUFXO2FBQ3BCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFdBQVcsR0FBRyxvQ0FBRyxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FDbkQsSUFBSSxFQUNKLGFBQWEsRUFDYixRQUFRLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQ3hDLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUFsRUQsc0RBa0VDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHtcbiAgYXdzX3JvdXRlNTMgYXMgcm91dGU1MyxcbiAgYXdzX2lhbSBhcyBpYW0sXG4gIGF3c19jZXJ0aWZpY2F0ZW1hbmFnZXIgYXMgYWNtLFxuICBhd3NfbGFtYmRhIGFzIGxhbWJkYSxcbiAgYXdzX2xvZ3MgYXMgbG9ncyxcbiAgY3VzdG9tX3Jlc291cmNlcyBhcyBjcixcbn0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBDbG91ZEZyb250Q2VydGlmaWNhdGUgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENsb3VkRnJvbnRDZXJ0aWZpY2F0ZVByb3BzIHtcbiAgLyoqIERvbWFpbiBuYW1lIGZvciB0aGUgY2VydGlmaWNhdGUgKGUuZy4sICdleGFtcGxlLmNvbScgb3IgJyouZXhhbXBsZS5jb20nKSAqL1xuICByZWFkb25seSBkb21haW5OYW1lOiBzdHJpbmc7XG4gIC8qKiBSb3V0ZTUzIGhvc3RlZCB6b25lIGZvciBETlMgdmFsaWRhdGlvbiAqL1xuICByZWFkb25seSBob3N0ZWRab25lOiByb3V0ZTUzLklIb3N0ZWRab25lO1xuICAvKiogT3B0aW9uYWwgc3ViamVjdCBhbHRlcm5hdGl2ZSBuYW1lcyAqL1xuICByZWFkb25seSBzdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gQUNNIGNlcnRpZmljYXRlIGluIHVzLWVhc3QtMSBmb3IgdXNlIHdpdGggQ2xvdWRGcm9udC5cbiAqXG4gKiBDbG91ZEZyb250IHJlcXVpcmVzIGNlcnRpZmljYXRlcyB0byBiZSBpbiB1cy1lYXN0LTEgcmVnaW9uLlxuICogVGhpcyBjb25zdHJ1Y3QgdXNlcyBhIGN1c3RvbSByZXNvdXJjZSB0byBjcmVhdGUgdGhlIGNlcnRpZmljYXRlXG4gKiBpbiB1cy1lYXN0LTEgcmVnYXJkbGVzcyBvZiB0aGUgc3RhY2sncyByZWdpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNlcnQgPSBuZXcgQ2xvdWRGcm9udENlcnRpZmljYXRlKHRoaXMsICdDZXJ0aWZpY2F0ZScsIHtcbiAqICAgZG9tYWluTmFtZTogJ2V4YW1wbGUuY29tJyxcbiAqICAgaG9zdGVkWm9uZTogem9uZSxcbiAqICAgc3ViamVjdEFsdGVybmF0aXZlTmFtZXM6IFsnKi5leGFtcGxlLmNvbSddLFxuICogfSk7XG4gKlxuICogbmV3IGNsb3VkZnJvbnQuRGlzdHJpYnV0aW9uKHRoaXMsICdEaXN0cmlidXRpb24nLCB7XG4gKiAgIGNlcnRpZmljYXRlOiBjZXJ0LmNlcnRpZmljYXRlLFxuICogICBkb21haW5OYW1lczogWydleGFtcGxlLmNvbSddLFxuICogICAvLyAuLi5cbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZEZyb250Q2VydGlmaWNhdGUgZXh0ZW5kcyBjb25zdHJ1Y3RzLkNvbnN0cnVjdCB7XG4gIC8qKiBUaGUgQUNNIGNlcnRpZmljYXRlIGluIHVzLWVhc3QtMSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2VydGlmaWNhdGU6IGFjbS5JQ2VydGlmaWNhdGU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2xvdWRGcm9udENlcnRpZmljYXRlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgY2VydExvZ0dyb3VwID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcywgJ0NlcnRpZmljYXRlRnVuY3Rpb25Mb2dHcm91cCcsIHtcbiAgICAgIHJldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9XRUVLLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY2VydEZ1bmN0aW9uID0gbmV3IGxhbWJkYS5TaW5nbGV0b25GdW5jdGlvbih0aGlzLCAnQ2VydGlmaWNhdGVGdW5jdGlvbicsIHtcbiAgICAgIHV1aWQ6ICdjbG91ZGZyb250LWNlcnRpZmljYXRlLXVzLWVhc3QtMScsXG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5QWVRIT05fM18xMixcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAnbGFtYmRhJywgJ2NlcnRpZmljYXRlJykpLFxuICAgICAgdGltZW91dDogY29yZS5EdXJhdGlvbi5taW51dGVzKDE1KSxcbiAgICAgIGxvZ0dyb3VwOiBjZXJ0TG9nR3JvdXAsXG4gICAgfSk7XG5cbiAgICBjZXJ0RnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ2FjbTpSZXF1ZXN0Q2VydGlmaWNhdGUnLFxuICAgICAgICAnYWNtOkRlc2NyaWJlQ2VydGlmaWNhdGUnLFxuICAgICAgICAnYWNtOkRlbGV0ZUNlcnRpZmljYXRlJyxcbiAgICAgICAgJ2FjbTpBZGRUYWdzVG9DZXJ0aWZpY2F0ZScsXG4gICAgICBdLFxuICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICB9KSk7XG5cbiAgICBjZXJ0RnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3JvdXRlNTM6R2V0Q2hhbmdlJyxcbiAgICAgICAgJ3JvdXRlNTM6TGlzdEhvc3RlZFpvbmVzJyxcbiAgICAgIF0sXG4gICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgIH0pKTtcblxuICAgIGNlcnRGdW5jdGlvbi5hZGRUb1JvbGVQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICAncm91dGU1MzpDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHMnLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogW3Byb3BzLmhvc3RlZFpvbmUuaG9zdGVkWm9uZUFybl0sXG4gICAgfSkpO1xuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgY3IuUHJvdmlkZXIodGhpcywgJ0NlcnRpZmljYXRlUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogY2VydEZ1bmN0aW9uLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgY29yZS5DdXN0b21SZXNvdXJjZSh0aGlzLCAnQ2VydGlmaWNhdGVSZXNvdXJjZScsIHtcbiAgICAgIHJlc291cmNlVHlwZTogJ0N1c3RvbTo6Q2xvdWRGcm9udENlcnRpZmljYXRlSW5Vc0Vhc3QxJyxcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBEb21haW5OYW1lOiBwcm9wcy5kb21haW5OYW1lLFxuICAgICAgICBTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lczogcHJvcHMuc3ViamVjdEFsdGVybmF0aXZlTmFtZXMgfHwgW10sXG4gICAgICAgIEhvc3RlZFpvbmVJZDogcHJvcHMuaG9zdGVkWm9uZS5ob3N0ZWRab25lSWQsXG4gICAgICAgIFJlZ2lvbjogJ3VzLWVhc3QtMScsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5jZXJ0aWZpY2F0ZSA9IGFjbS5DZXJ0aWZpY2F0ZS5mcm9tQ2VydGlmaWNhdGVBcm4oXG4gICAgICB0aGlzLFxuICAgICAgJ0NlcnRpZmljYXRlJyxcbiAgICAgIHJlc291cmNlLmdldEF0dFN0cmluZygnQ2VydGlmaWNhdGVBcm4nKSxcbiAgICApO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { aws_wafv2 as wafv2 } from 'aws-cdk-lib';
|
|
2
|
+
import * as constructs from 'constructs';
|
|
3
|
+
import { Country } from './countries';
|
|
4
|
+
export { Country, CountryCode } from './countries';
|
|
5
|
+
export type CountryName = keyof typeof Country;
|
|
6
|
+
/**
|
|
7
|
+
* Path-specific rate limit configuration.
|
|
8
|
+
*/
|
|
9
|
+
export interface PathRateLimit {
|
|
10
|
+
/** URI path pattern (e.g., '/oauth2/callback', '/api/auth/*') */
|
|
11
|
+
readonly path: string;
|
|
12
|
+
/** Rate limit for this path (requests per 5 minutes) */
|
|
13
|
+
readonly rateLimit: number;
|
|
14
|
+
/** Optional name for the rule (auto-generated if not provided) */
|
|
15
|
+
readonly name?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Properties for CloudFrontWebAcl construct.
|
|
19
|
+
*/
|
|
20
|
+
export interface CloudFrontWebAclProps {
|
|
21
|
+
/** Name for the Web ACL */
|
|
22
|
+
readonly name?: string;
|
|
23
|
+
/** Whether to enable AWS managed rules (default: true) */
|
|
24
|
+
readonly enableManagedRules?: boolean;
|
|
25
|
+
/** Custom rules to add to the Web ACL */
|
|
26
|
+
readonly rules?: wafv2.CfnWebACL.RuleProperty[];
|
|
27
|
+
/** Rate limit for requests per 5 minutes (default: 2000) */
|
|
28
|
+
readonly rateLimit?: number;
|
|
29
|
+
/** Path-specific rate limits (overrides default rateLimit for matching paths) */
|
|
30
|
+
readonly pathRateLimits?: PathRateLimit[];
|
|
31
|
+
/** Allow requests only from these countries (all others blocked) */
|
|
32
|
+
readonly allowedCountries?: CountryName[];
|
|
33
|
+
/** Block requests from these countries (all others allowed) */
|
|
34
|
+
readonly blockedCountries?: CountryName[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creates a WAF WebACL in us-east-1 for use with CloudFront.
|
|
38
|
+
*
|
|
39
|
+
* CloudFront requires WAF WebACLs to be in us-east-1 with CLOUDFRONT scope.
|
|
40
|
+
* This construct uses a custom resource to create the WebACL in us-east-1
|
|
41
|
+
* regardless of the stack's region.
|
|
42
|
+
*
|
|
43
|
+
* Provides sensible defaults with AWS managed rules for common threats.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const webAcl = new CloudFrontWebAcl(this, 'WebAcl', {
|
|
48
|
+
* name: 'MyCloudFrontWebAcl',
|
|
49
|
+
* rateLimit: 10000, // Default for all paths
|
|
50
|
+
* pathRateLimits: [
|
|
51
|
+
* { path: '/oauth2/callback', rateLimit: 100 },
|
|
52
|
+
* { path: '/oauth2/authorize', rateLimit: 100 },
|
|
53
|
+
* { path: '/api/auth', rateLimit: 500 },
|
|
54
|
+
* ],
|
|
55
|
+
* allowedCountries: ['UnitedStates', 'Canada', 'UnitedKingdom'],
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* new cloudfront.Distribution(this, 'Distribution', {
|
|
59
|
+
* webAclId: webAcl.webAclArn,
|
|
60
|
+
* // ...
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare class CloudFrontWebAcl extends constructs.Construct {
|
|
65
|
+
/** The WebACL ARN */
|
|
66
|
+
readonly webAclArn: string;
|
|
67
|
+
/** The WebACL ID */
|
|
68
|
+
readonly webAclId: string;
|
|
69
|
+
private readonly webAcl;
|
|
70
|
+
constructor(scope: constructs.Construct, id: string, props?: CloudFrontWebAclProps);
|
|
71
|
+
private buildRules;
|
|
72
|
+
}
|