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

While auth in progress, going to background closes the browser. #153

Open
nilesh1883 opened this issue Apr 16, 2020 · 25 comments
Open

While auth in progress, going to background closes the browser. #153

nilesh1883 opened this issue Apr 16, 2020 · 25 comments
Labels
help wanted Extra attention is needed

Comments

@nilesh1883
Copy link

Platform: Both iOS and Android
Device: Device and emulator both.

Steps to reproduce:

  1. Open browser using openAuth call.
  2. Auth should be two factor.
  3. Provide the first factor credentials.
  4. Go to application which will have to second factor code. (In other words take the application to background).
  5. Come back to application.
  6. Browser is dismissed.
  7. In iOS we don't get any response or error, but in Android we get response as {type: 'dismiss'} but this is not the proper response.

Thanks

@nilesh1883 nilesh1883 changed the title While auth in progress and and going to background closes the browser. While auth in progress, going to background closes the browser. Apr 16, 2020
@jdnichollsc
Copy link
Member

Please attach any reproducible demo

@nilesh1883
Copy link
Author

Please attach any reproducible demo

Thanks for replying @jdnichollsc, I really appreciate the work you have done in this library. I will try and attach the demo.

I did some more digging and it looks like on Android the issue only comes when "android:launchMode="singleTask"" and while reopening the application you click on the application rather than using app switcher.

For iOS the issue not reproducible anymore.

@jdnichollsc jdnichollsc added the help wanted Extra attention is needed label Apr 20, 2020
@Luke-Rogerson
Copy link

Luke-Rogerson commented Oct 11, 2020

@jdnichollsc I'm also having this issue on Android.

Here is working example I made. Simply clone and yarn.

To reproduce:

  1. Click the "PRESS ME" button
  2. Press the home button to return to the home screen.
  3. Open the app again by pressing the icon from home screen or app drawer.
  4. The in app browser will have closed, with {type: "dismiss"} being returned.

{type: "dismiss"} is resolved from the open promise that is called within _openAuthSessionPolyfillAsync. This is in turn originating from the close Java method.

I'm trying to help with a fix, but I need to understand exactly what the correct behaviour of this type: dismiss. Clearly, it should not be retuned at this point, but then when should the result of open or openAuth be type: dismiss? Would you mind explaining what is the expected behaviour?

Many thanks for all your hard work with this library!

@jdnichollsc
Copy link
Member

@Luke-Rogerson
Copy link

forceCloseOnRedirection seemed to not do anything.
I'm still trying to get my head around exactly what causing this, and further debugging tonight revealed it's certainly a native side issue, with dismiss being returned to the open method.

I'm not sure if we need this CustomTabsSession for this? It looks to be we can just handle this in your existing Android code?

@oailloud
Copy link

I had the exact same problem and I've finally found a combination of settings that works for me. Try to set:

