aws-amplify / amplify-ui

Amplify UI is a collection of accessible, themeable, performant React (and more!) components that can connect directly to the cloud.
https://ui.docs.amplify.aws
Apache License 2.0
884 stars 280 forks source link

FR (Authenticator): add option to display the full email on confirmation code screen #4998

Open renschler opened 7 months ago

renschler commented 7 months ago

On which framework/platform would you like to see this feature implemented?

React

Which UI component is this feature-request for?

Authenticator

Please describe your feature-request in detail.

Screenshot 2024-02-10 at 10 04 41 AM

If a user has a typo in their signup email, this screen won't let them catch the error.

This happens at least once a week for my app. I'll get a user who signs up with an invalid email, and then their verification code emails will bounce.

Screenshot 2024-02-10 at 10 13 14 AM

Most users do not reach out to me, they probably just assume the website is broken.

It would be great if the confirmation code screen showed the full email that was used instead of obfuscating the email.

Please describe a solution you'd like.

The confirmation code screen should display the full email address. (or we should have the option to display the full email address)

We love contributors! Is this something you'd be interested in working on?

renschler commented 7 months ago

not sure if there is a way for me to customize things with the current version. It looks like codeDeliveryDetails has the obfuscated email and not the full email

Screenshot 2024-02-10 at 10 26 58 AM
renschler commented 7 months ago

Just to provide some more context here. I checked in my cognito dashboard and I have numerous "unconfirmed" users. Many have emails with obvious typos @gmai.com, .con instead of .com, @hotamail.com, etc

Hard to say if these users ever figured things out themselves or if they just gave up. This is a high priority UI issue for me.

johnpc commented 7 months ago

As a workaround, you could write a preSignUp Cognito lambda trigger that checks the email for potential typos and fails if you determine the email is invalid. Something like:

export const handler: PreSignUpTriggerHandler = async (
  event,
  context,
  callback,
) => {
  const email = event.request.userAttributes.email;
  if (isValid(email)) {
    return callback(null, event);
  } else {
    const error = new Error(`Email ${email} is invalid.`);
    return callback(error as Error, event);
  }
};
renschler commented 7 months ago

thx, I could catch some of the obvious domain typos that way, would be hard to catch the typos that come before the @ though. Sometimes it's like michelllee@gmail vs michelle@gmail etc.

The best solution imo is for users to be able to see what email they used. If they don't receive a code, that's the first thing they would check but they can't check it today because it's obfuscated.

esauerbo commented 7 months ago

Hi @renschler thanks for creating this issue; we're considering adding this feature request to our roadmap.

renschler commented 7 months ago

@esauerbo fantastic!

Even just a 1% increase on signup conversion rates would be a huge value add if you consider all of the sites currently using the amplify authenticator.

I'll cast a vote for "full email visibility" to be the default behavior (I don't understand the need for obfuscation here).

renschler commented 6 months ago

Here's a good example. Yesterday I got several delivery status notification failures for the same email. So the user was trying to signup, didn't get the email, and kept pressing the "resend code" button to no avail.

Screenshot 2024-03-10 at 2 51 50 PM

I can see on my end that the user never figured things out, because there were no signups under a different email following their failed attempts.

Furthermore, the email doesn't have an obvious typo so I can't go email the person at their true email to let them know they were using a bad email. And preSignUp logic for catching typos wouldn't have done anything.

calebpollman commented 6 months ago

Hi @renschler Apologies for the churn here. The confirmation code destination value is obfuscated in the output of the service call, example:

{
    "isSignUpComplete": false,
    "nextStep": {
        "signUpStep": "CONFIRM_SIGN_UP",
        "codeDeliveryDetails": {
            "deliveryMedium": "EMAIL",
            "destination": "c***@g***",
            "attributeName": "email"
        }
    },
    "userId": "xxxxxx"
}

To achieve the desired behavior, you can pass a custom handleSignUp function inside the services prop and replace the destination value of the output to be the value the end user inputted in to the email field on sign up:

import { signUp, SignUpInput } from 'aws-amplify/auth';
import { Authenticator } from '@aws-amplify/ui-react';

async function handleSignUp(input: SignUpInput) {
  const output = await signUp(input);
  if (output.nextStep.signUpStep === 'CONFIRM_SIGN_UP') {
    return {
      ...output,
      nextStep: {
        ...output.nextStep,
        codeDeliveryDetails: {
          ...output.nextStep.codeDeliveryDetails,
          // sign up email field name is generic `username`
          destination: input.username,
        },
      },
    };
  }
  return output;
}

function App() {
  return (
    <Authenticator services={{ handleSignUp }} />
  );
}
renschler commented 6 months ago

thank you @calebpollman for the example. I tried the code but I get a "signUp" is not defined error in my cognito auth widget.

This is the line that fails const output = await signUp(input);

Do I also need to define signUp?

esauerbo commented 6 months ago

Hey @renschler yes you can import like so:

import { signUp, SignUpInput } from 'aws-amplify/auth';

Here's the documentation on that

renschler commented 6 months ago

thanks @esauerbo I'll give it a shot. I had tried using the approach mentioned here and it failed saying Auth.signUp was not a function https://ui.docs.amplify.aws/react/connected-components/authenticator/customization#override-function-calls

import { Auth } from 'aws-amplify';
...
await Auth.signUp(input)
esauerbo commented 6 months ago

@renschler sorry for the confusion there. That snippet uses aws-amplify@5 (the previous major version). We have a PR out to update those docs. In version 6 those functions are exported directly.

renschler commented 6 months ago

awesome thank you! I got it working on my amplify v6 website; it now displays the full email on the code submission prompt.

I have a question about the amplify v5 implementation for my v5 website. (sorry for the hand holding, I don't expect a response to this but just pasting it here to enrich the ticket).

import { Auth } from 'aws-amplify';
...
...
            async handleSignUp(input) {
              const output = await Auth.signUp({
                ...input,
                autoSignIn: {
                  enabled: true,
                },
              })
              //if (output.nextStep.signUpStep === 'CONFIRM_SIGN_UP') {
              if (output.codeDeliveryDetails != null) {
                return {
                  ...output,
                  codeDeliveryDetails: {
                    ...output.codeDeliveryDetails,
                    Destination: input.username,
                  },
                }
              }
              return output
            }

Does v5 has something similar to nextStep that I should be checking (i've commented out the output.nextStep check from the v6 implementation)?

renschler commented 5 months ago

Thanks again for the help here; since deploying this change it has saved 9 users from dropping off because they entered the wrong email address.

It's a small % of signups but everyone who uses the Authenticator widget must be facing this same issue (even though they probably don't realize it).

Screenshot 2024-04-29 at 8 47 30 AM