@leanbase.com/js 0.2.1 → 0.2.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/replay/external/config.d.ts +9 -0
- package/dist/extensions/replay/external/denylist.d.ts +5 -0
- package/dist/extensions/replay/external/lazy-loaded-session-recorder.d.ts +153 -0
- package/dist/extensions/replay/external/mutation-throttler.d.ts +20 -0
- package/dist/extensions/replay/external/network-plugin.d.ts +15 -0
- package/dist/extensions/replay/external/sessionrecording-utils.d.ts +19 -0
- package/dist/extensions/replay/external/triggerMatching.d.ts +102 -0
- package/dist/extensions/replay/rrweb-plugins/patch.d.ts +3 -0
- package/dist/extensions/replay/session-recording.d.ts +75 -0
- package/dist/extensions/replay/types/rrweb-types.d.ts +439 -0
- package/dist/extensions/replay/types/rrweb.d.ts +82 -0
- package/dist/extensions/sampling.d.ts +4 -0
- package/dist/leanbase.d.ts +3 -0
- package/dist/leanbase.iife.js +1 -1
- package/dist/leanbase.iife.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.d.ts +708 -0
- package/dist/module.js +1 -1
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +135 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/version.d.ts +1 -1
- package/lib/extensions/replay/external/config.d.ts +9 -0
- package/lib/extensions/replay/external/config.js +221 -0
- package/lib/extensions/replay/external/config.js.map +1 -0
- package/lib/extensions/replay/external/denylist.d.ts +5 -0
- package/lib/extensions/replay/external/denylist.js +28 -0
- package/lib/extensions/replay/external/denylist.js.map +1 -0
- package/lib/extensions/replay/external/lazy-loaded-session-recorder.d.ts +153 -0
- package/lib/extensions/replay/external/lazy-loaded-session-recorder.js +1042 -0
- package/lib/extensions/replay/external/lazy-loaded-session-recorder.js.map +1 -0
- package/lib/extensions/replay/external/mutation-throttler.d.ts +20 -0
- package/lib/extensions/replay/external/mutation-throttler.js +77 -0
- package/lib/extensions/replay/external/mutation-throttler.js.map +1 -0
- package/lib/extensions/replay/external/network-plugin.d.ts +15 -0
- package/lib/extensions/replay/external/network-plugin.js +503 -0
- package/lib/extensions/replay/external/network-plugin.js.map +1 -0
- package/lib/extensions/replay/external/sessionrecording-utils.d.ts +19 -0
- package/lib/extensions/replay/external/sessionrecording-utils.js +125 -0
- package/lib/extensions/replay/external/sessionrecording-utils.js.map +1 -0
- package/lib/extensions/replay/external/triggerMatching.d.ts +102 -0
- package/lib/extensions/replay/external/triggerMatching.js +342 -0
- package/lib/extensions/replay/external/triggerMatching.js.map +1 -0
- package/lib/extensions/replay/rrweb-plugins/patch.d.ts +3 -0
- package/lib/extensions/replay/rrweb-plugins/patch.js +32 -0
- package/lib/extensions/replay/rrweb-plugins/patch.js.map +1 -0
- package/lib/extensions/replay/session-recording.d.ts +75 -0
- package/lib/extensions/replay/session-recording.js +279 -0
- package/lib/extensions/replay/session-recording.js.map +1 -0
- package/lib/extensions/replay/types/rrweb-types.d.ts +439 -0
- package/lib/extensions/replay/types/rrweb-types.js +83 -0
- package/lib/extensions/replay/types/rrweb-types.js.map +1 -0
- package/lib/extensions/replay/types/rrweb.d.ts +82 -0
- package/lib/extensions/replay/types/rrweb.js +9 -0
- package/lib/extensions/replay/types/rrweb.js.map +1 -0
- package/lib/extensions/sampling.d.ts +4 -0
- package/lib/extensions/sampling.js +23 -0
- package/lib/extensions/sampling.js.map +1 -0
- package/lib/leanbase.d.ts +3 -0
- package/lib/leanbase.js +25 -0
- package/lib/leanbase.js.map +1 -1
- package/lib/types.d.ts +135 -0
- package/lib/types.js.map +1 -1
- package/lib/utils/logger.d.ts +10 -0
- package/lib/utils/logger.js +15 -0
- package/lib/utils/logger.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +5 -21
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FeatureFlagValue, JsonType, PostHogCoreOptions } from '@posthog/core';
|
|
2
2
|
import { KnownUnsafeEditableEvent } from '@posthog/core';
|
|
3
|
+
import type { recordOptions } from './extensions/replay/types/rrweb';
|
|
3
4
|
import { Leanbase } from './leanbase';
|
|
4
5
|
export declare const COPY_AUTOCAPTURE_EVENT = "$copy_autocapture";
|
|
5
6
|
export type Property = any;
|
|
@@ -104,6 +105,19 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
|
|
|
104
105
|
* @default true
|
|
105
106
|
*/
|
|
106
107
|
autocapture: boolean | AutocaptureConfig;
|
|
108
|
+
/**
|
|
109
|
+
* Enables or disables session recording. When true, session recording is disabled on the client.
|
|
110
|
+
* @default false
|
|
111
|
+
*/
|
|
112
|
+
disable_session_recording?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Session recording configuration
|
|
115
|
+
*/
|
|
116
|
+
session_recording?: SessionRecordingOptions;
|
|
117
|
+
/**
|
|
118
|
+
* Enable console.log recording for session replay (can be controlled remotely). Undefined defers to server.
|
|
119
|
+
*/
|
|
120
|
+
enable_recording_console_log?: boolean;
|
|
107
121
|
/**
|
|
108
122
|
* Determines whether Leanbase should capture pageview events automatically.
|
|
109
123
|
* Can be:
|
|
@@ -114,6 +128,12 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
|
|
|
114
128
|
* @default true
|
|
115
129
|
*/
|
|
116
130
|
capture_pageview: boolean | 'history_change';
|
|
131
|
+
/**
|
|
132
|
+
* Enables performance capture. When true, network performance timing can be forwarded to replay when enabled.
|
|
133
|
+
*/
|
|
134
|
+
capture_performance?: boolean | {
|
|
135
|
+
network_timing?: boolean;
|
|
136
|
+
};
|
|
117
137
|
/**
|
|
118
138
|
* Determines the session idle timeout in seconds.
|
|
119
139
|
* Any new event that's happened after this timeout will create a new session.
|
|
@@ -338,6 +358,73 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
|
|
|
338
358
|
*/
|
|
339
359
|
loaded: (instance: Leanbase) => void;
|
|
340
360
|
}
|
|
361
|
+
export type SessionRecordingCanvasOptions = {
|
|
362
|
+
recordCanvas?: boolean | null;
|
|
363
|
+
canvasFps?: number | null;
|
|
364
|
+
canvasQuality?: string | null;
|
|
365
|
+
};
|
|
366
|
+
export interface SessionRecordingOptions {
|
|
367
|
+
blockClass?: string | RegExp;
|
|
368
|
+
blockSelector?: string | null;
|
|
369
|
+
ignoreClass?: string | RegExp;
|
|
370
|
+
maskTextClass?: string | RegExp;
|
|
371
|
+
maskTextSelector?: string | null;
|
|
372
|
+
maskTextFn?: ((text: string, element?: HTMLElement) => string) | null;
|
|
373
|
+
maskAllInputs?: boolean;
|
|
374
|
+
maskInputOptions?: recordOptions['maskInputOptions'];
|
|
375
|
+
maskInputFn?: ((text: string, element?: HTMLElement) => string) | null;
|
|
376
|
+
slimDOMOptions?: recordOptions['slimDOMOptions'];
|
|
377
|
+
collectFonts?: boolean;
|
|
378
|
+
inlineStylesheet?: boolean;
|
|
379
|
+
recordCrossOriginIframes?: boolean;
|
|
380
|
+
recordHeaders?: boolean;
|
|
381
|
+
recordBody?: boolean;
|
|
382
|
+
captureCanvas?: SessionRecordingCanvasOptions;
|
|
383
|
+
maskCapturedNetworkRequestFn?: ((data: CapturedNetworkRequest) => CapturedNetworkRequest | null | undefined) | null;
|
|
384
|
+
maskNetworkRequestFn?: ((data: NetworkRequest) => NetworkRequest | null | undefined) | null;
|
|
385
|
+
full_snapshot_interval_millis?: number;
|
|
386
|
+
compress_events?: boolean;
|
|
387
|
+
session_idle_threshold_ms?: number;
|
|
388
|
+
__mutationThrottlerRefillRate?: number;
|
|
389
|
+
__mutationThrottlerBucketSize?: number;
|
|
390
|
+
/**
|
|
391
|
+
* Force-enable session recording locally even if remote config disables it.
|
|
392
|
+
* Useful for dev/testing when the backend has sessionRecording set to false.
|
|
393
|
+
*/
|
|
394
|
+
forceClientRecording?: boolean;
|
|
395
|
+
}
|
|
396
|
+
export type SessionRecordingPersistedConfig = Omit<SessionRecordingRemoteConfig, 'recordCanvas' | 'canvasFps' | 'canvasQuality' | 'networkPayloadCapture' | 'sampleRate' | 'minimumDurationMilliseconds'> & {
|
|
397
|
+
enabled: boolean;
|
|
398
|
+
networkPayloadCapture: SessionRecordingRemoteConfig['networkPayloadCapture'] & {
|
|
399
|
+
capturePerformance: RemoteConfig['capturePerformance'];
|
|
400
|
+
};
|
|
401
|
+
canvasRecording: {
|
|
402
|
+
enabled: SessionRecordingRemoteConfig['recordCanvas'];
|
|
403
|
+
fps: SessionRecordingRemoteConfig['canvasFps'];
|
|
404
|
+
quality: SessionRecordingRemoteConfig['canvasQuality'];
|
|
405
|
+
};
|
|
406
|
+
sampleRate: number | null;
|
|
407
|
+
minimumDurationMilliseconds: number | null | undefined;
|
|
408
|
+
};
|
|
409
|
+
export type SessionRecordingRemoteConfig = SessionRecordingCanvasOptions & {
|
|
410
|
+
endpoint?: string;
|
|
411
|
+
consoleLogRecordingEnabled?: boolean;
|
|
412
|
+
sampleRate?: string | null;
|
|
413
|
+
minimumDurationMilliseconds?: number;
|
|
414
|
+
linkedFlag?: string | {
|
|
415
|
+
flag: string;
|
|
416
|
+
variant: string;
|
|
417
|
+
} | null;
|
|
418
|
+
networkPayloadCapture?: Pick<NetworkRecordOptions, 'recordBody' | 'recordHeaders' | 'payloadHostDenyList'>;
|
|
419
|
+
masking?: Pick<SessionRecordingOptions, 'maskAllInputs' | 'maskTextSelector' | 'blockSelector'>;
|
|
420
|
+
urlTriggers?: SessionRecordingUrlTrigger[];
|
|
421
|
+
scriptConfig?: {
|
|
422
|
+
script?: string | undefined;
|
|
423
|
+
};
|
|
424
|
+
urlBlocklist?: SessionRecordingUrlTrigger[];
|
|
425
|
+
eventTriggers?: string[];
|
|
426
|
+
triggerMatchType?: 'any' | 'all';
|
|
427
|
+
};
|
|
341
428
|
export interface RageclickConfig {
|
|
342
429
|
/**
|
|
343
430
|
* List of CSS selectors to ignore rageclicks on
|
|
@@ -456,6 +543,10 @@ export interface RemoteConfig {
|
|
|
456
543
|
autocaptureExceptions?: boolean | {
|
|
457
544
|
endpoint?: string;
|
|
458
545
|
};
|
|
546
|
+
/**
|
|
547
|
+
* Session recording configuration options
|
|
548
|
+
*/
|
|
549
|
+
sessionRecording?: SessionRecordingRemoteConfig | false;
|
|
459
550
|
/**
|
|
460
551
|
* @deprecated, moved to toolbarParams
|
|
461
552
|
*/
|
|
@@ -533,6 +624,50 @@ export interface RequestWithOptions {
|
|
|
533
624
|
next?: NextOptions;
|
|
534
625
|
};
|
|
535
626
|
}
|
|
627
|
+
export type InitiatorType = 'audio' | 'beacon' | 'body' | 'css' | 'early-hint' | 'early-hints' | 'embed' | 'fetch' | 'frame' | 'iframe' | 'image' | 'img' | 'input' | 'link' | 'navigation' | 'object' | 'ping' | 'script' | 'track' | 'video' | 'xmlhttprequest';
|
|
628
|
+
export type NetworkRecordOptions = {
|
|
629
|
+
initiatorTypes?: InitiatorType[];
|
|
630
|
+
maskRequestFn?: (data: CapturedNetworkRequest) => CapturedNetworkRequest | undefined;
|
|
631
|
+
recordHeaders?: boolean | {
|
|
632
|
+
request: boolean;
|
|
633
|
+
response: boolean;
|
|
634
|
+
};
|
|
635
|
+
recordBody?: boolean | string[] | {
|
|
636
|
+
request: boolean | string[];
|
|
637
|
+
response: boolean | string[];
|
|
638
|
+
};
|
|
639
|
+
recordInitialRequests?: boolean;
|
|
640
|
+
recordPerformance?: boolean;
|
|
641
|
+
performanceEntryTypeToObserve: string[];
|
|
642
|
+
payloadSizeLimitBytes: number;
|
|
643
|
+
payloadHostDenyList?: string[];
|
|
644
|
+
};
|
|
645
|
+
export type NetworkRequest = {
|
|
646
|
+
url: string;
|
|
647
|
+
};
|
|
648
|
+
export type Headers = Record<string, any>;
|
|
649
|
+
type Writable<T> = {
|
|
650
|
+
-readonly [P in keyof T]: T[P];
|
|
651
|
+
};
|
|
652
|
+
export type CapturedNetworkRequest = Writable<Omit<PerformanceEntry, 'toJSON'>> & {
|
|
653
|
+
method?: string;
|
|
654
|
+
initiatorType?: InitiatorType;
|
|
655
|
+
status?: number;
|
|
656
|
+
timeOrigin?: number;
|
|
657
|
+
timestamp?: number;
|
|
658
|
+
startTime?: number;
|
|
659
|
+
endTime?: number;
|
|
660
|
+
requestHeaders?: Headers;
|
|
661
|
+
requestBody?: string | null;
|
|
662
|
+
responseHeaders?: Headers;
|
|
663
|
+
responseBody?: string | null;
|
|
664
|
+
isInitial?: boolean;
|
|
665
|
+
};
|
|
666
|
+
export interface SessionRecordingUrlTrigger {
|
|
667
|
+
url: string;
|
|
668
|
+
matching: 'regex';
|
|
669
|
+
}
|
|
670
|
+
export type SessionStartReason = 'sampling_overridden' | 'recording_initialized' | 'linked_flag_matched' | 'linked_flag_overridden' | 'sampled' | 'session_id_changed' | 'url_trigger_matched' | 'event_trigger_matched';
|
|
536
671
|
export type SessionIdChangedCallback = (sessionId: string, windowId: string | null | undefined, changeReason?: {
|
|
537
672
|
noSessionId: boolean;
|
|
538
673
|
activityTimeout: boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type PosthogJsLogger = {
|
|
2
|
+
info: (...args: any[]) => void;
|
|
3
|
+
warn: (...args: any[]) => void;
|
|
4
|
+
error: (...args: any[]) => void;
|
|
5
|
+
critical: (...args: any[]) => void;
|
|
6
|
+
uninitializedWarning: (methodName: string) => void;
|
|
7
|
+
createLogger: (prefix: string) => PosthogJsLogger;
|
|
8
|
+
};
|
|
9
|
+
export declare const logger: PosthogJsLogger;
|
|
10
|
+
export declare const createLogger: (prefix: string) => PosthogJsLogger;
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.2.
|
|
1
|
+
export declare const version = "0.2.2-alpha.0";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LeanbaseConfig, NetworkRecordOptions } from '../../../types';
|
|
2
|
+
export declare const defaultNetworkOptions: Required<NetworkRecordOptions>;
|
|
3
|
+
/**
|
|
4
|
+
* whether a maskRequestFn is provided or not,
|
|
5
|
+
* we ensure that we remove the denied header from requests
|
|
6
|
+
* we _never_ want to record that header by accident
|
|
7
|
+
* if someone complains then we'll add an opt-in to let them override it
|
|
8
|
+
*/
|
|
9
|
+
export declare const buildNetworkRequestOptions: (instanceConfig: LeanbaseConfig, remoteNetworkOptions?: Pick<NetworkRecordOptions, "recordHeaders" | "recordBody" | "recordPerformance" | "payloadHostDenyList">) => NetworkRecordOptions;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { isArray, isFunction, isNullish, isString, isUndefined } from '@posthog/core';
|
|
2
|
+
import { convertToURL } from '../../../utils/request-utils';
|
|
3
|
+
import { logger } from '../../../utils/logger';
|
|
4
|
+
import { shouldCaptureValue } from '../../../autocapture-utils';
|
|
5
|
+
import { each } from '../../../utils';
|
|
6
|
+
const LOGGER_PREFIX = '[SessionRecording]';
|
|
7
|
+
const REDACTED = 'redacted';
|
|
8
|
+
export const defaultNetworkOptions = {
|
|
9
|
+
initiatorTypes: [
|
|
10
|
+
'audio',
|
|
11
|
+
'beacon',
|
|
12
|
+
'body',
|
|
13
|
+
'css',
|
|
14
|
+
'early-hint', // ResourceTiming spec + browser parity with posthog-js
|
|
15
|
+
'embed',
|
|
16
|
+
'fetch',
|
|
17
|
+
'frame',
|
|
18
|
+
'iframe',
|
|
19
|
+
'image',
|
|
20
|
+
'img',
|
|
21
|
+
'input',
|
|
22
|
+
'link',
|
|
23
|
+
'navigation',
|
|
24
|
+
'object',
|
|
25
|
+
'ping',
|
|
26
|
+
'script',
|
|
27
|
+
'track',
|
|
28
|
+
'video',
|
|
29
|
+
'xmlhttprequest',
|
|
30
|
+
],
|
|
31
|
+
maskRequestFn: (data) => data,
|
|
32
|
+
recordHeaders: false,
|
|
33
|
+
recordBody: false,
|
|
34
|
+
recordInitialRequests: false,
|
|
35
|
+
recordPerformance: false,
|
|
36
|
+
performanceEntryTypeToObserve: [
|
|
37
|
+
// 'event', // This is too noisy as it covers all browser events
|
|
38
|
+
'first-input',
|
|
39
|
+
// 'mark', // Mark is used too liberally. We would need to filter for specific marks
|
|
40
|
+
// 'measure', // Measure is used too liberally. We would need to filter for specific measures
|
|
41
|
+
'navigation',
|
|
42
|
+
'paint',
|
|
43
|
+
'resource',
|
|
44
|
+
],
|
|
45
|
+
payloadSizeLimitBytes: 1000000,
|
|
46
|
+
payloadHostDenyList: [
|
|
47
|
+
'.lr-ingest.io',
|
|
48
|
+
'.ingest.sentry.io',
|
|
49
|
+
'.clarity.ms',
|
|
50
|
+
// NB no leading dot here
|
|
51
|
+
'analytics.google.com',
|
|
52
|
+
'bam.nr-data.net',
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
const HEADER_DENY_LIST = [
|
|
56
|
+
'authorization',
|
|
57
|
+
'x-forwarded-for',
|
|
58
|
+
'authorization',
|
|
59
|
+
'cookie',
|
|
60
|
+
'set-cookie',
|
|
61
|
+
'x-api-key',
|
|
62
|
+
'x-real-ip',
|
|
63
|
+
'remote-addr',
|
|
64
|
+
'forwarded',
|
|
65
|
+
'proxy-authorization',
|
|
66
|
+
'x-csrf-token',
|
|
67
|
+
'x-csrftoken',
|
|
68
|
+
'x-xsrf-token',
|
|
69
|
+
];
|
|
70
|
+
const PAYLOAD_CONTENT_DENY_LIST = [
|
|
71
|
+
'password',
|
|
72
|
+
'secret',
|
|
73
|
+
'passwd',
|
|
74
|
+
'api_key',
|
|
75
|
+
'apikey',
|
|
76
|
+
'auth',
|
|
77
|
+
'credentials',
|
|
78
|
+
'mysql_pwd',
|
|
79
|
+
'privatekey',
|
|
80
|
+
'private_key',
|
|
81
|
+
'token',
|
|
82
|
+
];
|
|
83
|
+
// we always remove headers on the deny list because we never want to capture this sensitive data
|
|
84
|
+
const removeAuthorizationHeader = (data) => {
|
|
85
|
+
const headers = data.requestHeaders;
|
|
86
|
+
if (!isNullish(headers)) {
|
|
87
|
+
const mutableHeaders = isArray(headers)
|
|
88
|
+
? Object.fromEntries(headers)
|
|
89
|
+
: headers;
|
|
90
|
+
each(Object.keys(mutableHeaders ?? {}), (header) => {
|
|
91
|
+
if (HEADER_DENY_LIST.includes(header.toLowerCase())) {
|
|
92
|
+
mutableHeaders[header] = REDACTED;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
data.requestHeaders = mutableHeaders;
|
|
96
|
+
}
|
|
97
|
+
return data;
|
|
98
|
+
};
|
|
99
|
+
const POSTHOG_PATHS_TO_IGNORE = ['/s/', '/e/', '/i/'];
|
|
100
|
+
// want to ignore posthog paths when capturing requests, or we can get trapped in a loop
|
|
101
|
+
// because calls to PostHog would be reported using a call to PostHog which would be reported....
|
|
102
|
+
const ignorePostHogPaths = (data, apiHostConfig) => {
|
|
103
|
+
const url = convertToURL(data.name);
|
|
104
|
+
const host = apiHostConfig || '';
|
|
105
|
+
let replaceValue = host.indexOf('http') === 0 ? convertToURL(host)?.pathname : host;
|
|
106
|
+
if (replaceValue === '/') {
|
|
107
|
+
replaceValue = '';
|
|
108
|
+
}
|
|
109
|
+
const pathname = url?.pathname.replace(replaceValue || '', '');
|
|
110
|
+
if (url && pathname && POSTHOG_PATHS_TO_IGNORE.some((path) => pathname.indexOf(path) === 0)) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
return data;
|
|
114
|
+
};
|
|
115
|
+
function estimateBytes(payload) {
|
|
116
|
+
return new Blob([payload]).size;
|
|
117
|
+
}
|
|
118
|
+
function enforcePayloadSizeLimit(payload, headers, limit, description) {
|
|
119
|
+
if (isNullish(payload)) {
|
|
120
|
+
return payload;
|
|
121
|
+
}
|
|
122
|
+
let requestContentLength = headers?.['content-length'] || estimateBytes(payload);
|
|
123
|
+
if (isString(requestContentLength)) {
|
|
124
|
+
requestContentLength = parseInt(requestContentLength);
|
|
125
|
+
}
|
|
126
|
+
if (requestContentLength > limit) {
|
|
127
|
+
return LOGGER_PREFIX + ` ${description} body too large to record (${requestContentLength} bytes)`;
|
|
128
|
+
}
|
|
129
|
+
return payload;
|
|
130
|
+
}
|
|
131
|
+
// people can have arbitrarily large payloads on their site, but we don't want to ingest them
|
|
132
|
+
const limitPayloadSize = (options) => {
|
|
133
|
+
// the smallest of 1MB or the specified limit if there is one
|
|
134
|
+
const limit = Math.min(1000000, options.payloadSizeLimitBytes ?? 1000000);
|
|
135
|
+
return (data) => {
|
|
136
|
+
if (data?.requestBody) {
|
|
137
|
+
data.requestBody = enforcePayloadSizeLimit(data.requestBody, data.requestHeaders, limit, 'Request');
|
|
138
|
+
}
|
|
139
|
+
if (data?.responseBody) {
|
|
140
|
+
data.responseBody = enforcePayloadSizeLimit(data.responseBody, data.responseHeaders, limit, 'Response');
|
|
141
|
+
}
|
|
142
|
+
return data;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
function scrubPayload(payload, label) {
|
|
146
|
+
if (isNullish(payload)) {
|
|
147
|
+
return payload;
|
|
148
|
+
}
|
|
149
|
+
let scrubbed = payload;
|
|
150
|
+
if (!shouldCaptureValue(scrubbed, false)) {
|
|
151
|
+
scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED;
|
|
152
|
+
}
|
|
153
|
+
each(PAYLOAD_CONTENT_DENY_LIST, (text) => {
|
|
154
|
+
if (scrubbed?.length && scrubbed?.indexOf(text) !== -1) {
|
|
155
|
+
scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED + ' as might contain: ' + text;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return scrubbed;
|
|
159
|
+
}
|
|
160
|
+
function scrubPayloads(capturedRequest) {
|
|
161
|
+
if (isUndefined(capturedRequest)) {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
capturedRequest.requestBody = scrubPayload(capturedRequest.requestBody, 'Request');
|
|
165
|
+
capturedRequest.responseBody = scrubPayload(capturedRequest.responseBody, 'Response');
|
|
166
|
+
return capturedRequest;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* whether a maskRequestFn is provided or not,
|
|
170
|
+
* we ensure that we remove the denied header from requests
|
|
171
|
+
* we _never_ want to record that header by accident
|
|
172
|
+
* if someone complains then we'll add an opt-in to let them override it
|
|
173
|
+
*/
|
|
174
|
+
export const buildNetworkRequestOptions = (instanceConfig, remoteNetworkOptions = {}) => {
|
|
175
|
+
const remoteOptions = remoteNetworkOptions || {};
|
|
176
|
+
const config = {
|
|
177
|
+
payloadSizeLimitBytes: defaultNetworkOptions.payloadSizeLimitBytes,
|
|
178
|
+
performanceEntryTypeToObserve: [...defaultNetworkOptions.performanceEntryTypeToObserve],
|
|
179
|
+
payloadHostDenyList: [
|
|
180
|
+
...(remoteOptions.payloadHostDenyList || []),
|
|
181
|
+
...defaultNetworkOptions.payloadHostDenyList,
|
|
182
|
+
],
|
|
183
|
+
};
|
|
184
|
+
// client can always disable despite remote options
|
|
185
|
+
const sessionRecordingConfig = instanceConfig.session_recording || {};
|
|
186
|
+
const canRecordHeaders = sessionRecordingConfig.recordHeaders === false ? false : !!remoteOptions.recordHeaders;
|
|
187
|
+
const canRecordBody = sessionRecordingConfig.recordBody === false ? false : !!remoteOptions.recordBody;
|
|
188
|
+
const canRecordPerformance = instanceConfig.capture_performance === false ? false : !!remoteOptions.recordPerformance;
|
|
189
|
+
const payloadLimiter = limitPayloadSize(config);
|
|
190
|
+
const enforcedCleaningFn = (d) => payloadLimiter(ignorePostHogPaths(removeAuthorizationHeader(d), instanceConfig.host || ''));
|
|
191
|
+
const hasDeprecatedMaskFunction = isFunction(sessionRecordingConfig.maskNetworkRequestFn);
|
|
192
|
+
if (hasDeprecatedMaskFunction && isFunction(sessionRecordingConfig.maskCapturedNetworkRequestFn)) {
|
|
193
|
+
logger.warn('Both `maskNetworkRequestFn` and `maskCapturedNetworkRequestFn` are defined. `maskNetworkRequestFn` will be ignored.');
|
|
194
|
+
}
|
|
195
|
+
if (hasDeprecatedMaskFunction) {
|
|
196
|
+
sessionRecordingConfig.maskCapturedNetworkRequestFn = (data) => {
|
|
197
|
+
const cleanedURL = sessionRecordingConfig.maskNetworkRequestFn({ url: data.name });
|
|
198
|
+
return {
|
|
199
|
+
...data,
|
|
200
|
+
name: cleanedURL?.url,
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
config.maskRequestFn = isFunction(sessionRecordingConfig.maskCapturedNetworkRequestFn)
|
|
205
|
+
? (data) => {
|
|
206
|
+
const cleanedRequest = enforcedCleaningFn(data);
|
|
207
|
+
return cleanedRequest
|
|
208
|
+
? (sessionRecordingConfig.maskCapturedNetworkRequestFn?.(cleanedRequest) ?? undefined)
|
|
209
|
+
: undefined;
|
|
210
|
+
}
|
|
211
|
+
: (data) => scrubPayloads(enforcedCleaningFn(data));
|
|
212
|
+
return {
|
|
213
|
+
...defaultNetworkOptions,
|
|
214
|
+
...config,
|
|
215
|
+
recordHeaders: canRecordHeaders,
|
|
216
|
+
recordBody: canRecordBody,
|
|
217
|
+
recordPerformance: canRecordPerformance,
|
|
218
|
+
recordInitialRequests: canRecordPerformance,
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/extensions/replay/external/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
function hostnameFromURL(url) {
|
|
2
|
+
try {
|
|
3
|
+
if (typeof url === 'string') {
|
|
4
|
+
return new URL(url).hostname;
|
|
5
|
+
}
|
|
6
|
+
if ('url' in url) {
|
|
7
|
+
return new URL(url.url).hostname;
|
|
8
|
+
}
|
|
9
|
+
return url.hostname;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function isHostOnDenyList(url, options) {
|
|
16
|
+
const hostname = hostnameFromURL(url);
|
|
17
|
+
const defaultNotDenied = { hostname, isHostDenied: false };
|
|
18
|
+
if (!options.payloadHostDenyList?.length || !hostname?.trim().length) {
|
|
19
|
+
return defaultNotDenied;
|
|
20
|
+
}
|
|
21
|
+
for (const deny of options.payloadHostDenyList) {
|
|
22
|
+
if (hostname.endsWith(deny)) {
|
|
23
|
+
return { hostname, isHostDenied: true };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return defaultNotDenied;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=denylist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"denylist.js","sourceRoot":"","sources":["../../../../src/extensions/replay/external/denylist.ts"],"names":[],"mappings":"AAEA,SAAS,eAAe,CAAC,GAA+B;IACpD,IAAI,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC1B,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;QAChC,CAAC;QACD,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACf,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;QACpC,CAAC;QACD,OAAO,GAAG,CAAC,QAAQ,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAA;IACf,CAAC;AACL,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAA2B,EAAE,OAA6B;IACvF,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,gBAAgB,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,CAAA;IAE1D,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QACnE,OAAO,gBAAgB,CAAA;IAC3B,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAC7C,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;QAC3C,CAAC;IACL,CAAC;IAED,OAAO,gBAAgB,CAAA;AAC3B,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { EventType, eventWithTime, IncrementalSource } from '../types/rrweb-types';
|
|
2
|
+
import { SessionRecordingStatus, TriggerType } from './triggerMatching';
|
|
3
|
+
import { Leanbase } from '../../../leanbase';
|
|
4
|
+
import { Properties, SessionRecordingPersistedConfig, SessionStartReason } from '../../../types';
|
|
5
|
+
export declare const RECORDING_IDLE_THRESHOLD_MS: number;
|
|
6
|
+
export declare const RECORDING_MAX_EVENT_SIZE: number;
|
|
7
|
+
export declare const RECORDING_BUFFER_TIMEOUT = 2000;
|
|
8
|
+
export declare const SESSION_RECORDING_BATCH_KEY = "recordings";
|
|
9
|
+
export interface SnapshotBuffer {
|
|
10
|
+
size: number;
|
|
11
|
+
data: any[];
|
|
12
|
+
sessionId: string;
|
|
13
|
+
windowId: string;
|
|
14
|
+
}
|
|
15
|
+
export type compressedFullSnapshotEvent = {
|
|
16
|
+
type: EventType.FullSnapshot;
|
|
17
|
+
data: string;
|
|
18
|
+
};
|
|
19
|
+
export type compressedIncrementalSnapshotEvent = {
|
|
20
|
+
type: EventType.IncrementalSnapshot;
|
|
21
|
+
data: {
|
|
22
|
+
source: IncrementalSource;
|
|
23
|
+
texts: string;
|
|
24
|
+
attributes: string;
|
|
25
|
+
removes: string;
|
|
26
|
+
adds: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export type compressedIncrementalStyleSnapshotEvent = {
|
|
30
|
+
type: EventType.IncrementalSnapshot;
|
|
31
|
+
data: {
|
|
32
|
+
source: IncrementalSource.StyleSheetRule;
|
|
33
|
+
id?: number;
|
|
34
|
+
styleId?: number;
|
|
35
|
+
replace?: string;
|
|
36
|
+
replaceSync?: string;
|
|
37
|
+
adds?: string;
|
|
38
|
+
removes?: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export type compressedEvent = compressedIncrementalStyleSnapshotEvent | compressedFullSnapshotEvent | compressedIncrementalSnapshotEvent;
|
|
42
|
+
export type compressedEventWithTime = compressedEvent & {
|
|
43
|
+
timestamp: number;
|
|
44
|
+
delay?: number;
|
|
45
|
+
cv: '2024-10';
|
|
46
|
+
};
|
|
47
|
+
export declare const SEVEN_MEGABYTES: number;
|
|
48
|
+
export declare function splitBuffer(buffer: SnapshotBuffer, sizeLimit?: number): SnapshotBuffer[];
|
|
49
|
+
export declare class LazyLoadedSessionRecording {
|
|
50
|
+
private readonly _instance;
|
|
51
|
+
private _endpoint;
|
|
52
|
+
private _mutationThrottler?;
|
|
53
|
+
/**
|
|
54
|
+
* Util to help developers working on this feature manually override
|
|
55
|
+
*/
|
|
56
|
+
private _forceAllowLocalhostNetworkCapture;
|
|
57
|
+
private _stopRrweb;
|
|
58
|
+
private _lastActivityTimestamp;
|
|
59
|
+
/**
|
|
60
|
+
* if pageview capture is disabled,
|
|
61
|
+
* then we can manually track href changes
|
|
62
|
+
*/
|
|
63
|
+
private _lastHref?;
|
|
64
|
+
/**
|
|
65
|
+
* and a queue - that contains rrweb events that we want to send to rrweb, but rrweb wasn't able to accept them yet
|
|
66
|
+
*/
|
|
67
|
+
private _queuedRRWebEvents;
|
|
68
|
+
private _isIdle;
|
|
69
|
+
private _warnedMissingConsolePlugin;
|
|
70
|
+
private _linkedFlagMatching;
|
|
71
|
+
private _urlTriggerMatching;
|
|
72
|
+
private _eventTriggerMatching;
|
|
73
|
+
private _triggerMatching;
|
|
74
|
+
private _fullSnapshotTimer?;
|
|
75
|
+
private _windowId;
|
|
76
|
+
private _sessionId;
|
|
77
|
+
get sessionId(): string;
|
|
78
|
+
private _flushBufferTimer?;
|
|
79
|
+
private _buffer;
|
|
80
|
+
private _removePageViewCaptureHook;
|
|
81
|
+
private _removeEventTriggerCaptureHook;
|
|
82
|
+
private get _sessionManager();
|
|
83
|
+
private get _sessionIdleThresholdMilliseconds();
|
|
84
|
+
private get _isSampled();
|
|
85
|
+
private get _sampleRate();
|
|
86
|
+
private get _minimumDuration();
|
|
87
|
+
private _statusMatcher;
|
|
88
|
+
private _onSessionIdListener;
|
|
89
|
+
private _onSessionIdleResetForcedListener;
|
|
90
|
+
private _samplingSessionListener;
|
|
91
|
+
private _forceIdleSessionIdListener;
|
|
92
|
+
constructor(_instance: Leanbase);
|
|
93
|
+
private get _masking();
|
|
94
|
+
private get _canvasRecording();
|
|
95
|
+
private get _isConsoleLogCaptureEnabled();
|
|
96
|
+
private get _networkPayloadCapture();
|
|
97
|
+
private _gatherRRWebPlugins;
|
|
98
|
+
private _maskUrl;
|
|
99
|
+
private _tryRRWebMethod;
|
|
100
|
+
private _tryAddCustomEvent;
|
|
101
|
+
private _pageViewFallBack;
|
|
102
|
+
private _processQueuedEvents;
|
|
103
|
+
private _tryTakeFullSnapshot;
|
|
104
|
+
private get _fullSnapshotIntervalMillis();
|
|
105
|
+
private _scheduleFullSnapshot;
|
|
106
|
+
private _pauseRecording;
|
|
107
|
+
private _resumeRecording;
|
|
108
|
+
private _activateTrigger;
|
|
109
|
+
get isStarted(): boolean;
|
|
110
|
+
get _remoteConfig(): SessionRecordingPersistedConfig | undefined;
|
|
111
|
+
start(startReason?: SessionStartReason): void;
|
|
112
|
+
private _onSessionIdCallback;
|
|
113
|
+
stop(): void;
|
|
114
|
+
onRRwebEmit(rawEvent: eventWithTime): void;
|
|
115
|
+
get status(): SessionRecordingStatus;
|
|
116
|
+
log(message: string, level?: 'log' | 'warn' | 'error'): void;
|
|
117
|
+
overrideLinkedFlag(): void;
|
|
118
|
+
/**
|
|
119
|
+
* this ignores the sampling config and (if other conditions are met) causes capture to start
|
|
120
|
+
*
|
|
121
|
+
* It is not usual to call this directly,
|
|
122
|
+
* instead call `posthog.startSessionRecording({sampling: true})`
|
|
123
|
+
* */
|
|
124
|
+
overrideSampling(): void;
|
|
125
|
+
/**
|
|
126
|
+
* this ignores the URL/Event trigger config and (if other conditions are met) causes capture to start
|
|
127
|
+
*
|
|
128
|
+
* It is not usual to call this directly,
|
|
129
|
+
* instead call `posthog.startSessionRecording({trigger: 'url' | 'event'})`
|
|
130
|
+
* */
|
|
131
|
+
overrideTrigger(triggerType: TriggerType): void;
|
|
132
|
+
private _clearFlushBufferTimer;
|
|
133
|
+
private _flushBuffer;
|
|
134
|
+
private _captureSnapshotBuffered;
|
|
135
|
+
private _captureSnapshot;
|
|
136
|
+
private _snapshotUrl;
|
|
137
|
+
private get _sessionDuration();
|
|
138
|
+
private _clearBufferBeforeMostRecentMeta;
|
|
139
|
+
private _clearBuffer;
|
|
140
|
+
private _onBeforeUnload;
|
|
141
|
+
private _onOffline;
|
|
142
|
+
private _onOnline;
|
|
143
|
+
private _onVisibilityChange;
|
|
144
|
+
private _reportStarted;
|
|
145
|
+
private _isInteractiveEvent;
|
|
146
|
+
private _updateWindowAndSessionIds;
|
|
147
|
+
private _clearConditionalRecordingPersistence;
|
|
148
|
+
private _makeSamplingDecision;
|
|
149
|
+
private _addEventTriggerListener;
|
|
150
|
+
get sdkDebugProperties(): Properties;
|
|
151
|
+
private _startRecorder;
|
|
152
|
+
tryAddCustomEvent(tag: string, payload: any): boolean;
|
|
153
|
+
}
|