Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FR (Authenticator): Graceful handling of error message triggered by PreSignup lambda in both react-native and react app #4960

Open
2 tasks
ericowhadi opened this issue Jan 27, 2024 · 6 comments
Labels
Authenticator An issue or a feature-request for an Authenticator UI Component feature-request Request a new feature React Native An issue or a feature-request for React Native platform React An issue or a feature-request for React platform

Comments

@ericowhadi
Copy link

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

React, React Native

Which UI component is this feature-request for?

Authenticator

Please describe your feature-request in detail.

Currently, I have a PreSignup lambda trigger that is used to verify that an existing account in cognito with the same email address does not already exist from a user that has been signing using different federated signin method. THis is to avoid creation of multiple account for same user, one per signin method. So the in PreSignup is just throwing an error with a message like "An account with this email already exists. Please use "Sign In with ${JSON.parse(providerName[0].providerName}" or Please "Sign In" using your email and password" if we detect that the existing account is a native cognito account.

However, and error thrown from the PreSignup lambda is displayed to the user in a very ugly, programmer style way. And depending on the various use case (federated signin, user/password), react-native federated, vs user password), the display of this error message is different and ugly in almost all cases. I did not find a way to hook it and make the UI user friendly. Therefore this feature request. Ether handle the error in the Hosted UI cleanly, or/and pass it somehow so we can drive our own UI when receiving it

Please describe a solution you'd like.

Ether handle the error in the Hosted UI cleanly, or/and pass it somehow so we can drive our own UI when receiving it

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

  • 👋 I may be able to implement this feature request.
  • ⚠️ This feature might incur a breaking change.
@ericowhadi ericowhadi added the feature-request Request a new feature label Jan 27, 2024
@github-actions github-actions bot added the pending-triage Issue is pending triage label Jan 27, 2024
@esauerbo esauerbo added Authenticator An issue or a feature-request for an Authenticator UI Component being-investigated and removed pending-triage Issue is pending triage labels Jan 29, 2024
@esauerbo
Copy link
Contributor

esauerbo commented Jan 29, 2024

Hi @ericowhadi thanks for creating this issue. We are looking into this

@reesscot
Copy link
Contributor

reesscot commented Jan 29, 2024

@ericowhadi Where are you seeing these error messages, in the Hosted UI or in the Authenticator?

@ericowhadi
Copy link
Author

it depends on many things. on webapp, if I try using social identity on an existing email/password account, vs use email/password on existing social identity, one will display as error message in Hosted UI, while the other will be passed as redirect URL error message (that I was able to use to display graceful error message). On React Native, it displays in the Authenticator, and I found no way to intercept the error message to gracefully handle it.

@ericowhadi
Copy link
Author

By the way, if preSignUp Lambda is baked into the overall logic to intercept the flow, there must be a way to implement gracefully what I try to do. Am I missing something that is not well documented? Throwing an error in this lambda is what I found googling around, but may be there is something else that I should have done instead of having this lambda throw?

@calebpollman
Copy link
Member

@ericowhadi Can you provide a code snippet of how you are integrating the PreSignup Lambda with the Authenticator?

@ericowhadi
Copy link
Author

ericowhadi commented Jan 31, 2024

Sure, I am using the PreSignup lambda template generated by amplify when setting up auth with social signin. And in the custom.js file I have:

/**
 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
 */
const AWS = require('aws-sdk')
const cognito = new AWS.CognitoIdentityServiceProvider()
exports.handler = async (event, context) => {
  // insert code to be executed by your lambda trigger
  const userPoolId = event.userPoolId
  const email = event.request.userAttributes.email
  try{
      const params = {
        UserPoolId: userPoolId,
        Filter: `email = "${email}"`
      }
        const users = await cognito.listUsers(params).promise()
        if (users.Users && users.Users.length > 0){
          const user = users.Users[0]
          console.log("user",user)
          const providerName = user.Attributes.find(attr=> attr.Name === 'identities')?.Value
          let signInMethod
          if (providerName){
            signInMethod = ` Please use "Sign In With ${JSON.parse(providerName)[0].providerName}"`
          }else{
            signInMethod = ' Please "Sign In" using your email and password'
          }
          //existing user found with the same email
          const errorMessage = `. An account with this email already exists. ${signInMethod}`
          throw new Error(errorMessage)

        }

      return event;
  } catch(error){
    console.error(error)
    throw error
  } 
};

hope this helps.
BTW, on the webapp, I do have some client side code to deal with one of the behavior when the hosted ui is not displaying the error but instead passing it as URL param to the redirect:
something like:

  const [errorMessage, setErrorMessage] = useState(null)
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const errorDescription = params.get('error_description');
    if (errorDescription) {
      setErrorMessage(errorDescription.startsWith("PreSignUp failed with error . ")?errorDescription.substring(30):errorDescription);
    }
  }, []);

and the render method displaying errorMessage when it is not null. I don't have any client side changes on react native. Error messages display somewhat, ugly and developer style on react native experience.

@reesscot reesscot changed the title graceful handling of error message triggered by PreSignup lambda in both react-native and react app FR (Authenticator): Graceful handling of error message triggered by PreSignup lambda in both react-native and react app Feb 7, 2024
@reesscot reesscot added React Native An issue or a feature-request for React Native platform React An issue or a feature-request for React platform and removed being-investigated labels Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Authenticator An issue or a feature-request for an Authenticator UI Component feature-request Request a new feature React Native An issue or a feature-request for React Native platform React An issue or a feature-request for React platform
Projects
None yet
Development

No branches or pull requests

4 participants