// app/beach/actions.ts 'use server'; export async function submitRegistration(prevState: unknown, formData: FormData) { // 1. Spara all rådata direkt för att kunna skicka tillbaka den vid fel const rawData = { name: formData.get('name') as string, email: formData.get('email') as string, tel: formData.get('tel') as string, team: formData.get('team') as string, count: formData.get('count') as string, level: formData.get('level') as string, message: formData.get('message') as string, }; const honeypot = formData.get('website'); if (honeypot) { return { success: false, message: 'Spam detekterat.', values: rawData }; } // 2. Hämta Turnstile Token och Secret const turnstileToken = formData.get('cf-turnstile-response'); const secretKey = process.env.TURNSTILE_SECRET; if (!secretKey) { console.error("Saknar TURNSTILE_SECRET i miljön."); return { success: false, message: 'Serverkonfiguration saknas. Kontakta administratör.', values: rawData }; } // 3. Verifiera mot Cloudflare try { const turnstileRes = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ secret: secretKey, response: String(turnstileToken || ''), }), }); const turnstileData = await turnstileRes.json(); if (!turnstileData.success) { console.error("Turnstile failed:", turnstileData); return { success: false, message: 'Säkerhetsverifieringen misslyckades. Ladda om sidan och försök igen.', values: rawData }; } } catch (error) { console.error("Turnstile fetch error:", error); return { success: false, message: 'Kunde inte nå verifieringsservern.', values: rawData }; } // 4. Formatera telefonnummer let cleanTel = rawData.tel.replace(/\D/g, ''); if (cleanTel.startsWith('46')) cleanTel = cleanTel.substring(2); else if (cleanTel.startsWith('0')) cleanTel = cleanTel.substring(1); const formattedTel = cleanTel.length === 9 ? `+46 (0)${cleanTel.substring(0, 2)}-${cleanTel.substring(2, 5)} ${cleanTel.substring(5, 7)} ${cleanTel.substring(7, 9)}` : rawData.tel; // 5. Stalwart JMAP Setup const jmapUrl = process.env.STALWART_JMAP_URL; const jmapToken = process.env.STALWART_API_TOKEN; const accountId = process.env.STALWART_ACCOUNT_ID; if (!jmapUrl || !jmapToken || !accountId) { console.error("Saknar JMAP-konfiguration i miljön."); return { success: false, message: 'E-postserver är inte konfigurerad. Kontakta administratör.', values: rawData }; } // Hjälpfunktion för att bygga och skicka via Stalwart JMAP async function sendMailJMAP(toEmail: string, replyToEmail: string, subject: string, htmlContent: string, fromName: string) { const payload = { using: [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail", "urn:ietf:params:jmap:submission" ], methodCalls: [ [ "Email/set", { accountId: accountId, create: { "draft-1": { from: [{ email: accountId, name: fromName }], to: [{ email: toEmail }], replyTo: [{ email: replyToEmail }], subject: subject, bodyValues: { "body-html": { value: htmlContent, isTruncated: false, isEncodingProblem: false } }, htmlBody: [{ partId: "body-html", type: "text/html" }] } } }, "0" ], [ "EmailSubmission/set", { accountId: accountId, create: { "sub-1": { emailId: "#draft-1" } } }, "1" ] ] }; const res = await fetch(jmapUrl as string, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${jmapToken}` }, body: JSON.stringify(payload) }); if (!res.ok) { throw new Error(`JMAP API Error: ${res.status} ${res.statusText}`); } return res.json(); } // 6. Skapa och skicka mail try { const dateStr = new Date().toLocaleString('sv-SE', { timeZone: 'Europe/Stockholm', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); const cleanMessage = rawData.message ? rawData.message.replace(/[\r\n;]/g, " ") : ""; // HTML för mail till klubben const mailTillKlubbHtml = `
| Lagnamn: | ${rawData.team} |
| Kontakt: | ${rawData.name} |
| E-post: | ${rawData.email} |
| Telefon: | ${formattedTel} |
| Spelare: | ${rawData.count} |
| Nivå: | ${rawData.level} |
Meddelande:
${rawData.message ? rawData.message.replace(/\n/g, '
') : 'Inget meddelande'}
| ${rawData.team} | ${rawData.count} | ${rawData.level} | ${rawData.name} | ${formattedTel} | ${rawData.email} | ${dateStr} | ${cleanMessage} |
Tack för din anmälan till beachturneringen. Vi återkommer så snart vi har granskat era uppgifter.
Ses på stranden!
Lerbergets Volleybollsällskap