@aws/nx-plugin 0.46.0 → 0.48.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 (104) hide show
  1. package/package.json +1 -1
  2. package/src/infra/app/generator.js +4 -1
  3. package/src/infra/app/generator.js.map +1 -1
  4. package/src/mcp-server/tools/create-workspace-command.js +4 -0
  5. package/src/mcp-server/tools/create-workspace-command.js.map +1 -1
  6. package/src/mcp-server/tools/general-guidance.js +3 -1
  7. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  8. package/src/preset/__snapshots__/generator.spec.ts.snap +9 -0
  9. package/src/preset/generator.d.ts +1 -1
  10. package/src/preset/generator.js +4 -1
  11. package/src/preset/generator.js.map +1 -1
  12. package/src/preset/schema.d.ts +3 -0
  13. package/src/preset/schema.json +9 -1
  14. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +60 -0
  15. package/src/py/fast-api/generator.js +5 -3
  16. package/src/py/fast-api/generator.js.map +1 -1
  17. package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +1 -0
  18. package/src/py/fast-api/schema.d.ts +3 -1
  19. package/src/py/fast-api/schema.json +4 -4
  20. package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +310 -0
  21. package/src/py/lambda-function/generator.js +17 -25
  22. package/src/py/lambda-function/generator.js.map +1 -1
  23. package/src/py/lambda-function/schema.d.ts +3 -0
  24. package/src/py/lambda-function/schema.json +8 -0
  25. package/src/py/mcp-server/generator.js +4 -2
  26. package/src/py/mcp-server/generator.js.map +1 -1
  27. package/src/py/mcp-server/schema.d.ts +4 -1
  28. package/src/py/mcp-server/schema.json +4 -4
  29. package/src/py/strands-agent/generator.js +4 -2
  30. package/src/py/strands-agent/generator.js.map +1 -1
  31. package/src/py/strands-agent/schema.d.ts +3 -1
  32. package/src/py/strands-agent/schema.json +4 -4
  33. package/src/terraform/project/generator.js +2 -1
  34. package/src/terraform/project/generator.js.map +1 -1
  35. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +60 -0
  36. package/src/trpc/backend/generator.js +4 -2
  37. package/src/trpc/backend/generator.js.map +1 -1
  38. package/src/trpc/backend/schema.d.ts +2 -1
  39. package/src/trpc/backend/schema.json +4 -4
  40. package/src/trpc/react/__snapshots__/generator.spec.ts.snap +1 -0
  41. package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +310 -0
  42. package/src/ts/lambda-function/generator.js +17 -27
  43. package/src/ts/lambda-function/generator.js.map +1 -1
  44. package/src/ts/lambda-function/schema.d.ts +3 -0
  45. package/src/ts/lambda-function/schema.json +8 -0
  46. package/src/ts/mcp-server/generator.js +4 -2
  47. package/src/ts/mcp-server/generator.js.map +1 -1
  48. package/src/ts/mcp-server/schema.d.ts +3 -1
  49. package/src/ts/mcp-server/schema.json +4 -4
  50. package/src/ts/nx-generator/__snapshots__/generator.spec.ts.snap +27 -1
  51. package/src/ts/nx-generator/files/nx-plugin-for-aws/docs/__nameKebabCase__.mdx.template +31 -0
  52. package/src/ts/nx-generator/files/nx-plugin-for-aws/generator/generator.spec.ts.template +1 -1
  53. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +756 -0
  54. package/src/ts/react-website/app/generator.js +44 -43
  55. package/src/ts/react-website/app/generator.js.map +1 -1
  56. package/src/ts/react-website/app/schema.d.ts +2 -0
  57. package/src/ts/react-website/app/schema.json +8 -0
  58. package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +259 -0
  59. package/src/ts/react-website/cognito-auth/generator.js +12 -13
  60. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  61. package/src/ts/react-website/cognito-auth/schema.d.ts +4 -0
  62. package/src/ts/react-website/cognito-auth/schema.json +8 -0
  63. package/src/ts/react-website/runtime-config/__snapshots__/generator.spec.ts.snap +0 -40
  64. package/src/ts/react-website/runtime-config/generator.js +0 -2
  65. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  66. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +4 -2
  67. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  68. package/src/utils/api-constructs/api-constructs.d.ts +2 -1
  69. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  70. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +10 -0
  71. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +10 -0
  72. package/src/utils/config/index.d.ts +6 -0
  73. package/src/utils/config/index.js.map +1 -1
  74. package/src/utils/files/terraform/src/core/runtime-config/entry/entry.tf.template +119 -0
  75. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +28 -0
  76. package/src/utils/files/terraform/src/metrics/metrics.tf.template +7 -1
  77. package/src/{py/lambda-function/files/common/constructs/src/app/lambda-functions/__constructFunctionKebabCase__.ts.template → utils/function-constructs/files/cdk/app/lambda-functions/__functionNameKebabCase__.ts.template} +5 -5
  78. package/src/utils/function-constructs/files/terraform/app/lambda-functions/__functionNameKebabCase__/__functionNameKebabCase__.tf.template +150 -0
  79. package/src/utils/function-constructs/function-constructs.d.ts +20 -0
  80. package/src/utils/function-constructs/function-constructs.js +57 -0
  81. package/src/utils/function-constructs/function-constructs.js.map +1 -0
  82. package/src/utils/iac.d.ts +21 -0
  83. package/src/utils/iac.js +25 -0
  84. package/src/utils/iac.js.map +1 -0
  85. package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +123 -0
  86. package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +421 -0
  87. package/src/utils/identity-constructs/files/terraform/core/user-identity/main.tf.template +47 -0
  88. package/src/utils/identity-constructs/identity-constructs.d.ts +16 -0
  89. package/src/utils/identity-constructs/identity-constructs.js +84 -0
  90. package/src/utils/identity-constructs/identity-constructs.js.map +1 -0
  91. package/src/utils/metrics.js +1 -1
  92. package/src/utils/metrics.js.map +1 -1
  93. package/src/utils/shared-constructs.d.ts +3 -2
  94. package/src/utils/shared-constructs.js +27 -3
  95. package/src/utils/shared-constructs.js.map +1 -1
  96. package/src/utils/website-constructs/files/terraform/app/static-websites/__websiteNameKebabCase__/__websiteNameKebabCase__.tf.template +42 -0
  97. package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +709 -0
  98. package/src/utils/website-constructs/website-constructs.d.ts +19 -0
  99. package/src/utils/website-constructs/website-constructs.js +61 -0
  100. package/src/utils/website-constructs/website-constructs.js.map +1 -0
  101. package/src/ts/lambda-function/files/common/constructs/src/app/lambda-functions/__constructFunctionNameKebabCase__.ts.template +0 -24
  102. /package/src/{ts/react-website/cognito-auth/files/common/constructs/src → utils/identity-constructs/files/cdk}/core/user-identity.ts.template +0 -0
  103. /package/src/{ts/react-website/app/files/common/constructs/src → utils/website-constructs/files/cdk}/app/static-websites/__websiteNameKebabCase__.ts.template +0 -0
  104. /package/src/{ts/react-website/app/files/common/constructs/src → utils/website-constructs/files/cdk}/core/static-website.ts.template +0 -0
