From aeb0e9bb55a921405bf0bc36700c52979d6da2c2 Mon Sep 17 00:00:00 2001 From: Gaurav Goel Date: Mon, 28 Oct 2024 08:37:24 +0530 Subject: [PATCH 1/3] feat: Replace custom chrome tabs with webview in login function Signed-off-by: Gaurav Goel --- app/src/main/res/layout/activity_main.xml | 2 + .../web3auth/core/CustomChromeTabsActivity.kt | 83 ++++++++++++------- .../main/java/com/web3auth/core/Web3Auth.kt | 46 +++++++++- .../java/com/web3auth/core/WebViewActivity.kt | 4 +- .../core/types/WebViewResultCallback.kt | 2 + core/src/main/res/layout/activity_cct.xml | 5 +- 6 files changed, 109 insertions(+), 33 deletions(-) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 7df9400..9048b05 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -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" diff --git a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt index 6493b6f..b79323d 100644 --- a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt +++ b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt @@ -1,54 +1,81 @@ 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 + 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) setContentView(R.layout.activity_cct) + webView = findViewById(R.id.webView) - 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 + 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() } } } \ No newline at end of file diff --git a/core/src/main/java/com/web3auth/core/Web3Auth.kt b/core/src/main/java/com/web3auth/core/Web3Auth.kt index 74b924f..3c32b42 100644 --- a/core/src/main/java/com/web3auth/core/Web3Auth.kt +++ b/core/src/main/java/com/web3auth/core/Web3Auth.kt @@ -47,6 +47,7 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu private lateinit var loginCompletableFuture: CompletableFuture private lateinit var enableMfaCompletableFuture: CompletableFuture private lateinit var signMsgCF: CompletableFuture + private var context = context private var web3AuthResponse: Web3AuthResponse? = null private var web3AuthOption = web3AuthOptions @@ -145,6 +146,7 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu //print("url: => $url") val intent = Intent(context, CustomChromeTabsActivity::class.java) intent.putExtra(WEBVIEW_URL, url.toString()) + intent.putExtra(REDIRECT_URL, web3AuthOption.redirectUrl.toString()) context.startActivity(intent) } } @@ -273,7 +275,7 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu loginParams.dappShare = share } } - + CustomChromeTabsActivity.webViewResultCallback = this //login processRequest("login", loginParams, context) @@ -681,5 +683,47 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu signMsgCF.complete(signResponse) } } + + override fun onSessionResponseReceived(sessionResponse: SessionResponse?) { + val sessionId = sessionResponse?.sessionId + if (sessionId?.isNotBlank() == true && sessionId.isNotEmpty()) { + sessionManager.saveSessionId(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.saveSessionId(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) + } + } } diff --git a/core/src/main/java/com/web3auth/core/WebViewActivity.kt b/core/src/main/java/com/web3auth/core/WebViewActivity.kt index c566149..1f6ea00 100644 --- a/core/src/main/java/com/web3auth/core/WebViewActivity.kt +++ b/core/src/main/java/com/web3auth/core/WebViewActivity.kt @@ -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 } diff --git a/core/src/main/java/com/web3auth/core/types/WebViewResultCallback.kt b/core/src/main/java/com/web3auth/core/types/WebViewResultCallback.kt index 978007c..78f3901 100644 --- a/core/src/main/java/com/web3auth/core/types/WebViewResultCallback.kt +++ b/core/src/main/java/com/web3auth/core/types/WebViewResultCallback.kt @@ -2,4 +2,6 @@ package com.web3auth.core.types interface WebViewResultCallback { fun onSignResponseReceived(signResponse: SignResponse?) + fun onSessionResponseReceived(sessionResponse: SessionResponse?) + } \ No newline at end of file diff --git a/core/src/main/res/layout/activity_cct.xml b/core/src/main/res/layout/activity_cct.xml index ed583c7..e75916c 100644 --- a/core/src/main/res/layout/activity_cct.xml +++ b/core/src/main/res/layout/activity_cct.xml @@ -4,6 +4,9 @@ android:layout_height="match_parent" tools:context=".WebViewActivity"> - + \ No newline at end of file From 707eba5afd5cd95d74c4435ffe7c68bd7059f17e Mon Sep 17 00:00:00 2001 From: Gaurav Goel Date: Fri, 22 Nov 2024 08:38:10 +0530 Subject: [PATCH 2/3] hide action bar in webview login Signed-off-by: Gaurav Goel --- core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt index b79323d..2aba94a 100644 --- a/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt +++ b/core/src/main/java/com/web3auth/core/CustomChromeTabsActivity.kt @@ -22,6 +22,7 @@ class CustomChromeTabsActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + supportActionBar?.hide() setContentView(R.layout.activity_cct) webView = findViewById(R.id.webView) From fdfb0a52fbffa06505a82fcba2ad21bfb230bd1b Mon Sep 17 00:00:00 2001 From: Gaurav Goel Date: Fri, 22 Nov 2024 12:04:34 +0530 Subject: [PATCH 3/3] resolved merge conflicts Signed-off-by: Gaurav Goel --- core/src/main/java/com/web3auth/core/Web3Auth.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/web3auth/core/Web3Auth.kt b/core/src/main/java/com/web3auth/core/Web3Auth.kt index 5a5c641..602cdde 100644 --- a/core/src/main/java/com/web3auth/core/Web3Auth.kt +++ b/core/src/main/java/com/web3auth/core/Web3Auth.kt @@ -50,6 +50,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, @@ -105,6 +106,7 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu private fun processRequest( actionType: String, params: LoginParams?, context: Context ) { + CustomChromeTabsActivity.webViewResultCallback = this val sdkUrl = Uri.parse(web3AuthOption.sdkUrl) val initOptions = JSONObject(gson.toJson(getInitOptions())) val initParams = JSONObject(gson.toJson(getInitParams(params))) @@ -695,7 +697,8 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu override fun onSessionResponseReceived(sessionResponse: SessionResponse?) { val sessionId = sessionResponse?.sessionId if (sessionId?.isNotBlank() == true && sessionId.isNotEmpty()) { - sessionManager.saveSessionId(sessionId) + SessionManager.saveSessionIdToStorage(sessionId) + sessionManager.setSessionId(sessionId) //Rehydrate Session this.authorizeSession(web3AuthOption.redirectUrl.toString(), this.context) @@ -710,7 +713,10 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions, context: Context) : WebViewResu throwLoginError(ErrorCode.SOMETHING_WENT_WRONG) throwEnableMFAError(ErrorCode.SOMETHING_WENT_WRONG) } else { - web3AuthResponse?.sessionId?.let { sessionManager.saveSessionId(it) } + web3AuthResponse?.sessionId?.let { + SessionManager.saveSessionIdToStorage(it) + sessionManager.setSessionId(it) + } if (web3AuthResponse?.userInfo?.dappShare?.isNotEmpty() == true) { KeyStoreManagerUtils.encryptData(