sunuid-sdk 1.0.29 → 1.0.30

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.
@@ -7,5 +7,5 @@ var e,t,n="function"==typeof Symbol?Symbol:{},i=n.iterator||"@@iterator",r=n.toS
7
7
  * @version 1.0.0
8
8
  * @author SunuID Team
9
9
  * @license MIT
10
- */(t,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var i=n.call(e,t||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}function f(e){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(e)}!function(e,t){var r,o,c={apiUrl:(null===(t=e.SunuIDConfig)||void 0===t?void 0:t.apiUrl)||"https://api.sunuid.fayma.sn",clientId:null,secretId:null,type:2,partnerName:"SunuID",theme:"light",language:"fr",autoRefresh:!0,refreshInterval:3e4,onSuccess:null,onError:null,onStatusUpdate:null,onExpired:null,enableSecurityLogs:!0,validateInputs:!0,maxRetries:3,requestTimeout:1e4,secureInit:!1,secureInitUrl:null!==(r=e.SunuIDConfig)&&void 0!==r&&null!==(r=r.apiUrl)&&void 0!==r&&r.includes("api.sunuid.fayma.sn")?"https://sunuid.fayma.sn/secure-init.php":(null===(o=e.SunuIDConfig)||void 0===o||null===(o=o.apiUrl)||void 0===o?void 0:o.replace("/api",""))+"/secure-init.php"||"https://sunuid.fayma.sn/secure-init.php",token:null},d=function(){return t=function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.config=s(s({},c),t),this.qrCode=null,this.refreshTimer=null,this.isInitialized=!1,this.socket=null,this.initPromise=this.init()},r=[{key:"init",value:(k=n(a().m(function e(){var t;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(e.p=0,!this.config.secureInit){e.n=2;break}return e.n=1,this.secureInit();case 1:e.n=3;break;case 2:this.config.validateInputs&&this.validateSecurityParams();case 3:this.logSecurityEvent("SDK_INIT_START",{apiUrl:this.config.apiUrl,type:this.config.type,partnerName:this.config.partnerName,secureInit:this.config.secureInit}),this.obfuscateCredentials(),this.isInitialized=!0,console.log("SunuID SDK initialisé avec succès"),this.logSecurityEvent("SDK_INIT_SUCCESS"),this.initWebSocket(),e.n=5;break;case 4:throw e.p=4,t=e.v,this.logSecurityEvent("SDK_INIT_ERROR",{error:t.message}),t;case 5:return e.a(2)}},e,this,[[0,4]])})),function(){return k.apply(this,arguments)})},{key:"secureInit",value:(b=n(a().m(function e(){var t,n,i,r,o;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return e.p=0,this.logSecurityEvent("SECURE_INIT_START"),t={type:this.config.type,partnerName:this.config.partnerName,theme:this.config.theme},e.n=1,fetch(this.config.secureInitUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)});case 1:if((n=e.v).ok){e.n=2;break}throw new Error("Erreur HTTP: ".concat(n.status));case 2:return e.n=3,n.json();case 3:if((i=e.v).success){e.n=4;break}throw new Error(i.error||"Erreur lors de l'initialisation sécurisée");case 4:if(this.config.token=i.data.token,this.config.apiUrl=i.data.api_url,!(r=this.decodeSecureToken(i.data.token))){e.n=5;break}this.config.clientId=r.client_id,this.config.secretId=r.secret_id,e.n=6;break;case 5:throw new Error("Impossible de décoder le token sécurisé");case 6:this.config.expiresIn=i.data.expires_in,this.config.maxRequests=i.data.max_requests,this.config.requestCount=0,this.logSecurityEvent("SECURE_INIT_SUCCESS",{expiresIn:i.data.expires_in,maxRequests:i.data.max_requests}),console.log("✅ Initialisation sécurisée réussie"),e.n=8;break;case 7:throw e.p=7,o=e.v,this.logSecurityEvent("SECURE_INIT_ERROR",{error:o.message}),new Error("Échec de l'initialisation sécurisée: ".concat(o.message));case 8:return e.a(2)}},e,this,[[0,7]])})),function(){return b.apply(this,arguments)})},{key:"decodeSecureToken",value:function(e){try{var t=e.split(".");if(2!==t.length)return console.error("❌ Format de token invalide"),null;var n=l(t,2),i=n[0],r=(n[1],atob(i)),o=JSON.parse(r);return o.exp&&o.exp<Date.now()/1e3?(console.error("❌ Token expiré"),null):(console.log("✅ Token décodé avec succès"),o)}catch(e){return console.error("❌ Erreur décodage token:",e),null}}},{key:"initWebSocket",value:function(){var e=this;try{if("undefined"==typeof io)return console.warn("⚠️ Socket.IO non disponible, WebSocket sera initialisé plus tard"),void setTimeout(function(){return e.initWebSocket()},1e3);var t=this.getClientIP();this.socket||(this.socket=io("wss://samasocket.fayma.sn:9443",{query:{token:this.config.clientId,type:"web",userId:this.config.clientId,username:t}}),this.socket.on("connect",function(){console.log("🌐 WebSocket connecté avec succès"),console.log("📊 Socket ID:",e.socket.id)}),this.socket.on("disconnect",function(e){console.log("❌ WebSocket déconnecté:",e)}),this.socket.on("connect_error",function(e){console.error("❌ Erreur connexion WebSocket:",e)}),this.socket.on("qr_status_update",function(t){console.log("📱 Mise à jour statut QR reçue:",t),e.handleQRStatusUpdate(t)}),this.socket.on("qr_scan_success",function(t){console.log("✅ Scan QR réussi reçu:",t),e.handleQRScanSuccess(t)}),this.socket.on("qr_expired",function(t){console.log("⏰ QR expiré reçu:",t),e.handleQRExpired(t)}))}catch(e){console.error("❌ Erreur initialisation WebSocket:",e)}}},{key:"getClientIP",value:function(){return"127.0.0.1"}},{key:"getTypeName",value:function(e){switch(e){case 1:return"KYC";case 2:return"AUTH";case 3:return"SIGNATURE";default:return"TYPE-".concat(e)}}},{key:"validateSecurityParams",value:function(){var e=[];if(this.config.clientId&&"string"==typeof this.config.clientId?this.config.clientId.length<10&&e.push("clientId trop court"):e.push("clientId invalide ou manquant"),this.config.secretId&&"string"==typeof this.config.secretId?this.config.secretId.length<32&&e.push("secretId trop court (minimum 32 caractères)"):e.push("secretId invalide ou manquant"),this.config.apiUrl&&this.isValidUrl(this.config.apiUrl)||e.push("apiUrl invalide"),[1,2,3].includes(this.config.type)||e.push("type invalide (doit être 1, 2 ou 3)"),e.length>0)throw this.logSecurityEvent("VALIDATION_ERROR",{errors:e}),new Error("Paramètres de sécurité invalides: ".concat(e.join(", ")));this.logSecurityEvent("VALIDATION_SUCCESS")}},{key:"isValidUrl",value:function(e){try{var t=new URL(e);return"https:"===t.protocol||"http:"===t.protocol}catch(e){return!1}}},{key:"logSecurityEvent",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.config.enableSecurityLogs){var i={timestamp:(new Date).toISOString(),event:t,data:n,userAgent:navigator.userAgent,url:e.location.href};console.warn("🔒 [SECURITY]",i),e.SunuIDSecurityLogs||(e.SunuIDSecurityLogs=[]),e.SunuIDSecurityLogs.push(i)}}},{key:"obfuscateCredentials",value:function(){this.config.originalClientId=this.config.clientId,this.config.originalSecretId=this.config.secretId,this.config.clientId&&(this.config.clientIdDisplay=this.config.clientId.replace(/(.{3}).*(.{3})/,"$1***$2")),this.config.secretId&&(this.config.secretIdDisplay=this.config.secretId.replace(/(.{4}).*(.{4})/,"$1***$2"))}},{key:"sanitizeInput",value:function(e){return"string"!=typeof e?e:e.replace(/[<>]/g,"").replace(/javascript:/gi,"").trim()}},{key:"handleQRStatusUpdate",value:function(e){this.config.onStatusUpdate&&this.config.onStatusUpdate(e)}},{key:"handleQRScanSuccess",value:function(e){this.config.onSuccess&&this.config.onSuccess(e)}},{key:"handleQRExpired",value:function(e){this.config.onExpired&&this.config.onExpired(e)}},{key:"emitWebSocketEvent",value:function(e,t){this.socket&&this.socket.connected?(this.socket.emit(e,t),console.log("📤 Événement WebSocket émis: ".concat(e),t)):"undefined"==typeof io?console.warn("⚠️ Socket.IO non disponible, impossible d'émettre l'événement:",e):console.warn("⚠️ WebSocket non connecté, impossible d'émettre l'événement:",e)}},{key:"getWebSocketStatus",value:function(){return this.socket?this.socket.connected?"connected":"disconnected":"not_initialized"}},{key:"forceWebSocketInit",value:function(){"undefined"==typeof io||this.socket||(console.log("🔄 Forçage de l'initialisation WebSocket..."),this.initWebSocket())}},{key:"generateQR",value:(I=n(a().m(function e(t){var n,i,r,o,c,u=this,l=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(n=l.length>1&&void 0!==l[1]?l[1]:{},!this.initPromise){e.n=2;break}return e.n=1,this.initPromise;case 1:this.initPromise=null;case 2:if(this.isInitialized){e.n=3;break}throw new Error("SunuID: SDK non initialisé");case 3:return e.p=3,e.n=4,this.makeRequest("/qr-generate",s({type:this.config.type},n));case 4:if(!(i=e.v).success){e.n=5;break}return r="".concat("https://sunuid.fayma.sn").concat(i.data.qrcode),this.currentQRUrl=r,this.displayQRCode(t,r,this.config.type,n),this.pendingQRInfo&&i.data.code&&(o=function(){if(u.socket&&u.socket.id&&"unknown"!==u.socket.id){var e=u.socket.id,t="".concat(u.config.type,"-").concat(i.data.code,"-").concat(e),n=i.data.partnerName||u.config.partnerName||"SunuID",r=u.getTypeName(u.config.type),s="".concat(r," - ").concat(n);u.generateCustomQRCode(t,s,u.pendingQRInfo.options),u.pendingQRInfo=null}else setTimeout(o,100)})(),this.startAutoRefresh(t,this.config.type,n),this.emitWebSocketEvent("qr_generated",{serviceId:i.data.service_id,type:this.config.type,qrCodeUrl:r,code:i.data.code,timestamp:Date.now()}),e.a(2,s(s({},i.data),{},{qrCodeUrl:r,sessionId:i.data.service_id}));case 5:throw new Error(i.message||"Erreur lors de la génération du QR code");case 6:e.n=8;break;case 7:throw e.p=7,c=e.v,console.error("Erreur API détectée:",c.message),console.error("Stack trace complet:",c.stack),console.error("Configuration SDK:",{apiUrl:this.config.apiUrl,type:this.config.type,secureInit:this.config.secureInit,clientId:this.config.clientId?"***"+this.config.clientId.slice(-4):"null",secretId:this.config.secretId?"***"+this.config.secretId.slice(-4):"null"}),console.log('Affichage du message "Service non disponible" pour type '+this.config.type),this.displayServiceUnavailable(t,this.config.type),new Error("Service non disponible");case 8:return e.a(2)}},e,this,[[3,7]])})),function(e){return I.apply(this,arguments)})},{key:"generateCustomQR",value:(S=n(a().m(function e(t,n){var i,r,o,c,u,l=this,d=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(i=d.length>2&&void 0!==d[2]?d[2]:{},!this.initPromise){e.n=2;break}return e.n=1,this.initPromise;case 1:this.initPromise=null;case 2:if(this.isInitialized){e.n=3;break}throw new Error("SunuID: SDK non initialisé");case 3:return e.p=3,e.n=4,this.makeRequest("/qr-generate",s({type:n},i));case 4:if(!(r=e.v).success){e.n=5;break}return o="".concat("https://sunuid.fayma.sn").concat(r.data.qrcode),this.displayQRCode(t,o,n,i),this.pendingQRInfo&&r.data.code&&(c=function(){if(l.socket&&l.socket.id&&"unknown"!==l.socket.id){var e=l.socket.id,t="".concat(n,"-").concat(r.data.code,"-").concat(e),i=r.data.partnerName||l.config.partnerName||"SunuID",o=l.getTypeName(n),s="".concat(o," - ").concat(i);l.generateCustomQRCode(t,s,l.pendingQRInfo.options),l.pendingQRInfo=null}else setTimeout(c,100)})(),this.startAutoRefresh(t,n,i),e.a(2,s(s({},r.data),{},{qrCodeUrl:o,sessionId:r.data.service_id}));case 5:throw new Error(r.message||"Erreur lors de la génération du QR code");case 6:e.n=8;break;case 7:throw e.p=7,u=e.v,console.error("Erreur API détectée:",u.message),console.error("Stack trace complet:",u.stack),console.error("Configuration SDK (Custom):",{apiUrl:this.config.apiUrl,type:n,secureInit:this.config.secureInit,clientId:this.config.clientId?"***"+this.config.clientId.slice(-4):"null",secretId:this.config.secretId?"***"+this.config.secretId.slice(-4):"null"}),console.log('Affichage du message "Service non disponible" pour type '+n),this.displayServiceUnavailable(t,n),new Error("Service non disponible");case 8:return e.a(2)}},e,this,[[3,7]])})),function(e,t){return S.apply(this,arguments)})},{key:"generateAuthQR",value:(m=n(a().m(function e(t){var n,i=arguments;return a().w(function(e){for(;;)if(0===e.n)return n=i.length>1&&void 0!==i[1]?i[1]:{},e.a(2,this.generateQR(t,n))},e,this)})),function(e){return m.apply(this,arguments)})},{key:"generateKYCQR",value:(v=n(a().m(function e(t){var n,i,r=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return n=r.length>1&&void 0!==r[1]?r[1]:{},i=this.config.type,this.config.type=1,e.p=1,e.n=2,this.generateQR(t,n);case 2:return e.a(2,e.v);case 3:return e.p=3,this.config.type=i,e.f(3);case 4:return e.a(2)}},e,this,[[1,,3,4]])})),function(e){return v.apply(this,arguments)})},{key:"generateSignatureQR",value:(y=n(a().m(function e(t){var n,i,r=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return n=r.length>1&&void 0!==r[1]?r[1]:{},i=this.config.type,this.config.type=3,e.p=1,e.n=2,this.generateQR(t,n);case 2:return e.a(2,e.v);case 3:return e.p=3,this.config.type=i,e.f(3);case 4:return e.a(2)}},e,this,[[1,,3,4]])})),function(e){return y.apply(this,arguments)})},{key:"checkQRStatus",value:(g=n(a().m(function e(t){var n,i;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(this.isInitialized){e.n=1;break}throw new Error("SunuID: SDK non initialisé");case 1:return e.p=1,e.n=2,this.makeRequest("/qr-status",{serviceId:t});case 2:if(!(n=e.v).success){e.n=3;break}return e.a(2,n.data);case 3:throw new Error(n.message||"Erreur lors de la vérification du statut");case 4:e.n=6;break;case 5:throw e.p=5,i=e.v,this.handleError(i),i;case 6:return e.a(2)}},e,this,[[1,5]])})),function(e){return g.apply(this,arguments)})},{key:"displayQRCode",value:function(e,t,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},r=document.getElementById(e);if(!r)throw new Error("Conteneur avec l'ID \"".concat(e,'" non trouvé'));r.innerHTML="";var o=document.createElement("div");o.className="sunuid-qr-code",this.getTypeName(n),o.innerHTML='\n <div class="sunuid-qr-header">\n <h3>'.concat(1===n?"Vérification KYC":2===n?"Authentification":3===n?"Signature":"Service Type "+n,'</h3>\n </div>\n <div class="sunuid-qr-image" id="sunuid-qr-container">\n <div style="text-align: center; padding: 40px;">\n <div class="sunuid-loader">\n <div class="sunuid-spinner"></div>\n <p style="margin-top: 20px; color: #666;">Initialisation en cours...</p>\n <p style="font-size: 12px; color: #999; margin-top: 10px;">Connexion API et WebSocket</p>\n <p style="font-size: 11px; color: #ccc; margin-top: 5px;">Attente du Socket ID...</p>\n </div>\n </div>\n </div>\n <div class="sunuid-qr-instructions" style="display: none;">\n <p>Scannez ce QR code avec l\'application ').concat(this.config.partnerName,' pour vous connecter</p>\n </div>\n <div class="sunuid-qr-status" id="sunuid-status" style="display: none;">\n <p>En attente de scan...</p>\n </div>\n '),r.appendChild(o),this.pendingQRInfo={containerId:e,type:n,options:i},this.applyTheme(i.theme||this.config.theme)}},{key:"generateCustomQRCode",value:(h=n(a().m(function e(t,n){var i,r,o,s,c,u,l;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(e.p=1,console.log("🎨 Début génération QR personnalisé avec PHP..."),console.log("📄 Contenu:",t),console.log("🏷️ Label:",n),i=document.getElementById("sunuid-qr-container")){e.n=2;break}return console.error("❌ QR container not found"),this.displayFallbackImage(),e.a(2);case 2:return console.log("✅ QR container trouvé"),i.innerHTML='<div style="text-align: center; padding: 20px;"><p>Génération QR code avec PHP...</p></div>',console.log("🔄 Appel endpoint PHP..."),r=this.config.apiUrl.includes("api.sunuid.fayma.sn")?"https://sunuid.fayma.sn/qr-generator.php":this.config.apiUrl.replace("/api","")+"/qr-generator.php",console.log("🔗 URL QR Generator:",r),e.n=3,fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({content:t,label:n,size:300,margin:10})});case 3:if(o=e.v,console.log("📥 Réponse PHP reçue - Status:",o.status),o.ok){e.n=4;break}throw new Error("Erreur HTTP: ".concat(o.status));case 4:return e.n=5,o.json();case 5:if((s=e.v).success){e.n=6;break}throw new Error("Erreur PHP: ".concat(s.error));case 6:console.log("✅ QR code généré par PHP avec succès"),console.log("📊 Taille:",s.data.size+"px"),console.log("📊 Longueur base64:",s.data.length+" caractères"),this.currentQRUrl=s.data.dataUrl,i.innerHTML='\n <div class="sunuid-qr-ready" style="text-align: center; padding: 20px;">\n <img src="'.concat(s.data.dataUrl,'" alt="QR Code ').concat(this.config.partnerName,'" style="max-width: 300px; border: 2px solid #ddd; border-radius: 10px;">\n </div>\n '),c=i.parentElement.querySelector(".sunuid-qr-instructions"),u=i.parentElement.querySelector(".sunuid-qr-status"),c&&(c.style.display="block",c.classList.add("sunuid-qr-ready")),u&&(u.style.display="block",u.classList.add("sunuid-qr-ready")),console.log("✅ QR code PHP affiché dans le conteneur"),e.n=8;break;case 7:e.p=7,l=e.v,console.error("❌ Erreur génération QR PHP:",l),console.error("Stack trace:",l.stack),this.displayFallbackImage();case 8:return e.a(2)}},e,this,[[1,7]])})),function(e,t){return h.apply(this,arguments)})},{key:"addLogoToCenter",value:function(e,t,n,i,r){try{var o=new Image;o.onload=function(){var r=40,s=t+(i-r)/2,a=n+(i-r)/2;e.fillStyle="white",e.fillRect(s-2,a-2,44,44),e.drawImage(o,s,a,r,r)},o.src="src/logoqr.png"}catch(e){console.warn("Logo non disponible:",e)}}},{key:"displayFallbackImage",value:function(){console.log("⚠️ Affichage de l'image de fallback");var e=document.getElementById("sunuid-qr-container");e?e.innerHTML='\n <div style="text-align: center; padding: 20px; color: #666;">\n <p>⚠️ Génération QR personnalisé non disponible</p>\n <p>Utilisation de l\'image par défaut</p>\n <p><strong>Debug:</strong> QRCode disponible: '.concat("undefined"!=typeof QRCode,"</p>\n <p><strong>Debug:</strong> Container trouvé: ").concat(null!==e,"</p>\n </div>\n "):console.error("❌ Container QR non trouvé pour fallback")}},{key:"displayServiceUnavailable",value:function(e,t){console.log("displayServiceUnavailable appelée pour ".concat(e,", type: ").concat(t));var n=document.getElementById(e);n?n.innerHTML='\n <div class="sunuid-service-unavailable" style="\n text-align: center;\n padding: 40px 20px;\n background: #f8f9fa;\n border: 2px dashed #dee2e6;\n border-radius: 10px;\n color: #6c757d;\n font-family: Arial, sans-serif;\n ">\n <div style="font-size: 48px; margin-bottom: 20px;">⚠️</div>\n <h3 style="margin: 0 0 10px 0; color: #495057;">Service Non Disponible</h3>\n <p style="margin: 0; font-size: 14px;">\n Le service d\'authentification est temporairement indisponible.<br>\n Veuillez réessayer plus tard.\n </p>\n <div style="margin-top: 20px; font-size: 12px; color: #adb5bd;">\n Type: '.concat(String(t).toUpperCase(),"\n </div>\n </div>\n "):console.error("Container ".concat(e," non trouvé"))}},{key:"refreshQR",value:(p=n(a().m(function e(t){var n,i,r,o=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return n=o.length>1&&void 0!==o[1]?o[1]:{},e.p=1,e.n=2,this.generateQR(t,n);case 2:return i=e.v,e.a(2,i);case 3:throw e.p=3,r=e.v,console.error("Erreur lors du rafraîchissement:",r.message),this.displayServiceUnavailable(t,this.config.type),r;case 4:return e.a(2)}},e,this,[[1,3]])})),function(e){return p.apply(this,arguments)})},{key:"startAutoRefresh",value:function(e,t,i){var r=this;this.config.autoRefresh&&(this.refreshTimer=setInterval(n(a().m(function n(){var o;return a().w(function(n){for(;;)switch(n.p=n.n){case 0:return n.p=0,n.n=1,r.refreshQR(e,t,i);case 1:n.n=3;break;case 2:n.p=2,o=n.v,console.warn("Erreur lors du rafraîchissement automatique:",o);case 3:return n.a(2)}},n,null,[[0,2]])})),this.config.refreshInterval))}},{key:"makeRequest",value:(d=n(a().m(function t(n,i){var r,o,s,c,l,d,f,p,h,g=this;return a().w(function(t){for(;;)switch(t.n){case 0:if(this.isInitialized){t.n=1;break}throw this.logSecurityEvent("REQUEST_BEFORE_INIT",{endpoint:n}),new Error("SDK non initialisé");case 1:if(!this.config.secureInit){t.n=2;break}if(this.config.requestCount++,!(this.config.requestCount>this.config.maxRequests)){t.n=2;break}throw this.logSecurityEvent("API_REQUEST_LIMIT_EXCEEDED",{requestCount:this.config.requestCount,maxRequests:this.config.maxRequests}),new Error("Limite de requêtes dépassée");case 2:s=this.sanitizeRequestData(i),console.log("🔍 Debug makeRequest - endpoint:",n),console.log("🔍 Debug makeRequest - apiUrl:",this.config.apiUrl),console.log("🔍 Debug makeRequest - url:","".concat(this.config.apiUrl).concat(n)),console.log("🔍 Debug makeRequest - data:",JSON.stringify(s,null,2)),console.log("🔍 Debug makeRequest - secureInit:",this.config.secureInit),console.log("🔍 Debug makeRequest - isInitialized:",this.isInitialized),c=(null===(r=e.SunuIDConfig)||void 0===r||null===(r=r.endpoints)||void 0===r?void 0:r[n.replace("/","")])||n,l="".concat(this.config.apiUrl).concat(c),console.log("🔍 URL finale construite:",l),console.log("🔍 EndpointPath:",c),console.log("🔍 SunuIDConfig endpoints:",JSON.stringify(null===(o=e.SunuIDConfig)||void 0===o?void 0:o.endpoints)),this.logSecurityEvent("API_REQUEST_START",{endpoint:c,url:l,dataKeys:Object.keys(s),secureInit:this.config.secureInit}),d=0,f=this.config.maxRetries,p=a().m(function e(){var t,n,i,r,o,u,p,h;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return e.p=0,t=new AbortController,n=setTimeout(function(){return t.abort()},g.config.requestTimeout),i={"Content-Type":"application/json"},e.n=1,fetch(l,{method:"POST",headers:i,body:JSON.stringify(s),signal:t.signal});case 1:if(r=e.v,clearTimeout(n),r.ok){e.n=3;break}return e.n=2,r.text();case 2:o=e.v;try{u=JSON.parse(o)}catch(e){u={message:o}}throw g.logSecurityEvent("API_REQUEST_ERROR",{status:r.status,statusText:r.statusText,error:u.message}),new Error(u.message||"Erreur HTTP: ".concat(r.status));case 3:return e.n=4,r.json();case 4:return p=e.v,g.logSecurityEvent("API_REQUEST_SUCCESS",{endpoint:c,responseKeys:Object.keys(p)}),e.a(2,{v:p});case 5:if(e.p=5,h=e.v,d++,"AbortError"!==h.name){e.n=7;break}if(g.logSecurityEvent("API_REQUEST_TIMEOUT",{retryCount:d}),!(d>f)){e.n=6;break}throw new Error("Timeout de la requête API");case 6:return e.a(2,0);case 7:if(!(d>f)){e.n=8;break}throw g.logSecurityEvent("API_REQUEST_MAX_RETRIES",{retryCount:d,error:h.message}),h;case 8:return e.n=9,new Promise(function(e){return setTimeout(e,1e3*d)});case 9:return e.a(2)}},e,null,[[0,5]])});case 3:if(!(d<=f)){t.n=7;break}return t.d(u(p()),4);case 4:if(0!==(h=t.v)){t.n=5;break}return t.a(3,3);case 5:if(!h){t.n=6;break}return t.a(2,h.v);case 6:t.n=3;break;case 7:return t.a(2)}},t,this)})),function(e,t){return d.apply(this,arguments)})},{key:"sanitizeRequestData",value:function(e){for(var t={},n=0,i=Object.entries(e);n<i.length;n++){var r=l(i[n],2),o=r[0],s=r[1];"string"==typeof s?t[o]=this.sanitizeInput(s):"object"===f(s)&&null!==s?t[o]=this.sanitizeRequestData(s):t[o]=s}return t.client_id=this.config.originalClientId||this.config.clientId,t.secret_id=this.config.originalSecretId||this.config.secretId,console.log("🔍 Credentials dans sanitizeRequestData - clientId:",this.config.clientId),console.log("🔍 Credentials dans sanitizeRequestData - secretId:",this.config.secretId?"***"+this.config.secretId.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedClientId:",t.client_id),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:",t.secret_id?"***"+t.secret_id.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - data complet:",JSON.stringify(t,null,2)),console.log("🔍 Credentials dans sanitizeRequestData - clientId:",this.config.clientId),console.log("🔍 Credentials dans sanitizeRequestData - secretId:",this.config.secretId?"***"+this.config.secretId.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedClientId:",t.client_id),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:",t.secret_id?"***"+t.secret_id.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - data complet:",JSON.stringify(t,null,2)),t}},{key:"generateRequestId",value:function(){return"req_"+Date.now()+"_"+Math.random().toString(36).substr(2,9)}},{key:"applyTheme",value:function(e){var t=document.querySelector(".sunuid-qr-code");t&&(t.className="sunuid-qr-code sunuid-theme-".concat(e))}},{key:"handleError",value:function(e){console.error("SunuID SDK Error:",e),this.config.onError&&this.config.onError(e)}},{key:"getQRCode",value:function(){return this.currentQRUrl?this.currentQRUrl:null}},{key:"destroy",value:function(){this.refreshTimer&&clearInterval(this.refreshTimer),this.socket&&(this.socket.disconnect(),this.socket=null,console.log("🌐 WebSocket déconnecté")),this.isInitialized=!1,this.logSecurityEvent("SDK_DESTROY"),console.log("SunuID SDK détruit")}},{key:"getSecurityLogs",value:function(){return e.SunuIDSecurityLogs||[]}},{key:"clearSecurityLogs",value:function(){e.SunuIDSecurityLogs=[],this.logSecurityEvent("SECURITY_LOGS_CLEARED")}}],r&&i(t.prototype,r),o&&i(t,o),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,r,o,d,p,h,g,y,v,m,S,I,b,k}();e.SunuID=d,e.sunuidInstance=null,e.initSunuID=function(t){try{return e.sunuidInstance=new d(t),e.sunuidInstance}catch(e){throw console.error("Erreur lors de l'initialisation de SunuID:",e),e}}}(window)}();
10
+ */(t,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var i=n.call(e,t||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}function f(e){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(e)}!function(e,t){var r,o,c={apiUrl:(null===(t=e.SunuIDConfig)||void 0===t?void 0:t.apiUrl)||"https://api.sunuid.fayma.sn",clientId:null,secretId:null,type:2,partnerName:"SunuID",theme:"light",language:"fr",autoRefresh:!0,refreshInterval:3e4,onSuccess:null,onError:null,onStatusUpdate:null,onExpired:null,enableSecurityLogs:!0,validateInputs:!0,maxRetries:3,requestTimeout:1e4,secureInit:!1,secureInitUrl:null!==(r=e.SunuIDConfig)&&void 0!==r&&null!==(r=r.apiUrl)&&void 0!==r&&r.includes("api.sunuid.fayma.sn")?"https://sunuid.fayma.sn/secure-init.php":(null===(o=e.SunuIDConfig)||void 0===o||null===(o=o.apiUrl)||void 0===o?void 0:o.replace("/api",""))+"/secure-init.php"||"https://sunuid.fayma.sn/secure-init.php",token:null},d=function(){return t=function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.config=s(s({},c),t),this.qrCode=null,this.refreshTimer=null,this.isInitialized=!1,this.socket=null,this.initPromise=this.init()},r=[{key:"init",value:(k=n(a().m(function e(){var t;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(e.p=0,!this.config.secureInit){e.n=2;break}return e.n=1,this.secureInit();case 1:e.n=3;break;case 2:this.config.validateInputs&&this.validateSecurityParams();case 3:this.logSecurityEvent("SDK_INIT_START",{apiUrl:this.config.apiUrl,type:this.config.type,partnerName:this.config.partnerName,secureInit:this.config.secureInit}),this.obfuscateCredentials(),this.isInitialized=!0,console.log("SunuID SDK initialisé avec succès"),this.logSecurityEvent("SDK_INIT_SUCCESS"),this.initWebSocket(),e.n=5;break;case 4:throw e.p=4,t=e.v,this.logSecurityEvent("SDK_INIT_ERROR",{error:t.message}),t;case 5:return e.a(2)}},e,this,[[0,4]])})),function(){return k.apply(this,arguments)})},{key:"secureInit",value:(b=n(a().m(function e(){var t,n,i,r,o;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return e.p=0,this.logSecurityEvent("SECURE_INIT_START"),t={type:this.config.type,partnerName:this.config.partnerName,theme:this.config.theme},e.n=1,fetch(this.config.secureInitUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(t)});case 1:if((n=e.v).ok){e.n=2;break}throw new Error("Erreur HTTP: ".concat(n.status));case 2:return e.n=3,n.json();case 3:if((i=e.v).success){e.n=4;break}throw new Error(i.error||"Erreur lors de l'initialisation sécurisée");case 4:if(this.config.token=i.data.token,this.config.apiUrl=i.data.api_url,!(r=this.decodeSecureToken(i.data.token))){e.n=5;break}this.config.clientId=r.client_id,this.config.secretId=r.secret_id,e.n=6;break;case 5:throw new Error("Impossible de décoder le token sécurisé");case 6:this.config.expiresIn=i.data.expires_in,this.config.maxRequests=i.data.max_requests,this.config.requestCount=0,this.logSecurityEvent("SECURE_INIT_SUCCESS",{expiresIn:i.data.expires_in,maxRequests:i.data.max_requests}),console.log("✅ Initialisation sécurisée réussie"),e.n=8;break;case 7:throw e.p=7,o=e.v,this.logSecurityEvent("SECURE_INIT_ERROR",{error:o.message}),new Error("Échec de l'initialisation sécurisée: ".concat(o.message));case 8:return e.a(2)}},e,this,[[0,7]])})),function(){return b.apply(this,arguments)})},{key:"decodeSecureToken",value:function(e){try{var t=e.split(".");if(2!==t.length)return console.error("❌ Format de token invalide"),null;var n=l(t,2),i=n[0],r=(n[1],atob(i)),o=JSON.parse(r);return o.exp&&o.exp<Date.now()/1e3?(console.error("❌ Token expiré"),null):(console.log("✅ Token décodé avec succès"),o)}catch(e){return console.error("❌ Erreur décodage token:",e),null}}},{key:"initWebSocket",value:function(){var e=this;try{if("undefined"==typeof io)return console.warn("⚠️ Socket.IO non disponible, WebSocket sera initialisé plus tard"),void setTimeout(function(){return e.initWebSocket()},1e3);var t=this.getClientIP();this.socket||(this.socket=io("wss://samasocket.fayma.sn:9443",{query:{token:this.config.clientId,type:"web",userId:this.config.clientId,username:t}}),this.socket.on("connect",function(){console.log("🌐 WebSocket connecté avec succès"),console.log("📊 Socket ID:",e.socket.id)}),this.socket.on("disconnect",function(e){console.log("❌ WebSocket déconnecté:",e)}),this.socket.on("connect_error",function(e){console.error("❌ Erreur connexion WebSocket:",e)}),this.socket.on("qr_status_update",function(t){console.log("📱 Mise à jour statut QR reçue:",t),e.handleQRStatusUpdate(t)}),this.socket.on("qr_scan_success",function(t){console.log("✅ Scan QR réussi reçu:",t),e.handleQRScanSuccess(t)}),this.socket.on("qr_expired",function(t){console.log("⏰ QR expiré reçu:",t),e.handleQRExpired(t)}))}catch(e){console.error("❌ Erreur initialisation WebSocket:",e)}}},{key:"getClientIP",value:function(){return"127.0.0.1"}},{key:"getTypeName",value:function(e){switch(e){case 1:return"KYC";case 2:return"AUTH";case 3:return"SIGNATURE";default:return"TYPE-".concat(e)}}},{key:"validateSecurityParams",value:function(){var e=[];if(this.config.clientId&&"string"==typeof this.config.clientId?this.config.clientId.length<10&&e.push("clientId trop court"):e.push("clientId invalide ou manquant"),this.config.secretId&&"string"==typeof this.config.secretId?this.config.secretId.length<32&&e.push("secretId trop court (minimum 32 caractères)"):e.push("secretId invalide ou manquant"),this.config.apiUrl&&this.isValidUrl(this.config.apiUrl)||e.push("apiUrl invalide"),[1,2,3].includes(this.config.type)||e.push("type invalide (doit être 1, 2 ou 3)"),e.length>0)throw this.logSecurityEvent("VALIDATION_ERROR",{errors:e}),new Error("Paramètres de sécurité invalides: ".concat(e.join(", ")));this.logSecurityEvent("VALIDATION_SUCCESS")}},{key:"isValidUrl",value:function(e){try{var t=new URL(e);return"https:"===t.protocol||"http:"===t.protocol}catch(e){return!1}}},{key:"logSecurityEvent",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.config.enableSecurityLogs){var i={timestamp:(new Date).toISOString(),event:t,data:n,userAgent:navigator.userAgent,url:e.location.href};console.warn("🔒 [SECURITY]",i),e.SunuIDSecurityLogs||(e.SunuIDSecurityLogs=[]),e.SunuIDSecurityLogs.push(i)}}},{key:"obfuscateCredentials",value:function(){this.config.originalClientId=this.config.clientId,this.config.originalSecretId=this.config.secretId,this.config.clientId&&(this.config.clientIdDisplay=this.config.clientId.replace(/(.{3}).*(.{3})/,"$1***$2")),this.config.secretId&&(this.config.secretIdDisplay=this.config.secretId.replace(/(.{4}).*(.{4})/,"$1***$2"))}},{key:"sanitizeInput",value:function(e){return"string"!=typeof e?e:e.replace(/[<>]/g,"").replace(/javascript:/gi,"").trim()}},{key:"handleQRStatusUpdate",value:function(e){this.config.onStatusUpdate&&this.config.onStatusUpdate(e)}},{key:"handleQRScanSuccess",value:function(e){this.config.onSuccess&&this.config.onSuccess(e)}},{key:"handleQRExpired",value:function(e){this.config.onExpired&&this.config.onExpired(e)}},{key:"emitWebSocketEvent",value:function(e,t){this.socket&&this.socket.connected?(this.socket.emit(e,t),console.log("📤 Événement WebSocket émis: ".concat(e),t)):"undefined"==typeof io?console.warn("⚠️ Socket.IO non disponible, impossible d'émettre l'événement:",e):console.warn("⚠️ WebSocket non connecté, impossible d'émettre l'événement:",e)}},{key:"getWebSocketStatus",value:function(){return this.socket?this.socket.connected?"connected":"disconnected":"not_initialized"}},{key:"forceWebSocketInit",value:function(){"undefined"==typeof io||this.socket||(console.log("🔄 Forçage de l'initialisation WebSocket..."),this.initWebSocket())}},{key:"generateQR",value:(I=n(a().m(function e(t){var n,i,r,o,c,u=this,l=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(n=l.length>1&&void 0!==l[1]?l[1]:{},!this.initPromise){e.n=2;break}return e.n=1,this.initPromise;case 1:this.initPromise=null;case 2:if(this.isInitialized){e.n=3;break}throw new Error("SunuID: SDK non initialisé");case 3:return e.p=3,e.n=4,this.makeRequest("/qr-generate",s({type:this.config.type},n));case 4:if(!(i=e.v).success){e.n=5;break}return r="".concat("https://sunuid.fayma.sn").concat(i.data.qrcode),this.currentQRUrl=r,this.displayQRCode(t,r,this.config.type,n),this.pendingQRInfo&&i.data.code&&(o=function(){if(u.socket&&u.socket.id&&"unknown"!==u.socket.id){var e=u.socket.id,t="".concat(u.config.type,"-").concat(i.data.code,"-").concat(e),n=i.data.partnerName||u.config.partnerName||"SunuID",r=u.getTypeName(u.config.type),s="".concat(r," - ").concat(n);u.generateCustomQRCode(t,s,u.pendingQRInfo.options),u.pendingQRInfo=null}else setTimeout(o,100)})(),this.startAutoRefresh(t,this.config.type,n),this.emitWebSocketEvent("qr_generated",{serviceId:i.data.service_id,type:this.config.type,qrCodeUrl:r,code:i.data.code,timestamp:Date.now()}),e.a(2,s(s({},i.data),{},{qrCodeUrl:r,sessionId:i.data.service_id}));case 5:throw new Error(i.message||"Erreur lors de la génération du QR code");case 6:e.n=8;break;case 7:throw e.p=7,c=e.v,console.error("Erreur API détectée:",c.message),console.error("Stack trace complet:",c.stack),console.error("Configuration SDK:",{apiUrl:this.config.apiUrl,type:this.config.type,secureInit:this.config.secureInit,clientId:this.config.clientId?"***"+this.config.clientId.slice(-4):"null",secretId:this.config.secretId?"***"+this.config.secretId.slice(-4):"null"}),console.log('Affichage du message "Service non disponible" pour type '+this.config.type),this.displayServiceUnavailable(t,this.config.type),new Error("Service non disponible");case 8:return e.a(2)}},e,this,[[3,7]])})),function(e){return I.apply(this,arguments)})},{key:"generateCustomQR",value:(S=n(a().m(function e(t,n){var i,r,o,c,u,l=this,d=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(i=d.length>2&&void 0!==d[2]?d[2]:{},!this.initPromise){e.n=2;break}return e.n=1,this.initPromise;case 1:this.initPromise=null;case 2:if(this.isInitialized){e.n=3;break}throw new Error("SunuID: SDK non initialisé");case 3:return e.p=3,e.n=4,this.makeRequest("/qr-generate",s({type:n},i));case 4:if(!(r=e.v).success){e.n=5;break}return o="".concat("https://sunuid.fayma.sn").concat(r.data.qrcode),this.displayQRCode(t,o,n,i),this.pendingQRInfo&&r.data.code&&(c=function(){if(l.socket&&l.socket.id&&"unknown"!==l.socket.id){var e=l.socket.id,t="".concat(n,"-").concat(r.data.code,"-").concat(e),i=r.data.partnerName||l.config.partnerName||"SunuID",o=l.getTypeName(n),s="".concat(o," - ").concat(i);l.generateCustomQRCode(t,s,l.pendingQRInfo.options),l.pendingQRInfo=null}else setTimeout(c,100)})(),this.startAutoRefresh(t,n,i),e.a(2,s(s({},r.data),{},{qrCodeUrl:o,sessionId:r.data.service_id}));case 5:throw new Error(r.message||"Erreur lors de la génération du QR code");case 6:e.n=8;break;case 7:throw e.p=7,u=e.v,console.error("Erreur API détectée:",u.message),console.error("Stack trace complet:",u.stack),console.error("Configuration SDK (Custom):",{apiUrl:this.config.apiUrl,type:n,secureInit:this.config.secureInit,clientId:this.config.clientId?"***"+this.config.clientId.slice(-4):"null",secretId:this.config.secretId?"***"+this.config.secretId.slice(-4):"null"}),console.log('Affichage du message "Service non disponible" pour type '+n),this.displayServiceUnavailable(t,n),new Error("Service non disponible");case 8:return e.a(2)}},e,this,[[3,7]])})),function(e,t){return S.apply(this,arguments)})},{key:"generateAuthQR",value:(m=n(a().m(function e(t){var n,i=arguments;return a().w(function(e){for(;;)if(0===e.n)return n=i.length>1&&void 0!==i[1]?i[1]:{},e.a(2,this.generateQR(t,n))},e,this)})),function(e){return m.apply(this,arguments)})},{key:"generateKYCQR",value:(v=n(a().m(function e(t){var n,i,r=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return n=r.length>1&&void 0!==r[1]?r[1]:{},i=this.config.type,this.config.type=1,e.p=1,e.n=2,this.generateQR(t,n);case 2:return e.a(2,e.v);case 3:return e.p=3,this.config.type=i,e.f(3);case 4:return e.a(2)}},e,this,[[1,,3,4]])})),function(e){return v.apply(this,arguments)})},{key:"generateSignatureQR",value:(y=n(a().m(function e(t){var n,i,r=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return n=r.length>1&&void 0!==r[1]?r[1]:{},i=this.config.type,this.config.type=3,e.p=1,e.n=2,this.generateQR(t,n);case 2:return e.a(2,e.v);case 3:return e.p=3,this.config.type=i,e.f(3);case 4:return e.a(2)}},e,this,[[1,,3,4]])})),function(e){return y.apply(this,arguments)})},{key:"checkQRStatus",value:(g=n(a().m(function e(t){var n,i;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(this.isInitialized){e.n=1;break}throw new Error("SunuID: SDK non initialisé");case 1:return e.p=1,e.n=2,this.makeRequest("/qr-status",{serviceId:t});case 2:if(!(n=e.v).success){e.n=3;break}return e.a(2,n.data);case 3:throw new Error(n.message||"Erreur lors de la vérification du statut");case 4:e.n=6;break;case 5:throw e.p=5,i=e.v,this.handleError(i),i;case 6:return e.a(2)}},e,this,[[1,5]])})),function(e){return g.apply(this,arguments)})},{key:"displayQRCode",value:function(e,t,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},r=document.getElementById(e);if(!r)throw new Error("Conteneur avec l'ID \"".concat(e,'" non trouvé'));r.innerHTML="";var o=document.createElement("div");o.className="sunuid-qr-code",this.getTypeName(n),o.innerHTML='\n <div class="sunuid-qr-header">\n <h3>'.concat(1===n?"Vérification KYC":2===n?"Authentification":3===n?"Signature":"Service Type "+n,'</h3>\n </div>\n <div class="sunuid-qr-image" id="sunuid-qr-container">\n <div style="text-align: center; padding: 40px;">\n <div class="sunuid-loader">\n <div class="sunuid-spinner"></div>\n <p style="margin-top: 20px; color: #666;">Initialisation en cours...</p>\n <p style="font-size: 12px; color: #999; margin-top: 10px;">Connexion API et WebSocket</p>\n <p style="font-size: 11px; color: #ccc; margin-top: 5px;">Attente du Socket ID...</p>\n </div>\n </div>\n </div>\n <div class="sunuid-qr-instructions" style="display: none;">\n <p>Scannez ce QR code avec l\'application ').concat(this.config.partnerName,' pour vous connecter</p>\n </div>\n <div class="sunuid-qr-status" id="sunuid-status" style="display: none;">\n <p>En attente de scan...</p>\n </div>\n '),r.appendChild(o),this.pendingQRInfo={containerId:e,type:n,options:i},this.applyTheme(i.theme||this.config.theme)}},{key:"generateCustomQRCode",value:(h=n(a().m(function e(t,n){var i,r,o,s,c,u,l;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:if(e.p=1,console.log("🎨 Début génération QR personnalisé avec PHP..."),console.log("📄 Contenu:",t),console.log("🏷️ Label:",n),i=document.getElementById("sunuid-qr-container")){e.n=2;break}return console.error("❌ QR container not found"),this.displayFallbackImage(),e.a(2);case 2:return console.log("✅ QR container trouvé"),i.innerHTML='<div style="text-align: center; padding: 20px;"><p>Génération QR code avec PHP...</p></div>',console.log("🔄 Appel endpoint PHP..."),r=this.config.apiUrl.includes("api.sunuid.fayma.sn")?"https://sunuid.fayma.sn/qr-generator.php":this.config.apiUrl.replace("/api","")+"/qr-generator.php",console.log("🔗 URL QR Generator:",r),e.n=3,fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({content:t,label:n,size:300,margin:10})});case 3:if(o=e.v,console.log("📥 Réponse PHP reçue - Status:",o.status),o.ok){e.n=4;break}throw new Error("Erreur HTTP: ".concat(o.status));case 4:return e.n=5,o.json();case 5:if((s=e.v).success){e.n=6;break}throw new Error("Erreur PHP: ".concat(s.error));case 6:console.log("✅ QR code généré par PHP avec succès"),console.log("📊 Taille:",s.data.size+"px"),console.log("📊 Longueur base64:",s.data.length+" caractères"),this.currentQRUrl=s.data.dataUrl,i.innerHTML='\n <div class="sunuid-qr-ready" style="text-align: center; padding: 20px;">\n <img src="'.concat(s.data.dataUrl,'" alt="QR Code ').concat(this.config.partnerName,'" style="max-width: 300px; border: 2px solid #ddd; border-radius: 10px;">\n </div>\n '),c=i.parentElement.querySelector(".sunuid-qr-instructions"),u=i.parentElement.querySelector(".sunuid-qr-status"),c&&(c.style.display="block",c.classList.add("sunuid-qr-ready")),u&&(u.style.display="block",u.classList.add("sunuid-qr-ready")),console.log("✅ QR code PHP affiché dans le conteneur"),e.n=8;break;case 7:e.p=7,l=e.v,console.error("❌ Erreur génération QR PHP:",l),console.error("Stack trace:",l.stack),l.message.includes("Failed to fetch")||l.message.includes("CORS")?(console.warn("🚫 Erreur CORS détectée, tentative de génération QR côté client..."),this.generateQRCodeClientSide(t,n,qrContainer)):this.displayFallbackImage();case 8:return e.a(2)}},e,this,[[1,7]])})),function(e,t){return h.apply(this,arguments)})},{key:"generateQRCodeClientSide",value:function(e,t,n){var i=this;try{if(console.log("🎨 Génération QR côté client..."),"undefined"==typeof QRCode)return console.error("❌ QRCode library non disponible"),void this.displayFallbackImage();var r=document.createElement("canvas");r.width=300,r.height=300;var o=r.getContext("2d");QRCode.toCanvas(r,e,{width:280,margin:10,color:{dark:"#000000",light:"#FFFFFF"}},function(e){if(e)return console.error("❌ Erreur génération QR côté client:",e),void i.displayFallbackImage();o.fillStyle="#333333",o.font="14px Arial",o.textAlign="center",o.fillText(t,150,295);var s=r.toDataURL("image/png");i.currentQRUrl=s,n.innerHTML='\n <div class="sunuid-qr-ready" style="text-align: center; padding: 20px;">\n <img src="'.concat(s,'" alt="QR Code ').concat(i.config.partnerName,'" style="max-width: 300px; border: 2px solid #ddd; border-radius: 10px;">\n <p style="margin-top: 10px; font-size: 12px; color: #666;">Généré côté client (CORS)</p>\n </div>\n ');var a=n.parentElement.querySelector(".sunuid-qr-instructions"),c=n.parentElement.querySelector(".sunuid-qr-status");a&&(a.style.display="block",a.classList.add("sunuid-qr-ready")),c&&(c.style.display="block",c.classList.add("sunuid-qr-ready")),console.log("✅ QR code côté client généré avec succès")})}catch(e){console.error("❌ Erreur génération QR côté client:",e),this.displayFallbackImage()}}},{key:"addLogoToCenter",value:function(e,t,n,i,r){try{var o=new Image;o.onload=function(){var r=40,s=t+(i-r)/2,a=n+(i-r)/2;e.fillStyle="white",e.fillRect(s-2,a-2,44,44),e.drawImage(o,s,a,r,r)},o.src="src/logoqr.png"}catch(e){console.warn("Logo non disponible:",e)}}},{key:"displayFallbackImage",value:function(){console.log("⚠️ Affichage de l'image de fallback");var e=document.getElementById("sunuid-qr-container");e?e.innerHTML='\n <div style="text-align: center; padding: 20px; color: #666;">\n <p>⚠️ Génération QR personnalisé non disponible</p>\n <p>Utilisation de l\'image par défaut</p>\n <p><strong>Debug:</strong> QRCode disponible: '.concat("undefined"!=typeof QRCode,"</p>\n <p><strong>Debug:</strong> Container trouvé: ").concat(null!==e,"</p>\n </div>\n "):console.error("❌ Container QR non trouvé pour fallback")}},{key:"displayServiceUnavailable",value:function(e,t){console.log("displayServiceUnavailable appelée pour ".concat(e,", type: ").concat(t));var n=document.getElementById(e);n?n.innerHTML='\n <div class="sunuid-service-unavailable" style="\n text-align: center;\n padding: 40px 20px;\n background: #f8f9fa;\n border: 2px dashed #dee2e6;\n border-radius: 10px;\n color: #6c757d;\n font-family: Arial, sans-serif;\n ">\n <div style="font-size: 48px; margin-bottom: 20px;">⚠️</div>\n <h3 style="margin: 0 0 10px 0; color: #495057;">Service Non Disponible</h3>\n <p style="margin: 0; font-size: 14px;">\n Le service d\'authentification est temporairement indisponible.<br>\n Veuillez réessayer plus tard.\n </p>\n <div style="margin-top: 20px; font-size: 12px; color: #adb5bd;">\n Type: '.concat(String(t).toUpperCase(),"\n </div>\n </div>\n "):console.error("Container ".concat(e," non trouvé"))}},{key:"refreshQR",value:(p=n(a().m(function e(t){var n,i,r,o=arguments;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return n=o.length>1&&void 0!==o[1]?o[1]:{},e.p=1,e.n=2,this.generateQR(t,n);case 2:return i=e.v,e.a(2,i);case 3:throw e.p=3,r=e.v,console.error("Erreur lors du rafraîchissement:",r.message),this.displayServiceUnavailable(t,this.config.type),r;case 4:return e.a(2)}},e,this,[[1,3]])})),function(e){return p.apply(this,arguments)})},{key:"startAutoRefresh",value:function(e,t,i){var r=this;this.config.autoRefresh&&(this.refreshTimer=setInterval(n(a().m(function n(){var o;return a().w(function(n){for(;;)switch(n.p=n.n){case 0:return n.p=0,n.n=1,r.refreshQR(e,t,i);case 1:n.n=3;break;case 2:n.p=2,o=n.v,console.warn("Erreur lors du rafraîchissement automatique:",o);case 3:return n.a(2)}},n,null,[[0,2]])})),this.config.refreshInterval))}},{key:"makeRequest",value:(d=n(a().m(function t(n,i){var r,o,s,c,l,d,f,p,h,g=this;return a().w(function(t){for(;;)switch(t.n){case 0:if(this.isInitialized){t.n=1;break}throw this.logSecurityEvent("REQUEST_BEFORE_INIT",{endpoint:n}),new Error("SDK non initialisé");case 1:if(!this.config.secureInit){t.n=2;break}if(this.config.requestCount++,!(this.config.requestCount>this.config.maxRequests)){t.n=2;break}throw this.logSecurityEvent("API_REQUEST_LIMIT_EXCEEDED",{requestCount:this.config.requestCount,maxRequests:this.config.maxRequests}),new Error("Limite de requêtes dépassée");case 2:s=this.sanitizeRequestData(i),console.log("🔍 Debug makeRequest - endpoint:",n),console.log("🔍 Debug makeRequest - apiUrl:",this.config.apiUrl),console.log("🔍 Debug makeRequest - url:","".concat(this.config.apiUrl).concat(n)),console.log("🔍 Debug makeRequest - data:",JSON.stringify(s,null,2)),console.log("🔍 Debug makeRequest - secureInit:",this.config.secureInit),console.log("🔍 Debug makeRequest - isInitialized:",this.isInitialized),c=(null===(r=e.SunuIDConfig)||void 0===r||null===(r=r.endpoints)||void 0===r?void 0:r[n.replace("/","")])||n,l="".concat(this.config.apiUrl).concat(c),console.log("🔍 URL finale construite:",l),console.log("🔍 EndpointPath:",c),console.log("🔍 SunuIDConfig endpoints:",JSON.stringify(null===(o=e.SunuIDConfig)||void 0===o?void 0:o.endpoints)),this.logSecurityEvent("API_REQUEST_START",{endpoint:c,url:l,dataKeys:Object.keys(s),secureInit:this.config.secureInit}),d=0,f=this.config.maxRetries,p=a().m(function e(){var t,n,i,r,o,u,p,h;return a().w(function(e){for(;;)switch(e.p=e.n){case 0:return e.p=0,t=new AbortController,n=setTimeout(function(){return t.abort()},g.config.requestTimeout),i={"Content-Type":"application/json"},e.n=1,fetch(l,{method:"POST",headers:i,body:JSON.stringify(s),signal:t.signal});case 1:if(r=e.v,clearTimeout(n),r.ok){e.n=3;break}return e.n=2,r.text();case 2:o=e.v;try{u=JSON.parse(o)}catch(e){u={message:o}}throw g.logSecurityEvent("API_REQUEST_ERROR",{status:r.status,statusText:r.statusText,error:u.message}),new Error(u.message||"Erreur HTTP: ".concat(r.status));case 3:return e.n=4,r.json();case 4:return p=e.v,g.logSecurityEvent("API_REQUEST_SUCCESS",{endpoint:c,responseKeys:Object.keys(p)}),e.a(2,{v:p});case 5:if(e.p=5,h=e.v,d++,"AbortError"!==h.name){e.n=7;break}if(g.logSecurityEvent("API_REQUEST_TIMEOUT",{retryCount:d}),!(d>f)){e.n=6;break}throw new Error("Timeout de la requête API");case 6:return e.a(2,0);case 7:if(!(d>f)){e.n=8;break}throw g.logSecurityEvent("API_REQUEST_MAX_RETRIES",{retryCount:d,error:h.message}),h;case 8:return e.n=9,new Promise(function(e){return setTimeout(e,1e3*d)});case 9:return e.a(2)}},e,null,[[0,5]])});case 3:if(!(d<=f)){t.n=7;break}return t.d(u(p()),4);case 4:if(0!==(h=t.v)){t.n=5;break}return t.a(3,3);case 5:if(!h){t.n=6;break}return t.a(2,h.v);case 6:t.n=3;break;case 7:return t.a(2)}},t,this)})),function(e,t){return d.apply(this,arguments)})},{key:"sanitizeRequestData",value:function(e){for(var t={},n=0,i=Object.entries(e);n<i.length;n++){var r=l(i[n],2),o=r[0],s=r[1];"string"==typeof s?t[o]=this.sanitizeInput(s):"object"===f(s)&&null!==s?t[o]=this.sanitizeRequestData(s):t[o]=s}return t.client_id=this.config.originalClientId||this.config.clientId,t.secret_id=this.config.originalSecretId||this.config.secretId,console.log("🔍 Credentials dans sanitizeRequestData - clientId:",this.config.clientId),console.log("🔍 Credentials dans sanitizeRequestData - secretId:",this.config.secretId?"***"+this.config.secretId.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedClientId:",t.client_id),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:",t.secret_id?"***"+t.secret_id.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - data complet:",JSON.stringify(t,null,2)),console.log("🔍 Credentials dans sanitizeRequestData - clientId:",this.config.clientId),console.log("🔍 Credentials dans sanitizeRequestData - secretId:",this.config.secretId?"***"+this.config.secretId.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedClientId:",t.client_id),console.log("🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:",t.secret_id?"***"+t.secret_id.slice(-4):"null"),console.log("🔍 Credentials dans sanitizeRequestData - data complet:",JSON.stringify(t,null,2)),t}},{key:"generateRequestId",value:function(){return"req_"+Date.now()+"_"+Math.random().toString(36).substr(2,9)}},{key:"applyTheme",value:function(e){var t=document.querySelector(".sunuid-qr-code");t&&(t.className="sunuid-qr-code sunuid-theme-".concat(e))}},{key:"handleError",value:function(e){console.error("SunuID SDK Error:",e),this.config.onError&&this.config.onError(e)}},{key:"getQRCode",value:function(){return this.currentQRUrl?this.currentQRUrl:null}},{key:"destroy",value:function(){this.refreshTimer&&clearInterval(this.refreshTimer),this.socket&&(this.socket.disconnect(),this.socket=null,console.log("🌐 WebSocket déconnecté")),this.isInitialized=!1,this.logSecurityEvent("SDK_DESTROY"),console.log("SunuID SDK détruit")}},{key:"getSecurityLogs",value:function(){return e.SunuIDSecurityLogs||[]}},{key:"clearSecurityLogs",value:function(){e.SunuIDSecurityLogs=[],this.logSecurityEvent("SECURITY_LOGS_CLEARED")}}],r&&i(t.prototype,r),o&&i(t,o),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,r,o,d,p,h,g,y,v,m,S,I,b,k}();e.SunuID=d,e.sunuidInstance=null,e.initSunuID=function(t){try{return e.sunuidInstance=new d(t),e.sunuidInstance}catch(e){throw console.error("Erreur lors de l'initialisation de SunuID:",e),e}}}(window)}();
11
11
  //# sourceMappingURL=sunuid-sdk.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sunuid-sdk.min.js","sources":["../src/sunuid-sdk.js"],"sourcesContent":["/**\n * SunuID SDK - Package d'intégration pour partenaires\n * \n * @version 1.0.0\n * @author SunuID Team\n * @license MIT\n */\n\n(function(window) {\n 'use strict';\n\n // Configuration par défaut\n const DEFAULT_CONFIG = {\n apiUrl: window.SunuIDConfig?.apiUrl || 'https://api.sunuid.fayma.sn',\n clientId: null,\n secretId: null,\n type: 2, // Type par défaut (2 = authentification)\n partnerName: 'SunuID', // Nom du partenaire par défaut\n theme: 'light',\n language: 'fr',\n autoRefresh: true,\n refreshInterval: 30000, // 30 secondes\n onSuccess: null,\n onError: null,\n onStatusUpdate: null,\n onExpired: null,\n // Nouvelles options de sécurité\n enableSecurityLogs: true,\n validateInputs: true,\n maxRetries: 3,\n requestTimeout: 10000, // 10 secondes\n // Options d'initialisation sécurisée\n secureInit: false,\n secureInitUrl: (() => {\n if (window.SunuIDConfig?.apiUrl?.includes('api.sunuid.fayma.sn')) {\n return 'https://sunuid.fayma.sn/secure-init.php';\n }\n return window.SunuIDConfig?.apiUrl?.replace('/api', '') + '/secure-init.php' || 'https://sunuid.fayma.sn/secure-init.php';\n })(),\n token: null\n };\n\n /**\n * Classe principale SunuID\n */\n class SunuID {\n constructor(config = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.qrCode = null;\n this.refreshTimer = null;\n this.isInitialized = false;\n this.socket = null;\n \n // Initialisation asynchrone\n this.initPromise = this.init();\n }\n\n /**\n * Initialisation du SDK\n */\n async init() {\n try {\n // Initialisation sécurisée si activée\n if (this.config.secureInit) {\n await this.secureInit();\n } else {\n // Validation sécurisée des paramètres\n if (this.config.validateInputs) {\n this.validateSecurityParams();\n }\n }\n\n // Log de sécurité pour l'initialisation\n this.logSecurityEvent('SDK_INIT_START', {\n apiUrl: this.config.apiUrl,\n type: this.config.type,\n partnerName: this.config.partnerName,\n secureInit: this.config.secureInit\n });\n\n // Obscurcir les credentials dans les logs\n this.obfuscateCredentials();\n\n this.isInitialized = true;\n console.log('SunuID SDK initialisé avec succès');\n \n this.logSecurityEvent('SDK_INIT_SUCCESS');\n \n // Initialiser la connexion WebSocket\n this.initWebSocket();\n \n } catch (error) {\n this.logSecurityEvent('SDK_INIT_ERROR', { error: error.message });\n throw error;\n }\n }\n\n /**\n * Initialisation sécurisée via PHP\n */\n async secureInit() {\n try {\n this.logSecurityEvent('SECURE_INIT_START');\n \n const initData = {\n type: this.config.type,\n partnerName: this.config.partnerName,\n theme: this.config.theme\n };\n\n const response = await fetch(this.config.secureInitUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n body: JSON.stringify(initData)\n });\n\n if (!response.ok) {\n throw new Error(`Erreur HTTP: ${response.status}`);\n }\n\n const result = await response.json();\n \n if (!result.success) {\n throw new Error(result.error || 'Erreur lors de l\\'initialisation sécurisée');\n }\n\n // Stocker le token et les données sécurisées\n this.config.token = result.data.token;\n this.config.apiUrl = result.data.api_url;\n \n // Décoder le token pour récupérer les credentials\n const decodedToken = this.decodeSecureToken(result.data.token);\n if (decodedToken) {\n this.config.clientId = decodedToken.client_id;\n this.config.secretId = decodedToken.secret_id;\n } else {\n throw new Error('Impossible de décoder le token sécurisé');\n }\n \n this.config.expiresIn = result.data.expires_in;\n this.config.maxRequests = result.data.max_requests;\n this.config.requestCount = 0;\n\n this.logSecurityEvent('SECURE_INIT_SUCCESS', {\n expiresIn: result.data.expires_in,\n maxRequests: result.data.max_requests\n });\n\n console.log('✅ Initialisation sécurisée réussie');\n \n } catch (error) {\n this.logSecurityEvent('SECURE_INIT_ERROR', { error: error.message });\n throw new Error(`Échec de l'initialisation sécurisée: ${error.message}`);\n }\n }\n\n /**\n * Décoder le token sécurisé\n */\n decodeSecureToken(token) {\n try {\n const parts = token.split('.');\n if (parts.length !== 2) {\n console.error('❌ Format de token invalide');\n return null;\n }\n \n const [payload, signature] = parts;\n \n // Décoder le payload (base64)\n const decodedPayload = atob(payload);\n const tokenData = JSON.parse(decodedPayload);\n \n // Vérifier l'expiration\n if (tokenData.exp && tokenData.exp < Date.now() / 1000) {\n console.error('❌ Token expiré');\n return null;\n }\n \n console.log('✅ Token décodé avec succès');\n return tokenData;\n \n } catch (error) {\n console.error('❌ Erreur décodage token:', error);\n return null;\n }\n }\n\n /**\n * Initialiser la connexion WebSocket\n */\n initWebSocket() {\n try {\n // Vérifier si Socket.IO est disponible\n if (typeof io === 'undefined') {\n console.warn('⚠️ Socket.IO non disponible, WebSocket sera initialisé plus tard');\n // Réessayer après un délai\n setTimeout(() => this.initWebSocket(), 1000);\n return;\n }\n \n // Obtenir l'IP du client (simulation)\n const ip = this.getClientIP();\n \n // Initialiser la connexion WebSocket si elle n'existe pas\n if (!this.socket) {\n this.socket = io('wss://samasocket.fayma.sn:9443', {\n query: {\n token: this.config.clientId,\n type: 'web',\n userId: this.config.clientId,\n username: ip\n }\n });\n\n // Gestion des événements WebSocket\n this.socket.on('connect', () => {\n console.log('🌐 WebSocket connecté avec succès');\n console.log('📊 Socket ID:', this.socket.id);\n });\n\n this.socket.on('disconnect', (reason) => {\n console.log('❌ WebSocket déconnecté:', reason);\n });\n\n this.socket.on('connect_error', (error) => {\n console.error('❌ Erreur connexion WebSocket:', error);\n });\n\n // Écouter les événements spécifiques\n this.socket.on('qr_status_update', (data) => {\n console.log('📱 Mise à jour statut QR reçue:', data);\n this.handleQRStatusUpdate(data);\n });\n\n this.socket.on('qr_scan_success', (data) => {\n console.log('✅ Scan QR réussi reçu:', data);\n this.handleQRScanSuccess(data);\n });\n\n this.socket.on('qr_expired', (data) => {\n console.log('⏰ QR expiré reçu:', data);\n this.handleQRExpired(data);\n });\n }\n } catch (error) {\n console.error('❌ Erreur initialisation WebSocket:', error);\n }\n }\n\n /**\n * Obtenir l'IP du client (simulation)\n */\n getClientIP() {\n // Simulation - en production, vous pourriez utiliser un service d'IP\n return '127.0.0.1';\n }\n\n /**\n * Obtenir le nom du type à partir du numéro\n */\n getTypeName(type) {\n switch(type) {\n case 1: return 'KYC';\n case 2: return 'AUTH';\n case 3: return 'SIGNATURE';\n default: return `TYPE-${type}`;\n }\n }\n\n /**\n * Validation sécurisée des paramètres\n */\n validateSecurityParams() {\n const errors = [];\n \n // Validation du clientId\n if (!this.config.clientId || typeof this.config.clientId !== 'string') {\n errors.push('clientId invalide ou manquant');\n } else if (this.config.clientId.length < 10) {\n errors.push('clientId trop court');\n }\n \n // Validation du secretId\n if (!this.config.secretId || typeof this.config.secretId !== 'string') {\n errors.push('secretId invalide ou manquant');\n } else if (this.config.secretId.length < 32) {\n errors.push('secretId trop court (minimum 32 caractères)');\n }\n \n // Validation de l'URL API\n if (!this.config.apiUrl || !this.isValidUrl(this.config.apiUrl)) {\n errors.push('apiUrl invalide');\n }\n \n // Validation du type\n if (![1, 2, 3].includes(this.config.type)) {\n errors.push('type invalide (doit être 1, 2 ou 3)');\n }\n \n if (errors.length > 0) {\n this.logSecurityEvent('VALIDATION_ERROR', { errors });\n throw new Error(`Paramètres de sécurité invalides: ${errors.join(', ')}`);\n }\n \n this.logSecurityEvent('VALIDATION_SUCCESS');\n }\n\n /**\n * Validation d'URL sécurisée\n */\n isValidUrl(string) {\n try {\n const url = new URL(string);\n return url.protocol === 'https:' || url.protocol === 'http:';\n } catch (_) {\n return false;\n }\n }\n\n /**\n * Logs de sécurité\n */\n logSecurityEvent(event, data = {}) {\n if (!this.config.enableSecurityLogs) return;\n \n const securityLog = {\n timestamp: new Date().toISOString(),\n event: event,\n data: data,\n userAgent: navigator.userAgent,\n url: window.location.href\n };\n \n console.warn('🔒 [SECURITY]', securityLog);\n \n // Stocker les logs de sécurité (optionnel)\n if (!window.SunuIDSecurityLogs) {\n window.SunuIDSecurityLogs = [];\n }\n window.SunuIDSecurityLogs.push(securityLog);\n }\n\n /**\n * Chiffrement simple des credentials (pour éviter l'exposition en clair)\n */\n obfuscateCredentials() {\n // Stocker les vraies valeurs pour les logs de sécurité\n this.config.originalClientId = this.config.clientId;\n this.config.originalSecretId = this.config.secretId;\n \n // Créer des versions obfusquées pour l'affichage uniquement\n if (this.config.clientId) {\n this.config.clientIdDisplay = this.config.clientId.replace(/(.{3}).*(.{3})/, '$1***$2');\n }\n if (this.config.secretId) {\n this.config.secretIdDisplay = this.config.secretId.replace(/(.{4}).*(.{4})/, '$1***$2');\n }\n }\n\n /**\n * Validation des entrées utilisateur\n */\n sanitizeInput(input) {\n if (typeof input !== 'string') return input;\n \n // Protection contre les injections XSS basiques\n return input\n .replace(/[<>]/g, '') // Supprimer les balises HTML\n .replace(/javascript:/gi, '') // Supprimer les protocoles dangereux\n .trim();\n }\n\n /**\n * Gérer la mise à jour du statut QR\n */\n handleQRStatusUpdate(data) {\n if (this.config.onStatusUpdate) {\n this.config.onStatusUpdate(data);\n }\n }\n\n /**\n * Gérer le succès du scan QR\n */\n handleQRScanSuccess(data) {\n if (this.config.onSuccess) {\n this.config.onSuccess(data);\n }\n }\n\n /**\n * Gérer l'expiration du QR\n */\n handleQRExpired(data) {\n if (this.config.onExpired) {\n this.config.onExpired(data);\n }\n }\n\n /**\n * Émettre un événement WebSocket\n */\n emitWebSocketEvent(event, data) {\n if (this.socket && this.socket.connected) {\n this.socket.emit(event, data);\n console.log(`📤 Événement WebSocket émis: ${event}`, data);\n } else if (typeof io === 'undefined') {\n console.warn('⚠️ Socket.IO non disponible, impossible d\\'émettre l\\'événement:', event);\n } else {\n console.warn('⚠️ WebSocket non connecté, impossible d\\'émettre l\\'événement:', event);\n }\n }\n\n /**\n * Obtenir le statut de la connexion WebSocket\n */\n getWebSocketStatus() {\n if (!this.socket) {\n return 'not_initialized';\n }\n return this.socket.connected ? 'connected' : 'disconnected';\n }\n\n /**\n * Forcer l'initialisation WebSocket (si Socket.IO devient disponible plus tard)\n */\n forceWebSocketInit() {\n if (typeof io !== 'undefined' && !this.socket) {\n console.log('🔄 Forçage de l\\'initialisation WebSocket...');\n this.initWebSocket();\n }\n }\n\n /**\n * Générer un QR code avec le type configuré\n */\n async generateQR(containerId, options = {}) {\n // Attendre l'initialisation si nécessaire\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n \n if (!this.isInitialized) {\n throw new Error('SunuID: SDK non initialisé');\n }\n\n try {\n const response = await this.makeRequest('/qr-generate', {\n type: this.config.type, // Utilise le type configuré\n ...options\n });\n\n if (response.success) {\n // Construire l'URL complète de l'image QR avec la base URL pour les images\n const imageBaseUrl = 'https://sunuid.fayma.sn';\n const qrImageUrl = `${imageBaseUrl}${response.data.qrcode}`;\n this.currentQRUrl = qrImageUrl; // Stocker l'URL pour getQRCode()\n this.displayQRCode(containerId, qrImageUrl, this.config.type, options);\n \n // Générer le QR code personnalisé avec le type + code de l'API + socket ID\n if (this.pendingQRInfo && response.data.code) {\n // Attendre que le socket ID soit bien défini\n const waitForSocketId = () => {\n if (this.socket && this.socket.id && this.socket.id !== 'unknown') {\n const socketId = this.socket.id;\n const qrContent = `${this.config.type}-${response.data.code}-${socketId}`;\n \n // Utiliser le partnerName de la réponse API et le nom du type\n const partnerName = response.data.partnerName || this.config.partnerName || 'SunuID';\n const typeName = this.getTypeName(this.config.type);\n const qrLabel = `${typeName} - ${partnerName}`;\n \n this.generateCustomQRCode(qrContent, qrLabel, this.pendingQRInfo.options);\n this.pendingQRInfo = null; // Nettoyer\n } else {\n // Réessayer après un délai si le socket ID n'est pas encore disponible\n setTimeout(waitForSocketId, 100);\n }\n };\n \n waitForSocketId();\n }\n \n this.startAutoRefresh(containerId, this.config.type, options);\n \n // Émettre un événement WebSocket pour la génération du QR\n this.emitWebSocketEvent('qr_generated', {\n serviceId: response.data.service_id,\n type: this.config.type,\n qrCodeUrl: qrImageUrl,\n code: response.data.code,\n timestamp: Date.now()\n });\n \n return {\n ...response.data,\n qrCodeUrl: qrImageUrl,\n sessionId: response.data.service_id\n };\n } else {\n throw new Error(response.message || 'Erreur lors de la génération du QR code');\n }\n } catch (error) {\n console.error('Erreur API détectée:', error.message);\n console.error('Stack trace complet:', error.stack);\n console.error('Configuration SDK:', {\n apiUrl: this.config.apiUrl,\n type: this.config.type,\n secureInit: this.config.secureInit,\n clientId: this.config.clientId ? '***' + this.config.clientId.slice(-4) : 'null',\n secretId: this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null'\n });\n console.log('Affichage du message \"Service non disponible\" pour type ' + this.config.type);\n this.displayServiceUnavailable(containerId, this.config.type);\n throw new Error('Service non disponible');\n }\n }\n\n\n\n /**\n * Générer un QR code avec un type personnalisé\n */\n async generateCustomQR(containerId, type, options = {}) {\n // Attendre l'initialisation si nécessaire\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n \n if (!this.isInitialized) {\n throw new Error('SunuID: SDK non initialisé');\n }\n\n try {\n const response = await this.makeRequest('/qr-generate', {\n type: type, // Type personnalisé (1, 2, 3, etc.)\n ...options\n });\n\n if (response.success) {\n // Construire l'URL complète de l'image QR avec la base URL pour les images\n const imageBaseUrl = 'https://sunuid.fayma.sn';\n const qrImageUrl = `${imageBaseUrl}${response.data.qrcode}`;\n this.displayQRCode(containerId, qrImageUrl, type, options);\n \n // Générer le QR code personnalisé avec le type + code de l'API + socket ID\n if (this.pendingQRInfo && response.data.code) {\n // Attendre que le socket ID soit bien défini\n const waitForSocketId = () => {\n if (this.socket && this.socket.id && this.socket.id !== 'unknown') {\n const socketId = this.socket.id;\n const qrContent = `${type}-${response.data.code}-${socketId}`;\n \n // Utiliser le partnerName de la réponse API et le nom du type\n const partnerName = response.data.partnerName || this.config.partnerName || 'SunuID';\n const typeName = this.getTypeName(type);\n const qrLabel = `${typeName} - ${partnerName}`;\n \n this.generateCustomQRCode(qrContent, qrLabel, this.pendingQRInfo.options);\n this.pendingQRInfo = null; // Nettoyer\n } else {\n // Réessayer après un délai si le socket ID n'est pas encore disponible\n setTimeout(waitForSocketId, 100);\n }\n };\n \n waitForSocketId();\n }\n \n this.startAutoRefresh(containerId, type, options);\n return {\n ...response.data,\n qrCodeUrl: qrImageUrl,\n sessionId: response.data.service_id\n };\n } else {\n throw new Error(response.message || 'Erreur lors de la génération du QR code');\n }\n } catch (error) {\n console.error('Erreur API détectée:', error.message);\n console.error('Stack trace complet:', error.stack);\n console.error('Configuration SDK (Custom):', {\n apiUrl: this.config.apiUrl,\n type: type,\n secureInit: this.config.secureInit,\n clientId: this.config.clientId ? '***' + this.config.clientId.slice(-4) : 'null',\n secretId: this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null'\n });\n console.log('Affichage du message \"Service non disponible\" pour type ' + type);\n this.displayServiceUnavailable(containerId, type);\n throw new Error('Service non disponible');\n }\n }\n\n // Alias pour maintenir la compatibilité\n async generateAuthQR(containerId, options = {}) {\n return this.generateQR(containerId, options);\n }\n\n async generateKYCQR(containerId, options = {}) {\n // Sauvegarder le type actuel\n const originalType = this.config.type;\n // Changer temporairement le type pour KYC\n this.config.type = 1;\n try {\n return await this.generateQR(containerId, options);\n } finally {\n // Restaurer le type original\n this.config.type = originalType;\n }\n }\n\n async generateSignatureQR(containerId, options = {}) {\n // Sauvegarder le type actuel\n const originalType = this.config.type;\n // Changer temporairement le type pour Signature\n this.config.type = 3;\n try {\n return await this.generateQR(containerId, options);\n } finally {\n // Restaurer le type original\n this.config.type = originalType;\n }\n }\n\n /**\n * Vérifier le statut d'un QR code\n */\n async checkQRStatus(sessionId) {\n if (!this.isInitialized) {\n throw new Error('SunuID: SDK non initialisé');\n }\n\n try {\n const response = await this.makeRequest('/qr-status', {\n serviceId: sessionId\n });\n\n if (response.success) {\n return response.data;\n } else {\n throw new Error(response.message || 'Erreur lors de la vérification du statut');\n }\n } catch (error) {\n this.handleError(error);\n throw error;\n }\n }\n\n /**\n * Afficher un QR code dans un conteneur\n */\n displayQRCode(containerId, qrUrl, type, options = {}) {\n const container = document.getElementById(containerId);\n if (!container) {\n throw new Error(`Conteneur avec l'ID \"${containerId}\" non trouvé`);\n }\n\n // Nettoyer le conteneur\n container.innerHTML = '';\n\n // Créer l'élément QR code\n const qrElement = document.createElement('div');\n qrElement.className = 'sunuid-qr-code';\n \n // Afficher un loader en attendant la réponse API et la connexion socket\n const typeName = this.getTypeName(type);\n qrElement.innerHTML = `\n <div class=\"sunuid-qr-header\">\n <h3>${type === 1 ? 'Vérification KYC' : type === 2 ? 'Authentification' : type === 3 ? 'Signature' : 'Service Type ' + type}</h3>\n </div>\n <div class=\"sunuid-qr-image\" id=\"sunuid-qr-container\">\n <div style=\"text-align: center; padding: 40px;\">\n <div class=\"sunuid-loader\">\n <div class=\"sunuid-spinner\"></div>\n <p style=\"margin-top: 20px; color: #666;\">Initialisation en cours...</p>\n <p style=\"font-size: 12px; color: #999; margin-top: 10px;\">Connexion API et WebSocket</p>\n <p style=\"font-size: 11px; color: #ccc; margin-top: 5px;\">Attente du Socket ID...</p>\n </div>\n </div>\n </div>\n <div class=\"sunuid-qr-instructions\" style=\"display: none;\">\n <p>Scannez ce QR code avec l'application ${this.config.partnerName} pour vous connecter</p>\n </div>\n <div class=\"sunuid-qr-status\" id=\"sunuid-status\" style=\"display: none;\">\n <p>En attente de scan...</p>\n </div>\n `;\n\n container.appendChild(qrElement);\n\n // Stocker les informations pour la génération ultérieure\n this.pendingQRInfo = {\n containerId,\n type,\n options\n };\n\n // Appliquer le thème\n this.applyTheme(options.theme || this.config.theme);\n }\n\n /**\n * Générer un QR code personnalisé avec PHP Endroid\n */\n async generateCustomQRCode(content, label, options = {}) {\n try {\n console.log('🎨 Début génération QR personnalisé avec PHP...');\n console.log('📄 Contenu:', content);\n console.log('🏷️ Label:', label);\n \n const qrContainer = document.getElementById('sunuid-qr-container');\n if (!qrContainer) {\n console.error('❌ QR container not found');\n this.displayFallbackImage();\n return;\n }\n \n console.log('✅ QR container trouvé');\n\n // Nettoyer le conteneur\n qrContainer.innerHTML = '<div style=\"text-align: center; padding: 20px;\"><p>Génération QR code avec PHP...</p></div>';\n\n // Appeler l'endpoint PHP\n console.log('🔄 Appel endpoint PHP...');\n // Construire l'URL du QR generator de manière plus robuste\n let qrGeneratorUrl;\n if (this.config.apiUrl.includes('api.sunuid.fayma.sn')) {\n qrGeneratorUrl = 'https://sunuid.fayma.sn/qr-generator.php';\n } else {\n qrGeneratorUrl = this.config.apiUrl.replace('/api', '') + '/qr-generator.php';\n }\n console.log('🔗 URL QR Generator:', qrGeneratorUrl);\n const response = await fetch(qrGeneratorUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n body: JSON.stringify({\n content: content,\n label: label,\n size: 300,\n margin: 10\n })\n });\n \n console.log('📥 Réponse PHP reçue - Status:', response.status);\n \n if (!response.ok) {\n throw new Error(`Erreur HTTP: ${response.status}`);\n }\n \n const responseData = await response.json();\n \n if (!responseData.success) {\n throw new Error(`Erreur PHP: ${responseData.error}`);\n }\n \n console.log('✅ QR code généré par PHP avec succès');\n console.log('📊 Taille:', responseData.data.size + 'px');\n console.log('📊 Longueur base64:', responseData.data.length + ' caractères');\n\n // Stocker l'URL du QR code pour getQRCode()\n this.currentQRUrl = responseData.data.dataUrl;\n \n // Créer le conteneur avec le QR code PHP\n qrContainer.innerHTML = `\n <div class=\"sunuid-qr-ready\" style=\"text-align: center; padding: 20px;\">\n <img src=\"${responseData.data.dataUrl}\" alt=\"QR Code ${this.config.partnerName}\" style=\"max-width: 300px; border: 2px solid #ddd; border-radius: 10px;\">\n </div>\n `;\n \n // Afficher les instructions et le statut maintenant que le QR est prêt\n const instructionsElement = qrContainer.parentElement.querySelector('.sunuid-qr-instructions');\n const statusElement = qrContainer.parentElement.querySelector('.sunuid-qr-status');\n \n if (instructionsElement) {\n instructionsElement.style.display = 'block';\n instructionsElement.classList.add('sunuid-qr-ready');\n }\n if (statusElement) {\n statusElement.style.display = 'block';\n statusElement.classList.add('sunuid-qr-ready');\n }\n \n console.log('✅ QR code PHP affiché dans le conteneur');\n\n } catch (error) {\n console.error('❌ Erreur génération QR PHP:', error);\n console.error('Stack trace:', error.stack);\n this.displayFallbackImage();\n }\n }\n\n /**\n * Ajouter le logo au centre du QR code\n */\n addLogoToCenter(ctx, x, y, width, height) {\n try {\n // Créer une image pour le logo\n const logo = new Image();\n logo.onload = () => {\n const logoSize = 40;\n const logoX = x + (width - logoSize) / 2;\n const logoY = y + (width - logoSize) / 2;\n\n // Dessiner un fond blanc pour le logo\n ctx.fillStyle = 'white';\n ctx.fillRect(logoX - 2, logoY - 2, logoSize + 4, logoSize + 4);\n\n // Dessiner le logo\n ctx.drawImage(logo, logoX, logoY, logoSize, logoSize);\n };\n logo.src = 'src/logoqr.png';\n } catch (error) {\n console.warn('Logo non disponible:', error);\n }\n }\n\n /**\n * Afficher l'image de fallback\n */\n displayFallbackImage() {\n console.log('⚠️ Affichage de l\\'image de fallback');\n const qrContainer = document.getElementById('sunuid-qr-container');\n if (qrContainer) {\n qrContainer.innerHTML = `\n <div style=\"text-align: center; padding: 20px; color: #666;\">\n <p>⚠️ Génération QR personnalisé non disponible</p>\n <p>Utilisation de l'image par défaut</p>\n <p><strong>Debug:</strong> QRCode disponible: ${typeof QRCode !== 'undefined'}</p>\n <p><strong>Debug:</strong> Container trouvé: ${qrContainer !== null}</p>\n </div>\n `;\n } else {\n console.error('❌ Container QR non trouvé pour fallback');\n }\n }\n\n /**\n * Afficher \"Service non disponible\"\n */\n displayServiceUnavailable(containerId, type) {\n console.log(`displayServiceUnavailable appelée pour ${containerId}, type: ${type}`);\n const container = document.getElementById(containerId);\n if (!container) {\n console.error(`Container ${containerId} non trouvé`);\n return;\n }\n\n container.innerHTML = `\n <div class=\"sunuid-service-unavailable\" style=\"\n text-align: center;\n padding: 40px 20px;\n background: #f8f9fa;\n border: 2px dashed #dee2e6;\n border-radius: 10px;\n color: #6c757d;\n font-family: Arial, sans-serif;\n \">\n <div style=\"font-size: 48px; margin-bottom: 20px;\">⚠️</div>\n <h3 style=\"margin: 0 0 10px 0; color: #495057;\">Service Non Disponible</h3>\n <p style=\"margin: 0; font-size: 14px;\">\n Le service d'authentification est temporairement indisponible.<br>\n Veuillez réessayer plus tard.\n </p>\n <div style=\"margin-top: 20px; font-size: 12px; color: #adb5bd;\">\n Type: ${String(type).toUpperCase()}\n </div>\n </div>\n `;\n }\n\n /**\n * Rafraîchir un QR code\n */\n async refreshQR(containerId, options = {}) {\n try {\n const result = await this.generateQR(containerId, options);\n return result;\n } catch (error) {\n console.error('Erreur lors du rafraîchissement:', error.message);\n this.displayServiceUnavailable(containerId, this.config.type);\n throw error;\n }\n }\n\n /**\n * Démarrer le rafraîchissement automatique\n */\n startAutoRefresh(containerId, type, options) {\n if (!this.config.autoRefresh) return;\n\n this.refreshTimer = setInterval(async () => {\n try {\n await this.refreshQR(containerId, type, options);\n } catch (error) {\n console.warn('Erreur lors du rafraîchissement automatique:', error);\n }\n }, this.config.refreshInterval);\n }\n\n /**\n * Démarrer le timer de compte à rebours\n */\n\n\n /**\n * Effectuer une requête API sécurisée\n */\n async makeRequest(endpoint, data) {\n // Validation de sécurité\n if (!this.isInitialized) {\n this.logSecurityEvent('REQUEST_BEFORE_INIT', { endpoint });\n throw new Error('SDK non initialisé');\n }\n\n // Vérifier les limites de requêtes pour l'initialisation sécurisée\n if (this.config.secureInit) {\n this.config.requestCount++;\n if (this.config.requestCount > this.config.maxRequests) {\n this.logSecurityEvent('API_REQUEST_LIMIT_EXCEEDED', { \n requestCount: this.config.requestCount,\n maxRequests: this.config.maxRequests \n });\n throw new Error('Limite de requêtes dépassée');\n }\n }\n\n // Sanitisation des données\n const sanitizedData = this.sanitizeRequestData(data);\n \n // Debug: Afficher les données envoyées\n console.log('🔍 Debug makeRequest - endpoint:', endpoint);\n console.log('🔍 Debug makeRequest - apiUrl:', this.config.apiUrl);\n console.log('🔍 Debug makeRequest - url:', `${this.config.apiUrl}${endpoint}`);\n console.log('🔍 Debug makeRequest - data:', JSON.stringify(sanitizedData, null, 2));\n console.log('🔍 Debug makeRequest - secureInit:', this.config.secureInit);\n console.log('🔍 Debug makeRequest - isInitialized:', this.isInitialized);\n \n // Utiliser l'endpoint depuis la configuration si disponible\n const endpointPath = window.SunuIDConfig?.endpoints?.[endpoint.replace('/', '')] || endpoint;\n const url = `${this.config.apiUrl}${endpointPath}`;\n \n // Debug: Afficher l'URL finale\n console.log('🔍 URL finale construite:', url);\n console.log('🔍 EndpointPath:', endpointPath);\n console.log('🔍 SunuIDConfig endpoints:', JSON.stringify(window.SunuIDConfig?.endpoints));\n \n // Log de sécurité pour la requête\n this.logSecurityEvent('API_REQUEST_START', {\n endpoint: endpointPath,\n url: url,\n dataKeys: Object.keys(sanitizedData),\n secureInit: this.config.secureInit\n });\n \n let retryCount = 0;\n const maxRetries = this.config.maxRetries;\n \n while (retryCount <= maxRetries) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.requestTimeout);\n \n // Headers minimaux (API SunuID n'accepte que les headers essentiels)\n const headers = {\n 'Content-Type': 'application/json'\n };\n\n // Note: En mode sécurisé, les credentials sont dans le body\n // Pas besoin d'ajouter de header spécial pour éviter les problèmes CORS\n // if (this.config.secureInit && this.config.token) {\n // headers['X-Secure-Token'] = this.config.token;\n // }\n \n const response = await fetch(url, {\n method: 'POST',\n headers: headers,\n body: JSON.stringify(sanitizedData),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorData;\n try {\n errorData = JSON.parse(errorText);\n } catch (e) {\n errorData = { message: errorText };\n }\n \n this.logSecurityEvent('API_REQUEST_ERROR', {\n status: response.status,\n statusText: response.statusText,\n error: errorData.message\n });\n \n throw new Error(errorData.message || `Erreur HTTP: ${response.status}`);\n }\n\n const result = await response.json();\n \n this.logSecurityEvent('API_REQUEST_SUCCESS', {\n endpoint: endpointPath,\n responseKeys: Object.keys(result)\n });\n \n return result;\n \n } catch (error) {\n retryCount++;\n \n if (error.name === 'AbortError') {\n this.logSecurityEvent('API_REQUEST_TIMEOUT', { retryCount });\n if (retryCount > maxRetries) {\n throw new Error('Timeout de la requête API');\n }\n continue;\n }\n \n if (retryCount > maxRetries) {\n this.logSecurityEvent('API_REQUEST_MAX_RETRIES', { \n retryCount, \n error: error.message \n });\n throw error;\n }\n \n // Attendre avant de réessayer\n await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));\n }\n }\n }\n\n /**\n * Sanitisation des données de requête\n */\n sanitizeRequestData(data) {\n const sanitized = {};\n \n for (const [key, value] of Object.entries(data)) {\n if (typeof value === 'string') {\n sanitized[key] = this.sanitizeInput(value);\n } else if (typeof value === 'object' && value !== null) {\n sanitized[key] = this.sanitizeRequestData(value);\n } else {\n sanitized[key] = value;\n }\n }\n \n // Ajouter les credentials dans le body (API SunuID les attend ici)\n // Utiliser les vraies valeurs (originales) si disponibles, sinon les valeurs directes\n sanitized.client_id = this.config.originalClientId || this.config.clientId;\n sanitized.secret_id = this.config.originalSecretId || this.config.secretId;\n \n // Debug: Vérifier les credentials\n console.log('🔍 Credentials dans sanitizeRequestData - clientId:', this.config.clientId);\n console.log('🔍 Credentials dans sanitizeRequestData - secretId:', this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedClientId:', sanitized.client_id);\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:', sanitized.secret_id ? '***' + sanitized.secret_id.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - data complet:', JSON.stringify(sanitized, null, 2));\n \n // Debug: Vérifier les credentials\n console.log('🔍 Credentials dans sanitizeRequestData - clientId:', this.config.clientId);\n console.log('🔍 Credentials dans sanitizeRequestData - secretId:', this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedClientId:', sanitized.client_id);\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:', sanitized.secret_id ? '***' + sanitized.secret_id.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - data complet:', JSON.stringify(sanitized, null, 2));\n \n return sanitized;\n }\n\n /**\n * Générer un ID de requête unique\n */\n generateRequestId() {\n return 'req_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);\n }\n\n /**\n * Appliquer le thème\n */\n applyTheme(theme) {\n const container = document.querySelector('.sunuid-qr-code');\n if (container) {\n container.className = `sunuid-qr-code sunuid-theme-${theme}`;\n }\n }\n\n /**\n * Gérer les erreurs\n */\n handleError(error) {\n console.error('SunuID SDK Error:', error);\n \n if (this.config.onError) {\n this.config.onError(error);\n }\n }\n\n /**\n * Obtenir l'URL du QR code généré\n */\n getQRCode() {\n // Retourner l'URL du QR code si disponible\n if (this.currentQRUrl) {\n return this.currentQRUrl;\n }\n \n // Sinon, retourner une URL par défaut ou null\n return null;\n }\n\n /**\n * Nettoyer les ressources\n */\n destroy() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n }\n \n // Fermer la connexion WebSocket\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n console.log('🌐 WebSocket déconnecté');\n }\n \n this.isInitialized = false;\n this.logSecurityEvent('SDK_DESTROY');\n console.log('SunuID SDK détruit');\n }\n\n /**\n * Obtenir les logs de sécurité\n */\n getSecurityLogs() {\n return window.SunuIDSecurityLogs || [];\n }\n\n /**\n * Nettoyer les logs de sécurité\n */\n clearSecurityLogs() {\n window.SunuIDSecurityLogs = [];\n this.logSecurityEvent('SECURITY_LOGS_CLEARED');\n }\n }\n\n // Exposer la classe globalement\n window.SunuID = SunuID;\n window.sunuidInstance = null;\n\n // Fonction d'initialisation globale\n window.initSunuID = function(config) {\n try {\n window.sunuidInstance = new SunuID(config);\n return window.sunuidInstance;\n } catch (error) {\n console.error('Erreur lors de l\\'initialisation de SunuID:', error);\n throw error;\n }\n };\n\n})(window); "],"names":["window","_window$SunuIDConfig","_window$SunuIDConfig2","_window$SunuIDConfig3","DEFAULT_CONFIG","apiUrl","SunuIDConfig","clientId","secretId","type","partnerName","theme","language","autoRefresh","refreshInterval","onSuccess","onError","onStatusUpdate","onExpired","enableSecurityLogs","validateInputs","maxRetries","requestTimeout","secureInit","secureInitUrl","includes","replace","token","SunuID","config","arguments","length","undefined","_classCallCheck","this","_objectSpread","qrCode","refreshTimer","isInitialized","socket","initPromise","init","key","value","_init","_asyncToGenerator","_regenerator","m","_callee","_t","w","_context","p","n","validateSecurityParams","logSecurityEvent","obfuscateCredentials","console","log","initWebSocket","v","error","message","a","apply","_secureInit","_callee2","initData","response","result","decodedToken","_t2","_context2","fetch","method","headers","Accept","body","JSON","stringify","ok","Error","concat","status","json","success","data","api_url","decodeSecureToken","client_id","secret_id","expiresIn","expires_in","maxRequests","max_requests","requestCount","parts","split","_parts","_slicedToArray","payload","decodedPayload","atob","tokenData","parse","exp","Date","now","_this","io","warn","setTimeout","ip","getClientIP","query","userId","username","on","id","reason","handleQRStatusUpdate","handleQRScanSuccess","handleQRExpired","errors","push","isValidUrl","join","string","url","URL","protocol","_","event","securityLog","timestamp","toISOString","userAgent","navigator","location","href","SunuIDSecurityLogs","originalClientId","originalSecretId","clientIdDisplay","secretIdDisplay","input","trim","connected","emit","_generateQR","_callee3","containerId","options","qrImageUrl","_waitForSocketId","_t3","_this2","_args3","_context3","makeRequest","qrcode","currentQRUrl","displayQRCode","pendingQRInfo","code","waitForSocketId","socketId","qrContent","typeName","getTypeName","qrLabel","generateCustomQRCode","startAutoRefresh","emitWebSocketEvent","serviceId","service_id","qrCodeUrl","sessionId","stack","slice","displayServiceUnavailable","_x","_generateCustomQR","_callee4","_response","_waitForSocketId2","_t4","_this3","_args4","_context4","_x2","_x3","_generateAuthQR","_callee5","_args5","_context5","generateQR","_x4","_generateKYCQR","_callee6","originalType","_args6","_context6","f","_x5","_generateSignatureQR","_callee7","_args7","_context7","_x6","_checkQRStatus","_callee8","_response2","_t5","_context8","handleError","_x7","qrUrl","container","document","getElementById","innerHTML","qrElement","createElement","className","appendChild","applyTheme","_generateCustomQRCode","_callee9","content","label","qrContainer","qrGeneratorUrl","_response3","responseData","instructionsElement","statusElement","_t6","_context9","displayFallbackImage","size","margin","dataUrl","parentElement","querySelector","style","display","classList","add","_x8","_x9","ctx","x","y","width","height","logo","Image","onload","logoSize","logoX","logoY","fillStyle","fillRect","drawImage","src","QRCode","String","toUpperCase","_refreshQR","_callee0","_t7","_args0","_context0","_x0","_this4","setInterval","_callee1","_t8","_context1","refreshQR","_makeRequest","_callee10","endpoint","_window$SunuIDConfig4","_window$SunuIDConfig5","sanitizedData","endpointPath","retryCount","_loop","_ret","_this5","_context11","sanitizeRequestData","endpoints","dataKeys","Object","keys","controller","timeoutId","_response4","errorText","errorData","_t9","_context10","AbortController","abort","signal","clearTimeout","text","e","statusText","responseKeys","name","Promise","resolve","d","_regeneratorValues","_x1","_x10","sanitized","_i","_Object$entries","entries","_Object$entries$_i","sanitizeInput","_typeof","Math","random","toString","substr","clearInterval","disconnect","sunuidInstance","initSunuID"],"mappings":"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"}
