- Remove extensionsToTreatAsEsm from jest.config.js (not needed with type:module) - Add Jest globals to ESLint config (describe, it, expect, etc.) - Fix unnecessary escape characters in debug-token-403.js - Change no-useless-escape from error to warning
157 lines
5.6 KiB
JavaScript
157 lines
5.6 KiB
JavaScript
/**
|
||
* Script de debug pour identifier la cause exacte de l'erreur 403
|
||
*/
|
||
|
||
import 'dotenv/config';
|
||
import jwt from 'jsonwebtoken';
|
||
import { pool } from '../db.js';
|
||
|
||
const TOKEN_FROM_BROWSER = process.argv[2] || '';
|
||
|
||
async function debugToken() {
|
||
console.log('🔍 DEBUG - Erreur 403 Forbidden\n');
|
||
console.log('=' .repeat(60));
|
||
|
||
// Générer un nouveau token admin
|
||
console.log('\n1️⃣ GÉNÉRATION D\'UN NOUVEAU TOKEN ADMIN\n');
|
||
|
||
const adminResult = await pool.query(`
|
||
SELECT id, email, role, first_name, last_name, is_verified
|
||
FROM users
|
||
WHERE role = 'ADMIN'
|
||
LIMIT 1
|
||
`);
|
||
|
||
if (adminResult.rows.length === 0) {
|
||
console.log('❌ Aucun utilisateur ADMIN trouvé dans la base !');
|
||
process.exit(1);
|
||
}
|
||
|
||
const admin = adminResult.rows[0];
|
||
console.log('✅ Admin trouvé:');
|
||
console.log(` ID: ${admin.id}`);
|
||
console.log(` Email: ${admin.email}`);
|
||
console.log(` Nom: ${admin.first_name} ${admin.last_name}`);
|
||
console.log(` Rôle: ${admin.role}`);
|
||
console.log(` Email vérifié: ${admin.is_verified ? 'Oui' : 'Non'}`);
|
||
|
||
// Générer le token
|
||
const newToken = jwt.sign(
|
||
{ userId: admin.id },
|
||
process.env.JWT_SECRET,
|
||
{ expiresIn: '7d' }
|
||
);
|
||
|
||
console.log(`\n✅ Nouveau token généré (expire dans 7 jours):`);
|
||
console.log(`\n${newToken}\n`);
|
||
|
||
// Tester le token
|
||
console.log('=' .repeat(60));
|
||
console.log('\n2️⃣ TEST DU NOUVEAU TOKEN\n');
|
||
|
||
try {
|
||
const decoded = jwt.verify(newToken, process.env.JWT_SECRET);
|
||
console.log('✅ Token valide et décodé:');
|
||
console.log(` User ID: ${decoded.userId}`);
|
||
console.log(` Émis à: ${new Date(decoded.iat * 1000).toLocaleString('fr-FR')}`);
|
||
console.log(` Expire à: ${new Date(decoded.exp * 1000).toLocaleString('fr-FR')}`);
|
||
|
||
// Vérifier l'utilisateur dans la DB
|
||
const userCheck = await pool.query(
|
||
'SELECT id, email, role FROM users WHERE id = $1',
|
||
[decoded.userId]
|
||
);
|
||
|
||
if (userCheck.rows.length > 0) {
|
||
const user = userCheck.rows[0];
|
||
console.log('\n✅ Utilisateur trouvé dans la base:');
|
||
console.log(` ID: ${user.id}`);
|
||
console.log(` Email: ${user.email}`);
|
||
console.log(` Rôle: ${user.role}`);
|
||
|
||
if (user.role === 'ADMIN') {
|
||
console.log('\n✅ L\'utilisateur a bien le rôle ADMIN');
|
||
} else {
|
||
console.log(`\n❌ PROBLÈME: L'utilisateur a le rôle "${user.role}" au lieu de "ADMIN"`);
|
||
}
|
||
} else {
|
||
console.log('\n❌ PROBLÈME: Utilisateur non trouvé dans la base');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.log('❌ Erreur lors de la vérification du token:');
|
||
console.log(` ${error.message}`);
|
||
}
|
||
|
||
// Si un token du navigateur est fourni, le tester aussi
|
||
if (TOKEN_FROM_BROWSER) {
|
||
console.log('=' .repeat(60));
|
||
console.log('\n3️⃣ TEST DU TOKEN DU NAVIGATEUR\n');
|
||
console.log(`Token reçu: ${TOKEN_FROM_BROWSER.substring(0, 50)}...`);
|
||
|
||
try {
|
||
const decoded = jwt.verify(TOKEN_FROM_BROWSER, process.env.JWT_SECRET);
|
||
console.log('\n✅ Token du navigateur valide et décodé:');
|
||
console.log(` User ID: ${decoded.userId}`);
|
||
console.log(` Émis à: ${new Date(decoded.iat * 1000).toLocaleString('fr-FR')}`);
|
||
console.log(` Expire à: ${new Date(decoded.exp * 1000).toLocaleString('fr-FR')}`);
|
||
|
||
// Vérifier l'utilisateur
|
||
const userCheck = await pool.query(
|
||
'SELECT id, email, role FROM users WHERE id = $1',
|
||
[decoded.userId]
|
||
);
|
||
|
||
if (userCheck.rows.length > 0) {
|
||
const user = userCheck.rows[0];
|
||
console.log('\n✅ Utilisateur trouvé:');
|
||
console.log(` Email: ${user.email}`);
|
||
console.log(` Rôle: ${user.role}`);
|
||
|
||
if (user.role === 'ADMIN') {
|
||
console.log('\n✅ Le token du navigateur est VALIDE et l\'utilisateur est ADMIN');
|
||
console.log('\n🔍 CONCLUSION: Le problème n\'est PAS le token !');
|
||
console.log(' Vérifiez plutôt:');
|
||
console.log(' - Que le header Authorization est bien envoyé depuis le frontend');
|
||
console.log(' - Que le format est bien "Bearer TOKEN"');
|
||
console.log(' - Les logs du serveur backend pour plus de détails');
|
||
} else {
|
||
console.log(`\n❌ PROBLÈME TROUVÉ: L'utilisateur a le rôle "${user.role}"`);
|
||
console.log(` Il faut un utilisateur ADMIN pour accéder aux routes /api/draw/*`);
|
||
}
|
||
} else {
|
||
console.log('\n❌ PROBLÈME TROUVÉ: L\'utilisateur du token n\'existe plus dans la base');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.log('\n❌ PROBLÈME TROUVÉ avec le token du navigateur:');
|
||
if (error.name === 'TokenExpiredError') {
|
||
console.log(' Token expiré !');
|
||
console.log(` Expiré le: ${new Date(error.expiredAt).toLocaleString('fr-FR')}`);
|
||
console.log('\n 💡 SOLUTION: Utiliser le nouveau token généré ci-dessus');
|
||
} else if (error.name === 'JsonWebTokenError') {
|
||
console.log(` Token invalide: ${error.message}`);
|
||
console.log('\n 💡 SOLUTION: Utiliser le nouveau token généré ci-dessus');
|
||
} else {
|
||
console.log(` ${error.message}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
console.log('\n' + '=' .repeat(60));
|
||
console.log('\n📋 INSTRUCTIONS POUR METTRE À JOUR LE TOKEN\n');
|
||
console.log('1. Ouvrir la console du navigateur (F12)');
|
||
console.log('2. Copier-coller ce code:');
|
||
console.log('\nlocalStorage.setItem(\'token\', \'' + newToken + '\');');
|
||
console.log('location.reload();\n');
|
||
console.log('3. Appuyer sur Entrée');
|
||
console.log('4. La page va se recharger avec le nouveau token\n');
|
||
|
||
await pool.end();
|
||
}
|
||
|
||
debugToken().catch(err => {
|
||
console.error('❌ Erreur:', err);
|
||
process.exit(1);
|
||
});
|