aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.41k stars 2.11k forks source link

How to handle when user cancels the pop up for federated Sign In #9948

Open MuhammadAbdullah54321 opened 2 years ago

MuhammadAbdullah54321 commented 2 years ago

I am developing app in React Native

When a user clicks on the button to sign in with google, a pop up appears but I don't see an option to handle the situation if user clicks on cancel on the top of pop up(in iOS). It do not trigger any event in the Hub listener

Provide code snippets (if applicable) WhatsApp Image 2021-11-06 at 7 25 12 PM

here is how I am using Hub.listen()

useEffect(() => {
    Hub.listen('auth', ({ payload: { event, data } }) => {
      switch (event) {
        case 'signIn':
          getUser().then(userData => ProcessUserData(userData));
        case 'cognitoHostedUI':
          console.log("Hosted UI")
          break;
        case 'signOut':
          console.log("Signed Out Successfully");
          break;
        case 'signIn_failure':
          console.log("Cancelled")
        case 'cognitoHostedUI_failure':
          console.log('Hostedn UI failure', data);
          break;
      }
    });

  }, []);

non of the case is triggered when user presses Cancel in the UI as marked in image attached

aajinkya1203 commented 2 years ago

Did you get any solution for this?

sregg commented 2 years ago

Has anyone found a solution?

therealtgd commented 1 year ago

Are there any solutions available?

tannerabread commented 1 year ago

Hi thread, can I get some clarity on this feature request.

What would you expect from our library in this situation? I'm not sure if the pop-up window itself is part of the auth flow, only the page that it navigates to and the response that is returned.

Currently, doesn't the library just return to the app if you close/cancel this window? What would you rather have happen?

Excuse my ignorance I'm just trying to figure out use cases for this feature request so that we can better address it.

therealtgd commented 1 year ago

My situation is this. I am using react-native and this library along with react-native-inappbrowser-reborn to handle auth. I have a very similar Hub listener as @MuhammadAbdullah54321, handling sign-in and sign-in failure. But there is no sign-in canceled event to listen to, so I can navigate back to a component or maybe stop a spinner component when the user cancels the sign-in. I show a spinner component when the user starts the auth process and hide it when it is finished, but I have no way of stopping it if the auth gets canceled by the user. It would be nice if a sign-in-canceled event was triggered, so I can implement said features.

tannerabread commented 1 year ago

Understood, thank you for the clarity, I'll bring this information to the rest of the team so it can be discussed and will update this thread with any new information.

SaadbinWaheed commented 10 months ago

Any update on this?

derekdavenport commented 10 months ago

There is a signIn_failure event, but it is dispatched before my page component is called. I can see it if I put the Hub listener outside the component function.

SaadbinWaheed commented 10 months ago

@tannerabread, any update on this?

@derekdavenport I don't get any such event on react native, amplify version 5+.

derekdavenport commented 10 months ago

I don't know about react native, but in react I'm doing this for now:

let passed = false
Hub.listen('auth', ({ payload }) => {
    if (payload.event == 'signIn_failure' && !passed) {
        passed = true
        setTimeout(() => Hub.dispatch('auth', payload), 1000)
    }
})

This goes at the top of my component file. Then inside the component I have the normal hub listener inside useEffect. There's probably a better solution especially since this will fail if it takes longer than a second for your component to render. But I tried putting the listener as far as I could up the component tree, and it could never capture the event in time. Don't judge me too harshly for this.

Perhaps amplify should queue events until at least one listener is attached? I haven't looked at the internals, but just a thought.

Joshmatjjen commented 8 months ago

@tannerabread ... This is bad, still no update on this.

dawidvdh commented 4 months ago

Also having major problems with this in our react-native app, especially with v6.

In v5 we were able to use react-native-inappbrowser-reborn and listen when a user pressed cancel and handle it, with the upgrade and having to use @aws-amplify/rtn-web-browser I have no way of listening to a cancel event, this is quite crucial for our use-case.

Is there currently any way to listen to a cancel in the browser pop using the required @aws-amplify/rtn-web-browser package?

Abdelalim-dev commented 4 months ago

@dawidvdh you mentioned that you could listen to 'cancel' event from the inappbrowser. Can you share how you did that, please?

Looking at the documentation of the inappbroswer-reborn, I can't see any event for cancellation or closing.

Abdelalim-dev commented 4 months ago

One way of detecting the inappbroswer-rebord cancel is by checking the resulting Promise returned by the open or openAuth functions.

You can check the type (success|cancel) to determine what to do.

I'm, currently, looking for a way to broadcast that event to the concerned screen/component.

asifkhan0410 commented 3 months ago

this worked for me:

async function urlOpener(url: string, redirectUrl: string): Promise<void> {
  await InAppBrowser.isAvailable();
  const authSessionResult = await InAppBrowser.openAuth(url, redirectUrl, {
    showTitle: false,
    enableUrlBarHiding: true,
    enableDefaultShare: false,
    ephemeralWebSession: false,
  });

  if (authSessionResult.type === 'success') {
    Linking.openURL(authSessionResult.url);
  } else if (authSessionResult.type === 'cancel') {
    Linking.openURL('kb://cancel');
  }
}

this has my scheme so on redirect the linking will trigger the url event listener

useEffect(() => {
    const listenerFn = (e: { url: string }) => {
      if (e?.url.includes('cancel')) {
        let message2 = 'Login cancelled';
        dispatch(setIsLoginInProgressEnd());
        if (isLoginInProgressType === 'Google') {
          setGoogleLoginError(message2);
        } else if (isLoginInProgressType === 'Apple') {
          setAppleLoginError(message2);
        }
      }
    };
    Linking.addEventListener('url', listenerFn);

    return () => Linking.removeAllListeners('url');
  }, [isLoginInProgressType]);