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');
} 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;
} }
role = RoleType.GESTIONNAIRE;
// Statut par défaut : EN_ATTENTE (sauf si super admin qui peut forcer) } else if (dto.role === RoleType.ADMINISTRATEUR) {
const statut = isSuperAdmin if (!isAdmin && !isSuperAdmin) {
? dto.statut ?? StatutUtilisateurType.EN_ATTENTE throw new ForbiddenException('Seuls les administrateurs peuvent créer un administrateur');
: StatutUtilisateurType.EN_ATTENTE; }
role = RoleType.ADMINISTRATEUR;
// Vérification spécifique pour assistantes maternelles } else if (dto.role === RoleType.ASSISTANTE_MATERNELLE) {
if (role === RoleType.ASSISTANTE_MATERNELLE && !dto.photo_url) { role = RoleType.ASSISTANTE_MATERNELLE;
if (!dto.photo_url) {
throw new BadRequestException( throw new BadRequestException(
'La photo de profil est obligatoire pour les assistantes maternelles.', 'La photo de profil est obligatoire pour les assistantes maternelles.',
); );
} }
} else {
// Vérification des champs obligatoires role = RoleType.PARENT;
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 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; 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');