cdk-factory 0.8.5__py3-none-any.whl → 0.8.7__py3-none-any.whl

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.

Potentially problematic release.


This version of cdk-factory might be problematic. Click here for more details.

@@ -243,3 +243,66 @@ class CognitoConfig(EnhancedBaseConfig):
243
243
  def ssm(self) -> Dict[str, Any]:
244
244
  """Whether to export the user pool name (default: False)"""
245
245
  return self.__config.get("ssm", {})
246
+
247
+ @property
248
+ def app_clients(self) -> list | None:
249
+ """
250
+ App clients for the user pool.
251
+ Supports multiple clients with different auth flows and OAuth settings.
252
+
253
+ Structure:
254
+ [{
255
+ "name": "web-client",
256
+ "generate_secret": False,
257
+ "auth_flows": {
258
+ "user_password": True,
259
+ "user_srp": True,
260
+ "custom": False,
261
+ "admin_user_password": False
262
+ },
263
+ "oauth": {
264
+ "flows": {
265
+ "authorization_code_grant": True,
266
+ "implicit_code_grant": False,
267
+ "client_credentials": False
268
+ },
269
+ "scopes": ["email", "openid", "profile"],
270
+ "callback_urls": ["https://example.com/callback"],
271
+ "logout_urls": ["https://example.com/logout"]
272
+ },
273
+ "supported_identity_providers": ["COGNITO"],
274
+ "prevent_user_existence_errors": True,
275
+ "enable_token_revocation": True,
276
+ "access_token_validity": {"minutes": 60},
277
+ "id_token_validity": {"minutes": 60},
278
+ "refresh_token_validity": {"days": 30},
279
+ "read_attributes": ["email", "name"],
280
+ "write_attributes": ["name"]
281
+ }]
282
+
283
+ Example:
284
+ [
285
+ {
286
+ "name": "web-app",
287
+ "generate_secret": False,
288
+ "auth_flows": {
289
+ "user_password": True,
290
+ "user_srp": True
291
+ }
292
+ },
293
+ {
294
+ "name": "backend-service",
295
+ "generate_secret": True,
296
+ "oauth": {
297
+ "flows": {
298
+ "client_credentials": True
299
+ },
300
+ "scopes": ["api/read", "api/write"]
301
+ }
302
+ }
303
+ ]
304
+
305
+ Returns:
306
+ list: List of app client configurations
307
+ """
308
+ return self.__config.get("app_clients")
@@ -365,6 +365,7 @@ class ApiGatewayStack(IStack, EnhancedSsmParameterMixin):
365
365
  This is the NEW PATTERN for separating Lambda and API Gateway stacks.
