diff --git a/backend/src/routes/adminEvents.js b/backend/src/routes/adminEvents.js index 2be8bd6..d50a47a 100644 --- a/backend/src/routes/adminEvents.js +++ b/backend/src/routes/adminEvents.js @@ -578,41 +578,39 @@ router.post('/:id/resend-email', adminAuth, async (req, res) => { return res.status(404).json({ error: 'Event not found' }); } - // Get the language preference - let language = 'en'; - try { - // First check app_settings for general_default_language - const langSetting = await db('app_settings') - .where('setting_key', 'general_default_language') - .first(); - - if (langSetting && langSetting.setting_value) { - language = langSetting.setting_value; - } - } catch (err) { - console.warn('Could not fetch language setting:', err); + // The email processor will determine the language based on: + // 1. Event language setting + // 2. App settings general_default_language + // 3. Email config default language + // 4. Domain-based detection + // So we don't need to determine it here + + // For resending creation email, we need the actual password + // First, try to get it from the request body if provided + let galleryPassword = req.body.password; + + // If no password provided, we can't decrypt the existing one + // So we'll show a security message + if (!galleryPassword) { + // We'll let the email processor determine the language for the security message + galleryPassword = '{{password_security_message}}'; } - // Format dates based on language + // Format dates in a neutral format - the email processor will localize them const eventDate = new Date(event.event_date); const expiryDate = new Date(event.expires_at); - const dateLocale = language === 'de' ? 'de-DE' : 'en-US'; - - // Prepare password text based on language - const passwordText = language === 'de' - ? '(Aus Sicherheitsgründen nicht angezeigt)' - : '(Not shown for security reasons)'; // Queue the email await queueEmail(id, event.host_email, 'gallery_created', { host_name: event.host_name || event.host_email.split('@')[0], event_name: event.event_name, - event_date: eventDate.toLocaleDateString(dateLocale), + event_date: eventDate.toISOString().split('T')[0], // YYYY-MM-DD format gallery_link: event.share_link, - gallery_password: passwordText, - expiry_date: expiryDate.toLocaleDateString(dateLocale), + gallery_password: galleryPassword, + expiry_date: expiryDate.toISOString().split('T')[0], // YYYY-MM-DD format welcome_message: event.welcome_message || '', - eventId: id + eventId: id, + isResend: true // Flag to indicate this is a resend }); // Log the activity using the proper schema diff --git a/backend/src/services/emailProcessor.js b/backend/src/services/emailProcessor.js index 07f8125..f41eb54 100644 --- a/backend/src/services/emailProcessor.js +++ b/backend/src/services/emailProcessor.js @@ -109,6 +109,9 @@ async function getRecipientLanguage(email, eventId = null) { // Process email template with variables async function processTemplate(template, variables, language = 'en') { + // Import date formatter + const { formatDate } = require('../utils/dateFormatter'); + // Get the appropriate language fields const subjectField = language === 'de' ? 'subject_de' : 'subject_en'; const htmlField = language === 'de' ? 'body_html_de' : 'body_html_en'; @@ -118,6 +121,27 @@ async function processTemplate(template, variables, language = 'en') { let subject = template[subjectField] || template.subject || ''; let htmlBody = template[htmlField] || template.body_html || ''; let textBody = template[textField] || template.body_text || ''; + + // Process variables before template compilation + const processedVariables = { ...variables }; + + // Handle password security message + if (processedVariables.gallery_password === '{{password_security_message}}') { + processedVariables.gallery_password = language === 'de' + ? '(Aus Sicherheitsgründen nicht angezeigt)' + : '(Not shown for security reasons)'; + } + + // Format dates if they exist + if (processedVariables.event_date) { + processedVariables.event_date = await formatDate(processedVariables.event_date, language); + } + if (processedVariables.expiry_date) { + processedVariables.expiry_date = await formatDate(processedVariables.expiry_date, language); + } + if (processedVariables.archive_date) { + processedVariables.archive_date = await formatDate(processedVariables.archive_date, language); + } // Get branding settings for logo let logoUrl = ''; @@ -156,10 +180,10 @@ async function processTemplate(template, variables, language = 'en') { const htmlTemplate = Handlebars.compile(htmlBody); const textTemplate = Handlebars.compile(textBody); - // Process templates with variables - subject = subjectTemplate(variables); - htmlBody = htmlTemplate(variables); - textBody = textTemplate(variables); + // Process templates with processedVariables (includes formatted dates and security messages) + subject = subjectTemplate(processedVariables); + htmlBody = htmlTemplate(processedVariables); + textBody = textTemplate(processedVariables); // Wrap HTML body in styled template const styledHtmlBody = ` diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json index 5886846..a7fd9a4 100644 --- a/frontend/src/i18n/locales/de.json +++ b/frontend/src/i18n/locales/de.json @@ -715,6 +715,7 @@ "settings_updated": "Einstellungen aktualisiert", "event_updated": "Veranstaltung aktualisiert: {{eventName}}", "event_deleted": "Veranstaltung gelöscht: {{eventName}}", + "email_resent": "Erstellungs-E-Mail erneut gesendet für: {{eventName}}", "category_created": "Kategorie erstellt: {{categoryName}}", "category_updated": "Kategorie aktualisiert: {{categoryName}}", "category_deleted": "Kategorie gelöscht: {{categoryName}}", diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index c69d862..f90defe 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -766,6 +766,7 @@ "settings_updated": "Settings updated", "event_updated": "Event updated: {{eventName}}", "event_deleted": "Event deleted: {{eventName}}", + "email_resent": "Creation email resent for: {{eventName}}", "category_created": "Category created: {{categoryName}}", "category_updated": "Category updated: {{categoryName}}", "category_deleted": "Category deleted: {{categoryName}}",