okta/okta-mobile-kotlin

Unable call login right after completing logout without delay

alexringberg opened this issue · 4 comments

Describe the bug?

I am working on an application that attempts to call login after logging out. I get an exception of Flow Cancelled by the login call. We are moving to this SDK from the old OIDC library and previously this worked just fine. The only way I have been able to get this sequence to work is by putting in a delay(1500) at the start of the login call to make sure the logout is completed.

Stack Trace
Failed to login. com.okta.webauthenticationui.WebAuthenticationClient$FlowCancelledException: Flow cancelled. at com.okta.webauthenticationui.DefaultRedirectCoordinator.emit(RedirectCoordinator.kt:123) at com.okta.webauthenticationui.SingletonRedirectCoordinator.emit(Unknown Source:2) at com.okta.webauthenticationui.ForegroundViewModel.flowCancelled(ForegroundViewModel.kt:78) at com.okta.webauthenticationui.ForegroundActivity.onDestroy(ForegroundActivity.kt:88) at android.app.Activity.performDestroy(Activity.java:8316) at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1364) at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5374) at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5420) at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:47) at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

What is expected to happen?

I was expecting that I can log out of a user and once logout is complete and an OidcClientResult is returned that I can then go into the login sequence.

What is the actual behavior?

If I call login right after or a couple of calls later in the call stack I get a Flow Cancelled exception.

Reproduction Steps?

I cloned the example project here and I entered my okta properties and then changed the onClickListener of logout to also call login to include logoutOfBrowserButton.setOnClickListener { viewModel.logoutOfBrowser(this) viewModel.login(this) }

in order to see this working as expected you can add a delay(1500) at the start of the coroutine launch here

Additional Information?

I believe the flowCancelled is being caused here

SDK Version and Artifact(s) used.

implementation(platform('com.okta.kotlin:bom:1.0.0'))
implementation('com.okta.kotlin:auth-foundation-bootstrap')
implementation('com.okta.kotlin:web-authentication-ui'

Build Information

No response

@alexringberg, the existing sample code isn't designed to call logoutOfBrowser and login functions one after another. They both launch a new job using viewmodelScope. That means there's no guarantee to the order of their execution. In your case, you want to convert login and logoutOfBrowser functions to suspend functions, and call them in the onClick listener using

lifecycleScope.launch {
    viewModel.logoutOfBrowser(context)
    viewModel.login(context)
}

However, I've tried this locally, and am still seeing the same issue as you. I am looking further into this and will report back my findings.

This issue is caused by a bug in our SDK. It is happening because two instances of ForegroundActivity are alive at the same time, and the instance belonging to logoutOfBrowser gets an onDestroy callback after the login call is made. Once ForegroundActivity for logoutOfBrowser is destroyed, onDestroy from the old instance of the activity accidentally cancels the login flow as a result. Working on a fix.

@alexringberg I believe I've fixed the issue in #238. Once that's merged and I have a release available, I will notify you.

@alexringberg, the fix is now available in release 1.1.2.