@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.
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/sdk/TrulyYouSDK.d.ts +0 -5
- package/package.json +5 -1
- package/src/sdk/TrulyYouSDK.ts +54 -56
|
@@ -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.
|
|
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",
|
package/src/sdk/TrulyYouSDK.ts
CHANGED
|
@@ -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 -
|
|
303
|
-
|
|
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
|
-
//
|
|
382
|
-
const
|
|
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({
|
|
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
|
|
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
|
-
|
|
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',
|