From d60b97ce4a777a2e693b831a1f91a6bd6ac2d8fd Mon Sep 17 00:00:00 2001 From: Oskar Eichler <62393985+OskarEichler@users.noreply.github.com> Date: Fri, 28 Aug 2026 04:18:43 +0300 Subject: [PATCH 1/2] fix(android): preserve structured additional response parameters --- .changeset/appauth-android-response-values.md | 5 +++ .../java/com/rnappauth/utils/MapUtil.java | 37 +++++++++++-------- .../rnappauth/utils/TokenResponseFactory.java | 12 +----- 3 files changed, 27 insertions(+), 27 deletions(-) create mode 100644 .changeset/appauth-android-response-values.md diff --git a/.changeset/appauth-android-response-values.md b/.changeset/appauth-android-response-values.md new file mode 100644 index 000000000..c3f68165f --- /dev/null +++ b/.changeset/appauth-android-response-values.md @@ -0,0 +1,5 @@ +--- +"react-native-app-auth": patch +--- + +Decode JSON objects and arrays once, preserve nested null values, accept null native values without a crash, and retain scalar/malformed strings. Iterate map entries directly and share the base authorization response serializer when adding a PKCE verifier. diff --git a/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java b/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java index 624201ad5..8242081e6 100644 --- a/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java +++ b/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java @@ -15,6 +15,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.json.JSONTokener; import java.util.HashMap; import java.util.Iterator; @@ -39,24 +40,24 @@ public static HashMap readableMapToHashMap(@Nullable ReadableMap public static final WritableMap createAdditionalParametersMap(Map additionalParameters) { WritableMap additionalParametersMap = Arguments.createMap(); - if (!additionalParameters.isEmpty()) { - - Iterator iterator = additionalParameters.keySet().iterator(); - - while(iterator.hasNext()) { - String key = iterator.next(); - String value = additionalParameters.get(key); - // Try to parse to JSON + for (Map.Entry entry : additionalParameters.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + if (value != null) { try { - JSONObject jsonObject = new JSONObject(value); - WritableMap json = convertJsonToMap(jsonObject); - additionalParametersMap.putMap(key, json); - continue; + Object parsed = new JSONTokener(value).nextValue(); + if (parsed instanceof JSONObject) { + additionalParametersMap.putMap(key, convertJsonToMap((JSONObject) parsed)); + continue; + } + if (parsed instanceof JSONArray) { + additionalParametersMap.putArray(key, convertJsonToArray((JSONArray) parsed)); + continue; + } } catch (JSONException ignored) { - } - additionalParametersMap.putString(key, additionalParameters.get(key)); } + additionalParametersMap.putString(key, value); } return additionalParametersMap; @@ -69,7 +70,9 @@ private static WritableMap convertJsonToMap(JSONObject jsonObject) throws JSONEx while (iterator.hasNext()) { String key = iterator.next(); Object value = jsonObject.get(key); - if (value instanceof JSONObject) { + if (value == JSONObject.NULL) { + map.putNull(key); + } else if (value instanceof JSONObject) { map.putMap(key, convertJsonToMap((JSONObject) value)); } else if (value instanceof JSONArray) { map.putArray(key, convertJsonToArray((JSONArray) value)); @@ -97,7 +100,9 @@ private static WritableArray convertJsonToArray(JSONArray jsonArray) throws JSON for (int i = 0; i < jsonArray.length(); i++) { Object value = jsonArray.get(i); - if (value instanceof JSONObject) { + if (value == JSONObject.NULL) { + array.pushNull(); + } else if (value instanceof JSONObject) { array.pushMap(convertJsonToMap((JSONObject) value)); } else if (value instanceof JSONArray) { array.pushArray(convertJsonToArray((JSONArray) value)); diff --git a/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/TokenResponseFactory.java b/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/TokenResponseFactory.java index 38467ebaa..0b336009a 100644 --- a/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/TokenResponseFactory.java +++ b/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/TokenResponseFactory.java @@ -91,17 +91,7 @@ public static final WritableMap authorizationResponseToMap(AuthorizationResponse * Read raw authorization into a React Native map with codeVerifier value added if present to be passed down the bridge */ public static final WritableMap authorizationCodeResponseToMap(AuthorizationResponse authResponse, String codeVerifier) { - WritableMap map = Arguments.createMap(); - map.putString("authorizationCode", authResponse.authorizationCode); - map.putString("accessToken", authResponse.accessToken); - map.putMap("additionalParameters", MapUtil.createAdditionalParametersMap(authResponse.additionalParameters)); - map.putString("idToken", authResponse.idToken); - map.putString("tokenType", authResponse.tokenType); - map.putArray("scopes", createScopeArray(authResponse.scope)); - - if (authResponse.accessTokenExpirationTime != null) { - map.putString("accessTokenExpirationTime", DateUtil.formatTimestamp(authResponse.accessTokenExpirationTime)); - } + WritableMap map = authorizationResponseToMap(authResponse); if (!TextUtils.isEmpty(codeVerifier)) { map.putString("codeVerifier", codeVerifier); From 62477eb2be5eebfdd6a5b62a7c70b4fd6ae51852 Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Sun, 30 Aug 2026 19:51:47 +0700 Subject: [PATCH 2/2] Reject trailing content in structured response values --- .../java/com/rnappauth/utils/MapUtil.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java b/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java index 8242081e6..4efa65301 100644 --- a/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java +++ b/packages/react-native-app-auth/android/src/main/java/com/rnappauth/utils/MapUtil.java @@ -45,14 +45,17 @@ public static final WritableMap createAdditionalParametersMap(Map