- Updated `env.example` to include NextAuth configuration for authentication. - Added `next-auth` dependency to manage user sessions. - Introduced `User` model in Prisma schema with fields for user details and password hashing. - Integrated `AuthProvider` in layout for session management across the app. - Enhanced `Header` component with `AuthButton` for user authentication controls.
151 lines
3.2 KiB
TypeScript
151 lines
3.2 KiB
TypeScript
import { prisma } from './core/database'
|
|
import bcrypt from 'bcryptjs'
|
|
|
|
export interface CreateUserData {
|
|
email: string
|
|
name?: string
|
|
firstName?: string
|
|
lastName?: string
|
|
avatar?: string
|
|
role?: string
|
|
password: string
|
|
}
|
|
|
|
export interface User {
|
|
id: string
|
|
email: string
|
|
name: string | null
|
|
firstName: string | null
|
|
lastName: string | null
|
|
avatar: string | null
|
|
role: string
|
|
isActive: boolean
|
|
lastLoginAt: Date | null
|
|
createdAt: Date
|
|
updatedAt: Date
|
|
}
|
|
|
|
export const usersService = {
|
|
async createUser(data: CreateUserData): Promise<User> {
|
|
const hashedPassword = await bcrypt.hash(data.password, 12)
|
|
|
|
const user = await prisma.user.create({
|
|
data: {
|
|
email: data.email,
|
|
name: data.name,
|
|
firstName: data.firstName,
|
|
lastName: data.lastName,
|
|
avatar: data.avatar,
|
|
role: data.role || 'user',
|
|
password: hashedPassword,
|
|
},
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
firstName: true,
|
|
lastName: true,
|
|
avatar: true,
|
|
role: true,
|
|
isActive: true,
|
|
lastLoginAt: true,
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
}
|
|
})
|
|
|
|
return user
|
|
},
|
|
|
|
async getUserByEmail(email: string) {
|
|
return await prisma.user.findUnique({
|
|
where: { email },
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
firstName: true,
|
|
lastName: true,
|
|
avatar: true,
|
|
role: true,
|
|
isActive: true,
|
|
lastLoginAt: true,
|
|
password: true,
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
}
|
|
})
|
|
},
|
|
|
|
async getUserById(id: string): Promise<User | null> {
|
|
return await prisma.user.findUnique({
|
|
where: { id },
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
firstName: true,
|
|
lastName: true,
|
|
avatar: true,
|
|
role: true,
|
|
isActive: true,
|
|
lastLoginAt: true,
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
}
|
|
})
|
|
},
|
|
|
|
async verifyPassword(password: string, hashedPassword: string): Promise<boolean> {
|
|
return await bcrypt.compare(password, hashedPassword)
|
|
},
|
|
|
|
async emailExists(email: string): Promise<boolean> {
|
|
const user = await prisma.user.findUnique({
|
|
where: { email },
|
|
select: { id: true }
|
|
})
|
|
return !!user
|
|
},
|
|
|
|
async updateLastLogin(userId: string): Promise<void> {
|
|
await prisma.user.update({
|
|
where: { id: userId },
|
|
data: { lastLoginAt: new Date() }
|
|
})
|
|
},
|
|
|
|
async updateUser(userId: string, data: {
|
|
name?: string | null
|
|
firstName?: string | null
|
|
lastName?: string | null
|
|
avatar?: string | null
|
|
}): Promise<User> {
|
|
const user = await prisma.user.update({
|
|
where: { id: userId },
|
|
data: {
|
|
name: data.name,
|
|
firstName: data.firstName,
|
|
lastName: data.lastName,
|
|
avatar: data.avatar,
|
|
updatedAt: new Date(),
|
|
},
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
firstName: true,
|
|
lastName: true,
|
|
avatar: true,
|
|
role: true,
|
|
isActive: true,
|
|
lastLoginAt: true,
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
}
|
|
})
|
|
|
|
return user
|
|
}
|
|
}
|