sunuid-sdk 1.0.38 → 1.0.41
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/sunuid-sdk.esm.js +267 -27
- package/dist/sunuid-sdk.esm.js.map +1 -1
- package/dist/sunuid-sdk.js +267 -27
- package/dist/sunuid-sdk.js.map +1 -1
- package/dist/sunuid-sdk.min.js +1 -1
- package/dist/sunuid-sdk.min.js.map +1 -1
- package/package.json +1 -1
package/dist/sunuid-sdk.esm.js
CHANGED
|
@@ -311,7 +311,15 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
311
311
|
token: null,
|
|
312
312
|
// Configuration pour forcer l'utilisation du serveur distant
|
|
313
313
|
forceRemoteServer: true,
|
|
314
|
-
useLocalFallback: false
|
|
314
|
+
useLocalFallback: false,
|
|
315
|
+
// Nouvelles options pour les callbacks
|
|
316
|
+
redirectAfterSuccess: null,
|
|
317
|
+
verifySignature: false,
|
|
318
|
+
tokenMaxAge: 300,
|
|
319
|
+
// 5 minutes par défaut
|
|
320
|
+
onAuthenticationSuccess: null,
|
|
321
|
+
onAuthenticationError: null,
|
|
322
|
+
state: null
|
|
315
323
|
};
|
|
316
324
|
|
|
317
325
|
/**
|
|
@@ -345,21 +353,28 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
345
353
|
while (1) switch (_context.p = _context.n) {
|
|
346
354
|
case 0:
|
|
347
355
|
_context.p = 0;
|
|
356
|
+
if (!this.handleCallback()) {
|
|
357
|
+
_context.n = 1;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
console.log('✅ Callback traité, initialisation terminée');
|
|
361
|
+
return _context.a(2);
|
|
362
|
+
case 1:
|
|
348
363
|
if (!this.config.secureInit) {
|
|
349
|
-
_context.n =
|
|
364
|
+
_context.n = 3;
|
|
350
365
|
break;
|
|
351
366
|
}
|
|
352
|
-
_context.n =
|
|
367
|
+
_context.n = 2;
|
|
353
368
|
return this.secureInit();
|
|
354
|
-
case 1:
|
|
355
|
-
_context.n = 3;
|
|
356
|
-
break;
|
|
357
369
|
case 2:
|
|
370
|
+
_context.n = 4;
|
|
371
|
+
break;
|
|
372
|
+
case 3:
|
|
358
373
|
// Validation sécurisée des paramètres
|
|
359
374
|
if (this.config.validateInputs) {
|
|
360
375
|
this.validateSecurityParams();
|
|
361
376
|
}
|
|
362
|
-
case
|
|
377
|
+
case 4:
|
|
363
378
|
// Log de sécurité pour l'initialisation
|
|
364
379
|
this.logSecurityEvent('SDK_INIT_START', {
|
|
365
380
|
apiUrl: this.config.apiUrl,
|
|
@@ -368,9 +383,9 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
368
383
|
});
|
|
369
384
|
|
|
370
385
|
// Récupérer les informations du partenaire depuis l'API
|
|
371
|
-
_context.n =
|
|
386
|
+
_context.n = 5;
|
|
372
387
|
return this.fetchPartnerInfo();
|
|
373
|
-
case
|
|
388
|
+
case 5:
|
|
374
389
|
// Obscurcir les credentials dans les logs
|
|
375
390
|
this.obfuscateCredentials();
|
|
376
391
|
this.isInitialized = true;
|
|
@@ -388,19 +403,19 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
388
403
|
|
|
389
404
|
// Initialiser la connexion WebSocket
|
|
390
405
|
this.initWebSocket();
|
|
391
|
-
_context.n =
|
|
406
|
+
_context.n = 7;
|
|
392
407
|
break;
|
|
393
|
-
case
|
|
394
|
-
_context.p =
|
|
408
|
+
case 6:
|
|
409
|
+
_context.p = 6;
|
|
395
410
|
_t = _context.v;
|
|
396
411
|
this.logSecurityEvent('SDK_INIT_ERROR', {
|
|
397
412
|
error: _t.message
|
|
398
413
|
});
|
|
399
414
|
throw _t;
|
|
400
|
-
case
|
|
415
|
+
case 7:
|
|
401
416
|
return _context.a(2);
|
|
402
417
|
}
|
|
403
|
-
}, _callee, this, [[0,
|
|
418
|
+
}, _callee, this, [[0, 6]]);
|
|
404
419
|
}));
|
|
405
420
|
function init() {
|
|
406
421
|
return _init.apply(this, arguments);
|
|
@@ -914,26 +929,51 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
914
929
|
_context3.n = 8;
|
|
915
930
|
return this.makeRequest('/qr-generate', _objectSpread2({
|
|
916
931
|
type: this.config.type,
|
|
917
|
-
|
|
918
|
-
//
|
|
932
|
+
data: qrContent,
|
|
933
|
+
// Essayer data au lieu de content
|
|
919
934
|
label: "".concat(this.getTypeName(this.config.type), " ").concat(partnerName)
|
|
920
935
|
}, options));
|
|
921
936
|
case 8:
|
|
922
937
|
response = _context3.v;
|
|
923
938
|
if (!response.success) {
|
|
924
|
-
_context3.n =
|
|
939
|
+
_context3.n = 11;
|
|
925
940
|
break;
|
|
926
941
|
}
|
|
942
|
+
// Debug: Afficher la structure complète de la réponse
|
|
943
|
+
console.log('📋 Réponse QR API complète:', response);
|
|
944
|
+
console.log('📋 Structure response.data:', response.data);
|
|
945
|
+
|
|
927
946
|
// Construire l'URL complète du QR code
|
|
928
947
|
qrImageUrl = response.data.qrCodeUrl; // Si l'URL est relative, la rendre absolue
|
|
929
|
-
if (qrImageUrl.startsWith('/')) {
|
|
948
|
+
if (qrImageUrl && qrImageUrl.startsWith('/')) {
|
|
930
949
|
qrImageUrl = "".concat(this.config.apiUrl).concat(qrImageUrl);
|
|
931
950
|
}
|
|
951
|
+
|
|
952
|
+
// Vérifier si l'URL du QR code existe
|
|
953
|
+
if (qrImageUrl) {
|
|
954
|
+
_context3.n = 10;
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
console.warn('⚠️ qrCodeUrl non trouvé dans la réponse, recherche d\'alternatives...');
|
|
958
|
+
|
|
959
|
+
// Essayer d'autres champs possibles
|
|
960
|
+
qrImageUrl = response.data.qr_url || response.data.qrUrl || response.data.url || response.data.image_url || response.data.imageUrl;
|
|
961
|
+
if (!qrImageUrl) {
|
|
962
|
+
_context3.n = 9;
|
|
963
|
+
break;
|
|
964
|
+
}
|
|
965
|
+
console.log('✅ URL QR trouvée dans un champ alternatif:', qrImageUrl);
|
|
966
|
+
_context3.n = 10;
|
|
967
|
+
break;
|
|
968
|
+
case 9:
|
|
969
|
+
console.error('❌ Aucune URL QR trouvée dans la réponse');
|
|
970
|
+
throw new Error('URL du QR code non trouvée dans la réponse API');
|
|
971
|
+
case 10:
|
|
932
972
|
this.currentQRUrl = qrImageUrl;
|
|
933
973
|
console.log('✅ QR code généré par API principale:', qrImageUrl);
|
|
934
974
|
console.log('📄 Contenu QR final:', qrContent);
|
|
935
|
-
console.log('🏷️ Label QR:', response.data.label);
|
|
936
|
-
console.log('🆔 Session ID:', response.data.sessionId);
|
|
975
|
+
console.log('🏷️ Label QR:', response.data.label || 'N/A');
|
|
976
|
+
console.log('🆔 Session ID:', response.data.sessionId || 'N/A');
|
|
937
977
|
|
|
938
978
|
// Afficher le QR code
|
|
939
979
|
this.displayQRCode(containerId, qrImageUrl, this.config.type, options);
|
|
@@ -955,13 +995,13 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
955
995
|
label: response.data.label,
|
|
956
996
|
sessionId: response.data.sessionId
|
|
957
997
|
}));
|
|
958
|
-
case
|
|
998
|
+
case 11:
|
|
959
999
|
throw new Error(response.message || 'Erreur lors de la génération du QR code');
|
|
960
|
-
case
|
|
961
|
-
_context3.n =
|
|
1000
|
+
case 12:
|
|
1001
|
+
_context3.n = 14;
|
|
962
1002
|
break;
|
|
963
|
-
case
|
|
964
|
-
_context3.p =
|
|
1003
|
+
case 13:
|
|
1004
|
+
_context3.p = 13;
|
|
965
1005
|
_t4 = _context3.v;
|
|
966
1006
|
console.error('Erreur API détectée:', _t4.message);
|
|
967
1007
|
console.error('Stack trace complet:', _t4.stack);
|
|
@@ -993,10 +1033,10 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
993
1033
|
console.log('Affichage du message "Service non disponible" pour type ' + this.config.type);
|
|
994
1034
|
this.displayServiceUnavailable(containerId, this.config.type);
|
|
995
1035
|
throw new Error('Service non disponible');
|
|
996
|
-
case
|
|
1036
|
+
case 14:
|
|
997
1037
|
return _context3.a(2);
|
|
998
1038
|
}
|
|
999
|
-
}, _callee3, this, [[7,
|
|
1039
|
+
}, _callee3, this, [[7, 13], [4, 6]]);
|
|
1000
1040
|
}));
|
|
1001
1041
|
function generateQR() {
|
|
1002
1042
|
return _generateQR.apply(this, arguments);
|
|
@@ -2484,6 +2524,206 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
2484
2524
|
container.innerHTML = "\n <div style=\"\n text-align: center;\n padding: 40px 20px;\n background: #f8f9fa;\n border: 2px solid #007bff;\n border-radius: 10px;\n color: #007bff;\n font-family: Arial, sans-serif;\n \">\n <div style=\"\n width: 60px;\n height: 60px;\n border: 4px solid #e3f2fd;\n border-top: 4px solid #007bff;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin: 0 auto 20px auto;\n \"></div>\n <h3 style=\"margin: 0 0 10px 0; color: #007bff;\">\uD83D\uDD0D Scan en cours...</h3>\n <p style=\"margin: 0; font-size: 14px;\">\n Veuillez patienter pendant la v\xE9rification de votre identit\xE9.\n </p>\n <div style=\"margin-top: 15px; font-size: 12px; color: #6c757d;\">\n \u23F1\uFE0F Traitement en cours...\n </div>\n </div>\n <style>\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n </style>\n ";
|
|
2485
2525
|
console.log('✅ Loader affiché avec succès');
|
|
2486
2526
|
}
|
|
2527
|
+
|
|
2528
|
+
/**
|
|
2529
|
+
* Gérer le callback SunuID
|
|
2530
|
+
*/
|
|
2531
|
+
}, {
|
|
2532
|
+
key: "handleCallback",
|
|
2533
|
+
value: function handleCallback() {
|
|
2534
|
+
var urlParams = new URLSearchParams(window.location.search);
|
|
2535
|
+
|
|
2536
|
+
// Vérifier si c'est un callback SunuID
|
|
2537
|
+
if (urlParams.has('token') && urlParams.has('session_id')) {
|
|
2538
|
+
console.log('🔗 Callback SunuID détecté');
|
|
2539
|
+
|
|
2540
|
+
// Récupérer les paramètres
|
|
2541
|
+
var callbackData = {
|
|
2542
|
+
token: urlParams.get('token'),
|
|
2543
|
+
state: urlParams.get('state'),
|
|
2544
|
+
session_id: urlParams.get('session_id'),
|
|
2545
|
+
user_id: urlParams.get('user_id'),
|
|
2546
|
+
partner_id: urlParams.get('partner_id'),
|
|
2547
|
+
type: urlParams.get('type'),
|
|
2548
|
+
timestamp: urlParams.get('timestamp'),
|
|
2549
|
+
signature: urlParams.get('signature')
|
|
2550
|
+
};
|
|
2551
|
+
console.log('📋 Données callback:', callbackData);
|
|
2552
|
+
|
|
2553
|
+
// Valider le callback
|
|
2554
|
+
this.validateCallback(callbackData);
|
|
2555
|
+
|
|
2556
|
+
// Traiter l'authentification
|
|
2557
|
+
this.processAuthentication(callbackData);
|
|
2558
|
+
return true;
|
|
2559
|
+
}
|
|
2560
|
+
return false;
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
/**
|
|
2564
|
+
* Valider le callback
|
|
2565
|
+
*/
|
|
2566
|
+
}, {
|
|
2567
|
+
key: "validateCallback",
|
|
2568
|
+
value: function validateCallback(data) {
|
|
2569
|
+
console.log('🔒 Validation du callback...');
|
|
2570
|
+
|
|
2571
|
+
// Vérifier l'état de sécurité
|
|
2572
|
+
if (data.state && data.state !== this.config.state) {
|
|
2573
|
+
console.error('❌ État de sécurité invalide');
|
|
2574
|
+
throw new Error('État de sécurité invalide');
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
// Vérifier la signature (si configurée)
|
|
2578
|
+
if (data.signature && this.config.verifySignature) {
|
|
2579
|
+
if (!this.verifySignature(data)) {
|
|
2580
|
+
console.error('❌ Signature invalide');
|
|
2581
|
+
throw new Error('Signature invalide');
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
// Vérifier l'expiration
|
|
2586
|
+
if (data.timestamp && this.isExpired(data.timestamp)) {
|
|
2587
|
+
console.error('❌ Token expiré');
|
|
2588
|
+
throw new Error('Token expiré');
|
|
2589
|
+
}
|
|
2590
|
+
console.log('✅ Callback validé avec succès');
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
/**
|
|
2594
|
+
* Traiter l'authentification
|
|
2595
|
+
*/
|
|
2596
|
+
}, {
|
|
2597
|
+
key: "processAuthentication",
|
|
2598
|
+
value: function processAuthentication(data) {
|
|
2599
|
+
console.log('🔐 Traitement de l\'authentification...');
|
|
2600
|
+
try {
|
|
2601
|
+
// Décoder le JWT token
|
|
2602
|
+
var decodedToken = this.decodeJWT(data.token);
|
|
2603
|
+
|
|
2604
|
+
// Vérifier les données utilisateur
|
|
2605
|
+
var userData = {
|
|
2606
|
+
user_id: decodedToken.user_id || data.user_id,
|
|
2607
|
+
session_id: decodedToken.session_id || data.session_id,
|
|
2608
|
+
partner_id: decodedToken.partner_id || data.partner_id,
|
|
2609
|
+
type: decodedToken.type || data.type,
|
|
2610
|
+
iat: decodedToken.iat,
|
|
2611
|
+
exp: decodedToken.exp
|
|
2612
|
+
};
|
|
2613
|
+
console.log('👤 Données utilisateur:', userData);
|
|
2614
|
+
|
|
2615
|
+
// Émettre l'événement de succès
|
|
2616
|
+
this.emitWebSocketEvent('authentication_success', {
|
|
2617
|
+
userData: userData,
|
|
2618
|
+
callbackData: data,
|
|
2619
|
+
timestamp: Date.now()
|
|
2620
|
+
});
|
|
2621
|
+
|
|
2622
|
+
// Appeler le callback de succès
|
|
2623
|
+
if (this.config.onAuthenticationSuccess) {
|
|
2624
|
+
this.config.onAuthenticationSuccess(userData, data);
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
// Rediriger si configuré
|
|
2628
|
+
if (this.config.redirectAfterSuccess) {
|
|
2629
|
+
this.redirectAfterSuccess(userData);
|
|
2630
|
+
}
|
|
2631
|
+
console.log('✅ Authentification traitée avec succès');
|
|
2632
|
+
} catch (error) {
|
|
2633
|
+
console.error('❌ Erreur lors du traitement:', error);
|
|
2634
|
+
|
|
2635
|
+
// Appeler le callback d'erreur
|
|
2636
|
+
if (this.config.onAuthenticationError) {
|
|
2637
|
+
this.config.onAuthenticationError(error, data);
|
|
2638
|
+
}
|
|
2639
|
+
throw error;
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
/**
|
|
2644
|
+
* Décoder un JWT token
|
|
2645
|
+
*/
|
|
2646
|
+
}, {
|
|
2647
|
+
key: "decodeJWT",
|
|
2648
|
+
value: function decodeJWT(token) {
|
|
2649
|
+
try {
|
|
2650
|
+
// Décodage simple du JWT (sans vérification de signature)
|
|
2651
|
+
var parts = token.split('.');
|
|
2652
|
+
if (parts.length !== 3) {
|
|
2653
|
+
throw new Error('Format JWT invalide');
|
|
2654
|
+
}
|
|
2655
|
+
var payload = parts[1];
|
|
2656
|
+
var decoded = JSON.parse(atob(payload));
|
|
2657
|
+
return decoded;
|
|
2658
|
+
} catch (error) {
|
|
2659
|
+
console.error('❌ Erreur décodage JWT:', error);
|
|
2660
|
+
throw new Error('Token JWT invalide');
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
/**
|
|
2665
|
+
* Vérifier la signature
|
|
2666
|
+
*/
|
|
2667
|
+
}, {
|
|
2668
|
+
key: "verifySignature",
|
|
2669
|
+
value: function verifySignature(data) {
|
|
2670
|
+
// Implémentation basique - à adapter selon vos besoins
|
|
2671
|
+
var expectedSignature = this.generateSignature(data);
|
|
2672
|
+
return data.signature === expectedSignature;
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
/**
|
|
2676
|
+
* Générer une signature
|
|
2677
|
+
*/
|
|
2678
|
+
}, {
|
|
2679
|
+
key: "generateSignature",
|
|
2680
|
+
value: function generateSignature(data) {
|
|
2681
|
+
// Implémentation basique - à adapter selon vos besoins
|
|
2682
|
+
var payload = "".concat(data.token, ".").concat(data.state, ".").concat(data.session_id, ".").concat(data.timestamp);
|
|
2683
|
+
return btoa(payload).slice(0, 12); // Signature simplifiée
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
/**
|
|
2687
|
+
* Vérifier l'expiration
|
|
2688
|
+
*/
|
|
2689
|
+
}, {
|
|
2690
|
+
key: "isExpired",
|
|
2691
|
+
value: function isExpired(timestamp) {
|
|
2692
|
+
var currentTime = Math.floor(Date.now() / 1000);
|
|
2693
|
+
var tokenTime = parseInt(timestamp);
|
|
2694
|
+
var maxAge = this.config.tokenMaxAge || 300; // 5 minutes par défaut
|
|
2695
|
+
|
|
2696
|
+
return currentTime - tokenTime > maxAge;
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
/**
|
|
2700
|
+
* Rediriger après succès
|
|
2701
|
+
*/
|
|
2702
|
+
}, {
|
|
2703
|
+
key: "redirectAfterSuccess",
|
|
2704
|
+
value: function redirectAfterSuccess(userData) {
|
|
2705
|
+
var redirectUrl = this.config.redirectAfterSuccess;
|
|
2706
|
+
|
|
2707
|
+
// Remplacer les variables dans l'URL
|
|
2708
|
+
redirectUrl = redirectUrl.replace('{user_id}', userData.user_id).replace('{session_id}', userData.session_id).replace('{partner_id}', userData.partner_id).replace('{type}', userData.type);
|
|
2709
|
+
console.log('🔄 Redirection vers:', redirectUrl);
|
|
2710
|
+
|
|
2711
|
+
// Redirection avec délai pour permettre les callbacks
|
|
2712
|
+
setTimeout(function () {
|
|
2713
|
+
window.location.href = redirectUrl;
|
|
2714
|
+
}, 100);
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
/**
|
|
2718
|
+
* Générer un état de sécurité
|
|
2719
|
+
*/
|
|
2720
|
+
}, {
|
|
2721
|
+
key: "generateState",
|
|
2722
|
+
value: function generateState() {
|
|
2723
|
+
var state = 'sunuid_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
2724
|
+
this.config.state = state;
|
|
2725
|
+
return state;
|
|
2726
|
+
}
|
|
2487
2727
|
}]);
|
|
2488
2728
|
}(); // Exposer la classe globalement
|
|
2489
2729
|
window.SunuID = SunuID;
|