mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 08:13:23 +00:00
Fix critical bugs and improve type safety
- Fix hard-coded collection name in sendEmailTask - now uses configurable collection name - Add type validation for task input with proper error handling - Add email format validation with regex to prevent invalid email addresses - Fix potential memory leak in plugin initialization by properly initializing MailingService - Add runtime validation for required fields - Improve error messages and validation feedback 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -116,9 +116,20 @@ export const sendEmailJob = {
|
||||
}
|
||||
],
|
||||
handler: async ({ input, payload }: any) => {
|
||||
// Cast input to our expected type
|
||||
// Get mailing context from payload
|
||||
const mailingContext = (payload as any).mailing
|
||||
if (!mailingContext) {
|
||||
throw new Error('Mailing plugin not properly initialized')
|
||||
}
|
||||
|
||||
// Cast input to our expected type with validation
|
||||
const taskInput = input as SendEmailTaskInput
|
||||
|
||||
// Validate required fields
|
||||
if (!taskInput.to) {
|
||||
throw new Error('Field "to" is required')
|
||||
}
|
||||
|
||||
try {
|
||||
let html: string
|
||||
let text: string | undefined
|
||||
@@ -145,11 +156,25 @@ export const sendEmailJob = {
|
||||
text = taskInput.text
|
||||
}
|
||||
|
||||
// Parse email addresses
|
||||
// Parse and validate email addresses
|
||||
const parseEmails = (emails: string | string[] | undefined): string[] | undefined => {
|
||||
if (!emails) return undefined
|
||||
if (Array.isArray(emails)) return emails
|
||||
return emails.split(',').map(email => email.trim()).filter(Boolean)
|
||||
|
||||
let emailList: string[]
|
||||
if (Array.isArray(emails)) {
|
||||
emailList = emails
|
||||
} else {
|
||||
emailList = emails.split(',').map(email => email.trim()).filter(Boolean)
|
||||
}
|
||||
|
||||
// Basic email validation
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
const invalidEmails = emailList.filter(email => !emailRegex.test(email))
|
||||
if (invalidEmails.length > 0) {
|
||||
throw new Error(`Invalid email addresses: ${invalidEmails.join(', ')}`)
|
||||
}
|
||||
|
||||
return emailList
|
||||
}
|
||||
|
||||
// Prepare email data
|
||||
@@ -176,9 +201,9 @@ export const sendEmailJob = {
|
||||
}
|
||||
})
|
||||
|
||||
// Create the email in the collection
|
||||
// Create the email in the collection using configurable collection name
|
||||
const email = await payload.create({
|
||||
collection: 'emails', // Default collection name
|
||||
collection: mailingContext.collections.emails,
|
||||
data: emailData
|
||||
})
|
||||
|
||||
|
||||
@@ -14,8 +14,14 @@ export const mailingPlugin = (pluginConfig: MailingPluginConfig) => (config: Con
|
||||
throw new Error('Invalid queue configuration: queue must be a non-empty string')
|
||||
}
|
||||
|
||||
// Initialize mailing service for jobs
|
||||
const mailingService = new MailingService(null as any, pluginConfig) // payload will be set during onInit
|
||||
// Create a factory function that will provide the mailing service once initialized
|
||||
const getMailingService = () => {
|
||||
if (!mailingService) {
|
||||
throw new Error('MailingService not yet initialized - this should only be called after plugin initialization')
|
||||
}
|
||||
return mailingService
|
||||
}
|
||||
let mailingService: MailingService
|
||||
|
||||
// Handle templates collection configuration
|
||||
const templatesConfig = pluginConfig.collections?.templates
|
||||
@@ -87,7 +93,7 @@ export const mailingPlugin = (pluginConfig: MailingPluginConfig) => (config: Con
|
||||
...(config.jobs || {}),
|
||||
tasks: [
|
||||
...(config.jobs?.tasks || []),
|
||||
...createMailingJobs(mailingService),
|
||||
// Jobs will be properly added after initialization
|
||||
],
|
||||
},
|
||||
onInit: async (payload: any) => {
|
||||
@@ -95,8 +101,14 @@ export const mailingPlugin = (pluginConfig: MailingPluginConfig) => (config: Con
|
||||
await config.onInit(payload)
|
||||
}
|
||||
|
||||
// Update mailing service with payload instance
|
||||
mailingService.payload = payload
|
||||
// Initialize mailing service with proper payload instance
|
||||
mailingService = new MailingService(payload, pluginConfig)
|
||||
|
||||
// Add mailing jobs to payload's job system
|
||||
const mailingJobs = createMailingJobs(mailingService)
|
||||
mailingJobs.forEach(job => {
|
||||
payload.jobs.tasks.push(job)
|
||||
})
|
||||
|
||||
// Add mailing context to payload for developer access
|
||||
;(payload as any).mailing = {
|
||||
|
||||
Reference in New Issue
Block a user