improve security (change RLS, and allow table sensitive access only at server side, with supabase service key)
This commit is contained in:
194
scripts/test-security.js
Normal file
194
scripts/test-security.js
Normal file
@@ -0,0 +1,194 @@
|
||||
#!/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);
|
||||
});
|
||||
Reference in New Issue
Block a user