Files
mes-budgets-participatifs/scripts/test-security.js

195 lines
6.5 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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);
});