Skip to content

Commit 324f1ff

Browse files
authored
React native changes (#193)
1 parent 3842499 commit 324f1ff

File tree

6 files changed

+30
-28
lines changed

6 files changed

+30
-28
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ written for Android. You can read more on the [Descope Website](https://descope.
99
Add the following to your `build.gradle` dependencies:
1010

1111
```groovy
12-
implementation 'com.descope:descope-kotlin:0.13.2'
12+
implementation 'com.descope:descope-kotlin:0.13.3'
1313
```
1414

1515
## Quickstart

descopesdk/src/main/java/com/descope/Descope.kt

+4
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,8 @@ object Descope {
117117

118118
// The underlying `DescopeSdk` object used by the `Descope` singleton.
119119
internal lateinit var sdk: DescopeSdk
120+
121+
// Used internally to check if the singleton object has an actual sdk value.
122+
internal val isInitialized
123+
get() = this::sdk.isInitialized
120124
}

descopesdk/src/main/java/com/descope/android/DescopeFlowCoordinator.kt

+19-18
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ class DescopeFlowCoordinator(val webView: WebView) {
5757
internal var listener: DescopeFlowView.Listener? = null
5858
internal var state: DescopeFlowView.State = Initial
5959

60-
private lateinit var flow: DescopeFlow
60+
private var flow: DescopeFlow? = null
6161
private val handler: Handler = Handler(Looper.getMainLooper())
62-
private val sdk: DescopeSdk
63-
get() = if (this::flow.isInitialized) flow.sdk ?: Descope.sdk else Descope.sdk
62+
private val sdk: DescopeSdk?
63+
get() = flow?.sdk ?: if (Descope.isInitialized) Descope.sdk else null
6464
private val logger: DescopeLogger?
65-
get() = sdk.client.config.logger
65+
get() = sdk?.client?.config?.logger
6666
private var currentFlowUrl: Uri? = null
6767
private var alreadySetUp = false
6868

@@ -95,9 +95,8 @@ class DescopeFlowCoordinator(val webView: WebView) {
9595
val jwtServerResponse = JwtServerResponse.fromJson(success, emptyList())
9696
// take tokens from cookies if missing
9797
val cookieString = CookieManager.getInstance().getCookie(url)
98-
val projectId = sdk.client.config.projectId
99-
jwtServerResponse.sessionJwt = jwtServerResponse.sessionJwt ?: findJwtInCookies(cookieString, projectId = projectId, name = SESSION_COOKIE_NAME)
100-
jwtServerResponse.refreshJwt = jwtServerResponse.refreshJwt ?: findJwtInCookies(cookieString, projectId = projectId, name = REFRESH_COOKIE_NAME)
98+
jwtServerResponse.sessionJwt = jwtServerResponse.sessionJwt ?: findJwtInCookies(cookieString, name = SESSION_COOKIE_NAME)
99+
jwtServerResponse.refreshJwt = jwtServerResponse.refreshJwt ?: findJwtInCookies(cookieString, name = REFRESH_COOKIE_NAME)
101100
handler.post {
102101
try {
103102
val authResponse = jwtServerResponse.convert()
@@ -153,13 +152,13 @@ class DescopeFlowCoordinator(val webView: WebView) {
153152

154153
is NativePayload.OAuthWeb -> {
155154
logger?.log(Info, "Launching custom tab for web-based oauth")
156-
launchCustomTab(webView.context, nativePayload.startUrl, flow.presentation?.createCustomTabsIntent(webView.context))
155+
launchCustomTab(webView.context, nativePayload.startUrl, flow?.presentation?.createCustomTabsIntent(webView.context))
157156
return@launch
158157
}
159158

160159
is NativePayload.Sso -> {
161160
logger?.log(Info, "Launching custom tab for sso")
162-
launchCustomTab(webView.context, nativePayload.startUrl, flow.presentation?.createCustomTabsIntent(webView.context))
161+
launchCustomTab(webView.context, nativePayload.startUrl, flow?.presentation?.createCustomTabsIntent(webView.context))
163162
return@launch
164163
}
165164

@@ -231,7 +230,7 @@ class DescopeFlowCoordinator(val webView: WebView) {
231230
DoNothing -> true
232231
OpenBrowser -> {
233232
try {
234-
launchCustomTab(webView.context, uri, flow.presentation?.createCustomTabsIntent(webView.context))
233+
launchCustomTab(webView.context, uri, flow?.presentation?.createCustomTabsIntent(webView.context))
235234
} catch (e: DescopeException) {
236235
logger?.log(Error, "Failed to open URL in browser", e)
237236
}
@@ -259,10 +258,10 @@ class DescopeFlowCoordinator(val webView: WebView) {
259258
evaluateJavascript(
260259
setupScript(
261260
origin = origin,
262-
oauthNativeProvider = flow.oauthNativeProvider?.name ?: "",
263-
oauthRedirect = pickRedirectUrl(flow.oauthRedirect, flow.oauthRedirectCustomScheme, useCustomSchemeFallback),
264-
ssoRedirect = pickRedirectUrl(flow.ssoRedirect, flow.ssoRedirectCustomScheme, useCustomSchemeFallback),
265-
magicLinkRedirect = flow.magicLinkRedirect ?: "",
261+
oauthNativeProvider = flow?.oauthNativeProvider?.name ?: "",
262+
oauthRedirect = pickRedirectUrl(flow?.oauthRedirect, flow?.oauthRedirectCustomScheme, useCustomSchemeFallback),
263+
ssoRedirect = pickRedirectUrl(flow?.ssoRedirect, flow?.ssoRedirectCustomScheme, useCustomSchemeFallback),
264+
magicLinkRedirect = flow?.magicLinkRedirect ?: "",
266265
isWebAuthnSupported = isWebAuthnSupported,
267266
)
268267
) {}
@@ -332,7 +331,10 @@ document.head.appendChild(element)
332331
}
333332

334333
internal fun resumeFromDeepLink(deepLink: Uri) {
335-
if (!this::flow.isInitialized) throw DescopeException.flowFailed.with(desc = "`resumeFromDeepLink` cannot be called before `startFlow`")
334+
if (flow == null) {
335+
logger?.log(Error, "resumeFromDeepLink cannot be called before startFlow")
336+
return
337+
}
336338
activityHelper.closeCustomTab(webView.context)
337339
val response = JSONObject().apply { put("url", deepLink.toString()) }
338340
val type = if (deepLink.queryParameterNames.contains("t")) "magicLink" else "oauthWeb"
@@ -344,7 +346,7 @@ document.head.appendChild(element)
344346
private fun executeHooks(event: Event) {
345347
val hooks = mutableListOf<DescopeFlowHook>().apply {
346348
addAll(DescopeFlowHook.defaults)
347-
if (this@DescopeFlowCoordinator::flow.isInitialized) addAll(flow.hooks)
349+
addAll(flow?.hooks ?: emptyList())
348350
}
349351
hooks.filter { it.events.contains(event) }
350352
.forEach { it.execute(event, this) }
@@ -499,7 +501,7 @@ private fun String.escapeForBackticks() = replace("\\", "\\\\")
499501

500502
// Cookies
501503

502-
internal fun findJwtInCookies(cookieString: String?, projectId: String, name: String): String? {
504+
internal fun findJwtInCookies(cookieString: String?, name: String): String? {
503505
// split and aggregate all cookies
504506
val cookies = mutableListOf<HttpCookie>().apply {
505507
cookieString?.split("; ")?.forEach {
@@ -518,7 +520,6 @@ internal fun findJwtInCookies(cookieString: String?, projectId: String, name: St
518520
null
519521
}
520522
}
521-
.filter { it.projectId == projectId } // enforce projectId
522523
.maxByOrNull { it.issuedAt }?.jwt // take latest
523524
}
524525

descopesdk/src/main/java/com/descope/android/DescopeFlowView.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class DescopeFlow {
148148
* Some of the default configurations might be OK to start out with,
149149
* but it is likely that modifications will be required before release.
150150
*
151-
* - **IMPORTANT NOTE**: even the Application links are the recommended way to configure
151+
* - **IMPORTANT NOTE**: even though Application links are the recommended way to configure
152152
* deep links, some browsers, such as Opera, do not honor them and open the URLs inline.
153153
* It is possible to circumvent this issue by using a custom scheme, albeit less secure.
154154
*

descopesdk/src/main/java/com/descope/sdk/Sdk.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,6 @@ class DescopeSdk(context: Context, projectId: String, configure: DescopeConfig.(
7373
const val NAME = "DescopeAndroid"
7474

7575
/** The Descope SDK version */
76-
const val VERSION = "0.13.2"
76+
const val VERSION = "0.13.3"
7777
}
7878
}

descopesdk/src/test/java/com/descope/session/TokenTest.kt

+4-7
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class TokenTest {
4545
cookies.add(HttpCookie("name$i", "value$i"))
4646
}
4747
cookies.add(HttpCookie(REFRESH_COOKIE_NAME, jwtForP123))
48-
val refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), projectId = "P123", name = REFRESH_COOKIE_NAME)
48+
val refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), name = REFRESH_COOKIE_NAME)
4949
assertEquals(jwtForP123, refreshJwt)
5050
}
5151

@@ -58,10 +58,7 @@ class TokenTest {
5858
}
5959
cookies.add(HttpCookie(REFRESH_COOKIE_NAME, jwtForP123))
6060

61-
var refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), projectId = "P123", name = REFRESH_COOKIE_NAME)
62-
assertEquals(jwtForP123, refreshJwt)
63-
64-
refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), projectId = "P456", name = REFRESH_COOKIE_NAME)
61+
val refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), name = REFRESH_COOKIE_NAME)
6562
assertEquals(jwtForP456, refreshJwt)
6663
}
6764

@@ -74,7 +71,7 @@ class TokenTest {
7471
}
7572
cookies.add(HttpCookie(SESSION_COOKIE_NAME, jwtForP123))
7673

77-
var refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), projectId = "P123", name = SESSION_COOKIE_NAME)
74+
var refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), name = SESSION_COOKIE_NAME)
7875
assertEquals(laterJwtForP123, refreshJwt)
7976

8077
// try again with a different order
@@ -85,7 +82,7 @@ class TokenTest {
8582
}
8683
cookies.add(HttpCookie(SESSION_COOKIE_NAME, laterJwtForP123))
8784

88-
refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), projectId = "P123", name = SESSION_COOKIE_NAME)
85+
refreshJwt = findJwtInCookies(cookies.joinToString(separator = "; "), name = SESSION_COOKIE_NAME)
8986
assertEquals(laterJwtForP123, refreshJwt)
9087
}
9188

0 commit comments

Comments
 (0)