Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7eefd4e
feat: add api auth to routes for swagger
aReynier Dec 15, 2025
9ac3d8a
feat: comment differences with MCD
aReynier Dec 15, 2025
3fba8a8
refactor(86c9kt142): implement interface for campuses module
aReynier May 1, 2026
1d9fc9a
refactor(86c9kt186): implement interface for categories module
aReynier May 1, 2026
b2fb06f
refactor(86c9kt9cf): implement interface for channels module
aReynier May 1, 2026
f02878c
refactor(86c9kt15m): implement interface for courses module
aReynier May 1, 2026
36758cf
refactor(86c9kt102): implement interface for discord-users module
aReynier May 1, 2026
77b8ecb
refactor(86c9kt13e): implement interface for guilds module
aReynier May 1, 2026
1858b33
refactor(86c9kt17t): implement interface for guilds-templates module
aReynier May 1, 2026
3fc308d
refactor(86c9kt114): implement interface for identification-requests …
aReynier May 1, 2026
8cb5add
refactor(86c9kt12c): implement interface for members module
aReynier May 1, 2026
9f06bbf
refactor(86c9kt11v): implement interface for members-informations module
aReynier May 1, 2026
55dff68
refactor(86c9kt14n): implement interface for promotions module
aReynier May 1, 2026
322f5a2
refactor(86c9kt16n): implement interface for roles module
aReynier May 1, 2026
ebe89fa
refactor(86c6w80gq): update signature dependencies after implement in…
aReynier May 1, 2026
e1feb5a
chore:update gitignore
aReynier May 1, 2026
4a1fa34
Merge pull request #6 from aReynier/feature/fix-solid
aReynier May 1, 2026
31a1899
feat(86c4246cr): implement helmet, csp and adjust dependency
aReynier Jun 17, 2025
3659541
feat(86c4246hm): implement cors
aReynier Jun 17, 2025
9e90c97
feat(86c4246ke): add rate limit
aReynier Jun 17, 2025
22d1373
feat(86c4246cr): change csp wether it's dev or prod environment
aReynier Jun 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ lerna-debug.log*
*.sublime-workspace

