humanbehavior-js 0.4.22 → 0.4.24

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.
Files changed (52) hide show
  1. package/dist/cjs/angular/index.cjs +276 -387
  2. package/dist/cjs/angular/index.cjs.map +1 -1
  3. package/dist/cjs/index.cjs +272 -383
  4. package/dist/cjs/index.cjs.map +1 -1
  5. package/dist/cjs/install-wizard.cjs +5 -5
  6. package/dist/cjs/install-wizard.cjs.map +1 -1
  7. package/dist/cjs/react/index.cjs +282 -393
  8. package/dist/cjs/react/index.cjs.map +1 -1
  9. package/dist/cjs/remix/index.cjs +272 -383
  10. package/dist/cjs/remix/index.cjs.map +1 -1
  11. package/dist/cjs/svelte/index.cjs +272 -383
  12. package/dist/cjs/svelte/index.cjs.map +1 -1
  13. package/dist/cjs/vue/index.cjs +272 -383
  14. package/dist/cjs/vue/index.cjs.map +1 -1
  15. package/dist/cjs/wizard/index.cjs +5 -5
  16. package/dist/cjs/wizard/index.cjs.map +1 -1
  17. package/dist/cli/ai-auto-install.js +5 -5
  18. package/dist/cli/ai-auto-install.js.map +1 -1
  19. package/dist/cli/auto-install.js +5 -5
  20. package/dist/cli/auto-install.js.map +1 -1
  21. package/dist/esm/angular/index.js +276 -387
  22. package/dist/esm/angular/index.js.map +1 -1
  23. package/dist/esm/index.js +272 -383
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/install-wizard.js +5 -5
  26. package/dist/esm/install-wizard.js.map +1 -1
  27. package/dist/esm/react/index.js +282 -393
  28. package/dist/esm/react/index.js.map +1 -1
  29. package/dist/esm/remix/index.js +272 -383
  30. package/dist/esm/remix/index.js.map +1 -1
  31. package/dist/esm/svelte/index.js +272 -383
  32. package/dist/esm/svelte/index.js.map +1 -1
  33. package/dist/esm/vue/index.js +272 -383
  34. package/dist/esm/vue/index.js.map +1 -1
  35. package/dist/esm/wizard/index.js +5 -5
  36. package/dist/esm/wizard/index.js.map +1 -1
  37. package/dist/index.min.js +1 -1
  38. package/dist/index.min.js.map +1 -1
  39. package/dist/types/angular/index.d.ts +39 -9
  40. package/dist/types/index.d.ts +74 -59
  41. package/dist/types/install-wizard.d.ts +1 -1
  42. package/dist/types/react/index.d.ts +40 -10
  43. package/dist/types/remix/index.d.ts +37 -7
  44. package/dist/types/svelte/index.d.ts +37 -7
  45. package/dist/types/wizard/index.d.ts +1 -1
  46. package/package.json +1 -1
  47. package/readme.md +59 -5
  48. package/src/angular/index.ts +4 -4
  49. package/src/react/index.tsx +10 -10
  50. package/src/redact.ts +205 -399
  51. package/src/tracker.ts +103 -19
  52. package/src/wizard/core/install-wizard.ts +5 -5
package/src/tracker.ts CHANGED
@@ -61,7 +61,12 @@ export class HumanBehaviorTracker {
61
61
  public static init(apiKey: string, options?: {
62
62
  ingestionUrl?: string;
63
63
  logLevel?: 'none' | 'error' | 'warn' | 'info' | 'debug';
64
- redactFields?: string[];
64
+ redactFields?: string[]; // DEPRECATED: Use redactionStrategy instead
65
+ redactionStrategy?: {
66
+ mode: 'privacy-first' | 'visibility-first'; // Default: 'privacy-first'
67
+ unredactFields?: string[]; // Fields to make visible (when mode: 'privacy-first')
68
+ redactFields?: string[]; // Fields to hide (when mode: 'visibility-first')
69
+ };
65
70
  enableAutomaticTracking?: boolean;
66
71
  suppressConsoleErrors?: boolean; // New option to control error suppression
67
72
  recordCanvas?: boolean; // Enable canvas recording with protection
@@ -162,11 +167,22 @@ export class HumanBehaviorTracker {
162
167
  // Store canvas recording preference
163
168
  tracker.recordCanvas = options?.recordCanvas ?? false;
164
169
 
165
- // Set redacted fields if specified
170
+ // Set unredacted fields if specified (legacy support)
166
171
  if (options?.redactFields) {
167
- tracker.setRedactedFields(options.redactFields);
168
- // ✅ Apply redaction classes to existing elements
169
- tracker.redactionManager.applyRedactionClasses();
172
+ tracker.setUnredactedFields(options.redactFields);
173
+ }
174
+
175
+ // Handle new redaction strategy
176
+ if (options?.redactionStrategy) {
177
+ if (options.redactionStrategy.mode === 'privacy-first') {
178
+ if (options.redactionStrategy.unredactFields) {
179
+ tracker.setUnredactedFields(options.redactionStrategy.unredactFields);
180
+ }
181
+ } else {
182
+ if (options.redactionStrategy.redactFields) {
183
+ tracker.setRedactedFields(options.redactionStrategy.redactFields);
184
+ }
185
+ }
170
186
  }
171
187
 
172
188
  // Setup automatic tracking if enabled
@@ -183,6 +199,12 @@ export class HumanBehaviorTracker {
183
199
  constructor(apiKey: string | undefined, ingestionUrl?: string, options?: {
184
200
  enableAutomaticProperties?: boolean;
185
201
  propertyDenylist?: string[];
202
+ redactionStrategy?: {
203
+ mode: 'privacy-first' | 'visibility-first';
204
+ unredactFields?: string[];
205
+ redactFields?: string[];
206
+ };
207
+ redactFields?: string[]; // Legacy support
186
208
  }) {
187
209
  if (!apiKey) {
188
210
  throw new Error('Human Behavior API Key is required');
@@ -197,7 +219,10 @@ export class HumanBehaviorTracker {
197
219
  ingestionUrl: ingestionUrl || defaultIngestionUrl
198
220
  });
199
221
  this.apiKey = apiKey;
200
- this.redactionManager = new RedactionManager();
222
+ this.redactionManager = new RedactionManager({
223
+ redactionStrategy: options?.redactionStrategy,
224
+ legacyRedactFields: options?.redactFields // For backward compatibility
225
+ });
201
226
 
202
227
  // Initialize property manager
203
228
  this.propertyManager = new PropertyManager({
@@ -880,6 +905,31 @@ export class HumanBehaviorTracker {
880
905
  throw new Error(`Failed to identify user: ${userResponse.statusText}`);
881
906
  }
882
907
 
908
+ // Get IP info and GeoIP data
909
+ try {
910
+ const ipResponse = await fetch(`${this.api['baseUrl']}/api/ingestion/ip-info`, {
911
+ method: 'POST',
912
+ headers: {
913
+ 'Content-Type': 'application/json',
914
+ 'Authorization': `Bearer ${this.apiKey}`
915
+ },
916
+ body: JSON.stringify({
917
+ sessionId: this.sessionId,
918
+ clientIP: null, // Let server detect from headers
919
+ ipDetectionMethod: 'headers',
920
+ timestamp: new Date().toISOString()
921
+ })
922
+ });
923
+
924
+ if (ipResponse.ok) {
925
+ logDebug('✅ IP info and GeoIP data retrieved successfully');
926
+ } else {
927
+ logDebug(`⚠️ IP info request failed: ${ipResponse.statusText}`);
928
+ }
929
+ } catch (error) {
930
+ logDebug(`⚠️ IP info request error: ${error}`);
931
+ }
932
+
883
933
  // Don't update endUserId - keep it as the original UUID
884
934
 
885
935
  return originalEndUserId || '';
@@ -923,7 +973,7 @@ export class HumanBehaviorTracker {
923
973
  // ✅ HUMANBEHAVIOR'S CUSTOM SETTINGS
924
974
  maskTextSelector: this.redactionManager.getMaskTextSelector() || undefined,
925
975
  maskTextFn: undefined,
926
- maskAllInputs: true, // HumanBehavior default
976
+ maskAllInputs: this.redactionManager.getRedactionMode() === 'privacy-first', // Configurable based on strategy
927
977
  maskInputOptions: { password: true }, // HumanBehavior default
928
978
  maskInputFn: undefined,
929
979
  slimDOMOptions: {},
@@ -1243,17 +1293,26 @@ export class HumanBehaviorTracker {
1243
1293
  }
1244
1294
 
1245
1295
  /**
1246
- * Set specific fields to be redacted during session recording
1247
- * Uses rrweb's built-in masking instead of custom redaction processing
1248
- * @param fields Array of CSS selectors for fields to redact (e.g., ['input[type="password"]', '#email-field'])
1296
+ * Set specific fields to be redacted (for visibility-first mode)
1297
+ * @param fields Array of CSS selectors for fields to redact
1249
1298
  */
1250
1299
  public setRedactedFields(fields: string[]): void {
1251
1300
  this.redactionManager.setFieldsToRedact(fields);
1252
1301
 
1253
- // ✅ APPLY RRWEB MASKING CLASSES - More reliable than custom processing
1254
- this.redactionManager.applyRedactionClasses();
1302
+ // ✅ RESTART RECORDING WITH NEW SETTINGS - Ensures redaction is applied
1303
+ if (this.recordInstance) {
1304
+ this.restartWithNewRedaction();
1305
+ }
1306
+ }
1307
+
1308
+ /**
1309
+ * Set specific fields to be unredacted (everything else stays redacted by rrweb)
1310
+ * @param fields Array of CSS selectors for fields to unredact (e.g., ['#username', '#comment'])
1311
+ */
1312
+ public setUnredactedFields(fields: string[]): void {
1313
+ this.redactionManager.setFieldsToUnredact(fields);
1255
1314
 
1256
- // ✅ RESTART RECORDING WITH NEW SETTINGS - Ensures masking is applied
1315
+ // ✅ RESTART RECORDING WITH NEW SETTINGS - Ensures unredaction is applied
1257
1316
  if (this.recordInstance) {
1258
1317
  this.restartWithNewRedaction();
1259
1318
  }
@@ -1267,17 +1326,42 @@ export class HumanBehaviorTracker {
1267
1326
  }
1268
1327
 
1269
1328
  /**
1270
- * Check if redaction is currently active
1329
+ * Check if any fields are currently unredacted
1330
+ */
1331
+ public hasUnredactedFields(): boolean {
1332
+ return this.redactionManager.hasUnredactedFields();
1333
+ }
1334
+
1335
+ /**
1336
+ * Get the currently unredacted fields
1271
1337
  */
1272
- public isRedactionActive(): boolean {
1273
- return this.redactionManager.isActive();
1338
+ public getUnredactedFields(): string[] {
1339
+ return this.redactionManager.getUnredactedFields();
1274
1340
  }
1275
1341
 
1276
1342
  /**
1277
- * Get the currently selected fields for redaction
1343
+ * Remove specific fields from unredaction (they become redacted again)
1344
+ * @param fields Array of CSS selectors for fields to redact
1278
1345
  */
1279
- public getRedactedFields(): string[] {
1280
- return this.redactionManager.getSelectedFields();
1346
+ public redactFields(fields: string[]): void {
1347
+ this.redactionManager.redactFields(fields);
1348
+
1349
+ // ✅ RESTART RECORDING WITH NEW SETTINGS - Ensures redaction is updated
1350
+ if (this.recordInstance) {
1351
+ this.restartWithNewRedaction();
1352
+ }
1353
+ }
1354
+
1355
+ /**
1356
+ * Clear all unredacted fields (everything becomes redacted again)
1357
+ */
1358
+ public clearUnredactedFields(): void {
1359
+ this.redactionManager.clearUnredactedFields();
1360
+
1361
+ // ✅ RESTART RECORDING WITH NEW SETTINGS - Ensures redaction is updated
1362
+ if (this.recordInstance) {
1363
+ this.restartWithNewRedaction();
1364
+ }
1281
1365
  }
1282
1366
 
1283
1367
  /**
@@ -299,17 +299,17 @@ export class AutoInstallationWizard {
299
299
  }
300
300
 
301
301
  /**
302
- * Install the SDK package
302
+ * Install the SDK package with latest version range
303
303
  */
304
304
  protected async installPackage(): Promise<void> {
305
305
  const { execSync } = await import('child_process');
306
306
 
307
- // Build base command
307
+ // Build base command with latest version range
308
308
  let command = this.framework?.packageManager === 'yarn'
309
- ? 'yarn add humanbehavior-js'
309
+ ? 'yarn add humanbehavior-js@latest'
310
310
  : this.framework?.packageManager === 'pnpm'
311
- ? 'pnpm add humanbehavior-js'
312
- : 'npm install humanbehavior-js';
311
+ ? 'pnpm add humanbehavior-js@latest'
312
+ : 'npm install humanbehavior-js@latest';
313
313
 
314
314
  // Add legacy peer deps flag for npm to handle dependency conflicts
315
315
  if (this.framework?.packageManager !== 'yarn' && this.framework?.packageManager !== 'pnpm') {