205 lines
4.2 KiB
TypeScript
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;
|
|
}
|
|
|