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.
Files changed (103) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +176 -0
  3. package/lib/bicep/deploy/deploy.d.ts +46 -0
  4. package/lib/bicep/deploy/deploy.js +123 -0
  5. package/lib/bicep/deploy/index.d.ts +3 -0
  6. package/lib/bicep/deploy/index.js +20 -0
  7. package/lib/bicep/deploy/template.d.ts +75 -0
  8. package/lib/bicep/deploy/template.js +364 -0
  9. package/lib/bicep/deploy/templateBuilder.d.ts +16 -0
  10. package/lib/bicep/deploy/templateBuilder.js +35 -0
  11. package/lib/bicep/index.d.ts +3 -0
  12. package/lib/bicep/index.js +40 -0
  13. package/lib/bicep/patterns/azureAdApplicationFederated.d.ts +58 -0
  14. package/lib/bicep/patterns/azureAdApplicationFederated.js +317 -0
  15. package/lib/bicep/patterns/index.d.ts +1 -0
  16. package/lib/bicep/patterns/index.js +18 -0
  17. package/lib/bicep/resources/azure/appServicePlan.d.ts +11 -0
  18. package/lib/bicep/resources/azure/appServicePlan.js +24 -0
  19. package/lib/bicep/resources/azure/applicationInsights.d.ts +13 -0
  20. package/lib/bicep/resources/azure/applicationInsights.js +27 -0
  21. package/lib/bicep/resources/azure/deploymentScript.d.ts +16 -0
  22. package/lib/bicep/resources/azure/deploymentScript.js +43 -0
  23. package/lib/bicep/resources/azure/functionApp.d.ts +20 -0
  24. package/lib/bicep/resources/azure/functionApp.js +54 -0
  25. package/lib/bicep/resources/azure/index.d.ts +8 -0
  26. package/lib/bicep/resources/azure/index.js +25 -0
  27. package/lib/bicep/resources/azure/logAnalyticsWorkspace.d.ts +11 -0
  28. package/lib/bicep/resources/azure/logAnalyticsWorkspace.js +26 -0
  29. package/lib/bicep/resources/azure/managedIdentity.d.ts +13 -0
  30. package/lib/bicep/resources/azure/managedIdentity.js +24 -0
  31. package/lib/bicep/resources/azure/roleAssignment.d.ts +18 -0
  32. package/lib/bicep/resources/azure/roleAssignment.js +34 -0
  33. package/lib/bicep/resources/azure/storageAccount.d.ts +11 -0
  34. package/lib/bicep/resources/azure/storageAccount.js +28 -0
  35. package/lib/bicep/resources/graph/appRoleAssignment.d.ts +25 -0
  36. package/lib/bicep/resources/graph/appRoleAssignment.js +33 -0
  37. package/lib/bicep/resources/graph/application.d.ts +51 -0
  38. package/lib/bicep/resources/graph/application.js +88 -0
  39. package/lib/bicep/resources/graph/bicepConstruct.d.ts +14 -0
  40. package/lib/bicep/resources/graph/bicepConstruct.js +29 -0
  41. package/lib/bicep/resources/graph/existingServicePrincipal.d.ts +19 -0
  42. package/lib/bicep/resources/graph/existingServicePrincipal.js +26 -0
  43. package/lib/bicep/resources/graph/federatedIdentityCredential.d.ts +29 -0
  44. package/lib/bicep/resources/graph/federatedIdentityCredential.js +31 -0
  45. package/lib/bicep/resources/graph/group.d.ts +26 -0
  46. package/lib/bicep/resources/graph/group.js +31 -0
  47. package/lib/bicep/resources/graph/index.d.ts +8 -0
  48. package/lib/bicep/resources/graph/index.js +25 -0
  49. package/lib/bicep/resources/graph/servicePrincipal.d.ts +22 -0
  50. package/lib/bicep/resources/graph/servicePrincipal.js +27 -0
  51. package/lib/bicep/resources/graph/types/index.d.ts +1 -0
  52. package/lib/bicep/resources/graph/types/index.js +18 -0
  53. package/lib/bicep/resources/graph/types/permissions.d.ts +54 -0
  54. package/lib/bicep/resources/graph/types/permissions.js +73 -0
  55. package/lib/bicep/resources/index.d.ts +2 -0
  56. package/lib/bicep/resources/index.js +39 -0
  57. package/lib/cloudfront/auth/authLambdaFunctions.d.ts +20 -0
  58. package/lib/cloudfront/auth/authLambdaFunctions.js +159 -0
  59. package/lib/cloudfront/auth/authSecretManager.d.ts +19 -0
  60. package/lib/cloudfront/auth/authSecretManager.js +92 -0
  61. package/lib/cloudfront/auth/cognitoAuthSecretManager.d.ts +20 -0
  62. package/lib/cloudfront/auth/cognitoAuthSecretManager.js +93 -0
  63. package/lib/cloudfront/auth/index.d.ts +3 -0
  64. package/lib/cloudfront/auth/index.js +20 -0
  65. package/lib/cloudfront/authSecurityTable.d.ts +10 -0
  66. package/lib/cloudfront/authSecurityTable.js +78 -0
  67. package/lib/cloudfront/cloudfront-functions/function-composer.d.ts +21 -0
  68. package/lib/cloudfront/cloudfront-functions/function-composer.js +132 -0
  69. package/lib/cloudfront/cloudfrontCertificate.d.ts +40 -0
  70. package/lib/cloudfront/cloudfrontCertificate.js +116 -0
  71. package/lib/cloudfront/cloudfrontWebAcl.d.ts +72 -0
  72. package/lib/cloudfront/cloudfrontWebAcl.js +249 -0
  73. package/lib/cloudfront/countries.d.ts +260 -0
  74. package/lib/cloudfront/countries.js +263 -0
  75. package/lib/cloudfront/deployment/viteFrontendDeployment.d.ts +12 -0
  76. package/lib/cloudfront/deployment/viteFrontendDeployment.js +63 -0
  77. package/lib/cloudfront/index.d.ts +11 -0
  78. package/lib/cloudfront/index.js +28 -0
  79. package/lib/cloudfront/jwtDecoder.d.ts +5 -0
  80. package/lib/cloudfront/jwtDecoder.js +57 -0
  81. package/lib/cloudfront/logging/auditLogArchive.d.ts +18 -0
  82. package/lib/cloudfront/logging/auditLogArchive.js +205 -0
  83. package/lib/cloudfront/logging/index.d.ts +1 -0
  84. package/lib/cloudfront/logging/index.js +18 -0
  85. package/lib/cloudfront/oauthEdgeRole.d.ts +9 -0
  86. package/lib/cloudfront/oauthEdgeRole.js +56 -0
  87. package/lib/cloudfront/patterns/authInfrastructure.d.ts +34 -0
  88. package/lib/cloudfront/patterns/authInfrastructure.js +140 -0
  89. package/lib/cloudfront/patterns/cognito-secured-cloudfront.d.ts +36 -0
  90. package/lib/cloudfront/patterns/cognito-secured-cloudfront.js +285 -0
  91. package/lib/cloudfront/patterns/cognitoAuthInfrastructure.d.ts +28 -0
  92. package/lib/cloudfront/patterns/cognitoAuthInfrastructure.js +157 -0
  93. package/lib/cloudfront/patterns/index.d.ts +4 -0
  94. package/lib/cloudfront/patterns/index.js +21 -0
  95. package/lib/cloudfront/patterns/securedCloudFront.d.ts +73 -0
  96. package/lib/cloudfront/patterns/securedCloudFront.js +416 -0
  97. package/lib/cloudfront/ssmCrossRegionWriter.d.ts +9 -0
  98. package/lib/cloudfront/ssmCrossRegionWriter.js +65 -0
  99. package/lib/cloudfront/syncSecretToKvs.d.ts +9 -0
  100. package/lib/cloudfront/syncSecretToKvs.js +89 -0
  101. package/lib/index.d.ts +2 -0
  102. package/lib/index.js +19 -0
  103. 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
+ }