93 lines
3.6 KiB
JavaScript
93 lines
3.6 KiB
JavaScript
import { BookingError, emailPattern } from "./booking-service.js";
|
|
|
|
// Prüft und normalisiert die vom Browser übermittelten Kontaktangaben.
|
|
function normalizeInput(input) {
|
|
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
throw new BookingError(
|
|
400,
|
|
"INVALID_INPUT",
|
|
"Bitte alle Pflichtfelder prüfen.",
|
|
);
|
|
}
|
|
|
|
// Legt die zulässige Höchstlänge für jedes Formularfeld fest.
|
|
const limits = { name: 120, email: 254, subject: 160, message: 5000 };
|
|
const fields = {};
|
|
const data = { consent: true };
|
|
if (input.consent !== true)
|
|
fields.consent = "Bitte die Datenschutzbestimmungen akzeptieren.";
|
|
for (const [field, max] of Object.entries(limits)) {
|
|
const value = input[field];
|
|
if (typeof value !== "string") {
|
|
fields[field] = "Dieses Feld ist erforderlich.";
|
|
continue;
|
|
}
|
|
const trimmed = value.trim();
|
|
if (!trimmed) fields[field] = "Dieses Feld ist erforderlich.";
|
|
else if (trimmed.length > max)
|
|
fields[field] = `Maximal ${max} Zeichen eingeben.`;
|
|
else if (
|
|
(field === "message"
|
|
? /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/
|
|
: /[\x00-\x1f\x7f]/
|
|
).test(trimmed)
|
|
)
|
|
fields[field] = "Bitte entferne ungültige Steuerzeichen.";
|
|
else data[field] = trimmed;
|
|
}
|
|
// Prüft zusätzlich das E-Mail-Format und die Mindestlänge der Nachricht.
|
|
if (
|
|
data.email &&
|
|
(!emailPattern.test(data.email) || data.email.split("@")[0].length > 64)
|
|
) {
|
|
fields.email = "Bitte eine gültige E-Mail-Adresse eingeben.";
|
|
}
|
|
if (data.message && [...data.message].length < 10) {
|
|
fields.message =
|
|
"Deine Nachricht muss mindestens 10 Zeichen enthalten.";
|
|
}
|
|
// Gibt alle gefundenen Feldfehler gesammelt an die Route zurück.
|
|
if (Object.keys(fields).length) {
|
|
throw new BookingError(
|
|
400,
|
|
"INVALID_INPUT",
|
|
"Bitte prüfe deine Eingaben.",
|
|
fields,
|
|
);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
// Verbindet Validierung, CSV-Speicherung und anschließenden E-Mail-Versand.
|
|
export function createContactFormService({ storage, sendContactForm }) {
|
|
return {
|
|
async submit(input) {
|
|
const data = normalizeInput(input);
|
|
// Ergänzt einen Zeitstempel, damit die Anfrage zeitlich nachvollziehbar bleibt.
|
|
const record = { createdAt: new Date().toISOString(), ...data };
|
|
// Speichert vor dem Versand, damit die Anfrage bei SMTP-Problemen erhalten bleibt.
|
|
try {
|
|
await storage.append(record);
|
|
} catch {
|
|
throw new BookingError(
|
|
503,
|
|
"CONTACT_NOT_SAVED",
|
|
"Deine Nachricht konnte gerade nicht gespeichert werden. Bitte versuche es erneut.",
|
|
);
|
|
}
|
|
// Sendet die beiden Mails erst nach erfolgreichem Speichern der Anfrage.
|
|
try {
|
|
await sendContactForm(record);
|
|
} catch (error) {
|
|
if (error instanceof BookingError) throw error;
|
|
throw new BookingError(
|
|
502,
|
|
"CONTACT_EMAIL_FAILED",
|
|
"Deine Nachricht wurde gespeichert, aber die E-Mails konnten nicht vollständig gesendet werden. Bitte versuche es später erneut oder melde dich direkt bei Tri-Hub.",
|
|
);
|
|
}
|
|
return { saved: true, emailStatus: "accepted" };
|
|
},
|
|
};
|
|
}
|