sunuid-sdk 1.0.51 → 1.0.53

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.
@@ -0,0 +1,250 @@
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SunuID - Exemple Sans Boucle</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ max-width: 800px;
11
+ margin: 0 auto;
12
+ padding: 20px;
13
+ background: #f5f5f5;
14
+ }
15
+ .container {
16
+ background: white;
17
+ padding: 30px;
18
+ border-radius: 10px;
19
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
20
+ }
21
+ .status {
22
+ padding: 15px;
23
+ border-radius: 5px;
24
+ margin: 10px 0;
25
+ }
26
+ .success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
27
+ .error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
28
+ .info { background: #d1ecf1; color: #0c5460; border: 1px solid #bee5eb; }
29
+ .warning { background: #fff3cd; color: #856404; border: 1px solid #ffeaa7; }
30
+ .qr-container {
31
+ text-align: center;
32
+ margin: 20px 0;
33
+ padding: 20px;
34
+ border: 2px dashed #ccc;
35
+ border-radius: 10px;
36
+ }
37
+ button {
38
+ background: #007bff;
39
+ color: white;
40
+ border: none;
41
+ padding: 10px 20px;
42
+ border-radius: 5px;
43
+ cursor: pointer;
44
+ margin: 5px;
45
+ }
46
+ button:hover { background: #0056b3; }
47
+ button:disabled { background: #6c757d; cursor: not-allowed; }
48
+ .hidden { display: none; }
49
+ .log {
50
+ background: #f8f9fa;
51
+ padding: 10px;
52
+ border-radius: 5px;
53
+ font-family: monospace;
54
+ font-size: 12px;
55
+ max-height: 200px;
56
+ overflow-y: auto;
57
+ margin: 10px 0;
58
+ }
59
+ </style>
60
+ </head>
61
+ <body>
62
+ <div class="container">
63
+ <h1>🔧 SunuID - Exemple Sans Boucle</h1>
64
+
65
+ <div id="status" class="status info">
66
+ Prêt à initialiser le SDK...
67
+ </div>
68
+
69
+ <div id="controls">
70
+ <button id="initBtn" onclick="initSDK()">🚀 Initialiser SDK</button>
71
+ <button id="qrBtn" onclick="generateQR()" disabled>📱 Générer QR</button>
72
+ <button id="destroyBtn" onclick="destroySDK()" disabled>🗑️ Détruire SDK</button>
73
+ </div>
74
+
75
+ <div id="qr-section" class="hidden">
76
+ <h2>📱 QR Code</h2>
77
+ <div id="qr-area" class="qr-container">
78
+ <!-- Le QR code sera affiché ici -->
79
+ </div>
80
+ </div>
81
+
82
+ <div id="logs">
83
+ <h3>📋 Logs</h3>
84
+ <div id="logContainer" class="log">
85
+ <!-- Les logs seront affichés ici -->
86
+ </div>
87
+ <button onclick="clearLogs()">🧹 Nettoyer logs</button>
88
+ </div>
89
+ </div>
90
+
91
+ <!-- Socket.IO -->
92
+ <script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
93
+
94
+ <!-- SunuID SDK -->
95
+ <script src="../../dist/sunuid-sdk.min.js"></script>
96
+
97
+ <script>
98
+ // Variables globales
99
+ let sunuid = null;
100
+ let initCount = 0;
101
+
102
+ // Configuration du SDK
103
+ const config = {
104
+ apiUrl: 'https://api.sunuid.fayma.sn',
105
+ clientId: '1754166754_221A57B46843D755',
106
+ secretId: '56d40fe70507228b27f2640ae65894177c2fedbf246e2b30978fde1fc43953c5',
107
+ type: 2, // AUTH
108
+ theme: 'light',
109
+ language: 'fr',
110
+
111
+ // IMPORTANT: autoInit désactivé
112
+ autoInit: false,
113
+
114
+ // Callbacks
115
+ onSuccess: function(data) {
116
+ log('🎉 Succès: ' + JSON.stringify(data));
117
+ updateStatus('Succès: ' + JSON.stringify(data), 'success');
118
+ },
119
+
120
+ onError: function(error) {
121
+ log('❌ Erreur: ' + error.message);
122
+ updateStatus('Erreur: ' + error.message, 'error');
123
+ },
124
+
125
+ onStatusUpdate: function(status) {
126
+ log('📊 Statut: ' + status);
127
+ updateStatus('Statut: ' + status, 'info');
128
+ }
129
+ };
130
+
131
+ // Fonction de log personnalisée
132
+ function log(message) {
133
+ const timestamp = new Date().toLocaleTimeString();
134
+ const logContainer = document.getElementById('logContainer');
135
+ logContainer.innerHTML += `[${timestamp}] ${message}\n`;
136
+ logContainer.scrollTop = logContainer.scrollHeight;
137
+ console.log(message);
138
+ }
139
+
140
+ // Fonction de mise à jour du statut
141
+ function updateStatus(message, type) {
142
+ const statusEl = document.getElementById('status');
143
+ statusEl.textContent = message;
144
+ statusEl.className = `status ${type}`;
145
+ }
146
+
147
+ // Fonction d'initialisation du SDK
148
+ async function initSDK() {
149
+ try {
150
+ initCount++;
151
+ log(`🔄 Tentative d'initialisation #${initCount}`);
152
+
153
+ // Vérifier si déjà initialisé
154
+ if (sunuid && sunuid.isInitialized) {
155
+ log('⚠️ SDK déjà initialisé, ignoré');
156
+ updateStatus('SDK déjà initialisé', 'warning');
157
+ return;
158
+ }
159
+
160
+ // Créer une nouvelle instance
161
+ log('🔧 Création nouvelle instance SDK...');
162
+ sunuid = new SunuID(config);
163
+
164
+ // Initialisation manuelle
165
+ log('🚀 Initialisation manuelle...');
166
+ await sunuid.init();
167
+
168
+ log('✅ SDK initialisé avec succès !');
169
+ updateStatus('SDK initialisé avec succès', 'success');
170
+
171
+ // Activer les boutons
172
+ document.getElementById('qrBtn').disabled = false;
173
+ document.getElementById('destroyBtn').disabled = false;
174
+ document.getElementById('initBtn').disabled = true;
175
+
176
+ } catch (error) {
177
+ log('❌ Erreur lors de l\'initialisation: ' + error.message);
178
+ updateStatus('Erreur d\'initialisation: ' + error.message, 'error');
179
+ }
180
+ }
181
+
182
+ // Fonction de génération de QR
183
+ async function generateQR() {
184
+ try {
185
+ if (!sunuid || !sunuid.isInitialized) {
186
+ log('⚠️ SDK non initialisé');
187
+ updateStatus('SDK non initialisé', 'warning');
188
+ return;
189
+ }
190
+
191
+ log('📱 Génération du QR code...');
192
+ document.getElementById('qr-section').classList.remove('hidden');
193
+
194
+ const result = await sunuid.generateQR('qr-area');
195
+ log('✅ QR code généré: ' + JSON.stringify(result));
196
+ updateStatus('QR code généré avec succès', 'success');
197
+
198
+ } catch (error) {
199
+ log('❌ Erreur génération QR: ' + error.message);
200
+ updateStatus('Erreur génération QR: ' + error.message, 'error');
201
+ }
202
+ }
203
+
204
+ // Fonction de destruction du SDK
205
+ function destroySDK() {
206
+ try {
207
+ if (sunuid) {
208
+ log('🗑️ Destruction du SDK...');
209
+ sunuid.destroy();
210
+ sunuid = null;
211
+
212
+ log('✅ SDK détruit');
213
+ updateStatus('SDK détruit', 'info');
214
+
215
+ // Réinitialiser l'interface
216
+ document.getElementById('qrBtn').disabled = true;
217
+ document.getElementById('destroyBtn').disabled = true;
218
+ document.getElementById('initBtn').disabled = false;
219
+ document.getElementById('qr-section').classList.add('hidden');
220
+ document.getElementById('qr-area').innerHTML = '';
221
+
222
+ } else {
223
+ log('⚠️ Aucun SDK à détruire');
224
+ }
225
+ } catch (error) {
226
+ log('❌ Erreur destruction: ' + error.message);
227
+ }
228
+ }
229
+
230
+ // Fonction de nettoyage des logs
231
+ function clearLogs() {
232
+ document.getElementById('logContainer').innerHTML = '';
233
+ log('🧹 Logs nettoyés');
234
+ }
235
+
236
+ // Initialisation au chargement de la page
237
+ document.addEventListener('DOMContentLoaded', function() {
238
+ log('📄 Page chargée - Prêt à initialiser le SDK');
239
+ updateStatus('Prêt à initialiser le SDK', 'info');
240
+ });
241
+
242
+ // Exposer globalement pour debug
243
+ window.sunuid = sunuid;
244
+ window.initSDK = initSDK;
245
+ window.generateQR = generateQR;
246
+ window.destroySDK = destroySDK;
247
+ window.clearLogs = clearLogs;
248
+ </script>
249
+ </body>
250
+ </html>
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Configuration SunuID SDK - Personnalisation du Nom du Partenaire
3
+ *
4
+ * Ce fichier montre comment configurer le SDK pour afficher le nom
5
+ * de votre entreprise au lieu de "SunuID" dans les labels et textes.
6
+ */
7
+
8
+ // Configuration pour la production avec nom personnalisé
9
+ window.SunuIDConfig = {
10
+ // URL de l'API de production
11
+ apiUrl: 'https://api.sunuid.fayma.sn',
12
+
13
+ // Endpoints spécifiques
14
+ endpoints: {
15
+ qrGenerate: '/qr-generate',
16
+ qrStatus: '/qr-status',
17
+ qrConfirm: '/qr-confirm',
18
+ debug: '/debug',
19
+ test: '/test-sdk'
20
+ }
21
+ };
22
+
23
+ // Exemple 1: Banque
24
+ const banqueConfig = {
25
+ clientId: 'banque_client_id',
26
+ secretId: 'banque_secret_id',
27
+ type: 2, // Authentification
28
+ partnerName: 'Ma Banque', // Nom personnalisé
29
+ theme: 'light',
30
+ language: 'fr',
31
+
32
+ // Configuration pour la production
33
+ apiUrl: 'https://api.sunuid.fayma.sn',
34
+ secureInitUrl: 'https://sunuid.fayma.sn/secure-init',
35
+
36
+ // Callbacks
37
+ onSuccess: (data) => {
38
+ console.log('Authentification réussie avec Ma Banque:', data);
39
+ },
40
+ onError: (error) => {
41
+ console.error('Erreur Ma Banque:', error);
42
+ }
43
+ };
44
+
45
+ // Exemple 2: E-commerce
46
+ const ecommerceConfig = {
47
+ clientId: 'ecommerce_client_id',
48
+ secretId: 'ecommerce_secret_id',
49
+ type: 2, // Authentification
50
+ partnerName: 'MonShop', // Nom personnalisé
51
+ theme: 'dark',
52
+ language: 'fr',
53
+
54
+ // Configuration pour la production
55
+ apiUrl: 'https://api.sunuid.fayma.sn',
56
+ secureInitUrl: 'https://sunuid.fayma.sn/secure-init',
57
+
58
+ // Callbacks
59
+ onSuccess: (data) => {
60
+ console.log('Authentification réussie avec MonShop:', data);
61
+ },
62
+ onError: (error) => {
63
+ console.error('Erreur MonShop:', error);
64
+ }
65
+ };
66
+
67
+ // Exemple 3: Administration
68
+ const adminConfig = {
69
+ clientId: 'admin_client_id',
70
+ secretId: 'admin_secret_id',
71
+ type: 1, // KYC
72
+ partnerName: 'Gouvernement', // Nom personnalisé
73
+ theme: 'light',
74
+ language: 'fr',
75
+
76
+ // Configuration pour la production
77
+ apiUrl: 'https://api.sunuid.fayma.sn',
78
+ secureInitUrl: 'https://sunuid.fayma.sn/secure-init',
79
+
80
+ // Callbacks
81
+ onSuccess: (data) => {
82
+ console.log('KYC réussi avec Gouvernement:', data);
83
+ },
84
+ onError: (error) => {
85
+ console.error('Erreur Gouvernement:', error);
86
+ }
87
+ };
88
+
89
+ // Initialisation avec configuration personnalisée
90
+ function initSunuIDWithPartnerName(config) {
91
+ const sunuid = new SunuID(config);
92
+
93
+ sunuid.init().then(() => {
94
+ console.log(`SDK initialisé pour ${config.partnerName}`);
95
+
96
+ // Exemple d'utilisation
97
+ sunuid.generateQR('qr-container', {
98
+ theme: config.theme,
99
+ onSuccess: config.onSuccess,
100
+ onError: config.onError
101
+ });
102
+
103
+ }).catch(error => {
104
+ console.error(`Erreur d'initialisation pour ${config.partnerName}:`, error);
105
+ });
106
+
107
+ return sunuid;
108
+ }
109
+
110
+ // Utilisation
111
+ // initSunuIDWithPartnerName(banqueConfig);
112
+ // initSunuIDWithPartnerName(ecommerceConfig);
113
+ // initSunuIDWithPartnerName(adminConfig);
114
+
115
+ // Export pour utilisation dans d'autres fichiers
116
+ if (typeof module !== 'undefined' && module.exports) {
117
+ module.exports = {
118
+ banqueConfig,
119
+ ecommerceConfig,
120
+ adminConfig,
121
+ initSunuIDWithPartnerName
122
+ };
123
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Configuration SunuID SDK pour la Production
3
+ *
4
+ * Ce fichier montre comment configurer le SDK pour la production
5
+ * en remplaçant les URLs locales par les URLs de production.
6
+ */
7
+
8
+ // Configuration pour la production
9
+ window.SunuIDConfig = {
10
+ // URL de l'API de production
11
+ apiUrl: 'https://api.sunuid.fayma.sn',
12
+
13
+ // Endpoints spécifiques
14
+ endpoints: {
15
+ qrGenerate: '/qr-generate',
16
+ qrStatus: '/qr-status',
17
+ qrConfirm: '/qr-confirm',
18
+ debug: '/debug',
19
+ test: '/test-sdk'
20
+ },
21
+
22
+ // Configuration par défaut
23
+ defaultConfig: {
24
+ theme: 'light',
25
+ language: 'fr',
26
+ autoRefresh: true,
27
+ refreshInterval: 30000, // 30 secondes
28
+ qrSize: 300,
29
+ qrMargin: 10
30
+ }
31
+ };
32
+
33
+ // Exemple d'utilisation en production
34
+ const sunuid = new SunuID({
35
+ clientId: 'votre_client_id',
36
+ secretId: 'votre_secret_id',
37
+ type: 2, // Authentification
38
+ partnerName: 'Votre Entreprise',
39
+ theme: 'light',
40
+ language: 'fr',
41
+
42
+ // Configuration pour la production
43
+ apiUrl: 'https://api.sunuid.fayma.sn',
44
+ secureInitUrl: 'https://sunuid.fayma.sn/secure-init',
45
+
46
+ // Callbacks
47
+ onSuccess: (data) => {
48
+ console.log('Authentification réussie:', data);
49
+ },
50
+ onError: (error) => {
51
+ console.error('Erreur:', error);
52
+ }
53
+ });
54
+
55
+ // Initialisation
56
+ sunuid.init().then(() => {
57
+ console.log('SDK initialisé pour la production');
58
+ }).catch(error => {
59
+ console.error('Erreur d\'initialisation:', error);
60
+ });
@@ -0,0 +1,154 @@
1
+ <?php
2
+ /**
3
+ * SunuID SDK - Endpoint d'initialisation sécurisée
4
+ *
5
+ * Ce fichier permet au SDK JavaScript de récupérer des tokens temporaires
6
+ * contenant les credentials sans les exposer directement dans le code client.
7
+ *
8
+ * IMPORTANT :
9
+ * - Remplacez les credentials par vos vrais credentials
10
+ * - Stockez ce fichier en dehors du répertoire public si possible
11
+ * - Utilisez des variables d'environnement en production
12
+ */
13
+
14
+ // Headers CORS pour permettre les requêtes depuis le SDK JavaScript
15
+ header('Content-Type: application/json');
16
+ header('Access-Control-Allow-Origin: *');
17
+ header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
18
+ header('Access-Control-Allow-Headers: Content-Type, Authorization');
19
+
20
+ // Gérer les requêtes OPTIONS (preflight)
21
+ if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
22
+ http_response_code(200);
23
+ exit();
24
+ }
25
+
26
+ // Configuration SunuID (à remplacer par vos vrais credentials)
27
+ $SUNUID_CONFIG = [
28
+ 'client_id' => $_ENV['SUNUID_CLIENT_ID'] ?? 'your_client_id_here',
29
+ 'secret_id' => $_ENV['SUNUID_SECRET_ID'] ?? 'your_secret_id_here',
30
+ 'api_url' => $_ENV['SUNUID_API_URL'] ?? 'https://api.sunuid.fayma.sn',
31
+ 'token_expiry' => $_ENV['SUNUID_TOKEN_EXPIRY'] ?? 300, // 5 minutes
32
+ 'max_requests' => $_ENV['SUNUID_MAX_REQUESTS'] ?? 10
33
+ ];
34
+
35
+ /**
36
+ * Valider les paramètres d'initialisation
37
+ */
38
+ function validateInitParams($data) {
39
+ $required = ['timestamp', 'nonce'];
40
+
41
+ foreach ($required as $field) {
42
+ if (!isset($data[$field])) {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ // Vérifier que le timestamp n'est pas trop ancien (5 minutes)
48
+ if (time() - $data['timestamp'] > 300) {
49
+ return false;
50
+ }
51
+
52
+ return true;
53
+ }
54
+
55
+ /**
56
+ * Générer un token sécurisé contenant les credentials
57
+ */
58
+ function generateSecureToken($config) {
59
+ $payload = [
60
+ 'client_id' => $config['client_id'],
61
+ 'secret_id' => $config['secret_id'],
62
+ 'api_url' => $config['api_url'],
63
+ 'exp' => time() + $config['token_expiry'],
64
+ 'iat' => time(),
65
+ 'nonce' => bin2hex(random_bytes(16))
66
+ ];
67
+
68
+ // Encoder en base64 pour simplicité
69
+ // En production, utilisez JWT ou un chiffrement plus robuste
70
+ return base64_encode(json_encode($payload));
71
+ }
72
+
73
+ /**
74
+ * Valider un token reçu
75
+ */
76
+ function validateToken($token) {
77
+ try {
78
+ $decoded = json_decode(base64_decode($token), true);
79
+
80
+ if (!$decoded) {
81
+ return false;
82
+ }
83
+
84
+ // Vérifier l'expiration
85
+ if (isset($decoded['exp']) && $decoded['exp'] < time()) {
86
+ return false;
87
+ }
88
+
89
+ return $decoded;
90
+ } catch (Exception $e) {
91
+ return false;
92
+ }
93
+ }
94
+
95
+ // Traitement des requêtes
96
+ $method = $_SERVER['REQUEST_METHOD'];
97
+ $input = json_decode(file_get_contents('php://input'), true) ?? [];
98
+
99
+ try {
100
+ switch ($method) {
101
+ case 'POST':
102
+ // Générer un token pour l'initialisation sécurisée
103
+ if (!validateInitParams($input)) {
104
+ throw new Exception('Paramètres invalides');
105
+ }
106
+
107
+ $token = generateSecureToken($SUNUID_CONFIG);
108
+
109
+ echo json_encode([
110
+ 'success' => true,
111
+ 'token' => $token,
112
+ 'expires_in' => $SUNUID_CONFIG['token_expiry'],
113
+ 'timestamp' => time()
114
+ ]);
115
+ break;
116
+
117
+ case 'GET':
118
+ // Valider un token (pour usage côté serveur)
119
+ $token = $_GET['token'] ?? null;
120
+
121
+ if (!$token) {
122
+ throw new Exception('Token manquant');
123
+ }
124
+
125
+ $decoded = validateToken($token);
126
+
127
+ if (!$decoded) {
128
+ throw new Exception('Token invalide ou expiré');
129
+ }
130
+
131
+ echo json_encode([
132
+ 'success' => true,
133
+ 'credentials' => [
134
+ 'client_id' => $decoded['client_id'],
135
+ 'secret_id' => $decoded['secret_id'],
136
+ 'api_url' => $decoded['api_url']
137
+ ],
138
+ 'expires_at' => $decoded['exp']
139
+ ]);
140
+ break;
141
+
142
+ default:
143
+ throw new Exception('Méthode non supportée');
144
+ }
145
+
146
+ } catch (Exception $e) {
147
+ http_response_code(400);
148
+ echo json_encode([
149
+ 'success' => false,
150
+ 'error' => $e->getMessage(),
151
+ 'timestamp' => time()
152
+ ]);
153
+ }
154
+ ?>