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