Ajout d'un endpoint pour modifier son mot de passe

This commit is contained in:
Emmy D'Anello 2024-12-07 13:52:49 +01:00
parent 45a1cebcf9
commit 1ae6b6634c
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
7 changed files with 48 additions and 8 deletions

View File

@ -16,7 +16,7 @@ export const JWT_SECRET = env.JWT_SECRET
PassportModule,
JwtModule.register({
secret: JWT_SECRET,
signOptions: { expiresIn: '5m' },
signOptions: { expiresIn: '12h' },
}),
UsersModule,
],

View File

@ -13,9 +13,7 @@ export class AuthService {
if (!user) {
throw new NotFoundException(`Aucun⋅e utilisateur⋅rice avec pour nom ${name}`)
}
const isPasswordValid = await bcrypt.compare(password, user.password)
if (!isPasswordValid) {
throw new UnauthorizedException('Mot de passe incorrect')
}
@ -24,4 +22,4 @@ export class AuthService {
accessToken: this.jwtService.sign({ userId: user.id }),
}
}
}
}

View File

@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger'
import { IsNotEmpty, IsString, MinLength } from 'class-validator'
import { IsNotEmpty, IsString } from 'class-validator'
export class LoginDto {
@IsString()

View File

@ -3,6 +3,7 @@ import { PassportStrategy } from '@nestjs/passport'
import { ExtractJwt, Strategy } from 'passport-jwt'
import { JWT_SECRET } from './auth.module'
import { UsersService } from 'src/users/users.service'
import { User } from '@prisma/client'
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
@ -13,7 +14,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
})
}
async validate(payload: { userId: number }) {
async validate(payload: { userId: number }): Promise<User> {
const user = await this.usersService.findOne(payload.userId)
if (!user) {
throw new UnauthorizedException()

View File

@ -0,0 +1,10 @@
import { ApiProperty } from '@nestjs/swagger'
import { IsNotEmpty, IsString, MinLength } from 'class-validator'
export class UpdatePasswordDto {
@IsString()
@IsNotEmpty()
@MinLength(8)
@ApiProperty()
password: string
}

View File

@ -1,8 +1,12 @@
import { Controller, Get, NotFoundException, Param, ParseIntPipe, UseGuards } from '@nestjs/common'
import { Body, Controller, Get, HttpCode, NotFoundException, Param, ParseIntPipe, Patch, Post, Req, UseGuards } from '@nestjs/common'
import { UsersService } from './users.service'
import { ApiBearerAuth, ApiNotFoundResponse, ApiOkResponse } from '@nestjs/swagger'
import { ApiBadRequestResponse, ApiBearerAuth, ApiForbiddenResponse, ApiNoContentResponse, ApiNotFoundResponse, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger'
import { UserEntity } from './entities/user.entity'
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard'
import { User } from '@prisma/client'
import { UpdatePasswordDto } from './dto/user_password.dto'
export type AuthenticatedRequest = Request & { user: User }
@Controller('users')
export class UsersController {
@ -12,6 +16,8 @@ export class UsersController {
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({ type: UserEntity, isArray: true })
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
@ApiForbiddenResponse({ description: "Permission refusée" })
async findAll() {
const users = await this.usersService.findAll()
return users.map(user => new UserEntity(user))
@ -21,6 +27,8 @@ export class UsersController {
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOkResponse({ type: UserEntity })
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
@ApiForbiddenResponse({ description: "Permission refusée" })
@ApiNotFoundResponse({ description: "Utilisateur⋅rice non trouvé⋅e" })
async findOne(@Param('id', ParseIntPipe) id: number) {
const user = await this.usersService.findOne(id)
@ -28,4 +36,17 @@ export class UsersController {
throw new NotFoundException(`L'utilisateur⋅rice avec l'identifiant ${id} n'existe pas`)
return new UserEntity(user)
}
@Patch('/update-password')
@HttpCode(204)
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiNoContentResponse({description: "Le mot de passe a bien été modifié."})
@ApiBadRequestResponse({description: "Erreur dans la saisie du nouveau mot de passe."})
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
@ApiForbiddenResponse({ description: "Permission refusée" })
async updatePassword(@Req() request: AuthenticatedRequest, @Body() { password }: UpdatePasswordDto) {
const user = request.user
await this.usersService.updatePassword(user, password)
}
}

View File

@ -1,5 +1,7 @@
import { Injectable } from '@nestjs/common'
import { User } from '@prisma/client'
import { PrismaService } from 'src/prisma/prisma.service'
import * as bcrypt from 'bcrypt'
@Injectable()
export class UsersService {
@ -12,4 +14,12 @@ export class UsersService {
async findOne(id: number) {
return await this.prisma.user.findUnique({ where: { id } })
}
async updatePassword(user: User, password: string) {
const hashedPassword = await bcrypt.hash(password, 10)
await this.prisma.user.update({
where: { id: user.id },
data: { password: hashedPassword }
})
}
}