import nodemailer from 'nodemailer' import { promises as fs } from 'fs' import path from 'path' import { createContactRequest } from '../utils/contact-requests.js' import { readUsers, migrateUserRoles } from '../utils/auth.js' // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal // filename is always a hardcoded constant ('config.json'), never user input const getDataPath = (filename) => { const cwd = process.cwd() if (cwd.endsWith('.output')) return path.join(cwd, '../server/data', filename) return path.join(cwd, 'server/data', filename) } async function loadConfig() { try { const configFile = getDataPath('config.json') const raw = await fs.readFile(configFile, 'utf-8') return JSON.parse(raw) } catch (error) { console.error('Fehler beim Laden der Konfiguration für Kontaktanfragen:', error) return {} } } async function collectRecipients(config) { const recipients = [] // Vorstand if (config?.vorstand && typeof config.vorstand === 'object') { for (const member of Object.values(config.vorstand)) { if (member?.email && typeof member.email === 'string' && member.email.trim()) { recipients.push(member.email.trim()) } } } // Trainer if (Array.isArray(config?.trainer)) { for (const trainer of config.trainer) { if (trainer?.email && typeof trainer.email === 'string' && trainer.email.trim()) { recipients.push(trainer.email.trim()) } } } // Zusätzlich: Benutzer mit Trainer-Rolle aus dem Login-System try { const users = await readUsers() for (const rawUser of users) { const user = migrateUserRoles({ ...rawUser }) const roles = Array.isArray(user.roles) ? user.roles : [] if (roles.includes('trainer') && user.email && String(user.email).trim()) { recipients.push(String(user.email).trim()) } } } catch (error) { console.error('Fehler beim Laden der Trainer-Empfänger aus Benutzerdaten:', error) } const unique = [...new Set(recipients)] if (unique.length > 0) return unique // Fallback if (config?.website?.verantwortlicher?.email) { return [config.website.verantwortlicher.email] } if (process.env.SMTP_USER) { return [process.env.SMTP_USER] } return ['j.dichmann@gmx.de'] } function createTransporter() { const smtpUser = process.env.SMTP_USER const smtpPass = process.env.SMTP_PASS || process.env.EMAIL_PASSWORD if (!smtpUser || !smtpPass) return null return nodemailer.createTransport({ host: process.env.SMTP_HOST || 'smtp.gmail.com', port: Number(process.env.SMTP_PORT || 587), secure: process.env.SMTP_SECURE === 'true', auth: { user: smtpUser, pass: smtpPass } }) } export default defineEventHandler(async (event) => { try { const body = await readBody(event) if (!body.name || !body.email || !body.subject || !body.message) { throw createError({ statusCode: 400, statusMessage: 'Alle Pflichtfelder müssen ausgefüllt werden' }) } const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ if (!emailRegex.test(body.email)) { throw createError({ statusCode: 400, statusMessage: 'Ungültige E-Mail-Adresse' }) } // Anfrage immer speichern, auch wenn E-Mail-Versand fehlschlägt. await createContactRequest({ name: String(body.name).trim(), email: String(body.email).trim(), phone: body.phone ? String(body.phone).trim() : '', subject: String(body.subject).trim(), message: String(body.message).trim() }) const config = await loadConfig() const recipients = await collectRecipients(config) const transporter = createTransporter() if (!transporter) { return { success: true, message: 'Anfrage wurde gespeichert. E-Mail-Versand ist aktuell nicht konfiguriert.' } } const nowLabel = new Date().toLocaleString('de-DE') const emailHtml = `

Neue Kontaktanfrage - Harheimer TC

Kontaktdaten:

Name: ${body.name}

E-Mail: ${body.email}

Telefon: ${body.phone || 'Nicht angegeben'}

Betreff: ${body.subject}

Nachricht:

${body.message}

Diese Nachricht wurde über das Kontaktformular der Harheimer TC Website gesendet.

Zeitstempel: ${nowLabel}

` const emailText = `Neue Kontaktanfrage - Harheimer TC Kontaktdaten: Name: ${body.name} E-Mail: ${body.email} Telefon: ${body.phone || 'Nicht angegeben'} Betreff: ${body.subject} Nachricht: ${body.message} --- Diese Nachricht wurde über das Kontaktformular der Harheimer TC Website gesendet. Zeitstempel: ${nowLabel}` await transporter.sendMail({ from: `"Harheimer TC Website" <${process.env.SMTP_FROM || process.env.SMTP_USER}>`, to: recipients.join(', '), replyTo: body.email, subject: `Kontaktanfrage: ${body.subject}`, text: emailText, html: emailHtml }) return { success: true, message: 'Anfrage wurde erfolgreich gesendet.' } } catch (error) { console.error('Fehler bei Kontaktanfrage:', error) if (error.statusCode) throw error throw createError({ statusCode: 500, statusMessage: 'Fehler beim Senden der Anfrage. Bitte versuchen Sie es später erneut.' }) } })