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