From d34902cd5f9f5ccdd389f6924b01a9259ed87712 Mon Sep 17 00:00:00 2001 From: joachimhummel <47454583-joachimhummel@users.noreply.replit.com> Date: Fri, 15 May 2026 17:14:35 +0000 Subject: [PATCH] feat: echo submitted message back in confirmation email MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task #18 — Send a copy of the submitted message back to the contact in the confirmation email. Changes made to artifacts/api-server/src/routes/contact.ts: - Updated buildConfirmationEmail() signature from (name: string) to ({ name, subject, message }) so it can accept and render the original submission. - Added a visually distinct "Ihre Nachricht" quoted block to the HTML template: - Light gray background (#f8fafc) matching the existing bgField colour - Subtle 3px left border (#e2e8f0) styled as a blockquote - Rounded right corners (border-radius: 0 6px 6px 0) - ALL-CAPS label "IHRE NACHRICHT" in the same style as field labels elsewhere - Optional subject line rendered in semi-bold if provided - Message body with white-space:pre-wrap to preserve line breaks - All user-supplied values (subject, message) passed through the existing escapeHtml() helper — XSS-safe. - Updated the plain-text fallback: adds a "—" delimited quoted section with optional "Betreff:" line before the message body. - Updated the call site to pass { name, subject, message } to buildConfirmationEmail(). No new dependencies. Pre-existing TS error (SendContactMessageBody missing from @workspace/api-zod) is unrelated to this task and unchanged. Replit-Task-Id: 63279220-bb35-4721-bbd6-86182301a697 --- artifacts/api-server/src/routes/contact.ts | 40 ++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/artifacts/api-server/src/routes/contact.ts b/artifacts/api-server/src/routes/contact.ts index 8f50978..c662ef6 100644 --- a/artifacts/api-server/src/routes/contact.ts +++ b/artifacts/api-server/src/routes/contact.ts @@ -67,13 +67,19 @@ router.post("/contact", contactRateLimit, async (req, res) => { "", "vielen Dank für Ihre Nachricht! Ich habe Ihre Anfrage erhalten und melde mich in der Regel innerhalb von 1–2 Werktagen bei Ihnen.", "", + "Zur Erinnerung, hier ist Ihre Nachricht:", + "—", + ...(subject ? [`Betreff: ${subject}`, ""] : []), + message, + "—", + "", "Mit freundlichen Grüßen", "Joachim Hummel", "", "—", "jh@unixweb.de", ].join("\n"), - htmlContent: buildConfirmationEmail(name), + htmlContent: buildConfirmationEmail({ name, subject, message }), }); req.log.info({ to: email }, "Confirmation email sent to sender via Brevo"); @@ -255,8 +261,18 @@ function buildNotificationEmail({ `; } -function buildConfirmationEmail(name: string): string { +function buildConfirmationEmail({ + name, + subject, + message, +}: { + name: string; + subject?: string; + message: string; +}): string { const safeName = escapeHtml(name); + const safeSubject = subject ? escapeHtml(subject) : null; + const safeMessage = escapeHtml(message); const brandBlue = "#3f4ff4"; const textDark = "#0f172a"; const textMid = "#334155"; @@ -265,6 +281,7 @@ function buildConfirmationEmail(name: string): string { const borderColor = "#e2e8f0"; const bgPage = "#f1f5f9"; const bgCard = "#ffffff"; + const bgQuote = "#f8fafc"; return ` @@ -301,7 +318,24 @@ function buildConfirmationEmail(name: string): string {

Vielen Dank, ${safeName}!

Ihre Anfrage ist eingegangen.

Schön, dass Sie sich gemeldet haben. Ich habe Ihre Nachricht erhalten und werde mich in der Regel innerhalb von 1–2 Werktagen bei Ihnen melden.

-

Bis dahin können Sie gerne mein Portfolio besuchen oder mir direkt eine E-Mail schicken.

+

Bis dahin können Sie gerne mein Portfolio besuchen oder mir direkt eine E-Mail schicken.

+ + + + + + +
+ + + + +
+

Ihre Nachricht

+ ${safeSubject ? `

Betreff: ${safeSubject}

` : ""} +

${safeMessage}

+
+