aws / aws/aws-cdk

Cognito UserPools - Hosted UI Customizations (including logo upload)

Open
#6,953 17 comments 52 reactions 0 assignees View on GitHub
@aws-cdk/aws-cognito effort/medium feature-request p1
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

As per the https://github.com/aws/aws-cdk/issues/6765 tracking issue, CDK doesn't yet have construct support for all Cognito things. We can use escape hatches, but it would be good to have native support to be able to apply Cognito UserPools Hosted UI Customisations (CSS, logo upload, etc)

### Use Case

To apply Cognito UserPool Hosted UI customizations as part of my CDK stack, without having to resort to escape hatches/workarounds.

### Proposed Solution

Implement some new constructs that support the UI customisations. As Cloudformation doesn't currently support uploading the logo, this would probably be achieved by a custom resource that calls the AWS SDK or similar.

The following code snippets are my initial attempts to workaround this with the escape hatch, but while they seemed to deploy, I don't know that they actually worked in the end. In particular, I'm not sure the latter AWS SDK call was working particularly well for the image upload. Originally I intended to use the CloudFormation part for the CSS, and just do the logo via the SDK, but I chopped and changed the code a little in trying to get things working.

You require a domain set on the UserPool before you are able to apply customisations.

The logo can apparently only be JPG/PNG.

Refs:

- CDK
- https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cognito.CfnUserPoolUICustomizationAttachment.html
- https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_custom-resources.AwsCustomResource.html
- https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpooluicustomizationattachment.html
- https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-ui-customization.html
- https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUICustomization.html
- https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#setUICustomization-property

Warning, this code may not actually work as it is currently:

```javascript
const fs = require('fs')

/**
* Cognito Hosted UI customisations.
*
* @type {CfnUserPoolUICustomizationAttachment}
*
* @see https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cognito.CfnUserPoolUICustomizationAttachment.html
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpooluicustomizationattachment.html
* @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-ui-customization.html
*/
const userPoolHostedUICustomisation = new cognito.CfnUserPoolUICustomizationAttachment(
this,
'UserPoolHostedUICustomisation',
{
userPoolId: userPool.userPoolId,
clientId: 'ALL',
css: fs.readFileSync('./assets/cognito-hosted-ui.css').toString('utf-8'),
}
)
userPoolHostedUICustomisation.node.addDependency(userPool)
userPoolHostedUICustomisation.node.addDependency(userPoolDomain)

/**
* Use the AWS SDK to upload a custom logo + CSS for the Cognito Hosted UI customisations.
*
* @type {AwsCustomResource}
*
* @see https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_custom-resources.AwsCustomResource.html
* @see https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUICustomization.html
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#setUICustomization-property
*/
const userPoolHostedUICustomisations = new cr.AwsCustomResource(
this,
'UserPoolHostedUILogo',
{
resourceType: 'Custom::SetCognitoUserPoolHostedUILogo',
onCreate: {
service: 'CognitoIdentityServiceProvider',
action: 'setUICustomization',
parameters: {
UserPoolId: userPool.userPoolId,
ClientId: 'ALL',
// Note: Wrap with Buffer because the SDK automatically Base64 encodes string, which double encodes the image
ImageFile: Buffer.from(fs.readFileSync('./assets/logo.png').toString('base64')),
// ImageFile: fs.readFileSync('./assets/logo.png'),
CSS: fs
.readFileSync('./assets/cognito-hosted-ui.css')
.toString('utf-8'),
},
physicalResourceId: cr.PhysicalResourceId.of(
`cognito-ui-logo-all-clients-${userPoolDomain.domain}`
),
},
// TODO: can we restrict this policy more? Get the ARN for the user pool domain? Or the user pool maybe?
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
// TODO: ?? resources: [userPool.userPoolArn],
}),
}
)
```

### Other

* [ ] :wave: I may be able to implement this feature request
* [ ] :warning: This feature might incur a breaking change

---

This is a :rocket: Feature Request

Contributor guide

Open the contributing guide

Research direction

Start with the Cognito CfnUserPoolUICustomizationAttachment and AwsCustomResource entry points, then review the linked CloudFormation and SetUICustomization API references. Done means native CDK support for UserPool Hosted UI CSS and logo customizations, including the required UserPool domain dependency, without escape-hatch workarounds.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
authentication, cloud
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.