import bcrypt from 'bcryptjs' import jwt from 'jsonwebtoken' import { prisma } from '@/lib/db' export async function createUser(email: string, password: string, name?: string) { const passwordHash = await bcrypt.hash(password, 10) return prisma.user.create({ data: { email, passwordHash, name } }) } export async function validateUser(email: string, password: string) { const user = await prisma.user.findUnique({ where: { email } }) if (!user) return null const isValid = await bcrypt.compare(password, user.passwordHash) return isValid ? user : null } export function generateToken(userId: string): string { return jwt.sign({ userId }, process.env.JWT_SECRET!, { expiresIn: '7d' }) } export async function verifyToken(token: string) { try { console.log('Server: Verifying token with JWT_SECRET exists:', !!process.env.JWT_SECRET) const payload = jwt.verify(token, process.env.JWT_SECRET!) as { userId: string } console.log('Server: Token verification successful, userId:', payload.userId) return payload } catch (error) { console.log('Server: Token verification failed:', (error as any)?.message || error) throw new Error('Invalid token') } } export async function getUserFromToken(token: string) { try { console.log('Server: Getting user from token...') const payload = await verifyToken(token) console.log('Server: Token payload userId:', payload.userId) // Use raw query to avoid Prisma client sync issues const users = await prisma.$queryRaw` SELECT id, email, name, role, theme, "fontSize", "createdAt", "updatedAt", "lastLoginAt" FROM "User" WHERE id = ${payload.userId} ` const user = Array.isArray(users) && users.length > 0 ? users[0] : null console.log('Server: User query result:', !!user) if (user) { console.log('Server: User found - email:', user.email) } else { console.log('Server: No user found with id:', payload.userId) } return user } catch (error) { console.log('Server: getUserFromToken error:', (error as any)?.message || error) return null } } export function isTokenExpired(token: string): boolean { try { const payload = jwt.decode(token) as { exp?: number } if (!payload || !payload.exp) return true const currentTime = Math.floor(Date.now() / 1000) return payload.exp < currentTime } catch (error) { return true } }