@truly-you/trulyyou-web-sdk 0.1.0 → 0.1.2

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.
@@ -42,11 +42,6 @@ export declare class TrulyYouSDK {
42
42
  * Also checks backend to verify key exists and is active
43
43
  */
44
44
  private probeIframeForKey;
45
- /**
46
- * Lightweight API call to check if key exists and is active in backend
47
- * Calls SDK frontend which proxies to SDK backend
48
- */
49
- private checkKeyStatus;
50
45
  /**
51
46
  * Open enrollment popup and wait for completion
52
47
  */
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@truly-you/trulyyou-web-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "TrulyYou Web SDK for secure authentication and payload signing",
5
5
  "type": "module",
6
6
  "main": "dist/index.esm.js",
7
7
  "module": "dist/index.esm.js",
8
8
  "types": "dist/index.d.ts",
9
+ "private": false,
10
+ "publishConfig": {
11
+ "access": "restricted"
12
+ },
9
13
  "exports": {
10
14
  ".": {
11
15
  "import": "./dist/index.esm.js",
@@ -299,18 +299,8 @@ export class TrulyYouSDK {
299
299
  if (data?.type === 'KEY_CHECK_RESULT') {
300
300
  cleanup()
301
301
  if (data.hasKey && data.keyId) {
302
- // Key found in localStorage - verify it's active in backend
303
- if (!backendCheckPromise) {
304
- backendCheckPromise = this.checkKeyStatus(data.keyId)
305
- }
306
-
307
- const isActive = await backendCheckPromise
308
- if (isActive) {
309
- resolve(data.keyId)
310
- } else {
311
- console.log('[SDK]: Key found in localStorage but not active in backend, ignoring')
312
- resolve(null)
313
- }
302
+ // Key found in localStorage - it will be validated when used in /api/signatures/create
303
+ resolve(data.keyId)
314
304
  } else {
315
305
  resolve(null)
316
306
  }
@@ -334,42 +324,6 @@ export class TrulyYouSDK {
334
324
  })
335
325
  }
336
326
 
337
- /**
338
- * Lightweight API call to check if key exists and is active in backend
339
- * Calls SDK frontend which proxies to SDK backend
340
- */
341
- private async checkKeyStatus(keyId: string): Promise<boolean> {
342
- try {
343
- const response = await fetch(`${this.frontendUrl}/api/key/check/${encodeURIComponent(keyId)}`, {
344
- method: 'GET',
345
- headers: { 'Content-Type': 'application/json' }
346
- })
347
-
348
- if (!response.ok) {
349
- console.log('[SDK]: Key status check failed:', response.status)
350
- return false
351
- }
352
-
353
- const result = await response.json() as any
354
- const isActive = result.success && result.exists && result.active === true
355
-
356
- if (!isActive) {
357
- console.log('[SDK]: Key found but not active:', {
358
- exists: result.exists,
359
- active: result.active,
360
- status: result.status
361
- })
362
- }
363
-
364
- return isActive
365
- } catch (error) {
366
- console.error('[SDK]: Error checking key status:', error)
367
- // If backend check fails, treat as invalid (fail closed for security)
368
- // This ensures we don't use keys if we can't verify their status
369
- return false
370
- }
371
- }
372
-
373
327
  /**
374
328
  * Open enrollment popup and wait for completion
375
329
  */
@@ -378,24 +332,45 @@ export class TrulyYouSDK {
378
332
  throw new Error('authAppId is required for enrollment. Please configure authAppId in SDK config.')
379
333
  }
380
334
 
381
- // Generate session first
382
- const sessionResponse = await fetch(`${this.frontendUrl}/api/sessions/generate`, {
335
+ // authAppId is guaranteed to exist here due to check above
336
+ const appId = this.authAppId!
337
+
338
+ // Get app to retrieve authFlowId
339
+ const appResponse = await fetch(`${this.apiUrl}/api/apps/${appId}`)
340
+
341
+ if (!appResponse.ok) {
342
+ throw new Error('Failed to load app configuration')
343
+ }
344
+
345
+ const appData = await appResponse.json()
346
+ const app = appData.app
347
+
348
+ if (!app.authFlowId) {
349
+ throw new Error('App does not have an authentication flow configured')
350
+ }
351
+
352
+ // Generate a clientId for this session
353
+ const clientId = `client_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
354
+
355
+ // Create session directly via SDK backend
356
+ const sessionResponse = await fetch(`${this.apiUrl}/api/sessions`, {
383
357
  method: 'POST',
384
358
  headers: { 'Content-Type': 'application/json' },
385
- body: JSON.stringify({ authAppId: this.authAppId })
359
+ body: JSON.stringify({
360
+ appId: appId,
361
+ flowId: app.authFlowId,
362
+ clientId: clientId
363
+ })
386
364
  })
387
365
 
388
366
  if (!sessionResponse.ok) {
389
367
  const errorData = await sessionResponse.json()
390
- throw new Error(errorData.error || 'Failed to generate enrollment session')
368
+ throw new Error(errorData.error || 'Failed to create enrollment session')
391
369
  }
392
370
 
393
371
  const sessionData = await sessionResponse.json()
394
372
  const sessionId = sessionData.data.sessionId
395
373
 
396
- // authAppId is guaranteed to exist here due to check above
397
- const appId = this.authAppId!
398
-
399
374
  return new Promise((resolve, reject) => {
400
375
  const origin = window.location.origin
401
376
 
@@ -1708,7 +1683,7 @@ export class TrulyYouSDK {
1708
1683
  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)}`
1709
1684
 
1710
1685
  // Get keyId and userId from localStorage
1711
- const keyId = localStorage.getItem('trulyYouKeyId')
1686
+ let keyId = localStorage.getItem('trulyYouKeyId')
1712
1687
  const userIdStr = localStorage.getItem('trulyYouUserId')
1713
1688
  let userId: string | undefined
1714
1689
  if (userIdStr) {
@@ -1722,6 +1697,29 @@ export class TrulyYouSDK {
1722
1697
  // Check if this will be a handoff flow (desktop device)
1723
1698
  const isHandoff = this.isDesktopDevice()
1724
1699
 
1700
+ // For mobile devices (non-handoff), if no key exists, trigger enrollment
1701
+ if (!isHandoff && !keyId) {
1702
+ console.log('[SDK]: No key found in localStorage, triggering enrollment...')
1703
+
1704
+ // Probe iframe first to check if key exists there
1705
+ keyId = await this.probeIframeForKey()
1706
+
1707
+ if (!keyId) {
1708
+ // No key found, trigger enrollment
1709
+ console.log('[SDK]: No key in iframe either, opening enrollment popup...')
1710
+ await this.enrollWithPopup()
1711
+
1712
+ // After enrollment, probe again to get the new key
1713
+ keyId = await this.probeIframeForKey()
1714
+
1715
+ if (!keyId) {
1716
+ throw new Error('Enrollment completed but no key found. Please try again.')
1717
+ }
1718
+
1719
+ console.log('[SDK]: Enrollment successful, obtained keyId:', keyId)
1720
+ }
1721
+ }
1722
+
1725
1723
  // Create signature document BEFORE signing (this also validates domain and template and starts countdown for handoff)
1726
1724
  const createResponse = await fetch(`${this.apiUrl}/api/signatures/create`, {
1727
1725
  method: 'POST',