Skip to content

Commit

Permalink
fix: compose passive sitekey (#165)
Browse files Browse the repository at this point in the history
* fix: infinite loading on hideDialog=true

* feat: update compose example to add hideDialog checkbox

* chore: bump to 4.0.2
  • Loading branch information
CAMOBAP authored Aug 21, 2024
1 parent e920635 commit dab230c
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

# 4.0.2

- Fix: passive site keys (hideDialog=true) broken for `compose-sdk`

# 4.0.1

- Feat: release of `compose-sdk`
Expand Down
4 changes: 2 additions & 2 deletions compose-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ android {
// See https://developer.android.com/studio/publish/versioning
// versionCode must be integer and be incremented by one for every new update
// android system uses this to prevent downgrades
versionCode 40
versionCode 41

// version number visible to the user
// should follow semantic versioning (See https://semver.org)
versionName "4.0.1"
versionName "4.0.2"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
Expand Down
41 changes: 38 additions & 3 deletions compose-sdk/src/main/java/com/hcaptcha/sdk/HCaptchaCompose.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,29 @@ import android.app.Activity
import android.os.Handler
import android.os.Looper
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties

@Composable
public fun HCaptchaCompose(config: HCaptchaConfig, onResult: (HCaptchaResponse) -> Unit) {
val handler = Handler(Looper.getMainLooper())
var helper: HCaptchaWebViewHelper? = null
val verifier = object : IHCaptchaVerifier {
override fun onLoaded() {
onResult(HCaptchaResponse.Event(HCaptchaEvent.Loaded))
if (config.hideDialog) {
helper?.let {
it.resetAndExecute()
} ?: run {
HCaptchaLog.w("HCaptchaWebViewHelper wasn't created, report but to developer")
onResult(HCaptchaResponse.Failure(HCaptchaError.INTERNAL_ERROR))
}
}
}

override fun onOpen() {
Expand All @@ -39,13 +50,16 @@ public fun HCaptchaCompose(config: HCaptchaConfig, onResult: (HCaptchaResponse)
}
}
val internalConfig = HCaptchaInternalConfig(com.hcaptcha.sdk.HCaptchaHtml())
HCaptchaLog.sDiagnosticsLogEnabled = config.diagnosticLog

HCaptchaLog.d("HCaptchaCompose($config)")

Dialog(onDismissRequest = {}, properties = DialogProperties(usePlatformDefaultWidth = false)) {
if (config.hideDialog) {
AndroidView(
modifier = Modifier.fillMaxSize(),
modifier = Modifier.size(0.dp),
factory = { context ->
HCaptchaWebView(context).apply {
HCaptchaWebViewHelper(
helper = HCaptchaWebViewHelper(
handler,
context,
config,
Expand All @@ -56,5 +70,26 @@ public fun HCaptchaCompose(config: HCaptchaConfig, onResult: (HCaptchaResponse)
}
}
)
} else {
Dialog(
onDismissRequest = {},
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
HCaptchaWebView(context).apply {
helper = HCaptchaWebViewHelper(
handler,
context,
config,
internalConfig,
verifier,
this
)
}
}
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.runtime.*
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
Expand All @@ -28,31 +29,49 @@ class ComposeActivity : ComponentActivity() {
setContent {
var hCaptchaStarted by remember { mutableStateOf(false) }
var hCaptchaLoaded by remember { mutableStateOf(false) }
var hideDialog by remember { mutableStateOf(false) }
var text by remember { mutableStateOf("") }

Column(
modifier = Modifier.fillMaxSize().padding(16.dp),
verticalArrangement = Arrangement.Bottom
) {
// Multiline Text
TextField(
value = text,
placeholder = { Text("Verification result will be here...") },
onValueChange = { newText -> text = newText },
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.background(Color.Gray)
)

Spacer(modifier = Modifier.weight(1f))

Row(
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked = hideDialog,
onCheckedChange = { isChecked ->
hideDialog = isChecked
}
)

Text(
text = "Hide Dialog (Passive Site Key)",
)
}

Button(
onClick = {
hCaptchaStarted = !hCaptchaStarted
},
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp)
.padding(vertical = 16.dp)
) {
Text(text = "Toggle WebView")
Text(text = "Verify with HCaptcha")
}

if (hCaptchaStarted && !hCaptchaLoaded) {
Expand All @@ -68,11 +87,12 @@ class ComposeActivity : ComponentActivity() {
}
}

// WebView Dialog
if (hCaptchaStarted) {
HCaptchaCompose(HCaptchaConfig
.builder()
.siteKey("10000000-ffff-ffff-ffff-000000000001")
.hideDialog(hideDialog)
.diagnosticLog(true)
.build()) { result ->
when (result) {
is HCaptchaResponse.Success -> {
Expand All @@ -89,7 +109,7 @@ class ComposeActivity : ComponentActivity() {
}
is HCaptchaResponse.Event -> {
if (result.event == HCaptchaEvent.Opened) {
hCaptchaLoaded = true;
hCaptchaLoaded = true
}
println("Event: ${result.event}")
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ android {
// See https://developer.android.com/studio/publish/versioning
// versionCode must be integer and be incremented by one for every new update
// android system uses this to prevent downgrades
versionCode 40
versionCode 41

// version number visible to the user
// should follow semantic versioning (See https://semver.org)
versionName "4.0.1"
versionName "4.0.2"

buildConfigField 'String', 'VERSION_NAME', "\"${defaultConfig.versionName}_${defaultConfig.versionCode}\""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.hcaptcha.sdk.HCaptchaCompose
import com.hcaptcha.sdk.HCaptchaConfig
import com.hcaptcha.sdk.HCaptchaError
import com.hcaptcha.sdk.HCaptchaResponse
import com.hcaptcha.sdk.HCaptchaSize
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.junit.Rule
Expand All @@ -25,22 +26,29 @@ import java.util.concurrent.TimeUnit

@RunWith(AndroidJUnit4::class)
class HCaptchaComposeTest {
companion object {
const val SITE_KEY = "10000000-ffff-ffff-ffff-000000000001"
const val TEST_TOKEN = "10000000-aaaa-bbbb-cccc-000000000001"
}

private val resultContentDescription = "HCaptchaResultString"
private val timeout = TimeUnit.SECONDS.toMillis(4)

@get:Rule
val composeTestRule = createComposeRule()

fun setContent(token: String = "10000000-ffff-ffff-ffff-000000000001") {
fun setContent(siteKey: String = SITE_KEY, passiveSiteKey: Boolean = false) {
composeTestRule.setContent {
var text by remember { mutableStateOf("<init>") }
Column {
Text(text = text, modifier = Modifier.semantics { contentDescription = resultContentDescription })

HCaptchaCompose(HCaptchaConfig
.builder()
.siteKey(token)
.siteKey(siteKey)
.diagnosticLog(true)
.size(HCaptchaSize.INVISIBLE)
.hideDialog(passiveSiteKey)
.build()) { result ->
when (result) {
is HCaptchaResponse.Success -> {
Expand All @@ -63,7 +71,7 @@ class HCaptchaComposeTest {
runBlocking { delay(timeout) }

composeTestRule.onNodeWithContentDescription(resultContentDescription)
.assertTextEquals("10000000-aaaa-bbbb-cccc-000000000001")
.assertTextEquals(TEST_TOKEN)
}

@Test
Expand All @@ -75,4 +83,14 @@ class HCaptchaComposeTest {
composeTestRule.onNodeWithContentDescription(resultContentDescription)
.assertTextContains(HCaptchaError.ERROR.name)
}

@Test
fun passiveSiteKey() {
setContent(SITE_KEY, true)

runBlocking { delay(timeout) }

composeTestRule.onNodeWithContentDescription(resultContentDescription)
.assertTextEquals(TEST_TOKEN)
}
}

0 comments on commit dab230c

Please sign in to comment.