From d34cdbec13891f8b1444548dedb535f032541e99 Mon Sep 17 00:00:00 2001 From: ahmadAlfhajri <82349749+ahmadAlfhajri@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:04:35 +0800 Subject: [PATCH 1/2] fix: Handle 3DS authentication edge case and version tracking - Fix premature webview dismissal caused by unexpected callback responses before 3DS OTP authentication - Correct version name tracking implementation --- .../src/main/java/com/xendit/Xendit.java | 3 +- .../main/java/com/xendit/XenditActivity.java | 9 ++-- .../xendit/utils/Auth3DSEventValidator.java | 43 +++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 xendit-android/src/main/java/com/xendit/utils/Auth3DSEventValidator.java diff --git a/xendit-android/src/main/java/com/xendit/Xendit.java b/xendit-android/src/main/java/com/xendit/Xendit.java index 9f100fb..81d7dbe 100644 --- a/xendit-android/src/main/java/com/xendit/Xendit.java +++ b/xendit-android/src/main/java/com/xendit/Xendit.java @@ -75,7 +75,6 @@ public class Xendit { private static final String GET_3DS_URL = PRODUCTION_XENDIT_BASE_URL + "/3ds_bin_recommendation"; private static final String DSN_SERVER = "https://7190a1331444434eb6aed7b5a8d776f0@o30316.ingest.sentry.io/6314580"; private static final String CLIENT_IDENTIFIER = "Xendit Android SDK"; - private static final String CLIENT_API_VERSION = "2.0.0"; private static final String CLIENT_TYPE = "SDK"; static final String ACTION_KEY = "ACTION_KEY"; @@ -1499,7 +1498,7 @@ private BaseRequest buildBaseRequest(int method, String url, String onBehalfOf, } request.addHeader("Authorization", basicAuthCredentials.replace("\n", "")); request.addHeader("x-client-identifier", CLIENT_IDENTIFIER); - request.addHeader("client-version", CLIENT_API_VERSION); + request.addHeader("client-version", BuildConfig.VERSION_NAME); request.addHeader("client-type", CLIENT_TYPE); return request; } diff --git a/xendit-android/src/main/java/com/xendit/XenditActivity.java b/xendit-android/src/main/java/com/xendit/XenditActivity.java index 57fd0f9..79691d6 100644 --- a/xendit-android/src/main/java/com/xendit/XenditActivity.java +++ b/xendit-android/src/main/java/com/xendit/XenditActivity.java @@ -13,8 +13,8 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ProgressBar; - import com.xendit.Models.HasAuthenticationUrl; +import com.xendit.utils.Auth3DSEventValidator; /** * Created by Sergey on 3/23/17. @@ -99,9 +99,10 @@ public void postMessage(String message) { handler.post(new Runnable() { @Override public void run() { - sendBroadcastReceiver(message); - - finish(); + if (Auth3DSEventValidator.is3DSResultEventFromXendit(message, XenditActivity.this)) { + sendBroadcastReceiver(message); + finish(); + } } }); } diff --git a/xendit-android/src/main/java/com/xendit/utils/Auth3DSEventValidator.java b/xendit-android/src/main/java/com/xendit/utils/Auth3DSEventValidator.java new file mode 100644 index 0000000..c5b4eef --- /dev/null +++ b/xendit-android/src/main/java/com/xendit/utils/Auth3DSEventValidator.java @@ -0,0 +1,43 @@ +package com.xendit.utils; + +import android.content.Context; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.xendit.R; +import java.util.HashMap; +import java.util.Map; + +public class Auth3DSEventValidator { + private static final String ID_FIELD = "id"; + private static final String STATUS_FIELD = "status"; + + private Auth3DSEventValidator() { + // Private constructor to prevent instantiation + } + + public static boolean is3DSResultEventFromXendit(String message, Context context) { + if (message.isEmpty()) return false; + + return isValidJsonMessage(message) || isKnownErrorMessage(message, context); + } + + private static boolean isValidJsonMessage(String message) { + try { + Map<String, Object> messageInJson = new Gson().fromJson( + message, + new TypeToken<HashMap<String, Object>>() {}.getType() + ); + + // A valid 3ds callback payload from Xendit, should contain required fields: id and status. + return messageInJson.get(ID_FIELD) != null && messageInJson.get(STATUS_FIELD) != null; + } catch (Exception e) { + return false; + } + } + + private static boolean isKnownErrorMessage(String message, Context context) { + return message.equals(context.getString(R.string.create_token_error_validation)) || + message.equals(context.getString(R.string.tokenization_error)); + } + +} From 8b54a94388b3d0ff3f3ecb822ac7d89e8411bbd3 Mon Sep 17 00:00:00 2001 From: ahmadAlfhajri <82349749+ahmadAlfhajri@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:24:01 +0800 Subject: [PATCH 2/2] Bump version to 4.2.3 --- CHANGELOG.md | 3 +++ README.md | 8 ++++---- xendit-android/build.gradle | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70bb1d1..0c890b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG +## 4.2.3 (2025-01-24) +- Fix: Handle 3DS authentication edge case and version tracking + ## 4.2.2 (2024-11-21) - Fixed app crash related to unregistered AuthenticationBroadcastReceiver by implementing proper lifecycle-aware receiver management diff --git a/README.md b/README.md index 4ce084e..0203315 100644 --- a/README.md +++ b/README.md @@ -31,24 +31,24 @@ Maven: <dependency> <groupId>com.xendit</groupId> <artifactId>xendit-android</artifactId> - <version>4.2.2</version> + <version>4.2.3</version> <type>pom</type> </dependency> ``` Gradle: ``` -compile 'com.xendit:xendit-android:4.2.2' +compile 'com.xendit:xendit-android:4.2.3' ``` Ivy: ``` -<dependency org='com.xendit' name='xendit-android' rev='4.2.2'> +<dependency org='com.xendit' name='xendit-android' rev='4.2.3'> <artifact name='xendit-android' ext='pom' ></artifact> </dependency> ``` -For more information, visit https://central.sonatype.com/artifact/com.xendit/xendit-android/4.2.2/versions +For more information, visit https://central.sonatype.com/artifact/com.xendit/xendit-android/4.2.3/versions **Note**: diff --git a/xendit-android/build.gradle b/xendit-android/build.gradle index 8da1720..df02fbe 100644 --- a/xendit-android/build.gradle +++ b/xendit-android/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'maven-publish' apply plugin: 'signing' group 'com.xendit' -version '4.2.2' +version '4.2.3' ext { bintrayOrg = 'xendit' @@ -37,7 +37,7 @@ android { minSdkVersion 21 targetSdkVersion 34 versionCode 1 - versionName '4.2.2' + versionName '4.2.3' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes {