Skip to content
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
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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: you don't need _Nullable or _Nonnull in the implementation. Everything should be treated as nullable (because technically they are in Objc), and then we code in a safe way based on this.

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