Authenticator - Allow adding custom fields to SignIn screen
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.
Im setting up a multi-tenant SaaS that requires using and organizationId in order to login our users.
I've managed to implement a custom organization_id field on the SignUp form using the following code:
<Authenticator
services={services({
inviteCode: invitation || undefined,
organizationId: organizationId || undefined,
})}
initialState={invitation ? 'signUp' : 'signIn'}
formFields={{
signUp: {
username: {
placeholder: 'Enter Your Email Here',
isRequired: true,
label: 'Email:',
},
...(invitation && organizationId
? {
'custom:organization_id': {
placeholder: 'Enter your Organization ID here',
isRequired: false,
label: 'Organization ID',
defaultValue: organizationId ?? undefined,
isReadOnly: true,
order: 1,
},
}
: {}),
},
}}
But now I also need to be able to provide the organization_id during the logIn process, so naturally I tried doing the following:
<Authenticator
services={services({
inviteCode: invitation || undefined,
organizationId: organizationId || undefined,
})}
initialState={invitation ? 'signUp' : 'signIn'}
formFields={{
signIn: {
organization_id: {
placeholder: '(Optional) Enter your Organization ID here',
isRequired: false,
label: 'Organization ID',
order: 1,
},
username: {
placeholder: 'Enter Your Email Here',
isRequired: true,
label: 'Email',
},
},
}}
But unfortunately when I implement the handleSignIn function in my service, I never get the value for this custom organization_id field
async handleSignIn(input: SignInInput) {
const { username, password, options } = input
const organizationId =
options?.userAttributes?.['custom:organization_id'] ||
options?.clientMetadata?.['custom:organization_id']
const hashedUsername = getHashedUsername(username, organizationId)
console.log({ input, organizationId, hashedUsername })
return signIn({
username: hashedUsername,
password,
options: {
...input.options,
userAttributes: {
email: username,
},
},
})
},
Please describe a solution you'd like.
I would like the SignIn form to display custom fields the same way that the SignUp form allows us to add custom userAttributes so that we can build more complex authentication flows.
Alternatively it would be nice to overwrite the components on the SignUp form doing something like:
components={{
SignIn: {
FormFields() {
// eslint-disable-next-line react-compiler/react-compiler
const { validationErrors } = useAuthenticator()
return (
<>
<TextField
name="organization_id"
label="Organization ID"
placeholder="Enter your Organization ID here"
defaultValue={organizationId ?? undefined}
/>
<Authenticator.SignIn.FormFields />
</>
)
},
},
We love contributors! Is this something you'd be interested in working on?
- [x] 👋 I may be able to implement this feature request.
- [ ] ⚠️ This feature might incur a breaking change.
+1 for this feature request 🙏
@fmonper1 Thanks for bringing this to our attention, we will look in to it
+1 🙏
I've tried running the repo locally but I haven't been able run the next-pages-router example app.
I think this feature shouldn't be super complex for someone familiar with XState.
We already have access to all the fields from the form in this piece of code here.
const handleSubmit = useCallback(
(event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
submitForm(getFormDataFromEvent(event));
},
[submitForm]
);
We can provide names to our custom fields like this (although Typescript complains, its still valid)
formFields={{
signIn: {
organization_id: {
placeholder: '(Optional) Enter your Organization ID here',
isRequired: false,
label: 'Organization ID',
defaultValue: organizationId ?? undefined,
order: 1,
// @ts-expect-error - name is not a valid prop for formFields
name: 'custom:organization_id',
},
And then in my services It would be nice to just have access to these custom properties somehow, i.e.:
async handleSignIn(input: SignInInput) {
const { username, password, customFields} = input
const organizationId = params?.organizationId
const hashedUsername = getHashedUsername(username, organizationId)
return signIn({
username: hashedUsername,
password,
options: {
...input.options,
userAttributes: {
email: username,
},
},
})
},
+1 for this feature 🙏
+1 for this feature request, please
🥺 🙏🏾
Hey there @osama-rizk I've made an attempt at extending the source code on https://github.com/aws-amplify/amplify-ui/pull/6581
The monorepo is quite big and complex as it is so any guidance would be appreciated
+1 for this feature request 🙏
bump
bump
Hey @fmonper1, we looked into your PR. Thank you for contributing. Unfortunately, the changes made to the codebase are not sufficient to implement your feature request. We are investigating it internally and will update this issue, as soon as we have an update.
Any updates on this feature request?
Hey @fmonper1, We don't have any update yet, but we're looking at this issue actively.