From 098075010f2999ca1c7acb564dd5fea74f38d1b1 Mon Sep 17 00:00:00 2001 From: alma Date: Mon, 28 Apr 2025 15:02:52 +0200 Subject: [PATCH] courrier multi account restore compose --- lib/services/email-service.ts | 101 +++++++++++++++++----------------- lib/types.ts | 2 + 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/lib/services/email-service.ts b/lib/services/email-service.ts index 1e9cd0a7..2b05df46 100644 --- a/lib/services/email-service.ts +++ b/lib/services/email-service.ts @@ -288,34 +288,30 @@ export async function getEmails( } try { - // Select the mailbox and wait for it to be fully opened - const mailbox = await client.mailboxOpen(folder); - if (!mailbox) { - throw new Error(`Failed to open mailbox ${folder}`); - } + // Open the mailbox + await client.mailboxOpen(folder); - // Get total count from the mailbox object - const totalEmails = mailbox.exists || 0; + // Get total count of messages + const status = await client.status(folder, { messages: true }); + const totalEmails = status.messages || 0; const totalPages = Math.ceil(totalEmails / perPage); - // Calculate range for this page - const start = Math.max(1, totalEmails - (page * perPage) + 1); - const end = Math.max(1, totalEmails - ((page - 1) * perPage)); + // Calculate the range of messages to fetch + const start = (page - 1) * perPage + 1; + const end = Math.min(start + perPage - 1, totalEmails); + + const emails: EmailMessage[] = []; - // Only fetch if we have messages if (totalEmails > 0) { - // Fetch messages + // Fetch messages in the specified range const messages = await client.fetch(`${start}:${end}`, { envelope: true, flags: true, bodyStructure: true, - internalDate: true, size: true, bodyParts: ['HEADER'] }); - - // Process messages - const emails: EmailMessage[] = []; + for await (const message of messages) { const email: EmailMessage = { id: message.uid.toString(), @@ -340,47 +336,48 @@ export async function getEmails( hasAttachments: message.bodyStructure?.childNodes?.some(node => node.disposition === 'attachment') || false, folder: folder, contentFetched: false, - accountId: accountId + accountId: accountId, + content: '', + messageId: message.envelope?.messageId || undefined }; emails.push(email); } - - const result: EmailListResult = { - emails, - totalEmails, - page, - perPage, - totalPages, - folder, - mailboxes: await getMailboxes(client) - }; - - // Cache the result with the correct accountId - await cacheEmailList(userId, accountId || 'default', folder, page, perPage, result); - - return result; - } else { - // Return empty result for empty folders - const result: EmailListResult = { - emails: [], - totalEmails: 0, - page, - perPage, - totalPages: 0, - folder, - mailboxes: await getMailboxes(client) - }; - - // Cache the empty result - await cacheEmailList(userId, accountId || 'default', folder, page, perPage, result); - - return result; } - } catch (error) { - console.error(`Error fetching emails for ${userId}${accountId ? ` account ${accountId}` : ''}:`, error); - throw error; + + const result: EmailListResult = { + emails, + totalEmails, + page, + perPage, + totalPages, + folder, + mailboxes: await getMailboxes(client) + }; + + // Cache the result with the correct accountId + await cacheEmailList(userId, accountId || 'default', folder, page, perPage, result); + + // Invalidate cache for other accounts' folders to prevent stale data + if (accountId) { + const accounts = await prisma.mailCredentials.findMany({ + where: { userId }, + select: { id: true } + }); + + for (const account of accounts) { + if (account.id !== accountId) { + await invalidateFolderCache(userId, account.id, folder); + } + } + } + + return result; } finally { - // Don't close the connection, it's managed by the connection pool + try { + await client.mailboxClose(); + } catch (error) { + console.error('Error closing mailbox:', error); + } } } diff --git a/lib/types.ts b/lib/types.ts index 22c986b3..ce46f726 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -53,6 +53,8 @@ export interface EmailMessage { folder: string; contentFetched: boolean; accountId?: string; + messageId?: string; + attachments?: EmailAttachment[]; } export interface Account {