Files
biblical-guide.com/lib/auth/index.ts
andupetcu 196ca00194 Fix authentication state persistence and admin role display
- Implement complete authentication system with JWT token validation
- Add auth provider with persistent login state across page refreshes
- Create multilingual login/register forms with Material-UI components
- Fix token validation using raw SQL queries to bypass Prisma sync issues
- Add comprehensive error handling for expired/invalid tokens
- Create profile and settings pages with full i18n support
- Add proper user role management (admin/user) with database sync
- Implement secure middleware with CSRF protection and auth checks
- Add debug endpoints for troubleshooting authentication issues
- Fix Zustand store persistence for authentication state

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-21 01:06:30 +03:00

72 lines
2.3 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.message)
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.message)
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
}
}