From 7b2b1c737f8260bf8d1f171e371a0e263365617b Mon Sep 17 00:00:00 2001 From: itaihanski Date: Wed, 27 Nov 2024 10:33:49 +0200 Subject: [PATCH] Add protection against ready race-condition --- README.md | 2 +- .../descope/android/DescopeFlowCoordinator.kt | 36 +++++++++++-------- .../src/main/java/com/descope/sdk/Sdk.kt | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index b33b8fc2..760dc15a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ written for Android. You can read more on the [Descope Website](https://descope. Add the following to your `build.gradle` dependencies: ```groovy -implementation 'com.descope:descope-kotlin:0.12.1' +implementation 'com.descope:descope-kotlin:0.12.2' ``` ## Quickstart diff --git a/descopesdk/src/main/java/com/descope/android/DescopeFlowCoordinator.kt b/descopesdk/src/main/java/com/descope/android/DescopeFlowCoordinator.kt index 567acb38..b5777e4b 100644 --- a/descopesdk/src/main/java/com/descope/android/DescopeFlowCoordinator.kt +++ b/descopesdk/src/main/java/com/descope/android/DescopeFlowCoordinator.kt @@ -62,13 +62,13 @@ internal class DescopeFlowCoordinator(private val webView: WebView) { webView.settings.setSupportZoom(false) webView.addJavascriptInterface(object { @JavascriptInterface - fun onReady() { + fun onReady(tag: String) { if (state != State.Started) { logger?.log(Info, "Flow onReady called in state $state - ignoring") return } state = State.Ready - logger?.log(Info, "Flow is ready") + logger?.log(Info, "Flow is ready ($tag)") handler.post { listener?.onReady() } @@ -276,7 +276,7 @@ private fun setupScript( magicLinkRedirect: String, isWebAuthnSupported: Boolean ) = """ -function waitWebComponent() { +function flowBridgeWaitWebComponent() { const styles = ` * { user-select: none; @@ -292,12 +292,21 @@ function waitWebComponent() { wc = document.getElementsByTagName('descope-wc')[0] if (wc) { clearInterval(id) - prepareWebComponent(wc) + flowBridgePrepareWebComponent(wc) } }, 20) } -function prepareWebComponent(wc) { +function flowBridgeIsReady(wc, tag) { + if (!wc.bridgeVersion) { + flow.onError('Hosted flow uses unsupported web-component SDK version'); + return + } + wc.sdk.webauthn.helpers.isSupported = async () => $isWebAuthnSupported + flow.onReady(tag); +} + +function flowBridgePrepareWebComponent(wc) { wc.nativeOptions = { bridgeVersion: 1, platform: 'android', @@ -308,14 +317,13 @@ function prepareWebComponent(wc) { origin: '$origin', } - wc.addEventListener('ready', () => { - if (!wc.bridgeVersion) { - flow.onError('Hosted flow uses unsupported web-component SDK version'); - return - } - wc.sdk.webauthn.helpers.isSupported = async () => $isWebAuthnSupported - flow.onReady(); - }) + if (document.querySelector('descope-wc')?.shadowRoot?.querySelector('descope-container')) { + flowBridgeIsReady(wc, 'immediate') + } else { + wc.addEventListener('ready', () => { + flowBridgeIsReady(wc, 'event') + }) + } wc.addEventListener('success', (e) => { flow.onSuccess(JSON.stringify(e.detail), window.location.href); @@ -330,7 +338,7 @@ function prepareWebComponent(wc) { }) } -waitWebComponent(); +flowBridgeWaitWebComponent(); """.trimIndent() private fun String.escapeForBackticks() = replace("\\", "\\\\") diff --git a/descopesdk/src/main/java/com/descope/sdk/Sdk.kt b/descopesdk/src/main/java/com/descope/sdk/Sdk.kt index 73119f03..d9f0e870 100644 --- a/descopesdk/src/main/java/com/descope/sdk/Sdk.kt +++ b/descopesdk/src/main/java/com/descope/sdk/Sdk.kt @@ -71,6 +71,6 @@ class DescopeSdk(context: Context, projectId: String, configure: DescopeConfig.( const val name = "DescopeAndroid" /** The Descope SDK version */ - const val version = "0.12.1" + const val version = "0.12.2" } }