Support auto-generated username in AmplifySignUp
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:
-
<AmplifySignUp>wouldn't send the username but Cognito auto-generates a UUID on the backend -
<AmplifySignUp>auto-generates the username (UUID) -
<AmplifySignUp>provides an interface to to pass the username before sending the signup call to Cognito -
<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 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?
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).
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 you're a life saver!!
I went through the same issue I ended overwriting the cloud formation file generated by removing
AliasAttributesand add:UsernameAttributes: - emailas 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
UsernameAttributesinsteadAliasAttributesuntil 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?
Hey Fabien I'm trying this, but getting an error when executing
amplify push:
Updates are not allowed for property - UsernameAttributesCan 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:
-
Amplify add auth -
Amplify push - Modified the CloudFormation file
-
Amplify push
Where in my case I:
-
Amplify add auth - Modified the CloudFormation file
-
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 authand then restart - Find a way to update the Cognito configuration through Cloudformation or the AWS console
I hope it helps
Hey Fabien I'm trying this, but getting an error when executing
amplify push:Updates are not allowed for property - UsernameAttributesCan 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:
Amplify add authAmplify push- Modified the CloudFormation file
Amplify pushWhere in my case I:
Amplify add auth- Modified the CloudFormation file
Amplify pushSo, 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 authand 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
@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 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 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!
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.