SMTP Config
This commit is contained in:
@ -1,173 +1,241 @@
|
|||||||
// app/api/contact/route.js
|
// app/api/contact/route.js
|
||||||
// ❌ REMOVE "use client" from here - API routes must NOT have this directive
|
|
||||||
|
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from 'next/server';
|
||||||
import nodemailer from 'nodemailer';
|
import nodemailer from 'nodemailer';
|
||||||
|
|
||||||
// Create transporter with Zoho configuration
|
// Test environment variables function
|
||||||
const createTransport = () => {
|
function testEnvironmentVariables() {
|
||||||
return nodemailer.createTransport({
|
console.log('\n🔍 === TESTING ENVIRONMENT VARIABLES ===');
|
||||||
|
|
||||||
|
const envVars = {
|
||||||
|
ZOHO_EMAIL: process.env.ZOHO_EMAIL,
|
||||||
|
ZOHO_PASSWORD: process.env.ZOHO_PASSWORD,
|
||||||
|
RECIPIENT_EMAIL: process.env.RECIPIENT_EMAIL,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('Environment check:');
|
||||||
|
Object.entries(envVars).forEach(([key, value]) => {
|
||||||
|
if (value) {
|
||||||
|
console.log(`✅ ${key}: ${key === 'ZOHO_PASSWORD' ? value.slice(0, 4) + '*'.repeat(value.length - 4) : value}`);
|
||||||
|
} else {
|
||||||
|
console.log(`❌ ${key}: MISSING`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const missing = Object.entries(envVars).filter(([key, value]) => !value);
|
||||||
|
if (missing.length > 0) {
|
||||||
|
console.log('❌ Missing variables:', missing.map(([key]) => key).join(', '));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('✅ All environment variables are set');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test SMTP connection with multiple configurations
|
||||||
|
async function testSMTPConnection() {
|
||||||
|
console.log('\n🔍 === TESTING SMTP CONNECTION ===');
|
||||||
|
|
||||||
|
// Configuration 1: SSL with port 465 (Recommended for Zoho)
|
||||||
|
const config1 = {
|
||||||
|
host: 'smtp.zoho.com',
|
||||||
|
port: 465,
|
||||||
|
secure: true, // SSL
|
||||||
|
auth: {
|
||||||
|
user: process.env.ZOHO_EMAIL,
|
||||||
|
pass: process.env.ZOHO_PASSWORD,
|
||||||
|
},
|
||||||
|
debug: false,
|
||||||
|
logger: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Configuration 2: STARTTLS with port 587
|
||||||
|
const config2 = {
|
||||||
host: 'smtp.zoho.com',
|
host: 'smtp.zoho.com',
|
||||||
port: 587,
|
port: 587,
|
||||||
secure: false,
|
secure: false,
|
||||||
|
requireTLS: true,
|
||||||
|
auth: {
|
||||||
|
user: process.env.ZOHO_EMAIL,
|
||||||
|
pass: process.env.ZOHO_PASSWORD,
|
||||||
|
},
|
||||||
|
debug: false,
|
||||||
|
logger: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Configuration 3: Alternative host for domain emails
|
||||||
|
const config3 = {
|
||||||
|
host: 'smtp.zoho.in',
|
||||||
|
port: 465,
|
||||||
|
secure: true,
|
||||||
|
auth: {
|
||||||
|
user: process.env.ZOHO_EMAIL,
|
||||||
|
pass: process.env.ZOHO_PASSWORD,
|
||||||
|
},
|
||||||
|
debug: false,
|
||||||
|
logger: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const configs = [
|
||||||
|
{ name: 'SSL Port 465 (smtp.zoho.com)', config: config1 },
|
||||||
|
{ name: 'STARTTLS Port 587 (smtp.zoho.com)', config: config2 },
|
||||||
|
{ name: 'SSL Port 465 (smtp.zoho.in)', config: config3 }
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const { name, config } of configs) {
|
||||||
|
try {
|
||||||
|
console.log(`📡 Testing ${name}...`);
|
||||||
|
const transporter = nodemailer.createTransport(config);
|
||||||
|
await transporter.verify();
|
||||||
|
console.log(`✅ SMTP connection successful with ${name}`);
|
||||||
|
return { success: true, transporter, config };
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`❌ ${name} failed: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: new Error('All SMTP configurations failed. Please check your credentials and enable App Password.')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create transporter with the successful configuration
|
||||||
|
const createTransporter = (config = null) => {
|
||||||
|
// Use the config that worked during testing, or fall back to SSL default
|
||||||
|
const defaultConfig = {
|
||||||
|
host: 'smtp.zoho.com',
|
||||||
|
port: 465,
|
||||||
|
secure: true, // SSL
|
||||||
auth: {
|
auth: {
|
||||||
user: process.env.ZOHO_EMAIL,
|
user: process.env.ZOHO_EMAIL,
|
||||||
pass: process.env.ZOHO_PASSWORD,
|
pass: process.env.ZOHO_PASSWORD,
|
||||||
},
|
},
|
||||||
debug: true,
|
debug: true,
|
||||||
logger: true,
|
logger: true,
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle Newsletter Subscription
|
|
||||||
async function handleNewsletter(data) {
|
|
||||||
console.log('Processing newsletter subscription for:', data.email);
|
|
||||||
|
|
||||||
const transporter = createTransport();
|
|
||||||
|
|
||||||
const mailOptions = {
|
|
||||||
from: process.env.ZOHO_EMAIL,
|
|
||||||
to: process.env.RECIPIENT_EMAIL,
|
|
||||||
subject: 'New Newsletter Subscription - Keystone Solutions',
|
|
||||||
html: `
|
|
||||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
||||||
<h2 style="color: #ff3a2d;">New Newsletter Subscription</h2>
|
|
||||||
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
|
||||||
<p><strong>Email:</strong> ${data.email}</p>
|
|
||||||
<p><strong>Subscribed at:</strong> ${new Date().toLocaleString()}</p>
|
|
||||||
</div>
|
|
||||||
<hr style="margin: 20px 0;">
|
|
||||||
<p style="color: #666; font-size: 14px;">
|
|
||||||
This email was sent from your website's newsletter subscription form.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await transporter.sendMail(mailOptions);
|
return nodemailer.createTransport(config || defaultConfig);
|
||||||
console.log('Newsletter email sent successfully:', result.messageId);
|
};
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Contact Form
|
// Handle Contact Form
|
||||||
async function handleContact(data) {
|
async function handleContact(data, smtpConfig = null) {
|
||||||
console.log('Processing contact form for:', data.fullName, data.email);
|
console.log('📝 Processing contact form...');
|
||||||
|
|
||||||
const transporter = createTransport();
|
const transporter = createTransporter(smtpConfig);
|
||||||
|
|
||||||
const mailOptions = {
|
const mailOptions = {
|
||||||
from: process.env.ZOHO_EMAIL,
|
from: process.env.ZOHO_EMAIL,
|
||||||
to: process.env.RECIPIENT_EMAIL,
|
to: process.env.RECIPIENT_EMAIL,
|
||||||
subject: 'New Contact Form Submission - Keystone Solutions',
|
replyTo: data.email, // User can reply directly to the person who submitted the form
|
||||||
|
subject: `New Contact Form Submission from ${data.fullName} - Keystone Solutions`,
|
||||||
html: `
|
html: `
|
||||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||||
<h2 style="color: #ff3a2d;">New Contact Form Submission</h2>
|
<h2 style="color: #ff3a2d;">New Contact Form Submission</h2>
|
||||||
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
||||||
<p><strong>Full Name:</strong> ${data.fullName}</p>
|
<p><strong>Full Name:</strong> ${data.fullName}</p>
|
||||||
<p><strong>Email:</strong> ${data.email}</p>
|
<p><strong>Email:</strong> <a href="mailto:${data.email}">${data.email}</a></p>
|
||||||
<p><strong>Phone:</strong> ${data.phone || 'Not provided'}</p>
|
<p><strong>Phone:</strong> ${data.phone || 'Not provided'}</p>
|
||||||
<p><strong>Message:</strong></p>
|
<p><strong>Message:</strong></p>
|
||||||
<div style="background: white; padding: 15px; border-left: 4px solid #ff3a2d; margin: 10px 0;">
|
<div style="background: white; padding: 15px; border-left: 4px solid #ff3a2d; margin: 10px 0;">
|
||||||
${data.message || 'No message provided'}
|
${data.message || 'No message provided'}
|
||||||
</div>
|
</div>
|
||||||
<p><strong>Submitted at:</strong> ${new Date().toLocaleString()}</p>
|
<p><strong>Submitted at:</strong> ${new Date().toLocaleString()}</p>
|
||||||
|
<hr style="margin: 20px 0; border: none; border-top: 1px solid #ddd;">
|
||||||
|
<p style="font-size: 12px; color: #666;">
|
||||||
|
💡 <strong>Tip:</strong> Click "Reply" to respond directly to ${data.fullName} at ${data.email}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<hr style="margin: 20px 0;">
|
|
||||||
<p style="color: #666; font-size: 14px;">
|
|
||||||
This email was sent from your website's contact form.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('📧 Attempting to send email...');
|
||||||
const result = await transporter.sendMail(mailOptions);
|
const result = await transporter.sendMail(mailOptions);
|
||||||
console.log('Contact email sent successfully:', result.messageId);
|
console.log('✅ Email sent successfully:', result.messageId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Career Form
|
// Handle Career Form
|
||||||
async function handleCareer(data) {
|
async function handleCareer(data, smtpConfig = null) {
|
||||||
console.log('Processing career form for:', data.fullName, data.email);
|
console.log('📝 Processing career form...');
|
||||||
|
|
||||||
const transporter = createTransport();
|
const transporter = createTransporter(smtpConfig);
|
||||||
|
|
||||||
const attachments = [];
|
|
||||||
|
|
||||||
// Handle file attachment if present
|
|
||||||
if (data.resume) {
|
|
||||||
console.log('Resume file attached:', data.resume.name);
|
|
||||||
attachments.push({
|
|
||||||
filename: data.resume.name,
|
|
||||||
content: Buffer.from(data.resume.data, 'base64'),
|
|
||||||
contentType: data.resume.type,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const mailOptions = {
|
const mailOptions = {
|
||||||
from: process.env.ZOHO_EMAIL,
|
from: process.env.ZOHO_EMAIL,
|
||||||
to: process.env.RECIPIENT_EMAIL,
|
to: process.env.RECIPIENT_EMAIL,
|
||||||
subject: 'New Career Application - Keystone Solutions',
|
replyTo: data.email, // User can reply directly to the applicant
|
||||||
|
subject: `New Career Application from ${data.fullName} for ${data.roles} - Keystone Solutions`,
|
||||||
html: `
|
html: `
|
||||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||||
<h2 style="color: #ff3a2d;">New Career Application</h2>
|
<h2 style="color: #ff3a2d;">New Career Application</h2>
|
||||||
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
|
||||||
<p><strong>Full Name:</strong> ${data.fullName}</p>
|
<p><strong>Full Name:</strong> ${data.fullName}</p>
|
||||||
<p><strong>Email:</strong> ${data.email}</p>
|
<p><strong>Email:</strong> <a href="mailto:${data.email}">${data.email}</a></p>
|
||||||
<p><strong>Phone:</strong> ${data.phone}</p>
|
<p><strong>Phone:</strong> <a href="tel:${data.phone}">${data.phone}</a></p>
|
||||||
<p><strong>Roles of Interest:</strong> ${data.roles}</p>
|
<p><strong>Roles of Interest:</strong> ${data.roles}</p>
|
||||||
<p><strong>Resume:</strong> ${data.resume ? 'Attached' : 'Not provided'}</p>
|
<p><strong>Resume:</strong> ${data.resume ? `📎 ${data.resume.name} (attached)` : 'Not provided'}</p>
|
||||||
<p><strong>Applied at:</strong> ${new Date().toLocaleString()}</p>
|
<p><strong>Applied at:</strong> ${new Date().toLocaleString()}</p>
|
||||||
|
<hr style="margin: 20px 0; border: none; border-top: 1px solid #ddd;">
|
||||||
|
<p style="font-size: 12px; color: #666;">
|
||||||
|
💡 <strong>Tip:</strong> Click "Reply" to respond directly to ${data.fullName} at ${data.email}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<hr style="margin: 20px 0;">
|
|
||||||
<p style="color: #666; font-size: 14px;">
|
|
||||||
This email was sent from your website's career application form.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
attachments: attachments,
|
attachments: data.resume ? [{
|
||||||
|
filename: data.resume.name,
|
||||||
|
content: data.resume.data,
|
||||||
|
encoding: 'base64'
|
||||||
|
}] : []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('📧 Attempting to send career application email...');
|
||||||
const result = await transporter.sendMail(mailOptions);
|
const result = await transporter.sendMail(mailOptions);
|
||||||
console.log('Career email sent successfully:', result.messageId);
|
console.log('✅ Career application email sent successfully:', result.messageId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST handler for all form submissions
|
// POST handler with comprehensive debugging
|
||||||
export async function POST(request) {
|
export async function POST(request) {
|
||||||
console.log('\n🚀 === EMAIL API ROUTE STARTED ===');
|
console.log('\n🚀 === CONTACT API ROUTE STARTED ===');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check environment variables first
|
// Step 1: Test environment variables
|
||||||
const requiredEnvVars = {
|
const envTest = testEnvironmentVariables();
|
||||||
ZOHO_EMAIL: process.env.ZOHO_EMAIL,
|
if (!envTest) {
|
||||||
ZOHO_PASSWORD: process.env.ZOHO_PASSWORD,
|
|
||||||
RECIPIENT_EMAIL: process.env.RECIPIENT_EMAIL,
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('Environment variables check:');
|
|
||||||
Object.entries(requiredEnvVars).forEach(([key, value]) => {
|
|
||||||
console.log(`${key}: ${value ? '✅ Set' : '❌ Missing'}`);
|
|
||||||
});
|
|
||||||
console.log(
|
|
||||||
'Loaded password (first 3 chars):',
|
|
||||||
process.env.ZOHO_PASSWORD?.slice(0, 3)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!requiredEnvVars.ZOHO_EMAIL || !requiredEnvVars.ZOHO_PASSWORD || !requiredEnvVars.RECIPIENT_EMAIL) {
|
|
||||||
console.error('❌ Missing required environment variables');
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Email configuration missing' },
|
{
|
||||||
|
error: 'Environment variables missing',
|
||||||
|
details: 'Please check your .env.local file'
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Test SMTP connection
|
||||||
|
const smtpTest = await testSMTPConnection();
|
||||||
|
if (!smtpTest.success) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: 'SMTP connection failed',
|
||||||
|
details: smtpTest.error.message,
|
||||||
|
code: smtpTest.error.code
|
||||||
|
},
|
||||||
{ status: 500 }
|
{ status: 500 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse request body
|
// Step 3: Parse request body
|
||||||
|
console.log('\n📝 === PARSING REQUEST ===');
|
||||||
let body;
|
let body;
|
||||||
try {
|
try {
|
||||||
body = await request.json();
|
body = await request.json();
|
||||||
console.log('✅ Request body parsed successfully');
|
console.log('✅ Request parsed successfully');
|
||||||
|
console.log('Form type:', body.type);
|
||||||
|
console.log('Data keys:', Object.keys(body).join(', '));
|
||||||
} catch (parseError) {
|
} catch (parseError) {
|
||||||
console.error('❌ Failed to parse request body:', parseError);
|
console.error('❌ Failed to parse request:', parseError.message);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Invalid JSON in request body' },
|
{ error: 'Invalid JSON in request body' },
|
||||||
{ status: 400 }
|
{ status: 400 }
|
||||||
@ -175,92 +243,84 @@ export async function POST(request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { type, ...data } = body;
|
const { type, ...data } = body;
|
||||||
console.log(`📝 Form type: ${type}`);
|
|
||||||
console.log(`📋 Form data keys: ${Object.keys(data).join(', ')}`);
|
|
||||||
|
|
||||||
|
// Step 4: Validate request
|
||||||
if (!type) {
|
if (!type) {
|
||||||
console.error('❌ No form type specified');
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Form type is required' },
|
{ error: 'Form type is required' },
|
||||||
{ status: 400 }
|
{ status: 400 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route to appropriate handler based on form type
|
if (!['contact', 'career'].includes(type)) {
|
||||||
let result;
|
return NextResponse.json(
|
||||||
switch (type) {
|
{ error: 'Invalid form type' },
|
||||||
case 'newsletter':
|
{ status: 400 }
|
||||||
if (!data.email) {
|
);
|
||||||
console.error('❌ Newsletter: Email is required');
|
|
||||||
return NextResponse.json({ error: 'Email is required' }, { status: 400 });
|
|
||||||
}
|
|
||||||
result = await handleNewsletter(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'contact':
|
|
||||||
if (!data.fullName || !data.email) {
|
|
||||||
console.error('❌ Contact: Full name and email are required');
|
|
||||||
return NextResponse.json({ error: 'Full name and email are required' }, { status: 400 });
|
|
||||||
}
|
|
||||||
result = await handleContact(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'career':
|
|
||||||
if (!data.fullName || !data.email || !data.phone) {
|
|
||||||
console.error('❌ Career: Full name, email, and phone are required');
|
|
||||||
return NextResponse.json({ error: 'Full name, email, and phone are required' }, { status: 400 });
|
|
||||||
}
|
|
||||||
result = await handleCareer(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
console.error('❌ Invalid form type:', type);
|
|
||||||
return NextResponse.json({ error: 'Invalid form type' }, { status: 400 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('✅ Email sent successfully!');
|
// Common validation
|
||||||
console.log('📧 Message ID:', result.messageId);
|
if (!data.fullName || !data.email) {
|
||||||
console.log('🎉 === EMAIL API ROUTE SUCCESS ===\n');
|
return NextResponse.json(
|
||||||
|
{ error: 'Full name and email are required' },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Career form specific validation
|
||||||
|
if (type === 'career') {
|
||||||
|
if (!data.phone || !data.roles) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Phone and roles are required for career applications' },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5: Send email based on form type
|
||||||
|
console.log('\n📧 === SENDING EMAIL ===');
|
||||||
|
let result;
|
||||||
|
|
||||||
|
if (type === 'contact') {
|
||||||
|
result = await handleContact(data, smtpTest.config);
|
||||||
|
} else if (type === 'career') {
|
||||||
|
result = await handleCareer(data, smtpTest.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🎉 === SUCCESS ===');
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
message: 'Email sent successfully',
|
message: 'Email sent successfully',
|
||||||
messageId: result.messageId,
|
messageId: result.messageId,
|
||||||
type: type
|
type: type
|
||||||
},
|
},
|
||||||
{ status: 200 }
|
{ status: 200 }
|
||||||
);
|
);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('\n💥 === EMAIL API ROUTE ERROR ===');
|
console.error('\n💥 === ERROR OCCURRED ===');
|
||||||
console.error('Error name:', error.name);
|
console.error('Error name:', error.name);
|
||||||
console.error('Error message:', error.message);
|
console.error('Error message:', error.message);
|
||||||
console.error('Error code:', error.code);
|
console.error('Error code:', error.code);
|
||||||
console.error('Error stack:', error.stack);
|
console.error('Full error:', error);
|
||||||
|
|
||||||
// Provide more specific error messages
|
// Determine specific error response
|
||||||
let errorMessage = 'Failed to send email';
|
let errorMessage = 'Failed to send email';
|
||||||
let statusCode = 500;
|
let statusCode = 500;
|
||||||
|
|
||||||
if (error.code === 'EAUTH') {
|
if (error.code === 'EAUTH') {
|
||||||
errorMessage = 'Authentication failed. Please check your Zoho email and app password.';
|
errorMessage = 'Email authentication failed. Check your Zoho credentials.';
|
||||||
console.error('🔐 Authentication issue - check ZOHO_EMAIL and ZOHO_PASSWORD');
|
|
||||||
} else if (error.code === 'ECONNECTION' || error.code === 'ETIMEDOUT') {
|
} else if (error.code === 'ECONNECTION' || error.code === 'ETIMEDOUT') {
|
||||||
errorMessage = 'Connection to email server failed. Please try again.';
|
errorMessage = 'Connection to email server failed.';
|
||||||
console.error('🌐 Network connection issue');
|
} else if (error.message?.includes('Invalid login')) {
|
||||||
} else if (error.code === 'EMESSAGE') {
|
errorMessage = 'Invalid email or password. Please check your Zoho app password.';
|
||||||
errorMessage = 'Invalid email message format.';
|
|
||||||
statusCode = 400;
|
|
||||||
console.error('📧 Email format issue');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('💥 === END ERROR DETAILS ===\n');
|
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
error: errorMessage,
|
error: errorMessage,
|
||||||
details: error.message,
|
details: error.message,
|
||||||
code: error.code
|
code: error.code || 'UNKNOWN'
|
||||||
},
|
},
|
||||||
{ status: statusCode }
|
{ status: statusCode }
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user