Skip to content

Dev #1405

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

Closed
wants to merge 11 commits into from
Closed

Dev #1405

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
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## [Unreleased](https://github.com/Instabug/Instabug-React-Native/compare/v14.3.0...dev)

### Added

- Add support enable/disable screenshot auto masking. ([#1389](https://github.com/Instabug/Instabug-React-Native/pull/1389))

- Add support for BugReporting user consents. ([#1383](https://github.com/Instabug/Instabug-React-Native/pull/1383))

- Add support for xCode 16. ([#1370](https://github.com/Instabug/Instabug-React-Native/pull/1370))

- Add support for network spans. ([#1394](https://github.com/Instabug/Instabug-React-Native/pull/1394))

- Add respect to backend network body limit. ([#1397](https://github.com/Instabug/Instabug-React-Native/pull/1397))

### Fixed

- Not sending the inComplete xhrRequest. ([#1365](https://github.com/Instabug/Instabug-React-Native/pull/1365))

- Added more search capabilities to the find-token.sh script. e.g., searching in .env file for react config. [#1366](https://github.com/Instabug/Instabug-React-Native/pull/1366)

## [14.3.0](https://github.com/Instabug/Instabug-React-Native/compare/v14.1.0...14.3.0)

### Added
Expand Down
5 changes: 3 additions & 2 deletions RNInstabug.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ Pod::Spec.new do |s|
s.homepage = package["homepage"]
s.source = { :git => "https://github.com/Instabug/Instabug-React-Native.git", :tag => 'v' + package["version"] }

s.platform = :ios, "9.0"
s.platform = :ios, "13.0"
s.source_files = "ios/**/*.{h,m,mm}"

s.dependency 'React-Core'
use_instabug!(s)
# use_instabug!(s)
s.dependency 'Instabug'

end
2 changes: 1 addition & 1 deletion android/native.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project.ext.instabug = [
version: '14.3.0'
version: '14.3.0.6760192-SNAPSHOT'
]

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.instabug.library.invocation.util.InstabugVideoRecordingButtonPosition;
import com.instabug.library.sessionreplay.model.SessionMetadata;
import com.instabug.library.ui.onboarding.WelcomeMessage;
import com.instabug.library.MaskingType;

import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -60,6 +61,8 @@ static Map<String, Object> getAll() {
putAll(locales);
putAll(placeholders);
putAll(launchType);
putAll(autoMaskingTypes);
putAll(userConsentActionType);
}};
}

Expand Down Expand Up @@ -142,6 +145,12 @@ static Map<String, Object> getAll() {
put("reproStepsDisabled", ReproMode.Disable);
}};

static final ArgsMap<String> userConsentActionType = new ArgsMap<String>() {{
put("dropAutoCapturedMedia", com.instabug.bug.userConsent.ActionType.DROP_AUTO_CAPTURED_MEDIA);
put("dropLogs", com.instabug.bug.userConsent.ActionType.DROP_LOGS);
put("noChat", com.instabug.bug.userConsent.ActionType.NO_CHAT);
}};

static final ArgsMap<Integer> sdkLogLevels = new ArgsMap<Integer>() {{
put("sdkDebugLogsLevelNone", com.instabug.library.LogLevel.NONE);
put("sdkDebugLogsLevelError", com.instabug.library.LogLevel.ERROR);
Expand Down Expand Up @@ -253,5 +262,10 @@ static Map<String, Object> getAll() {
put(SessionMetadata.LaunchType.COLD,"cold");
put(SessionMetadata.LaunchType.WARM,"warm" );
}};

public static final ArgsMap<Integer> autoMaskingTypes = new ArgsMap<Integer>() {{
put("labels", MaskingType.LABELS);
put("textInputs", MaskingType.TEXT_INPUTS);
put("media", MaskingType.MEDIA);
put("none", MaskingType.MASK_NOTHING);
}};
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ final class Constants {
final static String IBG_ON_NEW_MESSAGE_HANDLER = "IBGonNewMessageHandler";
final static String IBG_ON_NEW_REPLY_RECEIVED_CALLBACK = "IBGOnNewReplyReceivedCallback";

final static String IBG_ON_NEW_W3C_FLAGS_UPDATE_RECEIVED_CALLBACK = "IBGOnNewW3CFlagsUpdateReceivedCallback";
final static String IBG_ON_FEATURES_UPDATED_CALLBACK = "IBGOnFeatureUpdatedCallback";
final static String IBG_NETWORK_LOGGER_HANDLER = "IBGNetworkLoggerHandler";

final static String IBG_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK = "IBGOnNewFeatureFlagsUpdateReceivedCallback";

final static String IBG_SESSION_REPLAY_ON_SYNC_CALLBACK_INVOCATION = "IBGSessionReplayOnSyncCallback";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
Expand All @@ -21,6 +22,7 @@
import com.instabug.reactlibrary.utils.ArrayUtil;
import com.instabug.reactlibrary.utils.EventEmitterModule;
import com.instabug.reactlibrary.utils.MainThreadHandler;
import com.instabug.bug.userConsent.ActionType;

import java.util.ArrayList;

Expand Down Expand Up @@ -415,4 +417,30 @@ public void run() {
}
});
}

/**
* Adds a user consent item to the bug reporting
* @param key A unique identifier string for the consent item.
* @param description The text shown to the user describing the consent item.
* @param mandatory Whether the user must agree to this item before submitting a report.
* @param checked Whether the consent checkbox is pre-selected.
* @param actionType A string representing the action type to map to SDK behavior.
*/
@ReactMethod
public void addUserConsent(String key, String description, boolean mandatory, boolean checked, @Nullable String actionType) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
String mappedActionType = ArgsRegistry.userConsentActionType.get(actionType);
BugReporting.addUserConsent(key, description, mandatory, checked, mappedActionType);
} catch (Exception e) {
e.printStackTrace();
}
}
});

}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package com.instabug.reactlibrary;


import static com.instabug.apm.configuration.cp.APMFeature.APM_NETWORK_PLUGIN_INSTALLED;
import static com.instabug.apm.configuration.cp.APMFeature.CP_NATIVE_INTERCEPTION_ENABLED;

import android.util.Log;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.instabug.apm.InternalAPM;
import com.instabug.apm.sanitization.OnCompleteCallback;
import com.instabug.library.logging.listeners.networklogs.NetworkLogSnapshot;
import com.instabug.reactlibrary.utils.EventEmitterModule;
import com.instabug.reactlibrary.utils.MainThreadHandler;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class RNInstabugNetworkLoggerModule extends EventEmitterModule {

public final ConcurrentHashMap<String, OnCompleteCallback<NetworkLogSnapshot>> callbackMap = new ConcurrentHashMap<String, OnCompleteCallback<NetworkLogSnapshot>>();

public RNInstabugNetworkLoggerModule(ReactApplicationContext reactContext) {
super(reactContext);
}


@NonNull
@Override
public String getName() {
return "IBGNetworkLogger";
}


@ReactMethod
public void addListener(String event) {
super.addListener(event);
}

@ReactMethod
public void removeListeners(Integer count) {
super.removeListeners(count);
}

private boolean getFlagValue(String key) {
return InternalAPM._isFeatureEnabledCP(key, "");
}

private WritableMap convertFromMapToWritableMap(Map<String, Object> map) {
WritableMap writableMap = new WritableNativeMap();
for (String key : map.keySet()) {
Object value = map.get(key);
writableMap.putString(key, (String) value);
}
return writableMap;
}

private Map<String, Object> convertReadableMapToMap(ReadableMap readableMap) {
Map<String, Object> map = new HashMap<>();
if (readableMap != null) {
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
map.put(key, readableMap.getString(key));
}
}
return map;
}

/**
* Get first time Value of [cp_native_interception_enabled] flag
*/
@ReactMethod
public void isNativeInterceptionEnabled(Promise promise) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
promise.resolve(getFlagValue(CP_NATIVE_INTERCEPTION_ENABLED));
} catch (Exception e) {
e.printStackTrace();
promise.resolve(false); // Will rollback to JS interceptor
}

}
});
}

