170 lines
4.6 KiB
TypeScript
170 lines
4.6 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { getServerSession } from 'next-auth';
|
|
import { authOptions } from "@/app/api/auth/options";
|
|
import { getMailboxes } from '@/lib/services/email-service';
|
|
import { ImapFlow } from 'imapflow';
|
|
import { prisma } from '@/lib/prisma';
|
|
import { getCachedEmailCredentials } from '@/lib/redis';
|
|
|
|
export async function GET(request: Request) {
|
|
// Verify auth
|
|
const session = await getServerSession(authOptions);
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json(
|
|
{ error: 'Unauthorized' },
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
const { searchParams } = new URL(request.url);
|
|
const accountId = searchParams.get('accountId');
|
|
const userId = session.user.id;
|
|
|
|
try {
|
|
// If specific accountId is provided, get folders for that account
|
|
if (accountId) {
|
|
// Get account from database
|
|
const account = await prisma.mailCredentials.findFirst({
|
|
where: {
|
|
id: accountId,
|
|
userId
|
|
},
|
|
select: {
|
|
email: true,
|
|
password: true,
|
|
host: true,
|
|
port: true
|
|
}
|
|
});
|
|
|
|
if (!account) {
|
|
return NextResponse.json(
|
|
{ error: 'Account not found' },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
// Connect to IMAP server for this account
|
|
const client = new ImapFlow({
|
|
host: account.host,
|
|
port: account.port,
|
|
secure: true,
|
|
auth: {
|
|
user: account.email,
|
|
pass: account.password,
|
|
},
|
|
logger: false,
|
|
tls: {
|
|
rejectUnauthorized: false
|
|
}
|
|
});
|
|
|
|
try {
|
|
await client.connect();
|
|
|
|
// Get folders for this account
|
|
const folders = await getMailboxes(client);
|
|
|
|
// Close connection
|
|
await client.logout();
|
|
|
|
return NextResponse.json({
|
|
accountId,
|
|
email: account.email,
|
|
folders
|
|
});
|
|
} catch (error) {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to connect to IMAP server',
|
|
details: error instanceof Error ? error.message : 'Unknown error'
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
} else {
|
|
// Get all accounts for this user
|
|
const accounts = await prisma.mailCredentials.findMany({
|
|
where: { userId },
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
password: true,
|
|
host: true,
|
|
port: true
|
|
}
|
|
});
|
|
|
|
if (accounts.length === 0) {
|
|
return NextResponse.json({
|
|
accounts: []
|
|
});
|
|
}
|
|
|
|
// Fetch folders for each account individually
|
|
const accountsWithFolders = await Promise.all(accounts.map(async (account) => {
|
|
try {
|
|
// Connect to IMAP server for this specific account
|
|
const client = new ImapFlow({
|
|
host: account.host,
|
|
port: account.port,
|
|
secure: true,
|
|
auth: {
|
|
user: account.email,
|
|
pass: account.password,
|
|
},
|
|
logger: false,
|
|
tls: {
|
|
rejectUnauthorized: false
|
|
}
|
|
});
|
|
|
|
await client.connect();
|
|
|
|
// Get folders for this account
|
|
const folders = await getMailboxes(client);
|
|
|
|
// Close connection
|
|
await client.logout();
|
|
|
|
// Add display_name and color from database
|
|
const metadata = await prisma.$queryRaw`
|
|
SELECT display_name, color
|
|
FROM "MailCredentials"
|
|
WHERE id = ${account.id}
|
|
`;
|
|
|
|
const displayMetadata = Array.isArray(metadata) && metadata.length > 0 ? metadata[0] : {};
|
|
|
|
return {
|
|
id: account.id,
|
|
email: account.email,
|
|
display_name: displayMetadata.display_name || account.email,
|
|
color: displayMetadata.color || "#0082c9",
|
|
folders
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching folders for account ${account.email}:`, error);
|
|
// Return fallback folders on error
|
|
return {
|
|
id: account.id,
|
|
email: account.email,
|
|
folders: ['INBOX', 'Sent', 'Drafts', 'Trash'] // Fallback folders on error
|
|
};
|
|
}
|
|
}));
|
|
|
|
return NextResponse.json({
|
|
accounts: accountsWithFolders
|
|
});
|
|
}
|
|
} catch (error) {
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to get account folders',
|
|
details: error instanceof Error ? error.message : 'Unknown error'
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|