Co-authored-by: Julien Martin <julien.martin@ptits-pas.fr> Co-committed-by: Julien Martin <julien.martin@ptits-pas.fr>
This commit is contained in:
parent
c5028c3b22
commit
95d1c3741b
@ -1,10 +1,11 @@
|
||||
import { Body, Controller, Get, Post, Req, UnauthorizedException, UseGuards } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Post, Req, UnauthorizedException, BadRequestException, UseGuards } from '@nestjs/common';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
import { AuthService } from './auth.service';
|
||||
import { Public } from 'src/common/decorators/public.decorator';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
import { RegisterParentDto } from './dto/register-parent.dto';
|
||||
import { RegisterParentCompletDto } from './dto/register-parent-complet.dto';
|
||||
import { ChangePasswordRequiredDto } from './dto/change-password.dto';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { AuthGuard } from 'src/common/guards/auth.guard';
|
||||
import type { Request } from 'express';
|
||||
@ -97,5 +98,31 @@ export class AuthController {
|
||||
logout(@User() currentUser: Users) {
|
||||
return this.authService.logout(currentUser.id);
|
||||
}
|
||||
|
||||
@Post('change-password-required')
|
||||
@UseGuards(AuthGuard)
|
||||
@ApiBearerAuth('access-token')
|
||||
@ApiOperation({
|
||||
summary: 'Changement de mot de passe obligatoire',
|
||||
description: 'Permet de changer le mot de passe lors de la première connexion (flag changement_mdp_obligatoire)'
|
||||
})
|
||||
@ApiResponse({ status: 200, description: 'Mot de passe changé avec succès' })
|
||||
@ApiResponse({ status: 400, description: 'Mot de passe actuel incorrect ou confirmation non correspondante' })
|
||||
@ApiResponse({ status: 403, description: 'Changement de mot de passe non requis pour cet utilisateur' })
|
||||
async changePasswordRequired(
|
||||
@User() currentUser: Users,
|
||||
@Body() dto: ChangePasswordRequiredDto,
|
||||
) {
|
||||
// Vérifier que les mots de passe correspondent
|
||||
if (dto.nouveau_mot_de_passe !== dto.confirmation_mot_de_passe) {
|
||||
throw new BadRequestException('Les mots de passe ne correspondent pas');
|
||||
}
|
||||
|
||||
return this.authService.changePasswordRequired(
|
||||
currentUser.id,
|
||||
dto.mot_de_passe_actuel,
|
||||
dto.nouveau_mot_de_passe,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -455,6 +455,60 @@ export class AuthService {
|
||||
return `/uploads/photos/${nomFichierUnique}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changement de mot de passe obligatoire (première connexion)
|
||||
*/
|
||||
async changePasswordRequired(
|
||||
userId: string,
|
||||
motDePasseActuel: string,
|
||||
nouveauMotDePasse: string,
|
||||
) {
|
||||
const user = await this.usersRepo.findOne({ where: { id: userId } });
|
||||
|
||||
if (!user) {
|
||||
throw new UnauthorizedException('Utilisateur introuvable');
|
||||
}
|
||||
|
||||
// Vérifier que le changement est bien obligatoire
|
||||
if (!user.changement_mdp_obligatoire) {
|
||||
throw new BadRequestException(
|
||||
'Le changement de mot de passe n\'est pas requis pour cet utilisateur',
|
||||
);
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur a un mot de passe
|
||||
if (!user.password) {
|
||||
throw new BadRequestException('Compte non activé');
|
||||
}
|
||||
|
||||
// Vérifier le mot de passe actuel
|
||||
const motDePasseValide = await bcrypt.compare(motDePasseActuel, user.password);
|
||||
if (!motDePasseValide) {
|
||||
throw new BadRequestException('Mot de passe actuel incorrect');
|
||||
}
|
||||
|
||||
// Vérifier que le nouveau mot de passe est différent de l'ancien
|
||||
const memeMotDePasse = await bcrypt.compare(nouveauMotDePasse, user.password);
|
||||
if (memeMotDePasse) {
|
||||
throw new BadRequestException(
|
||||
'Le nouveau mot de passe doit être différent de l\'ancien',
|
||||
);
|
||||
}
|
||||
|
||||
// Hasher et sauvegarder le nouveau mot de passe
|
||||
const sel = await bcrypt.genSalt(12);
|
||||
user.password = await bcrypt.hash(nouveauMotDePasse, sel);
|
||||
user.changement_mdp_obligatoire = false;
|
||||
user.modifie_le = new Date();
|
||||
|
||||
await this.usersRepo.save(user);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Mot de passe changé avec succès',
|
||||
};
|
||||
}
|
||||
|
||||
async logout(userId: string) {
|
||||
return { success: true, message: 'Deconnexion'}
|
||||
}
|
||||
|
||||
23
backend/src/routes/auth/dto/change-password.dto.ts
Normal file
23
backend/src/routes/auth/dto/change-password.dto.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, MinLength, Matches } from 'class-validator';
|
||||
|
||||
export class ChangePasswordRequiredDto {
|
||||
@ApiProperty({ description: 'Mot de passe actuel' })
|
||||
@IsString()
|
||||
mot_de_passe_actuel: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Nouveau mot de passe (min 8 caractères, 1 majuscule, 1 chiffre)',
|
||||
minLength: 8
|
||||
})
|
||||
@IsString()
|
||||
@MinLength(8, { message: 'Le mot de passe doit contenir au moins 8 caractères' })
|
||||
@Matches(/^(?=.*[A-Z])(?=.*\d)/, {
|
||||
message: 'Le mot de passe doit contenir au moins une majuscule et un chiffre'
|
||||
})
|
||||
nouveau_mot_de_passe: string;
|
||||
|
||||
@ApiProperty({ description: 'Confirmation du nouveau mot de passe' })
|
||||
@IsString()
|
||||
confirmation_mot_de_passe: string;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user