/**
* Indicate if user added APM Network plugin or not
* [true] means user added the APM plugin
* [false] means not
*/
@ReactMethod
public void hasAPMNetworkPlugin(Promise promise) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
promise.resolve(getFlagValue(APM_NETWORK_PLUGIN_INSTALLED));
} catch (Exception e) {
e.printStackTrace();
promise.resolve(false); // Will rollback to JS interceptor
}

}
});
}


@ReactMethod
public void registerNetworkLogsListener() {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
InternalAPM._registerNetworkLogSanitizer((networkLogSnapshot, onCompleteCallback) -> {
final String id = String.valueOf(onCompleteCallback.hashCode());
callbackMap.put(id, onCompleteCallback);

WritableMap networkSnapshotParams = Arguments.createMap();
networkSnapshotParams.putString("id", id);
networkSnapshotParams.putString("url", networkLogSnapshot.getUrl());
networkSnapshotParams.putInt("responseCode", networkLogSnapshot.getResponseCode());
networkSnapshotParams.putString("requestBody", networkLogSnapshot.getRequestBody());
networkSnapshotParams.putString("response", networkLogSnapshot.getResponse());
final Map<String, Object> requestHeaders = networkLogSnapshot.getRequestHeaders();
if (requestHeaders != null) {
networkSnapshotParams.putMap("requestHeader", convertFromMapToWritableMap(requestHeaders));
}
final Map<String, Object> responseHeaders = networkLogSnapshot.getResponseHeaders();
if (responseHeaders != null) {
networkSnapshotParams.putMap("responseHeader", convertFromMapToWritableMap(responseHeaders));
}

sendEvent(Constants.IBG_NETWORK_LOGGER_HANDLER, networkSnapshotParams);
});
}
});
}

@ReactMethod
public void resetNetworkLogsListener() {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
InternalAPM._registerNetworkLogSanitizer(null);
}
});
}

@ReactMethod
public void updateNetworkLogSnapshot(
String url,
String callbackID,
String requestBody,
String responseBody,
int responseCode,
ReadableMap requestHeaders,
ReadableMap responseHeaders
) {
try {
// Convert ReadableMap to a Java Map for easier handling
Map<String, Object> requestHeadersMap = convertReadableMapToMap(requestHeaders);
Map<String, Object> responseHeadersMap = convertReadableMapToMap(responseHeaders);

NetworkLogSnapshot modifiedSnapshot = null;
if (!url.isEmpty()) {
modifiedSnapshot = new NetworkLogSnapshot(url, requestHeadersMap, requestBody, responseHeadersMap, responseBody, responseCode);
}

final OnCompleteCallback<NetworkLogSnapshot> callback = callbackMap.get(callbackID);
if (callback != null) {
callback.onComplete(modifiedSnapshot);
callbackMap.remove(callbackID);
}
} catch (Exception e) {
// Reject the promise to indicate an error occurred
Log.e("IB-CP-Bridge", "InstabugNetworkLogger.updateNetworkLogSnapshot failed to parse the network snapshot object.");
}
}
}
Loading