Skip to content

Release: v15.0.2 #1428

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

Merged
merged 5 commits into from
Aug 10, 2025
Merged
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

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

### Added

- Add support for ignoreFlagSecure to bypass SDK screenshot security protocols on Android. ([#1394](https://github.com/Instabug/Instabug-React-Native/pull/1394))

### Fixed

- async initialization. ([#1427](https://github.com/Instabug/Instabug-React-Native/pull/1427))

## [15.0.1](https://github.com/Instabug/Instabug-React-Native/compare/v14.3.0...v15.0.1)

### Added
Expand Down
56 changes: 38 additions & 18 deletions android/src/main/java/com/instabug/reactlibrary/RNInstabug.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public class RNInstabug {

private static RNInstabug instance;

private RNInstabug() {}
private RNInstabug() {
}


public static RNInstabug getInstance() {
Expand All @@ -36,14 +37,13 @@ public static RNInstabug getInstance() {
/**
* Initializes the SDK on the native side, which is useful for capturing startup issues specific to the native part of the app.
*
* @param application The application context.
* @param application The application context.
* @param applicationToken The app's identifying token, available on your dashboard.
* @param logLevel The level of detail in logs that you want to print.
* <p>Pick one of the log levels described in {@link LogLevel}.
* default logLevel is {@link LogLevel#ERROR}</p>
* @param InvocationEvent The events that trigger the SDK's user interface.
* Choose from the available events listed in {@link InstabugInvocationEvent}.
*
* @param logLevel The level of detail in logs that you want to print.
* <p>Pick one of the log levels described in {@link LogLevel}.
* default logLevel is {@link LogLevel#ERROR}</p>
* @param InvocationEvent The events that trigger the SDK's user interface.
* Choose from the available events listed in {@link InstabugInvocationEvent}.
* @example <p>Here's an example usage: </p>
* <blockquote><pre>
* RNInstabug.getInstance().init(
Expand All @@ -59,17 +59,24 @@ public void init(
@NonNull Application application,
@NonNull String applicationToken,
int logLevel,
Boolean ignoreSecureFlag,
@NonNull InstabugInvocationEvent... InvocationEvent
) {
) {
try {

setBaseUrlForDeprecationLogs();
setCurrentPlatform();

new Instabug.Builder(application, applicationToken)
Instabug.Builder builder = new Instabug.Builder(application, applicationToken)
.setInvocationEvents(InvocationEvent)
.setSdkDebugLogsLevel(logLevel)
.build();
.setSdkDebugLogsLevel(logLevel);

if (ignoreSecureFlag != null) {
builder.ignoreFlagSecure(ignoreSecureFlag);
}

builder.build();


// Temporarily disabling APM hot launches
APM.setHotAppLaunchEnabled(false);
Expand All @@ -80,15 +87,13 @@ public void init(
}



/**
* Initializes the SDK on the native side, which is useful for capturing startup issues specific to the native part of the app.
*
* @param application The application context.
* @param application The application context.
* @param applicationToken The app's identifying token, available on your dashboard.
* @param invocationEvent The events that trigger the SDK's user interface.
* Choose from the available events listed in {@link InstabugInvocationEvent}.
*
* @param invocationEvent The events that trigger the SDK's user interface.
* Choose from the available events listed in {@link InstabugInvocationEvent}.
* @example <p>Here's an example usage: </p>
* <blockquote><pre>
* RNInstabug.getInstance().init(
Expand All @@ -104,7 +109,7 @@ public void init(
@NonNull String applicationToken,
@NonNull InstabugInvocationEvent... invocationEvent
) {
init(application, applicationToken, LogLevel.ERROR, invocationEvent);
init(application, applicationToken, LogLevel.ERROR,null, invocationEvent);
}

@VisibleForTesting
Expand Down Expand Up @@ -160,6 +165,7 @@ public static class Builder {
* The events that trigger the SDK's user interface.
*/
private InstabugInvocationEvent[] invocationEvents;
private Boolean ignoreFlagSecure;


/**
Expand Down Expand Up @@ -210,6 +216,16 @@ public Builder setCodePushVersion(String codePushVersion) {
return this;
}

/**
* Sets flag to override SDK screenshot security behavior.
*
* @param ignoreFlagSecure flag to override SDK screenshot security behavior.
*/
public Builder ignoreFlagSecure(boolean ignoreFlagSecure) {
this.ignoreFlagSecure = ignoreFlagSecure;
return this;
}

/**
* Sets the invocation triggering events for the SDK's user interface
*
Expand Down Expand Up @@ -237,6 +253,10 @@ public void build() {
instabugBuilder.setCodePushVersion(codePushVersion);
}

if (ignoreFlagSecure != null) {
instabugBuilder.ignoreFlagSecure(ignoreFlagSecure);
}

instabugBuilder.build();

// Temporarily disabling APM hot launches
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ public void init(
final ReadableArray invocationEventValues,
final String logLevel,
final boolean useNativeNetworkInterception,
@Nullable final String codePushVersion
@Nullable final String codePushVersion,
final ReadableMap map
) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
Expand All @@ -166,6 +167,10 @@ public void run() {
.setInvocationEvents(invocationEvents)
.setLogLevel(parsedLogLevel);

if (map!=null&&map.hasKey("ignoreAndroidSecureFlag")) {
builder.ignoreFlagSecure(map.getBoolean("ignoreAndroidSecureFlag"));
}

if (codePushVersion != null) {
if (Instabug.isBuilt()) {
Instabug.setCodePushVersion(codePushVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static com.instabug.reactlibrary.util.GlobalMocks.reflected;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockConstruction;
Expand Down Expand Up @@ -62,18 +63,20 @@ public void testInitWithLogLevel() {
// Initializes Instabug with the correct token
assertEquals(token, actualToken);
when(mock.setSdkDebugLogsLevel(anyInt())).thenReturn(mock);
when(mock.ignoreFlagSecure(anyBoolean())).thenReturn(mock);
when(mock.setInvocationEvents(any())).thenReturn(mock);
});

sut.init(mContext, token, logLevel, invocationEvents);
sut.init(mContext, token, logLevel, true, invocationEvents);

Instabug.Builder builder = mInstabugBuilder.constructed().get(0);

// Here we check that it has changed to verbose value of the `logLevel` property
verify(builder).setSdkDebugLogsLevel(LogLevel.VERBOSE);
verify(builder).setInvocationEvents(invocationEvents);
verify(builder).build();
verify(builder).ignoreFlagSecure(true);

verify(builder).build();


verify(sut).setBaseUrlForDeprecationLogs();
Expand All @@ -95,7 +98,7 @@ public void testInitWithoutLogLevel() {

sut.init(mContext, token, invocationEvents);

verify(sut).init(mContext, token, defaultLogLevel, invocationEvents);
verify(sut).init(mContext, token, defaultLogLevel, null,invocationEvents);
mInstabugBuilder.close();
}

Expand Down
12 changes: 7 additions & 5 deletions examples/default/ios/InstabugTests/InstabugSampleTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ - (void)testInit {

OCMStub([mock setCodePushVersion:codePushVersion]);

[self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception codePushVersion:codePushVersion];
[self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception codePushVersion:codePushVersion
options:nil
];
OCMVerify([mock setCodePushVersion:codePushVersion]);

OCMVerify([self.mRNInstabug initWithToken:appToken invocationEvents:floatingButtonInvocationEvent debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception]);
Expand Down Expand Up @@ -610,18 +612,18 @@ - (void) testIsW3CaughtHeaderEnabled {

- (void)testEnableAutoMasking {
id mock = OCMClassMock([Instabug class]);

NSArray *autoMaskingTypes = [NSArray arrayWithObjects:
[NSNumber numberWithInteger:IBGAutoMaskScreenshotOptionLabels],
[NSNumber numberWithInteger:IBGAutoMaskScreenshotOptionTextInputs],
[NSNumber numberWithInteger:IBGAutoMaskScreenshotOptionMedia],
[NSNumber numberWithInteger:IBGAutoMaskScreenshotOptionMaskNothing],
nil];

OCMStub([mock setAutoMaskScreenshots:IBGAutoMaskScreenshotOptionLabels | IBGAutoMaskScreenshotOptionTextInputs | IBGAutoMaskScreenshotOptionMedia | IBGAutoMaskScreenshotOptionMaskNothing]);

[self.instabugBridge enableAutoMasking:autoMaskingTypes];

OCMVerify([mock setAutoMaskScreenshots:IBGAutoMaskScreenshotOptionLabels | IBGAutoMaskScreenshotOptionTextInputs | IBGAutoMaskScreenshotOptionMedia | IBGAutoMaskScreenshotOptionMaskNothing]);
}

Expand Down
27 changes: 8 additions & 19 deletions examples/default/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, StyleSheet } from 'react-native';
import React, { useEffect } from 'react';
import { StyleSheet } from 'react-native';

import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
Expand Down Expand Up @@ -40,13 +40,11 @@ export const App: React.FC = () => {

const navigationRef = useNavigationContainerRef();

const [isInstabugInitialized, setIsInstabugInitialized] = useState(false);

const initializeInstabug = async () => {
const initializeInstabug = () => {
try {
SessionReplay.setSyncCallback((data) => shouldSyncSession(data));

await Instabug.init({
Instabug.init({
token: 'deb1910a7342814af4e4c9210c786f35',
invocationEvents: [InvocationEvent.floatingButton],
debugLogsLevel: LogLevel.verbose,
Expand All @@ -55,21 +53,16 @@ export const App: React.FC = () => {

CrashReporting.setNDKCrashesEnabled(true);
Instabug.setReproStepsConfig({ all: ReproStepsMode.enabled });

setIsInstabugInitialized(true); // Set to true after initialization
} catch (error) {
console.error('Instabug initialization failed:', error);
setIsInstabugInitialized(true); // Proceed even if initialization fails
}
};

useEffect(() => {
initializeInstabug().then(() => {
NetworkLogger.setNetworkDataObfuscationHandler(async (networkData) => {
networkData.url = `${networkData.url}/JS/Obfuscated`;
return networkData;
});
// NetworkLogger.setRequestFilterExpression('false');
initializeInstabug();
NetworkLogger.setNetworkDataObfuscationHandler(async (networkData) => {
networkData.url = `${networkData.url}/JS/Obfuscated`;
return networkData;
});
});

Expand All @@ -80,10 +73,6 @@ export const App: React.FC = () => {
return unregisterListener;
}, [navigationRef]);

if (!isInstabugInitialized) {
return <ActivityIndicator size="large" color="#0000ff" style={styles.loading} />;
}

return (
<GestureHandlerRootView style={styles.root}>
<NativeBaseProvider theme={nativeBaseTheme}>
Expand Down
2 changes: 1 addition & 1 deletion ios/RNInstabug/InstabugNetworkLoggerBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ typedef NS_ENUM(NSInteger, NetworkListenerType) {
+------------------------------------------------------------------------+
*/

- (void)isNativeInterceptionEnabled:(RCTPromiseResolveBlock _Nullable )resolve :(RCTPromiseRejectBlock _Nullable )reject;
- (BOOL)isNativeInterceptionEnabled;

- (void) registerNetworkLogsListener:(NetworkListenerType)listenerType;

Expand Down
8 changes: 5 additions & 3 deletions ios/RNInstabug/InstabugNetworkLoggerBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ -(void)stopObserving {
// Remove upstream listeners, stop unnecessary background tasks
}

RCT_EXPORT_METHOD(isNativeInterceptionEnabled:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject) {
resolve(@(IBGNetworkLogger.isNativeNetworkInterceptionFeatureEnabled));
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isNativeInterceptionEnabled) {
return @(IBGNetworkLogger.isNativeNetworkInterceptionFeatureEnabled);
}



RCT_EXPORT_METHOD(registerNetworkLogsListener: (NetworkListenerType) listenerType) {
switch (listenerType) {
Expand Down
3 changes: 2 additions & 1 deletion ios/RNInstabug/InstabugReactBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@

- (void)setEnabled:(BOOL)isEnabled;

- (void)init:(NSString *)token invocationEvents:(NSArray *)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel useNativeNetworkInterception:(BOOL)useNativeNetworkInterception codePushVersion:(NSString *)codePushVersion;
- (void)init:(NSString *)token invocationEvents:(NSArray *)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel useNativeNetworkInterception:(BOOL)useNativeNetworkInterception codePushVersion:(NSString *)codePushVersion
options:(nullable NSDictionary *)options;

- (void)setCodePushVersion:(NSString *)version;

Expand Down
4 changes: 3 additions & 1 deletion ios/RNInstabug/InstabugReactBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ - (dispatch_queue_t)methodQueue {
invocationEvents:(NSArray *)invocationEventsArray
debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel
useNativeNetworkInterception:(BOOL)useNativeNetworkInterception
codePushVersion:(NSString *)codePushVersion) {
codePushVersion:(NSString *)codePushVersion
options:(nullable NSDictionary *)options
) {
IBGInvocationEvent invocationEvents = 0;

for (NSNumber *boxedValue in invocationEventsArray) {
Expand Down
5 changes: 5 additions & 0 deletions src/models/InstabugConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export interface InstabugConfig {
*/
codePushVersion?: string;

/**
* An optional flag to override SDK screenshot security behavior.
*/
ignoreAndroidSecureFlag?: boolean;

/**
* An optional network interception mode, this determines whether network interception
* is done in the JavaScript side or in the native Android and iOS SDK side.
Expand Down
13 changes: 8 additions & 5 deletions src/modules/Instabug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ function reportCurrentViewForAndroid(screenName: string | null) {
* Should be called in constructor of the AppRegistry component
* @param config SDK configurations. See {@link InstabugConfig} for more info.
*/
export const init = async (config: InstabugConfig) => {
export const init = (config: InstabugConfig) => {
if (Platform.OS === 'android') {
// Add android feature flags listener for android
registerFeatureFlagsListener();
addOnFeatureUpdatedListener(config);
} else {
isNativeInterceptionFeatureEnabled = await NativeNetworkLogger.isNativeInterceptionEnabled();
isNativeInterceptionFeatureEnabled = NativeNetworkLogger.isNativeInterceptionEnabled();

// Add app state listener to handle background/foreground transitions
addAppStateListener(async (nextAppState) => handleAppStateChange(nextAppState, config));
Expand Down Expand Up @@ -133,7 +133,6 @@ const handleAppStateChange = async (nextAppState: AppStateStatus, config: Instab
// Checks if the app has come to the foreground
if (['inactive', 'background'].includes(_currentAppState) && nextAppState === 'active') {
const isUpdated = await fetchApmNetworkFlags();

if (isUpdated) {
refreshAPMNetworkConfigs(config);
}
Expand All @@ -147,8 +146,7 @@ const handleAppStateChange = async (nextAppState: AppStateStatus, config: Instab
*/
const fetchApmNetworkFlags = async () => {
let isUpdated = false;
const newNativeInterceptionFeatureEnabled =
await NativeNetworkLogger.isNativeInterceptionEnabled();
const newNativeInterceptionFeatureEnabled = NativeNetworkLogger.isNativeInterceptionEnabled();
if (isNativeInterceptionFeatureEnabled !== newNativeInterceptionFeatureEnabled) {
isNativeInterceptionFeatureEnabled = newNativeInterceptionFeatureEnabled;
isUpdated = true;
Expand Down Expand Up @@ -275,6 +273,11 @@ const initializeNativeInstabug = (config: InstabugConfig) => {
shouldEnableNativeInterception &&
config.networkInterceptionMode === NetworkInterceptionMode.native,
config.codePushVersion,
config.ignoreAndroidSecureFlag != null
? {
ignoreAndroidSecureFlag: config.ignoreAndroidSecureFlag,
}
: undefined,
);
};

Expand Down
Loading