Skip to content

feat: support switching to native network interception #1120

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 4 commits into from
Feb 6, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
5 changes: 3 additions & 2 deletions examples/default/ios/InstabugTests/InstabugSampleTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,15 @@ - (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]);
OCMVerify([self.mRNInstabug initWithToken:appToken invocationEvents:floatingButtonInvocationEvent debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception]);
}

- (void)testSetUserData {
Expand Down
13 changes: 13 additions & 0 deletions examples/default/ios/InstabugTests/RNInstabugTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion ios/RNInstabug/InstabugReactBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 3 additions & 1 deletion ios/RNInstabug/InstabugReactBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions ios/RNInstabug/RNInstabug.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down
21 changes: 17 additions & 4 deletions ios/RNInstabug/RNInstabug.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand All @@ -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 {
Expand Down
13 changes: 12 additions & 1 deletion src/models/InstabugConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { InvocationEvent, LogLevel } from '../utils/Enums';
import type { InvocationEvent, LogLevel, NetworkInterceptionMode } from '../utils/Enums';

export interface InstabugConfig {
/**
Expand All @@ -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;
}
10 changes: 9 additions & 1 deletion src/modules/Instabug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ColorTheme,
Locale,
LogLevel,
NetworkInterceptionMode,
ReproStepsMode,
StringKey,
WelcomeMessageMode,
Expand Down Expand Up @@ -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,
);

Expand Down
1 change: 1 addition & 0 deletions src/native/NativeInstabug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface InstabugNativeModule extends NativeModule {
token: string,
invocationEvents: InvocationEvent[],
debugLogsLevel: LogLevel,
useNativeNetworkInterception: boolean,
codePushVersion?: string,
): void;
show(): void;
Expand Down
8 changes: 8 additions & 0 deletions src/utils/Enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
1 change: 1 addition & 0 deletions test/mocks/mockNetworkLogger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jest.mock('../../src/modules/NetworkLogger');
30 changes: 30 additions & 0 deletions test/modules/Instabug.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import '../mocks/mockInstabugUtils';
import '../mocks/mockNetworkLogger';

import { Platform, findNodeHandle, processColor } from 'react-native';

Expand All @@ -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,
Expand Down Expand Up @@ -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,
);
});
Expand Down