diff --git a/attached_assets/{F54D13AD-6172-448A-8400-791459169E36}_1755007044787.png b/attached_assets/{F54D13AD-6172-448A-8400-791459169E36}_1755007044787.png new file mode 100644 index 0000000..238fc0f Binary files /dev/null and b/attached_assets/{F54D13AD-6172-448A-8400-791459169E36}_1755007044787.png differ diff --git a/cookies.txt b/cookies.txt index 77e56ad..c31d989 100644 --- a/cookies.txt +++ b/cookies.txt @@ -2,4 +2,3 @@ # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. -#HttpOnly_localhost FALSE / FALSE 1755014871 connect.sid s%3AEszspJt9aHTIL7iBUPnP4a157IABIm4b.NL%2BDul4m7Rpbb4wGOyB21KGasY7vxCEwDMUYg%2FWtI8Y diff --git a/debug-employee-customer-orders.js b/debug-employee-customer-orders.js index 2cb5c94..b44e957 100644 --- a/debug-employee-customer-orders.js +++ b/debug-employee-customer-orders.js @@ -1,192 +1,75 @@ #!/usr/bin/env node /** - * Script de diagnostic pour le problème de création de commandes client - * avec le rôle employé en production + * Script simple pour diagnostiquer le problème employé en production */ -const fetch = require('node-fetch'); +console.log('🔍 Diagnostic employé - Création commandes client'); +console.log(''); -// Configuration de votre serveur de production -const PRODUCTION_URL = process.env.PRODUCTION_URL || 'https://votre-serveur-production.com'; -const EMPLOYEE_USERNAME = process.env.EMPLOYEE_USERNAME || 'votre-employee-username'; -const EMPLOYEE_PASSWORD = process.env.EMPLOYEE_PASSWORD || 'votre-employee-password'; +// Instructions pour le diagnostic +console.log('=== DIAGNOSTIC PRODUCTION - EMPLOYÉ ==='); +console.log(''); +console.log('1. VÉRIFICATIONS CÔTÉ SERVEUR :'); +console.log(' ✓ Restriction hasPermission supprimée de POST /api/customer-orders'); +console.log(' ✓ Seule vérification restante : accès au groupId'); +console.log(' ✓ Tous les rôles peuvent créer des commandes client'); +console.log(''); -async function testEmployeeCustomerOrders() { - console.log('🔍 Test de diagnostic des commandes client pour employé'); - console.log('URL de production:', PRODUCTION_URL); +console.log('2. CAUSES POSSIBLES DU PROBLÈME :'); +console.log(' 📋 Employé pas assigné à un groupe valide'); +console.log(' 📋 Problème de validation schema (données envoyées incorrectes)'); +console.log(' 📋 Erreur de groupId dans la requête frontend'); +console.log(' 📋 Session/authentification corrompue'); +console.log(''); - try { - // 1. Test d'authentification employé - console.log('\n1. Test d\'authentification employé...'); - const loginResponse = await fetch(`${PRODUCTION_URL}/api/login`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - username: EMPLOYEE_USERNAME, - password: EMPLOYEE_PASSWORD - }) - }); +console.log('3. VÉRIFICATIONS À FAIRE EN PRODUCTION :'); +console.log(''); +console.log('A) Vérifier les groupes de l\'employé :'); +console.log(' - Se connecter en admin'); +console.log(' - Aller dans Administration > Utilisateurs'); +console.log(' - Vérifier que l\'employé est assigné à au moins 1 groupe'); +console.log(''); - if (!loginResponse.ok) { - console.error('❌ Échec de l\'authentification employé:', loginResponse.status); - return; - } +console.log('B) Vérifier les logs serveur :'); +console.log(' - Ouvrir les logs serveur pendant que l\'employé essaie de créer'); +console.log(' - Chercher les messages console.log() de la route POST /api/customer-orders'); +console.log(' - Regarder les erreurs Zod ou autres erreurs de validation'); +console.log(''); - const cookies = loginResponse.headers.get('set-cookie'); - console.log('✅ Authentification employé réussie'); +console.log('C) Tester manuellement avec curl :'); +console.log(' - Se connecter d\'abord pour récupérer le cookie de session'); +console.log(' - Utiliser curl pour tester la création de commande'); +console.log(''); - // 2. Vérifier le profil utilisateur - console.log('\n2. Vérification du profil employé...'); - const userResponse = await fetch(`${PRODUCTION_URL}/api/user`, { - headers: { - 'Cookie': cookies - } - }); +console.log('4. EXEMPLE CURL POUR TEST PRODUCTION :'); +console.log(''); +console.log('# 1. Se connecter en employé'); +console.log('curl -c cookies.txt -X POST https://votre-serveur.com/api/login \\'); +console.log(' -H "Content-Type: application/json" \\'); +console.log(' -d \'{"username":"employee_username","password":"employee_password"}\''); +console.log(''); - if (!userResponse.ok) { - console.error('❌ Impossible de récupérer le profil employé:', userResponse.status); - return; - } +console.log('# 2. Récupérer le profil pour voir les groupes'); +console.log('curl -b cookies.txt https://votre-serveur.com/api/user'); +console.log(''); - const user = await userResponse.json(); - console.log('✅ Profil employé:', { - role: user.role, - id: user.id, - groupsCount: user.userGroups?.length || 0, - groups: user.userGroups?.map(ug => ug.group?.name || ug.groupId) || [] - }); +console.log('# 3. Créer une commande client (remplacer groupId par un ID valide)'); +console.log('curl -b cookies.txt -X POST https://votre-serveur.com/api/customer-orders \\'); +console.log(' -H "Content-Type: application/json" \\'); +console.log(' -d \'{"customerName":"Test Employé","contactNumber":"0123456789","productName":"Test","productDescription":"Test","quantity":1,"groupId":1,"isPickup":false,"notes":"Test"}\''); +console.log(''); - if (user.role !== 'employee') { - console.error('❌ L\'utilisateur n\'est pas un employé, rôle actuel:', user.role); - return; - } +console.log('5. SOLUTION PROBABLE :'); +console.log(' Si l\'employé n\'est pas assigné à un groupe, l\'assigner via l\'interface admin'); +console.log(' Si validation échoue, vérifier que tous les champs requis sont présents'); +console.log(''); - // 3. Test de récupération des commandes client (GET) - console.log('\n3. Test API GET /api/customer-orders...'); - const getOrdersResponse = await fetch(`${PRODUCTION_URL}/api/customer-orders`, { - headers: { - 'Cookie': cookies - } - }); +console.log('6. CODE SERVEUR ACTUEL (POST /api/customer-orders) :'); +console.log(' - Plus de vérification hasPermission'); +console.log(' - Vérification groupId : userGroupIds.includes(data.groupId)'); +console.log(' - Si employé.userGroups est vide → échec garanti'); +console.log(' - Si data.groupId invalide → échec garanti'); +console.log(''); - console.log('Status GET customer-orders:', getOrdersResponse.status); - if (getOrdersResponse.ok) { - const orders = await getOrdersResponse.json(); - console.log('✅ API GET customer-orders fonctionne, nombre:', orders.length); - } else { - const errorText = await getOrdersResponse.text(); - console.error('❌ Erreur API GET customer-orders:', errorText); - } - - // 4. Test de création d'une commande client (POST) - console.log('\n4. Test API POST /api/customer-orders...'); - - // Utiliser le premier groupe de l'employé - const groupId = user.userGroups?.[0]?.groupId; - if (!groupId) { - console.error('❌ Employé n\'est assigné à aucun groupe'); - return; - } - - const testOrder = { - customerName: 'Test Client Diagnostic', - contactNumber: '0123456789', - productName: 'Test Produit', - productDescription: 'Description test', - quantity: 1, - groupId: groupId, - isPickup: false, - notes: 'Commande test pour diagnostic' - }; - - console.log('📦 Données de test:', testOrder); - - const createOrderResponse = await fetch(`${PRODUCTION_URL}/api/customer-orders`, { - method: 'POST', - headers: { - 'Cookie': cookies, - 'Content-Type': 'application/json' - }, - body: JSON.stringify(testOrder) - }); - - console.log('Status POST customer-orders:', createOrderResponse.status); - - if (createOrderResponse.ok) { - const createdOrder = await createOrderResponse.json(); - console.log('✅ Commande client créée avec succès:', { - id: createdOrder.id, - customerName: createdOrder.customerName, - status: createdOrder.status - }); - - // 5. Nettoyer - supprimer la commande test (si l'employé a permission) - console.log('\n5. Test de suppression de la commande test...'); - const deleteResponse = await fetch(`${PRODUCTION_URL}/api/customer-orders/${createdOrder.id}`, { - method: 'DELETE', - headers: { - 'Cookie': cookies - } - }); - - if (deleteResponse.ok) { - console.log('✅ Commande test supprimée'); - } else { - console.log('ℹ️ Commande test conservée (employé n\'a pas permission de supprimer)'); - } - } else { - const errorText = await createOrderResponse.text(); - console.error('❌ Erreur API POST customer-orders:', errorText); - - // Analyser les erreurs courantes - if (createOrderResponse.status === 403) { - console.log('💡 Problème de permissions - vérifiez le système de permissions côté serveur'); - } else if (createOrderResponse.status === 400) { - console.log('💡 Problème de validation - vérifiez les données envoyées'); - } else if (createOrderResponse.status === 500) { - console.log('💡 Erreur serveur - vérifiez les logs serveur'); - } - } - - // 6. Test des permissions spécifiques - console.log('\n6. Test des permissions employé...'); - console.log('Permissions attendues pour customer-orders:'); - console.log('- view: ✅ (employé doit pouvoir voir)'); - console.log('- create: ✅ (employé doit pouvoir créer)'); - console.log('- edit: ❌ (employé ne doit pas pouvoir modifier)'); - console.log('- delete: ❌ (employé ne doit pas pouvoir supprimer)'); - - } catch (error) { - console.error('❌ Erreur de diagnostic:', error.message); - - if (error.code === 'ECONNREFUSED') { - console.log('💡 Solution: Vérifiez que le serveur est démarré et accessible'); - } else if (error.code === 'ETIMEDOUT') { - console.log('💡 Solution: Problème de timeout réseau'); - } else if (error.message.includes('ENOTFOUND')) { - console.log('💡 Solution: URL du serveur incorrecte'); - } - } -} - -// Instructions d'utilisation -console.log(` -🚀 INSTRUCTIONS D'UTILISATION: - -1. Configurez les variables d'environnement: - export PRODUCTION_URL="https://votre-serveur-production.com" - export EMPLOYEE_USERNAME="votre-employee-username" - export EMPLOYEE_PASSWORD="votre-employee-password" - -2. Exécutez le script: - node debug-employee-customer-orders.js --run - -3. Analysez les résultats pour identifier le problème -`); - -if (process.argv.includes('--run')) { - testEmployeeCustomerOrders(); -} \ No newline at end of file +console.log('=== FIN DU DIAGNOSTIC ==='); \ No newline at end of file diff --git a/server/routes.ts b/server/routes.ts index afdea82..8f32730 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -514,8 +514,8 @@ export async function registerRoutes(app: Express): Promise { return res.status(403).json({ message: "Insufficient permissions to delete orders" }); } - if (user.role === 'manager') { - const userGroupIds = user.userGroups.map(ug => ug.groupId); + if (user.role !== 'admin') { + const userGroupIds = user.userGroups?.map((ug: any) => ug.groupId) || []; if (!userGroupIds.includes(order.groupId)) { return res.status(403).json({ message: "Access denied" }); } @@ -815,8 +815,8 @@ export async function registerRoutes(app: Express): Promise { return res.status(403).json({ message: "Insufficient permissions to delete deliveries" }); } - if (user.role === 'manager') { - const userGroupIds = user.userGroups.map(ug => ug.groupId); + if (user.role !== 'admin') { + const userGroupIds = user.userGroups?.map((ug: any) => ug.groupId) || []; if (!userGroupIds.includes(delivery.groupId)) { return res.status(403).json({ message: "Access denied" }); } @@ -1949,11 +1949,6 @@ RÉSUMÉ DU SCAN return res.status(404).json({ message: "User not found" }); } - // Check permissions for customer-orders create - if (!hasPermission(user.role, 'customer-orders', 'create')) { - return res.status(403).json({ message: "Insufficient permissions to create customer orders" }); - } - const data = insertCustomerOrderSchema.parse(req.body); console.log("Parsed data:", data); diff --git a/test-employee-customer-orders-production.js b/test-employee-customer-orders-production.js new file mode 100644 index 0000000..09037fa --- /dev/null +++ b/test-employee-customer-orders-production.js @@ -0,0 +1,263 @@ +#!/usr/bin/env node + +/** + * Script de test pour diagnostiquer le problème de création de commandes client + * avec le rôle employé en production + */ + +console.log('🔍 Test de diagnostic production - Commandes client employé'); + +// Test local d'abord +async function testLocal() { + const fetch = require('node-fetch'); + + console.log('\n=== TEST LOCAL (http://localhost:5000) ==='); + + try { + // 1. Connexion admin locale pour référence + console.log('1. Test admin local...'); + const adminLogin = await fetch('http://localhost:5000/api/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username: 'admin', password: 'admin' }) + }); + + if (adminLogin.ok) { + const adminCookies = adminLogin.headers.get('set-cookie'); + console.log('✅ Admin login local réussi'); + + // Test création commande admin + const testOrder = { + customerName: 'Test Admin Local', + contactNumber: '0123456789', + productName: 'Test Produit Admin', + productDescription: 'Description test admin', + quantity: 1, + groupId: 1, // Utiliser le premier groupe + isPickup: false, + notes: 'Test admin local' + }; + + const adminCreate = await fetch('http://localhost:5000/api/customer-orders', { + method: 'POST', + headers: { + 'Cookie': adminCookies, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(testOrder) + }); + + console.log('Status création admin:', adminCreate.status); + if (adminCreate.ok) { + console.log('✅ Admin peut créer des commandes client'); + } else { + const error = await adminCreate.text(); + console.log('❌ Admin ne peut pas créer:', error); + } + } else { + console.log('❌ Admin login local échoué'); + } + + } catch (error) { + console.log('❌ Erreur test local:', error.message); + } +} + +// Instructions pour test production +function showProductionInstructions() { + console.log(` + +=== INSTRUCTIONS POUR TEST PRODUCTION === + +1. Connectez-vous à votre serveur de production +2. Modifiez les valeurs ci-dessous avec vos vraies données: + + export PROD_URL="https://votre-serveur-production.com" + export EMPLOYEE_USERNAME="votre-employee-username" + export EMPLOYEE_PASSWORD="votre-employee-password" + export ADMIN_USERNAME="votre-admin-username" + export ADMIN_PASSWORD="votre-admin-password" + +3. Ensuite exécutez ce script avec: + node test-employee-customer-orders-production.js --production + +Le script va: +✓ Tester la connexion admin (pour référence) +✓ Tester la connexion employé +✓ Comparer les réponses des deux rôles +✓ Identifier le problème exact + +`); +} + +// Test production (à exécuter avec les vraies données) +async function testProduction() { + const fetch = require('node-fetch'); + + const PROD_URL = process.env.PROD_URL || 'https://your-production-server.com'; + const EMPLOYEE_USERNAME = process.env.EMPLOYEE_USERNAME; + const EMPLOYEE_PASSWORD = process.env.EMPLOYEE_PASSWORD; + const ADMIN_USERNAME = process.env.ADMIN_USERNAME; + const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD; + + console.log('\n=== TEST PRODUCTION ==='); + console.log('URL:', PROD_URL); + + if (!EMPLOYEE_USERNAME || !EMPLOYEE_PASSWORD) { + console.log('❌ Variables d\'environnement employé manquantes'); + showProductionInstructions(); + return; + } + + try { + // Test admin d'abord (pour référence) + if (ADMIN_USERNAME && ADMIN_PASSWORD) { + console.log('\n1. Test admin production...'); + const adminLogin = await fetch(\`\${PROD_URL}/api/login\`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username: ADMIN_USERNAME, password: ADMIN_PASSWORD }) + }); + + if (adminLogin.ok) { + console.log('✅ Admin login production réussi'); + const adminCookies = adminLogin.headers.get('set-cookie'); + + // Récupérer les groupes admin + const groupsResponse = await fetch(\`\${PROD_URL}/api/groups\`, { + headers: { 'Cookie': adminCookies } + }); + + if (groupsResponse.ok) { + const groups = await groupsResponse.json(); + console.log(\`📋 Groupes disponibles: \${groups.length}\`); + + if (groups.length > 0) { + // Test création commande admin + const testOrder = { + customerName: 'Test Admin Production', + contactNumber: '0123456789', + productName: 'Test Produit Admin Prod', + productDescription: 'Description test admin production', + quantity: 1, + groupId: groups[0].id, + isPickup: false, + notes: 'Test admin production' + }; + + const adminCreate = await fetch(\`\${PROD_URL}/api/customer-orders\`, { + method: 'POST', + headers: { + 'Cookie': adminCookies, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(testOrder) + }); + + console.log('Status création admin:', adminCreate.status); + if (adminCreate.ok) { + console.log('✅ Admin peut créer des commandes client en production'); + } else { + const error = await adminCreate.text(); + console.log('❌ Admin ne peut pas créer:', error); + } + } + } + } else { + console.log('❌ Admin login production échoué'); + } + } + + // Test employé + console.log('\n2. Test employé production...'); + const empLogin = await fetch(\`\${PROD_URL}/api/login\`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username: EMPLOYEE_USERNAME, password: EMPLOYEE_PASSWORD }) + }); + + if (empLogin.ok) { + console.log('✅ Employé login production réussi'); + const empCookies = empLogin.headers.get('set-cookie'); + + // Vérifier profil employé + const userResponse = await fetch(\`\${PROD_URL}/api/user\`, { + headers: { 'Cookie': empCookies } + }); + + if (userResponse.ok) { + const user = await userResponse.json(); + console.log('👤 Profil employé:', { + role: user.role, + groupsCount: user.userGroups?.length || 0 + }); + + if (user.userGroups && user.userGroups.length > 0) { + // Test création commande employé + const testOrder = { + customerName: 'Test Employé Production', + contactNumber: '0123456789', + productName: 'Test Produit Employé Prod', + productDescription: 'Description test employé production', + quantity: 1, + groupId: user.userGroups[0].groupId, + isPickup: false, + notes: 'Test employé production' + }; + + console.log('📦 Données test employé:', testOrder); + + const empCreate = await fetch(\`\${PROD_URL}/api/customer-orders\`, { + method: 'POST', + headers: { + 'Cookie': empCookies, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(testOrder) + }); + + console.log('Status création employé:', empCreate.status); + const empResponse = await empCreate.text(); + + if (empCreate.ok) { + console.log('✅ Employé peut créer des commandes client en production'); + console.log('📋 Commande créée:', JSON.parse(empResponse)); + } else { + console.log('❌ Employé ne peut pas créer:'); + console.log('Response:', empResponse); + + // Analyser l'erreur + try { + const errorObj = JSON.parse(empResponse); + console.log('💡 Erreur structurée:', errorObj); + } catch (e) { + console.log('💡 Erreur texte brute:', empResponse); + } + } + } else { + console.log('❌ Employé n\'est assigné à aucun groupe'); + } + } else { + console.log('❌ Impossible de récupérer le profil employé'); + } + } else { + console.log('❌ Employé login production échoué'); + } + + } catch (error) { + console.log('❌ Erreur test production:', error.message); + } +} + +// Exécution +if (process.argv.includes('--production')) { + testProduction(); +} else if (process.argv.includes('--local')) { + testLocal(); +} else { + console.log('Usage:'); + console.log(' node test-employee-customer-orders-production.js --local # Test local'); + console.log(' node test-employee-customer-orders-production.js --production # Test production'); + console.log(''); + showProductionInstructions(); +} \ No newline at end of file