-
-
Notifications
You must be signed in to change notification settings - Fork 745
HCaptcha support. #5953
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
base: main
Are you sure you want to change the base?
HCaptcha support. #5953
Changes from 35 commits
8c2306e
20ac312
b3d33da
ad71a6d
37272e6
fd9208a
8ac738f
8f5c267
3089247
9301381
dc648de
c30ec25
c4f594a
2a1e4f8
e39ff4e
a7fe9c2
7331a7b
c68eba4
4db3bec
89a30c4
07f19e5
aa290b7
8c0c82d
75a26ea
805c5cb
5af9a02
002e291
a750a75
18dceba
2b3e3e6
1c8398e
acc88bf
c2db2de
4be5f44
9170c6e
c66ebd2
0c598a0
f30ee88
3b58a65
ad418e1
ed47c52
2dea1fb
12231d0
ad4e4d8
041ae18
b48ae83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| package org.wikipedia.captcha | ||
|
|
||
| import androidx.core.net.toUri | ||
| import androidx.fragment.app.FragmentActivity | ||
| import com.hcaptcha.sdk.HCaptcha | ||
| import com.hcaptcha.sdk.HCaptchaConfig | ||
| import com.hcaptcha.sdk.HCaptchaDialogFragment | ||
| import com.hcaptcha.sdk.HCaptchaTheme | ||
| import com.hcaptcha.sdk.HCaptchaTokenResponse | ||
| import org.wikipedia.WikipediaApp | ||
| import org.wikipedia.settings.RemoteConfig | ||
| import org.wikipedia.util.log.L | ||
| import kotlin.String | ||
|
|
||
| class HCaptchaHelper( | ||
| private val activity: FragmentActivity, | ||
| private val callback: Callback | ||
| ) { | ||
| interface Callback { | ||
| fun onSuccess(token: String) | ||
| fun onError(e: Exception) | ||
| } | ||
|
|
||
| private var hCaptcha: HCaptcha? = null | ||
| private var tokenResponse: HCaptchaTokenResponse? = null | ||
|
|
||
| private val configDefault get() = RemoteConfig.RemoteConfigHCaptcha( | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: even though these parameters are served by our remote configuration, we still want to hardcode some defaults here, in case the network call to fetch remote configuration fails. |
||
| baseURL = "https://meta.wikimedia.org", | ||
| jsSrc = "https://assets-hcaptcha.wikimedia.org/1/api.js", | ||
| endpoint = "https://hcaptcha.wikimedia.org", | ||
| assetHost = "https://assets-hcaptcha.wikimedia.org", | ||
| imgHost = "https://imgs-hcaptcha.wikimedia.org", | ||
| reportApi = "https://report-hcaptcha.wikimedia.org", | ||
| sentry = false, | ||
| siteKey = "e11698d6-51ca-4980-875c-72309c6678cc" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm curious, looking into this with the other team...
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be fixed now on the backend. |
||
| ) | ||
|
|
||
| private val dialogCancelableRunnable = MakeHCaptchaDialogCancelable() | ||
|
|
||
| fun show() { | ||
| if (hCaptcha == null) { | ||
| val config = RemoteConfig.config.androidv1?.hCaptcha ?: configDefault | ||
| hCaptcha = HCaptcha.getClient(activity) | ||
| hCaptcha?.setup( | ||
| HCaptchaConfig.builder() | ||
| .theme(if (WikipediaApp.instance.currentTheme.isDark) HCaptchaTheme.DARK else HCaptchaTheme.LIGHT) | ||
| .siteKey(config.siteKey) | ||
| .host(config.baseURL.toUri().host) | ||
| .jsSrc(config.jsSrc) | ||
| .endpoint(config.endpoint) | ||
| .assethost(config.assetHost) | ||
| .imghost(config.imgHost) | ||
| .reportapi(config.reportApi) | ||
| .sentry(config.sentry) | ||
| .loading(false) | ||
| .build() | ||
| ) | ||
|
|
||
| hCaptcha?.addOnSuccessListener { response -> | ||
| tokenResponse = response | ||
| callback.onSuccess(response.tokenResult) | ||
| }?.addOnFailureListener { e -> | ||
| tokenResponse = null | ||
| L.e("hCaptcha failed: ${e.message} (${e.statusCode})") | ||
| callback.onError(e) | ||
| }?.addOnOpenListener { | ||
| L.d("hCaptcha opened") | ||
| } | ||
| } | ||
| hCaptcha?.verifyWithHCaptcha() | ||
|
|
||
| // This works around an issue in the hCaptcha library where the "loading" dialog, even when | ||
| // it's not visible, still allows itself to be "canceled" by touching anywhere outside its | ||
| // bounds. We work around this by explicitly finding its DialogFragment and setting it to | ||
| // be non-cancelable, and then setting it back to cancelable after a short delay, so that | ||
| // the user doesn't accidentally tap the screen while hCaptcha is loading. | ||
| activity.window.decorView.post(MakeHCaptchaDialogCancelable(false)) | ||
| activity.window.decorView.postDelayed(dialogCancelableRunnable, 10000) | ||
| } | ||
|
|
||
| fun cleanup() { | ||
| if (!activity.isDestroyed) { | ||
| activity.window.decorView.removeCallbacks(dialogCancelableRunnable) | ||
| } | ||
| hCaptcha?.removeAllListeners() | ||
| hCaptcha?.reset() | ||
| hCaptcha = null | ||
| } | ||
|
|
||
| inner class MakeHCaptchaDialogCancelable(val cancelable: Boolean = true) : Runnable { | ||
| override fun run() { | ||
| if (!activity.isDestroyed) { | ||
| activity.supportFragmentManager.fragments.forEach { | ||
| if (it is HCaptchaDialogFragment) { | ||
| it.isCancelable = cancelable | ||
| } | ||
| } | ||
dbrant marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| } | ||
| } | ||

Uh oh!
There was an error while loading. Please reload this page.