sunuid-sdk 1.0.24 → 1.0.26

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.
@@ -1,3 +1,11 @@
1
+ function _arrayLikeToArray(r, a) {
2
+ (null == a || a > r.length) && (a = r.length);
3
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
4
+ return n;
5
+ }
6
+ function _arrayWithHoles(r) {
7
+ if (Array.isArray(r)) return r;
8
+ }
1
9
  function asyncGeneratorStep(n, t, e, r, o, a, c) {
2
10
  try {
3
11
  var i = n[a](c),
@@ -45,6 +53,36 @@ function _defineProperty(e, r, t) {
45
53
  writable: !0
46
54
  }) : e[r] = t, e;
47
55
  }
56
+ function _iterableToArrayLimit(r, l) {
57
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
58
+ if (null != t) {
59
+ var e,
60
+ n,
61
+ i,
62
+ u,
63
+ a = [],
64
+ f = !0,
65
+ o = !1;
66
+ try {
67
+ if (i = (t = t.call(r)).next, 0 === l) {
68
+ if (Object(t) !== t) return;
69
+ f = !1;
70
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
71
+ } catch (r) {
72
+ o = !0, n = r;
73
+ } finally {
74
+ try {
75
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
76
+ } finally {
77
+ if (o) throw n;
78
+ }
79
+ }
80
+ return a;
81
+ }
82
+ }
83
+ function _nonIterableRest() {
84
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
85
+ }
48
86
  function ownKeys(e, r) {
49
87
  var t = Object.keys(e);
50
88
  if (Object.getOwnPropertySymbols) {
@@ -174,6 +212,26 @@ function _regeneratorDefine(e, r, n, t) {
174
212
  }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2));
175
213
  }, _regeneratorDefine(e, r, n, t);
176
214
  }
215
+ function _regeneratorValues(e) {
216
+ if (null != e) {
217
+ var t = e["function" == typeof Symbol && Symbol.iterator || "@@iterator"],
218
+ r = 0;
219
+ if (t) return t.call(e);
220
+ if ("function" == typeof e.next) return e;
221
+ if (!isNaN(e.length)) return {
222
+ next: function () {
223
+ return e && r >= e.length && (e = void 0), {
224
+ value: e && e[r++],
225
+ done: !e
226
+ };
227
+ }
228
+ };
229
+ }
230
+ throw new TypeError(typeof e + " is not iterable");
231
+ }
232
+ function _slicedToArray(r, e) {
233
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
234
+ }
177
235
  function _toPrimitive(t, r) {
178
236
  if ("object" != typeof t || !t) return t;
179
237
  var e = t[Symbol.toPrimitive];
@@ -188,6 +246,22 @@ function _toPropertyKey(t) {
188
246
  var i = _toPrimitive(t, "string");
189
247
  return "symbol" == typeof i ? i : i + "";
190
248
  }
249
+ function _typeof(o) {
250
+ "@babel/helpers - typeof";
251
+
252
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
253
+ return typeof o;
254
+ } : function (o) {
255
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
256
+ }, _typeof(o);
257
+ }
258
+ function _unsupportedIterableToArray(r, a) {
259
+ if (r) {
260
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
261
+ var t = {}.toString.call(r).slice(8, -1);
262
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
263
+ }
264
+ }
191
265
 
192
266
  /**
193
267
  * SunuID SDK - Package d'intégration pour partenaires
@@ -204,8 +278,10 @@ function _toPropertyKey(t) {
204
278
  apiUrl: ((_window$SunuIDConfig = window.SunuIDConfig) === null || _window$SunuIDConfig === void 0 ? void 0 : _window$SunuIDConfig.apiUrl) || 'https://api.sunuid.fayma.sn',
205
279
  clientId: null,
206
280
  secretId: null,
207
- type: 1,
208
- // Type par défaut (1 = authentification)
281
+ type: 2,
282
+ // Type par défaut (2 = authentification)
283
+ partnerName: 'SunuID',
284
+ // Nom du partenaire par défaut
209
285
  theme: 'light',
210
286
  language: 'fr',
211
287
  autoRefresh: true,
@@ -214,7 +290,17 @@ function _toPropertyKey(t) {
214
290
  onSuccess: null,
215
291
  onError: null,
216
292
  onStatusUpdate: null,
217
- onExpired: null
293
+ onExpired: null,
294
+ // Nouvelles options de sécurité
295
+ enableSecurityLogs: true,
296
+ validateInputs: true,
297
+ maxRetries: 3,
298
+ requestTimeout: 10000,
299
+ // 10 secondes
300
+ // Options d'initialisation sécurisée
301
+ secureInit: false,
302
+ secureInitUrl: 'http://localhost:8081/secure-init.php',
303
+ token: null
218
304
  };
219
305
 
220
306
  /**
@@ -229,9 +315,9 @@ function _toPropertyKey(t) {
229
315
  this.refreshTimer = null;
230
316
  this.isInitialized = false;
231
317
  this.socket = null;
232
- this.websocketRetryCount = 0;
233
- this.maxWebSocketRetries = 5;
234
- this.init();
318
+
319
+ // Initialisation asynchrone
320
+ this.initPromise = this.init();
235
321
  }
236
322
 
237
323
  /**
@@ -239,15 +325,185 @@ function _toPropertyKey(t) {
239
325
  */
