NeahNew/lib/imap.ts
2025-05-05 13:04:01 +02:00

86 lines
2.4 KiB
TypeScript

import { ImapFlow } from 'imapflow';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/app/api/auth/options";
import { prisma } from '@/lib/prisma';
import { getCachedEmailCredentials } from '@/lib/redis';
export async function getImapClient() {
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
throw new Error('No authenticated user');
}
// First try to get credentials from Redis cache
let credentials = await getCachedEmailCredentials(session.user.id);
// If not in cache, get from database
if (!credentials) {
console.log(`Credentials not found in cache for ${session.user.id}, checking database`);
credentials = await prisma.mailCredentials.findUnique({
where: {
userId: session.user.id
}
});
}
if (!credentials) {
throw new Error('No mail credentials found. Please configure your email account.');
}
// Validate credentials
if (!credentials.password) {
throw new Error('No password configured for email account');
}
return new ImapFlow({
host: credentials.host,
port: credentials.port,
secure: true,
auth: {
user: credentials.email,
pass: credentials.password,
},
logger: false,
tls: {
rejectUnauthorized: false
}
});
}
export async function moveEmails(emailIds: number[], targetFolder: string) {
const imap = await getImapClient();
const lock = await imap.getMailboxLock('INBOX');
try {
for (const id of emailIds) {
const message = await imap.fetchOne(id.toString(), { uid: true });
if (message) {
const uid = typeof message.uid === 'number' ? message.uid.toString() : message.uid;
await imap.messageMove(uid, targetFolder);
}
}
} finally {
lock.release();
}
}
export async function markAsRead(emailIds: (string | number)[], isRead: boolean) {
const imap = await getImapClient();
try {
await imap.connect();
const lock = await imap.getMailboxLock('INBOX');
try {
for (const id of emailIds) {
const stringId = typeof id === 'number' ? id.toString() : id;
const message = await imap.fetchOne(stringId, { uid: true });
if (message) {
const uid = typeof message.uid === 'number' ? message.uid.toString() : message.uid;
await imap.messageFlagsAdd(uid, isRead ? ['\\Seen'] : [], { uid: true });
}
}
} finally {
lock.release();
}
} finally {
await imap.logout();
}
}