@truly-you/trulyyou-web-sdk 0.1.7 → 0.1.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.
@@ -11,10 +11,10 @@ export declare class TrulyYouSDK {
11
11
  private mockMobileDevice;
12
12
  constructor(config: TrulyYouSDKConfig);
13
13
  /**
14
- * Extract actual keyId from stored value (authFlowId_keyId format)
15
- * Returns just the keyId part after the underscore
14
+ * Helper to get keyId by authFlowId from localStorage
15
+ * Keys are stored as: trulyYouKeyId_<authFlowId> with value being just the keyId
16
16
  */
17
- private extractActualKeyId;
17
+ private getKeyIdByAuthFlowId;
18
18
  /**
19
19
  * Fetch app branding from SDK backend
20
20
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truly-you/trulyyou-web-sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "TrulyYou Web SDK for secure authentication and payload signing",
5
5
  "type": "module",
6
6
  "main": "dist/index.esm.js",
@@ -8,7 +8,7 @@ export class TrulyYouSDK {
8
8
  private authAppId: string | undefined
9
9
  private invisible: boolean
10
10
  private targetElement: string | HTMLElement | undefined
11
- private brandingCache: { primary?: string; background?: string; secondary?: string; textColor?: string; icon?: string; name?: string } | null = null
11
+ private brandingCache: { primary?: string; background?: string; secondary?: string; textColor?: string; icon?: string; name?: string; authFlowId?: string } | null = null
12
12
  private realtimeUrl: string
13
13
  private mockMobileDevice: boolean
14
14
 
@@ -43,19 +43,22 @@ export class TrulyYouSDK {
43
43
 
44
44
 
45
45
  /**
46
- * Extract actual keyId from stored value (authFlowId_keyId format)
47
- * Returns just the keyId part after the underscore
46
+ * Helper to get keyId by authFlowId from localStorage
47
+ * Keys are stored as: trulyYouKeyId_<authFlowId> with value being just the keyId
48
48
  */
49
- private extractActualKeyId(storedKeyId: string): string {
50
- // Format is: authFlowId_keyId
51
- // We only want the part after the underscore
52
- const parts = storedKeyId.split('_')
53
- if (parts.length > 1) {
54
- // Return everything after the first underscore
55
- return parts.slice(1).join('_')
49
+ private getKeyIdByAuthFlowId(authFlowId: string): string | null {
50
+ if (typeof window === 'undefined') return null
51
+
52
+ const storageKey = `trulyYouKeyId_${authFlowId}`
53
+ const keyId = localStorage.getItem(storageKey)
54
+
55
+ if (keyId) {
56
+ console.log(`[SDK]: Found keyId for authFlowId ${authFlowId}, key: ${storageKey}`)
57
+ return keyId
56
58
  }
57
- // If no underscore, return as-is (backward compatibility)
58
- return storedKeyId
59
+
60
+ console.log(`[SDK]: No keyId found for authFlowId: ${authFlowId}`)
61
+ return null
59
62
  }
60
63
 
61
64
  /**
@@ -74,16 +77,17 @@ export class TrulyYouSDK {
74
77
  const data = await response.json()
75
78
  // Handle both formats: { app: {...} } or direct app object
76
79
  const app = data.app || data
77
- if (app?.colors || app?.icon || app?.name) {
80
+ if (app?.colors || app?.icon || app?.name || app?.authFlowId) {
78
81
  this.brandingCache = {
79
82
  primary: app.colors?.primary,
80
83
  background: app.colors?.background,
81
84
  secondary: app.colors?.secondary,
82
85
  textColor: app.colors?.textColor,
83
86
  icon: app.icon,
84
- name: app.name
87
+ name: app.name,
88
+ authFlowId: app.authFlowId
85
89
  }
86
- console.log('[SDK]: Branding fetched and cached:', this.brandingCache)
90
+ console.log('[SDK]: Branding and authFlowId fetched and cached:', this.brandingCache)
87
91
  }
88
92
  }
89
93
  } catch (error) {
@@ -287,6 +291,15 @@ export class TrulyYouSDK {
287
291
  const probeUrl = new URL(`${this.frontendUrl}/sign`)
288
292
  probeUrl.searchParams.set('probe', 'true')
289
293
  probeUrl.searchParams.set('origin', origin)
294
+
295
+ // Add authFlowId if available from branding cache
296
+ if (this.brandingCache?.authFlowId) {
297
+ probeUrl.searchParams.set('authFlowId', this.brandingCache.authFlowId)
298
+ console.log('[SDK-PROBE]: Adding authFlowId to probe:', this.brandingCache.authFlowId)
299
+ } else {
300
+ console.log('[SDK-PROBE]: No authFlowId available in cache, will check for any key')
301
+ }
302
+
290
303
  iframe.src = probeUrl.toString()
291
304
 
292
305
  console.log('[SDK-PROBE]: Creating probe iframe with URL:', probeUrl.toString())
@@ -481,24 +494,23 @@ export class TrulyYouSDK {
481
494
  // Remove listener
482
495
  window.removeEventListener('message', handleMessage)
483
496
 
484
- // Get keyId from message first (avoids race condition with localStorage)
485
- // Fallback to localStorage if not in message
497
+ // Get keyId from message (enrollment page already stored it with authFlowId)
486
498
  const keyIdFromMessage = event.data.keyId
487
- const trulyYouKeyId = keyIdFromMessage || localStorage.getItem('trulyYouKeyId')
488
499
 
489
- if (trulyYouKeyId) {
490
- console.log('[SDK]: Enrollment successful, keyId obtained:', trulyYouKeyId, keyIdFromMessage ? '(from message)' : '(from localStorage)')
491
- // Also ensure it's in localStorage for future use
492
- if (keyIdFromMessage && !localStorage.getItem('trulyYouKeyId')) {
493
- localStorage.setItem('trulyYouKeyId', keyIdFromMessage)
494
- }
495
- resolve(trulyYouKeyId)
500
+ if (keyIdFromMessage) {
501
+ console.log('[SDK]: Enrollment successful, keyId obtained from message:', keyIdFromMessage)
502
+ // Note: keyId is already stored by enrollment page as trulyYouKeyId_<authFlowId>
503
+ resolve(keyIdFromMessage)
496
504
  } else {
497
- // Final fallback: wait a bit and check localStorage again (race condition mitigation)
505
+ // Fallback: check localStorage using authFlowId
498
506
  setTimeout(() => {
499
- const delayedKeyId = localStorage.getItem('trulyYouKeyId')
507
+ let delayedKeyId: string | null = null
508
+ if (this.brandingCache?.authFlowId) {
509
+ delayedKeyId = this.getKeyIdByAuthFlowId(this.brandingCache.authFlowId)
510
+ }
511
+
500
512
  if (delayedKeyId) {
501
- console.log('[SDK]: Enrollment successful, keyId obtained (delayed):', delayedKeyId)
513
+ console.log('[SDK]: Enrollment successful, keyId obtained (delayed) using authFlowId:', delayedKeyId)
502
514
  resolve(delayedKeyId)
503
515
  } else {
504
516
  reject(new Error('Enrollment completed but no keyId found in message or localStorage'))
@@ -1719,9 +1731,12 @@ export class TrulyYouSDK {
1719
1731
  // Generate a long, unique signatureId
1720
1732
  signatureId = `sig_${Date.now()}_${Math.random().toString(36).substring(2, 15)}${Math.random().toString(36).substring(2, 15)}${Math.random().toString(36).substring(2, 15)}${Math.random().toString(36).substring(2, 15)}`
1721
1733
 
1722
- // Get keyId and userId from localStorage
1723
- let storedKeyId = localStorage.getItem('trulyYouKeyId')
1724
- let keyId = storedKeyId ? this.extractActualKeyId(storedKeyId) : null
1734
+ // Get keyId using authFlowId
1735
+ let keyId: string | null = null
1736
+ if (this.brandingCache?.authFlowId) {
1737
+ keyId = this.getKeyIdByAuthFlowId(this.brandingCache.authFlowId)
1738
+ }
1739
+
1725
1740
  const userIdStr = localStorage.getItem('trulyYouUserId')
1726
1741
  let userId: string | undefined
1727
1742
  if (userIdStr) {
@@ -1740,17 +1755,12 @@ export class TrulyYouSDK {
1740
1755
  console.log('[SDK]: No key found in localStorage, triggering enrollment...')
1741
1756
 
1742
1757
  // Probe iframe first to check if key exists there
1743
- storedKeyId = await this.probeIframeForKey()
1744
- keyId = storedKeyId ? this.extractActualKeyId(storedKeyId) : null
1758
+ keyId = await this.probeIframeForKey()
1745
1759
 
1746
1760
  if (!keyId) {
1747
1761
  // No key found, trigger enrollment
1748
1762
  console.log('[SDK]: No key in iframe either, opening enrollment popup...')
1749
- await this.enrollWithPopup()
1750
-
1751
- // After enrollment, probe again to get the new key
1752
- storedKeyId = await this.probeIframeForKey()
1753
- keyId = storedKeyId ? this.extractActualKeyId(storedKeyId) : null
1763
+ keyId = await this.enrollWithPopup()
1754
1764
 
1755
1765
  if (!keyId) {
1756
1766
  throw new Error('Enrollment completed but no key found. Please try again.')
@@ -1794,8 +1804,7 @@ export class TrulyYouSDK {
1794
1804
 
1795
1805
  // Make the actual API call with signature and signatureId in header
1796
1806
  // Use keyId from signingResult (Device B's keyId for handoff, or localStorage keyId for mobile)
1797
- // Extract actual keyId from signingResult if it's in authFlowId_keyId format
1798
- const signingResultKeyId = signingResult.keyId ? this.extractActualKeyId(signingResult.keyId) : ''
1807
+ const signingResultKeyId = signingResult.keyId || ''
1799
1808
  console.log('[SDK]: 🔍 KeyId debug - signingResult.keyId:', signingResultKeyId, 'localStorage keyId:', keyId, 'keyId type:', typeof signingResultKeyId, 'empty?:', signingResultKeyId === '')
1800
1809
  const keyIdForAuth = signingResultKeyId || keyId || ''
1801
1810
  console.log('[SDK]: ✅ Final keyId for auth header:', keyIdForAuth, '(from', signingResultKeyId && signingResultKeyId !== '' ? 'Device B' : 'localStorage fallback', ')')