33
votes

Setup

I am using AWS Cognito to manage the user registration and user access for my web application. Specifically I am using the Cognito hosted UI. This means that Cognito presents a UI for my users to register, I do not have access to modify the user sign-up or login pages for my application (other than the controls provided by Cognito). I am using email addresses as usernames, so new users are simply asked to provide an email address and password.

enter image description here

Problem

Cognito treats email addresses as case sensitive. If a user signs up with the email address [email protected], they cannot then sign in using [email protected].

I want user email addresses for sign-up and login to be case insensitive.

What I have tried

Usually this would be trivial to deal with by setting the email address to the lowercase in the client before sending it to the server. However I do not have access to the client UI as it is hosted by Cognito.

My plan therefore was to try using a Lambda function invoked by a Cognito pre-signup trigger to lowercase the email supplied by the user.

Pre sign-up

Amazon Cognito invokes this trigger when a user attempts to register (sign up), allowing you to perform custom validation to accept or deny the registration request.

Here is the lamdba function I wrote:

'use strict';

console.log('Loading function');

exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));

    var triggerSource = event.triggerSource;
    console.log('Received triggerSource:', triggerSource);

    var email = event.request.userAttributes.email;
    console.log('Received email:', email);

    var modifiedEvent = event;

    if (email !== null) {
        var lowerEmail = email.toLowerCase();
        modifiedEvent.request.userAttributes.email = lowerEmail;
        console.log('Set email in request to', lowerEmail);
        console.log('Modified event:', JSON.stringify(modifiedEvent, null, 2));
    } else {
        console.log('Email evaluated as NULL, exiting with no action');
    }

    // Return result to Cognito
    callback(null, modifiedEvent);
};

This 'worked' in the sense that the email address in the event request was modified to be lowercase ([email protected]). However, it seems the account has already been created in the userpool by the time my Lambda function receives this event. Changing the email address in the request had no effect - the original email address ([email protected]) still appears in my user pool. I suspect the only fields in the event that have any effect are the response fields. Here is what my modified event looks like:

{
    "version": "1",
    "region": "us-east-1",
    "userPoolId": "us-east-1_xxxxxxx",
    "userName": "xxxxxx-xxxx-xxxx-xxxx-xxxxxxx",
    "callerContext": {
        "awsSdkVersion": "aws-sdk-java-console",
        "clientId": "xxxxxxxxxxxxxxxxxxxxxx"
    },
    "triggerSource": "PreSignUp_SignUp",
    "request": {
        "userAttributes": {
            "email": "[email protected]"
        },
        "validationData": null
    },
    "response": {
        "autoConfirmUser": false,
        "autoVerifyEmail": false,
        "autoVerifyPhone": false
    }
}

My question

I'm looking for ideas or examples to make my user registration and login case insensitive. This might include changes to my lambda trigger approach or something else entirely.

Please note I know I could implement my own UI, which I will only do as a last resort.

5
The documentation says that username is case sensitive, but email is not. Are you opposed to using usernames in addition to email?user
Clearly login email should be case insensitive and this is a bug on Amazon's side, have you tried logging bug report or a support request?Chris Gunawardena
I beg to differ. Emails are NOT case insensitive, I’ve seen people get access to accounts they should not have because of this.Martin M.
Apparently it is currently not possible to make the email case insensitive. If you decide to implement your own UI, I am currently lowercasing it on the client-side and verify that its lowercased in the preSignUp tigger.Philiiiiiipp
This is NOT a bug. As per RFC5321, the local-part of an email address (local-part@domain) is case sensitive. That's because historically that local-part was a username and user names were, and still are, case sensitive on some operating systems. Amazon are just following the RFC. Doesn't mean they shouldn't provide case insensitivity as an option though.bgdnlp

5 Answers

2
votes

You could trigger a Lambda function after sign-up to change the email to lowercase. Without actually testing it, you should be able to trigger a Lambda post confirmation. That Lambda could use AdminUpdateUserAttributes API, called from your SDK of choice, to change the email to lowercase.

Note that user names are also case sensitive.

0
votes

Since username is case sensetive: why not just use the username as the email address and have the prehook populate the email field with the username?

0
votes

Make username lowercase when creating the account. Make username lowercase when logging in. At least this way you only have to re-create users that have uppercase characters. Or you can rebuild your entire user pool and migrate the users, but who knows what affect that will have on passwords and MFA. It doesn't seem worth the trouble with an existing user pool. Hopefully you are doing a brand new project and you can select the case insensitive option when creating the user pool.

-3
votes

another possibility is if you can create a user signup api, which would create the user in the cognito. after trimming email along with performing lower case on email. you can perform your custom steps before that.

you are right that pre-signup trigger basically get invoked after signup is performed.

https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html#aws-lambda-triggers-pre-registration-tutorials