2025-06-09 21:45:06 +02:00
|
|
|
import nodemailer from 'nodemailer';
|
|
|
|
|
import Imap from 'imap';
|
|
|
|
|
import { encryptCredentials, storeCredentialsInSession } from '~/server/utils/encryption';
|
|
|
|
|
|
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
|
|
|
const xTagHeader = getRequestHeader(event, "x-tag");
|
|
|
|
|
|
|
|
|
|
if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) {
|
|
|
|
|
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const body = await readBody(event);
|
|
|
|
|
const { email, password, imapHost, smtpHost, sessionId } = body;
|
|
|
|
|
|
2025-06-10 12:26:50 +02:00
|
|
|
console.log('[test-connection] Testing email connection for:', email);
|
|
|
|
|
|
2025-06-09 21:45:06 +02:00
|
|
|
if (!email || !password || !sessionId) {
|
|
|
|
|
throw createError({
|
|
|
|
|
statusCode: 400,
|
|
|
|
|
statusMessage: "Email, password, and sessionId are required"
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Use provided hosts or defaults from environment
|
|
|
|
|
const imapHostToUse = imapHost || process.env.NUXT_EMAIL_IMAP_HOST || 'mail.portnimara.com';
|
|
|
|
|
const smtpHostToUse = smtpHost || process.env.NUXT_EMAIL_SMTP_HOST || 'mail.portnimara.com';
|
|
|
|
|
const imapPort = parseInt(process.env.NUXT_EMAIL_IMAP_PORT || '993');
|
|
|
|
|
const smtpPort = parseInt(process.env.NUXT_EMAIL_SMTP_PORT || '587');
|
|
|
|
|
|
2025-06-10 12:26:50 +02:00
|
|
|
console.log('[test-connection] Using IMAP:', imapHostToUse, ':', imapPort);
|
|
|
|
|
console.log('[test-connection] Using SMTP:', smtpHostToUse, ':', smtpPort);
|
|
|
|
|
|
2025-06-09 21:45:06 +02:00
|
|
|
// Test SMTP connection
|
2025-06-10 12:26:50 +02:00
|
|
|
console.log('[test-connection] Testing SMTP connection...');
|
2025-06-09 21:45:06 +02:00
|
|
|
const transporter = nodemailer.createTransport({
|
|
|
|
|
host: smtpHostToUse,
|
|
|
|
|
port: smtpPort,
|
|
|
|
|
secure: false, // false for STARTTLS
|
|
|
|
|
auth: {
|
|
|
|
|
user: email,
|
|
|
|
|
pass: password
|
|
|
|
|
},
|
|
|
|
|
tls: {
|
|
|
|
|
rejectUnauthorized: false // Allow self-signed certificates
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-06-10 12:26:50 +02:00
|
|
|
try {
|
|
|
|
|
await transporter.verify();
|
|
|
|
|
console.log('[test-connection] SMTP connection successful');
|
|
|
|
|
} catch (smtpError: any) {
|
|
|
|
|
console.error('[test-connection] SMTP connection failed:', smtpError);
|
|
|
|
|
throw new Error(`SMTP connection failed: ${smtpError.message || smtpError}`);
|
|
|
|
|
}
|
2025-06-09 21:45:06 +02:00
|
|
|
|
|
|
|
|
// Test IMAP connection
|
|
|
|
|
const imapConfig = {
|
|
|
|
|
user: email,
|
|
|
|
|
password: password,
|
|
|
|
|
host: imapHostToUse,
|
|
|
|
|
port: imapPort,
|
|
|
|
|
tls: true,
|
|
|
|
|
tlsOptions: {
|
|
|
|
|
rejectUnauthorized: false // Allow self-signed certificates
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const testImapConnection = () => {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2025-06-10 12:26:50 +02:00
|
|
|
console.log('[test-connection] Testing IMAP connection...');
|
2025-06-09 21:45:06 +02:00
|
|
|
const imap = new Imap(imapConfig);
|
|
|
|
|
|
2025-06-10 12:26:50 +02:00
|
|
|
// Add a timeout to prevent hanging
|
|
|
|
|
const timeout = setTimeout(() => {
|
|
|
|
|
console.error('[test-connection] IMAP connection timeout');
|
|
|
|
|
imap.end();
|
|
|
|
|
reject(new Error('IMAP connection timeout after 10 seconds'));
|
|
|
|
|
}, 10000); // 10 second timeout
|
|
|
|
|
|
2025-06-09 21:45:06 +02:00
|
|
|
imap.once('ready', () => {
|
2025-06-10 12:26:50 +02:00
|
|
|
console.log('[test-connection] IMAP connection successful');
|
|
|
|
|
clearTimeout(timeout);
|
2025-06-09 21:45:06 +02:00
|
|
|
imap.end();
|
|
|
|
|
resolve(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
imap.once('error', (err: Error) => {
|
2025-06-10 12:26:50 +02:00
|
|
|
console.error('[test-connection] IMAP connection error:', err);
|
|
|
|
|
clearTimeout(timeout);
|
2025-06-09 21:45:06 +02:00
|
|
|
reject(err);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
imap.connect();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-10 12:26:50 +02:00
|
|
|
try {
|
|
|
|
|
await testImapConnection();
|
|
|
|
|
} catch (imapError: any) {
|
|
|
|
|
console.error('[test-connection] IMAP connection failed:', imapError);
|
|
|
|
|
throw new Error(`IMAP connection failed: ${imapError.message || imapError}`);
|
|
|
|
|
}
|
2025-06-09 21:45:06 +02:00
|
|
|
|
|
|
|
|
// If both connections successful, encrypt and store credentials
|
2025-06-10 12:26:50 +02:00
|
|
|
console.log('[test-connection] Both connections successful, storing credentials');
|
2025-06-09 21:45:06 +02:00
|
|
|
const encryptedCredentials = encryptCredentials(email, password);
|
|
|
|
|
storeCredentialsInSession(sessionId, encryptedCredentials);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
message: "Email connection tested successfully",
|
|
|
|
|
email: email
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Email connection test failed:', error);
|
|
|
|
|
if (error instanceof Error) {
|
|
|
|
|
// Check for common authentication errors
|
|
|
|
|
if (error.message.includes('Authentication') || error.message.includes('AUTHENTICATIONFAILED')) {
|
|
|
|
|
throw createError({
|
|
|
|
|
statusCode: 401,
|
|
|
|
|
statusMessage: "Invalid email or password"
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
throw createError({
|
|
|
|
|
statusCode: 500,
|
|
|
|
|
statusMessage: `Connection failed: ${error.message}`
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
throw createError({
|
|
|
|
|
statusCode: 500,
|
|
|
|
|
statusMessage: "An unexpected error occurred",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|