Files
workshop-manager/src/services/auth.ts

205 lines
4.2 KiB
TypeScript

import { hash } from 'bcryptjs';
import { prisma } from '@/services/database';
export interface RegisterInput {
email: string;
password: string;
name?: string;
}
export interface AuthResult {
success: boolean;
error?: string;
user?: {
id: string;
email: string;
name: string | null;
};
}
export async function registerUser(input: RegisterInput): Promise<AuthResult> {
const { email, password, name } = input;
// Check if user already exists
const existingUser = await prisma.user.findUnique({
where: { email },
});
if (existingUser) {
return {
success: false,
error: 'Un compte existe déjà avec cet email',
};
}
// Hash password
const hashedPassword = await hash(password, 12);
// Create user
const user = await prisma.user.create({
data: {
email,
password: hashedPassword,
name: name || null,
},
});
return {
success: true,
user: {
id: user.id,
email: user.email,
name: user.name,
},
};
}
export async function getUserByEmail(email: string) {
return prisma.user.findUnique({
where: { email },
});
}
export async function getUserById(id: string) {
return prisma.user.findUnique({
where: { id },
});
}
export interface UpdateProfileInput {
name?: string;
email?: string;
}
export async function updateUserProfile(
userId: string,
input: UpdateProfileInput
): Promise<AuthResult> {
const { name, email } = input;
// If changing email, check it's not already taken
if (email) {
const existingUser = await prisma.user.findFirst({
where: {
email,
NOT: { id: userId },
},
});
if (existingUser) {
return {
success: false,
error: 'Cet email est déjà utilisé par un autre compte',
};
}
}
const user = await prisma.user.update({
where: { id: userId },
data: {
...(name !== undefined && { name: name || null }),
...(email && { email }),
},
});
return {
success: true,
user: {
id: user.id,
email: user.email,
name: user.name,
},
};
}
export async function updateUserPassword(
userId: string,
currentPassword: string,
newPassword: string
): Promise<{ success: boolean; error?: string }> {
const { compare } = await import('bcryptjs');
const user = await prisma.user.findUnique({
where: { id: userId },
});
if (!user) {
return { success: false, error: 'Utilisateur non trouvé' };
}
// Verify current password
const isValid = await compare(currentPassword, user.password);
if (!isValid) {
return { success: false, error: 'Mot de passe actuel incorrect' };
}
// Hash new password
const hashedPassword = await hash(newPassword, 12);
await prisma.user.update({
where: { id: userId },
data: { password: hashedPassword },
});
return { success: true };
}
export interface UserStats {
sessions: number;
motivatorSessions: number;
sharedSessions: number;
sharedMotivatorSessions: number;
}
export interface UserWithStats {
id: string;
email: string;
name: string | null;
createdAt: Date;
updatedAt: Date;
_count: UserStats;
}
export async function getAllUsersWithStats(): Promise<UserWithStats[]> {
const users = await prisma.user.findMany({
select: {
id: true,
email: true,
name: true,
createdAt: true,
updatedAt: true,
_count: {
select: {
sessions: true,
sharedSessions: true,
},
},
},
orderBy: { createdAt: 'desc' },
});
// Get motivator sessions count separately (Prisma doesn't have these in User model _count directly)
const usersWithMotivators = await Promise.all(
users.map(async (user) => {
const motivatorCount = await prisma.movingMotivatorsSession.count({
where: { userId: user.id },
});
const sharedMotivatorCount = await prisma.mMSessionShare.count({
where: { userId: user.id },
});
return {
...user,
_count: {
...user._count,
motivatorSessions: motivatorCount,
sharedMotivatorSessions: sharedMotivatorCount,
},
};
})
);
return usersWithMotivators;
}