feat: add authentication support and user model
- 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.
This commit is contained in:
150
src/services/users.ts
Normal file
150
src/services/users.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user