366
366
  """
367
367
  route_path = route["path"]
368
+ method = route.get("method", "GET").upper()
368
369
  suffix = self._get_route_suffix(route) # Use shared method for consistent suffix calculation
369
370
 
370
371
  # Get Lambda ARN from SSM Parameter Store
@@ -376,15 +377,30 @@ class ApiGatewayStack(IStack, EnhancedSsmParameterMixin):
376
377
  f"Ensure Lambda stack has deployed and exported ARN to SSM."
377
378
  )
378
379
 
379
- # Import Lambda function from ARN
380
- lambda_fn = _lambda.Function.from_function_arn(
380
+ # Import Lambda function from ARN using fromFunctionAttributes
381
+ # This allows us to add permissions even for imported functions
382
+ lambda_fn = _lambda.Function.from_function_attributes(
381
383
  self,
382
384
  f"{api_id}-imported-lambda-{suffix}",
383
- lambda_arn
385
+ function_arn=lambda_arn,
386
+ same_environment=True # Allow permission grants for same-account imports
384
387
  )
385
388
 
386
389
  logger.info(f"Imported Lambda for route {route_path}: {lambda_arn}")
387
390
 
391
+ # Add explicit resource-based permission for this specific API Gateway
392
+ # This is CRITICAL for cross-stack Lambda integrations
393
+ _lambda.CfnPermission(
394
+ self,
395
+ f"lambda-permission-{suffix}",
396
+ action="lambda:InvokeFunction",
397
+ function_name=lambda_fn.function_arn,
398
+ principal="apigateway.amazonaws.com",
399
+ source_arn=f"arn:aws:execute-api:{self.region}:{self.account}:{api_gateway.rest_api_id}/*/{method}{route_path}"
400
+ )
401
+
402
+ logger.info(f"Granted API Gateway invoke permissions for Lambda: {lambda_arn}")
403
+
388
404
  # Setup API Gateway resource
389
405
  resource = (
390
406
  api_gateway.root.resource_for_path(route_path)
@@ -6,6 +6,10 @@ MIT License. See Project Root for the license information.
6
6
 
7
7
  import aws_cdk as cdk
8
8
  from aws_cdk import aws_cognito as cognito
9
+ from aws_cdk import aws_secretsmanager as secretsmanager
10
+ from aws_cdk import aws_iam as iam
11
+ from aws_cdk import aws_lambda as _lambda
12
+ from aws_cdk import custom_resources as cr
9
13
  from constructs import Construct
10
14
  from aws_lambda_powertools import Logger
11
15
  from aws_cdk import aws_ssm as ssm
@@ -33,6 +37,8 @@ class CognitoStack(IStack, EnhancedSsmParameterMixin):
33
37
  self.stack_config: StackConfig | None = None
34
38
  self.deployment: DeploymentConfig | None = None
35
39
  self.cognito_config: CognitoConfig | None = None
40
+ self.user_pool: cognito.UserPool | None = None
41
+ self.app_clients: dict = {} # Store created app clients by name
36
42
 
37
43
  def build(
38
44
  self,
@@ -47,6 +53,10 @@ class CognitoStack(IStack, EnhancedSsmParameterMixin):
47
53
 
48
54
  # Create user pool with configuration
49
55
  self._create_user_pool_with_config()
56
+
57
+ # Create app clients if configured
58
+ if self.cognito_config.app_clients:
59
+ self._create_app_clients()
50
60
 
51
61
  def _setup_custom_attributes(self):
52
62
  attributes = {}
@@ -139,7 +149,7 @@ class CognitoStack(IStack, EnhancedSsmParameterMixin):
139
149
  # Remove None values
140
150
  kwargs = {k: v for k, v in kwargs.items() if v is not None}
141
151
 
142
- user_pool = cognito.UserPool(
152
+ self.user_pool = cognito.UserPool(
143
153
  self,
144
154
  id=self.deployment.build_resource_name(
145
155
  self.cognito_config.user_pool_name
@@ -148,9 +158,347 @@ class CognitoStack(IStack, EnhancedSsmParameterMixin):
148
158
  ),
149
159
  **kwargs,
150
160
  )
151
- logger.info(f"Created Cognito User Pool: {user_pool.user_pool_id}")
161
+ logger.info(f"Created Cognito User Pool: {self.user_pool.user_pool_id}")
162
+
163
+ self._export_ssm_parameters(self.user_pool)
164
+
165
+ def _create_app_clients(self):
166
+ """Create app clients for the user pool based on configuration"""
167
+ if not self.user_pool:
168
+ raise ValueError("User pool must be created before app clients")
169
+
170
+ for client_config in self.cognito_config.app_clients:
171
+ client_name = client_config.get("name")
172
+ if not client_name:
173
+ raise ValueError("App client name is required")
174
+
175
+ # Build authentication flows
176
+ auth_flows = self._build_auth_flows(client_config.get("auth_flows", {}))
177
+
178
+ # Build OAuth settings
179
+ oauth_settings = self._build_oauth_settings(client_config.get("oauth"))
180
+
181
+ # Build token validity settings
182
+ token_validity = self._build_token_validity(client_config)
183
+
184
+ # Build app client kwargs
185
+ client_kwargs = {
186
+ "user_pool": self.user_pool,
187
+ "user_pool_client_name": client_name,
188
+ "generate_secret": client_config.get("generate_secret", False),
189
+ "auth_flows": auth_flows,
190
+ "o_auth": oauth_settings,
191
+ "prevent_user_existence_errors": client_config.get("prevent_user_existence_errors"),
192
+ "enable_token_revocation": client_config.get("enable_token_revocation", True),
193
+ "access_token_validity": token_validity.get("access_token"),
194
+ "id_token_validity": token_validity.get("id_token"),
195
+ "refresh_token_validity": token_validity.get("refresh_token"),
196
+ "read_attributes": self._build_attributes(client_config.get("read_attributes")),
197
+ "write_attributes": self._build_attributes(client_config.get("write_attributes")),
198
+ "supported_identity_providers": self._build_identity_providers(
199
+ client_config.get("supported_identity_providers")
200
+ ),
201
+ }
202
+
203
+ # Remove None values
204
+ client_kwargs = {k: v for k, v in client_kwargs.items() if v is not None}
205
+
206
+ # Create the app client
207
+ app_client = cognito.UserPoolClient(
208
+ self,
209
+ id=self.deployment.build_resource_name(f"{client_name}-client"),
210
+ **client_kwargs,
211
+ )
212
+
213
+ # Store reference
214
+ self.app_clients[client_name] = app_client
215
+ logger.info(f"Created Cognito App Client: {client_name}")
216
+
217
+ # Store client secret in Secrets Manager if generated
218
+ if client_config.get("generate_secret", False):
219
+ self._store_client_secret_in_secrets_manager(
220
+ client_name, app_client, self.user_pool
221
+ )
222
+
223
+ def _build_auth_flows(self, auth_flows_config: dict) -> cognito.AuthFlow:
224
+ """
225
+ Build authentication flows from configuration.
226
+
227
+ Note: CDK automatically adds ALLOW_REFRESH_TOKEN_AUTH to all app clients,
228
+ which is required for token refresh functionality.
229
+ """
230
+ if not auth_flows_config:
231
+ return None
232
+
233
+ return cognito.AuthFlow(
234
+ user_password=auth_flows_config.get("user_password", False),
235
+ user_srp=auth_flows_config.get("user_srp", False),
236
+ custom=auth_flows_config.get("custom", False),
237
+ admin_user_password=auth_flows_config.get("admin_user_password", False),
238
+ )
239
+
240
+ def _build_oauth_settings(self, oauth_config: dict) -> cognito.OAuthSettings:
241
+ """Build OAuth settings from configuration"""
242
+ if not oauth_config:
243
+ return None
244
+
245
+ # Build OAuth flows
246
+ flows_config = oauth_config.get("flows", {})
247
+ flows = cognito.OAuthFlows(
248
+ authorization_code_grant=flows_config.get("authorization_code_grant", False),
249
+ implicit_code_grant=flows_config.get("implicit_code_grant", False),
250
+ client_credentials=flows_config.get("client_credentials", False),
251
+ )
252
+
253
+ # Build OAuth scopes
254
+ scopes = []
255
+ scope_list = oauth_config.get("scopes", [])
256
+ for scope in scope_list:
257
+ if scope.lower() == "openid":
258
+ scopes.append(cognito.OAuthScope.OPENID)
259
+ elif scope.lower() == "email":
260
+ scopes.append(cognito.OAuthScope.EMAIL)
261
+ elif scope.lower() == "phone":
262
+ scopes.append(cognito.OAuthScope.PHONE)
263
+ elif scope.lower() == "profile":
264
+ scopes.append(cognito.OAuthScope.PROFILE)
265
+ elif scope.lower() == "cognito_admin":
266
+ scopes.append(cognito.OAuthScope.COGNITO_ADMIN)
267
+ else:
268
+ # Custom scope
269
+ scopes.append(cognito.OAuthScope.custom(scope))
270
+
271
+ return cognito.OAuthSettings(
272
+ flows=flows,
273
+ scopes=scopes if scopes else None,
274
+ callback_urls=oauth_config.get("callback_urls"),
275
+ logout_urls=oauth_config.get("logout_urls"),
276
+ )
277
+
278
+ def _build_token_validity(self, client_config: dict) -> dict:
279
+ """Build token validity settings from configuration"""
280
+ result = {}
281
+
282
+ # Access token validity
283
+ if "access_token_validity" in client_config:
284
+ validity = client_config["access_token_validity"]
285
+ if "minutes" in validity:
286
+ result["access_token"] = cdk.Duration.minutes(validity["minutes"])
287
+ elif "hours" in validity:
288
+ result["access_token"] = cdk.Duration.hours(validity["hours"])
289
+ elif "days" in validity:
290
+ result["access_token"] = cdk.Duration.days(validity["days"])
291
+
292
+ # ID token validity
293
+ if "id_token_validity" in client_config:
294
+ validity = client_config["id_token_validity"]
295
+ if "minutes" in validity:
296
+ result["id_token"] = cdk.Duration.minutes(validity["minutes"])
297
+ elif "hours" in validity:
298
+ result["id_token"] = cdk.Duration.hours(validity["hours"])
299
+ elif "days" in validity:
300
+ result["id_token"] = cdk.Duration.days(validity["days"])
301
+
302
+ # Refresh token validity
303
+ if "refresh_token_validity" in client_config:
304
+ validity = client_config["refresh_token_validity"]
305
+ if "minutes" in validity:
306
+ result["refresh_token"] = cdk.Duration.minutes(validity["minutes"])
307
+ elif "hours" in validity:
308
+ result["refresh_token"] = cdk.Duration.hours(validity["hours"])
309
+ elif "days" in validity:
310
+ result["refresh_token"] = cdk.Duration.days(validity["days"])
311
+
312
+ return result
313
+
314
+ def _build_attributes(self, attribute_list: list) -> cognito.ClientAttributes:
315
+ """Build client attributes from configuration"""
316
+ if not attribute_list:
317
+ return None
318
+
319
+ # Standard attributes mapping
320
+ standard_attrs = {
321
+ "address": lambda: cognito.ClientAttributes().with_standard_attributes(address=True),
322
+ "birthdate": lambda: cognito.ClientAttributes().with_standard_attributes(birthdate=True),
323
+ "email": lambda: cognito.ClientAttributes().with_standard_attributes(email=True),
324
+ "email_verified": lambda: cognito.ClientAttributes().with_standard_attributes(email_verified=True),
325
+ "family_name": lambda: cognito.ClientAttributes().with_standard_attributes(family_name=True),
326
+ "gender": lambda: cognito.ClientAttributes().with_standard_attributes(gender=True),
327
+ "given_name": lambda: cognito.ClientAttributes().with_standard_attributes(given_name=True),
328
+ "locale": lambda: cognito.ClientAttributes().with_standard_attributes(locale=True),
329
+ "middle_name": lambda: cognito.ClientAttributes().with_standard_attributes(middle_name=True),
330
+ "name": lambda: cognito.ClientAttributes().with_standard_attributes(fullname=True),
331
+ "nickname": lambda: cognito.ClientAttributes().with_standard_attributes(nickname=True),
332
+ "phone_number": lambda: cognito.ClientAttributes().with_standard_attributes(phone_number=True),
333
+ "phone_number_verified": lambda: cognito.ClientAttributes().with_standard_attributes(phone_number_verified=True),
334
+ "picture": lambda: cognito.ClientAttributes().with_standard_attributes(picture=True),
335
+ "preferred_username": lambda: cognito.ClientAttributes().with_standard_attributes(preferred_username=True),
336
+ "profile": lambda: cognito.ClientAttributes().with_standard_attributes(profile=True),
337
+ "timezone": lambda: cognito.ClientAttributes().with_standard_attributes(timezone=True),
338
+ "updated_at": lambda: cognito.ClientAttributes().with_standard_attributes(last_update_time=True),
339
+ "website": lambda: cognito.ClientAttributes().with_standard_attributes(website=True),
340
+ }
341
+
342
+ # Start with empty attributes
343
+ attrs = cognito.ClientAttributes()
344
+
345
+ # Build standard attributes
346
+ standard_dict = {}
347
+ custom_list = []
348
+
349
+ for attr in attribute_list:
350
+ if attr in standard_attrs:
351
+ standard_dict[attr] = True
352
+ else:
353
+ # Custom attribute
354
+ custom_list.append(attr)
355
+
356
+ # Apply standard attributes if any
357
+ if standard_dict:
358
+ # Map attribute names to CDK parameter names
359
+ attr_mapping = {
360
+ "address": "address",
361
+ "birthdate": "birthdate",
362
+ "email": "email",
363
+ "email_verified": "email_verified",
364
+ "family_name": "family_name",
365
+ "gender": "gender",
366
+ "given_name": "given_name",
367
+ "locale": "locale",
368
+ "middle_name": "middle_name",
369
+ "name": "fullname",
370
+ "nickname": "nickname",
371
+ "phone_number": "phone_number",
372
+ "phone_number_verified": "phone_number_verified",
373
+ "picture": "picture",
374
+ "preferred_username": "preferred_username",
375
+ "profile": "profile",
376
+ "timezone": "timezone",
377
+ "updated_at": "last_update_time",
378
+ "website": "website",
379
+ }
380
+
381
+ # Convert to CDK parameter names
382
+ cdk_attrs = {attr_mapping.get(k, k): v for k, v in standard_dict.items()}
383
+ attrs = attrs.with_standard_attributes(**cdk_attrs)
384
+
385
+ # Add custom attributes if any
386
+ if custom_list:
387
+ attrs = attrs.with_custom_attributes(*custom_list)
388
+
389
+ return attrs
390
+
391
+ def _build_identity_providers(self, providers: list) -> list:
392
+ """Build identity provider list from configuration"""
393
+ if not providers:
394
+ return None
395
+
396
+ result = []
397
+ for provider in providers:
398
+ if isinstance(provider, str):
399
+ if provider.upper() == "COGNITO":
400
+ result.append(cognito.UserPoolClientIdentityProvider.COGNITO)
401
+ elif provider.upper() == "GOOGLE":
402
+ result.append(cognito.UserPoolClientIdentityProvider.GOOGLE)
403
+ elif provider.upper() == "FACEBOOK":
404
+ result.append(cognito.UserPoolClientIdentityProvider.FACEBOOK)
405
+ elif provider.upper() == "AMAZON":
406
+ result.append(cognito.UserPoolClientIdentityProvider.AMAZON)
407
+ elif provider.upper() == "APPLE":
408
+ result.append(cognito.UserPoolClientIdentityProvider.APPLE)
409
+ else:
410
+ # Custom provider
411
+ result.append(cognito.UserPoolClientIdentityProvider.custom(provider))
412
+
413
+ return result if result else None
152
414
 
153
- self._export_ssm_parameters(user_pool)
415
+ def _store_client_secret_in_secrets_manager(
416
+ self,
417
+ client_name: str,
418
+ app_client: cognito.UserPoolClient,
419
+ user_pool: cognito.UserPool
420
+ ):
421
+ """
422
+ Store Cognito app client secret in AWS Secrets Manager.
423
+ Uses a custom resource to retrieve the secret from Cognito API.
424
+ """
425
+ # Create a custom resource to retrieve the client secret
426
+ # This is necessary because CDK doesn't expose the client secret
427
+ get_client_secret = cr.AwsCustomResource(
428
+ self,
429
+ f"{client_name}-secret-retriever",
430
+ on_create=cr.AwsSdkCall(
431
+ service="CognitoIdentityServiceProvider",
432
+ action="describeUserPoolClient",
433
+ parameters={
434
+ "UserPoolId": user_pool.user_pool_id,
435
+ "ClientId": app_client.user_pool_client_id,
436
+ },
437
+ physical_resource_id=cr.PhysicalResourceId.of(
438
+ f"{client_name}-secret-{app_client.user_pool_client_id}"
439
+ ),
440
+ ),
441
+ policy=cr.AwsCustomResourcePolicy.from_statements([
442
+ iam.PolicyStatement(
443
+ actions=["cognito-idp:DescribeUserPoolClient"],
444
+ resources=[user_pool.user_pool_arn],
445
+ )
446
+ ]),
447
+ )
448
+
449
+ # Get the client secret from the custom resource response
450
+ client_secret = get_client_secret.get_response_field(
451
+ "UserPoolClient.ClientSecret"
452
+ )
453
+
454
+ # Create secret in Secrets Manager
455
+ secret = secretsmanager.Secret(
456
+ self,
457
+ f"{client_name}-client-secret",
458
+ secret_name=self.deployment.build_resource_name(
459
+ f"cognito/{client_name}/client-secret"
460
+ ),
461
+ description=f"Cognito app client secret for {client_name}",
462
+ secret_string_value=cdk.SecretValue.unsafe_plain_text(client_secret),
463
+ )
464
+
465
+ # Also store client ID in the same secret for convenience
466
+ secret_with_metadata = secretsmanager.Secret(
467
+ self,
468
+ f"{client_name}-client-credentials",
469
+ secret_name=self.deployment.build_resource_name(
470
+ f"cognito/{client_name}/credentials"
471
+ ),
472
+ description=f"Cognito app client credentials for {client_name}",
473
+ secret_object_value={
474
+ "client_id": cdk.SecretValue.unsafe_plain_text(
475
+ app_client.user_pool_client_id
476
+ ),
477
+ "client_secret": cdk.SecretValue.unsafe_plain_text(client_secret),
478
+ "user_pool_id": cdk.SecretValue.unsafe_plain_text(
479
+ user_pool.user_pool_id
480
+ ),
481
+ },
482
+ )
483
+
484
+ logger.info(
485
+ f"Stored client secret for {client_name} in Secrets Manager: "
486
+ f"{secret_with_metadata.secret_name}"
487
+ )
488
+
489
+ # Export secret ARN to SSM for cross-stack reference
490
+ if self.cognito_config.ssm.get("enabled"):
491
+ safe_client_name = client_name.replace("-", "_").replace(" ", "_")
492
+ org = self.cognito_config.ssm.get("organization", "default")
493
+ env = self.cognito_config.ssm.get("environment", "dev")
494
+
495
+ ssm.StringParameter(
496
+ self,
497
+ f"{client_name}-secret-arn-param",
498
+ parameter_name=f"/{org}/{env}/cognito/user-pool/app_client_{safe_client_name}_secret_arn",
499
+ string_value=secret_with_metadata.secret_arn,
500
+ description=f"Secrets Manager ARN for {client_name} credentials",
501
+ )
154
502
 
155
503
  def _export_ssm_parameters(self, user_pool: cognito.UserPool):
156
504
  """Export Cognito resources to SSM using enhanced SSM parameter mixin"""
@@ -172,6 +520,16 @@ class CognitoStack(IStack, EnhancedSsmParameterMixin):
172
520
  "user_pool_arn": user_pool.user_pool_arn,
173
521
  }
174
522
 
523
+ # Add app client IDs to export
524
+ for client_name, app_client in self.app_clients.items():
525
+ # Export client ID
526
+ safe_client_name = client_name.replace("-", "_").replace(" ", "_")
527
+ resource_values[f"app_client_{safe_client_name}_id"] = app_client.user_pool_client_id
528
+
529
+ # Note: Client secrets cannot be exported via SSM as they are only available
530
+ # at creation time and CDK doesn't expose them. Use AWS Secrets Manager
531
+ # or retrieve via AWS Console/CLI if needed.
532
+
175
533
  # Use enhanced SSM parameter export
176
534
  exported_params = self.auto_export_resources(resource_values)
177
535
 
cdk_factory/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.8.5"
1
+ __version__ = "0.8.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdk_factory
3
- Version: 0.8.5
3
+ Version: 0.8.7
4
4
  Summary: CDK Factory. A QuickStarter and best practices setup for CDK projects
5
5
  Author-email: Eric Wilson <eric.wilson@geekcafe.com>
6
6
  License: MIT License
@@ -1,7 +1,7 @@
1
1
  cdk_factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  cdk_factory/app.py,sha256=xv863N7O6HPKznB68_t7O4la9JacrkG87t9TjoDUk7s,2827
3
3
  cdk_factory/cdk.json,sha256=SKZKhJ2PBpFH78j-F8S3VDYW-lf76--Q2I3ON-ZIQfw,3106
4
- cdk_factory/version.py,sha256=K0kGrhh1kzVisZcoSkeuJdC06rTwxufV05Vy2hOVGoo,22
4
+ cdk_factory/version.py,sha256=vTwvdJOZi8jZb9U-Em7-d50qNDNPS2z51IXqRoojeNM,22
5
5
  cdk_factory/builds/README.md,sha256=9BBWd7bXpyKdMU_g2UljhQwrC9i5O_Tvkb6oPvndoZk,90
6
6
  cdk_factory/commands/command_loader.py,sha256=QbLquuP_AdxtlxlDy-2IWCQ6D-7qa58aphnDPtp_uTs,3744
7
7
  cdk_factory/configurations/base_config.py,sha256=JKjhNsy0RCUZy1s8n5D_aXXI-upR9izaLtCTfKYiV9k,9624
@@ -25,7 +25,7 @@ cdk_factory/configurations/resources/cloudwatch_widget.py,sha256=EdEQSXUkDtoY_Mg
25
25
  cdk_factory/configurations/resources/code_artifact.py,sha256=P2X2i6NEcePitEf2wkN6lFTjIbXasn0uzrlPOT0tEac,3253
26
26
  cdk_factory/configurations/resources/code_artifact_login.py,sha256=mKd8Bx0WypmSspfibwXbgubbIzW-6gGdQqIHvOnDAYQ,6066
27
27
  cdk_factory/configurations/resources/code_repository.py,sha256=rAM6cbMtNR_S4TfiBHtfQjnSlB7MOgfDkJWRzwUe764,1872
28
- cdk_factory/configurations/resources/cognito.py,sha256=SPemBnP0rVa6zr0HfATyXQIqnzwNzmx3ciZqRDxvj2k,8392
28
+ cdk_factory/configurations/resources/cognito.py,sha256=udX2AJ1ITLhy4f1XiJQwrva6F4i9NdbSm0zTg5PGku8,10649
29
29
  cdk_factory/configurations/resources/docker.py,sha256=hUbuxkuhcQu9LnLX7I8_57eTmHefEAGVnOHO37MkqC4,2166
30
30
  cdk_factory/configurations/resources/dynamodb.py,sha256=HsZMOaRwfuNPwKIzokeeE3f5zAQLTB5hRb_GzYq2ibg,2903
31
31
  cdk_factory/configurations/resources/ecr.py,sha256=LT2m13SsmxymaQXOtYTEbXwNWXIPURkoAR6py8pNrTE,6584
@@ -73,14 +73,14 @@ cdk_factory/stack/stack_module_registry.py,sha256=J14-A75VZESzRQa8p-Fepdap7Z8T7m
73
73
  cdk_factory/stack/stack_modules.py,sha256=kgEK-j0smZPozVwTCfM1g1V17EyTBT0TXAQZq4vZz0o,784
74
74
  cdk_factory/stack_library/__init__.py,sha256=5Y9TpIe8ZK1688G60PGcuP-hM0RvYEY_3Hl2qJCJJrw,581
75
75
  cdk_factory/stack_library/stack_base.py,sha256=tTleSFmlf26DuKVF_ytftf8P7IVWb5iex8cYfYupfvQ,4940
76
- cdk_factory/stack_library/api_gateway/api_gateway_stack.py,sha256=BWhawbwGHggKQN3QLolZhdECoeTTnTBTrRo2hTJC570,38469
76
+ cdk_factory/stack_library/api_gateway/api_gateway_stack.py,sha256=l6J5uurBQqbhj9JuvQitV9PiIHS5kqa-dFWifCeA3GM,39347
77
77
  cdk_factory/stack_library/auto_scaling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
78
  cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py,sha256=UsFqUb_3XPJAlmZ6F75nXna3elOggD1KuFmmdmhi0Lg,19070
79
79
  cdk_factory/stack_library/aws_lambdas/lambda_stack.py,sha256=SFbBPvvCopbyiuYtq-O5sQkFCf94Wzua6aDUXiFDSB4,26161
80
80
  cdk_factory/stack_library/buckets/README.md,sha256=XkK3UNVtRLE7NtUvbhCOBBYUYi8hlrrSaI1s3GJVrqI,78
81
81
  cdk_factory/stack_library/buckets/bucket_stack.py,sha256=SLoZqSffAqmeBBEVUQg54D_8Ad5UKdkjEAmKAVgAqQo,1778
82
82
  cdk_factory/stack_library/code_artifact/code_artifact_stack.py,sha256=vySYIjWGTdVfMcUOyJdW6gTL1maHWq9ThzfrN_rVL5A,6290
83
- cdk_factory/stack_library/cognito/cognito_stack.py,sha256=7z-cnr07lOtIh0U6dVJAHpuZtpAH8Of4f3Zll2LmrlM,7918
83
+ cdk_factory/stack_library/cognito/cognito_stack.py,sha256=zEHkKVCIeyZywPs_GIMXCXyCux9RAKdl5kba3wy8wtQ,24608
84
84
  cdk_factory/stack_library/dynamodb/dynamodb_stack.py,sha256=TVyOrUhgaSuN8uymkpaQcpOaSA0lkYJ8QUMgakTCKus,6771
85
85
  cdk_factory/stack_library/ecr/README.md,sha256=xw2wPx9WN03Y4BBwqvbi9lAFGNyaD1FUNpqxVJX14Oo,179
86
86
  cdk_factory/stack_library/ecr/ecr_stack.py,sha256=1xA68sxFVyqreYjXrP_7U9I8RF9RtFeR6KeEfSWuC2U,2118
@@ -112,7 +112,7 @@ cdk_factory/utilities/lambda_function_utilities.py,sha256=S1GvBsY_q2cyUiaud3HORJ
112
112
  cdk_factory/utilities/os_execute.py,sha256=5Op0LY_8Y-pUm04y1k8MTpNrmQvcLmQHPQITEP7EuSU,1019
113
113
  cdk_factory/utils/api_gateway_utilities.py,sha256=If7Xu5s_UxmuV-kL3JkXxPLBdSVUKoLtohm0IUFoiV8,4378
114
114
  cdk_factory/workload/workload_factory.py,sha256=yBUDGIuB8-5p_mGcVFxsD2ZoZIziak3yh3LL3JvS0M4,5903
115
- cdk_factory-0.8.5.dist-info/METADATA,sha256=YvPCDURf01vFMctbkAMdz74vNTDy3mhYPEIcaocczkY,2450
116
- cdk_factory-0.8.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
117
- cdk_factory-0.8.5.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
118
- cdk_factory-0.8.5.dist-info/RECORD,,
115
+ cdk_factory-0.8.7.dist-info/METADATA,sha256=WGWpDzr9pYOJtD_F35pKGQZF9Fb-BUBI5AAhj652bOw,2450
116
+ cdk_factory-0.8.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
117
+ cdk_factory-0.8.7.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
118
+ cdk_factory-0.8.7.dist-info/RECORD,,