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