Skip to content

Commit dad61ef

Browse files
authored
feat: add SR support for maskAllInputs and maskInputOptions (#354)
## Summary Support additional granular masking configurations on the SDK. ## How did you test this change? CI + local deploy <img width="878" height="886" alt="image" src="https://github.com/user-attachments/assets/20d90754-4a3a-4c5f-8da5-a52815113cec" /> <img width="878" height="886" alt="image" src="https://github.com/user-attachments/assets/d2837aeb-cda5-4550-8f1c-1cf829e0e9f9" /> ## Are there any deployment considerations? <!-- Backend - Do we need to consider migrations or backfilling data? --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces configurable input masking for session replay while preserving existing defaults. > > - Adds `maskAllInputs` and `maskInputOptions` to `HighlightClassOptions`/`RecordOptions` and defines `MaskInputOptions` type > - New `determineMaskInputOptions` utility computes `maskAllInputs`/`maskInputOptions` from `privacySetting`, always masking `password` > - Wires options into `rrweb.record` in both `client/index.tsx` and `sdk/record.ts`; minor cleanup with property shorthand > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 09b7cfe. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent b1b46d3 commit dad61ef

4 files changed

Lines changed: 41 additions & 3 deletions

File tree

sdk/highlight-run/src/client/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ import { createLog, defaultLogOptions } from './listeners/console-listener'
123123
import { CustomSampler } from './otel/sampling/CustomSampler'
124124
import randomUuidV4 from './utils/randomUuidV4'
125125
import { LDContext } from '@launchdarkly/js-client-sdk'
126+
import { MaskInputOptions } from './types/record'
126127

127128
export const HighlightWarning = (context: string, msg: any) => {
128129
console.warn(`Highlight Warning: (${context}): `, { output: msg })
@@ -141,6 +142,8 @@ export type HighlightClassOptions = {
141142
reportConsoleErrors?: boolean
142143
consoleMethodsToRecord?: ConsoleMethods[]
143144
privacySetting?: PrivacySettingOption
145+
maskAllInputs?: boolean
146+
maskInputOptions?: MaskInputOptions
144147
maskTextClass?: string | RegExp
145148
maskTextSelector?: string
146149
blockClass?: string | RegExp
@@ -829,6 +832,8 @@ SessionSecureID: ${this.sessionData.sessionSecureID}`,
829832

830833
const [maskAllInputs, maskInputOptions] = determineMaskInputOptions(
831834
this.privacySetting,
835+
this.options.maskAllInputs,
836+
this.options.maskInputOptions,
832837
)
833838

834839
this._recordStop = record({

sdk/highlight-run/src/client/types/record.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@ import type {
55
SamplingStrategy,
66
} from './types'
77

8+
export type MaskInputOptions = Partial<{
9+
color: boolean
10+
date: boolean
11+
'datetime-local': boolean
12+
email: boolean
13+
month: boolean
14+
number: boolean
15+
range: boolean
16+
search: boolean
17+
tel: boolean
18+
text: boolean
19+
time: boolean
20+
url: boolean
21+
week: boolean
22+
textarea: boolean
23+
select: boolean
24+
password: boolean
25+
}>
26+
827
export type RecordOptions = CommonOptions & {
928
/**
1029
* Specifies where the backend of the app lives. If specified, the SDK will attach the
@@ -37,6 +56,16 @@ export type RecordOptions = CommonOptions & {
3756
*/
3857
privacySetting?: PrivacySettingOption
3958

59+
/**
60+
* Enable masking all <input/> elements. Only applies if privacySetting is `none`.
61+
*/
62+
maskAllInputs?: boolean
63+
64+
/**
65+
* Customize the input element types that are masked. Only applies if privacySetting is `none`.
66+
*/
67+
maskInputOptions?: MaskInputOptions
68+
4069
/**
4170
* Customize which elements' text should be masked by specifying a CSS class name or RegExp.
4271
* Default class is 'highlight-mask'.
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
import { MaskInputOptions } from 'rrweb-snapshot'
21
import { PrivacySettingOption } from '../types/types'
2+
import { MaskInputOptions } from '../types/record'
33

44
// returns (1) whether all inputs should be masked and (2) which inputs should be masked
55
export const determineMaskInputOptions = (
66
privacyPolicy: PrivacySettingOption,
7+
maskAllInputs?: boolean,
8+
maskInputOptions?: MaskInputOptions,
79
): [maskAllOptions: boolean, maskOptions?: MaskInputOptions] => {
810
switch (privacyPolicy) {
911
case 'strict':
1012
return [true, undefined]
1113
case 'default':
1214
return [true, undefined]
1315
case 'none': {
14-
return [false, { password: true }]
16+
return [!!maskAllInputs, { ...maskInputOptions, password: true }]
1517
}
1618
}
1719
}

sdk/highlight-run/src/sdk/record.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,8 @@ SessionSecureID: ${this.sessionData.sessionSecureID}`,
602602

603603
const [maskAllInputs, maskInputOptions] = determineMaskInputOptions(
604604
this.privacySetting,
605+
this.options.maskAllInputs,
606+
this.options.maskInputOptions,
605607
)
606608

607609
this._recordStop = record({
@@ -613,7 +615,7 @@ SessionSecureID: ${this.sessionData.sessionSecureID}`,
613615
recordCrossOriginIframes: this.options.recordCrossOriginIframe,
614616
privacySetting: this.privacySetting,
615617
maskAllInputs,
616-
maskInputOptions: maskInputOptions,
618+
maskInputOptions,
617619
maskTextClass: this.options.maskTextClass,
618620
maskTextSelector: this.options.maskTextSelector,
619621
recordCanvas: this.enableCanvasRecording,

0 commit comments

Comments
 (0)