humanbehavior-js 0.0.8 → 0.0.9
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/cjs/index.js +254 -41
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/index.js +188 -51
- package/dist/cjs/react/index.js.map +1 -1
- package/dist/esm/index.js +250 -42
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/index.js +189 -52
- package/dist/esm/react/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/types/index.d.ts +59 -2
- package/package.json +2 -2
- package/src/api.ts +8 -6
- package/src/index.ts +3 -0
- package/src/react/index.tsx +85 -62
- package/src/redact.ts +19 -17
- package/src/tracker.ts +139 -20
- package/src/utils/logger.ts +144 -0
package/dist/types/index.d.ts
CHANGED
|
@@ -101,10 +101,34 @@ declare class HumanBehaviorTracker {
|
|
|
101
101
|
private initialized;
|
|
102
102
|
initializationPromise: Promise<void> | null;
|
|
103
103
|
private redactionManager;
|
|
104
|
+
private originalConsole;
|
|
105
|
+
private originalLogger;
|
|
106
|
+
private consoleTrackingEnabled;
|
|
104
107
|
constructor(apiKey: string | undefined, ingestionUrl?: string);
|
|
105
108
|
private init;
|
|
106
109
|
private ensureInitialized;
|
|
107
110
|
static logToStorage(message: string): void;
|
|
111
|
+
/**
|
|
112
|
+
* Configure logging behavior for the SDK
|
|
113
|
+
* @param config Logger configuration options
|
|
114
|
+
*/
|
|
115
|
+
static configureLogging(config: {
|
|
116
|
+
level?: 'none' | 'error' | 'warn' | 'info' | 'debug';
|
|
117
|
+
enableConsole?: boolean;
|
|
118
|
+
enableStorage?: boolean;
|
|
119
|
+
}): void;
|
|
120
|
+
/**
|
|
121
|
+
* Enable console event tracking
|
|
122
|
+
*/
|
|
123
|
+
enableConsoleTracking(): void;
|
|
124
|
+
/**
|
|
125
|
+
* Disable console event tracking
|
|
126
|
+
*/
|
|
127
|
+
disableConsoleTracking(): void;
|
|
128
|
+
/**
|
|
129
|
+
* Track console events
|
|
130
|
+
*/
|
|
131
|
+
private trackConsoleEvent;
|
|
108
132
|
private setupPageUnloadHandler;
|
|
109
133
|
viewLogs(): void;
|
|
110
134
|
addUserInfo(userProperties: Record<string, any>): Promise<void>;
|
|
@@ -168,5 +192,38 @@ declare class HumanBehaviorAPI {
|
|
|
168
192
|
sendBeaconCustomEvents(events: any[], sessionId: string): boolean;
|
|
169
193
|
}
|
|
170
194
|
|
|
171
|
-
|
|
172
|
-
|
|
195
|
+
declare enum LogLevel {
|
|
196
|
+
NONE = 0,
|
|
197
|
+
ERROR = 1,
|
|
198
|
+
WARN = 2,
|
|
199
|
+
INFO = 3,
|
|
200
|
+
DEBUG = 4
|
|
201
|
+
}
|
|
202
|
+
interface LoggerConfig {
|
|
203
|
+
level: LogLevel;
|
|
204
|
+
enableConsole: boolean;
|
|
205
|
+
enableStorage: boolean;
|
|
206
|
+
}
|
|
207
|
+
declare class Logger {
|
|
208
|
+
private config;
|
|
209
|
+
private isBrowser;
|
|
210
|
+
constructor(config?: Partial<LoggerConfig>);
|
|
211
|
+
setConfig(config: Partial<LoggerConfig>): void;
|
|
212
|
+
private shouldLog;
|
|
213
|
+
private formatMessage;
|
|
214
|
+
error(message: string, ...args: any[]): void;
|
|
215
|
+
warn(message: string, ...args: any[]): void;
|
|
216
|
+
info(message: string, ...args: any[]): void;
|
|
217
|
+
debug(message: string, ...args: any[]): void;
|
|
218
|
+
private logToStorage;
|
|
219
|
+
getLogs(): any[];
|
|
220
|
+
clearLogs(): void;
|
|
221
|
+
}
|
|
222
|
+
declare const logger: Logger;
|
|
223
|
+
declare const logError: (message: string, ...args: any[]) => void;
|
|
224
|
+
declare const logWarn: (message: string, ...args: any[]) => void;
|
|
225
|
+
declare const logInfo: (message: string, ...args: any[]) => void;
|
|
226
|
+
declare const logDebug: (message: string, ...args: any[]) => void;
|
|
227
|
+
|
|
228
|
+
export { HumanBehaviorAPI, HumanBehaviorTracker, LogLevel, MAX_CHUNK_SIZE_BYTES, RedactionManager, HumanBehaviorTracker as default, isChunkSizeExceeded, logDebug, logError, logInfo, logWarn, logger, redactionManager, validateSingleEventSize };
|
|
229
|
+
export type { LoggerConfig, RedactionOptions };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "humanbehavior-js",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "SDK for HumanBehavior session and event recording",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"repository": {
|
|
51
51
|
"type": "git",
|
|
52
|
-
"url": "https://github.com/humanbehavior-gh/HumanBehavior.git"
|
|
52
|
+
"url": "git+https://github.com/humanbehavior-gh/HumanBehavior.git"
|
|
53
53
|
},
|
|
54
54
|
"keywords": [
|
|
55
55
|
"session-recording",
|
package/src/api.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { logError, logInfo } from './utils/logger';
|
|
2
|
+
|
|
1
3
|
export const MAX_CHUNK_SIZE_BYTES = 1024 * 1024 * 10; // 10MB chunk size
|
|
2
4
|
|
|
3
5
|
export function isChunkSizeExceeded(currentChunk: any[], newEvent: any, sessionId: string): boolean {
|
|
@@ -147,7 +149,7 @@ export class HumanBehaviorAPI {
|
|
|
147
149
|
|
|
148
150
|
return results.flat();
|
|
149
151
|
} catch (error) {
|
|
150
|
-
|
|
152
|
+
logError('Error sending events:', error);
|
|
151
153
|
throw error;
|
|
152
154
|
}
|
|
153
155
|
}
|
|
@@ -173,7 +175,7 @@ export class HumanBehaviorAPI {
|
|
|
173
175
|
|
|
174
176
|
return await response.json();
|
|
175
177
|
} catch (error) {
|
|
176
|
-
|
|
178
|
+
logError('Error sending user data:', error);
|
|
177
179
|
throw error;
|
|
178
180
|
}
|
|
179
181
|
}
|
|
@@ -200,7 +202,7 @@ export class HumanBehaviorAPI {
|
|
|
200
202
|
|
|
201
203
|
return await response.json();
|
|
202
204
|
} catch (error) {
|
|
203
|
-
|
|
205
|
+
logError('Error authenticating user:', error);
|
|
204
206
|
throw error;
|
|
205
207
|
}
|
|
206
208
|
}
|
|
@@ -248,7 +250,7 @@ export class HumanBehaviorAPI {
|
|
|
248
250
|
} catch (error) {
|
|
249
251
|
retryCount++;
|
|
250
252
|
if (retryCount === maxRetries) {
|
|
251
|
-
|
|
253
|
+
logError('Error sending custom event after max retries:', error);
|
|
252
254
|
throw error;
|
|
253
255
|
}
|
|
254
256
|
// Exponential backoff
|
|
@@ -285,7 +287,7 @@ export class HumanBehaviorAPI {
|
|
|
285
287
|
} catch (error) {
|
|
286
288
|
retryCount++;
|
|
287
289
|
if (retryCount === maxRetries) {
|
|
288
|
-
|
|
290
|
+
logError('Error sending custom events after max retries:', error);
|
|
289
291
|
throw error;
|
|
290
292
|
}
|
|
291
293
|
// Exponential backoff
|
|
@@ -301,7 +303,7 @@ export class HumanBehaviorAPI {
|
|
|
301
303
|
data.append('timestamp', encodeURIComponent(Date.now().toString()))
|
|
302
304
|
data.append('apiKey', encodeURIComponent(this.apiKey))
|
|
303
305
|
if (isSessionComplete) {
|
|
304
|
-
|
|
306
|
+
logInfo('Session complete beacon sending');
|
|
305
307
|
localStorage.setItem('koalaware_session_complete', Date.now().toString());
|
|
306
308
|
data.append('sessionComplete', encodeURIComponent('true'))
|
|
307
309
|
}
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,9 @@ export * from './api';
|
|
|
13
13
|
// Export redaction functionality
|
|
14
14
|
export * from './redact';
|
|
15
15
|
|
|
16
|
+
// Export logger functionality
|
|
17
|
+
export * from './utils/logger';
|
|
18
|
+
|
|
16
19
|
// Also export the tracker as the default export
|
|
17
20
|
export { HumanBehaviorTracker as default } from './tracker';
|
|
18
21
|
|
package/src/react/index.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import React, { useEffect, useState, createContext, useContext, ReactNode } from "react";
|
|
1
|
+
import React, { useEffect, useState, createContext, useContext, ReactNode, useCallback, useMemo, useRef } from "react";
|
|
2
2
|
import { HumanBehaviorTracker } from "..";
|
|
3
|
+
import { logError, logWarn, logDebug } from "../utils/logger";
|
|
3
4
|
|
|
4
5
|
// Check if we're in a browser environment
|
|
5
6
|
const isBrowser = () => typeof window !== 'undefined';
|
|
@@ -25,6 +26,7 @@ interface HumanBehaviorProviderProps {
|
|
|
25
26
|
children: ReactNode;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
// Default context to prevent unnecessary re-renders
|
|
28
30
|
const defaultContext: HumanBehaviorContextType = {
|
|
29
31
|
humanBehavior: null,
|
|
30
32
|
queueEvent: (event: any) => {
|
|
@@ -32,7 +34,7 @@ const defaultContext: HumanBehaviorContextType = {
|
|
|
32
34
|
if (typeof window === 'undefined') {
|
|
33
35
|
return;
|
|
34
36
|
}
|
|
35
|
-
|
|
37
|
+
logWarn('HumanBehavior not initialized yet, event queued:', event);
|
|
36
38
|
}
|
|
37
39
|
};
|
|
38
40
|
|
|
@@ -43,11 +45,27 @@ export const HumanBehaviorProvider = ({ apiKey, client, children }: HumanBehavio
|
|
|
43
45
|
const [eventQueue, setEventQueue] = useState<any[]>([]);
|
|
44
46
|
const [isMounted, setIsMounted] = useState(false);
|
|
45
47
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
48
|
+
|
|
49
|
+
// Use refs to avoid dependency issues in useEffect
|
|
50
|
+
const apiKeyRef = useRef(apiKey);
|
|
51
|
+
const clientRef = useRef(client);
|
|
52
|
+
const eventQueueRef = useRef(eventQueue);
|
|
53
|
+
|
|
54
|
+
// Update refs when props change
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
apiKeyRef.current = apiKey;
|
|
57
|
+
clientRef.current = client;
|
|
58
|
+
}, [apiKey, client]);
|
|
59
|
+
|
|
60
|
+
// Update eventQueue ref when queue changes
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
eventQueueRef.current = eventQueue;
|
|
63
|
+
}, [eventQueue]);
|
|
46
64
|
|
|
47
|
-
//
|
|
48
|
-
const queueEvent = (event: any) => {
|
|
65
|
+
// Memoized queueEvent function to prevent unnecessary re-renders
|
|
66
|
+
const queueEvent = useCallback((event: any) => {
|
|
49
67
|
setEventQueue(prev => [...prev, event]);
|
|
50
|
-
};
|
|
68
|
+
}, []);
|
|
51
69
|
|
|
52
70
|
// Handle mounting state
|
|
53
71
|
useEffect(() => {
|
|
@@ -66,15 +84,15 @@ export const HumanBehaviorProvider = ({ apiKey, client, children }: HumanBehavio
|
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
// If client is provided, use that
|
|
69
|
-
if (
|
|
70
|
-
setHumanBehavior(
|
|
87
|
+
if (clientRef.current) {
|
|
88
|
+
setHumanBehavior(clientRef.current);
|
|
71
89
|
setIsInitialized(true);
|
|
72
90
|
return;
|
|
73
91
|
}
|
|
74
92
|
|
|
75
93
|
// If no client is provided, apiKey is required
|
|
76
|
-
if (!
|
|
77
|
-
|
|
94
|
+
if (!apiKeyRef.current || apiKeyRef.current.trim() === '') {
|
|
95
|
+
logError("An apiKey is required when no client is provided");
|
|
78
96
|
return;
|
|
79
97
|
}
|
|
80
98
|
|
|
@@ -83,7 +101,10 @@ export const HumanBehaviorProvider = ({ apiKey, client, children }: HumanBehavio
|
|
|
83
101
|
}
|
|
84
102
|
|
|
85
103
|
// Create new tracker instance with the validated apiKey
|
|
86
|
-
const tracker = new HumanBehaviorTracker(
|
|
104
|
+
const tracker = new HumanBehaviorTracker(
|
|
105
|
+
apiKeyRef.current.trim(),
|
|
106
|
+
process.env.NEXT_PUBLIC_INGESTION_URL || 'https://ingestion.humanbehavior.ai'
|
|
107
|
+
);
|
|
87
108
|
setHumanBehavior(tracker);
|
|
88
109
|
|
|
89
110
|
// Wait for initialization to complete
|
|
@@ -91,10 +112,11 @@ export const HumanBehaviorProvider = ({ apiKey, client, children }: HumanBehavio
|
|
|
91
112
|
setIsInitialized(true);
|
|
92
113
|
|
|
93
114
|
// Process any queued events
|
|
94
|
-
|
|
95
|
-
|
|
115
|
+
const currentQueue = eventQueueRef.current;
|
|
116
|
+
if (currentQueue.length > 0) {
|
|
117
|
+
currentQueue.forEach(event => {
|
|
96
118
|
if (event.type === 'identify') {
|
|
97
|
-
|
|
119
|
+
logDebug('Processing queued identify event', event.userProperties);
|
|
98
120
|
tracker.addUserInfo(event.userProperties);
|
|
99
121
|
} else {
|
|
100
122
|
tracker.addEvent(event);
|
|
@@ -103,40 +125,66 @@ export const HumanBehaviorProvider = ({ apiKey, client, children }: HumanBehavio
|
|
|
103
125
|
setEventQueue([]); // Clear the queue
|
|
104
126
|
}
|
|
105
127
|
}).catch(error => {
|
|
106
|
-
|
|
128
|
+
logError('Failed to initialize HumanBehaviorTracker:', error);
|
|
107
129
|
});
|
|
108
|
-
}, [apiKey, client, eventQueue
|
|
130
|
+
}, [isMounted, humanBehavior]); // Removed apiKey, client, eventQueue from dependencies
|
|
131
|
+
|
|
132
|
+
// Memoized context value to prevent unnecessary re-renders
|
|
133
|
+
const contextValue = useMemo(() => {
|
|
134
|
+
if (!isMounted) {
|
|
135
|
+
return { humanBehavior: null, queueEvent };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!isInitialized) {
|
|
139
|
+
return { humanBehavior: null, queueEvent };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return { humanBehavior, queueEvent };
|
|
143
|
+
}, [isMounted, isInitialized, humanBehavior, queueEvent]);
|
|
109
144
|
|
|
110
145
|
// If not in browser, render children without context
|
|
111
146
|
if (!(isBrowser())) {
|
|
112
147
|
return <>{children}</>;
|
|
113
148
|
}
|
|
114
149
|
|
|
115
|
-
// If not mounted yet, render children with queuing context
|
|
116
|
-
if (!isMounted) {
|
|
117
|
-
return (
|
|
118
|
-
<HumanBehaviorContext.Provider value={{ humanBehavior: null, queueEvent }}>
|
|
119
|
-
{children}
|
|
120
|
-
</HumanBehaviorContext.Provider>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// If not initialized yet, render children with queuing context
|
|
125
|
-
if (!isInitialized) {
|
|
126
|
-
return (
|
|
127
|
-
<HumanBehaviorContext.Provider value={{ humanBehavior: null, queueEvent }}>
|
|
128
|
-
{children}
|
|
129
|
-
</HumanBehaviorContext.Provider>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
150
|
return (
|
|
134
|
-
<HumanBehaviorContext.Provider value={
|
|
151
|
+
<HumanBehaviorContext.Provider value={contextValue}>
|
|
135
152
|
{children}
|
|
136
153
|
</HumanBehaviorContext.Provider>
|
|
137
154
|
);
|
|
138
155
|
};
|
|
139
156
|
|
|
157
|
+
// No-op implementation for server-side
|
|
158
|
+
const serverSideImplementation: HumanBehaviorInterface = {
|
|
159
|
+
addEvent: () => {},
|
|
160
|
+
addUserInfo: async () => {},
|
|
161
|
+
start: () => {},
|
|
162
|
+
stop: () => {},
|
|
163
|
+
viewLogs: () => {},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// Memoized queuing implementation for initialization period
|
|
167
|
+
const createQueuingImplementation = (queueEvent: (event: any) => void): HumanBehaviorInterface => ({
|
|
168
|
+
addEvent: (event: any) => {
|
|
169
|
+
queueEvent(event);
|
|
170
|
+
},
|
|
171
|
+
addUserInfo: async (userProperties: Record<string, any>) => {
|
|
172
|
+
queueEvent({
|
|
173
|
+
type: 'identify',
|
|
174
|
+
userProperties,
|
|
175
|
+
});
|
|
176
|
+
},
|
|
177
|
+
start: () => {
|
|
178
|
+
// Start will be called automatically when initialized
|
|
179
|
+
},
|
|
180
|
+
stop: () => {
|
|
181
|
+
// Stop is a no-op when not initialized
|
|
182
|
+
},
|
|
183
|
+
viewLogs: () => {
|
|
184
|
+
logWarn('Logs are not available until HumanBehaviorTracker is initialized');
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
140
188
|
export const useHumanBehavior = (): HumanBehaviorInterface => {
|
|
141
189
|
const context = useContext(HumanBehaviorContext);
|
|
142
190
|
|
|
@@ -147,14 +195,8 @@ export const useHumanBehavior = (): HumanBehaviorInterface => {
|
|
|
147
195
|
|
|
148
196
|
// If we're in the server-side, return a no-op implementation
|
|
149
197
|
if (typeof window === 'undefined') {
|
|
150
|
-
|
|
151
|
-
return
|
|
152
|
-
addEvent: () => {},
|
|
153
|
-
addUserInfo: async () => {},
|
|
154
|
-
start: () => {},
|
|
155
|
-
stop: () => {},
|
|
156
|
-
viewLogs: () => {},
|
|
157
|
-
};
|
|
198
|
+
logWarn('HumanBehavior is being used before being initialized');
|
|
199
|
+
return serverSideImplementation;
|
|
158
200
|
}
|
|
159
201
|
|
|
160
202
|
// If we have an initialized tracker, return it as the interface
|
|
@@ -166,24 +208,5 @@ export const useHumanBehavior = (): HumanBehaviorInterface => {
|
|
|
166
208
|
// - context.humanBehavior is null
|
|
167
209
|
// - context.queueEvent is available
|
|
168
210
|
// - we need to queue all operations until initialization completes
|
|
169
|
-
return
|
|
170
|
-
addEvent: (event: any) => {
|
|
171
|
-
context.queueEvent(event);
|
|
172
|
-
},
|
|
173
|
-
addUserInfo: async (userProperties: Record<string, any>) => {
|
|
174
|
-
context.queueEvent({
|
|
175
|
-
type: 'identify',
|
|
176
|
-
userProperties,
|
|
177
|
-
});
|
|
178
|
-
},
|
|
179
|
-
start: () => {
|
|
180
|
-
// Start will be called automatically when initialized
|
|
181
|
-
},
|
|
182
|
-
stop: () => {
|
|
183
|
-
// Stop is a no-op when not initialized
|
|
184
|
-
},
|
|
185
|
-
viewLogs: () => {
|
|
186
|
-
console.warn('Logs are not available until HumanBehaviorTracker is initialized');
|
|
187
|
-
}
|
|
188
|
-
};
|
|
211
|
+
return useMemo(() => createQueuingImplementation(context.queueEvent), [context.queueEvent]);
|
|
189
212
|
};
|
package/src/redact.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Redaction functionality for sensitive input fields
|
|
2
2
|
// This module provides methods to redact sensitive input fields in event recordings
|
|
3
3
|
|
|
4
|
+
import { logDebug, logWarn } from './utils/logger';
|
|
5
|
+
|
|
4
6
|
// Check if we're in a browser environment
|
|
5
7
|
const isBrowser = typeof window !== 'undefined';
|
|
6
8
|
|
|
@@ -39,18 +41,18 @@ export class RedactionManager {
|
|
|
39
41
|
fields.forEach(field => this.userSelectedFields.add(field));
|
|
40
42
|
|
|
41
43
|
if (fields.length > 0) {
|
|
42
|
-
|
|
44
|
+
logDebug(`Redaction: Active for ${fields.length} field(s):`, fields);
|
|
43
45
|
|
|
44
46
|
// Debug: Check if elements exist
|
|
45
47
|
fields.forEach(selector => {
|
|
46
48
|
const elements = document.querySelectorAll(selector);
|
|
47
|
-
|
|
49
|
+
logDebug(`Redaction: Found ${elements.length} element(s) for selector '${selector}'`);
|
|
48
50
|
elements.forEach((el, index) => {
|
|
49
|
-
|
|
51
|
+
logDebug(`Redaction: Element ${index} for '${selector}':`, el);
|
|
50
52
|
});
|
|
51
53
|
});
|
|
52
54
|
} else {
|
|
53
|
-
|
|
55
|
+
logDebug('Redaction: Disabled - no fields selected');
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
|
|
@@ -85,7 +87,7 @@ export class RedactionManager {
|
|
|
85
87
|
if (processedEvent.data.source === 5) { // Input event
|
|
86
88
|
const shouldRedact = this.isFieldSelected(processedEvent.data);
|
|
87
89
|
if (shouldRedact) {
|
|
88
|
-
|
|
90
|
+
logDebug('Redaction: Processing input event for redaction');
|
|
89
91
|
this.redactInputEvent(processedEvent.data);
|
|
90
92
|
}
|
|
91
93
|
}
|
|
@@ -114,14 +116,14 @@ export class RedactionManager {
|
|
|
114
116
|
return;
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
logDebug('Redaction: Redacting input event with text:', inputData.text);
|
|
118
120
|
|
|
119
121
|
// Redact all text-related properties that could contain input data
|
|
120
122
|
const textProperties = ['text', 'value', 'content', 'data', 'input', 'textContent'];
|
|
121
123
|
textProperties.forEach(prop => {
|
|
122
124
|
if (inputData[prop] !== undefined && typeof inputData[prop] === 'string') {
|
|
123
125
|
inputData[prop] = this.redactedText;
|
|
124
|
-
|
|
126
|
+
logDebug(`Redaction: Redacted property '${prop}'`);
|
|
125
127
|
}
|
|
126
128
|
});
|
|
127
129
|
|
|
@@ -129,7 +131,7 @@ export class RedactionManager {
|
|
|
129
131
|
Object.keys(inputData).forEach(key => {
|
|
130
132
|
if (typeof inputData[key] === 'string' && inputData[key].length > 0) {
|
|
131
133
|
inputData[key] = this.redactedText;
|
|
132
|
-
|
|
134
|
+
logDebug(`Redaction: Redacted additional property '${key}'`);
|
|
133
135
|
}
|
|
134
136
|
});
|
|
135
137
|
|
|
@@ -137,11 +139,11 @@ export class RedactionManager {
|
|
|
137
139
|
if (inputData.attributes && typeof inputData.attributes === 'object') {
|
|
138
140
|
if (inputData.attributes.value && typeof inputData.attributes.value === 'string') {
|
|
139
141
|
inputData.attributes.value = this.redactedText;
|
|
140
|
-
|
|
142
|
+
logDebug('Redaction: Redacted nested value attribute');
|
|
141
143
|
}
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
logDebug('Redaction: Input event redaction complete');
|
|
145
147
|
}
|
|
146
148
|
|
|
147
149
|
/**
|
|
@@ -209,7 +211,7 @@ export class RedactionManager {
|
|
|
209
211
|
|
|
210
212
|
return false;
|
|
211
213
|
} catch (e) {
|
|
212
|
-
|
|
214
|
+
logWarn('Error checking if DOM change should be redacted:', e);
|
|
213
215
|
return false;
|
|
214
216
|
}
|
|
215
217
|
}
|
|
@@ -373,10 +375,10 @@ export class RedactionManager {
|
|
|
373
375
|
if (matchingElements.length > 0) {
|
|
374
376
|
// Check if any of these elements are currently focused
|
|
375
377
|
for (const el of matchingElements) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
if (el === document.activeElement) {
|
|
379
|
+
logDebug('Redaction: Found focused element matching selector:', selector);
|
|
380
|
+
return true;
|
|
381
|
+
}
|
|
380
382
|
}
|
|
381
383
|
}
|
|
382
384
|
}
|
|
@@ -385,7 +387,7 @@ export class RedactionManager {
|
|
|
385
387
|
// Look for any input element that might be the active one
|
|
386
388
|
const activeElement = document.activeElement;
|
|
387
389
|
if (activeElement && this.shouldRedactElement(activeElement as HTMLElement)) {
|
|
388
|
-
|
|
390
|
+
logDebug('Redaction: Active element should be redacted');
|
|
389
391
|
return true;
|
|
390
392
|
}
|
|
391
393
|
|
|
@@ -423,7 +425,7 @@ export class RedactionManager {
|
|
|
423
425
|
|
|
424
426
|
return false;
|
|
425
427
|
} catch (e) {
|
|
426
|
-
|
|
428
|
+
logWarn('Error checking if field should be redacted:', e);
|
|
427
429
|
return false;
|
|
428
430
|
}
|
|
429
431
|
}
|