amplify-ui icon indicating copy to clipboard operation
amplify-ui copied to clipboard

Support auto-generated username in AmplifySignUp

Open ronnyroeller opened this issue 4 years ago • 10 comments

Is your feature request related to a problem? Please describe. I want user to self-signup with email/password. Users don't control the username.

For this, I set up AmplifySignUp as following:

<AmplifyAuthenticator usernameAlias="email">
  <AmplifySignUp
    slot="sign-up"
    usernameAlias="email"
    formFields={[
      {
        type: 'email',
      },
      {
        type: 'password',
      },
    ]}
  />
</AmplifyAuthenticator>

Yet, when submitting the form, I it gives the error "Username cannot be of email format, since user pool is configured for email alias".

I read various discord message and tickets (e.g. https://github.com/aws-amplify/amplify-js/issues/2160#issuecomment-469000756), which pointed to inconsistent usernameAlias and to signUpFields (which doesn't seem to exist any longer) - but none of this seems to apply to my code

Describe the solution you'd like In order of preference:

  1. <AmplifySignUp> wouldn't send the username but Cognito auto-generates a UUID on the backend
  2. <AmplifySignUp> auto-generates the username (UUID)
  3. <AmplifySignUp> provides an interface to to pass the username before sending the signup call to Cognito
  4. <AmplifySignUp> defaulted the username to the email address (but doesn't give the "Username cannot be of email format, since user pool is configured for email alias")

Describe alternatives you've considered I reimplementing the signUp function (see below) but it doesn't feel right:

  • After successfully running through <AmplifySignUp>, <AmplifyConfirmSignUp> gets confused and shows the username in the email field.
  • Many functions from AmplifySignUp.signUp aren't accessible from the outside (e.g. handleSignIn, dispatchToastHubEvent) - it feels like one isn't actually supposed to reimplement the function.
<AmplifySignUp
  slot="sign-up"
  usernameAlias="email"
  handleSubmit={signUp}
  formFields={[
    {
      type: 'email',
      handleInputChange: (e: any) => setEmail(e.target.value),
      required: true,
    },
    {
      type: 'password',
      handleInputChange: (e: any) => setPassword(e.target.value),
      required: true,
  },
]}
    const signUp = useCallback(async (event: Event) => {
        if (event) {
            event.preventDefault();
        }

        if (!email || !password) {
            throw new Error(`Email ${email} and password must be set`);
        }

        const signUpAttributes: any = {
            attributes: {
                email,
            },
            password,
            username: uuidV4(),
        };

        const handleAuthStateChange: AuthStateHandler = (nextAuthState, data) => {
            Hub.dispatch(UI_AUTH_CHANNEL, {
                event: AUTH_STATE_CHANGE_EVENT,
                message: nextAuthState,
                data,
            });
        }
        const dispatchToastHubEvent = (error: any) => {
            Hub.dispatch(UI_AUTH_CHANNEL, {
                event: TOAST_AUTH_ERROR_EVENT,
                message: I18n.get(error.message),
            });
        };

        // this.loading = true;
        try {
            const data = await Auth.signUp(signUpAttributes);
            if (!data) {
                throw new Error(Translations.SIGN_UP_FAILED);
            }
            if (data.userConfirmed) {
                alert('handleSignIn');
                // await handleSignIn(signUpAttributes.username, password, handleAuthStateChange);
            } else {
                const signUpAttrs = { ...signUpAttributes };
                handleAuthStateChange(AuthState.ConfirmSignUp, { ...data.user, signUpAttrs });
            }
        } catch (error) {
            dispatchToastHubEvent(error);
        } finally {
            // this.loading = false;
        }
    }, [email, password]);

Additional context I'm using @aws-amplify/ui-react#1.0.1.

ronnyroeller avatar Feb 20 '21 08:02 ronnyroeller

@ronnyroeller I'm interesting in learning more about why the username is autogenerated. It sounds like you're using email for identification & sign-in, so what's the purpose of the UUID?

ericclemmons avatar Feb 23 '21 21:02 ericclemmons

what's the purpose of the UUID?

It's not a hard requirement but more a convince.

Here are the challenges we faced with using email addresses as usernames:

  • Users can change their emails, leading to e.g. a user with username [email protected] to have email address [email protected]. That's not a problem as long as operators/developers remember that the username is just a random string that happens to look like an email address - but we found that this is hard on people. UUIDs communicate clearer that the username is the identifier and the email is where emails are sent to.
  • One needs to take extra care where to use the username because it's now personal identifiable data, which is legally stronger protected (e.g. by GDPR in Europe). This starts from obvious things like avoiding to use the username for profiles (e.g. example.com/profile/USERNAME); to having to introduce another non-identifiable ID to link users to other data point; up to developers ensuring to strip out the username from any logs that aren't cleared for personal identifiable data (or more realistically: ensure log destinations are legally cleared to store it).

ronnyroeller avatar Feb 23 '21 22:02 ronnyroeller

I went through the same issue I ended overwriting the cloud formation file generated by removing AliasAttributes and add:

UsernameAttributes:
  - email

as it met the expectation that you describe:

  • have the username using a hash
  • ability to sign-up/sign-in with email/pwd

Note that Amplify-Cli use to use UsernameAttributes instead AliasAttributes until recently: https://github.com/aws-amplify/amplify-cli/pull/7461 which explain the unexpected error message: "Username cannot be of email format, since user pool is configured for email alias".

fabientownsend avatar Aug 16 '21 13:08 fabientownsend

@fabientownsend you're a life saver!!

meatherly avatar Aug 22 '21 23:08 meatherly

I went through the same issue I ended overwriting the cloud formation file generated by removing AliasAttributes and add:

UsernameAttributes:
  - email

as it met the expectation that you describe:

  • have the username using a hash
  • ability to sign-up/sign-in with email/pwd

Note that Amplify-Cli use to use UsernameAttributes instead AliasAttributes until recently: aws-amplify/amplify-cli#7461 which explain the unexpected error message: "Username cannot be of email format, since user pool is configured for email alias".

Hey Fabien I'm trying this, but getting an error when executing amplify push:

Updates are not allowed for property - UsernameAttributes

Can you provide more details on how you did it please?

karmap avatar Sep 07 '21 05:09 karmap

Hey Fabien I'm trying this, but getting an error when executing amplify push:

Updates are not allowed for property - UsernameAttributes

Can you provide more details on how you did it please?

Hey Karmap, I have a very limited experience with Amplify and CloudFormation so I'm not quite sure about the source of the issue. Based on the error that you have, it seems that you may have:

  1. Amplify add auth
  2. Amplify push
  3. Modified the CloudFormation file
  4. Amplify push

Where in my case I:

  1. Amplify add auth
  2. Modified the CloudFormation file
  3. Amplify push

So, if you pushed the Auth before modifying the CloudFormation, I'm not quite sure if you can update/modify your current Cognito configuration through CloudFormation.

From here I would either:

  • Amplify remove auth and then restart
  • Find a way to update the Cognito configuration through Cloudformation or the AWS console

I hope it helps

fabientownsend avatar Sep 11 '21 09:09 fabientownsend

Hey Fabien I'm trying this, but getting an error when executing amplify push: Updates are not allowed for property - UsernameAttributes Can you provide more details on how you did it please?

Hey Karmap, I have a very limited experience with Amplify and CloudFormation so I'm not quite sure about the source of the issue. Based on the error that you have, it seems that you may have:

  1. Amplify add auth
  2. Amplify push
  3. Modified the CloudFormation file
  4. Amplify push

Where in my case I:

  1. Amplify add auth
  2. Modified the CloudFormation file
  3. Amplify push

So, if you pushed the Auth before modifying the CloudFormation, I'm not quite sure if you can update/modify your current Cognito configuration through CloudFormation.

From here I would either:

  • Amplify remove auth and then restart
  • Find a way to update the Cognito configuration through Cloudformation or the AWS console

I hope it helps

Thank you so much for your detailed answer, that exactly what I was doing!

As and extra info por people getting here: I ended up hashing the email as a uuid.v5() and saving it as username

karmap avatar Sep 20 '21 21:09 karmap

@ronnyroeller We have released a new major version of Authenticator UI component which has a support for custom styling, zero config support (signup attributes), social sign ins, parity across all web frameworks, password manager support and many more. The Authenticator automatically infers signUpAttributes from amplify pull, but can be explicitly defined as seen below. Authenticator component automatically renders most Cognito User Pools attributes, with the exception of address, gender, locale, picture, updated_at, and zoneinfo. Because these are often app-specific, they can be customized via Sign Up fields. Let us know if you run into any new issues, we are here to help :)

Milan-Shah avatar Nov 23 '21 23:11 Milan-Shah

@Milan-Shah I'm not sure I understand the documentation properly, so let me ask explicitly: Is there a way to use this component without the Amplify CLI and aws-exports.js?

ankon avatar Nov 24 '21 09:11 ankon

@ankon Yes, few of our customers have used an Authenticator component with CDK instead of Amplify CLI. in 2023, we intend to support the implementation with CDK and Terraform with guides on how to for every connected component. We will keep you posted!

Milan-Shah avatar Jul 21 '22 18:07 Milan-Shah

Closing this as it refers to a deprecated version of Authenticator and the CDK request is a duplicate of https://github.com/aws-amplify/amplify-ui/issues/274

If anyone comes across the problems mentioned above with the new Authenticator, please create a new issue.

reesscot avatar May 26 '23 22:05 reesscot