Skip to content
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

Feat/login using webview #100

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
android:layout_margin="32dp"
android:minHeight="48dp"
android:visibility="gone"
android:focusable="true"
android:focusableInTouchMode="true"
android:backgroundTint="@color/black"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
Expand Down
84 changes: 56 additions & 28 deletions core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt
Original file line number Diff line number Diff line change
@@ -1,54 +1,82 @@
package com.web3auth.core

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent
import com.google.gson.GsonBuilder
import com.web3auth.core.types.REDIRECT_URL
import com.web3auth.core.types.SessionResponse
import com.web3auth.core.types.WEBVIEW_URL
import com.web3auth.core.types.WebViewResultCallback

class CustomChromeTabsActivity : AppCompatActivity() {

private lateinit var customTabLauncher: ActivityResultLauncher<Intent>
private lateinit var webView: WebView
private val gson = GsonBuilder().disableHtmlEscaping().create()

companion object {
var webViewResultCallback: WebViewResultCallback? = null
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportActionBar?.hide()
setContentView(R.layout.activity_cct)
webView = findViewById(R.id.webView)

Check warning

Code scanning / CodeQL

Android WebView settings allows access to content links Medium

Sensitive information may be exposed via a malicious link due to access to content:// links being allowed in this WebView.

Copilot Autofix AI about 1 month ago

To fix the problem, we need to explicitly disable access to content:// URLs in the WebView settings. This can be done by calling setAllowContentAccess(false) on the WebSettings object associated with the WebView. This change should be made in the onCreate method where other WebView settings are configured.

Suggested changeset 1
core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt
--- a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt
+++ b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt
@@ -70,2 +70,3 @@
         webSettings.setSupportMultipleWindows(true)
+        webSettings.setAllowContentAccess(false)
         webView.settings.userAgentString = null
EOF
@@ -70,2 +70,3 @@
webSettings.setSupportMultipleWindows(true)
webSettings.setAllowContentAccess(false)
webView.settings.userAgentString = null
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options

customTabLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_CANCELED) {
Web3Auth.setCustomTabsClosed(true)
finish()
}
}

// Handle loading URL from intent extras
val extras = intent.extras
if (extras != null) {
val webViewUrl = extras.getString(WEBVIEW_URL)
val redirectUrl = extras.getString(REDIRECT_URL)
if (webViewUrl != null) {
launchCustomTabs(webViewUrl)
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (redirectUrl?.isNotEmpty() == true) {
if (url?.contains(redirectUrl) == true) {
val uri = Uri.parse(url)
val hashUri = Uri.parse(uri.host + "?" + uri.fragment)
val b64Params = hashUri.getQueryParameter("b64Params")
val b64ParamString =
decodeBase64URLString(b64Params!!).toString(Charsets.UTF_8)
val sessionResponse =
gson.fromJson(b64ParamString, SessionResponse::class.java)
println("Session Response: $sessionResponse")
webViewResultCallback?.onSessionResponseReceived(sessionResponse)
//WebViewActivity.webViewResultCallback?.onSignResponseReceived(signResponse)
finish()
return true
}
}
return false
}

override fun onPageFinished(view: WebView?, url: String?) {

}
}
}

if (webViewUrl != null) {
webView.loadUrl(webViewUrl)
}
}

val webSettings = webView.settings
webSettings.javaScriptEnabled = true

Check warning

Code scanning / CodeQL

Android WebView JavaScript settings Medium

JavaScript execution enabled in WebView.

Copilot Autofix AI about 1 month ago

To fix the problem, we should disable JavaScript execution in the WebView by setting webSettings.javaScriptEnabled to false. If JavaScript is necessary for the application's functionality, we should ensure that the WebView only loads content from trusted sources using encrypted channels (HTTPS). In this case, we will disable JavaScript execution as a precaution.

Suggested changeset 1
core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt
--- a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt
+++ b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt
@@ -67,3 +67,3 @@
         val webSettings = webView.settings
-        webSettings.javaScriptEnabled = true
+        webSettings.javaScriptEnabled = false
         webSettings.domStorageEnabled = true
EOF
@@ -67,3 +67,3 @@
val webSettings = webView.settings
webSettings.javaScriptEnabled = true
webSettings.javaScriptEnabled = false
webSettings.domStorageEnabled = true
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
webSettings.domStorageEnabled = true
webSettings.setSupportMultipleWindows(true)
webView.settings.userAgentString = null

}

