Terminplaner: Kalenderdatei, Gaesteversand, Vorlagen-Engine fuer G-Vorlagen
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0c033ab1d2
commit
181445a69d
5 files changed
+514
-6
No files matched your search
@@ -176,6 +176,44 @@ export async function sendCustomerMail(to, { attachments = [], bccTeam = true, .
|
||||
})
|
||||
}
|
||||
|
||||
// Genau ein Postfach (Terminplaner: kein Mail-Relais ueber Listen oder Anzeigenamen), hoechstens 254 Zeichen
|
||||
const SINGLE_MAILBOX = /^[^\s,;<>"\\]+@[^\s,;<>"\\]+$/
|
||||
const checkMailbox = (value, name) => {
|
||||
if (typeof value !== 'string' || value.length > 254 || !SINGLE_MAILBOX.test(value)) {
|
||||
throw new TypeError(`${name}: genau eine E-Mail-Adresse erwartet`)
|
||||
}
|
||||
}
|
||||
const oneLine = (value) => String(value ?? '').replace(/\s*[\r\n]+\s*/g, ' ').trim()
|
||||
|
||||
/**
|
||||
* Terminplaner: Mail an einen Gast (Spec 2026-10-02 Abschnitt 6). Verschickt schon gerenderte Inhalte (Betreff, HTML, Text
|
||||
* kommen aus termineOutbox/G-Vorlagen); Absendername = Betrieb, Adresse bleibt SMTP_FROM, Antworten gehen an `replyTo`
|
||||
* (Betriebs-E-Mail), nie BCC. Mit `ics` haengt die Kalenderdatei als icalEvent (nodemailer-Kalenderteil, kein Anhang) an.
|
||||
* Wirft bei fehlendem SMTP, ungueltiger Adresse oder Methode - der Aufrufer (Outbox) entscheidet ueber Wiederholung.
|
||||
* @param {{ to: string, fromName: string, replyTo?: string|null, subject: string, html: string, text: string,
|
||||
* ics?: string|null, icsMethod?: 'REQUEST'|'CANCEL'|'PUBLISH' }} message
|
||||
*/
|
||||
export async function sendGuestMail({ to, fromName, replyTo = null, subject, html, text, ics = null, icsMethod = 'REQUEST' }) {
|
||||
const mailer = getTransporter()
|
||||
if (!mailer) throw new Error('SMTP nicht konfiguriert')
|
||||
checkMailbox(to, 'to')
|
||||
if (replyTo) checkMailbox(replyTo, 'replyTo')
|
||||
const name = oneLine(fromName)
|
||||
const subj = oneLine(subject)
|
||||
if (!name) throw new TypeError('fromName fehlt')
|
||||
if (!subj) throw new TypeError('subject fehlt')
|
||||
if (ics && !['REQUEST', 'CANCEL', 'PUBLISH'].includes(icsMethod)) throw new TypeError('icsMethod muss REQUEST, CANCEL oder PUBLISH sein')
|
||||
return mailer.sendMail({
|
||||
from: { name, address: config.smtp.from },
|
||||
replyTo: replyTo || undefined,
|
||||
to,
|
||||
subject: subj,
|
||||
text,
|
||||
html,
|
||||
icalEvent: ics ? { method: icsMethod, filename: 'termin.ics', content: ics } : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Mail an eine einzelne Person im Team aus einer T-Vorlage (z. B. T15 Push-Zeitmail), ohne BCC.
|
||||
* Wirft bei fehlendem SMTP oder Versandfehler - der Aufrufer entscheidet, ob das schlimm ist.
|
||||
|
||||
Reference in new issue
Block a user