#!/usr/bin/env node /** * Script de test de sécurité pour Mes Budgets Participatifs * Vérifie que les politiques RLS sont bien appliquées */ // Charger les variables d'environnement depuis .env.local require('dotenv').config({ path: '.env.local' }); const { createClient } = require('@supabase/supabase-js'); // Configuration const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY; if (!supabaseUrl || !supabaseAnonKey || !supabaseServiceKey) { console.error('❌ Variables d\'environnement manquantes'); console.log('Assurez-vous d\'avoir configuré dans .env.local :'); console.log('- NEXT_PUBLIC_SUPABASE_URL'); console.log('- NEXT_PUBLIC_SUPABASE_ANON_KEY'); console.log('- SUPABASE_SERVICE_ROLE_KEY'); console.log('\n💡 Vérifiez que le fichier .env.local existe à la racine du projet'); process.exit(1); } const supabase = createClient(supabaseUrl, supabaseAnonKey); const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey); console.log('🔒 Test de sécurité - Mes Budgets Participatifs\n'); async function testSecurity() { let allTestsPassed = true; // Test 1: Vérifier que les tables existent console.log('1️⃣ Vérification de l\'existence des tables...'); try { const { data: campaigns, error: campaignsError } = await supabase .from('campaigns') .select('id') .limit(1); if (campaignsError) { console.log('❌ Table campaigns non accessible'); allTestsPassed = false; } else { console.log('✅ Table campaigns accessible'); } const { data: adminUsers, error: adminUsersError } = await supabase .from('admin_users') .select('id') .limit(1); if (adminUsersError) { console.log('❌ Table admin_users non accessible'); allTestsPassed = false; } else { console.log('✅ Table admin_users accessible'); } } catch (error) { console.log('❌ Erreur lors de la vérification des tables:', error.message); allTestsPassed = false; } // Test 2: Vérifier les politiques RLS console.log('\n2️⃣ Vérification des politiques RLS...'); try { // Test lecture publique des campagnes const { data: publicCampaigns, error: publicCampaignsError } = await supabase .from('campaigns') .select('id, title') .limit(1); if (publicCampaignsError) { console.log('❌ Lecture publique des campagnes bloquée'); allTestsPassed = false; } else { console.log('✅ Lecture publique des campagnes autorisée'); } // Test création publique des campagnes (doit être bloquée) const { data: createCampaign, error: createCampaignError } = await supabase .from('campaigns') .insert({ title: 'Test Campaign', description: 'Test Description', budget_per_user: 100, spending_tiers: '10,25,50,100' }) .select(); if (createCampaignError && createCampaignError.code === '42501') { console.log('✅ Création de campagnes bloquée pour les utilisateurs non authentifiés'); } else if (createCampaign) { console.log('❌ Création de campagnes autorisée pour les utilisateurs non authentifiés'); allTestsPassed = false; } else { console.log('⚠️ Erreur inattendue lors du test de création:', createCampaignError?.message); } } catch (error) { console.log('❌ Erreur lors de la vérification des politiques RLS:', error.message); allTestsPassed = false; } // Test 3: Vérifier l'accès admin avec clé de service console.log('\n3️⃣ Vérification de l\'accès administrateur...'); try { const { data: adminCampaigns, error: adminCampaignsError } = await supabaseAdmin .from('campaigns') .select('id, title') .limit(1); if (adminCampaignsError) { console.log('❌ Accès administrateur aux campagnes bloqué'); allTestsPassed = false; } else { console.log('✅ Accès administrateur aux campagnes autorisé'); } // Test création avec clé de service const { data: newCampaign, error: newCampaignError } = await supabaseAdmin .from('campaigns') .insert({ title: 'Test Admin Campaign', description: 'Test Admin Description', budget_per_user: 100, spending_tiers: '10,25,50,100' }) .select(); if (newCampaignError) { console.log('❌ Création de campagne avec clé de service bloquée'); allTestsPassed = false; } else { console.log('✅ Création de campagne avec clé de service autorisée'); // Nettoyer le test await supabaseAdmin .from('campaigns') .delete() .eq('id', newCampaign[0].id); } } catch (error) { console.log('❌ Erreur lors de la vérification de l\'accès admin:', error.message); allTestsPassed = false; } // Test 4: Vérifier les fonctions utilitaires console.log('\n4️⃣ Vérification des fonctions utilitaires...'); try { const { data: stats, error: statsError } = await supabase .rpc('get_campaign_stats', { campaign_uuid: '00000000-0000-0000-0000-000000000000' }); if (statsError) { console.log('❌ Fonction get_campaign_stats non accessible'); allTestsPassed = false; } else { console.log('✅ Fonction get_campaign_stats accessible'); } } catch (error) { console.log('❌ Erreur lors de la vérification des fonctions:', error.message); allTestsPassed = false; } // Résumé console.log('\n📊 Résumé des tests de sécurité'); console.log('================================'); if (allTestsPassed) { console.log('🎉 Tous les tests de sécurité sont passés !'); console.log('✅ Votre application est correctement sécurisée'); console.log('✅ Les politiques RLS sont bien appliquées'); console.log('✅ L\'accès administrateur fonctionne'); console.log('✅ Les pages publiques restent accessibles'); } else { console.log('❌ Certains tests de sécurité ont échoué'); console.log('⚠️ Vérifiez votre configuration et les politiques RLS'); console.log('📖 Consultez le guide de migration : MIGRATION-GUIDE.md'); } return allTestsPassed; } // Exécuter les tests testSecurity() .then((success) => { process.exit(success ? 0 : 1); }) .catch((error) => { console.error('❌ Erreur lors des tests:', error); process.exit(1); });