172 lines
5.1 KiB
TypeScript
172 lines
5.1 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { cookies } from 'next/headers';
|
|
import Imap from 'imap';
|
|
|
|
interface StoredCredentials {
|
|
email: string;
|
|
password: string;
|
|
host: string;
|
|
port: number;
|
|
}
|
|
|
|
function getStoredCredentials(): StoredCredentials | null {
|
|
const cookieStore = cookies();
|
|
const credentialsCookie = cookieStore.get('imap_credentials');
|
|
|
|
if (!credentialsCookie?.value) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const credentials = JSON.parse(credentialsCookie.value);
|
|
if (!credentials.email || !credentials.password || !credentials.host || !credentials.port) {
|
|
return null;
|
|
}
|
|
return credentials;
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const { emailIds, action } = await request.json();
|
|
|
|
if (!emailIds || !Array.isArray(emailIds) || !action) {
|
|
return NextResponse.json(
|
|
{ error: 'Invalid request parameters' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Get the current folder from the request URL
|
|
const url = new URL(request.url);
|
|
const folder = url.searchParams.get('folder') || 'INBOX';
|
|
|
|
// Get stored credentials
|
|
const credentials = getStoredCredentials();
|
|
if (!credentials) {
|
|
return NextResponse.json(
|
|
{ error: 'No stored credentials found' },
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
|
const imap = new Imap({
|
|
user: credentials.email,
|
|
password: credentials.password,
|
|
host: credentials.host,
|
|
port: credentials.port,
|
|
tls: true,
|
|
tlsOptions: { rejectUnauthorized: false },
|
|
authTimeout: 30000,
|
|
connTimeout: 30000
|
|
});
|
|
|
|
const timeout = setTimeout(() => {
|
|
console.error('IMAP connection timeout');
|
|
imap.end();
|
|
resolve(NextResponse.json({ error: 'Connection timeout' }));
|
|
}, 30000);
|
|
|
|
imap.once('error', (err: Error) => {
|
|
console.error('IMAP error:', err);
|
|
clearTimeout(timeout);
|
|
resolve(NextResponse.json({ error: 'IMAP connection error' }));
|
|
});
|
|
|
|
imap.once('ready', () => {
|
|
imap.openBox(folder, false, (err, box) => {
|
|
if (err) {
|
|
console.error(`Error opening box ${folder}:`, err);
|
|
clearTimeout(timeout);
|
|
imap.end();
|
|
resolve(NextResponse.json({ error: `Failed to open folder ${folder}` }));
|
|
return;
|
|
}
|
|
|
|
// Convert string IDs to numbers
|
|
const numericIds = emailIds.map(id => parseInt(id, 10));
|
|
|
|
// Process each email
|
|
let processedCount = 0;
|
|
const totalEmails = numericIds.length;
|
|
|
|
const processNextEmail = (index: number) => {
|
|
if (index >= totalEmails) {
|
|
clearTimeout(timeout);
|
|
imap.end();
|
|
resolve(NextResponse.json({ success: true }));
|
|
return;
|
|
}
|
|
|
|
const id = numericIds[index];
|
|
const fetch = imap.fetch(id.toString(), {
|
|
bodies: '',
|
|
struct: true
|
|
});
|
|
|
|
fetch.on('message', (msg) => {
|
|
msg.once('attributes', (attrs) => {
|
|
const uid = attrs.uid;
|
|
if (!uid) {
|
|
processedCount++;
|
|
processNextEmail(index + 1);
|
|
return;
|
|
}
|
|
|
|
switch (action) {
|
|
case 'delete':
|
|
imap.move(uid, 'Trash', (err) => {
|
|
if (err) console.error('Error moving to trash:', err);
|
|
processedCount++;
|
|
processNextEmail(index + 1);
|
|
});
|
|
break;
|
|
case 'mark-read':
|
|
imap.addFlags(uid, ['\\Seen'], (err) => {
|
|
if (err) console.error('Error marking as read:', err);
|
|
processedCount++;
|
|
processNextEmail(index + 1);
|
|
});
|
|
break;
|
|
case 'mark-unread':
|
|
imap.removeFlags(uid, ['\\Seen'], (err) => {
|
|
if (err) console.error('Error marking as unread:', err);
|
|
processedCount++;
|
|
processNextEmail(index + 1);
|
|
});
|
|
break;
|
|
case 'archive':
|
|
imap.move(uid, 'Archive', (err) => {
|
|
if (err) console.error('Error moving to archive:', err);
|
|
processedCount++;
|
|
processNextEmail(index + 1);
|
|
});
|
|
break;
|
|
}
|
|
});
|
|
});
|
|
|
|
fetch.on('error', (err) => {
|
|
console.error('Error fetching email:', err);
|
|
processedCount++;
|
|
processNextEmail(index + 1);
|
|
});
|
|
};
|
|
|
|
processNextEmail(0);
|
|
});
|
|
});
|
|
|
|
imap.connect();
|
|
});
|
|
} catch (error) {
|
|
console.error('Error in bulk actions:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to perform bulk action' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|