Skip to content

Commit 82df001

Browse files
chore: add request filtering & obfuscation react-native logic
1 parent 16140ef commit 82df001

File tree

7 files changed

+209
-21
lines changed

7 files changed

+209
-21
lines changed

android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,4 +1167,57 @@ public Map<String, Object> getConstants() {
11671167

11681168
return constants;
11691169
}
1170+
1171+
// private final ConcurrentHashMap<Integer, OnCompleteCallback<NetworkLogSnapshot>> callbackMap = new ConcurrentHashMap<Integer, OnCompleteCallback<NetworkLogSnapshot>>();
1172+
//
1173+
// @ReactMethod
1174+
// public void registerNetworkLogsListener() {
1175+
// MainThreadHandler.runOnMainThread(new Runnable() {
1176+
// @Override
1177+
// public void run() {
1178+
// InternalAPM._registerNetworkLogSanitizer(new VoidSanitizer<NetworkLogSnapshot>() {
1179+
// @Override
1180+
// public void sanitize(NetworkLogSnapshot networkLogSnapshot, @NonNull OnCompleteCallback<NetworkLogSnapshot> onCompleteCallback) {
1181+
// final int id = onCompleteCallback.hashCode();
1182+
// callbackMap.put(id, onCompleteCallback);
1183+
//
1184+
// WritableMap networkSnapshotParams = Arguments.createMap();
1185+
// networkSnapshotParams.putInt("id", id);
1186+
// networkSnapshotParams.putString("url", networkLogSnapshot.getUrl());
1187+
// networkSnapshotParams.putInt("responseCode", networkLogSnapshot.getResponseCode());
1188+
//
1189+
// sendEvent("IBGNetworkLoggerHandler", networkSnapshotParams);
1190+
//
1191+
// }
1192+
// });
1193+
// }
1194+
// });
1195+
// }
1196+
//
1197+
// @ReactMethod
1198+
// protected void updateNetworkLogSnapshot(String jsonString) {
1199+
//
1200+
// JSONObject newJSONObject = null;
1201+
// try {
1202+
// newJSONObject = new JSONObject(jsonString);
1203+
// } catch (JSONException e) {
1204+
// throw new RuntimeException(e);
1205+
// }
1206+
// final Integer ID = newJSONObject.optInt("id");
1207+
// final NetworkLogSnapshot modifiedSnapshot = new NetworkLogSnapshot(
1208+
// newJSONObject.optString("url"),
1209+
// null,
1210+
// null,
1211+
// null,
1212+
// null,
1213+
// newJSONObject.optInt("responseCode")
1214+
// );
1215+
//
1216+
// final OnCompleteCallback<NetworkLogSnapshot> callback = callbackMap.get(ID);
1217+
// if (callback != null) {
1218+
// callback.onComplete(null);
1219+
// }
1220+
// callbackMap.remove(ID);
1221+
//
1222+
// }
11701223
}

examples/default/src/App.tsx

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import React, { useEffect } from 'react';
22
import { StyleSheet } from 'react-native';
33

44
import { GestureHandlerRootView } from 'react-native-gesture-handler';
5-
import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
5+
import { NavigationContainer } from '@react-navigation/native';
66
import Instabug, {
77
CrashReporting,
88
InvocationEvent,
99
LogLevel,
1010
NetworkInterceptionMode,
11+
NetworkLogger,
1112
ReproStepsMode,
1213
} from 'instabug-reactnative';
1314
import { NativeBaseProvider } from 'native-base';
@@ -16,40 +17,62 @@ import { RootTabNavigator } from './navigation/RootTab';
1617
import { nativeBaseTheme } from './theme/nativeBaseTheme';
1718
import { navigationTheme } from './theme/navigationTheme';
1819

19-
import { QueryClient, QueryClientProvider } from 'react-query';
20+
// import { QueryClient } from 'react-query';
21+
import {
22+
ApolloClient,
23+
ApolloLink,
24+
ApolloProvider,
25+
from,
26+
HttpLink,
27+
InMemoryCache,
28+
} from '@apollo/client';
29+
// import { NativeInstabug } from '../../../src/native/NativeInstabug';
30+
//
31+
// const queryClient = new QueryClient();
2032

