Neah version mail remove mail correction 2 ??
This commit is contained in:
parent
f9ebf07855
commit
0de53ddb6e
@ -1,5 +1,32 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getImapClient } from '@/lib/imap';
|
||||
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 {
|
||||
@ -16,53 +43,125 @@ export async function POST(request: Request) {
|
||||
const url = new URL(request.url);
|
||||
const folder = url.searchParams.get('folder') || 'INBOX';
|
||||
|
||||
// Get the IMAP client using the same method as the mail endpoint
|
||||
const imap = await getImapClient();
|
||||
if (!imap) {
|
||||
// Get stored credentials
|
||||
const credentials = getStoredCredentials();
|
||||
if (!credentials) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to connect to mail server' },
|
||||
{ status: 500 }
|
||||
{ error: 'No stored credentials found' },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
// Convert string IDs to numbers
|
||||
const numericIds = emailIds.map(id => parseInt(id, 10));
|
||||
|
||||
// Get mailbox lock for the current folder
|
||||
const lock = await imap.getMailboxLock(folder);
|
||||
|
||||
try {
|
||||
// Fetch messages to get their UIDs
|
||||
const messages = await imap.fetch({
|
||||
seq: numericIds.map(id => id.toString()),
|
||||
uid: true,
|
||||
envelope: true
|
||||
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
|
||||
});
|
||||
|
||||
// Process each message based on the action
|
||||
for await (const message of messages) {
|
||||
if (!message.uid) continue;
|
||||
const timeout = setTimeout(() => {
|
||||
console.error('IMAP connection timeout');
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ error: 'Connection timeout' }));
|
||||
}, 30000);
|
||||
|
||||
switch (action) {
|
||||
case 'delete':
|
||||
await imap.messageMove(message.uid, 'Trash');
|
||||
break;
|
||||
case 'mark-read':
|
||||
await imap.messageFlagsAdd(message.uid, ['\\Seen'], { uid: true });
|
||||
break;
|
||||
case 'mark-unread':
|
||||
await imap.messageFlagsRemove(message.uid, ['\\Seen'], { uid: true });
|
||||
break;
|
||||
case 'archive':
|
||||
await imap.messageMove(message.uid, 'Archive');
|
||||
break;
|
||||
}
|
||||
}
|
||||
imap.once('error', (err: Error) => {
|
||||
console.error('IMAP error:', err);
|
||||
clearTimeout(timeout);
|
||||
resolve(NextResponse.json({ error: 'IMAP connection error' }));
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} finally {
|
||||
lock.release();
|
||||
}
|
||||
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(
|
||||
|
||||
@ -1,5 +1,32 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getImapClient } from '@/lib/imap';
|
||||
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 {
|
||||
@ -16,44 +43,108 @@ export async function POST(request: Request) {
|
||||
const url = new URL(request.url);
|
||||
const folder = url.searchParams.get('folder') || 'INBOX';
|
||||
|
||||
// Get the IMAP client using the same method as the mail endpoint
|
||||
const imap = await getImapClient();
|
||||
if (!imap) {
|
||||
// Get stored credentials
|
||||
const credentials = getStoredCredentials();
|
||||
if (!credentials) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to connect to mail server' },
|
||||
{ status: 500 }
|
||||
{ error: 'No stored credentials found' },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
// Convert string ID to number
|
||||
const numericId = parseInt(emailId, 10);
|
||||
|
||||
// Get mailbox lock for the current folder
|
||||
const lock = await imap.getMailboxLock(folder);
|
||||
|
||||
try {
|
||||
// Fetch message to get its UID
|
||||
const messages = await imap.fetch({
|
||||
seq: numericId.toString(),
|
||||
uid: true,
|
||||
envelope: true
|
||||
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
|
||||
});
|
||||
|
||||
// Process the message
|
||||
for await (const message of messages) {
|
||||
if (!message.uid) continue;
|
||||
const timeout = setTimeout(() => {
|
||||
console.error('IMAP connection timeout');
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ error: 'Connection timeout' }));
|
||||
}, 30000);
|
||||
|
||||
if (isRead) {
|
||||
await imap.messageFlagsAdd(message.uid, ['\\Seen'], { uid: true });
|
||||
} else {
|
||||
await imap.messageFlagsRemove(message.uid, ['\\Seen'], { uid: true });
|
||||
}
|
||||
}
|
||||
imap.once('error', (err: Error) => {
|
||||
console.error('IMAP error:', err);
|
||||
clearTimeout(timeout);
|
||||
resolve(NextResponse.json({ error: 'IMAP connection error' }));
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} finally {
|
||||
lock.release();
|
||||
}
|
||||
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 ID to number
|
||||
const numericId = parseInt(emailId, 10);
|
||||
|
||||
const fetch = imap.fetch(numericId.toString(), {
|
||||
bodies: '',
|
||||
struct: true
|
||||
});
|
||||
|
||||
fetch.on('message', (msg) => {
|
||||
msg.once('attributes', (attrs) => {
|
||||
const uid = attrs.uid;
|
||||
if (!uid) {
|
||||
clearTimeout(timeout);
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ error: 'No UID found for email' }));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isRead) {
|
||||
imap.addFlags(uid, ['\\Seen'], (err) => {
|
||||
if (err) {
|
||||
console.error('Error marking as read:', err);
|
||||
clearTimeout(timeout);
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ error: 'Failed to mark as read' }));
|
||||
return;
|
||||
}
|
||||
clearTimeout(timeout);
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ success: true }));
|
||||
});
|
||||
} else {
|
||||
imap.removeFlags(uid, ['\\Seen'], (err) => {
|
||||
if (err) {
|
||||
console.error('Error marking as unread:', err);
|
||||
clearTimeout(timeout);
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ error: 'Failed to mark as unread' }));
|
||||
return;
|
||||
}
|
||||
clearTimeout(timeout);
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ success: true }));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
fetch.on('error', (err) => {
|
||||
console.error('Error fetching email:', err);
|
||||
clearTimeout(timeout);
|
||||
imap.end();
|
||||
resolve(NextResponse.json({ error: 'Failed to fetch email' }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
imap.connect();
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error marking email as read:', error);
|
||||
return NextResponse.json(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user