Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: payload capture - move timing into copied plugin #902

Merged
merged 14 commits into from
Nov 21, 2023
153 changes: 141 additions & 12 deletions src/__tests__/extensions/replay/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,35 @@ describe('config', () => {
it('should remove the Authorization header from requests even if no other config is set', () => {
const networkOptions = buildNetworkRequestOptions(defaultConfig(), {})
const cleaned = networkOptions.maskRequestFn!({
url: 'something',
name: 'something',
requestHeaders: {
Authorization: 'Bearer 123',
'content-type': 'application/json',
},
})
expect(cleaned?.requestHeaders).toEqual({
'content-type': 'application/json',
expect(cleaned).toEqual({
name: 'something',
requestHeaders: {
'content-type': 'application/json',
},
})
})

it('should cope with no headers when even if no other config is set', () => {
const networkOptions = buildNetworkRequestOptions(defaultConfig(), {})
const cleaned = networkOptions.maskRequestFn!({
url: 'something',
name: 'something',
requestHeaders: undefined,
})
expect(cleaned).toEqual({
name: 'something',
requestHeaders: undefined,
})
expect(cleaned?.requestHeaders).toBeUndefined()
})

it('should remove the Authorization header from requests even when a mask request fn is set', () => {
const posthogConfig = defaultConfig()
posthogConfig.session_recording.maskNetworkRequestFn = (data) => {
posthogConfig.session_recording.maskCapturedNetworkRequestFn = (data) => {
return {
...data,
requestHeaders: {
Expand All @@ -65,28 +71,151 @@ describe('config', () => {
const networkOptions = buildNetworkRequestOptions(posthogConfig, {})

const cleaned = networkOptions.maskRequestFn!({
url: 'something',
name: 'something',
requestHeaders: {
Authorization: 'Bearer 123',
'content-type': 'application/json',
},
})
expect(cleaned?.requestHeaders).toEqual({
'content-type': 'edited',
expect(cleaned).toEqual({
name: 'something',
requestHeaders: {
'content-type': 'edited',
},
})
})

it('uses the deprecated mask fn when set', () => {
const posthogConfig = defaultConfig()
posthogConfig.session_recording.maskNetworkRequestFn = (data) => {
return {
...data,
url: 'edited', // deprecated fn only edits the url
}
}
const networkOptions = buildNetworkRequestOptions(posthogConfig, {})

const cleaned = networkOptions.maskRequestFn!({
name: 'something',
requestHeaders: {
Authorization: 'Bearer 123',
'content-type': 'application/json',
},
})
expect(cleaned).toEqual({
name: 'edited',
requestHeaders: {
'content-type': 'application/json',
},
})
})

it('case insensitively removes headers on the deny list', () => {
const networkOptions = buildNetworkRequestOptions(defaultConfig(), {})
const cleaned = networkOptions.maskRequestFn!({
url: 'something',
name: 'something',
requestHeaders: {
AuThOrIzAtIoN: 'Bearer 123',
'content-type': 'application/json',
},
})
expect(cleaned?.requestHeaders).toEqual({
'content-type': 'application/json',
expect(cleaned).toEqual({
name: 'something',
requestHeaders: {
'content-type': 'application/json',
},
})
})

it.each([
[
{
name: 'https://app.posthog.com/api/feature_flag/',
},
{
name: 'https://app.posthog.com/api/feature_flag/',
},
],
[
{
name: 'https://app.posthog.com/s/',
},
undefined,
],
[
{
name: 'https://app.posthog.com/e/',
},
undefined,
],
[
{
name: 'https://app.posthog.com/i/vo/e/',
},
undefined,
],
])('ignores ingestion paths', (capturedRequest, expected) => {
const networkOptions = buildNetworkRequestOptions(defaultConfig(), {})
const x = networkOptions.maskRequestFn!(capturedRequest)
expect(x).toEqual(expected)
})

it('redacts large request body', () => {
const networkOptions = buildNetworkRequestOptions(defaultConfig(), {})
const cleaned = networkOptions.maskRequestFn!({
name: 'something',
requestHeaders: {
'content-type': 'application/json',
'content-length': '1000001',
},
requestBody: 'something very large',
})
expect(cleaned).toEqual({
name: 'something',
requestHeaders: {
'content-type': 'application/json',
'content-length': '1000001',
},
requestBody: 'Request body too large to record',
})
})

it('redacts large response body', () => {
const networkOptions = buildNetworkRequestOptions(defaultConfig(), {})
const cleaned = networkOptions.maskRequestFn!({
name: 'something',
responseHeaders: {
'content-type': 'application/json',
'content-length': '1000001',
},
responseBody: 'something very large',
})
expect(cleaned).toEqual({
name: 'something',
responseHeaders: {
'content-type': 'application/json',
'content-length': '1000001',
},
responseBody: 'Response body too large to record',
})
})

it('cannot redact when there is no content length header', () => {
const networkOptions = buildNetworkRequestOptions(defaultConfig(), {})
const largeString = 'a'.repeat(1000001)
const cleaned = networkOptions.maskRequestFn!({
name: 'something',
requestHeaders: {
'content-type': 'application/json',
},
requestBody: largeString,
})
expect(cleaned).toEqual({
name: 'something',
requestHeaders: {
'content-type': 'application/json',
},
requestBody: largeString,
})
})
})
Expand Down
161 changes: 0 additions & 161 deletions src/__tests__/extensions/replay/web-performance.test.ts

This file was deleted.

5 changes: 5 additions & 0 deletions src/__tests__/posthog-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -1117,4 +1117,9 @@ describe('posthog core', () => {
)
})
})

test('deprecated web performance observer still exposes _forceAllowLocalhost', () => {
expect(given.lib.webPerformance._forceAllowLocalhost).toBe(false)
expect(() => given.lib.webPerformance._forceAllowLocalhost).not.toThrow()
})
})
1 change: 0 additions & 1 deletion src/decide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export class Decide {
this.instance.toolbar.afterDecideResponse(response)
this.instance.sessionRecording?.afterDecideResponse(response)
autocapture.afterDecideResponse(response, this.instance)
this.instance.webPerformance?.afterDecideResponse(response)
this.instance._afterDecideResponse(response)

if (!this.instance.config.advanced_disable_feature_flags_on_first_load) {
Expand Down
Loading
Loading