Skip to content

Commit

Permalink
fix(replay): Mask SVGs from react-native-svg when `maskAllVectors=t…
Browse files Browse the repository at this point in the history
…rue` (#3930)
  • Loading branch information
krystofwoldrich authored Jul 10, 2024
1 parent 6fd2a34 commit 3dcf57b
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Redact `react-native-svg` SVGs when `maskAllVectors` ([#3930](https://github.com/getsentry/sentry-react-native/pull/3930))
- Set `currentScreen` on native scope ([#3927](https://github.com/getsentry/sentry-react-native/pull/3927))
- Add `annotateReactComponents` option to `@sentry/react-native/metro` ([#3916](https://github.com/getsentry/sentry-react-native/pull/3916))

Expand Down
7 changes: 7 additions & 0 deletions android/src/main/java/io/sentry/react/RNSentryModuleImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

import io.sentry.Breadcrumb;
Expand Down Expand Up @@ -326,6 +328,11 @@ private SentryReplayOptions getReplayOptions(@NotNull ReadableMap rnOptions) {
androidReplayOptions.setRedactAllText(!rnMobileReplayOptions.hasKey("maskAllText") || rnMobileReplayOptions.getBoolean("maskAllText"));
androidReplayOptions.setRedactAllImages(!rnMobileReplayOptions.hasKey("maskAllImages") || rnMobileReplayOptions.getBoolean("maskAllImages"));

final boolean redactVectors = !rnMobileReplayOptions.hasKey("maskAllVectors") || rnMobileReplayOptions.getBoolean("maskAllVectors");
if (redactVectors) {
androidReplayOptions.addClassToRedact("com.horcrux.svg.SvgView"); // react-native-svg
}

return androidReplayOptions;
}

Expand Down
16 changes: 14 additions & 2 deletions ios/RNSentryReplay.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,23 @@ + (void)updateOptions:(NSMutableDictionary *)options {

+ (void)addReplayRNRedactClasses:(NSDictionary *_Nullable)replayOptions {
NSMutableArray *_Nonnull classesToRedact = [[NSMutableArray alloc] init];
if ([replayOptions[@"maskAllVectors"] boolValue] == YES) {
Class _Nullable maybeRNSVGViewClass = NSClassFromString(@"RNSVGSvgView");
if (maybeRNSVGViewClass != nil) {
[classesToRedact addObject:maybeRNSVGViewClass];
}
}
if ([replayOptions[@"maskAllImages"] boolValue] == YES) {
[classesToRedact addObject:NSClassFromString(@"RCTImageView")];
Class _Nullable maybeRCTImageClass = NSClassFromString(@"RCTImageView");
if (maybeRCTImageClass != nil) {
[classesToRedact addObject:maybeRCTImageClass];
}
}
if ([replayOptions[@"maskAllText"] boolValue] == YES) {
[classesToRedact addObject:NSClassFromString(@"RCTTextView")];
Class _Nullable maybeRCTTextClass = NSClassFromString(@"RCTTextView");
if (maybeRCTTextClass != nil) {
[classesToRedact addObject:maybeRCTTextClass];
}
}
[PrivateSentrySDKOnly addReplayRedactClasses:classesToRedact];
}
Expand Down
1 change: 1 addition & 0 deletions samples/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"react-native-reanimated": "3.8.1",
"react-native-safe-area-context": "4.8.0",
"react-native-screens": "3.29.0",
"react-native-svg": "^15.3.0",
"react-native-vector-icons": "^10.0.3",
"react-redux": "^8.1.3",
"redux": "^4.2.1"
Expand Down
3 changes: 2 additions & 1 deletion samples/react-native/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ Sentry.init({
}),
Sentry.metrics.metricsAggregatorIntegration(),
Sentry.mobileReplayIntegration({
maskAllImages: false,
maskAllImages: true,
maskAllVectors: true,
// maskAllText: false,
}),
);
Expand Down
3 changes: 3 additions & 0 deletions samples/react-native/src/Screens/PlaygroundScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SafeAreaView,
Pressable,
} from 'react-native';
import SvgGraphic from '../components/SvgGraphic';

const multilineText = `This
is
Expand Down Expand Up @@ -65,6 +66,8 @@ const PlaygroundScreen = () => {
}}>
<Text>Press me</Text>
</Pressable>
<Text>react-native-svg</Text>
<SvgGraphic />
</View>
</TouchableWithoutFeedback>
</ScrollView>
Expand Down
288 changes: 288 additions & 0 deletions samples/react-native/src/components/SvgGraphic.tsx

Large diffs are not rendered by default.

84 changes: 84 additions & 0 deletions samples/react-native/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4284,6 +4284,11 @@ bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"

boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==

brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
Expand Down Expand Up @@ -4702,6 +4707,30 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"

css-select@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
dependencies:
boolbase "^1.0.0"
css-what "^6.1.0"
domhandler "^5.0.2"
domutils "^3.0.1"
nth-check "^2.0.1"

css-tree@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
dependencies:
mdn-data "2.0.14"
source-map "^0.6.1"

css-what@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==

csstype@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
Expand Down Expand Up @@ -4847,6 +4876,36 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"

dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"

domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==

domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"

domutils@^3.0.1:
version "3.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"

[email protected]:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
Expand Down Expand Up @@ -4877,6 +4936,11 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==

entities@^4.2.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==

envinfo@^7.10.0:
version "7.11.0"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f"
Expand Down Expand Up @@ -6834,6 +6898,11 @@ marky@^1.2.2:
resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0"
integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==

[email protected]:
version "2.0.14"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==

memoize-one@^5.0.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
Expand Down Expand Up @@ -7381,6 +7450,13 @@ npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"

nth-check@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
boolbase "^1.0.0"

nullthrows@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1"
Expand Down Expand Up @@ -7910,6 +7986,14 @@ [email protected]:
react-freeze "^1.0.0"
warn-once "^0.1.0"

react-native-svg@^15.3.0:
version "15.3.0"
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.3.0.tgz#e24b833fe330714c99f1dd894bb0da52ad859a4c"
integrity sha512-mBHu/fdlzUbpGX8SZFxgbKvK/sgqLfDLP8uh8G7Us+zJgdjO8OSEeqHQs+kPRdQmdLJQiqPJX2WXgCl7ToTWqw==
dependencies:
css-select "^5.1.0"
css-tree "^1.1.3"

react-native-vector-icons@^10.0.3:
version "10.0.3"
resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-10.0.3.tgz#369824a3b17994b2cd65edbaa32dbf9540d49678"
Expand Down
13 changes: 13 additions & 0 deletions src/js/replay/mobilereplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,31 @@ export const MOBILE_REPLAY_INTEGRATION_NAME = 'MobileReplay';
export interface MobileReplayOptions {
/**
* Mask all text in recordings
*
* @default true
*/
maskAllText?: boolean;

/**
* Mask all text in recordings
*
* @default true
*/
maskAllImages?: boolean;

/**
* Mask all vector graphics in recordings
* Supports `react-native-svg`
*
* @default true
*/
maskAllVectors?: boolean;
}

const defaultOptions: Required<MobileReplayOptions> = {
maskAllText: true,
maskAllImages: true,
maskAllVectors: true,
};

type MobileReplayIntegration = IntegrationFnResult & {
Expand Down

0 comments on commit 3dcf57b

Please sign in to comment.