27 lines
1.1 KiB
TypeScript
27 lines
1.1 KiB
TypeScript
|
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
||
|
|
import { prisma } from '@/lib/prisma'
|
||
|
|
import { verifyPassword, createSession, SESSION_COOKIE, SESSION_EXPIRY_DAYS } from '@/lib/auth'
|
||
|
|
|
||
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||
|
|
if (req.method !== 'POST') return res.status(405).end()
|
||
|
|
|
||
|
|
const { email, password } = req.body || {}
|
||
|
|
if (!email || !password) return res.status(400).json({ error: 'Email and password are required' })
|
||
|
|
|
||
|
|
const user = await prisma.user.findUnique({ where: { email: String(email).trim().toLowerCase() } })
|
||
|
|
if (!user || !user.active) return res.status(401).json({ error: 'Invalid email or password' })
|
||
|
|
|
||
|
|
const ok = await verifyPassword(password, user.password)
|
||
|
|
if (!ok) return res.status(401).json({ error: 'Invalid email or password' })
|
||
|
|
|
||
|
|
const token = await createSession(user.id)
|
||
|
|
const maxAge = SESSION_EXPIRY_DAYS * 24 * 60 * 60
|
||
|
|
res.setHeader(
|
||
|
|
'Set-Cookie',
|
||
|
|
`${SESSION_COOKIE}=${token}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${maxAge}`
|
||
|
|
)
|
||
|
|
|
||
|
|
const { password: _pw, ...safe } = user
|
||
|
|
return res.json({ user: safe })
|
||
|
|
}
|