Neah version mail remove mail correction 2 ??

This commit is contained in:
alma 2025-04-16 20:37:03 +02:00
parent f9ebf07855
commit 0de53ddb6e
2 changed files with 261 additions and 71 deletions

View File

@ -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(

View File

@ -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(