import { apiI18n } from '../i18n/api-i18n'; export type MailTemplate = 'verifyEmail' | 'resetPassword' | 'smtpTest'; export interface RenderedMail { subject: string; text: string; html: string; } /** * Renders the layout-light transactional mails (text + simple HTML) from * the `mails` i18n namespace. Every template gets: greeting, body text, * one action link, expiry note, ignore hint, signoff. */ export function renderMail( template: MailTemplate, params: { displayName: string; link: string }, locale: 'de' | 'en', ): RenderedMail { const t = (key: string, options: Record = {}): string => apiI18n.t(`mails:${key}`, { lng: locale, ...options }); const greeting = t('common.greeting', { displayName: params.displayName }); const body = t(`${template}.body`); const action = t(`${template}.action`); const expiry = t(`${template}.expiry`); const ignore = t('common.ignoreHint'); const signoff = t('common.signoff'); const text = [greeting, '', body, '', params.link, '', expiry, ignore, '', signoff].join('\n'); const html = `

${escapeHtml(greeting)}

${escapeHtml(body)}

${escapeHtml(action)}

${escapeHtml(expiry)}
${escapeHtml(ignore)}

${escapeHtml(signoff)}

`; return { subject: t(`${template}.subject`), text, html }; } function escapeHtml(value: string): string { return value .replaceAll('&', '&') .replaceAll('<', '<') .replaceAll('>', '>') .replaceAll('"', '"'); }