fix: Ensure email configuration from environment variables is properly used

Fixed an issue where SMTP configuration would fall back to defaults despite
environment variables being set in docker-compose.yml. The email utility now
properly accesses runtime configuration by accepting the H3 event context.

Changes:
- Created getEmailConfig() helper with dual-strategy config access
- Pass event context from API handlers to email functions
- Added fallback to direct process.env access for reliability
- Added debug logging to diagnose configuration issues in production

This ensures Office365 and other SMTP providers work correctly when configured
via environment variables.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-05 18:11:13 -05:00
parent a689bee58b
commit 47b4a14c4b
3 changed files with 47 additions and 7 deletions

View File

@@ -31,7 +31,7 @@ export default defineEventHandler(async (event) => {
// Send email // Send email
try { try {
await sendPasswordResetEmail(email, code) await sendPasswordResetEmail(email, code, event)
} catch (error) { } catch (error) {
console.error('Failed to send reset email:', error) console.error('Failed to send reset email:', error)
throw createError({ throw createError({

View File

@@ -89,7 +89,8 @@ export default defineEventHandler(async (event) => {
bibleReferencesText, bibleReferencesText,
sermon.personal_appliance, sermon.personal_appliance,
sermon.pastors_challenge, sermon.pastors_challenge,
userNotes userNotes,
event
) )
return { return {

View File

@@ -1,8 +1,46 @@
import nodemailer from 'nodemailer' import nodemailer from 'nodemailer'
import crypto from 'crypto' import crypto from 'crypto'
import type { H3Event } from 'h3'
export async function sendPasswordResetEmail(email: string, code: string) { /**
const config = useRuntimeConfig() * Get email configuration from runtime config or environment variables
* In production, environment variables are accessed directly for reliability
*/
function getEmailConfig(event?: H3Event) {
// Try to use runtime config if event is provided
if (event) {
try {
const config = useRuntimeConfig(event)
return {
emailHost: config.emailHost,
emailPort: config.emailPort,
emailUser: config.emailUser,
emailPassword: config.emailPassword,
emailFrom: config.emailFrom,
}
} catch (e) {
console.warn('[EMAIL] Failed to access runtime config, falling back to env vars')
}
}
// Fallback to direct environment variable access
return {
emailHost: process.env.EMAIL_HOST || 'smtp.example.com',
emailPort: process.env.EMAIL_PORT || '587',
emailUser: process.env.EMAIL_USER || 'noreply@example.com',
emailPassword: process.env.EMAIL_PASSWORD || '',
emailFrom: process.env.EMAIL_FROM || 'New Life Christian Church <noreply@example.com>',
}
}
export async function sendPasswordResetEmail(email: string, code: string, event?: H3Event) {
const config = getEmailConfig(event)
// Debug logging for email configuration
console.log('[EMAIL CONFIG] Host:', config.emailHost)
console.log('[EMAIL CONFIG] Port:', config.emailPort)
console.log('[EMAIL CONFIG] User:', config.emailUser)
console.log('[EMAIL CONFIG] From:', config.emailFrom)
const transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
host: config.emailHost, host: config.emailHost,
@@ -82,9 +120,10 @@ export async function sendSermonNotesEmail(
bibleReferences: string, bibleReferences: string,
personalAppliance: string, personalAppliance: string,
pastorsChallenge: string, pastorsChallenge: string,
userNotes: string userNotes: string,
event?: H3Event
) { ) {
const config = useRuntimeConfig() const config = getEmailConfig(event)
const transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
host: config.emailHost, host: config.emailHost,