21-
const queryClient = new QueryClient();
33+
//Setting up the handler
34+
const IBGApolloLink = new ApolloLink(NetworkLogger.apolloLinkRequestHandler);
35+
36+
//Sample code
37+
const httpLink = new HttpLink({ uri: 'https://countries.trevorblades.com/graphql' });
38+
const apolloQueryClient = new ApolloClient({
39+
cache: new InMemoryCache(),
40+
link: from([IBGApolloLink, httpLink]),
41+
});
2242

2343
export const App: React.FC = () => {
24-
const navigationRef = useNavigationContainerRef();
2544
useEffect(() => {
2645
Instabug.init({
27-
token: 'deb1910a7342814af4e4c9210c786f35',
46+
// token: 'deb1910a7342814af4e4c9210c786f35',
47+
token: '0fcc87b8bf731164828cc411eccc802a',
2848
invocationEvents: [InvocationEvent.floatingButton],
2949
debugLogsLevel: LogLevel.verbose,
3050
networkInterceptionMode: NetworkInterceptionMode.native,
3151
});
3252
CrashReporting.setNDKCrashesEnabled(true);
3353

54+
// NetworkLogger.setNetworkDataObfuscationHandler(async (networkData) => {
55+
// networkData.url = `${networkData.url}/RN/obfuscated`;
56+
// return networkData;
57+
// });
58+
59+
// NetworkLogger.setRequestFilterExpression('true');
60+
3461
Instabug.setReproStepsConfig({
3562
all: ReproStepsMode.enabled,
3663
});
3764
}, []);
3865

39-
useEffect(() => {
40-
const unregisterListener = Instabug.setNavigationListener(navigationRef);
41-
42-
return unregisterListener;
43-
}, [navigationRef]);
44-
4566
return (
4667
<GestureHandlerRootView style={styles.root}>
4768
<NativeBaseProvider theme={nativeBaseTheme}>
48-
<QueryClientProvider client={queryClient}>
49-
<NavigationContainer theme={navigationTheme} ref={navigationRef}>
69+
{/*<QueryClientProvider client={queryClient}>*/}
70+
<ApolloProvider client={apolloQueryClient}>
71+
<NavigationContainer onStateChange={Instabug.onStateChange} theme={navigationTheme}>
5072
<RootTabNavigator />
5173
</NavigationContainer>
52-
</QueryClientProvider>
74+
</ApolloProvider>
75+
{/*</QueryClientProvider>*/}
5376
</NativeBaseProvider>
5477
</GestureHandlerRootView>
5578
);

ios/RNInstabug/InstabugAPMBridge.m

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ - (id) init
115115
@try {
116116
// Assuming you want to return YES for now, wrapped in NSNumber
117117
resolve(@(YES));
118-
119-
120118
} @catch (NSError *error) {
121119
reject(@"error_code", @"An error occurred", error);
122120
}

ios/RNInstabug/InstabugReactBridge.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@
123123
gqlQueryName:(NSString * _Nullable)gqlQueryName
124124
serverErrorMessage:(NSString * _Nullable)serverErrorMessage;
125125

126+
// - (void) registerNetworkLogsListener;
127+
//
128+
// - (void) updateNetworkLogSnapshot: (NSString * _Nonnull)jsonString;
129+
//
130+
// - (void) setNetworkLoggingRequestFilterPredicateIOS:(BOOL)value;
131+
126132
/*
127133
+------------------------------------------------------------------------+
128134
| Experiments |

ios/RNInstabug/InstabugReactBridge.m

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ + (void)setWillSendReportHandler_private:(void(^)(IBGReport *report, void(^repor
2323
@implementation InstabugReactBridge
2424

2525
- (NSArray<NSString *> *)supportedEvents {
26-
return @[@"IBGpreSendingHandler"];
26+
return @[@"IBGpreSendingHandler" , @"IBGNetworkLoggerHandler"];
2727
}
2828

2929
RCT_EXPORT_MODULE(Instabug)
@@ -317,6 +317,75 @@ - (dispatch_queue_t)methodQueue {
317317
serverErrorMessage:serverErrorMessage];
318318
}
319319

320+
// RCT_EXPORT_METHOD(registerNetworkLogsListener){
321+
// [IBGNetworkLogger setRequestObfuscationHandlerV2:^(NSURLRequest * _Nonnull request, void (^ _Nonnull completionHandler)(NSURLRequest * _Nonnull)) {
322+
// NSString *tempId = [[[NSUUID alloc] init] UUIDString];
323+
// self.dictionary[tempId] = completionHandler;
324+
//
325+
// // Ensure the URL, HTTP body, and headers are in the correct format
326+
// NSString *urlString = request.URL.absoluteString ?: @"";
327+
// NSString *bodyString = [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding] ?: @"";
328+
// NSDictionary *headerDict = request.allHTTPHeaderFields ?: @{};
329+
//
330+
// // Create the dictionary to send
331+
// NSDictionary *dict = @{
332+
// @"tempId": tempId,
333+
// @"url": urlString,
334+
// @"requestBody": bodyString,
335+
// @"requestHeader": headerDict
336+
// };
337+
//
338+
// // Send the event
339+
// [self sendEventWithName:@"IBGNetworkLoggerHandler" body:dict];
340+
//
341+
// }];
342+
// }
343+
//
344+
// RCT_EXPORT_METHOD(updateNetworkLogSnapshot:(NSString * _Nonnull)jsonString) {
345+
// // Properly initialize the NSMutableURLRequest
346+
// NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
347+
//
348+
// // Convert jsonString to NSData
349+
// NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
350+
//
351+
// // Parse the JSON into a dictionary
352+
// NSError *error = nil;
353+
// NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
354+
//
355+
// // Check for JSON parsing errors
356+
// if (error) {
357+
// NSLog(@"Failed to parse JSON: %@", error);
358+
// return;
359+
// }
360+
//
361+
// // Set the URL, HTTP body, and headers
362+
// request.URL = [NSURL URLWithString:dict[@"url"]];
363+
// request.HTTPBody = [dict[@"requestBody"] dataUsingEncoding:NSUTF8StringEncoding];
364+
//
365+
// // Ensure requestHeader is a dictionary
366+
// if ([dict[@"requestHeader"] isKindOfClass:[NSDictionary class]]) {
367+
// request.allHTTPHeaderFields = dict[@"requestHeader"];
368+
// } else {
369+
// NSLog(@"Invalid requestHeader format");
370+
// // return;
371+
// }
372+
//
373+
// // Ensure self.completion is not nil before calling it
374+
// NSString *tempId = dict[@"tempId"];
375+
// if ([tempId isKindOfClass:[NSString class]] && self.dictionary[tempId] != nil) {
376+
// ((IBGURLRequestObfuscationHandler)self.dictionary[tempId])(request);
377+
// } else {
378+
// NSLog(@"Not Available Completion");
379+
// }
380+
// }
381+
//
382+
// RCT_EXPORT_METHOD(setNetworkLoggingRequestFilterPredicateIOS: (BOOL)value){
383+
//
384+
// NSPredicate *requestPredicate = [NSPredicate predicateWithValue:(value) ? YES : NO];
385+
//
386+
// [IBGNetworkLogger setNetworkLoggingRequestFilterPredicate:requestPredicate responseFilterPredicate:nil];
387+
// }
388+
320389
RCT_EXPORT_METHOD(addPrivateView: (nonnull NSNumber *)reactTag) {
321390
UIView* view = [self.bridge.uiManager viewForReactTag:reactTag];
322391
view.instabug_privateView = true;
@@ -364,7 +433,7 @@ - (dispatch_queue_t)methodQueue {
364433
[featureFlags addObject:[[IBGFeatureFlag alloc] initWithName:key variant:variant]];
365434
}
366435
}
367-
436+
368437
[Instabug addFeatureFlags:featureFlags];
369438
}
370439

@@ -373,7 +442,7 @@ - (dispatch_queue_t)methodQueue {
373442
for(id item in featureFlags){
374443
[features addObject:[[IBGFeatureFlag alloc] initWithName:item]];
375444
}
376-
445+
377446
@try {
378447
[Instabug removeFeatureFlags:features];
379448
}

src/modules/NetworkLogger.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { RequestHandler } from '@apollo/client';
22

33
import InstabugConstants from '../utils/InstabugConstants';
44
import xhr, { NetworkData, ProgressCallback } from '../utils/XhrNetworkInterceptor';
5-
import { reportNetworkLog, isContentTypeNotAllowed } from '../utils/InstabugUtils';
5+
import { isContentTypeNotAllowed, reportNetworkLog } from '../utils/InstabugUtils';
66

77
export type { NetworkData };
88

@@ -70,6 +70,19 @@ export const setNetworkDataObfuscationHandler = (
7070
handler?: NetworkDataObfuscationHandler | null | undefined,
7171
) => {
7272
_networkDataObfuscationHandler = handler;
73+
74+
// if (isNativeInterceptionEnabled) {
75+
// registerNetworkLogsListener(async (networkSnapshot) => {
76+
// console.log(
77+
// `Andrew: new snapshot from setNetworkDataObfuscationHandler: ${networkSnapshot.url}`,
78+
// );
79+
//
80+
// if (_networkDataObfuscationHandler) {
81+
// networkSnapshot = await _networkDataObfuscationHandler(networkSnapshot);
82+
// }
83+
// NativeInstabug.updateNetworkLogSnapshot(JSON.stringify(networkSnapshot));
84+
// });
85+
// }
7386
};
7487

7588
/**
@@ -78,6 +91,23 @@ export const setNetworkDataObfuscationHandler = (
7891
*/
7992
export const setRequestFilterExpression = (expression: string) => {
8093
_requestFilterExpression = expression;
94+
95+
// if (isNativeInterceptionEnabled) {
96+
// registerNetworkLogsListener(async (networkSnapshot) => {
97+
// console.log(`Andrew: new snapshot from setRequestFilterExpression: ${networkSnapshot.url}`);
98+
// // eslint-disable-next-line no-new-func
99+
// const predicate = Function('network', 'return ' + _requestFilterExpression);
100+
// const value = predicate(networkSnapshot);
101+
// if (Platform.OS === 'ios') {
102+
// NativeInstabug.setNetworkLoggingRequestFilterPredicateIOS(value);
103+
// } else {
104+
// // set android request url to null ;
105+
// if (value) {
106+
// NativeInstabug.updateNetworkLogSnapshot('');
107+
// }
108+
// }
109+
// });
110+
// }
81111
};
82112

83113
/**

src/native/NativeAPM.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { NativeModule } from 'react-native';
1+
import { NativeEventEmitter, type NativeModule } from 'react-native';
22

33
import { NativeModules } from './NativePackage';
44

@@ -25,6 +25,9 @@ export interface ApmNativeModule extends NativeModule {
2525
gqlQueryName?: string,
2626
serverErrorMessage?: string,
2727
): void;
28+
// registerNetworkLogsListener(): void;
29+
// updateNetworkLogSnapshot(networkData: string): void;
30+
// setNetworkLoggingRequestFilterPredicateIOS(value: boolean): void;
2831

2932
// App Launches APIs //
3033
setAppLaunchEnabled(isEnabled: boolean): void;
@@ -53,3 +56,9 @@ export interface ApmNativeModule extends NativeModule {
5356
}
5457

5558
export const NativeAPM = NativeModules.IBGAPM;
59+
60+
export enum NativeAPMEvent {
61+
NETWORK_LOGGER_HANDLER = 'IBGNetworkLoggerHandler',
62+
}
63+
64+
export const APMEmitter = new NativeEventEmitter(NativeAPM);

0 commit comments

Comments
 (0)