/** * POST /api/report-general * * Signalement général (bug, contenu inapproprié, suggestion) * * Body : { category: string, description: string, email?: string } * Rate limit : 5/IP/jour * Envoi vers jules@trans-former.fr via Resend API */ import { checkRateLimitJson } from '~/server/utils/rateLimitJson' const EMAIL_JULES = process.env.EMAIL_JULES || 'jules@trans-former.fr' const VALID_CATEGORIES = ['Une fiche', 'Le chatbot', 'La carte', 'Autre'] as const export default defineEventHandler(async (event) => { // 1. IP const ip = getHeader(event, 'x-forwarded-for')?.split(',')[0].trim() || event.node.req.socket?.remoteAddress || '0.0.0.0' // 2. Rate limit 5/IP/jour const allowed = checkRateLimitJson(ip, 'report-general', 5) if (!allowed) { throw createError({ statusCode: 429, statusMessage: 'Limite de 5 signalements par jour atteinte.', }) } // 3. Lire le body const body = await readBody(event) const category: string = (body?.category ?? '').trim() const description: string = (body?.description ?? '').trim() const email: string = (body?.email ?? '').trim() // 4. Validation if (!VALID_CATEGORIES.includes(category as any)) { throw createError({ statusCode: 400, statusMessage: 'Catégorie invalide.' }) } if (!description || description.length < 5 || description.length > 500) { throw createError({ statusCode: 400, statusMessage: 'Description requise (5-500 caractères).' }) } if (email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ if (!emailRegex.test(email)) { throw createError({ statusCode: 400, statusMessage: 'Email invalide.' }) } } // 5. Envoi via Resend const resendApiKey = process.env.RESEND_API_KEY if (!resendApiKey) { console.error('[report-general] RESEND_API_KEY manquante') throw createError({ statusCode: 500, statusMessage: 'Configuration email manquante.' }) } const submittedAt = new Date().toLocaleString('fr-FR', { timeZone: 'Europe/Paris' }) try { await $fetch('https://api.resend.com/emails', { method: 'POST', headers: { Authorization: `Bearer ${resendApiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ from: 'AEP Signalement ', to: EMAIL_JULES, subject: `[AEP] Signalement — ${category}`, html: `

Signalement AEP — ${category}

Date : ${submittedAt}

Catégorie : ${category}

${email ? `

Email expéditeur : ${email}

` : '

Pas d\'email fourni

'}

Description :

${description.replace(/\n/g, '
')}
`, }), }) } catch (e: any) { console.error('[report-general] Erreur Resend:', e?.message ?? e) throw createError({ statusCode: 502, statusMessage: 'Erreur envoi email — réessaie dans quelques instants.', }) } return { ok: true, message: 'Signalement envoyé, merci !' } })