ajout envoi smtp (paramètres, test envois, envoi à 1 participant). protège vue mot de passe
- ajout filtre page statistiques
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { supabase } from './supabase';
|
||||
import { Campaign, Proposition, Participant, Vote, ParticipantWithVoteStatus } from '@/types';
|
||||
import { Campaign, Proposition, Participant, Vote, ParticipantWithVoteStatus, Setting, SmtpSettings } from '@/types';
|
||||
import { encryptionService } from './encryption';
|
||||
import { emailService } from './email';
|
||||
|
||||
// Services pour les campagnes
|
||||
export const campaignService = {
|
||||
@@ -279,3 +281,175 @@ export const voteService = {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Services pour les paramètres
|
||||
export const settingsService = {
|
||||
async getAll(): Promise<Setting[]> {
|
||||
const { data, error } = await supabase
|
||||
.from('settings')
|
||||
.select('*')
|
||||
.order('category', { ascending: true })
|
||||
.order('key', { ascending: true });
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
|
||||
async getByCategory(category: string): Promise<Setting[]> {
|
||||
const { data, error } = await supabase
|
||||
.from('settings')
|
||||
.select('*')
|
||||
.eq('category', category)
|
||||
.order('key', { ascending: true });
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
|
||||
async getByKey(key: string): Promise<Setting | null> {
|
||||
const { data, error } = await supabase
|
||||
.from('settings')
|
||||
.select('*')
|
||||
.eq('key', key)
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
if (error.code === 'PGRST116') return null; // No rows returned
|
||||
throw error;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
async getValue(key: string, defaultValue: string = ''): Promise<string> {
|
||||
const setting = await this.getByKey(key);
|
||||
return setting?.value || defaultValue;
|
||||
},
|
||||
|
||||
async getBooleanValue(key: string, defaultValue: boolean = false): Promise<boolean> {
|
||||
const value = await this.getValue(key, defaultValue.toString());
|
||||
return value === 'true';
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async create(setting: any): Promise<Setting> {
|
||||
const { data, error } = await supabase
|
||||
.from('settings')
|
||||
.insert(setting)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
return data;
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async update(key: string, updates: any): Promise<Setting> {
|
||||
const { data, error } = await supabase
|
||||
.from('settings')
|
||||
.update(updates)
|
||||
.eq('key', key)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
return data;
|
||||
},
|
||||
|
||||
async setValue(key: string, value: string): Promise<Setting> {
|
||||
const existing = await this.getByKey(key);
|
||||
if (existing) {
|
||||
return this.update(key, { value });
|
||||
} else {
|
||||
return this.create({ key, value, category: 'general' });
|
||||
}
|
||||
},
|
||||
|
||||
async setBooleanValue(key: string, value: boolean): Promise<Setting> {
|
||||
return this.setValue(key, value.toString());
|
||||
},
|
||||
|
||||
async delete(key: string): Promise<void> {
|
||||
const { error } = await supabase
|
||||
.from('settings')
|
||||
.delete()
|
||||
.eq('key', key);
|
||||
|
||||
if (error) throw error;
|
||||
},
|
||||
|
||||
// Méthodes spécifiques pour les paramètres SMTP
|
||||
async getSmtpSettings(): Promise<SmtpSettings> {
|
||||
const smtpKeys = [
|
||||
'smtp_host', 'smtp_port', 'smtp_username', 'smtp_password',
|
||||
'smtp_secure', 'smtp_from_email', 'smtp_from_name'
|
||||
];
|
||||
|
||||
const settings = await Promise.all(
|
||||
smtpKeys.map(key => this.getByKey(key))
|
||||
);
|
||||
|
||||
return {
|
||||
host: settings[0]?.value || '',
|
||||
port: parseInt(settings[1]?.value || '587'),
|
||||
username: settings[2]?.value || '',
|
||||
password: encryptionService.isEncrypted(settings[3]?.value || '')
|
||||
? encryptionService.decrypt(settings[3]?.value || '')
|
||||
: settings[3]?.value || '',
|
||||
secure: settings[4]?.value === 'true',
|
||||
from_email: settings[5]?.value || '',
|
||||
from_name: settings[6]?.value || ''
|
||||
};
|
||||
},
|
||||
|
||||
async setSmtpSettings(smtpSettings: SmtpSettings): Promise<void> {
|
||||
const settingsToUpdate = [
|
||||
{ key: 'smtp_host', value: smtpSettings.host, category: 'email', description: 'Serveur SMTP' },
|
||||
{ key: 'smtp_port', value: smtpSettings.port.toString(), category: 'email', description: 'Port SMTP' },
|
||||
{ key: 'smtp_username', value: smtpSettings.username, category: 'email', description: 'Nom d\'utilisateur SMTP' },
|
||||
{ key: 'smtp_password', value: encryptionService.encrypt(smtpSettings.password), category: 'email', description: 'Mot de passe SMTP (chiffré)' },
|
||||
{ key: 'smtp_secure', value: smtpSettings.secure.toString(), category: 'email', description: 'Connexion sécurisée SSL/TLS' },
|
||||
{ key: 'smtp_from_email', value: smtpSettings.from_email, category: 'email', description: 'Adresse email d\'expédition' },
|
||||
{ key: 'smtp_from_name', value: smtpSettings.from_name, category: 'email', description: 'Nom d\'expédition' }
|
||||
];
|
||||
|
||||
await Promise.all(
|
||||
settingsToUpdate.map(setting => this.setValue(setting.key, setting.value))
|
||||
);
|
||||
},
|
||||
|
||||
async testSmtpConnection(smtpSettings: SmtpSettings): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
// Validation basique des paramètres
|
||||
if (!smtpSettings.host || !smtpSettings.port || !smtpSettings.username || !smtpSettings.password) {
|
||||
return { success: false, error: 'Paramètres SMTP incomplets' };
|
||||
}
|
||||
|
||||
if (smtpSettings.port < 1 || smtpSettings.port > 65535) {
|
||||
return { success: false, error: 'Port SMTP invalide' };
|
||||
}
|
||||
|
||||
if (!smtpSettings.from_email.includes('@')) {
|
||||
return { success: false, error: 'Adresse email d\'expédition invalide' };
|
||||
}
|
||||
|
||||
// Test de connexion via API route
|
||||
return await emailService.testConnection(smtpSettings);
|
||||
} catch (error) {
|
||||
return { success: false, error: error instanceof Error ? error.message : 'Erreur inconnue' };
|
||||
}
|
||||
},
|
||||
|
||||
async sendTestEmail(smtpSettings: SmtpSettings, toEmail: string): Promise<{ success: boolean; error?: string; messageId?: string }> {
|
||||
try {
|
||||
// Validation de l'email de destination
|
||||
if (!emailService.validateEmail(toEmail)) {
|
||||
return { success: false, error: 'Adresse email de destination invalide' };
|
||||
}
|
||||
|
||||
// Envoi de l'email de test via API route
|
||||
return await emailService.sendTestEmail(smtpSettings, toEmail);
|
||||
} catch (error) {
|
||||
return { success: false, error: error instanceof Error ? error.message : 'Erreur lors de l\'envoi de l\'email de test' };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user