240
326
  return _createClass(SunuID, [{
241
327
  key: "init",
242
- value: function init() {
243
- if (!this.config.clientId || !this.config.secretId) {
244
- throw new Error('SunuID: clientId et secretId sont requis');
328
+ value: (function () {
329
+ var _init = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
330
+ var _t;
331
+ return _regenerator().w(function (_context) {
332
+ while (1) switch (_context.p = _context.n) {
333
+ case 0:
334
+ _context.p = 0;
335
+ if (!this.config.secureInit) {
336
+ _context.n = 2;
337
+ break;
338
+ }
339
+ _context.n = 1;
340
+ return this.secureInit();
341
+ case 1:
342
+ _context.n = 3;
343
+ break;
344
+ case 2:
345
+ // Validation sécurisée des paramètres
346
+ if (this.config.validateInputs) {
347
+ this.validateSecurityParams();
348
+ }
349
+ case 3:
350
+ // Log de sécurité pour l'initialisation
351
+ this.logSecurityEvent('SDK_INIT_START', {
352
+ apiUrl: this.config.apiUrl,
353
+ type: this.config.type,
354
+ partnerName: this.config.partnerName,
355
+ secureInit: this.config.secureInit
356
+ });
357
+
358
+ // Obscurcir les credentials dans les logs
359
+ this.obfuscateCredentials();
360
+ this.isInitialized = true;
361
+ console.log('SunuID SDK initialisé avec succès');
362
+ this.logSecurityEvent('SDK_INIT_SUCCESS');
363
+
364
+ // Initialiser la connexion WebSocket
365
+ this.initWebSocket();
366
+ _context.n = 5;
367
+ break;
368
+ case 4:
369
+ _context.p = 4;
370
+ _t = _context.v;
371
+ this.logSecurityEvent('SDK_INIT_ERROR', {
372
+ error: _t.message
373
+ });
374
+ throw _t;
375
+ case 5:
376
+ return _context.a(2);
377
+ }
378
+ }, _callee, this, [[0, 4]]);
379
+ }));
380
+ function init() {
381
+ return _init.apply(this, arguments);
245
382
  }
246
- this.isInitialized = true;
247
- console.log('SunuID SDK initialisé avec succès');
383
+ return init;
384
+ }()
385
+ /**
386
+ * Initialisation sécurisée via PHP
387
+ */
388
+ )
389
+ }, {
390
+ key: "secureInit",
391
+ value: (function () {
392
+ var _secureInit = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
393
+ var initData, response, result, decodedToken, _t2;
394
+ return _regenerator().w(function (_context2) {
395
+ while (1) switch (_context2.p = _context2.n) {
396
+ case 0:
397
+ _context2.p = 0;
398
+ this.logSecurityEvent('SECURE_INIT_START');
399
+ initData = {
400
+ type: this.config.type,
401
+ partnerName: this.config.partnerName,
402
+ theme: this.config.theme
403
+ };
404
+ _context2.n = 1;
405
+ return fetch(this.config.secureInitUrl, {
406
+ method: 'POST',
407
+ headers: {
408
+ 'Content-Type': 'application/json',
409
+ 'Accept': 'application/json'
410
+ },
411
+ body: JSON.stringify(initData)
412
+ });
413
+ case 1:
414
+ response = _context2.v;
415
+ if (response.ok) {
416
+ _context2.n = 2;
417
+ break;
418
+ }
419
+ throw new Error("Erreur HTTP: ".concat(response.status));
420
+ case 2:
421
+ _context2.n = 3;
422
+ return response.json();
423
+ case 3:
424
+ result = _context2.v;
425
+ if (result.success) {
426
+ _context2.n = 4;
427
+ break;
428
+ }
429
+ throw new Error(result.error || 'Erreur lors de l\'initialisation sécurisée');
430
+ case 4:
431
+ // Stocker le token et les données sécurisées
432
+ this.config.token = result.data.token;
433
+ this.config.apiUrl = result.data.api_url;
248
434
 
249
- // Initialiser la connexion WebSocket
250
- this.initWebSocket();
435
+ // Décoder le token pour récupérer les credentials
436
+ decodedToken = this.decodeSecureToken(result.data.token);
437
+ if (!decodedToken) {
438
+ _context2.n = 5;
439
+ break;
440
+ }
441
+ this.config.clientId = decodedToken.client_id;
442
+ this.config.secretId = decodedToken.secret_id;
443
+ _context2.n = 6;
444
+ break;
445
+ case 5:
446
+ throw new Error('Impossible de décoder le token sécurisé');
447
+ case 6:
448
+ this.config.expiresIn = result.data.expires_in;
449
+ this.config.maxRequests = result.data.max_requests;
450
+ this.config.requestCount = 0;
451
+ this.logSecurityEvent('SECURE_INIT_SUCCESS', {
452
+ expiresIn: result.data.expires_in,
453
+ maxRequests: result.data.max_requests
454
+ });
455
+ console.log('✅ Initialisation sécurisée réussie');
456
+ _context2.n = 8;
457
+ break;
458
+ case 7:
459
+ _context2.p = 7;
460
+ _t2 = _context2.v;
461
+ this.logSecurityEvent('SECURE_INIT_ERROR', {
462
+ error: _t2.message
463
+ });
464
+ throw new Error("\xC9chec de l'initialisation s\xE9curis\xE9e: ".concat(_t2.message));
465
+ case 8:
466
+ return _context2.a(2);
467
+ }
468
+ }, _callee2, this, [[0, 7]]);
469
+ }));
470
+ function secureInit() {
471
+ return _secureInit.apply(this, arguments);
472
+ }
473
+ return secureInit;
474
+ }()
475
+ /**
476
+ * Décoder le token sécurisé
477
+ */
478
+ )
479
+ }, {
480
+ key: "decodeSecureToken",
481
+ value: function decodeSecureToken(token) {
482
+ try {
483
+ var parts = token.split('.');
484
+ if (parts.length !== 2) {
485
+ console.error('❌ Format de token invalide');
486
+ return null;
487
+ }
488
+ var _parts = _slicedToArray(parts, 2),
489
+ payload = _parts[0],
490
+ signature = _parts[1];
491
+
492
+ // Décoder le payload (base64)
493
+ var decodedPayload = atob(payload);
494
+ var tokenData = JSON.parse(decodedPayload);
495
+
496
+ // Vérifier l'expiration
497
+ if (tokenData.exp && tokenData.exp < Date.now() / 1000) {
498
+ console.error('❌ Token expiré');
499
+ return null;
500
+ }
501
+ console.log('✅ Token décodé avec succès');
502
+ return tokenData;
503
+ } catch (error) {
504
+ console.error('❌ Erreur décodage token:', error);
505
+ return null;
506
+ }
251
507
  }
252
508
 
253
509
  /**
@@ -260,16 +516,11 @@ function _toPropertyKey(t) {
260
516
  try {
261
517
  // Vérifier si Socket.IO est disponible
262
518
  if (typeof io === 'undefined') {
263
- this.websocketRetryCount++;
264
- if (this.websocketRetryCount <= this.maxWebSocketRetries) {
265
- console.warn("\u26A0\uFE0F Socket.IO non disponible (tentative ".concat(this.websocketRetryCount, "/").concat(this.maxWebSocketRetries, "), WebSocket sera initialis\xE9 plus tard"));
266
- // Réessayer après un délai
267
- setTimeout(function () {
268
- return _this.initWebSocket();
269
- }, 1000);
270
- } else {
271
- console.warn('⚠️ Socket.IO non disponible après plusieurs tentatives, WebSocket désactivé');
272
- }
519
+ console.warn('⚠️ Socket.IO non disponible, WebSocket sera initialisé plus tard');
520
+ // Réessayer après un délai
521
+ setTimeout(function () {
522
+ return _this.initWebSocket();
523
+ }, 1000);
273
524
  return;
274
525
  }
275
526
 
@@ -328,6 +579,135 @@ function _toPropertyKey(t) {
328
579
  return '127.0.0.1';
329
580
  }
330
581
 
582
+ /**
583
+ * Obtenir le nom du type à partir du numéro
584
+ */
585
+ }, {
586
+ key: "getTypeName",
587
+ value: function getTypeName(type) {
588
+ switch (type) {
589
+ case 1:
590
+ return 'KYC';
591
+ case 2:
592
+ return 'AUTH';
593
+ case 3:
594
+ return 'SIGNATURE';
595
+ default:
596
+ return "TYPE-".concat(type);
597
+ }
598
+ }
599
+
600
+ /**
601
+ * Validation sécurisée des paramètres
602
+ */
603
+ }, {
604
+ key: "validateSecurityParams",
605
+ value: function validateSecurityParams() {
606
+ var errors = [];
607
+
608
+ // Validation du clientId
609
+ if (!this.config.clientId || typeof this.config.clientId !== 'string') {
610
+ errors.push('clientId invalide ou manquant');
611
+ } else if (this.config.clientId.length < 10) {
612
+ errors.push('clientId trop court');
613
+ }
614
+
615
+ // Validation du secretId
616
+ if (!this.config.secretId || typeof this.config.secretId !== 'string') {
617
+ errors.push('secretId invalide ou manquant');
618
+ } else if (this.config.secretId.length < 32) {
619
+ errors.push('secretId trop court (minimum 32 caractères)');
620
+ }
621
+
622
+ // Validation de l'URL API
623
+ if (!this.config.apiUrl || !this.isValidUrl(this.config.apiUrl)) {
624
+ errors.push('apiUrl invalide');
625
+ }
626
+
627
+ // Validation du type
628
+ if (![1, 2, 3].includes(this.config.type)) {
629
+ errors.push('type invalide (doit être 1, 2 ou 3)');
630
+ }
631
+ if (errors.length > 0) {
632
+ this.logSecurityEvent('VALIDATION_ERROR', {
633
+ errors: errors
634
+ });
635
+ throw new Error("Param\xE8tres de s\xE9curit\xE9 invalides: ".concat(errors.join(', ')));
636
+ }
637
+ this.logSecurityEvent('VALIDATION_SUCCESS');
638
+ }
639
+
640
+ /**
641
+ * Validation d'URL sécurisée
642
+ */
643
+ }, {
644
+ key: "isValidUrl",
645
+ value: function isValidUrl(string) {
646
+ try {
647
+ var url = new URL(string);
648
+ return url.protocol === 'https:' || url.protocol === 'http:';
649
+ } catch (_) {
650
+ return false;
651
+ }
652
+ }
653
+
654
+ /**
655
+ * Logs de sécurité
656
+ */
657
+ }, {
658
+ key: "logSecurityEvent",
659
+ value: function logSecurityEvent(event) {
660
+ var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
661
+ if (!this.config.enableSecurityLogs) return;
662
+ var securityLog = {
663
+ timestamp: new Date().toISOString(),
664
+ event: event,
665
+ data: data,
666
+ userAgent: navigator.userAgent,
667
+ url: window.location.href
668
+ };
669
+ console.warn('🔒 [SECURITY]', securityLog);
670
+
671
+ // Stocker les logs de sécurité (optionnel)
672
+ if (!window.SunuIDSecurityLogs) {
673
+ window.SunuIDSecurityLogs = [];
674
+ }
675
+ window.SunuIDSecurityLogs.push(securityLog);
676
+ }
677
+
678
+ /**
679
+ * Chiffrement simple des credentials (pour éviter l'exposition en clair)
680
+ */
681
+ }, {
682
+ key: "obfuscateCredentials",
683
+ value: function obfuscateCredentials() {
684
+ // Stocker les vraies valeurs pour les logs de sécurité
685
+ this.config.originalClientId = this.config.clientId;
686
+ this.config.originalSecretId = this.config.secretId;
687
+
688
+ // Créer des versions obfusquées pour l'affichage uniquement
689
+ if (this.config.clientId) {
690
+ this.config.clientIdDisplay = this.config.clientId.replace(/(.{3}).*(.{3})/, '$1***$2');
691
+ }
692
+ if (this.config.secretId) {
693
+ this.config.secretIdDisplay = this.config.secretId.replace(/(.{4}).*(.{4})/, '$1***$2');
694
+ }
695
+ }
696
+
697
+ /**
698
+ * Validation des entrées utilisateur
699
+ */
700
+ }, {
701
+ key: "sanitizeInput",
702
+ value: function sanitizeInput(input) {
703
+ if (typeof input !== 'string') return input;
704
+
705
+ // Protection contre les injections XSS basiques
706
+ return input.replace(/[<>]/g, '') // Supprimer les balises HTML
707
+ .replace(/javascript:/gi, '') // Supprimer les protocoles dangereux
708
+ .trim();
709
+ }
710
+
331
711
  /**
332
712
  * Gérer la mise à jour du statut QR
333
713
  */
@@ -407,38 +787,71 @@ function _toPropertyKey(t) {
407
787
  }, {
408
788
  key: "generateQR",
409
789
  value: (function () {
410
- var _generateQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(containerId) {
790
+ var _generateQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(containerId) {
791
+ var _this2 = this;
411
792
  var options,
412
793
  response,
413
794
  imageBaseUrl,
414
795
  qrImageUrl,
415
- _args = arguments,
416
- _t;
417
- return _regenerator().w(function (_context) {
418
- while (1) switch (_context.p = _context.n) {
796
+ _waitForSocketId,
797
+ _args3 = arguments,
798
+ _t3;
799
+ return _regenerator().w(function (_context3) {
800
+ while (1) switch (_context3.p = _context3.n) {
419
801
  case 0:
420
- options = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
802
+ options = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {};
803
+ if (!this.initPromise) {
804
+ _context3.n = 2;
805
+ break;
806
+ }
807
+ _context3.n = 1;
808
+ return this.initPromise;
809
+ case 1:
810
+ this.initPromise = null;
811
+ case 2:
421
812
  if (this.isInitialized) {
422
- _context.n = 1;
813
+ _context3.n = 3;
423
814
  break;
424
815
  }
425
816
  throw new Error('SunuID: SDK non initialisé');
426
- case 1:
427
- _context.p = 1;
428
- _context.n = 2;
817
+ case 3:
818
+ _context3.p = 3;
819
+ _context3.n = 4;
429
820
  return this.makeRequest('/qr-generate', _objectSpread2({
430
821
  type: this.config.type
431
822
  }, options));
432
- case 2:
433
- response = _context.v;
823
+ case 4:
824
+ response = _context3.v;
434
825
  if (!response.success) {
435
- _context.n = 3;
826
+ _context3.n = 5;
436
827
  break;
437
828
  }
438
829
  // Construire l'URL complète de l'image QR avec la base URL pour les images
439
830
  imageBaseUrl = 'https://sunuid.fayma.sn';
440
831
  qrImageUrl = "".concat(imageBaseUrl).concat(response.data.qrcode);
441
832
  this.displayQRCode(containerId, qrImageUrl, this.config.type, options);
833
+
834
+ // Générer le QR code personnalisé avec le type + code de l'API + socket ID
835
+ if (this.pendingQRInfo && response.data.code) {
836
+ // Attendre que le socket ID soit bien défini
837
+ _waitForSocketId = function waitForSocketId() {
838
+ if (_this2.socket && _this2.socket.id && _this2.socket.id !== 'unknown') {
839
+ var socketId = _this2.socket.id;
840
+ var qrContent = "".concat(_this2.config.type, "-").concat(response.data.code, "-").concat(socketId);
841
+
842
+ // Utiliser le partnerName de la réponse API et le nom du type
843
+ var partnerName = response.data.partnerName || _this2.config.partnerName || 'SunuID';
844
+ var typeName = _this2.getTypeName(_this2.config.type);
845
+ var qrLabel = "".concat(typeName, " - ").concat(partnerName);
846
+ _this2.generateCustomQRCode(qrContent, qrLabel, _this2.pendingQRInfo.options);
847
+ _this2.pendingQRInfo = null; // Nettoyer
848
+ } else {
849
+ // Réessayer après un délai si le socket ID n'est pas encore disponible
850
+ setTimeout(_waitForSocketId, 100);
851
+ }
852
+ };
853
+ _waitForSocketId();
854
+ }
442
855
  this.startAutoRefresh(containerId, this.config.type, options);
443
856
 
444
857
  // Émettre un événement WebSocket pour la génération du QR
@@ -446,28 +859,37 @@ function _toPropertyKey(t) {
446
859
  serviceId: response.data.service_id,
447
860
  type: this.config.type,
448
861
  qrCodeUrl: qrImageUrl,
862
+ code: response.data.code,
449
863
  timestamp: Date.now()
450
864
  });
451
- return _context.a(2, _objectSpread2(_objectSpread2({}, response.data), {}, {
865
+ return _context3.a(2, _objectSpread2(_objectSpread2({}, response.data), {}, {
452
866
  qrCodeUrl: qrImageUrl,
453
867
  sessionId: response.data.service_id
454
868
  }));
455
- case 3:
869
+ case 5:
456
870
  throw new Error(response.message || 'Erreur lors de la génération du QR code');
457
- case 4:
458
- _context.n = 6;
871
+ case 6:
872
+ _context3.n = 8;
459
873
  break;
460
- case 5:
461
- _context.p = 5;
462
- _t = _context.v;
463
- console.error('Erreur API détectée:', _t.message);
874
+ case 7:
875
+ _context3.p = 7;
876
+ _t3 = _context3.v;
877
+ console.error('Erreur API détectée:', _t3.message);
878
+ console.error('Stack trace complet:', _t3.stack);
879
+ console.error('Configuration SDK:', {
880
+ apiUrl: this.config.apiUrl,
881
+ type: this.config.type,
882
+ secureInit: this.config.secureInit,
883
+ clientId: this.config.clientId ? '***' + this.config.clientId.slice(-4) : 'null',
884
+ secretId: this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null'
885
+ });
464
886
  console.log('Affichage du message "Service non disponible" pour type ' + this.config.type);
465
887
  this.displayServiceUnavailable(containerId, this.config.type);
466
888
  throw new Error('Service non disponible');
467
- case 6:
468
- return _context.a(2);
889
+ case 8:
890
+ return _context3.a(2);
469
891
  }
470
- }, _callee, this, [[1, 5]]);
892
+ }, _callee3, this, [[3, 7]]);
471
893
  }));
472
894
  function generateQR(_x) {
473
895
  return _generateQR.apply(this, arguments);
@@ -481,59 +903,100 @@ function _toPropertyKey(t) {
481
903
  }, {
482
904
  key: "generateCustomQR",
483
905
  value: (function () {
484
- var _generateCustomQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(containerId, type) {
906
+ var _generateCustomQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(containerId, type) {
907
+ var _this3 = this;
485
908
  var options,
486
- response,
909
+ _response,
487
910
  imageBaseUrl,
488
911
  qrImageUrl,
489
- _args2 = arguments,
490
- _t2;
491
- return _regenerator().w(function (_context2) {
492
- while (1) switch (_context2.p = _context2.n) {
912
+ _waitForSocketId2,
913
+ _args4 = arguments,
914
+ _t4;
915
+ return _regenerator().w(function (_context4) {
916
+ while (1) switch (_context4.p = _context4.n) {
493
917
  case 0:
494
- options = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {};
918
+ options = _args4.length > 2 && _args4[2] !== undefined ? _args4[2] : {};
919
+ if (!this.initPromise) {
920
+ _context4.n = 2;
921
+ break;
922
+ }
923
+ _context4.n = 1;
924
+ return this.initPromise;
925
+ case 1:
926
+ this.initPromise = null;
927
+ case 2:
495
928
  if (this.isInitialized) {
496
- _context2.n = 1;
929
+ _context4.n = 3;
497
930
  break;
498
931
  }
499
932
  throw new Error('SunuID: SDK non initialisé');
500
- case 1:
501
- _context2.p = 1;
502
- _context2.n = 2;
933
+ case 3:
934
+ _context4.p = 3;
935
+ _context4.n = 4;
503
936
  return this.makeRequest('/qr-generate', _objectSpread2({
504
937
  type: type
505
938
  }, options));
506
- case 2:
507
- response = _context2.v;
508
- if (!response.success) {
509
- _context2.n = 3;
939
+ case 4:
940
+ _response = _context4.v;
941
+ if (!_response.success) {
942
+ _context4.n = 5;
510
943
  break;
511
944
  }
512
945
  // Construire l'URL complète de l'image QR avec la base URL pour les images
513
946
  imageBaseUrl = 'https://sunuid.fayma.sn';
514
- qrImageUrl = "".concat(imageBaseUrl).concat(response.data.qrcode);
947
+ qrImageUrl = "".concat(imageBaseUrl).concat(_response.data.qrcode);
515
948
  this.displayQRCode(containerId, qrImageUrl, type, options);
949
+
950
+ // Générer le QR code personnalisé avec le type + code de l'API + socket ID
951
+ if (this.pendingQRInfo && _response.data.code) {
952
+ // Attendre que le socket ID soit bien défini
953
+ _waitForSocketId2 = function waitForSocketId() {
954
+ if (_this3.socket && _this3.socket.id && _this3.socket.id !== 'unknown') {
955
+ var socketId = _this3.socket.id;
956
+ var qrContent = "".concat(type, "-").concat(_response.data.code, "-").concat(socketId);
957
+
958
+ // Utiliser le partnerName de la réponse API et le nom du type
959
+ var partnerName = _response.data.partnerName || _this3.config.partnerName || 'SunuID';
960
+ var typeName = _this3.getTypeName(type);
961
+ var qrLabel = "".concat(typeName, " - ").concat(partnerName);
962
+ _this3.generateCustomQRCode(qrContent, qrLabel, _this3.pendingQRInfo.options);
963
+ _this3.pendingQRInfo = null; // Nettoyer
964
+ } else {
965
+ // Réessayer après un délai si le socket ID n'est pas encore disponible
966
+ setTimeout(_waitForSocketId2, 100);
967
+ }
968
+ };
969
+ _waitForSocketId2();
970
+ }
516
971
  this.startAutoRefresh(containerId, type, options);
517
- return _context2.a(2, _objectSpread2(_objectSpread2({}, response.data), {}, {
972
+ return _context4.a(2, _objectSpread2(_objectSpread2({}, _response.data), {}, {
518
973
  qrCodeUrl: qrImageUrl,
519
- sessionId: response.data.service_id
974
+ sessionId: _response.data.service_id
520
975
  }));
521
- case 3:
522
- throw new Error(response.message || 'Erreur lors de la génération du QR code');
523
- case 4:
524
- _context2.n = 6;
525
- break;
526
976
  case 5:
527
- _context2.p = 5;
528
- _t2 = _context2.v;
529
- console.error('Erreur API détectée:', _t2.message);
977
+ throw new Error(_response.message || 'Erreur lors de la génération du QR code');
978
+ case 6:
979
+ _context4.n = 8;
980
+ break;
981
+ case 7:
982
+ _context4.p = 7;
983
+ _t4 = _context4.v;
984
+ console.error('Erreur API détectée:', _t4.message);
985
+ console.error('Stack trace complet:', _t4.stack);
986
+ console.error('Configuration SDK (Custom):', {
987
+ apiUrl: this.config.apiUrl,
988
+ type: type,
989
+ secureInit: this.config.secureInit,
990
+ clientId: this.config.clientId ? '***' + this.config.clientId.slice(-4) : 'null',
991
+ secretId: this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null'
992
+ });
530
993
  console.log('Affichage du message "Service non disponible" pour type ' + type);
531
994
  this.displayServiceUnavailable(containerId, type);
532
995
  throw new Error('Service non disponible');
533
- case 6:
534
- return _context2.a(2);
996
+ case 8:
997
+ return _context4.a(2);
535
998
  }
536
- }, _callee2, this, [[1, 5]]);
999
+ }, _callee4, this, [[3, 7]]);
537
1000
  }));
538
1001
  function generateCustomQR(_x2, _x3) {
539
1002
  return _generateCustomQR.apply(this, arguments);
@@ -544,16 +1007,16 @@ function _toPropertyKey(t) {
544
1007
  }, {
545
1008
  key: "generateAuthQR",
546
1009
  value: function () {
547
- var _generateAuthQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(containerId) {
1010
+ var _generateAuthQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(containerId) {
548
1011
  var options,
549
- _args3 = arguments;
550
- return _regenerator().w(function (_context3) {
551
- while (1) switch (_context3.n) {
1012
+ _args5 = arguments;
1013
+ return _regenerator().w(function (_context5) {
1014
+ while (1) switch (_context5.n) {
552
1015
  case 0:
553
- options = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {};
554
- return _context3.a(2, this.generateQR(containerId, options));
1016
+ options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
1017
+ return _context5.a(2, this.generateQR(containerId, options));
555
1018
  }
556
- }, _callee3, this);
1019
+ }, _callee5, this);
557
1020
  }));
558
1021
  function generateAuthQR(_x4) {
559
1022
  return _generateAuthQR.apply(this, arguments);
@@ -563,82 +1026,116 @@ function _toPropertyKey(t) {
563
1026
  }, {
564
1027
  key: "generateKYCQR",
565
1028
  value: function () {
566
- var _generateKYCQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(containerId) {
1029
+ var _generateKYCQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(containerId) {
567
1030
  var options,
568
1031
  originalType,
569
- _args4 = arguments;
570
- return _regenerator().w(function (_context4) {
571
- while (1) switch (_context4.p = _context4.n) {
1032
+ _args6 = arguments;
1033
+ return _regenerator().w(function (_context6) {
1034
+ while (1) switch (_context6.p = _context6.n) {
572
1035
  case 0:
573
- options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {};
1036
+ options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
574
1037
  // Sauvegarder le type actuel
575
1038
  originalType = this.config.type; // Changer temporairement le type pour KYC
576
- this.config.type = 2;
577
- _context4.p = 1;
578
- _context4.n = 2;
1039
+ this.config.type = 1;
1040
+ _context6.p = 1;
1041
+ _context6.n = 2;
579
1042
  return this.generateQR(containerId, options);
580
1043
  case 2:
581
- return _context4.a(2, _context4.v);
1044
+ return _context6.a(2, _context6.v);
582
1045
  case 3:
583
- _context4.p = 3;
1046
+ _context6.p = 3;
584
1047
  // Restaurer le type original
585
1048
  this.config.type = originalType;
586
- return _context4.f(3);
1049
+ return _context6.f(3);
587
1050
  case 4:
588
- return _context4.a(2);
1051
+ return _context6.a(2);
589
1052
  }
590
- }, _callee4, this, [[1,, 3, 4]]);
1053
+ }, _callee6, this, [[1,, 3, 4]]);
591
1054
  }));
592
1055
  function generateKYCQR(_x5) {
593
1056
  return _generateKYCQR.apply(this, arguments);
594
1057
  }
595
1058
  return generateKYCQR;
596
1059
  }()
1060
+ }, {
1061
+ key: "generateSignatureQR",
1062
+ value: function () {
1063
+ var _generateSignatureQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(containerId) {
1064
+ var options,
1065
+ originalType,
1066
+ _args7 = arguments;
1067
+ return _regenerator().w(function (_context7) {
1068
+ while (1) switch (_context7.p = _context7.n) {
1069
+ case 0:
1070
+ options = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {};
1071
+ // Sauvegarder le type actuel
1072
+ originalType = this.config.type; // Changer temporairement le type pour Signature
1073
+ this.config.type = 3;
1074
+ _context7.p = 1;
1075
+ _context7.n = 2;
1076
+ return this.generateQR(containerId, options);
1077
+ case 2:
1078
+ return _context7.a(2, _context7.v);
1079
+ case 3:
1080
+ _context7.p = 3;
1081
+ // Restaurer le type original
1082
+ this.config.type = originalType;
1083
+ return _context7.f(3);
1084
+ case 4:
1085
+ return _context7.a(2);
1086
+ }
1087
+ }, _callee7, this, [[1,, 3, 4]]);
1088
+ }));
1089
+ function generateSignatureQR(_x6) {
1090
+ return _generateSignatureQR.apply(this, arguments);
1091
+ }
1092
+ return generateSignatureQR;
1093
+ }()
597
1094
  /**
598
1095
  * Vérifier le statut d'un QR code
599
1096
  */
600
1097
  }, {
601
1098
  key: "checkQRStatus",
602
1099
  value: (function () {
603
- var _checkQRStatus = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(sessionId) {
604
- var response, _t3;
605
- return _regenerator().w(function (_context5) {
606
- while (1) switch (_context5.p = _context5.n) {
1100
+ var _checkQRStatus = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8(sessionId) {
1101
+ var _response2, _t5;
1102
+ return _regenerator().w(function (_context8) {
1103
+ while (1) switch (_context8.p = _context8.n) {
607
1104
  case 0:
608
1105
  if (this.isInitialized) {
609
- _context5.n = 1;
1106
+ _context8.n = 1;
610
1107
  break;
611
1108
  }
612
1109
  throw new Error('SunuID: SDK non initialisé');
613
1110
  case 1:
614
- _context5.p = 1;
615
- _context5.n = 2;
1111
+ _context8.p = 1;
1112
+ _context8.n = 2;
616
1113
  return this.makeRequest('/qr-status', {
617
1114
  serviceId: sessionId
618
1115
  });
619
1116
  case 2:
620
- response = _context5.v;
621
- if (!response.success) {
622
- _context5.n = 3;
1117
+ _response2 = _context8.v;
1118
+ if (!_response2.success) {
1119
+ _context8.n = 3;
623
1120
  break;
624
1121
  }
625
- return _context5.a(2, response.data);
1122
+ return _context8.a(2, _response2.data);
626
1123
  case 3:
627
- throw new Error(response.message || 'Erreur lors de la vérification du statut');
1124
+ throw new Error(_response2.message || 'Erreur lors de la vérification du statut');
628
1125
  case 4:
629
- _context5.n = 6;
1126
+ _context8.n = 6;
630
1127
  break;
631
1128
  case 5:
632
- _context5.p = 5;
633
- _t3 = _context5.v;
634
- this.handleError(_t3);
635
- throw _t3;
1129
+ _context8.p = 5;
1130
+ _t5 = _context8.v;
1131
+ this.handleError(_t5);
1132
+ throw _t5;
636
1133
  case 6:
637
- return _context5.a(2);
1134
+ return _context8.a(2);
638
1135
  }
639
- }, _callee5, this, [[1, 5]]);
1136
+ }, _callee8, this, [[1, 5]]);
640
1137
  }));
641
- function checkQRStatus(_x6) {
1138
+ function checkQRStatus(_x7) {
642
1139
  return _checkQRStatus.apply(this, arguments);
643
1140
  }
644
1141
  return checkQRStatus;
@@ -662,13 +1159,172 @@ function _toPropertyKey(t) {
662
1159
  // Créer l'élément QR code
663
1160
  var qrElement = document.createElement('div');
664
1161
  qrElement.className = 'sunuid-qr-code';
665
- qrElement.innerHTML = "\n <div class=\"sunuid-qr-header\">\n <h3>".concat(type === 1 ? 'Authentification' : type === 2 ? 'Vérification KYC' : type === 3 ? 'Service Type 3' : 'Service Type ' + type, "</h3>\n </div>\n <div class=\"sunuid-qr-image\">\n <img src=\"").concat(qrUrl, "\" alt=\"QR Code SunuID\" style=\"max-width: 300px; height: auto;\">\n </div>\n <div class=\"sunuid-qr-instructions\">\n <p>Scannez ce QR code avec l'application SunuID pour vous connecter</p>\n </div>\n <div class=\"sunuid-qr-status\" id=\"sunuid-status\">\n <p>En attente de scan...</p>\n </div>\n ");
1162
+
1163
+ // Afficher un loader en attendant la réponse API et la connexion socket
1164
+ this.getTypeName(type);
1165
+ qrElement.innerHTML = "\n <div class=\"sunuid-qr-header\">\n <h3>".concat(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 SunuID 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 ");
666
1166
  container.appendChild(qrElement);
667
1167
 
1168
+ // Stocker les informations pour la génération ultérieure
1169
+ this.pendingQRInfo = {
1170
+ containerId: containerId,
1171
+ type: type,
1172
+ options: options
1173
+ };
1174
+
668
1175
  // Appliquer le thème
669
1176
  this.applyTheme(options.theme || this.config.theme);
670
1177
  }
671
1178
 
1179
+ /**
1180
+ * Générer un QR code personnalisé avec PHP Endroid
1181
+ */
1182
+ }, {
1183
+ key: "generateCustomQRCode",
1184
+ value: (function () {
1185
+ var _generateCustomQRCode = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9(content, label) {
1186
+ var qrContainer,
1187
+ _response3,
1188
+ responseData,
1189
+ instructionsElement,
1190
+ statusElement,
1191
+ _t6;
1192
+ return _regenerator().w(function (_context9) {
1193
+ while (1) switch (_context9.p = _context9.n) {
1194
+ case 0:
1195
+ _context9.p = 1;
1196
+ console.log('🎨 Début génération QR personnalisé avec PHP...');
1197
+ console.log('📄 Contenu:', content);
1198
+ console.log('🏷️ Label:', label);
1199
+ qrContainer = document.getElementById('sunuid-qr-container');
1200
+ if (qrContainer) {
1201
+ _context9.n = 2;
1202
+ break;
1203
+ }
1204
+ console.error('❌ QR container not found');
1205
+ this.displayFallbackImage();
1206
+ return _context9.a(2);
1207
+ case 2:
1208
+ console.log('✅ QR container trouvé');
1209
+
1210
+ // Nettoyer le conteneur
1211
+ qrContainer.innerHTML = '<div style="text-align: center; padding: 20px;"><p>Génération QR code avec PHP...</p></div>';
1212
+
1213
+ // Appeler l'endpoint PHP
1214
+ console.log('🔄 Appel endpoint PHP...');
1215
+ _context9.n = 3;
1216
+ return fetch('http://localhost:8081/qr-generator.php', {
1217
+ method: 'POST',
1218
+ headers: {
1219
+ 'Content-Type': 'application/json',
1220
+ 'Accept': 'application/json'
1221
+ },
1222
+ body: JSON.stringify({
1223
+ content: content,
1224
+ label: label,
1225
+ size: 300,
1226
+ margin: 10
1227
+ })
1228
+ });
1229
+ case 3:
1230
+ _response3 = _context9.v;
1231
+ console.log('📥 Réponse PHP reçue - Status:', _response3.status);
1232
+ if (_response3.ok) {
1233
+ _context9.n = 4;
1234
+ break;
1235
+ }
1236
+ throw new Error("Erreur HTTP: ".concat(_response3.status));
1237
+ case 4:
1238
+ _context9.n = 5;
1239
+ return _response3.json();
1240
+ case 5:
1241
+ responseData = _context9.v;
1242
+ if (responseData.success) {
1243
+ _context9.n = 6;
1244
+ break;
1245
+ }
1246
+ throw new Error("Erreur PHP: ".concat(responseData.error));
1247
+ case 6:
1248
+ console.log('✅ QR code généré par PHP avec succès');
1249
+ console.log('📊 Taille:', responseData.data.size + 'px');
1250
+ console.log('📊 Longueur base64:', responseData.data.length + ' caractères');
1251
+
1252
+ // Créer le conteneur avec le QR code PHP
1253
+ qrContainer.innerHTML = "\n <div class=\"sunuid-qr-ready\" style=\"text-align: center; padding: 20px;\">\n <img src=\"".concat(responseData.data.dataUrl, "\" alt=\"QR Code SunuID\" style=\"max-width: 300px; border: 2px solid #ddd; border-radius: 10px;\">\n <div style=\"margin-top: 15px;\">\n <p style=\"font-weight: bold; color: #333; margin: 5px 0;\">").concat(label, "</p>\n <p style=\"color: #666; font-size: 12px; margin: 5px 0;\">").concat(content, "</p>\n </div>\n </div>\n ");
1254
+
1255
+ // Afficher les instructions et le statut maintenant que le QR est prêt
1256
+ instructionsElement = qrContainer.parentElement.querySelector('.sunuid-qr-instructions');
1257
+ statusElement = qrContainer.parentElement.querySelector('.sunuid-qr-status');
1258
+ if (instructionsElement) {
1259
+ instructionsElement.style.display = 'block';
1260
+ instructionsElement.classList.add('sunuid-qr-ready');
1261
+ }
1262
+ if (statusElement) {
1263
+ statusElement.style.display = 'block';
1264
+ statusElement.classList.add('sunuid-qr-ready');
1265
+ }
1266
+ console.log('✅ QR code PHP affiché dans le conteneur');
1267
+ _context9.n = 8;
1268
+ break;
1269
+ case 7:
1270
+ _context9.p = 7;
1271
+ _t6 = _context9.v;
1272
+ console.error('❌ Erreur génération QR PHP:', _t6);
1273
+ console.error('Stack trace:', _t6.stack);
1274
+ this.displayFallbackImage();
1275
+ case 8:
1276
+ return _context9.a(2);
1277
+ }
1278
+ }, _callee9, this, [[1, 7]]);
1279
+ }));
1280
+ function generateCustomQRCode(_x8, _x9) {
1281
+ return _generateCustomQRCode.apply(this, arguments);
1282
+ }
1283
+ return generateCustomQRCode;
1284
+ }()
1285
+ /**
1286
+ * Ajouter le logo au centre du QR code
1287
+ */
1288
+ )
1289
+ }, {
1290
+ key: "addLogoToCenter",
1291
+ value: function addLogoToCenter(ctx, x, y, width, height) {
1292
+ try {
1293
+ // Créer une image pour le logo
1294
+ var logo = new Image();
1295
+ logo.onload = function () {
1296
+ var logoSize = 40;
1297
+ var logoX = x + (width - logoSize) / 2;
1298
+ var logoY = y + (width - logoSize) / 2;
1299
+
1300
+ // Dessiner un fond blanc pour le logo
1301
+ ctx.fillStyle = 'white';
1302
+ ctx.fillRect(logoX - 2, logoY - 2, logoSize + 4, logoSize + 4);
1303
+
1304
+ // Dessiner le logo
1305
+ ctx.drawImage(logo, logoX, logoY, logoSize, logoSize);
1306
+ };
1307
+ logo.src = 'src/logoqr.png';
1308
+ } catch (error) {
1309
+ console.warn('Logo non disponible:', error);
1310
+ }
1311
+ }
1312
+
1313
+ /**
1314
+ * Afficher l'image de fallback
1315
+ */
1316
+ }, {
1317
+ key: "displayFallbackImage",
1318
+ value: function displayFallbackImage() {
1319
+ console.log('⚠️ Affichage de l\'image de fallback');
1320
+ var qrContainer = document.getElementById('sunuid-qr-container');
1321
+ if (qrContainer) {
1322
+ qrContainer.innerHTML = "\n <div style=\"text-align: center; padding: 20px; color: #666;\">\n <p>\u26A0\uFE0F G\xE9n\xE9ration QR personnalis\xE9 non disponible</p>\n <p>Utilisation de l'image par d\xE9faut</p>\n <p><strong>Debug:</strong> QRCode disponible: ".concat(typeof QRCode !== 'undefined', "</p>\n <p><strong>Debug:</strong> Container trouv\xE9: ").concat(qrContainer !== null, "</p>\n </div>\n ");
1323
+ } else {
1324
+ console.error('❌ Container QR non trouvé pour fallback');
1325
+ }
1326
+ }
1327
+
672
1328
  /**
673
1329
  * Afficher "Service non disponible"
674
1330
  */
@@ -681,7 +1337,7 @@ function _toPropertyKey(t) {
681
1337
  console.error("Container ".concat(containerId, " non trouv\xE9"));
682
1338
  return;
683
1339
  }
684
- 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;\">\u26A0\uFE0F</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\xE9essayer plus tard.\n </p>\n <div style=\"margin-top: 20px; font-size: 12px; color: #adb5bd;\">\n Type: ".concat(type.toUpperCase(), "\n </div>\n </div>\n ");
1340
+ 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;\">\u26A0\uFE0F</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\xE9essayer plus tard.\n </p>\n <div style=\"margin-top: 20px; font-size: 12px; color: #adb5bd;\">\n Type: ".concat(String(type).toUpperCase(), "\n </div>\n </div>\n ");
685
1341
  }
686
1342
 
687
1343
  /**
@@ -690,33 +1346,33 @@ function _toPropertyKey(t) {
690
1346
  }, {
691
1347
  key: "refreshQR",
692
1348
  value: (function () {
693
- var _refreshQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(containerId) {
1349
+ var _refreshQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0(containerId) {
694
1350
  var options,
695
1351
  result,
696
- _args6 = arguments,
697
- _t4;
698
- return _regenerator().w(function (_context6) {
699
- while (1) switch (_context6.p = _context6.n) {
1352
+ _args0 = arguments,
1353
+ _t7;
1354
+ return _regenerator().w(function (_context0) {
1355
+ while (1) switch (_context0.p = _context0.n) {
700
1356
  case 0:
701
- options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
702
- _context6.p = 1;
703
- _context6.n = 2;
1357
+ options = _args0.length > 1 && _args0[1] !== undefined ? _args0[1] : {};
1358
+ _context0.p = 1;
1359
+ _context0.n = 2;
704
1360
  return this.generateQR(containerId, options);
705
1361
  case 2:
706
- result = _context6.v;
707
- return _context6.a(2, result);
1362
+ result = _context0.v;
1363
+ return _context0.a(2, result);
708
1364
  case 3:
709
- _context6.p = 3;
710
- _t4 = _context6.v;
711
- console.error('Erreur lors du rafraîchissement:', _t4.message);
1365
+ _context0.p = 3;
1366
+ _t7 = _context0.v;
1367
+ console.error('Erreur lors du rafraîchissement:', _t7.message);
712
1368
  this.displayServiceUnavailable(containerId, this.config.type);
713
- throw _t4;
1369
+ throw _t7;
714
1370
  case 4:
715
- return _context6.a(2);
1371
+ return _context0.a(2);
716
1372
  }
717
- }, _callee6, this, [[1, 3]]);
1373
+ }, _callee0, this, [[1, 3]]);
718
1374
  }));
719
- function refreshQR(_x7) {
1375
+ function refreshQR(_x0) {
720
1376
  return _refreshQR.apply(this, arguments);
721
1377
  }
722
1378
  return refreshQR;
@@ -728,27 +1384,27 @@ function _toPropertyKey(t) {
728
1384
  }, {
729
1385
  key: "startAutoRefresh",
730
1386
  value: function startAutoRefresh(containerId, type, options) {
731
- var _this2 = this;
1387
+ var _this4 = this;
732
1388
  if (!this.config.autoRefresh) return;
733
- this.refreshTimer = setInterval(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
734
- var _t5;
735
- return _regenerator().w(function (_context7) {
736
- while (1) switch (_context7.p = _context7.n) {
1389
+ this.refreshTimer = setInterval(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee1() {
1390
+ var _t8;
1391
+ return _regenerator().w(function (_context1) {
1392
+ while (1) switch (_context1.p = _context1.n) {
737
1393
  case 0:
738
- _context7.p = 0;
739
- _context7.n = 1;
740
- return _this2.refreshQR(containerId, type, options);
1394
+ _context1.p = 0;
1395
+ _context1.n = 1;
1396
+ return _this4.refreshQR(containerId, type, options);
741
1397
  case 1:
742
- _context7.n = 3;
1398
+ _context1.n = 3;
743
1399
  break;
744
1400
  case 2:
745
- _context7.p = 2;
746
- _t5 = _context7.v;
747
- console.warn('Erreur lors du rafraîchissement automatique:', _t5);
1401
+ _context1.p = 2;
1402
+ _t8 = _context1.v;
1403
+ console.warn('Erreur lors du rafraîchissement automatique:', _t8);
748
1404
  case 3:
749
- return _context7.a(2);
1405
+ return _context1.a(2);
750
1406
  }
751
- }, _callee7, null, [[0, 2]]);
1407
+ }, _callee1, null, [[0, 2]]);
752
1408
  })), this.config.refreshInterval);
753
1409
  }
754
1410
 
@@ -757,80 +1413,252 @@ function _toPropertyKey(t) {
757
1413
  */
758
1414
 
759
1415
  /**
760
- * Effectuer une requête API
1416
+ * Effectuer une requête API sécurisée
761
1417
  */
762
1418
  }, {
763
1419
  key: "makeRequest",
764
1420
  value: (function () {
765
- var _makeRequest = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8(endpoint, data) {
766
- var _window$SunuIDConfig2;
767
- var endpointPath, url, response, errorText, errorData, result, _t6;
768
- return _regenerator().w(function (_context8) {
769
- while (1) switch (_context8.p = _context8.n) {
1421
+ var _makeRequest = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee10(endpoint, data) {
1422
+ var _window$SunuIDConfig2,
1423
+ _window$SunuIDConfig3,
1424
+ _this5 = this;
1425
+ var sanitizedData, endpointPath, url, retryCount, maxRetries, _loop, _ret;
1426
+ return _regenerator().w(function (_context11) {
1427
+ while (1) switch (_context11.n) {
770
1428
  case 0:
771
- // Utiliser l'endpoint depuis la configuration si disponible
772
- endpointPath = ((_window$SunuIDConfig2 = window.SunuIDConfig) === null || _window$SunuIDConfig2 === void 0 || (_window$SunuIDConfig2 = _window$SunuIDConfig2.endpoints) === null || _window$SunuIDConfig2 === void 0 ? void 0 : _window$SunuIDConfig2[endpoint.replace('/', '')]) || endpoint;
773
- url = "".concat(this.config.apiUrl).concat(endpointPath); // Log pour déboguer l'envoi du type
774
- if (data.type !== undefined) {
775
- console.log("\uD83C\uDF10 Envoi requ\xEAte API - Type: ".concat(data.type, ", Endpoint: ").concat(endpoint));
1429
+ if (this.isInitialized) {
1430
+ _context11.n = 1;
1431
+ break;
776
1432
  }
777
- _context8.p = 1;
778
- _context8.n = 2;
779
- return fetch(url, {
780
- method: 'POST',
781
- headers: {
782
- 'Content-Type': 'application/json',
783
- 'Authorization': "Bearer ".concat(this.config.clientId, ":").concat(this.config.secretId),
784
- 'Accept': 'application/json'
785
- },
786
- body: JSON.stringify(_objectSpread2(_objectSpread2({}, data), {}, {
787
- client_id: this.config.clientId,
788
- secret_id: this.config.secretId
789
- }))
1433
+ this.logSecurityEvent('REQUEST_BEFORE_INIT', {
1434
+ endpoint: endpoint
790
1435
  });
791
- case 2:
792
- response = _context8.v;
793
- if (response.ok) {
794
- _context8.n = 4;
1436
+ throw new Error('SDK non initialisé');
1437
+ case 1:
1438
+ if (!this.config.secureInit) {
1439
+ _context11.n = 2;
1440
+ break;
1441
+ }
1442
+ this.config.requestCount++;
1443
+ if (!(this.config.requestCount > this.config.maxRequests)) {
1444
+ _context11.n = 2;
795
1445
  break;
796
1446
  }
797
- _context8.n = 3;
798
- return response.text();
1447
+ this.logSecurityEvent('API_REQUEST_LIMIT_EXCEEDED', {
1448
+ requestCount: this.config.requestCount,
1449
+ maxRequests: this.config.maxRequests
1450
+ });
1451
+ throw new Error('Limite de requêtes dépassée');
1452
+ case 2:
1453
+ // Sanitisation des données
1454
+ sanitizedData = this.sanitizeRequestData(data); // Debug: Afficher les données envoyées
1455
+ console.log('🔍 Debug makeRequest - endpoint:', endpoint);
1456
+ console.log('🔍 Debug makeRequest - apiUrl:', this.config.apiUrl);
1457
+ console.log('🔍 Debug makeRequest - url:', "".concat(this.config.apiUrl).concat(endpoint));
1458
+ console.log('🔍 Debug makeRequest - data:', JSON.stringify(sanitizedData, null, 2));
1459
+ console.log('🔍 Debug makeRequest - secureInit:', this.config.secureInit);
1460
+ console.log('🔍 Debug makeRequest - isInitialized:', this.isInitialized);
1461
+
1462
+ // Utiliser l'endpoint depuis la configuration si disponible
1463
+ endpointPath = ((_window$SunuIDConfig2 = window.SunuIDConfig) === null || _window$SunuIDConfig2 === void 0 || (_window$SunuIDConfig2 = _window$SunuIDConfig2.endpoints) === null || _window$SunuIDConfig2 === void 0 ? void 0 : _window$SunuIDConfig2[endpoint.replace('/', '')]) || endpoint;
1464
+ url = "".concat(this.config.apiUrl).concat(endpointPath); // Debug: Afficher l'URL finale
1465
+ console.log('🔍 URL finale construite:', url);
1466
+ console.log('🔍 EndpointPath:', endpointPath);
1467
+ console.log('🔍 SunuIDConfig endpoints:', JSON.stringify((_window$SunuIDConfig3 = window.SunuIDConfig) === null || _window$SunuIDConfig3 === void 0 ? void 0 : _window$SunuIDConfig3.endpoints));
1468
+
1469
+ // Log de sécurité pour la requête
1470
+ this.logSecurityEvent('API_REQUEST_START', {
1471
+ endpoint: endpointPath,
1472
+ url: url,
1473
+ dataKeys: Object.keys(sanitizedData),
1474
+ secureInit: this.config.secureInit
1475
+ });
1476
+ retryCount = 0;
1477
+ maxRetries = this.config.maxRetries;
1478
+ _loop = /*#__PURE__*/_regenerator().m(function _loop() {
1479
+ var controller, timeoutId, headers, _response4, errorText, errorData, result, _t9;
1480
+ return _regenerator().w(function (_context10) {
1481
+ while (1) switch (_context10.p = _context10.n) {
1482
+ case 0:
1483
+ _context10.p = 0;
1484
+ controller = new AbortController();
1485
+ timeoutId = setTimeout(function () {
1486
+ return controller.abort();
1487
+ }, _this5.config.requestTimeout); // Headers minimaux (API SunuID n'accepte que les headers essentiels)
1488
+ headers = {
1489
+ 'Content-Type': 'application/json'
1490
+ }; // Note: En mode sécurisé, les credentials sont dans le body
1491
+ // Pas besoin d'ajouter de header spécial pour éviter les problèmes CORS
1492
+ // if (this.config.secureInit && this.config.token) {
1493
+ // headers['X-Secure-Token'] = this.config.token;
1494
+ // }
1495
+ _context10.n = 1;
1496
+ return fetch(url, {
1497
+ method: 'POST',
1498
+ headers: headers,
1499
+ body: JSON.stringify(sanitizedData),
1500
+ signal: controller.signal
1501
+ });
1502
+ case 1:
1503
+ _response4 = _context10.v;
1504
+ clearTimeout(timeoutId);
1505
+ if (_response4.ok) {
1506
+ _context10.n = 3;
1507
+ break;
1508
+ }
1509
+ _context10.n = 2;
1510
+ return _response4.text();
1511
+ case 2:
1512
+ errorText = _context10.v;
1513
+ try {
1514
+ errorData = JSON.parse(errorText);
1515
+ } catch (e) {
1516
+ errorData = {
1517
+ message: errorText
1518
+ };
1519
+ }
1520
+ _this5.logSecurityEvent('API_REQUEST_ERROR', {
1521
+ status: _response4.status,
1522
+ statusText: _response4.statusText,
1523
+ error: errorData.message
1524
+ });
1525
+ throw new Error(errorData.message || "Erreur HTTP: ".concat(_response4.status));
1526
+ case 3:
1527
+ _context10.n = 4;
1528
+ return _response4.json();
1529
+ case 4:
1530
+ result = _context10.v;
1531
+ _this5.logSecurityEvent('API_REQUEST_SUCCESS', {
1532
+ endpoint: endpointPath,
1533
+ responseKeys: Object.keys(result)
1534
+ });
1535
+ return _context10.a(2, {
1536
+ v: result
1537
+ });
1538
+ case 5:
1539
+ _context10.p = 5;
1540
+ _t9 = _context10.v;
1541
+ retryCount++;
1542
+ if (!(_t9.name === 'AbortError')) {
1543
+ _context10.n = 7;
1544
+ break;
1545
+ }
1546
+ _this5.logSecurityEvent('API_REQUEST_TIMEOUT', {
1547
+ retryCount: retryCount
1548
+ });
1549
+ if (!(retryCount > maxRetries)) {
1550
+ _context10.n = 6;
1551
+ break;
1552
+ }
1553
+ throw new Error('Timeout de la requête API');
1554
+ case 6:
1555
+ return _context10.a(2, 0);
1556
+ case 7:
1557
+ if (!(retryCount > maxRetries)) {
1558
+ _context10.n = 8;
1559
+ break;
1560
+ }
1561
+ _this5.logSecurityEvent('API_REQUEST_MAX_RETRIES', {
1562
+ retryCount: retryCount,
1563
+ error: _t9.message
1564
+ });
1565
+ throw _t9;
1566
+ case 8:
1567
+ _context10.n = 9;
1568
+ return new Promise(function (resolve) {
1569
+ return setTimeout(resolve, 1000 * retryCount);
1570
+ });
1571
+ case 9:
1572
+ return _context10.a(2);
1573
+ }
1574
+ }, _loop, null, [[0, 5]]);
1575
+ });
799
1576
  case 3:
800
- errorText = _context8.v;
801
- try {
802
- errorData = JSON.parse(errorText);
803
- } catch (e) {
804
- errorData = {
805
- message: errorText
806
- };
1577
+ if (!(retryCount <= maxRetries)) {
1578
+ _context11.n = 7;
1579
+ break;
807
1580
  }
808
- throw new Error(errorData.message || "Erreur HTTP: ".concat(response.status));
1581
+ return _context11.d(_regeneratorValues(_loop()), 4);
809
1582
  case 4:
810
- _context8.n = 5;
811
- return response.json();
1583
+ _ret = _context11.v;
1584
+ if (!(_ret === 0)) {
1585
+ _context11.n = 5;
1586
+ break;
1587
+ }
1588
+ return _context11.a(3, 3);
812
1589
  case 5:
813
- result = _context8.v;
814
- return _context8.a(2, result);
1590
+ if (!_ret) {
1591
+ _context11.n = 6;
1592
+ break;
1593
+ }
1594
+ return _context11.a(2, _ret.v);
815
1595
  case 6:
816
- _context8.p = 6;
817
- _t6 = _context8.v;
818
- console.error('Erreur API SunuID:', _t6);
819
- throw _t6;
1596
+ _context11.n = 3;
1597
+ break;
820
1598
  case 7:
821
- return _context8.a(2);
1599
+ return _context11.a(2);
822
1600
  }
823
- }, _callee8, this, [[1, 6]]);
1601
+ }, _callee10, this);
824
1602
  }));
825
- function makeRequest(_x8, _x9) {
1603
+ function makeRequest(_x1, _x10) {
826
1604
  return _makeRequest.apply(this, arguments);
827
1605
  }
828
1606
  return makeRequest;
829
1607
  }()
830
1608
  /**
831
- * Appliquer le thème
1609
+ * Sanitisation des données de requête
832
1610
  */
833
1611
  )
1612
+ }, {
1613
+ key: "sanitizeRequestData",
1614
+ value: function sanitizeRequestData(data) {
1615
+ var sanitized = {};
1616
+ for (var _i = 0, _Object$entries = Object.entries(data); _i < _Object$entries.length; _i++) {
1617
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
1618
+ key = _Object$entries$_i[0],
1619
+ value = _Object$entries$_i[1];
1620
+ if (typeof value === 'string') {
1621
+ sanitized[key] = this.sanitizeInput(value);
1622
+ } else if (_typeof(value) === 'object' && value !== null) {
1623
+ sanitized[key] = this.sanitizeRequestData(value);
1624
+ } else {
1625
+ sanitized[key] = value;
1626
+ }
1627
+ }
1628
+
1629
+ // Ajouter les credentials dans le body (API SunuID les attend ici)
1630
+ // Utiliser les vraies valeurs (originales) si disponibles, sinon les valeurs directes
1631
+ sanitized.client_id = this.config.originalClientId || this.config.clientId;
1632
+ sanitized.secret_id = this.config.originalSecretId || this.config.secretId;
1633
+
1634
+ // Debug: Vérifier les credentials
1635
+ console.log('🔍 Credentials dans sanitizeRequestData - clientId:', this.config.clientId);
1636
+ console.log('🔍 Credentials dans sanitizeRequestData - secretId:', this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null');
1637
+ console.log('🔍 Credentials dans sanitizeRequestData - sanitizedClientId:', sanitized.client_id);
1638
+ console.log('🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:', sanitized.secret_id ? '***' + sanitized.secret_id.slice(-4) : 'null');
1639
+ console.log('🔍 Credentials dans sanitizeRequestData - data complet:', JSON.stringify(sanitized, null, 2));
1640
+
1641
+ // Debug: Vérifier les credentials
1642
+ console.log('🔍 Credentials dans sanitizeRequestData - clientId:', this.config.clientId);
1643
+ console.log('🔍 Credentials dans sanitizeRequestData - secretId:', this.config.secretId ? '***' + this.config.secretId.slice(-4) : 'null');
1644
+ console.log('🔍 Credentials dans sanitizeRequestData - sanitizedClientId:', sanitized.client_id);
1645
+ console.log('🔍 Credentials dans sanitizeRequestData - sanitizedSecretId:', sanitized.secret_id ? '***' + sanitized.secret_id.slice(-4) : 'null');
1646
+ console.log('🔍 Credentials dans sanitizeRequestData - data complet:', JSON.stringify(sanitized, null, 2));
1647
+ return sanitized;
1648
+ }
1649
+
1650
+ /**
1651
+ * Générer un ID de requête unique
1652
+ */
1653
+ }, {
1654
+ key: "generateRequestId",
1655
+ value: function generateRequestId() {
1656
+ return 'req_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
1657
+ }
1658
+
1659
+ /**
1660
+ * Appliquer le thème
1661
+ */
834
1662
  }, {
835
1663
  key: "applyTheme",
836
1664
  value: function applyTheme(theme) {
@@ -869,8 +1697,28 @@ function _toPropertyKey(t) {
869
1697
  console.log('🌐 WebSocket déconnecté');
870
1698
  }
871
1699
  this.isInitialized = false;
1700
+ this.logSecurityEvent('SDK_DESTROY');
872
1701
  console.log('SunuID SDK détruit');
873
1702
  }
1703
+
1704
+ /**
1705
+ * Obtenir les logs de sécurité
1706
+ */
1707
+ }, {
1708
+ key: "getSecurityLogs",
1709
+ value: function getSecurityLogs() {
1710
+ return window.SunuIDSecurityLogs || [];
1711
+ }
1712
+
1713
+ /**
1714
+ * Nettoyer les logs de sécurité
1715
+ */
1716
+ }, {
1717
+ key: "clearSecurityLogs",
1718
+ value: function clearSecurityLogs() {
1719
+ window.SunuIDSecurityLogs = [];
1720
+ this.logSecurityEvent('SECURITY_LOGS_CLEARED');
1721
+ }
874
1722
  }]);
875
1723
  }(); // Exposer la classe globalement
876
1724
  window.SunuID = SunuID;