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.
- package/README.md +204 -24
- package/dist/sunuid-sdk.esm.js +1047 -199
- package/dist/sunuid-sdk.esm.js.map +1 -1
- package/dist/sunuid-sdk.js +1047 -199
- package/dist/sunuid-sdk.js.map +1 -1
- package/dist/sunuid-sdk.min.js +3 -3
- package/dist/sunuid-sdk.min.js.map +1 -1
- package/package.json +3 -4
package/dist/sunuid-sdk.js
CHANGED
|
@@ -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:
|
|
211
|
-
// Type par défaut (
|
|
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
|
-
|
|
236
|
-
|
|
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
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
250
|
-
|
|
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
|
-
|
|
253
|
-
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
|
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
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
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 =
|
|
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
|
-
|
|
816
|
+
_context3.n = 3;
|
|
426
817
|
break;
|
|
427
818
|
}
|
|
428
819
|
throw new Error('SunuID: SDK non initialisé');
|
|
429
|
-
case
|
|
430
|
-
|
|
431
|
-
|
|
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
|
|
436
|
-
response =
|
|
826
|
+
case 4:
|
|
827
|
+
response = _context3.v;
|
|
437
828
|
if (!response.success) {
|
|
438
|
-
|
|
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
|
|
868
|
+
return _context3.a(2, _objectSpread2(_objectSpread2({}, response.data), {}, {
|
|
455
869
|
qrCodeUrl: qrImageUrl,
|
|
456
870
|
sessionId: response.data.service_id
|
|
457
871
|
}));
|
|
458
|
-
case
|
|
872
|
+
case 5:
|
|
459
873
|
throw new Error(response.message || 'Erreur lors de la génération du QR code');
|
|
460
|
-
case
|
|
461
|
-
|
|
874
|
+
case 6:
|
|
875
|
+
_context3.n = 8;
|
|
462
876
|
break;
|
|
463
|
-
case
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
console.error('Erreur API détectée:',
|
|
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
|
|
471
|
-
return
|
|
892
|
+
case 8:
|
|
893
|
+
return _context3.a(2);
|
|
472
894
|
}
|
|
473
|
-
},
|
|
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
|
|
909
|
+
var _generateCustomQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(containerId, type) {
|
|
910
|
+
var _this3 = this;
|
|
488
911
|
var options,
|
|
489
|
-
|
|
912
|
+
_response,
|
|
490
913
|
imageBaseUrl,
|
|
491
914
|
qrImageUrl,
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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 =
|
|
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
|
-
|
|
932
|
+
_context4.n = 3;
|
|
500
933
|
break;
|
|
501
934
|
}
|
|
502
935
|
throw new Error('SunuID: SDK non initialisé');
|
|
503
|
-
case
|
|
504
|
-
|
|
505
|
-
|
|
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
|
|
510
|
-
|
|
511
|
-
if (!
|
|
512
|
-
|
|
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(
|
|
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
|
|
975
|
+
return _context4.a(2, _objectSpread2(_objectSpread2({}, _response.data), {}, {
|
|
521
976
|
qrCodeUrl: qrImageUrl,
|
|
522
|
-
sessionId:
|
|
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
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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
|
|
537
|
-
return
|
|
999
|
+
case 8:
|
|
1000
|
+
return _context4.a(2);
|
|
538
1001
|
}
|
|
539
|
-
},
|
|
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
|
|
1013
|
+
var _generateAuthQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(containerId) {
|
|
551
1014
|
var options,
|
|
552
|
-
|
|
553
|
-
return _regenerator().w(function (
|
|
554
|
-
while (1) switch (
|
|
1015
|
+
_args5 = arguments;
|
|
1016
|
+
return _regenerator().w(function (_context5) {
|
|
1017
|
+
while (1) switch (_context5.n) {
|
|
555
1018
|
case 0:
|
|
556
|
-
options =
|
|
557
|
-
return
|
|
1019
|
+
options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
|
|
1020
|
+
return _context5.a(2, this.generateQR(containerId, options));
|
|
558
1021
|
}
|
|
559
|
-
},
|
|
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
|
|
1032
|
+
var _generateKYCQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(containerId) {
|
|
570
1033
|
var options,
|
|
571
1034
|
originalType,
|
|
572
|
-
|
|
573
|
-
return _regenerator().w(function (
|
|
574
|
-
while (1) switch (
|
|
1035
|
+
_args6 = arguments;
|
|
1036
|
+
return _regenerator().w(function (_context6) {
|
|
1037
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
575
1038
|
case 0:
|
|
576
|
-
options =
|
|
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 =
|
|
580
|
-
|
|
581
|
-
|
|
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
|
|
1047
|
+
return _context6.a(2, _context6.v);
|
|
585
1048
|
case 3:
|
|
586
|
-
|
|
1049
|
+
_context6.p = 3;
|
|
587
1050
|
// Restaurer le type original
|
|
588
1051
|
this.config.type = originalType;
|
|
589
|
-
return
|
|
1052
|
+
return _context6.f(3);
|
|
590
1053
|
case 4:
|
|
591
|
-
return
|
|
1054
|
+
return _context6.a(2);
|
|
592
1055
|
}
|
|
593
|
-
},
|
|
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
|
|
607
|
-
var
|
|
608
|
-
return _regenerator().w(function (
|
|
609
|
-
while (1) switch (
|
|
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
|
-
|
|
1109
|
+
_context8.n = 1;
|
|
613
1110
|
break;
|
|
614
1111
|
}
|
|
615
1112
|
throw new Error('SunuID: SDK non initialisé');
|
|
616
1113
|
case 1:
|
|
617
|
-
|
|
618
|
-
|
|
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
|
-
|
|
624
|
-
if (!
|
|
625
|
-
|
|
1120
|
+
_response2 = _context8.v;
|
|
1121
|
+
if (!_response2.success) {
|
|
1122
|
+
_context8.n = 3;
|
|
626
1123
|
break;
|
|
627
1124
|
}
|
|
628
|
-
return
|
|
1125
|
+
return _context8.a(2, _response2.data);
|
|
629
1126
|
case 3:
|
|
630
|
-
throw new Error(
|
|
1127
|
+
throw new Error(_response2.message || 'Erreur lors de la vérification du statut');
|
|
631
1128
|
case 4:
|
|
632
|
-
|
|
1129
|
+
_context8.n = 6;
|
|
633
1130
|
break;
|
|
634
1131
|
case 5:
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
this.handleError(
|
|
638
|
-
throw
|
|
1132
|
+
_context8.p = 5;
|
|
1133
|
+
_t5 = _context8.v;
|
|
1134
|
+
this.handleError(_t5);
|
|
1135
|
+
throw _t5;
|
|
639
1136
|
case 6:
|
|
640
|
-
return
|
|
1137
|
+
return _context8.a(2);
|
|
641
1138
|
}
|
|
642
|
-
},
|
|
1139
|
+
}, _callee8, this, [[1, 5]]);
|
|
643
1140
|
}));
|
|
644
|
-
function checkQRStatus(
|
|
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
|
-
|
|
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
|
|
1352
|
+
var _refreshQR = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0(containerId) {
|
|
697
1353
|
var options,
|
|
698
1354
|
result,
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
return _regenerator().w(function (
|
|
702
|
-
while (1) switch (
|
|
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 =
|
|
705
|
-
|
|
706
|
-
|
|
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 =
|
|
710
|
-
return
|
|
1365
|
+
result = _context0.v;
|
|
1366
|
+
return _context0.a(2, result);
|
|
711
1367
|
case 3:
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
console.error('Erreur lors du rafraîchissement:',
|
|
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
|
|
1372
|
+
throw _t7;
|
|
717
1373
|
case 4:
|
|
718
|
-
return
|
|
1374
|
+
return _context0.a(2);
|
|
719
1375
|
}
|
|
720
|
-
},
|
|
1376
|
+
}, _callee0, this, [[1, 3]]);
|
|
721
1377
|
}));
|
|
722
|
-
function refreshQR(
|
|
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
|
|
1390
|
+
var _this4 = this;
|
|
735
1391
|
if (!this.config.autoRefresh) return;
|
|
736
|
-
this.refreshTimer = setInterval(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
737
|
-
var
|
|
738
|
-
return _regenerator().w(function (
|
|
739
|
-
while (1) switch (
|
|
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
|
-
|
|
742
|
-
|
|
743
|
-
return
|
|
1397
|
+
_context1.p = 0;
|
|
1398
|
+
_context1.n = 1;
|
|
1399
|
+
return _this4.refreshQR(containerId, type, options);
|
|
744
1400
|
case 1:
|
|
745
|
-
|
|
1401
|
+
_context1.n = 3;
|
|
746
1402
|
break;
|
|
747
1403
|
case 2:
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
console.warn('Erreur lors du rafraîchissement automatique:',
|
|
1404
|
+
_context1.p = 2;
|
|
1405
|
+
_t8 = _context1.v;
|
|
1406
|
+
console.warn('Erreur lors du rafraîchissement automatique:', _t8);
|
|
751
1407
|
case 3:
|
|
752
|
-
return
|
|
1408
|
+
return _context1.a(2);
|
|
753
1409
|
}
|
|
754
|
-
},
|
|
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
|
|
769
|
-
var _window$SunuIDConfig2
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
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
|
-
|
|
775
|
-
|
|
776
|
-
|
|
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
|
-
|
|
781
|
-
|
|
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
|
-
|
|
795
|
-
|
|
796
|
-
if (
|
|
797
|
-
|
|
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
|
-
|
|
801
|
-
|
|
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
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
} catch (e) {
|
|
807
|
-
errorData = {
|
|
808
|
-
message: errorText
|
|
809
|
-
};
|
|
1580
|
+
if (!(retryCount <= maxRetries)) {
|
|
1581
|
+
_context11.n = 7;
|
|
1582
|
+
break;
|
|
810
1583
|
}
|
|
811
|
-
|
|
1584
|
+
return _context11.d(_regeneratorValues(_loop()), 4);
|
|
812
1585
|
case 4:
|
|
813
|
-
|
|
814
|
-
|
|
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
|
-
|
|
817
|
-
|
|
1593
|
+
if (!_ret) {
|
|
1594
|
+
_context11.n = 6;
|
|
1595
|
+
break;
|
|
1596
|
+
}
|
|
1597
|
+
return _context11.a(2, _ret.v);
|
|
818
1598
|
case 6:
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
console.error('Erreur API SunuID:', _t6);
|
|
822
|
-
throw _t6;
|
|
1599
|
+
_context11.n = 3;
|
|
1600
|
+
break;
|
|
823
1601
|
case 7:
|
|
824
|
-
return
|
|
1602
|
+
return _context11.a(2);
|
|
825
1603
|
}
|
|
826
|
-
},
|
|
1604
|
+
}, _callee10, this);
|
|
827
1605
|
}));
|
|
828
|
-
function makeRequest(
|
|
1606
|
+
function makeRequest(_x1, _x10) {
|
|
829
1607
|
return _makeRequest.apply(this, arguments);
|
|
830
1608
|
}
|
|
831
1609
|
return makeRequest;
|
|
832
1610
|
}()
|
|
833
1611
|
/**
|
|
834
|
-
*
|
|
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;
|