73 lines
2.4 KiB
TypeScript
73 lines
2.4 KiB
TypeScript
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
|
|
}
|
|
}
|