diff --git a/CHANGELOG.md b/CHANGELOG.md index e6d4c84694..854b0febd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - Add support for tracing network requests from Instabug to services like Datadog and New Relic ([#1288](https://github.com/Instabug/Instabug-React-Native/pull/1288)) +- Add support enable/disable the automatic masking of sensitive information in network logs. ([#1314](https://github.com/Instabug/Instabug-React-Native/pull/1314)) + ## [14.0.0](https://github.com/Instabug/Instabug-React-Native/compare/v13.4.0...14.0.0) (November 19, 2024) ### Added diff --git a/RNInstabug.podspec b/RNInstabug.podspec index 40c480f4cb..5ae59ff4ef 100644 --- a/RNInstabug.podspec +++ b/RNInstabug.podspec @@ -16,5 +16,6 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm}" s.dependency 'React-Core' - use_instabug!(s) + # use_instabug!(s) + s.dependency 'Instabug' end diff --git a/android/native.gradle b/android/native.gradle index ca10ca83b8..4e1631f54f 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '14.0.0' + version: '14.0.0.6423071-SNAPSHOT' ] dependencies { diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java index 9c901cb7a5..770bdabbb6 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java @@ -1157,6 +1157,27 @@ public void run() { }); } /** + * Enables or disables network logs sensitive information auto masking. + * @param isEnabled A boolean to enable/disable auto masking. + */ + @ReactMethod + public void setAutoMaskingEnabled(final boolean isEnabled) { + MainThreadHandler.runOnMainThread(new Runnable() { + @Override + public void run() { + try { + if(isEnabled) + Instabug.setNetworkAutoMaskingState(Feature.State.ENABLED); + else + Instabug.setNetworkAutoMaskingState(Feature.State.DISABLED); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** * Register a listener for W3C flags value change */ @ReactMethod @@ -1186,8 +1207,7 @@ public void invoke(@NonNull CoreFeaturesState featuresState) { }); } - - + /** * Get first time Value of W3ExternalTraceID flag */ diff --git a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java index e8aad5b0c5..96bc3930a0 100644 --- a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java +++ b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java @@ -638,6 +638,25 @@ public void testWillRedirectToStore() { // then mockInstabug.verify(() -> Instabug.willRedirectToStore()); } + + @Test + public void testEnableAutoMasking() { + // when + rnModule.setAutoMaskingEnabled(true); + + // then + mockInstabug.verify(() -> Instabug.setNetworkAutoMaskingState(Feature.State.ENABLED)); + } + + @Test + public void testDisableAutoMasking() { + // when + rnModule.setAutoMaskingEnabled(false); + + // then + mockInstabug.verify(() -> Instabug.setNetworkAutoMaskingState(Feature.State.DISABLED)); + } + @Test public void testW3CExternalTraceIDFlag(){ Promise promise = mock(Promise.class); diff --git a/examples/default/ios/InstabugTests/InstabugSampleTests.m b/examples/default/ios/InstabugTests/InstabugSampleTests.m index 8744ce4eb8..801e5f2596 100644 --- a/examples/default/ios/InstabugTests/InstabugSampleTests.m +++ b/examples/default/ios/InstabugTests/InstabugSampleTests.m @@ -550,6 +550,15 @@ - (void)testRemoveAllFeatureFlags { OCMVerify([mock removeAllFeatureFlags]); } +- (void)testSetAutoMaskingEnabled { + id mock = OCMClassMock([IBGNetworkLogger class]); + BOOL isEnabled = true; + + OCMStub([mock setAutoMaskingEnabled:isEnabled]); + [self.instabugBridge setAutoMaskingEnabled:isEnabled]; + OCMVerify([mock setAutoMaskingEnabled:isEnabled]); +} + - (void) testIsW3ExternalTraceIDEnabled { id mock = OCMClassMock([IBGNetworkLogger class]); diff --git a/examples/default/ios/Podfile b/examples/default/ios/Podfile index 3526171cd4..b2c55d8276 100644 --- a/examples/default/ios/Podfile +++ b/examples/default/ios/Podfile @@ -15,7 +15,7 @@ target 'InstabugExample' do config = use_native_modules! rn_maps_path = '../node_modules/react-native-maps' pod 'react-native-google-maps', :path => rn_maps_path - # Flags change depending on the env values. + pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/feature-MOB-16539-NetworkConfigHandler/14.0.0/Instabug.podspec' # Flags change depending on the env values. flags = get_default_flags() use_react_native!( diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 81ba100a5a..5c238f218b 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -1603,7 +1603,7 @@ PODS: - ReactCommon/turbomodule/core - Yoga - RNInstabug (14.0.0): - - Instabug (= 14.0.0) + - Instabug - React-Core - RNReanimated (3.16.1): - DoubleConversion @@ -1747,6 +1747,7 @@ DEPENDENCIES: - fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - Instabug (from `https://ios-releases.instabug.com/custom/feature-MOB-16539-NetworkConfigHandler/14.0.0/Instabug.podspec`) - instabug-reactnative-ndk (from `../node_modules/instabug-reactnative-ndk`) - OCMock - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -1825,7 +1826,6 @@ SPEC REPOS: trunk: - Google-Maps-iOS-Utils - GoogleMaps - - Instabug - OCMock - SocketRocket @@ -1843,6 +1843,8 @@ EXTERNAL SOURCES: hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-2024-08-15-RNv0.75.1-4b3bf912cc0f705b51b71ce1a5b8bd79b93a451b + Instabug: + :podspec: https://ios-releases.instabug.com/custom/feature-MOB-16539-NetworkConfigHandler/14.0.0/Instabug.podspec instabug-reactnative-ndk: :path: "../node_modules/instabug-reactnative-ndk" RCT-Folly: @@ -1993,7 +1995,7 @@ SPEC CHECKSUMS: Google-Maps-iOS-Utils: f77eab4c4326d7e6a277f8e23a0232402731913a GoogleMaps: 032f676450ba0779bd8ce16840690915f84e57ac hermes-engine: ea92f60f37dba025e293cbe4b4a548fd26b610a0 - Instabug: a0beffc01658773e2fac549845782f8937707dc4 + Instabug: d727e5d85ca7ae8571eeb0754086a2df7b096b19 instabug-reactnative-ndk: d765ac289d56e8896398d02760d9abf2562fc641 OCMock: 589f2c84dacb1f5aaf6e4cec1f292551fe748e74 RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740 @@ -2059,7 +2061,7 @@ SPEC CHECKSUMS: ReactCommon: 6a952e50c2a4b694731d7682aaa6c79bc156e4ad RNCClipboard: 2821ac938ef46f736a8de0c8814845dde2dcbdfb RNGestureHandler: 511250b190a284388f9dd0d2e56c1df76f14cfb8 - RNInstabug: eaa8cde2bcd3c8e757c6dd5c0d33a20814f9658a + RNInstabug: 520f214ffe48a265a1f4a405f535aedb87b61784 RNReanimated: f42a5044d121d68e91680caacb0293f4274228eb RNScreens: c7ceced6a8384cb9be5e7a5e88e9e714401fd958 RNSVG: 8b1a777d54096b8c2a0fd38fc9d5a454332bbb4d @@ -2067,6 +2069,6 @@ SPEC CHECKSUMS: SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: 055f92ad73f8c8600a93f0e25ac0b2344c3b07e6 -PODFILE CHECKSUM: 63bf073bef3872df95ea45e7c9c023a331ebb3c3 +PODFILE CHECKSUM: 7831a33bb56767a6f0fcb113f32cb0d0036bc791 COCOAPODS: 1.14.0 diff --git a/ios/RNInstabug/InstabugReactBridge.h b/ios/RNInstabug/InstabugReactBridge.h index bca04ddfd0..bac1797efe 100644 --- a/ios/RNInstabug/InstabugReactBridge.h +++ b/ios/RNInstabug/InstabugReactBridge.h @@ -138,4 +138,5 @@ w3cExternalTraceAttributes:(NSDictionary * _Nullable)w3cExternalTraceAttributes; - (void)addFeatureFlags:(NSDictionary *)featureFlagsMap; - (void)removeFeatureFlags:(NSArray *)featureFlags; - (void)removeAllFeatureFlags; +- (void)setAutoMaskingEnabled:(BOOL)isEnabled; @end diff --git a/ios/RNInstabug/InstabugReactBridge.m b/ios/RNInstabug/InstabugReactBridge.m index e7ca15600e..93dfd53af4 100644 --- a/ios/RNInstabug/InstabugReactBridge.m +++ b/ios/RNInstabug/InstabugReactBridge.m @@ -402,6 +402,9 @@ - (dispatch_queue_t)methodQueue { RCT_EXPORT_METHOD(willRedirectToStore){ [Instabug willRedirectToAppStore]; } +RCT_EXPORT_METHOD(setAutoMaskingEnabled:(BOOL)isEnabled) { + IBGNetworkLogger.autoMaskingEnabled = isEnabled; +} RCT_EXPORT_METHOD(isW3ExternalTraceIDEnabled:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject) { resolve(@(IBGNetworkLogger.w3ExternalTraceIDEnabled)); diff --git a/src/modules/NetworkLogger.ts b/src/modules/NetworkLogger.ts index 67f3a54ccf..574514ba24 100644 --- a/src/modules/NetworkLogger.ts +++ b/src/modules/NetworkLogger.ts @@ -3,6 +3,7 @@ import type { RequestHandler } from '@apollo/client'; import InstabugConstants from '../utils/InstabugConstants'; import xhr, { NetworkData, ProgressCallback } from '../utils/XhrNetworkInterceptor'; import { reportNetworkLog, isContentTypeNotAllowed } from '../utils/InstabugUtils'; +import { NativeInstabug } from '../native/NativeInstabug'; export type { NetworkData }; @@ -101,3 +102,12 @@ export const apolloLinkRequestHandler: RequestHandler = (operation, forward) => return forward(operation); }; + +/** + * Sets whether network logs sensitive information should be masked. + * It is disabled by default. + * @param isEnabled + */ +export const setAutoMaskingEnabled = (isEnabled: boolean) => { + NativeInstabug.setAutoMaskingEnabled(isEnabled); +}; diff --git a/src/native/NativeInstabug.ts b/src/native/NativeInstabug.ts index 5f0628ef71..7960cb2526 100644 --- a/src/native/NativeInstabug.ts +++ b/src/native/NativeInstabug.ts @@ -72,6 +72,7 @@ export interface InstabugNativeModule extends NativeModule { ): void; setNetworkLoggingEnabled(isEnabled: boolean): void; + setAutoMaskingEnabled(isEnabled: boolean): void; // Repro Steps APIs // setReproStepsConfig( diff --git a/test/mocks/mockInstabug.ts b/test/mocks/mockInstabug.ts index 7b3cf2e695..cb13f7e897 100644 --- a/test/mocks/mockInstabug.ts +++ b/test/mocks/mockInstabug.ts @@ -69,6 +69,7 @@ const mockInstabug: InstabugNativeModule = { addFileAttachmentWithDataToReport: jest.fn(), setNetworkLoggingEnabled: jest.fn(), willRedirectToStore: jest.fn(), + setAutoMaskingEnabled: jest.fn(), isW3ExternalTraceIDEnabled: jest.fn(), isW3ExternalGeneratedHeaderEnabled: jest.fn(), isW3CaughtHeaderEnabled: jest.fn(), diff --git a/test/modules/NetworkLogger.spec.ts b/test/modules/NetworkLogger.spec.ts index be258d7403..335be9e0ce 100644 --- a/test/modules/NetworkLogger.spec.ts +++ b/test/modules/NetworkLogger.spec.ts @@ -7,6 +7,7 @@ import * as NetworkLogger from '../../src/modules/NetworkLogger'; import Interceptor from '../../src/utils/XhrNetworkInterceptor'; import { isContentTypeNotAllowed, reportNetworkLog } from '../../src/utils/InstabugUtils'; import InstabugConstants from '../../src/utils/InstabugConstants'; +import { NativeInstabug } from '../../src/native/NativeInstabug'; const clone = (obj: T): T => { return JSON.parse(JSON.stringify(obj)); @@ -281,4 +282,11 @@ describe('NetworkLogger Module', () => { expect(reportNetworkLog).toHaveBeenCalledWith(networkData); }); + + it('should call the native method setAutoMaskingEnabled', () => { + NetworkLogger.setAutoMaskingEnabled(true); + + expect(NativeInstabug.setAutoMaskingEnabled).toBeCalledTimes(1); + expect(NativeInstabug.setAutoMaskingEnabled).toBeCalledWith(true); + }); });