# IDE - VSCode
.vscode/
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
Expand Down
83 changes: 46 additions & 37 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"test:e2e": "playwright test"
},
"dependencies": {
"@fastify/helmet": "^13.0.1",
"@fastify/static": "^8.1.1",
"@nestjs/axios": "^4.0.0",
"@nestjs/common": "^11.0.1",
Expand All @@ -31,13 +32,14 @@
"@nestjs/platform-express": "^11.0.1",
"@nestjs/platform-fastify": "^11.0.9",
"@nestjs/swagger": "^11.0.5",
"@nestjs/throttler": "^6.4.0",
"@nestjs/typeorm": "^11.0.0",
"@types/uuid": "^10.0.0",
"axios": "^1.7.9",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.7",
"fastify": "^5.2.1",
"fastify": "^5.3.3",
"jsonwebtoken": "^9.0.2",
"nestjs-pino": "^4.3.0",
"passport": "^0.7.0",
Expand Down
8 changes: 7 additions & 1 deletion src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import { AnswerTemplatesModule } from './answer-templates/answer-templates.modul
// IMPORTS POUR LA SÉCURITÉ GLOBALE
import { APP_GUARD } from '@nestjs/core';
import { GlobalAuthGuard } from './auth/guards/global-auth.guard';
import { ThrottlerModule } from '@nestjs/throttler';


/**
* Module principal de l'application
Expand Down Expand Up @@ -84,7 +86,11 @@ import { GlobalAuthGuard } from './auth/guards/global-auth.guard';
SignatureModule,
PollTemplatesModule,
QuestionTemplatesModule,
AnswerTemplatesModule
AnswerTemplatesModule,
ThrottlerModule.forRoot([{
ttl: 1, // 1 seconde
limit: 50, // 50 requêtes par seconde
}]),
],
controllers: [AppController],
// CONFIGURATION DU GUARD GLOBAL
Expand Down
6 changes: 5 additions & 1 deletion src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,11 @@ export class AuthService {
guildId: this.allowedGuildId,
};

return this.jwtService.sign(payload);
const token = this.jwtService.sign(payload);

console.log('JWT Token', token)

return token;
}

/**
Expand Down
64 changes: 54 additions & 10 deletions src/campuses/campuses.controller.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,84 @@
import { Controller, Get, Post, Body, Put, Param, Delete, NotFoundException } from '@nestjs/common';
import { CampusesService } from './campuses.service';
import {
Controller,
Get,
Post,
Body,
Put,
Param,
Delete,
NotFoundException,
Inject,
} from '@nestjs/common';
import { CreateCampusDto } from './dto/create-campus.dto';
import { UpdateCampusDto } from './dto/update-campus.dto';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiBearerAuth,
} from '@nestjs/swagger';
import { Campus } from './entities/campus.entity';
import {
ICampusesServiceToken,
ICampusesService,
} from './interfaces/campus.interface';

@ApiTags('campuses')
@ApiBearerAuth('JWT-auth')
@Controller('campuses')
export class CampusesController {
constructor(private readonly campusService: CampusesService) {}
constructor(
@Inject(ICampusesServiceToken)
private readonly campusService: ICampusesService,
) {}

@Post()
@ApiOperation({ summary: 'Créer un nouveau campus' })
@ApiResponse({ status: 201, description: 'Le campus a été créé avec succès.', type: Campus })
@ApiResponse({
status: 201,
description: 'Le campus a été créé avec succès.',
type: Campus,
})
@ApiResponse({ status: 400, description: 'Requête invalide' })
create(@Body() createCampusDto: CreateCampusDto) {
return this.campusService.create(createCampusDto);
}

@Get()
@ApiOperation({ summary: 'Récupérer tous les campus' })
@ApiResponse({ status: 200, description: 'Liste des campus récupérée avec succès.', type: [Campus] })
@ApiResponse({
status: 200,
description: 'Liste des campus récupérée avec succès.',
type: [Campus],
})
findAll() {
return this.campusService.findAll();
}

@Get(':uuid')
@ApiOperation({ summary: 'Récupérer un campus par son UUID' })
@ApiResponse({ status: 200, description: 'Le campus a été trouvé.', type: Campus })
@ApiResponse({
status: 200,
description: 'Le campus a été trouvé.',
type: Campus,
})
@ApiResponse({ status: 404, description: 'Campus non trouvé' })
findOne(@Param('uuid') uuid: string) {
return this.campusService.findOne(uuid);
}

@Put(':uuid')
@ApiOperation({ summary: 'Mettre à jour un campus' })
@ApiResponse({ status: 200, description: 'Le campus a été mis à jour avec succès.', type: Campus })
@ApiResponse({
status: 200,
description: 'Le campus a été mis à jour avec succès.',
type: Campus,
})
@ApiResponse({ status: 404, description: 'Campus non trouvé' })
async update(@Param('uuid') uuid: string, @Body() updateCampusDto: UpdateCampusDto) {
async update(
@Param('uuid') uuid: string,
@Body() updateCampusDto: UpdateCampusDto,
) {
const campus = await this.campusService.update(uuid, updateCampusDto);
if (!campus) {
throw new NotFoundException(`Campus with UUID "${uuid}" not found`);
Expand All @@ -47,7 +88,10 @@ export class CampusesController {

@Delete(':uuid')
@ApiOperation({ summary: 'Supprimer un campus' })
@ApiResponse({ status: 200, description: 'Le campus a été supprimé avec succès.' })
@ApiResponse({
status: 200,
description: 'Le campus a été supprimé avec succès.',
})
@ApiResponse({ status: 404, description: 'Campus non trouvé' })
remove(@Param('uuid') uuid: string) {
return this.campusService.remove(uuid);
Expand Down
9 changes: 8 additions & 1 deletion src/campuses/campuses.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ import { CampusesService } from './campuses.service';
import { CampusesController } from './campuses.controller';
import { Campus } from './entities/campus.entity';
import { RolesModule } from 'src/roles/roles.module';
import { ICampusesServiceToken } from './interfaces/campus.interface';

@Module({
imports: [TypeOrmModule.forFeature([Campus]), RolesModule],
controllers: [CampusesController],
providers: [CampusesService],
providers: [
{
provide: ICampusesServiceToken,
useClass: CampusesService,
},
],
exports: [ICampusesServiceToken],
})
export class CampusesModule {}
21 changes: 14 additions & 7 deletions src/campuses/campuses.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { Injectable, BadRequestException, NotFoundException } from '@nestjs/common';
import {
Injectable,
BadRequestException,
NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateCampusDto } from './dto/create-campus.dto';
import { UpdateCampusDto } from './dto/update-campus.dto';
import { Campus } from './entities/campus.entity';
import { Role } from 'src/roles/entities/role.entity';
import { Campus } from './entities/campus.entity';
import { ICampusesService } from './interfaces/campus.interface';

@Injectable()
export class CampusesService {
export class CampusesService implements ICampusesService {
constructor(
@InjectRepository(Campus)
private campusRepository: Repository<Campus>,
Expand All @@ -19,13 +24,13 @@ export class CampusesService {
async create(createCampusDto: CreateCampusDto): Promise<Campus> {
try {
const newRole = this.roleRepository.create({
uuidRole: createCampusDto.uuidRole,
uuidRole: createCampusDto.uuidRole,
uuidGuild: createCampusDto.uuidGuild,
name: createCampusDto.name,
memberCount: 0,
rolePosition: 0,
hoist: false,
color: "#000000",
color: '#000000',
});

const savedRole = await this.roleRepository.save(newRole);
Expand All @@ -37,11 +42,13 @@ export class CampusesService {

return await this.campusRepository.save(newCampus);
} catch (error) {
throw new BadRequestException('Erreur lors de la création du campus: ' + error.message);
throw new BadRequestException(
'Erreur lors de la création du campus: ' + error.message,
);
}
}

findAll() {
findAll(): Promise<Campus[]> {
return this.campusRepository.find();
}

Expand Down
2 changes: 1 addition & 1 deletion src/campuses/dto/create-campus.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PickableDtoFields } from 'src/utils/pickable-dto-fields';
import { PickableDiscordUUIDFields } from 'src/utils/pickable-discord-uuid-fields';

export class CreateCampusDto extends PickType(IntersectionType(PickableDtoFields, PickableDiscordUUIDFields), [
'name',
'name', //name_campus dans le MCD
'uuidRole',
'uuidGuild'
]) {
Expand Down
Loading