correction + authguard current id corrected

This commit is contained in:
sdraris 2025-10-01 15:43:36 +02:00
parent 78c155c910
commit 05529d299b
4 changed files with 40 additions and 49 deletions

View File

@ -11,7 +11,7 @@ export class AuthGuard implements CanActivate {
private readonly jwtService: JwtService,
private readonly reflector: Reflector,
private readonly configService: ConfigService,
) { }
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
@ -24,8 +24,8 @@ export class AuthGuard implements CanActivate {
if (request.path.startsWith('/api-docs')) {
return true;
}
const authHeader = request.headers['authorization'] as string | undefined;
const authHeader = request.headers['authorization'] as string | undefined;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw new UnauthorizedException('Token manquant ou invalide');
}
@ -35,7 +35,12 @@ export class AuthGuard implements CanActivate {
const payload = await this.jwtService.verifyAsync(token, {
secret: this.configService.get<string>('jwt.accessSecret'),
});
request.user = payload;
request.user = {
...payload,
id: payload.sub,
};
return true;
} catch (error) {
throw new UnauthorizedException('Token invalide ou expiré');

View File

@ -1,5 +1,5 @@
import { ApiProperty } from "@nestjs/swagger";
import { IsBoolean, IsDateString, IsEnum, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, ValidateIf } from "class-validator";
import { IsBoolean, IsDateString, IsEnum, IsNotEmpty, IsOptional, IsString, MaxLength, ValidateIf } from "class-validator";
import { GenreType, StatutEnfantType } from "src/entities/children.entity";
export class CreateEnfantsDto {
@ -54,10 +54,4 @@ export class CreateEnfantsDto {
@ApiProperty({ default: false })
@IsBoolean()
is_multiple: boolean;
@ApiProperty({ example: 'UUID-parent' })
@IsUUID()
@IsNotEmpty()
id_parent: string;
}

View File

@ -3,56 +3,50 @@ import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagg
import { RolesGuard } from 'src/common/guards/roles.guard';
import { EnfantsService } from './enfants.service';
import { Roles } from 'src/common/decorators/roles.decorator';
import { RoleType } from 'src/entities/users.entity';
import { Children } from 'src/entities/children.entity';
import { RoleType, Users } from 'src/entities/users.entity';
import { CreateEnfantsDto } from './dto/create_enfants.dto';
import { EnfantResponseDto } from './dto/enfants_response.dto';
import { mapEnfantsToResponseDto, mapEnfantToResponseDto } from './enfants.mapper';
import { AuthGuard } from 'src/common/guards/auth.guard';
import { User } from 'src/common/decorators/user.decorator';
@ApiBearerAuth('access-token')
@ApiTags('Enfants')
@UseGuards(AuthGuard,RolesGuard)
@UseGuards(AuthGuard, RolesGuard)
@Controller('enfants')
export class EnfantsController {
constructor(private readonly enfantsService: EnfantsService) { }
// Inscrire un enfant
@Post()
@ApiOperation({ summary: 'Inscrire un enfant' })
@ApiResponse({ status: 201, type: EnfantResponseDto, description: 'L\'enfant a été inscrit avec succès.' })
@Roles(RoleType.PARENT, RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE)
async create(@Body() dto: CreateEnfantsDto): Promise<EnfantResponseDto> {
const enfant = await this.enfantsService.create(dto);
// Mapper l'entité enfant vers le DTO de réponse
async create(
@Body() dto: CreateEnfantsDto,
@User() currentUser: Users, // <-- ton décorateur
): Promise<EnfantResponseDto> {
const enfant = await this.enfantsService.create(dto, currentUser);
return mapEnfantToResponseDto(enfant);
}
// Récupérer tous les enfants avec leurs liens parents
@Get()
@ApiOperation({ summary: 'Récupérer tous les enfants avec leurs liens parents' })
@ApiResponse({ status: 200, type: [EnfantResponseDto], description: 'Liste de tous les enfants avec leurs liens parents.' })
@Get()
@Roles(RoleType.GESTIONNAIRE, RoleType.SUPER_ADMIN)
async findAll(): Promise<EnfantResponseDto[]> {
const enfants = await this.enfantsService.findAll();
// Mapper les entités enfants vers les DTO de réponse
return mapEnfantsToResponseDto(enfants);
}
// Récupérer un enfant par son ID
@Get(':id')
@ApiOperation({ summary: 'Récupérer un enfant par son ID' })
@ApiResponse({ status: 200, type: EnfantResponseDto, description: 'Détails de l\'enfant avec ses liens parents.' })
@Roles(RoleType.GESTIONNAIRE, RoleType.SUPER_ADMIN, RoleType.PARENT)
async findOne(@Param('id', new ParseUUIDPipe()) id: string): Promise<EnfantResponseDto> {
const enfant = await this.enfantsService.findOne(id);
// Mapper l'entité enfant vers le DTO de réponse
return mapEnfantToResponseDto(enfant);
}
// Mettre à jour un enfant
@Patch(':id')
@ApiOperation({ summary: 'Mettre à jour un enfant' })
@ApiResponse({ status: 200, type: EnfantResponseDto, description: 'L\'enfant a été mis à jour avec succès.' })
@ -62,16 +56,13 @@ export class EnfantsController {
@Body() dto: Partial<CreateEnfantsDto>,
): Promise<EnfantResponseDto> {
const enfant = await this.enfantsService.update(id, dto);
// Mapper l'entité enfant vers le DTO de réponse
return mapEnfantToResponseDto(enfant);
}
// Supprimer un enfant
@Delete(':id')
@Roles(RoleType.GESTIONNAIRE, RoleType.SUPER_ADMIN)
@ApiOperation({ summary: 'Supprimer un enfant' })
@ApiResponse({ status: 204, description: 'L\'enfant a été supprimé avec succès.' })
@Roles(RoleType.GESTIONNAIRE, RoleType.SUPER_ADMIN)
async remove(@Param('id', new ParseUUIDPipe()) id: string): Promise<void> {
return this.enfantsService.remove(id);
}

View File

@ -5,6 +5,7 @@ import { Parents } from 'src/entities/parents.entity';
import { ParentsChildren } from 'src/entities/parents_children.entity';
import { Repository } from 'typeorm';
import { CreateEnfantsDto } from './dto/create_enfants.dto';
import { Users } from 'src/entities/users.entity';
@Injectable()
export class EnfantsService {
@ -20,21 +21,17 @@ export class EnfantsService {
) { }
// Inscruire un enfant
async create(dto: CreateEnfantsDto): Promise<Children> {
// Vérifier que le parent existe
async create(dto: CreateEnfantsDto, currentUser: Users): Promise<Children> {
// Récupérer le parent lié à l'utilisateur connecté
const parent = await this.parentsRepository.findOne({
where: { user_id: dto.id_parent },
where: { user_id: currentUser.id },
});
// Si le parent n'existe pas, lever une exception
if (!parent) {
throw new NotFoundException(`Id de parent : ${dto.id_parent} introuvable`);
throw new NotFoundException(`Parent introuvable pour l'utilisateur connecté`);
}
// Evolution future : rendre l'option photo obligatoire ou non configurable
// Vérifier la règle métier sur la photo
const optionObligatoire = false;
// Si l'enfant est pas a naitre, vérifier qu'une photo est fournie
// Puis si l'option est obligatoire
if (dto.status !== StatutEnfantType.A_NAITRE && !dto.photo_url && optionObligatoire) {
throw new BadRequestException(`Pour un enfant actif, une photo est obligatoire`);
}
@ -54,12 +51,13 @@ export class EnfantsService {
});
await this.childrenRepository.save(child);
// Créer le lien entre le parent et l'enfant
// Créer le lien automatiquement avec le parent connecté
const parentLink = this.parentsChildrenRepository.create({
parentId: parent.user_id,
enfantId: child.id,
});
await this.parentsChildrenRepository.save(parentLink);
return this.findOne(child.id);
}
@ -93,16 +91,19 @@ export class EnfantsService {
}
// Mettre à jour un enfant
async update(id: string, dto: Partial<CreateEnfantsDto>): Promise<Children> {
const child = await this.childrenRepository.findOne({ where: { id } });
if (!child) {
throw new NotFoundException(`Id d'enfant : ${id} introuvable`);
}
const { id_parent, ...childData } = dto;
await this.childrenRepository.update(id, childData);
return this.findOne(id);
// Mettre à jour un enfant
async update(id: string, dto: Partial<CreateEnfantsDto>): Promise<Children> {
const child = await this.childrenRepository.findOne({ where: { id } });
if (!child) {
throw new NotFoundException(`Id d'enfant : ${id} introuvable`);
}
// On na plus besoin de gérer id_parent ici
await this.childrenRepository.update(id, dto);
return this.findOne(id);
}
// Supprimer un enfant
async remove(id: string): Promise<void> {
await this.childrenRepository.delete(id);