@@ -0,0 +1,123 @@
1
+ terraform {
2
+ required_providers {
3
+ aws = {
4
+ source = "hashicorp/aws"
5
+ version = "~> 6.0"
6
+ }
7
+ }
8
+ }
9
+
10
+ # Variables
11
+ variable "callback_url" {
12
+ description = "Callback URL to add (e.g., https://d123456789.cloudfront.net)"
13
+ type = string
14
+ }
15
+
16
+ # Read runtime config to get user pool client details
17
+ module "runtime_config_reader" {
18
+ source = "../../runtime-config/read"
19
+ }
20
+
21
+ # Extract cognito details from runtime config
22
+ locals {
23
+ cognito_props = try(module.runtime_config_reader.config.cognitoProps, null)
24
+
25
+ user_pool_id = local.cognito_props != null ? local.cognito_props.userPoolId : null
26
+ user_pool_client_id = local.cognito_props != null ? local.cognito_props.userPoolWebClientId : null
27
+ }
28
+
29
+ # Validation: Ensure cognito props exist in runtime config
30
+ resource "terraform_data" "validate_cognito_props" {
31
+ lifecycle {
32
+ precondition {
33
+ condition = local.cognito_props != null
34
+ error_message = "ERROR: cognitoProps not found in runtime config. Ensure user-identity module has been deployed first and has added cognitoProps to the runtime configuration."
35
+ }
36
+
37
+ precondition {
38
+ condition = local.user_pool_id != null && local.user_pool_id != ""
39
+ error_message = "ERROR: cognitoProps.userPoolId is missing or empty in runtime config. Check that user-identity module completed successfully."
40
+ }
41
+
42
+ precondition {
43
+ condition = local.user_pool_client_id != null && local.user_pool_client_id != ""
44
+ error_message = "ERROR: cognitoProps.userPoolWebClientId is missing or empty in runtime config. Check that user-identity module completed successfully."
45
+ }
46
+ }
47
+ }
48
+
49
+
50
+ # Update the user pool client with additional callback URL
51
+ resource "null_resource" "add_callback_url" {
52
+ triggers = {
53
+ callback_url = var.callback_url
54
+ user_pool_id = local.user_pool_id
55
+ user_pool_client_id = local.user_pool_client_id
56
+ }
57
+
58
+ provisioner "local-exec" {
59
+ command = <<-EOT
60
+ uv run --with boto3 python -c "
61
+ import boto3
62
+ import sys
63
+
64
+ # Configuration
65
+ user_pool_id = '${local.user_pool_id}'
66
+ client_id = '${local.user_pool_client_id}'
67
+ new_callback_url = '${var.callback_url}'
68
+
69
+ # Initialize Cognito client
70
+ cognito = boto3.client('cognito-idp')
71
+
72
+ try:
73
+ # Get current user pool client configuration
74
+ response = cognito.describe_user_pool_client(
75
+ UserPoolId=user_pool_id,
76
+ ClientId=client_id
77
+ )
78
+
79
+ client_config = response['UserPoolClient']
80
+ current_callback_urls = client_config.get('CallbackURLs', [])
81
+ current_logout_urls = client_config.get('LogoutURLs', [])
82
+
83
+ # Check if URL already exists
84
+ if new_callback_url in current_callback_urls:
85
+ print(f'Callback URL {new_callback_url} already exists')
86
+ else:
87
+ # Add new URL to both callback and logout URLs
88
+ updated_callback_urls = current_callback_urls + [new_callback_url]
89
+ updated_logout_urls = current_logout_urls + [new_callback_url]
90
+
91
+ # Update the user pool client
92
+ # Only include valid update parameters (exclude read-only fields and ones we're setting)
93
+ valid_update_params = [
94
+ 'ClientName', 'RefreshTokenValidity', 'AccessTokenValidity', 'IdTokenValidity',
95
+ 'TokenValidityUnits', 'ReadAttributes', 'WriteAttributes', 'ExplicitAuthFlows',
96
+ 'SupportedIdentityProviders', 'DefaultRedirectURI', 'AllowedOAuthFlows',
97
+ 'AllowedOAuthScopes', 'AllowedOAuthFlowsUserPoolClient', 'AnalyticsConfiguration',
98
+ 'PreventUserExistenceErrors', 'EnableTokenRevocation',
99
+ 'EnablePropagateAdditionalUserContextData', 'AuthSessionValidity', 'RefreshTokenRotation'
100
+ ]
101
+
102
+ update_config = {k: v for k, v in client_config.items() if k in valid_update_params}
103
+
104
+ cognito.update_user_pool_client(
105
+ UserPoolId=user_pool_id,
106
+ ClientId=client_id,
107
+ CallbackURLs=updated_callback_urls,
108
+ LogoutURLs=updated_logout_urls,
109
+ **update_config
110
+ )
111
+
112
+ print(f'Successfully added callback URL: {new_callback_url}')
113
+
114
+ except Exception as e:
115
+ print(f'Error updating callback URLs: {e}')
116
+ sys.exit(1)
117
+ "
118
+ EOT
119
+ }
120
+
121
+ depends_on = [terraform_data.validate_cognito_props]
122
+ }
123
+
@@ -0,0 +1,421 @@
1
+ terraform {
2
+ required_providers {
3
+ aws = {
4
+ source = "hashicorp/aws"
5
+ version = "~> 6.0"
6
+ }
7
+ random = {
8
+ source = "hashicorp/random"
9
+ version = "~> 3.1"
10
+ }
11
+ }
12
+ }
13
+
14
+ # Variables
15
+ variable "user_pool_domain_prefix" {
16
+ description = "Prefix for the Cognito User Pool domain"
17
+ type = string
18
+ }
19
+
20
+ variable "allow_signup" {
21
+ description = "Set to true to allow users to sign themselves up"
22
+ type = bool
23
+ }
24
+
25
+ variable "callback_urls" {
26
+ description = "Additional callback URLs for the user pool client"
27
+ type = list(string)
28
+ default = []
29
+ }
30
+
31
+ variable "logout_urls" {
32
+ description = "Additional logout URLs for the user pool client"
33
+ type = list(string)
34
+ default = []
35
+ }
36
+
37
+ # Data sources
38
+ data "aws_caller_identity" "current" {}
39
+ data "aws_region" "current" {}
40
+
41
+ # Random suffix for resource names
42
+ resource "random_id" "unique_suffix" {
43
+ byte_length = 4
44
+ }
45
+
46
+ # Generate a random external ID for SMS role security
47
+ resource "random_uuid" "sms_external_id" {}
48
+
49
+ # IAM role for SMS MFA
50
+ resource "aws_iam_role" "cognito_sms_role" {
51
+ name = "cognito-sms-role-${random_id.unique_suffix.hex}"
52
+
53
+ assume_role_policy = jsonencode({
54
+ Version = "2012-10-17"
55
+ Statement = [
56
+ {
57
+ Action = "sts:AssumeRole"
58
+ Effect = "Allow"
59
+ Principal = {
60
+ Service = "cognito-idp.amazonaws.com"
61
+ }
62
+ Condition = {
63
+ StringEquals = {
64
+ "sts:ExternalId" = random_uuid.sms_external_id.result
65
+ "aws:SourceAccount" = data.aws_caller_identity.current.account_id
66
+ }
67
+ ArnLike = {
68
+ "aws:SourceArn" = "arn:aws:cognito-idp:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:userpool/*"
69
+ }
70
+ }
71
+ }
72
+ ]
73
+ })
74
+ }
75
+
76
+ resource "aws_iam_role_policy" "cognito_sms_policy" {
77
+ # checkov:skip=CKV_AWS_290:Cognito SMS requires sns:Publish with wildcard resource
78
+ # checkov:skip=CKV_AWS_355:Cognito SMS requires sns:Publish with wildcard resource
79
+ name = "cognito-sms-policy-${random_id.unique_suffix.hex}"
80
+ role = aws_iam_role.cognito_sms_role.id
81
+
82
+ policy = jsonencode({
83
+ Version = "2012-10-17"
84
+ Statement = [
85
+ {
86
+ Effect = "Allow"
87
+ Action = [
88
+ "sns:Publish"
89
+ ]
90
+ Resource = "*"
91
+ }
92
+ ]
93
+ })
94
+ }
95
+
96
+ # Cognito User Pool
97
+ resource "aws_cognito_user_pool" "user_pool" {
98
+ name = "UserPool-${random_id.unique_suffix.hex}"
99
+ deletion_protection = "ACTIVE"
100
+
101
+ admin_create_user_config {
102
+ allow_admin_create_user_only = !var.allow_signup
103
+ }
104
+
105
+ # Password policy
106
+ password_policy {
107
+ minimum_length = 8
108
+ require_lowercase = true
109
+ require_uppercase = true
110
+ require_numbers = true
111
+ require_symbols = true
112
+ temporary_password_validity_days = 3
113
+ }
114
+
115
+ # MFA configuration
116
+ mfa_configuration = "ON"
117
+
118
+ # Software token MFA configuration
119
+ software_token_mfa_configuration {
120
+ enabled = true
121
+ }
122
+
123
+ # SMS MFA configuration
124
+ sms_configuration {
125
+ external_id = random_uuid.sms_external_id.result
126
+ sns_caller_arn = aws_iam_role.cognito_sms_role.arn
127
+ sns_region = data.aws_region.current.name
128
+ }
129
+
130
+ depends_on = [aws_iam_role_policy.cognito_sms_policy]
131
+
132
+ # Sign-in configuration
133
+ username_configuration {
134
+ case_sensitive = false
135
+ }
136
+
137
+ alias_attributes = ["email"]
138
+
139
+ # Account recovery
140
+ account_recovery_setting {
141
+ recovery_mechanism {
142
+ name = "verified_email"
143
+ priority = 1
144
+ }
145
+ }
146
+
147
+ # Auto verification
148
+ auto_verified_attributes = ["email", "phone_number"]
149
+
150
+ # User pool add-ons (equivalent to FeaturePlan.ESSENTIALS)
151
+ user_pool_add_ons {
152
+ advanced_security_mode = "ENFORCED"
153
+ }
154
+
155
+ # Schema attributes
156
+ schema {
157
+ attribute_data_type = "String"
158
+ name = "email"
159
+ required = true
160
+ mutable = true
161
+
162
+ string_attribute_constraints {
163
+ min_length = 1
164
+ max_length = 256
165
+ }
166
+ }
167
+
168
+ schema {
169
+ attribute_data_type = "String"
170
+ name = "given_name"
171
+ required = true
172
+ mutable = true
173
+
174
+ string_attribute_constraints {
175
+ min_length = 1
176
+ max_length = 256
177
+ }
178
+ }
179
+
180
+ schema {
181
+ attribute_data_type = "String"
182
+ name = "family_name"
183
+ required = true
184
+ mutable = true
185
+
186
+ string_attribute_constraints {
187
+ min_length = 1
188
+ max_length = 256
189
+ }
190
+ }
191
+
192
+ schema {
193
+ attribute_data_type = "String"
194
+ name = "phone_number"
195
+ required = false
196
+ mutable = true
197
+
198
+ string_attribute_constraints {
199
+ min_length = 1
200
+ max_length = 256
201
+ }
202
+ }
203
+
204
+ # User attribute update settings - require verification before update
205
+ user_attribute_update_settings {
206
+ attributes_require_verification_before_update = ["email", "phone_number"]
207
+ }
208
+
209
+ # Verification message templates
210
+ verification_message_template {
211
+ default_email_option = "CONFIRM_WITH_CODE"
212
+ email_message = "The verification code to your new account is {####}"
213
+ email_subject = "Verify your new account"
214
+ sms_message = "The verification code to your new account is {####}"
215
+ }
216
+
217
+ tags = {
218
+ Name = "UserPool-${random_id.unique_suffix.hex}"
219
+ }
220
+ }
221
+
222
+ # User Pool Domain - temporarily commented out to resolve domain conflicts
223
+ # Will be re-enabled after User Pool Client OAuth configuration is fixed
224
+ resource "aws_cognito_user_pool_domain" "user_pool_domain" {
225
+ domain = "${var.user_pool_domain_prefix}-${data.aws_caller_identity.current.account_id}-${random_id.unique_suffix.hex}"
226
+ user_pool_id = aws_cognito_user_pool.user_pool.id
227
+ managed_login_version = 2
228
+ }
229
+
230
+ # User Pool Client
231
+ resource "aws_cognito_user_pool_client" "web_client" {
232
+ name = "WebClient-${random_id.unique_suffix.hex}"
233
+ user_pool_id = aws_cognito_user_pool.user_pool.id
234
+
235
+ # Auth flows - match CDK implementation (order matches CloudFormation)
236
+ explicit_auth_flows = [
237
+ "ALLOW_REFRESH_TOKEN_AUTH",
238
+ "ALLOW_USER_AUTH",
239
+ "ALLOW_USER_PASSWORD_AUTH",
240
+ "ALLOW_USER_SRP_AUTH"
241
+ ]
242
+
243
+ # Supported identity providers
244
+ supported_identity_providers = ["COGNITO"]
245
+
246
+ # OAuth configuration - MUST be set before callback/logout URLs
247
+ allowed_oauth_flows_user_pool_client = true
248
+ allowed_oauth_flows = ["code"]
249
+ allowed_oauth_scopes = ["email", "openid", "profile"]
250
+
251
+ # OAuth-dependent URLs - set after OAuth configuration
252
+ callback_urls = concat([
253
+ "http://localhost:4200",
254
+ "http://localhost:4300",
255
+ "https://${data.aws_region.current.name}.console.aws.amazon.com"
256
+ ], var.callback_urls)
257
+
258
+ logout_urls = concat([
259
+ "http://localhost:4200",
260
+ "http://localhost:4300",
261
+ "https://${data.aws_region.current.name}.console.aws.amazon.com"
262
+ ], var.logout_urls)
263
+
264
+ # Security settings
265
+ prevent_user_existence_errors = "ENABLED"
266
+ enable_token_revocation = true
267
+ enable_propagate_additional_user_context_data = false
268
+
269
+ # Token validity - ONLY refresh token to match CloudFormation exactly
270
+ refresh_token_validity = 30
271
+
272
+ # Auth session validity
273
+ auth_session_validity = 3
274
+
275
+ }
276
+
277
+ # Identity Pool
278
+ resource "aws_cognito_identity_pool" "identity_pool" {
279
+ identity_pool_name = "IdentityPool-${random_id.unique_suffix.hex}"
280
+ allow_unauthenticated_identities = false
281
+
282
+ cognito_identity_providers {
283
+ client_id = aws_cognito_user_pool_client.web_client.id
284
+ provider_name = aws_cognito_user_pool.user_pool.endpoint
285
+ server_side_token_check = true
286
+ }
287
+
288
+ tags = {
289
+ Name = "IdentityPool-${random_id.unique_suffix.hex}"
290
+ }
291
+ }
292
+
293
+ # IAM roles for identity pool
294
+ resource "aws_iam_role" "authenticated_role" {
295
+ name = "cognito-authenticated-role-${random_id.unique_suffix.hex}"
296
+
297
+ assume_role_policy = jsonencode({
298
+ Version = "2012-10-17"
299
+ Statement = [
300
+ {
301
+ Effect = "Allow"
302
+ Principal = {
303
+ Federated = "cognito-identity.amazonaws.com"
304
+ }
305
+ Action = "sts:AssumeRoleWithWebIdentity"
306
+ Condition = {
307
+ StringEquals = {
308
+ "cognito-identity.amazonaws.com:aud" = aws_cognito_identity_pool.identity_pool.id
309
+ }
310
+ "ForAnyValue:StringLike" = {
311
+ "cognito-identity.amazonaws.com:amr" = "authenticated"
312
+ }
313
+ }
314
+ }
315
+ ]
316
+ })
317
+ }
318
+
319
+ resource "aws_iam_role" "unauthenticated_role" {
320
+ name = "cognito-unauthenticated-role-${random_id.unique_suffix.hex}"
321
+
322
+ assume_role_policy = jsonencode({
323
+ Version = "2012-10-17"
324
+ Statement = [
325
+ {
326
+ Effect = "Allow"
327
+ Principal = {
328
+ Federated = "cognito-identity.amazonaws.com"
329
+ }
330
+ Action = "sts:AssumeRoleWithWebIdentity"
331
+ Condition = {
332
+ StringEquals = {
333
+ "cognito-identity.amazonaws.com:aud" = aws_cognito_identity_pool.identity_pool.id
334
+ }
335
+ "ForAnyValue:StringLike" = {
336
+ "cognito-identity.amazonaws.com:amr" = "unauthenticated"
337
+ }
338
+ }
339
+ }
340
+ ]
341
+ })
342
+ }
343
+
344
+ # Attach roles to identity pool
345
+ resource "aws_cognito_identity_pool_roles_attachment" "identity_pool_roles" {
346
+ identity_pool_id = aws_cognito_identity_pool.identity_pool.id
347
+
348
+ roles = {
349
+ "authenticated" = aws_iam_role.authenticated_role.arn
350
+ "unauthenticated" = aws_iam_role.unauthenticated_role.arn
351
+ }
352
+ }
353
+
354
+ # Managed Login Branding - temporarily commented out to resolve state conflicts
355
+ # Will be re-enabled after User Pool Client OAuth configuration is fixed
356
+ resource "aws_cognito_managed_login_branding" "managed_login_branding" {
357
+ user_pool_id = aws_cognito_user_pool.user_pool.id
358
+ client_id = aws_cognito_user_pool_client.web_client.id
359
+ use_cognito_provided_values = true
360
+
361
+ depends_on = [
362
+ aws_cognito_user_pool.user_pool,
363
+ aws_cognito_user_pool_client.web_client,
364
+ aws_cognito_user_pool_domain.user_pool_domain # commented out with domain
365
+ ]
366
+
367
+ }
368
+
369
+ # Always add cognito props to runtime config
370
+ module "add_cognito_to_runtime_config" {
371
+ source = "../../runtime-config/entry"
372
+
373
+ key_path = "cognitoProps"
374
+ value = {
375
+ region = data.aws_region.current.name
376
+ identityPoolId = aws_cognito_identity_pool.identity_pool.id
377
+ userPoolId = aws_cognito_user_pool.user_pool.id
378
+ userPoolWebClientId = aws_cognito_user_pool_client.web_client.id
379
+ }
380
+ }
381
+
382
+ # Outputs
383
+ output "region" {
384
+ description = "AWS region"
385
+ value = data.aws_region.current.name
386
+ }
387
+
388
+ output "user_pool_id" {
389
+ description = "ID of the Cognito User Pool"
390
+ value = aws_cognito_user_pool.user_pool.id
391
+ }
392
+
393
+ output "user_pool_arn" {
394
+ description = "ARN of the Cognito User Pool"
395
+ value = aws_cognito_user_pool.user_pool.arn
396
+ }
397
+
398
+ output "user_pool_client_id" {
399
+ description = "ID of the Cognito User Pool Client"
400
+ value = aws_cognito_user_pool_client.web_client.id
401
+ }
402
+
403
+ output "identity_pool_id" {
404
+ description = "ID of the Cognito Identity Pool"
405
+ value = aws_cognito_identity_pool.identity_pool.id
406
+ }
407
+
408
+ output "authenticated_role_name" {
409
+ description = "Name of the authenticated IAM role"
410
+ value = aws_iam_role.authenticated_role.name
411
+ }
412
+
413
+ output "authenticated_role_arn" {
414
+ description = "ARN of the authenticated IAM role"
415
+ value = aws_iam_role.authenticated_role.arn
416
+ }
417
+
418
+ output "user_pool_domain" {
419
+ description = "Domain of the Cognito User Pool"
420
+ value = aws_cognito_user_pool_domain.user_pool_domain.domain
421
+ }
@@ -0,0 +1,47 @@
1
+ module "identity" {
2
+ source = "./identity"
3
+
4
+ user_pool_domain_prefix = "<%= cognitoDomain %>"
5
+ allow_signup = <%= allowSignup %>
6
+ }
7
+
8
+ # Outputs
9
+ output "region" {
10
+ description = "AWS region"
11
+ value = module.identity.region
12
+ }
13
+
14
+ output "user_pool_id" {
15
+ description = "ID of the Cognito User Pool"
16
+ value = module.identity.user_pool_id
17
+ }
18
+
19
+ output "user_pool_arn" {
20
+ description = "ARN of the Cognito User Pool"
21
+ value = module.identity.user_pool_arn
22
+ }
23
+
24
+ output "user_pool_client_id" {
25
+ description = "ID of the Cognito User Pool Client"
26
+ value = module.identity.user_pool_client_id
27
+ }
28
+
29
+ output "identity_pool_id" {
30
+ description = "ID of the Cognito Identity Pool"
31
+ value = module.identity.identity_pool_id
32
+ }
33
+
34
+ output "authenticated_role_name" {
35
+ description = "Name of the authenticated IAM role"
36
+ value = module.identity.authenticated_role_name
37
+ }
38
+
39
+ output "authenticated_role_arn" {
40
+ description = "ARN of the authenticated IAM role"
41
+ value = module.identity.authenticated_role_arn
42
+ }
43
+
44
+ output "user_pool_domain" {
45
+ description = "Domain of the Cognito User Pool"
46
+ value = module.identity.user_pool_domain
47
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { Tree } from '@nx/devkit';
6
+ import { IacProvider } from '../iac';
7
+ export interface AddIdentityInfraOptions {
8
+ cognitoDomain: string;
9
+ allowSignup: boolean;
10
+ }
11
+ /**
12
+ * Add infrastructure for a static website
13
+ */
14
+ export declare const addIdentityInfra: (tree: Tree, options: AddIdentityInfraOptions & {
15
+ iacProvider: IacProvider;
16
+ }) => void;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addIdentityInfra = void 0;
4
+ /**
5
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ const devkit_1 = require("@nx/devkit");
9
+ const shared_constructs_constants_1 = require("../shared-constructs-constants");
10
+ const ast_1 = require("../ast");
11
+ /**
12
+ * Add infrastructure for a static website
13
+ */
14
+ const addIdentityInfra = (tree, options) => {
15
+ if (options.iacProvider === 'CDK') {
16
+ addIdentityCdkConstructs(tree, options);
17
+ }
18
+ else if (options.iacProvider === 'Terraform') {
19
+ addIdentityTerraformModules(tree, options);
20
+ }
21
+ else {
22
+ throw new Error(`Unsupported iacProvider ${options.iacProvider}`);
23
+ }
24
+ };
25
+ exports.addIdentityInfra = addIdentityInfra;
26
+ const addIdentityCdkConstructs = (tree, options) => {
27
+ (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', 'cdk', 'core'), (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR, 'src', 'core'), options, {
28
+ overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting,
29
+ });
30
+ (0, ast_1.addStarExport)(tree, (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_CONSTRUCTS_DIR, 'src', 'core', 'index.ts'), './user-identity.js');
31
+ };
32
+ const addIdentityTerraformModules = (tree, options) => {
33
+ (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', 'terraform', 'core'), (0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_TERRAFORM_DIR, 'src', 'core'), options, {
34
+ overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting,
35
+ });
36
+ // Update the static website module to add the callback url
37
+ const staticWebsiteModule = tree.read((0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_TERRAFORM_DIR, 'src', 'core', 'static-website', 'static-website.tf'), 'utf-8');
38
+ if (staticWebsiteModule &&
39
+ !staticWebsiteModule.includes('source = "../user-identity/add-callback-url"')) {
40
+ // Find the aws_cloudfront_distribution.website resource and add the callback URL module after it
41
+ const callbackUrlModule = `
42
+
43
+ # Add CloudFront domain to user pool client callback URLs
44
+ module "add_callback_url" {
45
+ source = "../user-identity/add-callback-url"
46
+
47
+ callback_url = "https://\${aws_cloudfront_distribution.website.domain_name}"
48
+
49
+ depends_on = [aws_cloudfront_distribution.website]
50
+ }`;
51
+ // Find the CloudFront distribution resource using proper brace counting
52
+ // This handles deeply nested structures correctly
53
+ const resourceStartPattern = /resource\s+"aws_cloudfront_distribution"\s+"website"\s*\{/;
54
+ const resourceStartMatch = staticWebsiteModule.match(resourceStartPattern);
55
+ if (resourceStartMatch) {
56
+ const startIndex = resourceStartMatch.index + resourceStartMatch[0].length - 1; // Position at opening brace
57
+ let braceCount = 0;
58
+ let insertionPoint = -1;
59
+ // Count braces to find the end of the resource block
60
+ for (let i = startIndex; i < staticWebsiteModule.length; i++) {
61
+ const char = staticWebsiteModule[i];
62
+ if (char === '{') {
63
+ braceCount++;
64
+ }
65
+ else if (char === '}') {
66
+ braceCount--;
67
+ if (braceCount === 0) {
68
+ // Found the closing brace of the CloudFront resource
69
+ insertionPoint = i + 1;
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ if (insertionPoint !== -1) {
75
+ // Insert the callback URL module right after the CloudFront distribution
76
+ const beforeInsertion = staticWebsiteModule.substring(0, insertionPoint);
77
+ const afterInsertion = staticWebsiteModule.substring(insertionPoint);
78
+ const updatedContent = beforeInsertion + callbackUrlModule + afterInsertion;
79
+ tree.write((0, devkit_1.joinPathFragments)(shared_constructs_constants_1.PACKAGES_DIR, shared_constructs_constants_1.SHARED_TERRAFORM_DIR, 'src', 'core', 'static-website', 'static-website.tf'), updatedContent);
80
+ }
81
+ }
82
+ }
83
+ };
84
+ //# sourceMappingURL=identity-constructs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-constructs.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/utils/identity-constructs/identity-constructs.ts"],"names":[],"mappings":"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"}