From 461d78871e6e3c6f6987942a6e0ac99163b3fbe5 Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Sun, 4 Feb 2024 14:30:56 +0200 Subject: [PATCH 1/4] feat: add support switching to native network interception --- .../RNInstabugReactnativeModule.java | 1 + ios/RNInstabug/InstabugReactBridge.h | 2 +- ios/RNInstabug/InstabugReactBridge.m | 4 +++- ios/RNInstabug/RNInstabug.h | 8 +++++++ ios/RNInstabug/RNInstabug.m | 21 +++++++++++++++---- src/models/InstabugConfig.ts | 13 +++++++++++- src/modules/Instabug.ts | 10 ++++++++- src/native/NativeInstabug.ts | 1 + src/utils/Enums.ts | 8 +++++++ 9 files changed, 60 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java index bf568cbf8..042dbbb71 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java @@ -127,6 +127,7 @@ public void init( final String token, final ReadableArray invocationEventValues, final String logLevel, + final boolean useNativeNetworkInterception, @Nullable final String codePushVersion ) { MainThreadHandler.runOnMainThread(new Runnable() { diff --git a/ios/RNInstabug/InstabugReactBridge.h b/ios/RNInstabug/InstabugReactBridge.h index 24baf146a..b9816da4a 100644 --- a/ios/RNInstabug/InstabugReactBridge.h +++ b/ios/RNInstabug/InstabugReactBridge.h @@ -27,7 +27,7 @@ - (void)setEnabled:(BOOL)isEnabled; -- (void)init:(NSString *)token invocationEvents:(NSArray *)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel codePushVersion:(NSString *)codePushVersion; +- (void)init:(NSString *)token invocationEvents:(NSArray *)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel useNativeNetworkInterception:(BOOL)useNativeNetworkInterception codePushVersion:(NSString *)codePushVersion; - (void)setUserData:(NSString *)userData; diff --git a/ios/RNInstabug/InstabugReactBridge.m b/ios/RNInstabug/InstabugReactBridge.m index ed512fe32..56f09a5bc 100644 --- a/ios/RNInstabug/InstabugReactBridge.m +++ b/ios/RNInstabug/InstabugReactBridge.m @@ -40,6 +40,7 @@ - (dispatch_queue_t)methodQueue { RCT_EXPORT_METHOD(init:(NSString *)token invocationEvents:(NSArray *)invocationEventsArray debugLogsLevel:(IBGSDKDebugLogsLevel)sdkDebugLogsLevel + useNativeNetworkInterception:(BOOL)useNativeNetworkInterception codePushVersion:(NSString *)codePushVersion) { IBGInvocationEvent invocationEvents = 0; @@ -51,7 +52,8 @@ - (dispatch_queue_t)methodQueue { [RNInstabug initWithToken:token invocationEvents:invocationEvents - debugLogsLevel:sdkDebugLogsLevel]; + debugLogsLevel:sdkDebugLogsLevel + useNativeNetworkInterception:useNativeNetworkInterception]; } RCT_EXPORT_METHOD(setReproStepsConfig:(IBGUserStepsMode)bugMode :(IBGUserStepsMode)crashMode:(IBGUserStepsMode)sessionReplayMode) { diff --git a/ios/RNInstabug/RNInstabug.h b/ios/RNInstabug/RNInstabug.h index e42b38844..91eaea84d 100644 --- a/ios/RNInstabug/RNInstabug.h +++ b/ios/RNInstabug/RNInstabug.h @@ -6,6 +6,14 @@ @interface RNInstabug : NSObject + (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents debugLogsLevel:(IBGSDKDebugLogsLevel)debugLogsLevel; + ++ (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents debugLogsLevel:(IBGSDKDebugLogsLevel)debugLogsLevel +useNativeNetworkInterception:(BOOL)useNativeNetworkInterception; + ++ (void)initWithToken:(NSString *)token + invocationEvents:(IBGInvocationEvent)invocationEvents +useNativeNetworkInterception:(BOOL)useNativeNetworkInterception; + + (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents; /** diff --git a/ios/RNInstabug/RNInstabug.m b/ios/RNInstabug/RNInstabug.m index 378835f72..275d0095b 100644 --- a/ios/RNInstabug/RNInstabug.m +++ b/ios/RNInstabug/RNInstabug.m @@ -13,15 +13,19 @@ + (void)reset { didInit = NO; } -+ (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents { ++ (void)initWithToken:(NSString *)token + invocationEvents:(IBGInvocationEvent)invocationEvents +useNativeNetworkInterception:(BOOL)useNativeNetworkInterception { didInit = YES; [Instabug setCurrentPlatform:IBGPlatformReactNative]; - // Disable automatic network logging in the iOS SDK to avoid duplicate network logs coming - // from both the iOS and React Native SDKs - [IBGNetworkLogger disableAutomaticCapturingOfNetworkLogs]; + if (!useNativeNetworkInterception) { + // Disable automatic network logging in the iOS SDK to avoid duplicate network logs coming + // from both the iOS and React Native SDKs + [IBGNetworkLogger disableAutomaticCapturingOfNetworkLogs]; + } [Instabug startWithToken:token invocationEvents:invocationEvents]; @@ -37,6 +41,15 @@ + (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)inv IBGAPM.hotAppLaunchEnabled = NO; } ++ (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents { + [self initWithToken:token invocationEvents:invocationEvents useNativeNetworkInterception:NO]; +} + ++ (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents debugLogsLevel:(IBGSDKDebugLogsLevel)debugLogsLevel useNativeNetworkInterception:(BOOL)useNativeNetworkInterception { + [Instabug setSdkDebugLogsLevel:debugLogsLevel]; + [self initWithToken:token invocationEvents:invocationEvents useNativeNetworkInterception:useNativeNetworkInterception]; +} + + (void)initWithToken:(NSString *)token invocationEvents:(IBGInvocationEvent)invocationEvents debugLogsLevel:(IBGSDKDebugLogsLevel)debugLogsLevel { diff --git a/src/models/InstabugConfig.ts b/src/models/InstabugConfig.ts index 0eda7a318..614ade892 100644 --- a/src/models/InstabugConfig.ts +++ b/src/models/InstabugConfig.ts @@ -1,4 +1,4 @@ -import type { InvocationEvent, LogLevel } from '../utils/Enums'; +import type { InvocationEvent, LogLevel, NetworkInterceptionMode } from '../utils/Enums'; export interface InstabugConfig { /** @@ -18,4 +18,15 @@ export interface InstabugConfig { * An optional code push version to be used for all reports. */ codePushVersion?: string; + + /** + * 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. + * + * When set to `NetworkInterceptionMode.native`, configuring network logging + * should be done through native code not JavaScript (e.g. network request obfuscation). + * + * @default NetworkInterceptionMode.javascript + */ + networkInterceptionMode?: NetworkInterceptionMode; } diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index cf0debc9a..9f537ca5f 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -12,6 +12,7 @@ import { ColorTheme, Locale, LogLevel, + NetworkInterceptionMode, ReproStepsMode, StringKey, WelcomeMessageMode, @@ -61,12 +62,19 @@ function reportCurrentViewForAndroid(screenName: string | null) { export const init = (config: InstabugConfig) => { InstabugUtils.captureJsErrors(); captureUnhandledRejections(); - NetworkLogger.setEnabled(true); + + // Default networkInterceptionMode to JavaScript + config.networkInterceptionMode ??= NetworkInterceptionMode.javascript; + + if (config.networkInterceptionMode === NetworkInterceptionMode.javascript) { + NetworkLogger.setEnabled(true); + } NativeInstabug.init( config.token, config.invocationEvents, config.debugLogsLevel ?? LogLevel.error, + config.networkInterceptionMode === NetworkInterceptionMode.native, config.codePushVersion, ); diff --git a/src/native/NativeInstabug.ts b/src/native/NativeInstabug.ts index b8b1d912f..f27684da2 100644 --- a/src/native/NativeInstabug.ts +++ b/src/native/NativeInstabug.ts @@ -23,6 +23,7 @@ export interface InstabugNativeModule extends NativeModule { token: string, invocationEvents: InvocationEvent[], debugLogsLevel: LogLevel, + useNativeNetworkInterception: boolean, codePushVersion?: string, ): void; show(): void; diff --git a/src/utils/Enums.ts b/src/utils/Enums.ts index 06878f37f..9fc86e5dc 100644 --- a/src/utils/Enums.ts +++ b/src/utils/Enums.ts @@ -24,6 +24,14 @@ export enum InvocationEvent { floatingButton = constants.invocationEventFloatingButton, } +/** + * The network interceptor to use. + */ +export enum NetworkInterceptionMode { + javascript, + native, +} + /** * Options added while invoking bug reporting. */ From 4aa55d7ceb4db2f1783e65c1aef4f12de830ad54 Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Sun, 4 Feb 2024 14:31:56 +0200 Subject: [PATCH 2/4] test(ios): add tests for enabling native network interception --- .../default/ios/InstabugTests/InstabugSampleTests.m | 3 ++- .../default/ios/InstabugTests/RNInstabugTests.m | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/examples/default/ios/InstabugTests/InstabugSampleTests.m b/examples/default/ios/InstabugTests/InstabugSampleTests.m index 05e085ee3..d87654d99 100644 --- a/examples/default/ios/InstabugTests/InstabugSampleTests.m +++ b/examples/default/ios/InstabugTests/InstabugSampleTests.m @@ -70,11 +70,12 @@ - (void)testInit { NSString *appToken = @"app_token"; NSString *codePushVersion = @"1.0.0(1)"; NSArray *invocationEvents = [NSArray arrayWithObjects:[NSNumber numberWithInteger:floatingButtonInvocationEvent], nil]; + BOOL useNativeNetworkInterception = YES; IBGSDKDebugLogsLevel sdkDebugLogsLevel = IBGSDKDebugLogsLevelDebug; OCMStub([mock setCodePushVersion:codePushVersion]); - [self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel codePushVersion:codePushVersion]; + [self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception codePushVersion:codePushVersion]; OCMVerify([mock setCodePushVersion:codePushVersion]); OCMVerify([self.mRNInstabug initWithToken:appToken invocationEvents:floatingButtonInvocationEvent debugLogsLevel:sdkDebugLogsLevel]); diff --git a/examples/default/ios/InstabugTests/RNInstabugTests.m b/examples/default/ios/InstabugTests/RNInstabugTests.m index d34c17abf..0df2fd843 100644 --- a/examples/default/ios/InstabugTests/RNInstabugTests.m +++ b/examples/default/ios/InstabugTests/RNInstabugTests.m @@ -41,6 +41,19 @@ - (void)testInitWithoutLogsLevel { OCMVerify([self.mIBGNetworkLogger setEnabled:YES]); } +- (void)testInitWithNativeNetworkInterception { + NSString *token = @"app-token"; + IBGInvocationEvent invocationEvents = IBGInvocationEventFloatingButton | IBGInvocationEventShake; + BOOL useNativeNetworkInterception = YES; + + [RNInstabug initWithToken:token invocationEvents:invocationEvents useNativeNetworkInterception:useNativeNetworkInterception]; + + OCMVerify([self.mInstabug startWithToken:token invocationEvents:invocationEvents]); + OCMVerify([self.mInstabug setCurrentPlatform:IBGPlatformReactNative]); + OCMVerify(never(), [self.mIBGNetworkLogger disableAutomaticCapturingOfNetworkLogs]); + OCMVerify([self.mIBGNetworkLogger setEnabled:YES]); +} + - (void)testInitWithLogsLevel { NSString *token = @"app-token"; IBGInvocationEvent invocationEvents = IBGInvocationEventFloatingButton | IBGInvocationEventShake; From b1d2990d89a634a6b735967d9ed912d4149c6db0 Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Sun, 4 Feb 2024 14:55:31 +0200 Subject: [PATCH 3/4] test: add tests for enabling native network interception in JS --- test/mocks/mockNetworkLogger.ts | 1 + test/modules/Instabug.spec.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/mocks/mockNetworkLogger.ts diff --git a/test/mocks/mockNetworkLogger.ts b/test/mocks/mockNetworkLogger.ts new file mode 100644 index 000000000..0eaed26e0 --- /dev/null +++ b/test/mocks/mockNetworkLogger.ts @@ -0,0 +1 @@ +jest.mock('../../src/modules/NetworkLogger'); diff --git a/test/modules/Instabug.spec.ts b/test/modules/Instabug.spec.ts index c8019c1ea..712ba0b5b 100644 --- a/test/modules/Instabug.spec.ts +++ b/test/modules/Instabug.spec.ts @@ -1,4 +1,5 @@ import '../mocks/mockInstabugUtils'; +import '../mocks/mockNetworkLogger'; import { Platform, findNodeHandle, processColor } from 'react-native'; @@ -7,12 +8,14 @@ import waitForExpect from 'wait-for-expect'; import Report from '../../src/models/Report'; import * as Instabug from '../../src/modules/Instabug'; +import * as NetworkLogger from '../../src/modules/NetworkLogger'; import { NativeEvents, NativeInstabug, emitter } from '../../src/native/NativeInstabug'; import { ColorTheme, InvocationEvent, Locale, LogLevel, + NetworkInterceptionMode, ReproStepsMode, StringKey, WelcomeMessageMode, @@ -239,13 +242,40 @@ describe('Instabug Module', () => { debugLogsLevel: LogLevel.debug, codePushVersion: '1.1.0', }; + const usesNativeNetworkInterception = false; + + Instabug.init(instabugConfig); + + expect(NetworkLogger.setEnabled).toBeCalledWith(true); + expect(NativeInstabug.init).toBeCalledTimes(1); + expect(NativeInstabug.init).toBeCalledWith( + instabugConfig.token, + instabugConfig.invocationEvents, + instabugConfig.debugLogsLevel, + usesNativeNetworkInterception, + instabugConfig.codePushVersion, + ); + }); + + it('init should disable JavaScript interceptor when using native interception mode', () => { + const instabugConfig = { + token: 'some-token', + invocationEvents: [InvocationEvent.floatingButton, InvocationEvent.shake], + debugLogsLevel: LogLevel.debug, + networkInterceptionMode: NetworkInterceptionMode.native, + codePushVersion: '1.1.0', + }; + Instabug.init(instabugConfig); + expect(NetworkLogger.setEnabled).not.toBeCalled(); expect(NativeInstabug.init).toBeCalledTimes(1); expect(NativeInstabug.init).toBeCalledWith( instabugConfig.token, instabugConfig.invocationEvents, instabugConfig.debugLogsLevel, + // usesNativeNetworkInterception should be true when using native interception mode + true, instabugConfig.codePushVersion, ); }); From 8f5f38feb18b645810ab64b3aaeb59b888342280 Mon Sep 17 00:00:00 2001 From: Ahmed Mahmoud Date: Sun, 4 Feb 2024 15:46:10 +0200 Subject: [PATCH 4/4] fix(ios): verify correct method call in native tests --- examples/default/ios/InstabugTests/InstabugSampleTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/default/ios/InstabugTests/InstabugSampleTests.m b/examples/default/ios/InstabugTests/InstabugSampleTests.m index d87654d99..0de13708a 100644 --- a/examples/default/ios/InstabugTests/InstabugSampleTests.m +++ b/examples/default/ios/InstabugTests/InstabugSampleTests.m @@ -78,7 +78,7 @@ - (void)testInit { [self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception codePushVersion:codePushVersion]; OCMVerify([mock setCodePushVersion:codePushVersion]); - OCMVerify([self.mRNInstabug initWithToken:appToken invocationEvents:floatingButtonInvocationEvent debugLogsLevel:sdkDebugLogsLevel]); + OCMVerify([self.mRNInstabug initWithToken:appToken invocationEvents:floatingButtonInvocationEvent debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception]); } - (void)testSetUserData {