private fun launchCustomTabs(url: String) {
val defaultBrowser = this.getDefaultBrowser()
val customTabsBrowsers = this.getCustomTabsBrowsers()
if (customTabsBrowsers.contains(defaultBrowser)) {
val intent = CustomTabsIntent.Builder().build().intent
intent.data = Uri.parse(url)
intent.`package` = defaultBrowser
customTabLauncher.launch(intent)
} else if (customTabsBrowsers.isNotEmpty()) {
val intent = CustomTabsIntent.Builder().build().intent
intent.data = Uri.parse(url)
intent.`package` = customTabsBrowsers[0]
customTabLauncher.launch(intent)
override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
super.onBackPressed()
}
}
}
49 changes: 49 additions & 0 deletions core/src/main/java/com/web3auth/core/Web3Auth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu

private var web3AuthResponse: Web3AuthResponse? = null
private var web3AuthOption = web3AuthOptions
private var context = context
private var sessionManager: SessionManager = SessionManager(
context,
web3AuthOptions.sessionTime ?: 600,
Expand Down Expand Up @@ -107,6 +108,7 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu
private fun processRequest(
actionType: String, params: LoginParams?
) {
CustomChromeTabsActivity.webViewResultCallback = this
val sdkUrl = Uri.parse(web3AuthOption.sdkUrl)
val initOptions = JSONObject(gson.toJson(getInitOptions()))
val initParams = JSONObject(gson.toJson(getInitParams(params)))
Expand Down Expand Up @@ -147,6 +149,7 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu
//print("url: => $url")
val intent = Intent(baseContext, CustomChromeTabsActivity::class.java)
intent.putExtra(WEBVIEW_URL, url.toString())
intent.putExtra(REDIRECT_URL, web3AuthOption.redirectUrl.toString())
baseContext.startActivity(intent)
}
}
Expand Down Expand Up @@ -691,6 +694,52 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu
}
}

override fun onSessionResponseReceived(sessionResponse: SessionResponse?) {
val sessionId = sessionResponse?.sessionId
if (sessionId?.isNotBlank() == true && sessionId.isNotEmpty()) {
SessionManager.saveSessionIdToStorage(sessionId)
sessionManager.setSessionId(sessionId)

//Rehydrate Session
this.authorizeSession(web3AuthOption.redirectUrl.toString(), this.context)
.whenComplete { resp, error ->
runOnUIThread {
if (error == null) {
web3AuthResponse = resp
if (web3AuthResponse?.error?.isNotBlank() == true) {
throwLoginError(ErrorCode.SOMETHING_WENT_WRONG)
throwEnableMFAError(ErrorCode.SOMETHING_WENT_WRONG)
} else if (web3AuthResponse?.privKey.isNullOrBlank() && web3AuthResponse?.factorKey.isNullOrBlank()) {
throwLoginError(ErrorCode.SOMETHING_WENT_WRONG)
throwEnableMFAError(ErrorCode.SOMETHING_WENT_WRONG)
} else {
web3AuthResponse?.sessionId?.let {
SessionManager.saveSessionIdToStorage(it)
sessionManager.setSessionId(it)
}

if (web3AuthResponse?.userInfo?.dappShare?.isNotEmpty() == true) {
KeyStoreManagerUtils.encryptData(
web3AuthResponse?.userInfo?.verifier.plus(" | ")
.plus(web3AuthResponse?.userInfo?.verifierId),
web3AuthResponse?.userInfo?.dappShare!!,
)
}
loginCompletableFuture.complete(web3AuthResponse)
if (::enableMfaCompletableFuture.isInitialized)
enableMfaCompletableFuture.complete(true)
}
} else {
print(error)
}
}
}
} else {
throwLoginError(ErrorCode.SOMETHING_WENT_WRONG)
throwEnableMFAError(ErrorCode.SOMETHING_WENT_WRONG)
}
}

override fun onWebViewCancelled() {
signMsgCF.completeExceptionally(Exception("User cancelled the operation."))
}
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/java/com/web3auth/core/WebViewActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@ class WebViewActivity : AppCompatActivity() {
gson.fromJson(b64ParamString, SignResponse::class.java)
webViewResultCallback?.onSignResponseReceived(signResponse)
finish()
return true
}
}
if (webViewUrl != null) {
view?.loadUrl(webViewUrl)
}
return false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ package com.web3auth.core.types

interface WebViewResultCallback {
fun onSignResponseReceived(signResponse: SignResponse?)
fun onSessionResponseReceived(sessionResponse: SessionResponse?)
fun onWebViewCancelled()
}
5 changes: 4 additions & 1 deletion core/src/main/res/layout/activity_cct.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
android:layout_height="match_parent"
tools:context=".WebViewActivity">

<!-- You can add any views or layout elements here as needed -->
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</RelativeLayout>