gestion des roles pour user service

This commit is contained in:
sdraris 2025-09-19 13:40:40 +02:00
parent 6b82af49ae
commit bceffda1e8

View File

@ -1,4 +1,4 @@
import { BadRequestException, ConflictException, ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
import { BadRequestException, ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { RoleType, StatutUtilisateurType, Users } from "src/entities/users.entity";
import { Repository } from "typeorm";
@ -17,58 +17,51 @@ export class UserService {
private readonly validationRepository: Repository<Validation>
) { }
// Création utilisateur
async createUser(dto: CreateUserDto, currentUser?: Users): Promise<Users> {
// Vérification CGU
if (!dto.cguAccepted) {
throw new BadRequestException(
'Vous devez accepter les CGU et la Politique de confidentialité pour créer un compte.',
);
}
// Déterminer si le créateur est super admin
const isSuperAdmin = currentUser?.role === RoleType.SUPER_ADMIN;
const exist = await this.usersRepository.findOneBy({ email: dto.email });
if (exist) throw new ConflictException('Email déjà utilisé');
if (exist) throw new BadRequestException('Email déjà utilisé');
const isSuperAdmin = currentUser?.role === RoleType.SUPER_ADMIN;
const isAdmin = currentUser?.role === RoleType.ADMINISTRATEUR;
let role: RoleType;
if (isSuperAdmin) {
// Un super admin peut créer n'importe quel rôle
role = dto.role;
} else if (dto.role === RoleType.ASSISTANTE_MATERNELLE) {
// Autoriser l'auto-inscription des AM
role = RoleType.ASSISTANTE_MATERNELLE;
} else {
// Tous les autres cas → forcer en PARENT
role = RoleType.PARENT;
if (dto.role === RoleType.GESTIONNAIRE) {
if (!isAdmin && !isSuperAdmin) {
throw new ForbiddenException('Seuls les administrateurs peuvent créer un gestionnaire');
}
// Statut par défaut : EN_ATTENTE (sauf si super admin qui peut forcer)
const statut = isSuperAdmin
? dto.statut ?? StatutUtilisateurType.EN_ATTENTE
: StatutUtilisateurType.EN_ATTENTE;
// Vérification spécifique pour assistantes maternelles
if (role === RoleType.ASSISTANTE_MATERNELLE && !dto.photo_url) {
role = RoleType.GESTIONNAIRE;
} else if (dto.role === RoleType.ADMINISTRATEUR) {
if (!isAdmin && !isSuperAdmin) {
throw new ForbiddenException('Seuls les administrateurs peuvent créer un administrateur');
}
role = RoleType.ADMINISTRATEUR;
} else if (dto.role === RoleType.ASSISTANTE_MATERNELLE) {
role = RoleType.ASSISTANTE_MATERNELLE;
if (!dto.photo_url) {
throw new BadRequestException(
'La photo de profil est obligatoire pour les assistantes maternelles.',
);
}
// Vérification des champs obligatoires
if (!dto.nom?.trim()) {
throw new BadRequestException('Nom est obligatoire.');
} else if (!dto.prenom?.trim()) {
throw new BadRequestException('Prénom est obligatoire.');
} else if (!dto.adresse?.trim()) {
throw new BadRequestException('Adresse est obligatoire.');
} else if (!dto.telephone?.trim()) {
throw new BadRequestException('Téléphone est obligatoire.');
} else {
role = RoleType.PARENT;
}
// Gestion consentement photo
const statut = isSuperAdmin
? dto.statut ?? StatutUtilisateurType.EN_ATTENTE
: StatutUtilisateurType.EN_ATTENTE;
if (!dto.nom?.trim()) throw new BadRequestException('Nom est obligatoire.');
if (!dto.prenom?.trim()) throw new BadRequestException('Prénom est obligatoire.');
if (!dto.adresse?.trim()) throw new BadRequestException('Adresse est obligatoire.');
if (!dto.telephone?.trim()) throw new BadRequestException('Téléphone est obligatoire.');
let consentDate: Date | undefined;
if (dto.consentement_photo && dto.date_consentement_photo) {
const parsed = new Date(dto.date_consentement_photo);
@ -77,11 +70,9 @@ export class UserService {
}
}
// Hash mot de passe
const salt = await bcrypt.genSalt();
const hashedPassword = await bcrypt.hash(dto.password, salt);
// Création de lentité
const entity = this.usersRepository.create({
email: dto.email,
password: hashedPassword,
@ -97,15 +88,16 @@ export class UserService {
photo_url: dto.photo_url,
consentement_photo: dto.consentement_photo ?? false,
date_consentement_photo: consentDate,
changement_mdp_obligatoire: dto.changement_mdp_obligatoire ?? false,
changement_mdp_obligatoire:
role === RoleType.ADMINISTRATEUR || role === RoleType.GESTIONNAIRE
? true
: dto.changement_mdp_obligatoire ?? false,
});
const saved = await this.usersRepository.save(entity);
return this.findOne(saved.id);
}
async findAll(): Promise<Users[]> {
return this.usersRepository.find();
}
@ -134,11 +126,23 @@ export class UserService {
throw new ForbiddenException('Accès réservé aux super admins');
}
// Empêcher de modifier le flag changement_mdp_obligatoire pour admin/gestionnaire
if (
(user.role === RoleType.ADMINISTRATEUR || user.role === RoleType.GESTIONNAIRE) &&
dto.changement_mdp_obligatoire === false
) {
throw new ForbiddenException(
'Impossible de désactiver lobligation de changement de mot de passe pour ce rôle',
);
}
// Gestion du mot de passe
if (dto.password) {
const salt = await bcrypt.genSalt();
user.password = await bcrypt.hash(dto.password, salt);
delete (dto as any).password;
// Une fois le mot de passe changé, on peut lever lobligation
user.changement_mdp_obligatoire = false;
}
// Conversion de la date de consentement
@ -153,6 +157,7 @@ export class UserService {
return this.usersRepository.save(user);
}
async validateUser(user_id: string, currentUser: Users, comment?: string): Promise<Users> {
if (![RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE].includes(currentUser.role)) {
throw new ForbiddenException('Accès réservé aux super admins, administrateurs et gestionnaires');