InAppBrowser.open(url, {
    ...
    forceCloseOnRedirection: false,
    showInRecents: true,
    ...
}

Strangely enough, it doesn't show a new task in the "recents" but it leaves the in-app browser on top of the original application and allows switching through other apps.

Concretely, it creates the intent (the one that launches the chrome custom tab) without any flag, neither FLAG_ACTIVITY_NEW_TASK nor FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS/FLAG_ACTIVITY_NO_HISTORY. I'm a noob when it comes to the Android platform but here's my understanding:

  • WhenforceCloseOnRedirection: true is set (FLAG_ACTIVITY_NEW_TASK enabled), Android launches the chrome custom tab (the browser) in a new task that appears in the recents, whatever the value of showInRecents. But that task is closed from the moment when you exit it (either switching via the recents screen or going back to the home). Maybe there's a magic flag that would prevent that behavior?
  • On the other way, if forceCloseOnRedirection: false is set with showInRecents: false, the browser does stay in the original application tab but when switching back to it, onResume is called on the ChromeTabsManagerActivity and it closes the browser because it doesn't know how to differentiate between coming back from explicitly closing the browser or coming back from another app as onResume is legitimately called in both cases. That may be more of a bug in the lib but I have no idea what it would take to figure out the case which it's in.

Hope that helps!

@Kiran0791
Copy link

I had the exact same problem and I've finally found a combination of settings that works for me. Try to set:

InAppBrowser.open(url, {
    ...
    forceCloseOnRedirection: false,
    showInRecents: true,
    ...
}

Strangely enough, it doesn't show a new task in the "recents" but it leaves the in-app browser on top of the original application and allows switching through other apps.

Concretely, it creates the intent (the one that launches the chrome custom tab) without any flag, neither FLAG_ACTIVITY_NEW_TASK nor FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS/FLAG_ACTIVITY_NO_HISTORY. I'm a noob when it comes to the Android platform but here's my understanding:

  • WhenforceCloseOnRedirection: true is set (FLAG_ACTIVITY_NEW_TASK enabled), Android launches the chrome custom tab (the browser) in a new task that appears in the recents, whatever the value of showInRecents. But that task is closed from the moment when you exit it (either switching via the recents screen or going back to the home). Maybe there's a magic flag that would prevent that behavior?
  • On the other way, if forceCloseOnRedirection: false is set with showInRecents: false, the browser does stay in the original application tab but when switching back to it, onResume is called on the ChromeTabsManagerActivity and it closes the browser because it doesn't know how to differentiate between coming back from explicitly closing the browser or coming back from another app as onResume is legitimately called in both cases. That may be more of a bug in the lib but I have no idea what it would take to figure out the case which it's in.

Hope that helps!

Above fix works when switching between the app. But when the app is opened by clicking on app icon the inapp browser gets closed.

Any Solution for this

@jdnichollsc
Copy link
Member

Hello folks, do you have examples of another apps supporting this workflow?

@Kiran0791
Copy link

Hello folks, do you have examples of another apps supporting this workflow?

@jdnichollsc am not sure if Instagram is on react-native. But when you open any ad link which comes on feed screen it gets open in a similar kind of in-app browser. And when you put app in background and click on the app icon you can still see the link opened.

@jdnichollsc
Copy link
Member

@Kiran0791 any example using auth flow? :)

@niljaisw
Copy link

I had the exact same problem and I've finally found a combination of settings that works for me. Try to set:

InAppBrowser.open(url, {
    ...
    forceCloseOnRedirection: false,
    showInRecents: true,
    ...
}

Strangely enough, it doesn't show a new task in the "recents" but it leaves the in-app browser on top of the original application and allows switching through other apps.
Concretely, it creates the intent (the one that launches the chrome custom tab) without any flag, neither FLAG_ACTIVITY_NEW_TASK nor FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS/FLAG_ACTIVITY_NO_HISTORY. I'm a noob when it comes to the Android platform but here's my understanding:

  • WhenforceCloseOnRedirection: true is set (FLAG_ACTIVITY_NEW_TASK enabled), Android launches the chrome custom tab (the browser) in a new task that appears in the recents, whatever the value of showInRecents. But that task is closed from the moment when you exit it (either switching via the recents screen or going back to the home). Maybe there's a magic flag that would prevent that behavior?
  • On the other way, if forceCloseOnRedirection: false is set with showInRecents: false, the browser does stay in the original application tab but when switching back to it, onResume is called on the ChromeTabsManagerActivity and it closes the browser because it doesn't know how to differentiate between coming back from explicitly closing the browser or coming back from another app as onResume is legitimately called in both cases. That may be more of a bug in the lib but I have no idea what it would take to figure out the case which it's in.

Hope that helps!

Above fix works when switching between the app. But when the app is opened by clicking on app icon the inapp browser gets closed.

Any Solution for this

I can confirm this is happening.

@asami95
Copy link

asami95 commented Jan 12, 2022

@jdnichollsc
Thank you so much for your efforts here!

I have an issue that may be related to this issue, I am trying to build a simple application to demonstrate the use of the library.

It works really fine with iOS but I face strange behavior in Android here's a gif:

_gif

And I have this response in the console:

{message: 'chrome tabs activity closed', type: 'cancel'}

And here is my simple code which is executed when I press on "Authorize":

const url = `${URLS.authorizationEndpoint}?state=hello&client_id=${SECRETS.clientId}&redirect_uri=${URLS.redirectUrl}&response_type=token`;
  try {
    InAppBrowser.openAuth(url, URLS.redirectUrl, {
      forceCloseOnRedirectionL: false,
      showInRecents: true,
    })
      .then(async response => {
        if (response.type === 'success' && response.url) {
          const parsed = qs.parse(response.url);
          await AsyncStorage.setItem('@SSO_CRDS', JSON.stringify(parsed))
            .then(() => {
              onSuccess && onSuccess();
            })
            .catch(e => alert(e));
        }
      })
      .catch(err => console.log(err));
  } catch (error) {
    console.log(error);
  }

@GautierT
Copy link

GautierT commented Mar 8, 2022

I had the exact same problem and I've finally found a combination of settings that works for me. Try to set:

InAppBrowser.open(url, {
    ...
    forceCloseOnRedirection: false,
    showInRecents: true,
    ...
}

Strangely enough, it doesn't show a new task in the "recents" but it leaves the in-app browser on top of the original application and allows switching through other apps.
Concretely, it creates the intent (the one that launches the chrome custom tab) without any flag, neither FLAG_ACTIVITY_NEW_TASK nor FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS/FLAG_ACTIVITY_NO_HISTORY. I'm a noob when it comes to the Android platform but here's my understanding:

  • WhenforceCloseOnRedirection: true is set (FLAG_ACTIVITY_NEW_TASK enabled), Android launches the chrome custom tab (the browser) in a new task that appears in the recents, whatever the value of showInRecents. But that task is closed from the moment when you exit it (either switching via the recents screen or going back to the home). Maybe there's a magic flag that would prevent that behavior?
  • On the other way, if forceCloseOnRedirection: false is set with showInRecents: false, the browser does stay in the original application tab but when switching back to it, onResume is called on the ChromeTabsManagerActivity and it closes the browser because it doesn't know how to differentiate between coming back from explicitly closing the browser or coming back from another app as onResume is legitimately called in both cases. That may be more of a bug in the lib but I have no idea what it would take to figure out the case which it's in.

Hope that helps!

Above fix works when switching between the app. But when the app is opened by clicking on app icon the inapp browser gets closed.

Any Solution for this

Same issue, when I switch between app using the recent screen the in-app browser is kept open but if I go back to the homescreen then click on the app icon, the in-app browser is dismissed...

const result = await InAppBrowser.open(url, {
    forceCloseOnRedirection: false,
    showInRecents: false
})

Btw, thanks for this awesome lib !

@jdnichollsc
Copy link
Member

@jdnichollsc Thank you so much for your efforts here!

I have an issue that may be related to this issue, I am trying to build a simple application to demonstrate the use of the library.

It works really fine with iOS but I face strange behavior in Android here's a gif:

_gif

And I have this response in the console:

{message: 'chrome tabs activity closed', type: 'cancel'}

And here is my simple code which is executed when I press on "Authorize":

const url = `${URLS.authorizationEndpoint}?state=hello&client_id=${SECRETS.clientId}&redirect_uri=${URLS.redirectUrl}&response_type=token`;
  try {
    InAppBrowser.openAuth(url, URLS.redirectUrl, {
      forceCloseOnRedirectionL: false,
      showInRecents: true,
    })
      .then(async response => {
        if (response.type === 'success' && response.url) {
          const parsed = qs.parse(response.url);
          await AsyncStorage.setItem('@SSO_CRDS', JSON.stringify(parsed))
            .then(() => {
              onSuccess && onSuccess();
            })
            .catch(e => alert(e));
        }
      })
      .catch(err => console.log(err));
  } catch (error) {
    console.log(error);
  }

Hey mate, please create another issue and attach a reproducible demo to be able to debug your error 👍

@rogierslag
Copy link

I encountered the same problem, and solved it using #213 (comment)

It boils down that pressing the app icon in the launcher relaunches the activity which closes the browser when relaunched. Preventing a relauch from happening ensures the browser stays in place

@rubina-shakhkyan
Copy link

I had the exact same problem and I've finally found a combination of settings that works for me. Try to set:

InAppBrowser.open(url, {
    ...
    forceCloseOnRedirection: false,
    showInRecents: true,
    ...
}

Strangely enough, it doesn't show a new task in the "recents" but it leaves the in-app browser on top of the original application and allows switching through other apps.

Concretely, it creates the intent (the one that launches the chrome custom tab) without any flag, neither FLAG_ACTIVITY_NEW_TASK nor FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS/FLAG_ACTIVITY_NO_HISTORY. I'm a noob when it comes to the Android platform but here's my understanding:

  • WhenforceCloseOnRedirection: true is set (FLAG_ACTIVITY_NEW_TASK enabled), Android launches the chrome custom tab (the browser) in a new task that appears in the recents, whatever the value of showInRecents. But that task is closed from the moment when you exit it (either switching via the recents screen or going back to the home). Maybe there's a magic flag that would prevent that behavior?
  • On the other way, if forceCloseOnRedirection: false is set with showInRecents: false, the browser does stay in the original application tab but when switching back to it, onResume is called on the ChromeTabsManagerActivity and it closes the browser because it doesn't know how to differentiate between coming back from explicitly closing the browser or coming back from another app as onResume is legitimately called in both cases. That may be more of a bug in the lib but I have no idea what it would take to figure out the case which it's in.

Hope that helps!

Did you manage to solve the problem for iOS?

@oailloud
Copy link

If I remember correctly, I didn't have any problem with iOS, it was already working for me...

@thuongtv-vn
Copy link
Contributor

thuongtv-vn commented Jul 12, 2022

I have such issue on Android. I see that while the authenticate is processing. If the authorize URI is matched with your deeplinks declared on your android manifest. Then it will get back to your app and interrupt the authentication process before redirectUrl is called.

Do you guys have any idea?

@jdnichollsc
Copy link
Member

Hey folks, can you help me to review the new Release 3.7.0 please? #375

@sonuwise
Copy link

While auth process, once the authentication is done it try to go back the app but the application gets closed without throwing error. In ios its working find but on android I'm facing problem. Kindly help me out to resolve this asap.

@nitesh-habilelabs
Copy link

nitesh-habilelabs commented Sep 21, 2023

anyone got any fixes or workaround for that?
i am using keycloak for authentication in my react native application and as soon as i enter my credentials and otp, in-app browser gets closed with message {"message": "chrome tabs activity destroyed", "type": "dismiss"}

it is working totally fine in IOS. issue is only in android.
any help would be appreciated.
Here is my code to handle Login which is working fine for ios but not for android.

`

export async function login() {
  InAppBrowser.close();
  const challenge = pkceChallenge();
  const stateValue = generateRandomState();
  const Loginurl = `${ENDPOINT_URL}/auth?client_id=${CLIENT_ID}&response_type=${response_type}&redirect_uri=${
    Platform.OS === 'ios' ? redirectUriIos : redirectUriAndroid
  }&scope=${scope}&nonce&state=${stateValue}&code_challenge=${
    challenge.codeChallenge
  }&code_challenge_method=S256`;
  const localCodeVerifier = challenge.codeVerifier;

  try {
    if (await InAppBrowser.isAvailable()) {
      const result: any = await InAppBrowser.openAuth(
        Loginurl,
        Platform.OS === 'ios' ? redirectUriIos : redirectUriAndroid,
        {
          forceCloseOnRedirection: false,
          showInRecents: true,
          // iOS Properties
          ephemeralWebSession: false,
          // Android Properties
          showTitle: false,

          enableUrlBarHiding: true,
          enableDefaultShare: false,
        },
      );

      if (result.type === 'success') {
        const match_auth_token = result.url.match('code=([^&"]+)');
        if (match_auth_token && match_auth_token[1]) {
          const authToken = match_auth_token[1];

          const resFromFetchToken = await getAccessTokenFromAuthCode(
            authToken,
            localCodeVerifier,
          );
          return resFromFetchToken;
        } else {
          console.error('Access token not found');
          return null;
        }
      }
      // when the users presses the cancel/close button
      if (result.type === 'cancel') {
        onCancel();
        return null;
      }
    } else {
      Linking.openURL(Loginurl);
    }
  } catch (error) {
    console.debug(' error: ', error);
    return null;
  }
}

@TamasSzigeti
Copy link

@nitesh-habilelabs Been a while since I had worked with this but looking at my code it seems this same android issue I solved by passing a deep link url as a redirect one (second param of openAuth()). iOS doesn't care what you pass in there, but for Android it is myapp:/// – and I use the same as the second redirect from the html page which I pass in as redirectUrl for the third party OAuth provider. Hope it's clear, let me know.

@nitesh-habilelabs
Copy link

@nitesh-habilelabs Been a while since I had worked with this but looking at my code it seems this same android issue I solved by passing a deep link url as a redirect one (second param of openAuth()). iOS doesn't care what you pass in there, but for Android it is myapp:/// – and I use the same as the second redirect from the html page which I pass in as redirectUrl for the third party OAuth provider. Hope it's clear, let me know.

Hi @TamasSzigeti , Thank you for your help. It is fixed now. issue was with my intent filter. i had to pass host in that.
<data android:scheme="app" android:host="main" />

@krini
Copy link

krini commented Jan 5, 2024

I had to set showInRecents to true.

@imraunak007
Copy link

imraunak007 commented Dec 30, 2024

@oailloud @jdnichollsc it is not working for ios. can you please help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests