humanbehavior-js 0.2.3 → 0.2.4

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.
@@ -194,6 +194,10 @@ declare class HumanBehaviorTracker {
194
194
  userId?: string;
195
195
  userProperties: Record<string, any>;
196
196
  }): Promise<string>;
197
+ /**
198
+ * Get current user attributes
199
+ */
200
+ getUserAttributes(): Record<string, any>;
197
201
  start(): Promise<void>;
198
202
  stop(): Promise<void>;
199
203
  addEvent(event: any): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanbehavior-js",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "SDK for HumanBehavior session and event recording",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
package/simple-spa.html CHANGED
@@ -228,6 +228,57 @@
228
228
  <button class="button secondary" onclick="trackCustomEvent('demo_button_2', {button: 'demo2'})">Demo Button 2</button>
229
229
  <button class="button success" onclick="trackCustomEvent('demo_button_3', {button: 'demo3'})">Demo Button 3</button>
230
230
 
231
+ <h3>User Authentication Test</h3>
232
+ <button class="button" onclick="testUserAuthentication()">
233
+ Test User Authentication
234
+ </button>
235
+ <p style="font-size: 12px; color: #666; margin-top: 5px;">
236
+ Tests the new behavior where endUserId stays the same but posthogName gets updated with email
237
+ </p>
238
+
239
+ <h3>Real User Authentication</h3>
240
+ <form onsubmit="handleAuthSubmit(event)" style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px; margin: 15px 0;">
241
+ <div style="margin-bottom: 15px;">
242
+ <label for="authEmail" style="display: block; margin-bottom: 5px; font-weight: 600;">Email:</label>
243
+ <input type="email" id="authEmail" placeholder="your.email@example.com" required
244
+ style="width: 100%; padding: 10px; border-radius: 5px; border: none; background: rgba(255,255,255,0.9);">
245
+ </div>
246
+
247
+ <div style="margin-bottom: 15px;">
248
+ <label for="authName" style="display: block; margin-bottom: 5px; font-weight: 600;">Name:</label>
249
+ <input type="text" id="authName" placeholder="Your Name" required
250
+ style="width: 100%; padding: 10px; border-radius: 5px; border: none; background: rgba(255,255,255,0.9);">
251
+ </div>
252
+
253
+ <div style="margin-bottom: 15px;">
254
+ <label for="authPlan" style="display: block; margin-bottom: 5px; font-weight: 600;">Plan:</label>
255
+ <select id="authPlan" style="width: 100%; padding: 10px; border-radius: 5px; border: none; background: rgba(255,255,255,0.9);">
256
+ <option value="free">Free</option>
257
+ <option value="basic">Basic</option>
258
+ <option value="premium">Premium</option>
259
+ <option value="enterprise">Enterprise</option>
260
+ </select>
261
+ </div>
262
+
263
+ <div style="margin-bottom: 15px;">
264
+ <label for="authCompany" style="display: block; margin-bottom: 5px; font-weight: 600;">Company (Optional):</label>
265
+ <input type="text" id="authCompany" placeholder="Your Company"
266
+ style="width: 100%; padding: 10px; border-radius: 5px; border: none; background: rgba(255,255,255,0.9);">
267
+ </div>
268
+
269
+ <button type="submit" class="button success" style="width: 100%;">
270
+ 🔐 Authenticate User
271
+ </button>
272
+ </form>
273
+
274
+ <div style="margin-top: 15px; display: flex; gap: 10px;">
275
+ <button class="button secondary" onclick="showAuthStatus()" style="flex: 1;">
276
+ 📊 Show Auth Status
277
+ </button>
278
+ </div>
279
+
280
+ <div id="authResult" style="margin-top: 15px; padding: 10px; border-radius: 5px; display: none;"></div>
281
+
231
282
  <div class="logs" id="demoLogs">
232
283
  <div>Demo events will appear here...</div>
233
284
  </div>
@@ -498,7 +549,45 @@
498
549
  addLog('customEvent method not available');
499
550
  }
500
551
  } catch (error) {
501
- addLog(`Error tracking event: ${error.message}`);
552
+ console.error('Error tracking custom event:', error);
553
+ addLog('Error tracking custom event: ' + error.message);
554
+ }
555
+ }
556
+
557
+ // Test user authentication (new behavior)
558
+ async function testUserAuthentication() {
559
+ if (!tracker) {
560
+ addLog('Tracker not available');
561
+ return;
562
+ }
563
+
564
+ try {
565
+ const originalEndUserId = tracker.getSessionId();
566
+ addLog(`Original endUserId: ${originalEndUserId}`);
567
+
568
+ // Simulate user sign-in
569
+ const userId = await tracker.addUserInfo({
570
+ userId: 'user123@example.com',
571
+ userProperties: {
572
+ email: 'user123@example.com',
573
+ name: 'John Doe',
574
+ plan: 'premium',
575
+ signupDate: new Date().toISOString()
576
+ }
577
+ });
578
+
579
+ const newEndUserId = tracker.getSessionId();
580
+ addLog(`New endUserId: ${newEndUserId}`);
581
+ addLog(`endUserId changed: ${originalEndUserId !== newEndUserId ? 'YES (BAD)' : 'NO (GOOD)'}`);
582
+ addLog(`User authenticated: ${userId}`);
583
+
584
+ // The endUserId should stay the same, but posthogName will be updated with email
585
+ addLog('✅ endUserId maintained for session continuity');
586
+ addLog('✅ posthogName will be updated with email for UI display');
587
+
588
+ } catch (error) {
589
+ console.error('Error testing user authentication:', error);
590
+ addLog('Error testing user authentication: ' + error.message);
502
591
  }
503
592
  }
504
593
 
@@ -524,6 +613,60 @@
524
613
 
525
614
  input.value = '';
526
615
  }
616
+
617
+ // Handle authentication form submission
618
+ async function handleAuthSubmit(event) {
619
+ event.preventDefault();
620
+ const email = document.getElementById('authEmail').value;
621
+ const name = document.getElementById('authName').value;
622
+ const plan = document.getElementById('authPlan').value;
623
+ const company = document.getElementById('authCompany').value;
624
+
625
+ if (!email || !name) {
626
+ alert('Email and Name are required for authentication.');
627
+ return;
628
+ }
629
+
630
+ try {
631
+ const userId = await tracker.addUserInfo({
632
+ userId: email, // Use email as userId
633
+ userProperties: {
634
+ email: email,
635
+ name: name,
636
+ plan: plan,
637
+ company: company,
638
+ signupDate: new Date().toISOString()
639
+ }
640
+ });
641
+
642
+ const newEndUserId = tracker.getSessionId();
643
+ addLog(`New endUserId after authentication: ${newEndUserId}`);
644
+ addLog(`endUserId changed: ${tracker.getSessionId() !== newEndUserId ? 'YES (BAD)' : 'NO (GOOD)'}`);
645
+ addLog(`User authenticated: ${userId}`);
646
+
647
+ const authResultDiv = document.getElementById('authResult');
648
+ authResultDiv.style.display = 'block';
649
+ authResultDiv.innerHTML = `
650
+ <strong>Authentication Successful!</strong><br>
651
+ New End User ID: ${newEndUserId}<br>
652
+ Original End User ID: ${tracker.getSessionId()}<br>
653
+ endUserId changed: ${tracker.getSessionId() !== newEndUserId ? 'YES (BAD)' : 'NO (GOOD)'}
654
+ `;
655
+ authResultDiv.style.color = 'green';
656
+
657
+ } catch (error) {
658
+ console.error('Error authenticating user:', error);
659
+ addLog('Error authenticating user: ' + error.message);
660
+
661
+ const authResultDiv = document.getElementById('authResult');
662
+ authResultDiv.style.display = 'block';
663
+ authResultDiv.innerHTML = `
664
+ <strong>Authentication Failed!</strong><br>
665
+ Error: ${error.message}
666
+ `;
667
+ authResultDiv.style.color = 'red';
668
+ }
669
+ }
527
670
 
528
671
  // View logs
529
672
  function viewLogs() {
@@ -571,8 +714,7 @@
571
714
  try {
572
715
  const userInfo = tracker.getUserInfo ? tracker.getUserInfo() : null;
573
716
  if (userInfo) {
574
- const infoText = `
575
- <strong>Detailed User Information:</strong><br>
717
+ const infoText = ` <strong>Detailed User Information:</strong><br>
576
718
  End User ID: ${userInfo.endUserId || 'Not set'}<br>
577
719
  Session ID: ${userInfo.sessionId}<br>
578
720
  Is Preexisting User: ${userInfo.isPreexistingUser ? 'Yes' : 'No'}<br>
@@ -593,6 +735,44 @@
593
735
  addLog(`Error getting user info: ${error.message}`);
594
736
  }
595
737
  }
738
+
739
+ // Show current authentication status
740
+ function showAuthStatus() {
741
+ if (!tracker) {
742
+ addLog('Tracker not available');
743
+ return;
744
+ }
745
+ try {
746
+ const userInfo = tracker.getUserInfo ? tracker.getUserInfo() : null;
747
+ const userAttributes = tracker.getUserAttributes ? tracker.getUserAttributes() : {};
748
+
749
+ if (userInfo) {
750
+ const statusText = `
751
+ <strong>Current Authentication Status:</strong><br>
752
+ End User ID: ${userInfo.endUserId || 'Not set'}<br>
753
+ Session ID: ${userInfo.sessionId}<br>
754
+ Is Preexisting User: ${userInfo.isPreexistingUser ? 'Yes' : 'No'}<br>
755
+ Initialized: ${userInfo.initialized ? 'Yes' : 'No'}<br>
756
+ <br>
757
+ <strong>User Attributes:</strong><br>
758
+ ${Object.keys(userAttributes).length > 0 ?
759
+ Object.entries(userAttributes).map(([key, value]) => `${key}: ${value}`).join('<br>') :
760
+ 'No user attributes set'
761
+ }
762
+ <br><br>
763
+ <strong>Cookie Check:</strong><br>
764
+ End User Cookie: ${tracker.getCookie ? tracker.getCookie(`human_behavior_end_user_id_13c3e029-ca45-4a3c-a33b-f5dcb297e31c`) : 'Method not available'}<br>
765
+ Session Cookie: ${tracker.getCookie ? tracker.getCookie('human_behavior_session_id') : 'Method not available'}
766
+ `;
767
+ addLog('Authentication status displayed', { userInfo, userAttributes });
768
+ alert(statusText);
769
+ } else {
770
+ addLog('getUserInfo method not available for status');
771
+ }
772
+ } catch (error) {
773
+ addLog(`Error getting authentication status: ${error.message}`);
774
+ }
775
+ }
596
776
 
597
777
  // Add log message
598
778
  function addLog(message, data = null) {
@@ -655,4 +835,4 @@
655
835
  }, 5000); // Check every 5 seconds
656
836
  </script>
657
837
  </body>
658
- </html>
838
+ </html>
package/src/api.ts CHANGED
@@ -222,24 +222,31 @@ export class HumanBehaviorAPI {
222
222
 
223
223
  async sendUserData(userId: string, userData: Record<string, any>, sessionId: string) {
224
224
  try {
225
+ const payload = {
226
+ userId: userId,
227
+ userAttributes: userData,
228
+ sessionId: sessionId,
229
+ posthogName: userData.email || userData.name || null // Update posthogName with email
230
+ };
231
+
232
+ console.log('Sending user data to server:', payload);
233
+
225
234
  const response = await fetch(`${this.baseUrl}/api/ingestion/user`, {
226
235
  method: 'POST',
227
236
  headers: {
228
237
  'Content-Type': 'application/json',
229
238
  'Authorization': `Bearer ${this.apiKey}`
230
239
  },
231
- body: JSON.stringify({
232
- userId: userId,
233
- userAttributes: userData,
234
- sessionId: sessionId
235
- })
240
+ body: JSON.stringify(payload)
236
241
  });
237
242
 
238
243
  if (!response.ok) {
239
244
  throw new Error(`Failed to send user data: ${response.statusText} with API key: ${this.apiKey}`);
240
245
  }
241
246
 
242
- return await response.json();
247
+ const result = await response.json();
248
+ console.log('Server response:', result);
249
+ return result;
243
250
  } catch (error) {
244
251
  logError('Error sending user data:', error);
245
252
  throw error;
package/src/tracker.ts CHANGED
@@ -725,19 +725,26 @@ export class HumanBehaviorTracker {
725
725
  { userId, userProperties }: { userId?: string, userProperties: Record<string, any> }
726
726
  ): Promise<string> {
727
727
  await this.ensureInitialized();
728
- // Determine the userId to use
729
- const resolvedUserId = userId || userProperties.email;
730
- if (!resolvedUserId) {
731
- return this.endUserId || '';
732
- }
728
+
729
+ // Keep the original endUserId (UUID) - don't change it
730
+ const originalEndUserId = this.endUserId;
731
+
732
+ // Store user properties
733
733
  this.userProperties = userProperties;
734
- await this.api.sendUserData(resolvedUserId, userProperties, this.sessionId);
735
- // Update endUserId and cookie if changed
736
- if (resolvedUserId !== this.endUserId) {
737
- this.endUserId = resolvedUserId;
738
- this.setCookie(`human_behavior_end_user_id_${this.apiKey}`, resolvedUserId, 365);
739
- }
740
- return this.endUserId || '';
734
+
735
+ // Send user data with the original endUserId
736
+ await this.api.sendUserData(originalEndUserId!, userProperties, this.sessionId);
737
+
738
+ // Don't update endUserId - keep it as the original UUID
739
+ // The posthogName will be updated on the server side with the email
740
+
741
+ return originalEndUserId || '';
742
+ }
743
+ /**
744
+ * Get current user attributes
745
+ */
746
+ public getUserAttributes(): Record<string, any> {
747
+ return { ...this.userProperties };
741
748
  }
742
749
 
743
750
  public async start() {