Files
memegoat/backend/src/users/users.controller.ts
Mathis HERRIOT f852835c59 feat: add user search functionality
- Implemented `GET /users/search` endpoint in the backend to enable user search by username or display name.
- Added `search` method in `UsersService` and `UsersRepository`.
- Updated frontend `UserService` to support the new search API.
2026-01-29 15:47:03 +01:00

150 lines
3.8 KiB
TypeScript

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);
}
@Get("search")
@UseGuards(AuthGuard)
search(@Query("q") query: string) {
return this.usersService.search(query);
}
// 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);
}
}