diff --git a/README.md b/README.md index 9b2412a..98d45e0 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ This React Native bridge supports React Native app builds with version `0.61.5` - [Screenshot](#screenshot) - [Submit the results of the form](#submit-the-results-of-the-form) - [Feedback submission callback](#feedback-submission-callback) + - [Masking Private Identifiable Information](#masking-private-identifiable-information) - [Custom Variables](#custom-variables) - [Localization](#localization) - [Installation steps for React Native without Auto-Linking](#installation-steps-for-react-native-without-auto-linking) @@ -345,6 +346,40 @@ If you close a feedback form with `onBackPressed()`, then the **response** will **sent**: false **abandonedpageindex**: -1 +## Masking Private Identifiable Information + +The SDK has an option to mask (on the back-end side) the data from input texts, specifically `Text Input` and `Text Area`. Please note that the an email input field is not being masked. + +It matches a list of RegEx and replaces them by the "X" character by default. + +The SDK has a `setDataMasking` method that can be used as: +``` +usabilla.setDataMasking(); +usabilla.setDataMasking([String]); +usabilla.setDataMasking([String], String); +``` +**1st parameter - [String] `masks`** is a list of RegExes to mask data in input fields. It uses the default RegExes that the SDK provides. +**2nd parameter - String `maskCharacter`** is a character to replace the matched RegExes. By default it uses 'X'. + +**NOTE**: **To clear / remove data masking** use `usabilla.setDataMasking(masks: [])` empty array `masks` removes the data masking feature. + +The default RegExes that the SDK provides are: Email Addresses & Numbers + +For email it uses: +``` +[a-zA-Z0-9\+\.\_\%\-\+]{1,256}\@[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}(\.[a-zA-Z0-9][a-zA-Z0-9\-]{0,25})+ +``` +For Numbers with the length 4 or more +``` +[0-9]{4,} +``` +The default RegEx can be accessed by: + +``` +usabilla.getDefaultDataMasks(); +``` + + ## Custom Variables In order to set custom variables in the Usabilla native library it's necessary to call the method: diff --git a/android/src/main/java/com/usabilla/reactnative/ubform/UsabillaBridge.java b/android/src/main/java/com/usabilla/reactnative/ubform/UsabillaBridge.java index bfbf371..c474610 100644 --- a/android/src/main/java/com/usabilla/reactnative/ubform/UsabillaBridge.java +++ b/android/src/main/java/com/usabilla/reactnative/ubform/UsabillaBridge.java @@ -38,10 +38,10 @@ public class UsabillaBridge extends ReactContextBaseJavaModule implements UsabillaFormCallback, LifecycleEventListener { public static final String FRAGMENT_TAG = "passive form"; - + private static final String LOG_TAG = "Usabilla React Bridge"; private static final String DEFAULT_DATA_MASKS = "DEFAULT_DATA_MASKS"; - + private static final String DEFAULT_MASK_CHARACTER = "X"; private static final String KEY_RATING = "rating"; private static final String KEY_ABANDONED_PAGE_INDEX = "abandonedPageIndex"; private static final String KEY_SENT = "sent"; @@ -129,7 +129,7 @@ public String getName() { @ReactMethod public void initialize(@NonNull String appId) { final Activity activity = getCurrentActivity(); - if (activity != null) { + if (activity != null) { usabilla.initialize(activity.getBaseContext(), appId); usabilla.updateFragmentManager(((FragmentActivity) activity).getSupportFragmentManager()); return; @@ -258,12 +258,18 @@ public boolean dismiss() { * Called via the index.js to mask sensitive information from the feedback before sending it */ @ReactMethod - public void setDataMasking(@NonNull final ReadableArray masks, @NonNull final String character) { - List listMasks = new ArrayList<>(); - for (int i = 0; i < masks.size(); i++) { - listMasks.add(masks.getString(i)); + public void setDataMasking(final @Nullable ReadableArray masks, final @Nullable String character) { + List listMasks = null; + if (masks == null) { + listMasks = UbConstants.getDefaultDataMasks(); + } else { + listMasks = new ArrayList<>(masks.size()); + for (int i = 0; i < masks.size(); i++) { + listMasks.add(masks.getString(i)); + } } - usabilla.setDataMasking(listMasks, character.charAt(0)); + String maskChar = (character != null) ? character : DEFAULT_MASK_CHARACTER; + usabilla.setDataMasking(listMasks, maskChar.charAt(0)); } @Override diff --git a/ios/ReactNativeUsabilla/ReactNativeUsabilla.m b/ios/ReactNativeUsabilla/ReactNativeUsabilla.m index 33e93c9..4cf3984 100644 --- a/ios/ReactNativeUsabilla/ReactNativeUsabilla.m +++ b/ios/ReactNativeUsabilla/ReactNativeUsabilla.m @@ -22,7 +22,7 @@ + (BOOL)requiresMainQueueSetup RCT_EXTERN_METHOD(setDebugEnabled:(BOOL * _Nonnull)debugEnabled) RCT_EXTERN_METHOD(loadLocalizedStringFile:(NSString * _Nullable)localizedStringFile) RCT_EXTERN_METHOD(loadFeedbackForm:(NSString * _Nullable)formID) -RCT_EXTERN_METHOD(setDataMasking:(NSArray*)masks : (NSString *)maskChar) +RCT_EXTERN_METHOD(setDataMasking:(NSArray* _Nullable)masks : (NSString * _Nullable)maskChar) RCT_EXTERN_METHOD(setCustomVariables:(NSDictionary * _Nonnull)variables) RCT_EXTERN_METHOD(loadFeedbackFormWithCurrentViewScreenshot:(NSString * _Nonnull)formID) RCT_EXTERN_METHOD(preloadFeedbackForms:(NSArray*)formIDs) diff --git a/ios/ReactNativeUsabilla/UsabillaBridge.swift b/ios/ReactNativeUsabilla/UsabillaBridge.swift index d12a162..3fd5097 100644 --- a/ios/ReactNativeUsabilla/UsabillaBridge.swift +++ b/ios/ReactNativeUsabilla/UsabillaBridge.swift @@ -112,11 +112,10 @@ class UsabillaBridge: RCTEventEmitter { } @objc(setDataMasking::) - func setDataMasking(_ masks: [String], _ maskChar: String) { - guard let maskCharacter = maskChar.first else { Usabilla.setDataMasking(masks: Usabilla.defaultDataMasks, maskCharacter: "X") - return - } - Usabilla.setDataMasking(masks: masks, maskCharacter: maskCharacter) + func setDataMasking(_ masks: [String]?, _ maskChar: String?) { + let mask = masks ?? Usabilla.defaultDataMasks + let maskCharacter = maskChar?.first ?? "X" + Usabilla.setDataMasking(masks: mask, maskCharacter: maskCharacter) } } diff --git a/src/index.d.ts b/src/index.d.ts index e6d30c5..376e29f 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -19,7 +19,7 @@ declare module 'usabilla-react-native' { setFormDidFailLoading: (callback: (...args: any[]) => any) => void; setCampaignDidClose: (callback: (...args: any[]) => any) => void; dismiss: () => void; - setDataMasking: (masks: string[], character: string) => void; + setDataMasking: (masks?: string[], character?: string) => void; getDefaultDataMasks: () => string[]; };