import { CacheInterceptor, CacheTTL } from "@nestjs/cache-manager"; import { Body, Controller, DefaultValuePipe, Delete, forwardRef, Get, Inject, Param, ParseIntPipe, Patch, Post, Query, Req, UploadedFile, UseGuards, UseInterceptors, } from "@nestjs/common"; import { FileInterceptor } from "@nestjs/platform-express"; import { AuthService } from "../auth/auth.service"; import { Roles } from "../auth/decorators/roles.decorator"; import { AuthGuard } from "../auth/guards/auth.guard"; import { RolesGuard } from "../auth/guards/roles.guard"; import type { AuthenticatedRequest } from "../common/interfaces/request.interface"; import { UpdateConsentDto } from "./dto/update-consent.dto"; import { UpdateUserDto } from "./dto/update-user.dto"; import { UsersService } from "./users.service"; @Controller("users") export class UsersController { constructor( private readonly usersService: UsersService, @Inject(forwardRef(() => AuthService)) private readonly authService: AuthService, ) {} // Gestion administrative des utilisateurs @Get("admin") @UseGuards(AuthGuard, RolesGuard) @Roles("admin") findAll( @Query("limit", new DefaultValuePipe(10), ParseIntPipe) limit: number, @Query("offset", new DefaultValuePipe(0), ParseIntPipe) offset: number, ) { return this.usersService.findAll(limit, offset); } // Listing public d'un profil @Get("public/:username") @UseInterceptors(CacheInterceptor) @CacheTTL(60000) // 1 minute findPublicProfile(@Param("username") username: string) { return this.usersService.findPublicProfile(username); } // Gestion de son propre compte @Get("me") @UseGuards(AuthGuard) findMe(@Req() req: AuthenticatedRequest) { return this.usersService.findOneWithPrivateData(req.user.sub); } @Get("me/export") @UseGuards(AuthGuard) exportMe(@Req() req: AuthenticatedRequest) { return this.usersService.exportUserData(req.user.sub); } @Patch("me") @UseGuards(AuthGuard) updateMe( @Req() req: AuthenticatedRequest, @Body() updateUserDto: UpdateUserDto, ) { return this.usersService.update(req.user.sub, updateUserDto); } @Post("me/avatar") @UseGuards(AuthGuard) @UseInterceptors(FileInterceptor("file")) updateAvatar( @Req() req: AuthenticatedRequest, @UploadedFile() file: Express.Multer.File, ) { return this.usersService.updateAvatar(req.user.sub, file); } @Patch("me/consent") @UseGuards(AuthGuard) updateConsent( @Req() req: AuthenticatedRequest, @Body() consentDto: UpdateConsentDto, ) { return this.usersService.updateConsent( req.user.sub, consentDto.termsVersion, consentDto.privacyVersion, ); } @Delete("me") @UseGuards(AuthGuard) removeMe(@Req() req: AuthenticatedRequest) { return this.usersService.remove(req.user.sub); } @Delete(":uuid") @UseGuards(AuthGuard, RolesGuard) @Roles("admin") removeAdmin(@Param("uuid") uuid: string) { return this.usersService.remove(uuid); } @Patch("admin/:uuid") @UseGuards(AuthGuard, RolesGuard) @Roles("admin") updateAdmin( @Param("uuid") uuid: string, @Body() updateUserDto: UpdateUserDto, ) { return this.usersService.update(uuid, updateUserDto); } // Double Authentification (2FA) @Post("me/2fa/setup") @UseGuards(AuthGuard) setup2fa(@Req() req: AuthenticatedRequest) { return this.authService.generateTwoFactorSecret(req.user.sub); } @Post("me/2fa/enable") @UseGuards(AuthGuard) enable2fa(@Req() req: AuthenticatedRequest, @Body("token") token: string) { return this.authService.enableTwoFactor(req.user.sub, token); } @Post("me/2fa/disable") @UseGuards(AuthGuard) disable2fa(@Req() req: AuthenticatedRequest, @Body("token") token: string) { return this.authService.disableTwoFactor(req.user.sub, token); } }