From ed7a749be7cddcbf656ac9f72e444ea9f822a718 Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:05:13 -0500 Subject: [PATCH] Signals: add redaction to formData (#1179) --- .changeset/two-pillows-wonder.md | 5 +++++ .../signals/src/core/client/__tests__/redact.test.ts | 4 ++-- packages/signals/signals/src/core/client/redact.ts | 11 +++++++++-- .../signals/src/core/signal-generators/dom-gen.ts | 12 ++++++++---- 4 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 .changeset/two-pillows-wonder.md diff --git a/.changeset/two-pillows-wonder.md b/.changeset/two-pillows-wonder.md new file mode 100644 index 000000000..7225ccd8f --- /dev/null +++ b/.changeset/two-pillows-wonder.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-signals': patch +--- + +Redact formData diff --git a/packages/signals/signals/src/core/client/__tests__/redact.test.ts b/packages/signals/signals/src/core/client/__tests__/redact.test.ts index d6c4d0a8d..a09b1db9e 100644 --- a/packages/signals/signals/src/core/client/__tests__/redact.test.ts +++ b/packages/signals/signals/src/core/client/__tests__/redact.test.ts @@ -79,11 +79,11 @@ describe(redactSignalData, () => { it('should redact the value in the "target" property if the type is "interaction"', () => { const signal = factories.createInteractionSignal({ eventType: 'change', - target: { value: 'secret' }, + target: { value: 'secret', formData: { password: '123' } }, }) const expected = factories.createInteractionSignal({ eventType: 'change', - target: { value: 'XXX' }, + target: { value: 'XXX', formData: { password: 'XXX' } }, }) expect(redactSignalData(signal)).toEqual(expected) }) diff --git a/packages/signals/signals/src/core/client/redact.ts b/packages/signals/signals/src/core/client/redact.ts index 97a6de013..3c28c2ada 100644 --- a/packages/signals/signals/src/core/client/redact.ts +++ b/packages/signals/signals/src/core/client/redact.ts @@ -3,8 +3,15 @@ import { Signal } from '@segment/analytics-signals-runtime' export const redactSignalData = (signalArg: Signal): Signal => { const signal = structuredClone(signalArg) if (signal.type === 'interaction') { - if ('target' in signal.data && 'value' in signal.data.target) { - signal.data.target.value = redactJsonValues(signal.data.target.value) + if ('target' in signal.data) { + if ('value' in signal.data.target) { + signal.data.target.value = redactJsonValues(signal.data.target.value) + } + if ('formData' in signal.data.target) { + signal.data.target.formData = redactJsonValues( + signal.data.target.formData + ) + } } } else if (signal.type === 'network') { signal.data = redactJsonValues(signal.data, 2) diff --git a/packages/signals/signals/src/core/signal-generators/dom-gen.ts b/packages/signals/signals/src/core/signal-generators/dom-gen.ts index aa48957d0..94e39c4cb 100644 --- a/packages/signals/signals/src/core/signal-generators/dom-gen.ts +++ b/packages/signals/signals/src/core/signal-generators/dom-gen.ts @@ -56,12 +56,12 @@ interface ParsedElementBase { id: string labels?: Label[] label?: Label - name: string + name?: string nodeName: string tagName: string title: string - type: string - value: string + type?: string + value?: string textContent?: string innerText?: string } @@ -88,6 +88,8 @@ interface ParsedMediaElement extends ParsedElementBase { interface ParsedHTMLFormElement extends ParsedElementBase { formData: Record + innerText: never + textContent: never } type AnyParsedElement = @@ -99,7 +101,7 @@ type AnyParsedElement = const parseElement = (el: HTMLElement): AnyParsedElement => { const labels = parseLabels((el as HTMLInputElement).labels) - const base = { + const base: ParsedElementBase = { // adding a bunch of fields that are not on _all_ elements, but are on enough that it's useful to have them here. attributes: parseNodeMap(el.attributes), classList: [...el.classList], @@ -147,6 +149,8 @@ const parseElement = (el: HTMLElement): AnyParsedElement => { } else if (el instanceof HTMLFormElement) { return { ...base, + innerText: undefined, + textContent: undefined, formData: parseFormData(new FormData(el)), } }