Ajout d'un endpoint pour modifier son mot de passe
This commit is contained in:
parent
45a1cebcf9
commit
1ae6b6634c
@ -16,7 +16,7 @@ export const JWT_SECRET = env.JWT_SECRET
|
|||||||
PassportModule,
|
PassportModule,
|
||||||
JwtModule.register({
|
JwtModule.register({
|
||||||
secret: JWT_SECRET,
|
secret: JWT_SECRET,
|
||||||
signOptions: { expiresIn: '5m' },
|
signOptions: { expiresIn: '12h' },
|
||||||
}),
|
}),
|
||||||
UsersModule,
|
UsersModule,
|
||||||
],
|
],
|
||||||
|
@ -13,9 +13,7 @@ export class AuthService {
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
throw new NotFoundException(`Aucun⋅e utilisateur⋅rice avec pour nom ${name}`)
|
throw new NotFoundException(`Aucun⋅e utilisateur⋅rice avec pour nom ${name}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPasswordValid = await bcrypt.compare(password, user.password)
|
const isPasswordValid = await bcrypt.compare(password, user.password)
|
||||||
|
|
||||||
if (!isPasswordValid) {
|
if (!isPasswordValid) {
|
||||||
throw new UnauthorizedException('Mot de passe incorrect')
|
throw new UnauthorizedException('Mot de passe incorrect')
|
||||||
}
|
}
|
||||||
@ -24,4 +22,4 @@ export class AuthService {
|
|||||||
accessToken: this.jwtService.sign({ userId: user.id }),
|
accessToken: this.jwtService.sign({ userId: user.id }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger'
|
import { ApiProperty } from '@nestjs/swagger'
|
||||||
import { IsNotEmpty, IsString, MinLength } from 'class-validator'
|
import { IsNotEmpty, IsString } from 'class-validator'
|
||||||
|
|
||||||
export class LoginDto {
|
export class LoginDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ -3,6 +3,7 @@ import { PassportStrategy } from '@nestjs/passport'
|
|||||||
import { ExtractJwt, Strategy } from 'passport-jwt'
|
import { ExtractJwt, Strategy } from 'passport-jwt'
|
||||||
import { JWT_SECRET } from './auth.module'
|
import { JWT_SECRET } from './auth.module'
|
||||||
import { UsersService } from 'src/users/users.service'
|
import { UsersService } from 'src/users/users.service'
|
||||||
|
import { User } from '@prisma/client'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
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)
|
const user = await this.usersService.findOne(payload.userId)
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new UnauthorizedException()
|
throw new UnauthorizedException()
|
||||||
|
10
server/src/users/dto/user_password.dto.ts
Normal file
10
server/src/users/dto/user_password.dto.ts
Normal 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
|
||||||
|
}
|
@ -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 { 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 { UserEntity } from './entities/user.entity'
|
||||||
import { JwtAuthGuard } from 'src/auth/jwt-auth.guard'
|
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')
|
@Controller('users')
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
@ -12,6 +16,8 @@ export class UsersController {
|
|||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOkResponse({ type: UserEntity, isArray: true })
|
@ApiOkResponse({ type: UserEntity, isArray: true })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
async findAll() {
|
async findAll() {
|
||||||
const users = await this.usersService.findAll()
|
const users = await this.usersService.findAll()
|
||||||
return users.map(user => new UserEntity(user))
|
return users.map(user => new UserEntity(user))
|
||||||
@ -21,6 +27,8 @@ export class UsersController {
|
|||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOkResponse({ type: UserEntity })
|
@ApiOkResponse({ type: UserEntity })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
@ApiNotFoundResponse({ description: "Utilisateur⋅rice non trouvé⋅e" })
|
@ApiNotFoundResponse({ description: "Utilisateur⋅rice non trouvé⋅e" })
|
||||||
async findOne(@Param('id', ParseIntPipe) id: number) {
|
async findOne(@Param('id', ParseIntPipe) id: number) {
|
||||||
const user = await this.usersService.findOne(id)
|
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`)
|
throw new NotFoundException(`L'utilisateur⋅rice avec l'identifiant ${id} n'existe pas`)
|
||||||
return new UserEntity(user)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { Injectable } from '@nestjs/common'
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { User } from '@prisma/client'
|
||||||
import { PrismaService } from 'src/prisma/prisma.service'
|
import { PrismaService } from 'src/prisma/prisma.service'
|
||||||
|
import * as bcrypt from 'bcrypt'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
@ -12,4 +14,12 @@ export class UsersService {
|
|||||||
async findOne(id: number) {
|
async findOne(id: number) {
|
||||||
return await this.prisma.user.findUnique({ where: { id } })
|
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 }
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user