From 1731d045ec04fe48591e9059e72b2cb24798848a Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 13:23:18 +0200 Subject: [PATCH 01/17] Added kotlinc --- .idea/kotlinc.xml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .idea/kotlinc.xml diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..0fc3113 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file From 2a60df4d5f42203478ceb0baff40dfad26d75e65 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 13:26:15 +0200 Subject: [PATCH 02/17] Updated misc --- .idea/misc.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 783daea..cbe0346 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -21,7 +21,7 @@ - + From 5ba8627b53d2bb89eaa6cf6dc83daa252278c2a4 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 13:26:27 +0200 Subject: [PATCH 03/17] Version bump --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 8c1cc7e..d7072fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official GROUP=com.fintecsystems -VERSION_NAME=5.1.4 +VERSION_NAME=5.2.0 POM_URL=https://github.com/FinTecSystems/xs2a-android POM_SCM_URL=git@github.com:FinTecSystems/xs2a-android.git POM_SCM_CONNECTION=scm:git:git@github.com:FinTecSystems/xs2a-android.git From c943873810bd5f9bfa92437838ea5c94d9d2dc5a Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 13:35:41 +0200 Subject: [PATCH 04/17] Added redirectURL parameter --- .../main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt | 2 ++ .../xs2awizard/components/XS2AWizardBundleKeys.kt | 1 + .../xs2awizard/components/XS2AWizardViewModel.kt | 9 +++++++++ .../xs2awizard/wrappers/XS2AWizardFragment.kt | 7 +++++-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt index 1d7d244..45fcbab 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt @@ -66,6 +66,7 @@ fun XS2AWizard( enableBackButton: Boolean = true, enableAutomaticRetry: Boolean = true, callbackListener: XS2AWizardCallbackListener? = null, + redirectUrl: String? = null, xs2aWizardViewModel: XS2AWizardViewModel = viewModel() ) { val form by xs2aWizardViewModel.form.observeAsState(null) @@ -86,6 +87,7 @@ fun XS2AWizard( enableScroll, enableBackButton, enableAutomaticRetry, + redirectUrl, context as Activity ) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt index 8c43055..ec532cf 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt @@ -11,6 +11,7 @@ object XS2AWizardBundleKeys { const val enableScroll = "enableScroll" const val enableBackButton = "enableBackButton" const val enableAutomaticRetry = "enableAutomaticRetry" + const val redirectURL = "redirectURL" const val currentWebViewUrl = "currentWebViewUrl" } \ No newline at end of file diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index 03f7069..22e3e48 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -64,6 +64,12 @@ class XS2AWizardViewModel( */ private var enableAutomaticRetry: Boolean = true + /** + * Used for App2App redirection. + * URL of Host-App to return to. + */ + private var redirectURL: String? = null + internal val form = MutableLiveData?>() internal val loadingIndicatorLock = MutableLiveData(false) @@ -120,12 +126,14 @@ class XS2AWizardViewModel( enableScroll: Boolean, enableBackButton: Boolean, enableAutomaticRetry: Boolean, + redirectURL: String?, activity: Activity ) { this.language = language this.enableScroll = enableScroll this.enableBackButton = enableBackButton this.enableAutomaticRetry = enableAutomaticRetry + this.redirectURL = redirectURL currentActivity = WeakReference(activity) NetworkingInstance.getInstance(context).apply { @@ -148,6 +156,7 @@ class XS2AWizardViewModel( enableScroll = true enableBackButton = true enableAutomaticRetry = true + redirectURL = null currentActivity = WeakReference(null) connectionState.value = ConnectionState.UNKNOWN context.unregisterNetworkCallback(networkCallback) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt index 2b367cd..e61f341 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt @@ -31,7 +31,8 @@ class XS2AWizardFragment() : Fragment(), XS2AWizardCallbackListener { language: XS2AWizardLanguage? = null, enableScroll: Boolean = true, enableBackButton: Boolean = true, - enableAutomaticRetry: Boolean = true + enableAutomaticRetry: Boolean = true, + redirectURL: String? = null ) : this() { arguments = Bundle().apply { putString(XS2AWizardBundleKeys.sessionKey, sessionKey) @@ -43,6 +44,7 @@ class XS2AWizardFragment() : Fragment(), XS2AWizardCallbackListener { putBoolean(XS2AWizardBundleKeys.enableScroll, enableScroll) putBoolean(XS2AWizardBundleKeys.enableBackButton, enableBackButton) putBoolean(XS2AWizardBundleKeys.enableAutomaticRetry, enableAutomaticRetry) + putString(XS2AWizardBundleKeys.redirectURL, redirectURL) if (fontResId != null) { putInt(XS2AWizardBundleKeys.fontResId, fontResId) @@ -89,7 +91,8 @@ class XS2AWizardFragment() : Fragment(), XS2AWizardCallbackListener { enableScroll = arguments.getBoolean(XS2AWizardBundleKeys.enableScroll), enableBackButton = arguments.getBoolean(XS2AWizardBundleKeys.enableBackButton), enableAutomaticRetry = arguments.getBoolean(XS2AWizardBundleKeys.enableAutomaticRetry), - callbackListener = this@XS2AWizardFragment + callbackListener = this@XS2AWizardFragment, + redirectUrl = arguments.getString(XS2AWizardBundleKeys.redirectURL) ) } } From 0c8df6370e8cba8199c9a15a8ee160468dea5cfa Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 13:42:04 +0200 Subject: [PATCH 05/17] Now puts redirectURL into init call --- .../xs2awizard/components/XS2AWizardViewModel.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index 22e3e48..c39918e 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -172,6 +172,10 @@ class XS2AWizardViewModel( buildJsonObject { put("version", JsonPrimitive(BuildConfig.VERSION)) put("client", JsonPrimitive(context.getString(R.string.xs2a_client_tag))) + + if (redirectURL != null) { + put("location", JsonPrimitive(redirectURL)) + } }, true ) From 825f21f6ec434c553c7f673e6489e2829f14dd34 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 14:06:39 +0200 Subject: [PATCH 06/17] Added first iteration of App2App redirection logic --- .idea/compiler.xml | 2 +- .../components/XS2AWizardViewModel.kt | 43 ++++++++++++++++++- .../form/components/RedirectLine.kt | 2 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb7f4a8..b589d56 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index c39918e..da66acd 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -3,6 +3,7 @@ package com.fintecsystems.xs2awizard.components import android.app.Activity import android.app.Application import android.content.Context +import android.content.Intent import android.net.ConnectivityManager import android.net.Network import android.net.Uri @@ -13,6 +14,7 @@ import androidx.biometric.BiometricManager import androidx.biometric.BiometricPrompt import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.ui.text.AnnotatedString +import androidx.core.net.toUri import androidx.fragment.app.FragmentActivity import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData @@ -357,6 +359,7 @@ class XS2AWizardViewModel( submitForm(constructJsonBody("autosubmit", jsonBody)) } + else -> CustomTabsIntent.Builder().build().launchUrl( activity, Uri.parse(annotation.item) ) @@ -590,7 +593,7 @@ class XS2AWizardViewModel( * * @param url url to open. */ - internal fun openWebView(url: String) { + private fun openWebView(url: String) { currentWebViewUrl.value = url } @@ -601,6 +604,31 @@ class XS2AWizardViewModel( currentWebViewUrl.value = null } + /** + * Opens the provided [url] in an external Browser. + * + * @param url The URl to open. + */ + private fun openExternalUrl(url: String) { + val webIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + + currentActivity.get()!!.startActivity(webIntent) + } + + /** + * Open supplied [url] in either an external Browser or internal Webview, + * depending if the current provider supports it. + * + * @param url the URL to open. + */ + internal fun openRedirectURL(url: String) { + if (supportsAppRedirection(url)) { + openExternalUrl(url) + } else { + openWebView(url) + } + } + /** * Checks if the current form is the bank search. */ @@ -613,12 +641,25 @@ class XS2AWizardViewModel( @Suppress("unused") fun isLogin() = currentState == "login" + /** + * Checks if provided [url] is known to support App2App redirection. + * + * @param url URL to check + * @return true if URL supports App2App redirection + */ + private fun supportsAppRedirection(url: String) = + supportedAppRedirectionProviders.contains(url.toUri().host) + companion object { private const val rememberLoginName = "store_credentials" private const val sharedPreferencesFileName = "xs2a_credentials" private const val storedProvidersKey = "providers" private const val masterKeyAlias = "xs2a_credentials_master_key" + private val supportedAppRedirectionProviders = listOf( + "api.xs2a.com" + ) + /** * Delete all saved credentials. * diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/form/components/RedirectLine.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/form/components/RedirectLine.kt index c0caaed..4f0c155 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/form/components/RedirectLine.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/form/components/RedirectLine.kt @@ -26,7 +26,7 @@ fun RedirectLine(formData: RedirectLineData, viewModel: XS2AWizardViewModel) { verticalArrangement = Arrangement.spacedBy(5.dp) ) { FormButton(label = formData.label!!, buttonStyle = XS2ATheme.CURRENT.redirectButtonStyle) { - viewModel.openWebView(formData.url!!) + viewModel.openRedirectURL(formData.url!!) } FormButton( From 6bcec038f7efffeed29a77f55a3cec27c3d1b625 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 14:19:35 +0200 Subject: [PATCH 07/17] Updated supported urls list --- .../fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index da66acd..9b8a8d5 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -657,7 +657,8 @@ class XS2AWizardViewModel( private const val masterKeyAlias = "xs2a_credentials_master_key" private val supportedAppRedirectionProviders = listOf( - "api.xs2a.com" + "manage.xs2a.com", + "myaccount.ing.com" ) /** From ab2143bfe83ab99025191be7823b1d9f2382853d Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 14:25:51 +0200 Subject: [PATCH 08/17] URLWebView now checks if current URL is redirect url --- .../xs2awizard/components/XS2AWizardViewModel.kt | 8 ++++++++ .../xs2awizard/components/webview/URLBarWebView.kt | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index 9b8a8d5..fb07b95 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -650,6 +650,14 @@ class XS2AWizardViewModel( private fun supportsAppRedirection(url: String) = supportedAppRedirectionProviders.contains(url.toUri().host) + /** + * Checks if provided [url] is the [redirectURL]. + * + * @param url URL to check + * @return true if it's the [redirectURL] + */ + internal fun isRedirectURL(url: String) = url == redirectURL + companion object { private const val rememberLoginName = "store_credentials" private const val sharedPreferencesFileName = "xs2a_credentials" diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt index 9b32199..31199cf 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt @@ -161,6 +161,13 @@ fun URLBarWebView(viewModel: XS2AWizardViewModel) { webViewClient = object : WebViewClient() { @Deprecated("Deprecated in Java") override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { + if (viewModel.isRedirectURL(url)) { + viewModel.closeWebView() + viewModel.submitForm("post-code") + + return true + } + currentUrl = url view.loadUrl(url) return true From 327015c758e35a6042270999db354b0f4e6b454c Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 14:29:00 +0200 Subject: [PATCH 09/17] Renamed method --- .../xs2awizard/components/XS2AWizardViewModel.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index fb07b95..20e84c3 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -622,7 +622,7 @@ class XS2AWizardViewModel( * @param url the URL to open. */ internal fun openRedirectURL(url: String) { - if (supportsAppRedirection(url)) { + if (urlSupportsAppRedirection(url)) { openExternalUrl(url) } else { openWebView(url) @@ -647,8 +647,8 @@ class XS2AWizardViewModel( * @param url URL to check * @return true if URL supports App2App redirection */ - private fun supportsAppRedirection(url: String) = - supportedAppRedirectionProviders.contains(url.toUri().host) + private fun urlSupportsAppRedirection(url: String) = + supportedAppRedirectionURLs.contains(url.toUri().host) /** * Checks if provided [url] is the [redirectURL]. @@ -664,7 +664,7 @@ class XS2AWizardViewModel( private const val storedProvidersKey = "providers" private const val masterKeyAlias = "xs2a_credentials_master_key" - private val supportedAppRedirectionProviders = listOf( + private val supportedAppRedirectionURLs = listOf( "manage.xs2a.com", "myaccount.ing.com" ) From ff2d7cb2a722eab21d13f0e8e3cfab1e85203275 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 15:10:20 +0200 Subject: [PATCH 10/17] Added AlertDialog prompt & now refreshes state when navigating back to host app --- .idea/misc.xml | 2 +- .../components/XS2AWizardViewModel.kt | 39 ++++++++++++++++++- .../components/webview/URLBarWebView.kt | 9 +---- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index cbe0346..d9afb20 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -21,7 +21,7 @@ - + diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index 20e84c3..e7ec2e7 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -9,12 +9,15 @@ import android.net.Network import android.net.Uri import android.os.Build import android.os.Bundle +import androidx.activity.ComponentActivity import androidx.annotation.RequiresApi +import androidx.appcompat.app.AlertDialog import androidx.biometric.BiometricManager import androidx.biometric.BiometricPrompt import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.ui.text.AnnotatedString import androidx.core.net.toUri +import androidx.core.util.Consumer import androidx.fragment.app.FragmentActivity import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData @@ -106,6 +109,14 @@ class XS2AWizardViewModel( private var currentState: String? = null + private val onNewIntentListener = Consumer { + if (it.action != Intent.ACTION_VIEW || it.data == null) return@Consumer + + if (it.dataString == redirectURL) { + redirectionCallback(true) + } + } + init { val xs2aWizardBundle = savedStateHandle.get(XS2AWizardBundleKeys.bundleName) @@ -145,6 +156,8 @@ class XS2AWizardViewModel( context.registerNetworkCallback(networkCallback) + (activity as? ComponentActivity)?.addOnNewIntentListener(onNewIntentListener) + initForm() } @@ -159,6 +172,9 @@ class XS2AWizardViewModel( enableBackButton = true enableAutomaticRetry = true redirectURL = null + (currentActivity.get() as? ComponentActivity)?.removeOnNewIntentListener( + onNewIntentListener + ) currentActivity = WeakReference(null) connectionState.value = ConnectionState.UNKNOWN context.unregisterNetworkCallback(networkCallback) @@ -623,7 +639,16 @@ class XS2AWizardViewModel( */ internal fun openRedirectURL(url: String) { if (urlSupportsAppRedirection(url)) { - openExternalUrl(url) + AlertDialog.Builder(currentActivity.get()!!).apply { + setMessage("Open in WebView or external App?") + setPositiveButton("External App") { _, _ -> + openExternalUrl(url) + } + setNegativeButton("WebView") { _, _ -> + openWebView(url) + } + show() + } } else { openWebView(url) } @@ -658,6 +683,18 @@ class XS2AWizardViewModel( */ internal fun isRedirectURL(url: String) = url == redirectURL + /** + * Callback method for the redirection result. + * + * @param success True if redirection operation was successful. + */ + internal fun redirectionCallback(success: Boolean) { + closeWebView() + + if (success) + submitForm("post-code") + } + companion object { private const val rememberLoginName = "store_credentials" private const val sharedPreferencesFileName = "xs2a_credentials" diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt index 31199cf..564bd1e 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt @@ -54,10 +54,7 @@ fun URLBarWebView(viewModel: XS2AWizardViewModel) { val callbackHandler = object : XS2AJavascriptInterfaceCallback { override fun xS2AJavascriptInterfaceCallbackHandler(success: Boolean) { coroutineScope.launch { - viewModel.closeWebView() - - if (success) - viewModel.submitForm("post-code") + viewModel.redirectionCallback(success) } } } @@ -162,9 +159,7 @@ fun URLBarWebView(viewModel: XS2AWizardViewModel) { @Deprecated("Deprecated in Java") override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { if (viewModel.isRedirectURL(url)) { - viewModel.closeWebView() - viewModel.submitForm("post-code") - + viewModel.redirectionCallback(true) return true } From 252a3e55ea325764d49d91617f4cdee82ca51f44 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 15:17:35 +0200 Subject: [PATCH 11/17] Added localized strings for redirection dialog --- .../xs2awizard/components/XS2AWizardViewModel.kt | 7 ++++--- xs2awizard/src/main/res/values-de/strings.xml | 4 ++++ xs2awizard/src/main/res/values/strings.xml | 4 ++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index e7ec2e7..65c559b 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -640,11 +640,12 @@ class XS2AWizardViewModel( internal fun openRedirectURL(url: String) { if (urlSupportsAppRedirection(url)) { AlertDialog.Builder(currentActivity.get()!!).apply { - setMessage("Open in WebView or external App?") - setPositiveButton("External App") { _, _ -> + setTitle(R.string.redirect_dialog_title) + setMessage(R.string.redirect_dialog_message) + setPositiveButton(R.string.redirect_dialog_banking_app_button_title) { _, _ -> openExternalUrl(url) } - setNegativeButton("WebView") { _, _ -> + setNegativeButton(R.string.redirect_dialog_website_button_title) { _, _ -> openWebView(url) } show() diff --git a/xs2awizard/src/main/res/values-de/strings.xml b/xs2awizard/src/main/res/values-de/strings.xml index 3e1348c..17cf280 100644 --- a/xs2awizard/src/main/res/values-de/strings.xml +++ b/xs2awizard/src/main/res/values-de/strings.xml @@ -24,4 +24,8 @@ Abbrechen Keine Internetverbindung Serverfehler + Authentifizierungs-Methode wählen + Wie möchtest du dich einloggen? Hast du die App deiner Bank installiert, wähle \\\"Banking App\\\", andernfalls \\\"Webseite\\\". + Banking App + Webseite \ No newline at end of file diff --git a/xs2awizard/src/main/res/values/strings.xml b/xs2awizard/src/main/res/values/strings.xml index d271433..3f2c874 100644 --- a/xs2awizard/src/main/res/values/strings.xml +++ b/xs2awizard/src/main/res/values/strings.xml @@ -36,4 +36,8 @@ No Internet Connection Server Error + Select authentication method + How do you want to log in? If you have installed your bank\'s app, select \\\"Banking App\\\", otherwise select \\\"Website\\\". + Banking App + Website From 6bfc6378a7b7d0d9a79c4b12f5d4921d13e0a278 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 15:20:05 +0200 Subject: [PATCH 12/17] Removed escapes --- xs2awizard/src/main/res/values-de/strings.xml | 2 +- xs2awizard/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xs2awizard/src/main/res/values-de/strings.xml b/xs2awizard/src/main/res/values-de/strings.xml index 17cf280..b570809 100644 --- a/xs2awizard/src/main/res/values-de/strings.xml +++ b/xs2awizard/src/main/res/values-de/strings.xml @@ -25,7 +25,7 @@ Keine Internetverbindung Serverfehler Authentifizierungs-Methode wählen - Wie möchtest du dich einloggen? Hast du die App deiner Bank installiert, wähle \\\"Banking App\\\", andernfalls \\\"Webseite\\\". + Wie möchtest du dich einloggen? Hast du die App deiner Bank installiert, wähle \"Banking App\", andernfalls \"Webseite\". Banking App Webseite \ No newline at end of file diff --git a/xs2awizard/src/main/res/values/strings.xml b/xs2awizard/src/main/res/values/strings.xml index 3f2c874..bbe28d0 100644 --- a/xs2awizard/src/main/res/values/strings.xml +++ b/xs2awizard/src/main/res/values/strings.xml @@ -37,7 +37,7 @@ No Internet Connection Server Error Select authentication method - How do you want to log in? If you have installed your bank\'s app, select \\\"Banking App\\\", otherwise select \\\"Website\\\". + How do you want to log in? If you have installed your bank\'s app, select \"Banking App\", otherwise select \"Website\". Banking App Website From 9c860098befa11ebdd4601d9a4091ea3466d3261 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 15:40:36 +0200 Subject: [PATCH 13/17] Renamed redirectURL to redirectDeepLink --- .../fintecsystems/xs2awizard/XS2AWizard.kt | 4 ++-- .../components/XS2AWizardBundleKeys.kt | 2 +- .../components/XS2AWizardViewModel.kt | 20 +++++++++---------- .../components/webview/URLBarWebView.kt | 2 +- .../xs2awizard/wrappers/XS2AWizardFragment.kt | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt index 45fcbab..bd05503 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt @@ -66,7 +66,7 @@ fun XS2AWizard( enableBackButton: Boolean = true, enableAutomaticRetry: Boolean = true, callbackListener: XS2AWizardCallbackListener? = null, - redirectUrl: String? = null, + redirectDeepLink: String? = null, xs2aWizardViewModel: XS2AWizardViewModel = viewModel() ) { val form by xs2aWizardViewModel.form.observeAsState(null) @@ -87,7 +87,7 @@ fun XS2AWizard( enableScroll, enableBackButton, enableAutomaticRetry, - redirectUrl, + redirectDeepLink, context as Activity ) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt index ec532cf..78737fd 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardBundleKeys.kt @@ -11,7 +11,7 @@ object XS2AWizardBundleKeys { const val enableScroll = "enableScroll" const val enableBackButton = "enableBackButton" const val enableAutomaticRetry = "enableAutomaticRetry" - const val redirectURL = "redirectURL" + const val redirectDeepLink = "redirectDeepLink" const val currentWebViewUrl = "currentWebViewUrl" } \ No newline at end of file diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt index 65c559b..c9148c2 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/XS2AWizardViewModel.kt @@ -73,7 +73,7 @@ class XS2AWizardViewModel( * Used for App2App redirection. * URL of Host-App to return to. */ - private var redirectURL: String? = null + private var redirectDeepLink: String? = null internal val form = MutableLiveData?>() @@ -112,7 +112,7 @@ class XS2AWizardViewModel( private val onNewIntentListener = Consumer { if (it.action != Intent.ACTION_VIEW || it.data == null) return@Consumer - if (it.dataString == redirectURL) { + if (isRedirectDeepLink(it.dataString)) { redirectionCallback(true) } } @@ -139,14 +139,14 @@ class XS2AWizardViewModel( enableScroll: Boolean, enableBackButton: Boolean, enableAutomaticRetry: Boolean, - redirectURL: String?, + redirectDeepLink: String?, activity: Activity ) { this.language = language this.enableScroll = enableScroll this.enableBackButton = enableBackButton this.enableAutomaticRetry = enableAutomaticRetry - this.redirectURL = redirectURL + this.redirectDeepLink = redirectDeepLink currentActivity = WeakReference(activity) NetworkingInstance.getInstance(context).apply { @@ -171,7 +171,7 @@ class XS2AWizardViewModel( enableScroll = true enableBackButton = true enableAutomaticRetry = true - redirectURL = null + redirectDeepLink = null (currentActivity.get() as? ComponentActivity)?.removeOnNewIntentListener( onNewIntentListener ) @@ -191,8 +191,8 @@ class XS2AWizardViewModel( put("version", JsonPrimitive(BuildConfig.VERSION)) put("client", JsonPrimitive(context.getString(R.string.xs2a_client_tag))) - if (redirectURL != null) { - put("location", JsonPrimitive(redirectURL)) + if (redirectDeepLink != null) { + put("location", JsonPrimitive(redirectDeepLink)) } }, true @@ -677,12 +677,12 @@ class XS2AWizardViewModel( supportedAppRedirectionURLs.contains(url.toUri().host) /** - * Checks if provided [url] is the [redirectURL]. + * Checks if provided [url] is the [redirectDeepLink]. * * @param url URL to check - * @return true if it's the [redirectURL] + * @return true if it's the [redirectDeepLink] */ - internal fun isRedirectURL(url: String) = url == redirectURL + internal fun isRedirectDeepLink(url: String?) = url == redirectDeepLink /** * Callback method for the redirection result. diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt index 564bd1e..0b9c3ec 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/components/webview/URLBarWebView.kt @@ -158,7 +158,7 @@ fun URLBarWebView(viewModel: XS2AWizardViewModel) { webViewClient = object : WebViewClient() { @Deprecated("Deprecated in Java") override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { - if (viewModel.isRedirectURL(url)) { + if (viewModel.isRedirectDeepLink(url)) { viewModel.redirectionCallback(true) return true } diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt index e61f341..c74e037 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt @@ -32,7 +32,7 @@ class XS2AWizardFragment() : Fragment(), XS2AWizardCallbackListener { enableScroll: Boolean = true, enableBackButton: Boolean = true, enableAutomaticRetry: Boolean = true, - redirectURL: String? = null + redirectDeepLink: String? = null ) : this() { arguments = Bundle().apply { putString(XS2AWizardBundleKeys.sessionKey, sessionKey) @@ -44,7 +44,7 @@ class XS2AWizardFragment() : Fragment(), XS2AWizardCallbackListener { putBoolean(XS2AWizardBundleKeys.enableScroll, enableScroll) putBoolean(XS2AWizardBundleKeys.enableBackButton, enableBackButton) putBoolean(XS2AWizardBundleKeys.enableAutomaticRetry, enableAutomaticRetry) - putString(XS2AWizardBundleKeys.redirectURL, redirectURL) + putString(XS2AWizardBundleKeys.redirectDeepLink, redirectDeepLink) if (fontResId != null) { putInt(XS2AWizardBundleKeys.fontResId, fontResId) @@ -92,7 +92,7 @@ class XS2AWizardFragment() : Fragment(), XS2AWizardCallbackListener { enableBackButton = arguments.getBoolean(XS2AWizardBundleKeys.enableBackButton), enableAutomaticRetry = arguments.getBoolean(XS2AWizardBundleKeys.enableAutomaticRetry), callbackListener = this@XS2AWizardFragment, - redirectUrl = arguments.getString(XS2AWizardBundleKeys.redirectURL) + redirectDeepLink = arguments.getString(XS2AWizardBundleKeys.redirectDeepLink) ) } } From f02828071929eaac5a4ac82283b6cd9cf86f9bc2 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 7 Aug 2023 15:45:05 +0200 Subject: [PATCH 14/17] Added Docs for XS2AWizard and XS2AWizardFragment --- .../fintecsystems/xs2awizard/XS2AWizard.kt | 3 +++ .../xs2awizard/wrappers/XS2AWizardFragment.kt | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt index bd05503..89ada1f 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/XS2AWizard.kt @@ -52,6 +52,9 @@ import com.fintecsystems.xs2awizard.form.components.textLine.TextLine * @param enableAutomaticRetry - If true requests to the backend will be retried if the device is offline and goes online again. * This also means that the loading indicator will stay during that time. * @param callbackListener - Listener to all XS2A callbacks. + * @param redirectDeepLink - Deep Link of Host-App used for returning App2App redirection. + * Must match your scheme and host declared in your AndroidManifest. + * e.g "://". * @param xs2aWizardViewModel - ViewModel of the Wizard-Instance. */ @Composable diff --git a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt index c74e037..6af1ade 100644 --- a/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt +++ b/xs2awizard/src/main/java/com/fintecsystems/xs2awizard/wrappers/XS2AWizardFragment.kt @@ -22,6 +22,27 @@ import com.fintecsystems.xs2awizard.components.theme.XS2ATheme * Wrapper for the XS2A-Wizard Compose Component */ class XS2AWizardFragment() : Fragment(), XS2AWizardCallbackListener { + /** + * Renders the XS2A-Wizard. + * + * @param sessionKey - Session key used by the wizard. + * @param backendURL - Optional URL to target a different backend. + * @param theme - Theme to be used. + * If null the default Light- or Dark-Theme, depending on the device settings, is used. + * @param fontResId - Custom typography to be used by all form elements. + * @param language - Specifies the wizard language. + * Defaults to the device language if supported, [XS2AWizardLanguage.EN] otherwise. + * @param enableScroll - If true the form container allows for automatic scrolling. + * Disable if you need to implement nested scrolling. + * @param enableBackButton - If true renders back button on some forms. + * Disable this only if you implement your own back-handling-logic. + * The user needs to have a way to "go-back". + * @param enableAutomaticRetry - If true requests to the backend will be retried if the device is offline and goes online again. + * This also means that the loading indicator will stay during that time. + * @param redirectDeepLink - Deep Link of Host-App used for returning App2App redirection. + * Must match your scheme and host declared in your AndroidManifest. + * e.g "://". + */ @Suppress("unused") constructor( sessionKey: String, From 133b37887af78712f694713dc277f609d3da0a04 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 14 Aug 2023 15:53:18 +0200 Subject: [PATCH 15/17] Added translations for french, spanish and italian --- xs2awizard/src/main/res/values-es/strings.xml | 4 ++++ xs2awizard/src/main/res/values-fr/strings.xml | 4 ++++ xs2awizard/src/main/res/values-it/strings.xml | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/xs2awizard/src/main/res/values-es/strings.xml b/xs2awizard/src/main/res/values-es/strings.xml index 617d9ba..6c0cf79 100644 --- a/xs2awizard/src/main/res/values-es/strings.xml +++ b/xs2awizard/src/main/res/values-es/strings.xml @@ -24,4 +24,8 @@ ¿Utilizar los datos guardados? Sin conexión a Internet Error de servidor + Seleccione el método de autenticación + ¿Cómo quiere conectarse? Si ha instalado la aplicación de su banco, seleccione \"Aplicación bancaria\"; de lo contrario, seleccione \"Página web\". + Aplicación bancaria + Página web \ No newline at end of file diff --git a/xs2awizard/src/main/res/values-fr/strings.xml b/xs2awizard/src/main/res/values-fr/strings.xml index 7faef07..2179db5 100644 --- a/xs2awizard/src/main/res/values-fr/strings.xml +++ b/xs2awizard/src/main/res/values-fr/strings.xml @@ -24,4 +24,8 @@ Annuler Pas de connexion Internet Erreur de serveur + Sélectionner la méthode d\'authentification + Comment voulez-vous vous connecter ? Si vous avez installé l\'application de votre banque, sélectionnez \"Application bancaire\", sinon sélectionnez \"Site web\". + Application bancaire + Site web \ No newline at end of file diff --git a/xs2awizard/src/main/res/values-it/strings.xml b/xs2awizard/src/main/res/values-it/strings.xml index f517e25..ad45f54 100644 --- a/xs2awizard/src/main/res/values-it/strings.xml +++ b/xs2awizard/src/main/res/values-it/strings.xml @@ -24,4 +24,8 @@ Usare i dati salvati? Nessuna connessione Internet Errore del server + Selezionare il metodo di autenticazione + Come si desidera effettuare il login? Se avete installato l\'applicazione della vostra banca, selezionate \"App bancaria\", altrimenti selezionate \"Sito web\". + App bancaria + Sito web \ No newline at end of file From 6c53b6aecea11549b136e8bdb90c8b1091f92088 Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 14 Aug 2023 16:02:36 +0200 Subject: [PATCH 16/17] Updated README.md --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/README.md b/README.md index 89b3585..739433c 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,52 @@ Pass your ViewModel, using the `viewModels` function, and pass it to the `XS2AWi > It is possible to freely define the ViewModel-Scope. > Please refer to [this answer](https://stackoverflow.com/a/68971296) for more information. +## App to App redirection +Some banks support redirecting to their banking app. +Per default the SDK will not redirect to the banking app and opens the internal WebView instead. + +If you'd like to make use of this feature you can configure the SDK the following way: + +Modify your `AndroidManifest.xml` with the following: + +```xml + + ... + + + + + + + +``` + +Populate `host` and `scheme` with your the URL of your App. + +After that just pass your URL to the SDK: + +```kotlin +// Compose +XS2AWizard( + sessionKey = , + redirectDeepLink = "://" // Insert your deep link +) + +// Fragment +XS2AWizardFragment( + sessionKey = , + redirectDeepLink = "://" // Insert your deep link +) +``` + +Now every time the SDK encounters an URL to a bank which is known by us to support App2App redirection, the user gets asked if they want +to perform the action within the WebView or the banking app. + #### Example ```kotlin From cef6cc1b4d760a6bf2084a48f040f674e9f07f4d Mon Sep 17 00:00:00 2001 From: Maik Mursall Date: Mon, 14 Aug 2023 16:04:01 +0200 Subject: [PATCH 17/17] Added Beta tag to App2App Redirection section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 739433c..099a05d 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ Pass your ViewModel, using the `viewModels` function, and pass it to the `XS2AWi > It is possible to freely define the ViewModel-Scope. > Please refer to [this answer](https://stackoverflow.com/a/68971296) for more information. -## App to App redirection +## App to App redirection (Beta) Some banks support redirecting to their banking app. Per default the SDK will not redirect to the banking app and opens the internal WebView instead.