diff --git a/app/api/mail/login/route.ts b/app/api/mail/login/route.ts index 2cff5255..214d320d 100644 --- a/app/api/mail/login/route.ts +++ b/app/api/mail/login/route.ts @@ -1,16 +1,19 @@ import { NextResponse } from 'next/server'; import { ImapFlow } from 'imapflow'; -import { cookies } from 'next/headers'; - -interface StoredCredentials { - email: string; - password: string; - host: string; - port: number; -} +import { getServerSession } from 'next-auth'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route'; +import { prisma } from '@/lib/prisma'; export async function POST(request: Request) { try { + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + const { email, password, host, port } = await request.json(); if (!email || !password || !host || !port) { @@ -37,22 +40,24 @@ export async function POST(request: Request) { await client.connect(); await client.mailboxOpen('INBOX'); - // Store credentials in cookie - const cookieStore = cookies(); - const credentials: StoredCredentials = { - email, - password, - host, - port: parseInt(port) - }; - - // Set the cookie with proper security options - cookieStore.set('imap_credentials', JSON.stringify(credentials), { - httpOnly: true, - secure: process.env.NODE_ENV === 'production', - sameSite: 'lax', - path: '/', - maxAge: 30 * 24 * 60 * 60 // 30 days + // Store or update credentials in database + await prisma.mailCredentials.upsert({ + where: { + userId: session.user.id + }, + update: { + email, + password, + host, + port: parseInt(port) + }, + create: { + userId: session.user.id, + email, + password, + host, + port: parseInt(port) + } }); return NextResponse.json({ success: true }); @@ -90,25 +95,38 @@ export async function POST(request: Request) { } export async function GET() { - const cookieStore = cookies(); - const credentialsCookie = cookieStore.get('imap_credentials'); - - if (!credentialsCookie?.value) { - return NextResponse.json( - { error: 'No stored credentials found' }, - { status: 404 } - ); - } - try { - const credentials = JSON.parse(credentialsCookie.value); - // Return credentials without password for security - const { password, ...safeCredentials } = credentials; - return NextResponse.json(safeCredentials); + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + + const credentials = await prisma.mailCredentials.findUnique({ + where: { + userId: session.user.id + }, + select: { + email: true, + host: true, + port: true + } + }); + + if (!credentials) { + return NextResponse.json( + { error: 'No stored credentials found' }, + { status: 404 } + ); + } + + return NextResponse.json(credentials); } catch (error) { return NextResponse.json( - { error: 'Invalid credentials format' }, - { status: 400 } + { error: 'Failed to retrieve credentials' }, + { status: 500 } ); } } \ No newline at end of file diff --git a/app/api/mail/route.ts b/app/api/mail/route.ts index 192f0684..8febce3d 100644 --- a/app/api/mail/route.ts +++ b/app/api/mail/route.ts @@ -1,30 +1,41 @@ import { NextResponse } from 'next/server'; -import { cookies } from 'next/headers'; import { ImapFlow } from 'imapflow'; +import { getServerSession } from 'next-auth'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route'; +import { prisma } from '@/lib/prisma'; export async function GET() { try { - const cookieStore = cookies(); - const credentials = cookieStore.get('imap_credentials'); + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + + const credentials = await prisma.mailCredentials.findUnique({ + where: { + userId: session.user.id + } + }); if (!credentials) { return NextResponse.json( - { error: 'No credentials found. Please login to your email account first.' }, + { error: 'No mail credentials found. Please configure your email account.' }, { status: 401 } ); } let client; try { - const { email, password, host, port } = JSON.parse(credentials.value); - client = new ImapFlow({ - host, - port: parseInt(port), + host: credentials.host, + port: credentials.port, secure: true, auth: { - user: email, - pass: password, + user: credentials.email, + pass: credentials.password, }, logger: false, emitLogs: false @@ -50,7 +61,7 @@ export async function GET() { if (error instanceof Error) { if (error.message.includes('Invalid login')) { return NextResponse.json( - { error: 'Invalid email credentials. Please login again.' }, + { error: 'Invalid email credentials. Please update your email settings.' }, { status: 401 } ); } diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 0500d83d..73858801 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -19,6 +19,7 @@ model User { updatedAt DateTime @updatedAt calendars Calendar[] events Event[] + mailCredentials MailCredentials? } model Calendar { @@ -51,5 +52,19 @@ model Event { user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([calendarId]) + @@index([userId]) +} + +model MailCredentials { + id String @id @default(uuid()) + userId String @unique + email String + password String + host String + port Int + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + @@index([userId]) } \ No newline at end of file