import { eq, sql } from "drizzle-orm"; import { getDb } from "./db"; import { parametres, historiqueParametres } from "../drizzle/schema"; /** * Récupérer les paramètres de l'application * S'il n'y a pas de paramètres, en créer un avec les valeurs par défaut */ export async function getParametres() { const db = await getDb(); if (!db) throw new Error("Database not available"); const result = await db.select().from(parametres).limit(1); if (result.length === 0) { // Créer les paramètres par défaut await db.insert(parametres).values({ urlPublique: "https://formations.itinova.org", }); const newResult = await db.select().from(parametres).limit(1); return newResult[0]; } return result[0]; } /** * Mettre à jour les paramètres de l'application * Enregistre automatiquement l'historique des modifications */ export async function updateParametres( updates: Partial<{ urlPublique: string; delaiExpirationQR: number; dureeValiditeToken: number; notificationsActives: boolean; envoiAutomatiqueAttestations: boolean; }>, userId: number, userName: string ) { const db = await getDb(); if (!db) throw new Error("Database not available"); const params = await getParametres(); // Enregistrer l'historique pour chaque champ modifié for (const [key, value] of Object.entries(updates)) { const oldValue = params[key as keyof typeof params]; if (oldValue !== value) { await db.insert(historiqueParametres).values({ userId, userName, champModifie: key, ancienneValeur: oldValue !== null && oldValue !== undefined ? String(oldValue) : null, nouvelleValeur: value !== null && value !== undefined ? String(value) : null, }); } } // Mettre à jour les paramètres await db.update(parametres) .set(updates) .where(eq(parametres.id, params.id)); return getParametres(); } /** * Mettre à jour l'URL publique (fonction de compatibilité) */ export async function updateUrlPublique(urlPublique: string, userId?: number, userName?: string) { return updateParametres( { urlPublique }, userId || 1, userName || "Système" ); } /** * Récupérer l'historique des modifications des paramètres */ export async function getHistoriqueParametres(limit: number = 50) { const db = await getDb(); if (!db) throw new Error("Database not available"); return db.select() .from(historiqueParametres) .orderBy(sql`${historiqueParametres.dateModification} DESC`) .limit(limit); } /** * Tester l'accessibilité d'une URL */ export async function testerUrl(url: string): Promise<{ accessible: boolean; message: string; statusCode?: number }> { try { // Vérifier le format de l'URL const urlObj = new URL(url); if (!['http:', 'https:'].includes(urlObj.protocol)) { return { accessible: false, message: "L'URL doit commencer par http:// ou https://" }; } // Tenter une requête HEAD pour vérifier l'accessibilité const response = await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(5000), // Timeout de 5 secondes }); return { accessible: response.ok, message: response.ok ? "L'URL est accessible" : `L'URL a retourné une erreur HTTP ${response.status}`, statusCode: response.status }; } catch (error) { if (error instanceof TypeError && error.message.includes('Invalid URL')) { return { accessible: false, message: "Format d'URL invalide" }; } return { accessible: false, message: `Erreur lors du test: ${error instanceof Error ? error.message : 'Erreur inconnue'}` }; } }