1
+ {"version":3,"file":"sunuid-sdk.min.js","sources":["../src/sunuid-sdk.js"],"sourcesContent":["/**\n * SunuID SDK - Package d'intégration pour partenaires\n * \n * @version 1.0.0\n * @author SunuID Team\n * @license MIT\n */\n\n(function(window) {\n 'use strict';\n\n // Configuration par défaut\n const DEFAULT_CONFIG = {\n apiUrl: window.SunuIDConfig?.apiUrl || 'https://api.sunuid.fayma.sn',\n clientId: null,\n secretId: null,\n type: 2, // Type par défaut (2 = authentification)\n partnerName: 'SunuID', // Nom du partenaire par défaut\n theme: 'light',\n language: 'fr',\n autoRefresh: true,\n refreshInterval: 30000, // 30 secondes\n onSuccess: null,\n onError: null,\n onStatusUpdate: null,\n onExpired: null,\n // Nouvelles options de sécurité\n enableSecurityLogs: true,\n validateInputs: true,\n maxRetries: 3,\n requestTimeout: 10000, // 10 secondes\n // Options d'initialisation sécurisée\n secureInit: false,\n secureInitUrl: (() => {\n if (window.SunuIDConfig?.apiUrl?.includes('api.sunuid.fayma.sn')) {\n return 'https://sunuid.fayma.sn/secure-init.php';\n }\n return window.SunuIDConfig?.apiUrl?.replace('/api', '') + '/secure-init.php' || 'https://sunuid.fayma.sn/secure-init.php';\n })(),\n token: null\n };\n\n /**\n * Classe principale SunuID\n */\n class SunuID {\n constructor(config = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.qrCode = null;\n this.refreshTimer = null;\n this.isInitialized = false;\n this.socket = null;\n \n // Initialisation asynchrone\n this.initPromise = this.init();\n }\n\n /**\n * Initialisation du SDK\n */\n async init() {\n try {\n // Initialisation sécurisée si activée\n if (this.config.secureInit) {\n await this.secureInit();\n } else {\n // Validation sécurisée des paramètres\n if (this.config.validateInputs) {\n this.validateSecurityParams();\n }\n }\n\n // Log de sécurité pour l'initialisation\n this.logSecurityEvent('SDK_INIT_START', {\n apiUrl: this.config.apiUrl,\n type: this.config.type,\n partnerName: this.config.partnerName,\n secureInit: this.config.secureInit\n });\n\n // Obscurcir les credentials dans les logs\n this.obfuscateCredentials();\n\n this.isInitialized = true;\n console.log('SunuID SDK initialisé avec succès');\n \n this.logSecurityEvent('SDK_INIT_SUCCESS');\n \n // Initialiser la connexion WebSocket\n this.initWebSocket();\n \n } catch (error) {\n this.logSecurityEvent('SDK_INIT_ERROR', { error: error.message });\n throw error;\n }\n }\n\n /**\n * Initialisation sécurisée via PHP\n */\n async secureInit() {\n try {\n this.logSecurityEvent('SECURE_INIT_START');\n \n const initData = {\n type: this.config.type,\n partnerName: this.config.partnerName,\n theme: this.config.theme\n };\n\n const response = await fetch(this.config.secureInitUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n body: JSON.stringify(initData)\n });\n\n if (!response.ok) {\n throw new Error(`Erreur HTTP: ${response.status}`);\n }\n\n const result = await response.json();\n \n if (!result.success) {\n throw new Error(result.error || 'Erreur lors de l\\'initialisation sécurisée');\n }\n\n // Stocker le token et les données sécurisées\n this.config.token = result.data.token;\n this.config.apiUrl = result.data.api_url;\n \n // Décoder le token pour récupérer les credentials\n const decodedToken = this.decodeSecureToken(result.data.token);\n if (decodedToken) {\n this.config.clientId = decodedToken.client_id;\n this.config.secretId = decodedToken.secret_id;\n } else {\n throw new Error('Impossible de décoder le token sécurisé');\n }\n \n this.config.expiresIn = result.data.expires_in;\n this.config.maxRequests = result.data.max_requests;\n this.config.requestCount = 0;\n\n this.logSecurityEvent('SECURE_INIT_SUCCESS', {\n expiresIn: result.data.expires_in,\n maxRequests: result.data.max_requests\n });\n\n console.log('✅ Initialisation sécurisée réussie');\n \n } catch (error) {\n this.logSecurityEvent('SECURE_INIT_ERROR', { error: error.message });\n throw new Error(`Échec de l'initialisation sécurisée: ${error.message}`);\n }\n }\n\n /**\n * Décoder le token sécurisé\n */\n decodeSecureToken(token) {\n try {\n const parts = token.split('.');\n if (parts.length !== 2) {\n console.error('❌ Format de token invalide');\n return null;\n }\n \n const [payload, signature] = parts;\n \n // Décoder le payload (base64)\n const decodedPayload = atob(payload);\n const tokenData = JSON.parse(decodedPayload);\n \n // Vérifier l'expiration\n if (tokenData.exp && tokenData.exp < Date.now() / 1000) {\n console.error('❌ Token expiré');\n return null;\n }\n \n console.log('✅ Token décodé avec succès');\n return tokenData;\n \n } catch (error) {\n console.error('❌ Erreur décodage token:', error);\n return null;\n }\n }\n\n /**\n * Initialiser la connexion WebSocket\n */\n initWebSocket() {\n try {\n // Vérifier si Socket.IO est disponible\n if (typeof io === 'undefined') {\n console.warn('⚠️ Socket.IO non disponible, WebSocket sera initialisé plus tard');\n // Réessayer après un délai\n setTimeout(() => this.initWebSocket(), 1000);\n return;\n }\n \n // Obtenir l'IP du client (simulation)\n const ip = this.getClientIP();\n \n // Initialiser la connexion WebSocket si elle n'existe pas\n if (!this.socket) {\n this.socket = io('wss://samasocket.fayma.sn:9443', {\n query: {\n token: this.config.clientId,\n type: 'web',\n userId: this.config.clientId,\n username: ip\n }\n });\n\n // Gestion des événements WebSocket\n this.socket.on('connect', () => {\n console.log('🌐 WebSocket connecté avec succès');\n console.log('📊 Socket ID:', this.socket.id);\n });\n\n this.socket.on('disconnect', (reason) => {\n console.log('❌ WebSocket déconnecté:', reason);\n });\n\n this.socket.on('connect_error', (error) => {\n console.error('❌ Erreur connexion WebSocket:', error);\n });\n\n // Écouter les événements spécifiques\n this.socket.on('qr_status_update', (data) => {\n console.log('📱 Mise à jour statut QR reçue:', data);\n this.handleQRStatusUpdate(data);\n });\n\n this.socket.on('qr_scan_success', (data) => {\n console.log('✅ Scan QR réussi reçu:', data);\n this.handleQRScanSuccess(data);\n });\n\n this.socket.on('qr_expired', (data) => {\n console.log('⏰ QR expiré reçu:', data);\n this.handleQRExpired(data);\n });\n }\n } catch (error) {\n console.error('❌ Erreur initialisation WebSocket:', error);\n }\n }\n\n /**\n * Obtenir l'IP du client (simulation)\n */\n getClientIP() {\n // Simulation - en production, vous pourriez utiliser un service d'IP\n return '127.0.0.1';\n }\n\n /**\n * Obtenir le nom du type à partir du numéro\n */\n getTypeName(type) {\n switch(type) {\n case 1: return 'KYC';\n case 2: return 'AUTH';\n case 3: return 'SIGNATURE';\n default: return `TYPE-${type}`;\n }\n }\n\n /**\n * Validation sécurisée des paramètres\n */\n validateSecurityParams() {\n const errors = [];\n \n // Validation du clientId\n if (!this.config.clientId || typeof this.config.clientId !== 'string') {\n errors.push('clientId invalide ou manquant');\n } else if (this.config.clientId.length < 10) {\n errors.push('clientId trop court');\n }\n \n // Validation du secretId\n if (!this.config.secretId || typeof this.config.secretId !== 'string') {\n errors.push('secretId invalide ou manquant');\n } else if (this.config.secretId.length < 32) {\n errors.push('secretId trop court (minimum 32 caractères)');\n }\n \n // Validation de l'URL API\n if (!this.config.apiUrl || !this.isValidUrl(this.config.apiUrl)) {\n errors.push('apiUrl invalide');\n }\n \n // Validation du type\n if (![1, 2, 3].includes(this.config.type)) {\n errors.push('type invalide (doit être 1, 2 ou 3)');\n }\n \n if (errors.length > 0) {\n this.logSecurityEvent('VALIDATION_ERROR', { errors });\n throw new Error(`Paramètres de sécurité invalides: ${errors.join(', ')}`);\n }\n \n this.logSecurityEvent('VALIDATION_SUCCESS');\n }\n\n /**\n * Validation d'URL sécurisée\n */\n isValidUrl(string) {\n try {\n const url = new URL(string);\n return url.protocol === 'https:' || url.protocol === 'http:';\n } catch (_) {\n return false;\n }\n }\n\n /**\n * Logs de sécurité\n */\n logSecurityEvent(event, data = {}) {\n if (!this.config.enableSecurityLogs) return;\n \n const securityLog = {\n timestamp: new Date().toISOString(),\n event: event,\n data: data,\n userAgent: navigator.userAgent,\n url: window.location.href\n };\n \n console.warn('🔒 [SECURITY]', securityLog);\n \n // Stocker les logs de sécurité (optionnel)\n if (!window.SunuIDSecurityLogs) {\n window.SunuIDSecurityLogs = [];\n }\n window.SunuIDSecurityLogs.push(securityLog);\n }\n\n /**\n * Chiffrement simple des credentials (pour éviter l'exposition en clair)\n */\n obfuscateCredentials() {\n // Stocker les vraies valeurs pour les logs de sécurité\n this.config.originalClientId = this.config.clientId;\n this.config.originalSecretId = this.config.secretId;\n \n // Créer des versions obfusquées pour l'affichage uniquement\n if (this.config.clientId) {\n this.config.clientIdDisplay = this.config.clientId.replace(/(.{3}).*(.{3})/, '$1***$2');\n }\n if (this.config.secretId) {\n this.config.secretIdDisplay = this.config.secretId.replace(/(.{4}).*(.{4})/, '$1***$2');\n }\n }\n\n /**\n * Validation des entrées utilisateur\n */\n sanitizeInput(input) {\n if (typeof input !== 'string') return input;\n \n // Protection contre les injections XSS basiques\n return input\n .replace(/[<>]/g, '') // Supprimer les balises HTML\n .replace(/javascript:/gi, '') // Supprimer les protocoles dangereux\n .trim();\n }\n\n /**\n * Gérer la mise à jour du statut QR\n */\n handleQRStatusUpdate(data) {\n if (this.config.onStatusUpdate) {\n this.config.onStatusUpdate(data);\n }\n }\n\n /**\n * Gérer le succès du scan QR\n */\n handleQRScanSuccess(data) {\n if (this.config.onSuccess) {\n this.config.onSuccess(data);\n }\n }\n\n /**\n * Gérer l'expiration du QR\n */\n handleQRExpired(data) {\n if (this.config.onExpired) {\n this.config.onExpired(data);\n }\n }\n\n /**\n * Émettre un événement WebSocket\n */\n emitWebSocketEvent(event, data) {\n if (this.socket && this.socket.connected) {\n this.socket.emit(event, data);\n console.log(`📤 Événement WebSocket émis: ${event}`, data);\n } else if (typeof io === 'undefined') {\n console.warn('⚠️ Socket.IO non disponible, impossible d\\'émettre l\\'événement:', event);\n } else {\n console.warn('⚠️ WebSocket non connecté, impossible d\\'émettre l\\'événement:', event);\n }\n }\n\n /**\n * Obtenir le statut de la connexion WebSocket\n */\n getWebSocketStatus() {\n if (!this.socket) {\n return 'not_initialized';\n }\n return this.socket.connected ? 'connected' : 'disconnected';\n }\n\n /**\n * Forcer l'initialisation WebSocket (si Socket.IO devient disponible plus tard)\n */\n forceWebSocketInit() {\n if (typeof io !== 'undefined' && !this.socket) {\n console.log('🔄 Forçage de l\\'initialisation WebSocket...');\n this.initWebSocket();\n }\n }\n\n /**\n * Générer un QR code avec le type configuré\n */\n async generateQR(containerId, options = {}) {\n // Attendre l'initialisation si nécessaire\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n \n if (!this.isInitialized) {\n throw new Error('SunuID: SDK non initialisé');\n }\n\n try {\n const response = await this.makeRequest('/qr-generate', {\n type: this.config.type, // Utilise le type configuré\n ...options\n });\n\n if (response.success) {\n // Construire l'URL complète de l'image QR avec la base URL pour les images\n const imageBaseUrl = 'https://sunuid.fayma.sn';\n const qrImageUrl = `${imageBaseUrl}${response.data.qrcode}`;\n this.currentQRUrl = qrImageUrl; // Stocker l'URL pour getQRCode()\n this.displayQRCode(containerId, qrImageUrl, this.config.type, options);\n \n // Générer le QR code personnalisé avec le type + code de l'API + socket ID\n if (this.pendingQRInfo && response.data.code) {\n // Attendre que le socket ID soit bien défini\n const waitForSocketId = () => {\n if (this.socket && this.socket.id && this.socket.id !== 'unknown') {\n const socketId = this.socket.id;\n const qrContent = `${this.config.type}-${response.data.code}-${socketId}`;\n \n // Utiliser le partnerName de la réponse API et le nom du type\n const partnerName = response.data.partnerName || this.config.partnerName || 'SunuID';\n const typeName = this.getTypeName(this.config.type);\n const qrLabel = `${typeName} - ${partnerName}`;\n \n this.generateCustomQRCode(qrContent, qrLabel, this.pendingQRInfo.options);\n this.pendingQRInfo = null; // Nettoyer\n } else {\n // Réessayer après un délai si le socket ID n'est pas encore disponible\n setTimeout(waitForSocketId, 100);\n }\n };\n \n waitForSocketId();\n }\n \n this.startAutoRefresh(containerId, this.config.type, options);\n \n // Émettre un événement WebSocket pour la génération du QR\n this.emitWebSocketEvent('qr_generated', {\n serviceId: response.data.service_id,\n type: this.config.type,\n qrCodeUrl: qrImageUrl,\n code: response.data.code,\n timestamp: Date.now()\n });\n \n return {\n ...response.data,\n qrCodeUrl: qrImageUrl,\n sessionId: response.data.service_id\n };\n } else {\n throw new Error(response.message || 'Erreur lors de la génération du QR code');\n }\n } catch (error) {\n console.error('Erreur API détectée:', error.message);\n console.error('Stack trace complet:', error.stack);\n console.error('Configuration SDK:', {\n apiUrl: this.config.apiUrl,\n type: this.config.type,\n secureInit: this.config.secureInit,\n clientId: this.config.clientId ? '***' + this.config.clientId.slice(-4) : 'null',\n secretId: this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null'\n });\n console.log('Affichage du message \"Service non disponible\" pour type ' + this.config.type);\n this.displayServiceUnavailable(containerId, this.config.type);\n throw new Error('Service non disponible');\n }\n }\n\n\n\n /**\n * Générer un QR code avec un type personnalisé\n */\n async generateCustomQR(containerId, type, options = {}) {\n // Attendre l'initialisation si nécessaire\n if (this.initPromise) {\n await this.initPromise;\n this.initPromise = null;\n }\n \n if (!this.isInitialized) {\n throw new Error('SunuID: SDK non initialisé');\n }\n\n try {\n const response = await this.makeRequest('/qr-generate', {\n type: type, // Type personnalisé (1, 2, 3, etc.)\n ...options\n });\n\n if (response.success) {\n // Construire l'URL complète de l'image QR avec la base URL pour les images\n const imageBaseUrl = 'https://sunuid.fayma.sn';\n const qrImageUrl = `${imageBaseUrl}${response.data.qrcode}`;\n this.displayQRCode(containerId, qrImageUrl, type, options);\n \n // Générer le QR code personnalisé avec le type + code de l'API + socket ID\n if (this.pendingQRInfo && response.data.code) {\n // Attendre que le socket ID soit bien défini\n const waitForSocketId = () => {\n if (this.socket && this.socket.id && this.socket.id !== 'unknown') {\n const socketId = this.socket.id;\n const qrContent = `${type}-${response.data.code}-${socketId}`;\n \n // Utiliser le partnerName de la réponse API et le nom du type\n const partnerName = response.data.partnerName || this.config.partnerName || 'SunuID';\n const typeName = this.getTypeName(type);\n const qrLabel = `${typeName} - ${partnerName}`;\n \n this.generateCustomQRCode(qrContent, qrLabel, this.pendingQRInfo.options);\n this.pendingQRInfo = null; // Nettoyer\n } else {\n // Réessayer après un délai si le socket ID n'est pas encore disponible\n setTimeout(waitForSocketId, 100);\n }\n };\n \n waitForSocketId();\n }\n \n this.startAutoRefresh(containerId, type, options);\n return {\n ...response.data,\n qrCodeUrl: qrImageUrl,\n sessionId: response.data.service_id\n };\n } else {\n throw new Error(response.message || 'Erreur lors de la génération du QR code');\n }\n } catch (error) {\n console.error('Erreur API détectée:', error.message);\n console.error('Stack trace complet:', error.stack);\n console.error('Configuration SDK (Custom):', {\n apiUrl: this.config.apiUrl,\n type: type,\n secureInit: this.config.secureInit,\n clientId: this.config.clientId ? '***' + this.config.clientId.slice(-4) : 'null',\n secretId: this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null'\n });\n console.log('Affichage du message \"Service non disponible\" pour type ' + type);\n this.displayServiceUnavailable(containerId, type);\n throw new Error('Service non disponible');\n }\n }\n\n // Alias pour maintenir la compatibilité\n async generateAuthQR(containerId, options = {}) {\n return this.generateQR(containerId, options);\n }\n\n async generateKYCQR(containerId, options = {}) {\n // Sauvegarder le type actuel\n const originalType = this.config.type;\n // Changer temporairement le type pour KYC\n this.config.type = 1;\n try {\n return await this.generateQR(containerId, options);\n } finally {\n // Restaurer le type original\n this.config.type = originalType;\n }\n }\n\n async generateSignatureQR(containerId, options = {}) {\n // Sauvegarder le type actuel\n const originalType = this.config.type;\n // Changer temporairement le type pour Signature\n this.config.type = 3;\n try {\n return await this.generateQR(containerId, options);\n } finally {\n // Restaurer le type original\n this.config.type = originalType;\n }\n }\n\n /**\n * Vérifier le statut d'un QR code\n */\n async checkQRStatus(sessionId) {\n if (!this.isInitialized) {\n throw new Error('SunuID: SDK non initialisé');\n }\n\n try {\n const response = await this.makeRequest('/qr-status', {\n serviceId: sessionId\n });\n\n if (response.success) {\n return response.data;\n } else {\n throw new Error(response.message || 'Erreur lors de la vérification du statut');\n }\n } catch (error) {\n this.handleError(error);\n throw error;\n }\n }\n\n /**\n * Afficher un QR code dans un conteneur\n */\n displayQRCode(containerId, qrUrl, type, options = {}) {\n const container = document.getElementById(containerId);\n if (!container) {\n throw new Error(`Conteneur avec l'ID \"${containerId}\" non trouvé`);\n }\n\n // Nettoyer le conteneur\n container.innerHTML = '';\n\n // Créer l'élément QR code\n const qrElement = document.createElement('div');\n qrElement.className = 'sunuid-qr-code';\n \n // Afficher un loader en attendant la réponse API et la connexion socket\n const typeName = this.getTypeName(type);\n qrElement.innerHTML = `\n <div class=\"sunuid-qr-header\">\n <h3>${type === 1 ? 'Vérification KYC' : type === 2 ? 'Authentification' : type === 3 ? 'Signature' : 'Service Type ' + type}</h3>\n </div>\n <div class=\"sunuid-qr-image\" id=\"sunuid-qr-container\">\n <div style=\"text-align: center; padding: 40px;\">\n <div class=\"sunuid-loader\">\n <div class=\"sunuid-spinner\"></div>\n <p style=\"margin-top: 20px; color: #666;\">Initialisation en cours...</p>\n <p style=\"font-size: 12px; color: #999; margin-top: 10px;\">Connexion API et WebSocket</p>\n <p style=\"font-size: 11px; color: #ccc; margin-top: 5px;\">Attente du Socket ID...</p>\n </div>\n </div>\n </div>\n <div class=\"sunuid-qr-instructions\" style=\"display: none;\">\n <p>Scannez ce QR code avec l'application ${this.config.partnerName} pour vous connecter</p>\n </div>\n <div class=\"sunuid-qr-status\" id=\"sunuid-status\" style=\"display: none;\">\n <p>En attente de scan...</p>\n </div>\n `;\n\n container.appendChild(qrElement);\n\n // Stocker les informations pour la génération ultérieure\n this.pendingQRInfo = {\n containerId,\n type,\n options\n };\n\n // Appliquer le thème\n this.applyTheme(options.theme || this.config.theme);\n }\n\n /**\n * Générer un QR code personnalisé avec PHP Endroid\n */\n async generateCustomQRCode(content, label, options = {}) {\n try {\n console.log('🎨 Début génération QR personnalisé avec PHP...');\n console.log('📄 Contenu:', content);\n console.log('🏷️ Label:', label);\n \n const qrContainer = document.getElementById('sunuid-qr-container');\n if (!qrContainer) {\n console.error('❌ QR container not found');\n this.displayFallbackImage();\n return;\n }\n \n console.log('✅ QR container trouvé');\n\n // Nettoyer le conteneur\n qrContainer.innerHTML = '<div style=\"text-align: center; padding: 20px;\"><p>Génération QR code avec PHP...</p></div>';\n\n // Appeler l'endpoint PHP\n console.log('🔄 Appel endpoint PHP...');\n // Construire l'URL du QR generator de manière plus robuste\n let qrGeneratorUrl;\n if (this.config.apiUrl.includes('api.sunuid.fayma.sn')) {\n qrGeneratorUrl = 'https://sunuid.fayma.sn/qr-generator.php';\n } else {\n qrGeneratorUrl = this.config.apiUrl.replace('/api', '') + '/qr-generator.php';\n }\n console.log('🔗 URL QR Generator:', qrGeneratorUrl);\n const response = await fetch(qrGeneratorUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n body: JSON.stringify({\n content: content,\n label: label,\n size: 300,\n margin: 10\n })\n });\n \n console.log('📥 Réponse PHP reçue - Status:', response.status);\n \n if (!response.ok) {\n throw new Error(`Erreur HTTP: ${response.status}`);\n }\n \n const responseData = await response.json();\n \n if (!responseData.success) {\n throw new Error(`Erreur PHP: ${responseData.error}`);\n }\n \n console.log('✅ QR code généré par PHP avec succès');\n console.log('📊 Taille:', responseData.data.size + 'px');\n console.log('📊 Longueur base64:', responseData.data.length + ' caractères');\n\n // Stocker l'URL du QR code pour getQRCode()\n this.currentQRUrl = responseData.data.dataUrl;\n \n // Créer le conteneur avec le QR code PHP\n qrContainer.innerHTML = `\n <div class=\"sunuid-qr-ready\" style=\"text-align: center; padding: 20px;\">\n <img src=\"${responseData.data.dataUrl}\" alt=\"QR Code ${this.config.partnerName}\" style=\"max-width: 300px; border: 2px solid #ddd; border-radius: 10px;\">\n </div>\n `;\n \n // Afficher les instructions et le statut maintenant que le QR est prêt\n const instructionsElement = qrContainer.parentElement.querySelector('.sunuid-qr-instructions');\n const statusElement = qrContainer.parentElement.querySelector('.sunuid-qr-status');\n \n if (instructionsElement) {\n instructionsElement.style.display = 'block';\n instructionsElement.classList.add('sunuid-qr-ready');\n }\n if (statusElement) {\n statusElement.style.display = 'block';\n statusElement.classList.add('sunuid-qr-ready');\n }\n \n console.log('✅ QR code PHP affiché dans le conteneur');\n\n } catch (error) {\n console.error('❌ Erreur génération QR PHP:', error);\n console.error('Stack trace:', error.stack);\n \n // Détecter les erreurs CORS spécifiquement\n if (error.message.includes('Failed to fetch') || error.message.includes('CORS')) {\n console.warn('🚫 Erreur CORS détectée, tentative de génération QR côté client...');\n this.generateQRCodeClientSide(content, label, qrContainer);\n } else {\n this.displayFallbackImage();\n }\n }\n }\n\n /**\n * Générer un QR code côté client en cas d'erreur CORS\n */\n generateQRCodeClientSide(content, label, qrContainer) {\n try {\n console.log('🎨 Génération QR côté client...');\n \n // Vérifier si QRCode est disponible\n if (typeof QRCode === 'undefined') {\n console.error('❌ QRCode library non disponible');\n this.displayFallbackImage();\n return;\n }\n \n // Créer un canvas pour le QR code\n const canvas = document.createElement('canvas');\n canvas.width = 300;\n canvas.height = 300;\n const ctx = canvas.getContext('2d');\n \n // Générer le QR code avec QRCode library\n QRCode.toCanvas(canvas, content, {\n width: 280,\n margin: 10,\n color: {\n dark: '#000000',\n light: '#FFFFFF'\n }\n }, (error) => {\n if (error) {\n console.error('❌ Erreur génération QR côté client:', error);\n this.displayFallbackImage();\n return;\n }\n \n // Ajouter le label en bas du QR code\n ctx.fillStyle = '#333333';\n ctx.font = '14px Arial';\n ctx.textAlign = 'center';\n ctx.fillText(label, 150, 295);\n \n // Convertir en data URL\n const dataUrl = canvas.toDataURL('image/png');\n \n // Stocker l'URL du QR code pour getQRCode()\n this.currentQRUrl = dataUrl;\n \n // Afficher le QR code\n qrContainer.innerHTML = `\n <div class=\"sunuid-qr-ready\" style=\"text-align: center; padding: 20px;\">\n <img src=\"${dataUrl}\" alt=\"QR Code ${this.config.partnerName}\" style=\"max-width: 300px; border: 2px solid #ddd; border-radius: 10px;\">\n <p style=\"margin-top: 10px; font-size: 12px; color: #666;\">Généré côté client (CORS)</p>\n </div>\n `;\n \n // Afficher les instructions et le statut\n const instructionsElement = qrContainer.parentElement.querySelector('.sunuid-qr-instructions');\n const statusElement = qrContainer.parentElement.querySelector('.sunuid-qr-status');\n \n if (instructionsElement) {\n instructionsElement.style.display = 'block';\n instructionsElement.classList.add('sunuid-qr-ready');\n }\n if (statusElement) {\n statusElement.style.display = 'block';\n statusElement.classList.add('sunuid-qr-ready');\n }\n \n console.log('✅ QR code côté client généré avec succès');\n });\n \n } catch (error) {\n console.error('❌ Erreur génération QR côté client:', error);\n this.displayFallbackImage();\n }\n }\n\n /**\n * Ajouter le logo au centre du QR code\n */\n addLogoToCenter(ctx, x, y, width, height) {\n try {\n // Créer une image pour le logo\n const logo = new Image();\n logo.onload = () => {\n const logoSize = 40;\n const logoX = x + (width - logoSize) / 2;\n const logoY = y + (width - logoSize) / 2;\n\n // Dessiner un fond blanc pour le logo\n ctx.fillStyle = 'white';\n ctx.fillRect(logoX - 2, logoY - 2, logoSize + 4, logoSize + 4);\n\n // Dessiner le logo\n ctx.drawImage(logo, logoX, logoY, logoSize, logoSize);\n };\n logo.src = 'src/logoqr.png';\n } catch (error) {\n console.warn('Logo non disponible:', error);\n }\n }\n\n /**\n * Afficher l'image de fallback\n */\n displayFallbackImage() {\n console.log('⚠️ Affichage de l\\'image de fallback');\n const qrContainer = document.getElementById('sunuid-qr-container');\n if (qrContainer) {\n qrContainer.innerHTML = `\n <div style=\"text-align: center; padding: 20px; color: #666;\">\n <p>⚠️ Génération QR personnalisé non disponible</p>\n <p>Utilisation de l'image par défaut</p>\n <p><strong>Debug:</strong> QRCode disponible: ${typeof QRCode !== 'undefined'}</p>\n <p><strong>Debug:</strong> Container trouvé: ${qrContainer !== null}</p>\n </div>\n `;\n } else {\n console.error('❌ Container QR non trouvé pour fallback');\n }\n }\n\n /**\n * Afficher \"Service non disponible\"\n */\n displayServiceUnavailable(containerId, type) {\n console.log(`displayServiceUnavailable appelée pour ${containerId}, type: ${type}`);\n const container = document.getElementById(containerId);\n if (!container) {\n console.error(`Container ${containerId} non trouvé`);\n return;\n }\n\n container.innerHTML = `\n <div class=\"sunuid-service-unavailable\" style=\"\n text-align: center;\n padding: 40px 20px;\n background: #f8f9fa;\n border: 2px dashed #dee2e6;\n border-radius: 10px;\n color: #6c757d;\n font-family: Arial, sans-serif;\n \">\n <div style=\"font-size: 48px; margin-bottom: 20px;\">⚠️</div>\n <h3 style=\"margin: 0 0 10px 0; color: #495057;\">Service Non Disponible</h3>\n <p style=\"margin: 0; font-size: 14px;\">\n Le service d'authentification est temporairement indisponible.<br>\n Veuillez réessayer plus tard.\n </p>\n <div style=\"margin-top: 20px; font-size: 12px; color: #adb5bd;\">\n Type: ${String(type).toUpperCase()}\n </div>\n </div>\n `;\n }\n\n /**\n * Rafraîchir un QR code\n */\n async refreshQR(containerId, options = {}) {\n try {\n const result = await this.generateQR(containerId, options);\n return result;\n } catch (error) {\n console.error('Erreur lors du rafraîchissement:', error.message);\n this.displayServiceUnavailable(containerId, this.config.type);\n throw error;\n }\n }\n\n /**\n * Démarrer le rafraîchissement automatique\n */\n startAutoRefresh(containerId, type, options) {\n if (!this.config.autoRefresh) return;\n\n this.refreshTimer = setInterval(async () => {\n try {\n await this.refreshQR(containerId, type, options);\n } catch (error) {\n console.warn('Erreur lors du rafraîchissement automatique:', error);\n }\n }, this.config.refreshInterval);\n }\n\n /**\n * Démarrer le timer de compte à rebours\n */\n\n\n /**\n * Effectuer une requête API sécurisée\n */\n async makeRequest(endpoint, data) {\n // Validation de sécurité\n if (!this.isInitialized) {\n this.logSecurityEvent('REQUEST_BEFORE_INIT', { endpoint });\n throw new Error('SDK non initialisé');\n }\n\n // Vérifier les limites de requêtes pour l'initialisation sécurisée\n if (this.config.secureInit) {\n this.config.requestCount++;\n if (this.config.requestCount > this.config.maxRequests) {\n this.logSecurityEvent('API_REQUEST_LIMIT_EXCEEDED', { \n requestCount: this.config.requestCount,\n maxRequests: this.config.maxRequests \n });\n throw new Error('Limite de requêtes dépassée');\n }\n }\n\n // Sanitisation des données\n const sanitizedData = this.sanitizeRequestData(data);\n \n // Debug: Afficher les données envoyées\n console.log('🔍 Debug makeRequest - endpoint:', endpoint);\n console.log('🔍 Debug makeRequest - apiUrl:', this.config.apiUrl);\n console.log('🔍 Debug makeRequest - url:', `${this.config.apiUrl}${endpoint}`);\n console.log('🔍 Debug makeRequest - data:', JSON.stringify(sanitizedData, null, 2));\n console.log('🔍 Debug makeRequest - secureInit:', this.config.secureInit);\n console.log('🔍 Debug makeRequest - isInitialized:', this.isInitialized);\n \n // Utiliser l'endpoint depuis la configuration si disponible\n const endpointPath = window.SunuIDConfig?.endpoints?.[endpoint.replace('/', '')] || endpoint;\n const url = `${this.config.apiUrl}${endpointPath}`;\n \n // Debug: Afficher l'URL finale\n console.log('🔍 URL finale construite:', url);\n console.log('🔍 EndpointPath:', endpointPath);\n console.log('🔍 SunuIDConfig endpoints:', JSON.stringify(window.SunuIDConfig?.endpoints));\n \n // Log de sécurité pour la requête\n this.logSecurityEvent('API_REQUEST_START', {\n endpoint: endpointPath,\n url: url,\n dataKeys: Object.keys(sanitizedData),\n secureInit: this.config.secureInit\n });\n \n let retryCount = 0;\n const maxRetries = this.config.maxRetries;\n \n while (retryCount <= maxRetries) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.requestTimeout);\n \n // Headers minimaux (API SunuID n'accepte que les headers essentiels)\n const headers = {\n 'Content-Type': 'application/json'\n };\n\n // Note: En mode sécurisé, les credentials sont dans le body\n // Pas besoin d'ajouter de header spécial pour éviter les problèmes CORS\n // if (this.config.secureInit && this.config.token) {\n // headers['X-Secure-Token'] = this.config.token;\n // }\n \n const response = await fetch(url, {\n method: 'POST',\n headers: headers,\n body: JSON.stringify(sanitizedData),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorData;\n try {\n errorData = JSON.parse(errorText);\n } catch (e) {\n errorData = { message: errorText };\n }\n \n this.logSecurityEvent('API_REQUEST_ERROR', {\n status: response.status,\n statusText: response.statusText,\n error: errorData.message\n });\n \n throw new Error(errorData.message || `Erreur HTTP: ${response.status}`);\n }\n\n const result = await response.json();\n \n this.logSecurityEvent('API_REQUEST_SUCCESS', {\n endpoint: endpointPath,\n responseKeys: Object.keys(result)\n });\n \n return result;\n \n } catch (error) {\n retryCount++;\n \n if (error.name === 'AbortError') {\n this.logSecurityEvent('API_REQUEST_TIMEOUT', { retryCount });\n if (retryCount > maxRetries) {\n throw new Error('Timeout de la requête API');\n }\n continue;\n }\n \n if (retryCount > maxRetries) {\n this.logSecurityEvent('API_REQUEST_MAX_RETRIES', { \n retryCount, \n error: error.message \n });\n throw error;\n }\n \n // Attendre avant de réessayer\n await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));\n }\n }\n }\n\n /**\n * Sanitisation des données de requête\n */\n sanitizeRequestData(data) {\n const sanitized = {};\n \n for (const [key, value] of Object.entries(data)) {\n if (typeof value === 'string') {\n sanitized[key] = this.sanitizeInput(value);\n } else if (typeof value === 'object' && value !== null) {\n sanitized[key] = this.sanitizeRequestData(value);\n } else {\n sanitized[key] = value;\n }\n }\n \n // Ajouter les credentials dans le body (API SunuID les attend ici)\n // Utiliser les vraies valeurs (originales) si disponibles, sinon les valeurs directes\n sanitized.client_id = this.config.originalClientId || this.config.clientId;\n sanitized.secret_id = this.config.originalSecretId || this.config.secretId;\n \n // Debug: Vérifier les credentials\n console.log('🔍 Credentials dans sanitizeRequestData - clientId:', this.config.clientId);\n console.log('🔍 Credentials dans sanitizeRequestData - secretId:', this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedClientId:', sanitized.client_id);\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:', sanitized.secret_id ? '***' + sanitized.secret_id.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - data complet:', JSON.stringify(sanitized, null, 2));\n \n // Debug: Vérifier les credentials\n console.log('🔍 Credentials dans sanitizeRequestData - clientId:', this.config.clientId);\n console.log('🔍 Credentials dans sanitizeRequestData - secretId:', this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedClientId:', sanitized.client_id);\n console.log('🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:', sanitized.secret_id ? '***' + sanitized.secret_id.slice(-4) : 'null');\n console.log('🔍 Credentials dans sanitizeRequestData - data complet:', JSON.stringify(sanitized, null, 2));\n \n return sanitized;\n }\n\n /**\n * Générer un ID de requête unique\n */\n generateRequestId() {\n return 'req_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);\n }\n\n /**\n * Appliquer le thème\n */\n applyTheme(theme) {\n const container = document.querySelector('.sunuid-qr-code');\n if (container) {\n container.className = `sunuid-qr-code sunuid-theme-${theme}`;\n }\n }\n\n /**\n * Gérer les erreurs\n */\n handleError(error) {\n console.error('SunuID SDK Error:', error);\n \n if (this.config.onError) {\n this.config.onError(error);\n }\n }\n\n /**\n * Obtenir l'URL du QR code généré\n */\n getQRCode() {\n // Retourner l'URL du QR code si disponible\n if (this.currentQRUrl) {\n return this.currentQRUrl;\n }\n \n // Sinon, retourner une URL par défaut ou null\n return null;\n }\n\n /**\n * Nettoyer les ressources\n */\n destroy() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n }\n \n // Fermer la connexion WebSocket\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n console.log('🌐 WebSocket déconnecté');\n }\n \n this.isInitialized = false;\n this.logSecurityEvent('SDK_DESTROY');\n console.log('SunuID SDK détruit');\n }\n\n /**\n * Obtenir les logs de sécurité\n */\n getSecurityLogs() {\n return window.SunuIDSecurityLogs || [];\n }\n\n /**\n * Nettoyer les logs de sécurité\n */\n clearSecurityLogs() {\n window.SunuIDSecurityLogs = [];\n this.logSecurityEvent('SECURITY_LOGS_CLEARED');\n }\n }\n\n // Exposer la classe globalement\n window.SunuID = SunuID;\n window.sunuidInstance = null;\n\n // Fonction d'initialisation globale\n window.initSunuID = function(config) {\n try {\n window.sunuidInstance = new SunuID(config);\n return window.sunuidInstance;\n } catch (error) {\n console.error('Erreur lors de l\\'initialisation de SunuID:', error);\n throw error;\n }\n };\n\n})(window); "],"names":["window","_window$SunuIDConfig","_window$SunuIDConfig2","_window$SunuIDConfig3","DEFAULT_CONFIG","apiUrl","SunuIDConfig","clientId","secretId","type","partnerName","theme","language","autoRefresh","refreshInterval","onSuccess","onError","onStatusUpdate","onExpired","enableSecurityLogs","validateInputs","maxRetries","requestTimeout","secureInit","secureInitUrl","includes","replace","token","SunuID","config","arguments","length","undefined","_classCallCheck","this","_objectSpread","qrCode","refreshTimer","isInitialized","socket","initPromise","init","key","value","_init","_asyncToGenerator","_regenerator","m","_callee","_t","w","_context","p","n","validateSecurityParams","logSecurityEvent","obfuscateCredentials","console","log","initWebSocket","v","error","message","a","apply","_secureInit","_callee2","initData","response","result","decodedToken","_t2","_context2","fetch","method","headers","Accept","body","JSON","stringify","ok","Error","concat","status","json","success","data","api_url","decodeSecureToken","client_id","secret_id","expiresIn","expires_in","maxRequests","max_requests","requestCount","parts","split","_parts","_slicedToArray","payload","decodedPayload","atob","tokenData","parse","exp","Date","now","_this","io","warn","setTimeout","ip","getClientIP","query","userId","username","on","id","reason","handleQRStatusUpdate","handleQRScanSuccess","handleQRExpired","errors","push","isValidUrl","join","string","url","URL","protocol","_","event","securityLog","timestamp","toISOString","userAgent","navigator","location","href","SunuIDSecurityLogs","originalClientId","originalSecretId","clientIdDisplay","secretIdDisplay","input","trim","connected","emit","_generateQR","_callee3","containerId","options","qrImageUrl","_waitForSocketId","_t3","_this2","_args3","_context3","makeRequest","qrcode","currentQRUrl","displayQRCode","pendingQRInfo","code","waitForSocketId","socketId","qrContent","typeName","getTypeName","qrLabel","generateCustomQRCode","startAutoRefresh","emitWebSocketEvent","serviceId","service_id","qrCodeUrl","sessionId","stack","slice","displayServiceUnavailable","_x","_generateCustomQR","_callee4","_response","_waitForSocketId2","_t4","_this3","_args4","_context4","_x2","_x3","_generateAuthQR","_callee5","_args5","_context5","generateQR","_x4","_generateKYCQR","_callee6","originalType","_args6","_context6","f","_x5","_generateSignatureQR","_callee7","_args7","_context7","_x6","_checkQRStatus","_callee8","_response2","_t5","_context8","handleError","_x7","qrUrl","container","document","getElementById","innerHTML","qrElement","createElement","className","appendChild","applyTheme","_generateCustomQRCode","_callee9","content","label","_qrContainer","qrGeneratorUrl","_response3","responseData","instructionsElement","statusElement","_t6","_context9","qrContainer","displayFallbackImage","size","margin","dataUrl","parentElement","querySelector","style","display","classList","add","generateQRCodeClientSide","_x8","_x9","_this4","QRCode","canvas","width","height","ctx","getContext","toCanvas","color","dark","light","fillStyle","font","textAlign","fillText","toDataURL","x","y","logo","Image","onload","logoSize","logoX","logoY","fillRect","drawImage","src","String","toUpperCase","_refreshQR","_callee0","_t7","_args0","_context0","_x0","_this5","setInterval","_callee1","_t8","_context1","refreshQR","_makeRequest","_callee10","endpoint","_window$SunuIDConfig4","_window$SunuIDConfig5","sanitizedData","endpointPath","retryCount","_loop","_ret","_this6","_context11","sanitizeRequestData","endpoints","dataKeys","Object","keys","controller","timeoutId","_response4","errorText","errorData","_t9","_context10","AbortController","abort","signal","clearTimeout","text","e","statusText","responseKeys","name","Promise","resolve","d","_regeneratorValues","_x1","_x10","sanitized","_i","_Object$entries","entries","_Object$entries$_i","sanitizeInput","_typeof","Math","random","toString","substr","clearInterval","disconnect","sunuidInstance","initSunuID"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sunuid-sdk",
3
- "version": "1.0.29",
3
+ "version": "1.0.30",
4
4
  "type": "module",
5
5
  "description": "SDK JavaScript pour l'intégration des QR codes d'authentification et KYC SunuID",
6
6
  "main": "dist/sunuid-sdk.js",