From 37a23390d52e7c12bbc628ff1dea9997d58556a3 Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:36:59 +0100 Subject: [PATCH] refactor: enhance module exports and imports across services Refactor multiple modules to improve dependency management by adding missing imports (e.g., `AuthModule`, `CryptoModule`) and ensuring essential services and repositories are exported. Update Dockerfile for better build and runtime efficiency, improve CORS handling, and enhance validation with updates to DTOs. Include package.json refinements for dependency organization. --- backend/Dockerfile | 18 ++++++++--- backend/package.json | 27 +++++++--------- backend/src/api-keys/api-keys.module.ts | 6 ++-- backend/src/auth/auth.module.ts | 2 +- backend/src/auth/dto/register.dto.ts | 13 +++++++- backend/src/categories/categories.module.ts | 6 ++-- backend/src/common/common.module.ts | 14 +++++++-- backend/src/contents/contents.module.ts | 1 + backend/src/favorites/favorites.module.ts | 6 ++-- backend/src/main.ts | 35 +++++++++++++++------ backend/src/media/media.service.ts | 2 +- backend/src/reports/reports.module.ts | 5 +-- backend/src/sessions/sessions.module.ts | 2 +- backend/src/tags/tags.module.ts | 6 ++-- backend/src/users/users.module.ts | 2 +- 15 files changed, 98 insertions(+), 47 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index bf25c92..359d907 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,16 +1,26 @@ -FROM pnpm/pnpm:22 AS base +FROM node:22-slim AS base ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable && corepack prepare pnpm@latest --activate FROM base AS build WORKDIR /usr/src/app +COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./ +COPY backend/package.json ./backend/ +COPY frontend/package.json ./frontend/ +COPY documentation/package.json ./documentation/ +RUN pnpm install --no-frozen-lockfile COPY . . -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +# On réinstalle après COPY pour s'assurer que tous les scripts de cycle de vie et les liens sont corrects +RUN pnpm install --no-frozen-lockfile RUN pnpm run --filter @memegoat/backend build -RUN pnpm deploy --filter=@memegoat/backend --prod /app +RUN pnpm deploy --filter=@memegoat/backend --prod --legacy /app +RUN cp -r backend/dist /app/dist +RUN cp -r backend/.migrations /app/.migrations FROM base AS runtime WORKDIR /app COPY --from=build /app . EXPOSE 3000 -CMD [ "node", "dist/main" ] +ENV NODE_ENV=production +CMD [ "node", "dist/src/main" ] diff --git a/backend/package.json b/backend/package.json index 7a7996f..3e07cc6 100644 --- a/backend/package.json +++ b/backend/package.json @@ -6,7 +6,9 @@ "private": true, "license": "UNLICENSED", "files": [ - "dist" + "dist", + ".migrations", + "drizzle.config.ts" ], "scripts": { "build": "nest build", @@ -60,24 +62,11 @@ "rxjs": "^7.8.1", "sharp": "^0.34.5", "uuid": "^13.0.0", - "zod": "^4.3.5" + "zod": "^4.3.5", + "drizzle-kit": "^0.31.8" }, "devDependencies": { "@nestjs/cli": "^11.0.0", - "@nestjs/schematics": "^11.0.0", - "@nestjs/testing": "^11.0.1", - "@types/express": "^5.0.0", - "@types/fluent-ffmpeg": "^2.1.28", - "@types/jest": "^30.0.0", - "@types/multer": "^2.0.0", - "@types/node": "^22.10.7", - "@types/nodemailer": "^7.0.4", - "@types/pg": "^8.16.0", - "@types/qrcode": "^1.5.6", - "@types/sharp": "^0.32.0", - "@types/supertest": "^6.0.2", - "@types/uuid": "^11.0.0", - "drizzle-kit": "^0.31.8", "globals": "^16.0.0", "jest": "^30.0.0", "source-map-support": "^0.5.21", @@ -87,6 +76,12 @@ "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", "tsx": "^4.21.0", + "@types/express": "^5.0.0", + "@types/multer": "^1.4.12", + "@types/jest": "^29.5.14", + "@types/node": "^22.10.7", + "@types/pg": "^8.11.10", + "@types/supertest": "^6.0.2", "typescript": "^5.7.3", "typescript-eslint": "^8.20.0" }, diff --git a/backend/src/api-keys/api-keys.module.ts b/backend/src/api-keys/api-keys.module.ts index 9f49ed9..b3f644a 100644 --- a/backend/src/api-keys/api-keys.module.ts +++ b/backend/src/api-keys/api-keys.module.ts @@ -1,4 +1,4 @@ -import { Module } from "@nestjs/common"; +import { forwardRef, Module } from "@nestjs/common"; import { AuthModule } from "../auth/auth.module"; import { CryptoModule } from "../crypto/crypto.module"; import { DatabaseModule } from "../database/database.module"; @@ -7,9 +7,9 @@ import { ApiKeysService } from "./api-keys.service"; import { ApiKeysRepository } from "./repositories/api-keys.repository"; @Module({ - imports: [DatabaseModule, AuthModule, CryptoModule], + imports: [DatabaseModule, forwardRef(() => AuthModule), CryptoModule], controllers: [ApiKeysController], providers: [ApiKeysService, ApiKeysRepository], - exports: [ApiKeysService], + exports: [ApiKeysService, ApiKeysRepository], }) export class ApiKeysModule {} diff --git a/backend/src/auth/auth.module.ts b/backend/src/auth/auth.module.ts index 5d44d45..303727c 100644 --- a/backend/src/auth/auth.module.ts +++ b/backend/src/auth/auth.module.ts @@ -17,6 +17,6 @@ import { RbacRepository } from "./repositories/rbac.repository"; ], controllers: [AuthController], providers: [AuthService, RbacService, RbacRepository], - exports: [AuthService, RbacService], + exports: [AuthService, RbacService, RbacRepository], }) export class AuthModule {} diff --git a/backend/src/auth/dto/register.dto.ts b/backend/src/auth/dto/register.dto.ts index 51c371b..2dbc5ec 100644 --- a/backend/src/auth/dto/register.dto.ts +++ b/backend/src/auth/dto/register.dto.ts @@ -1,10 +1,21 @@ -import { IsEmail, IsNotEmpty, IsString, MinLength } from "class-validator"; +import { + IsEmail, + IsNotEmpty, + IsString, + MaxLength, + MinLength, +} from "class-validator"; export class RegisterDto { @IsString() @IsNotEmpty() + @MaxLength(32) username!: string; + @IsString() + @MaxLength(32) + displayName?: string; + @IsEmail() email!: string; diff --git a/backend/src/categories/categories.module.ts b/backend/src/categories/categories.module.ts index adf89be..e66aa18 100644 --- a/backend/src/categories/categories.module.ts +++ b/backend/src/categories/categories.module.ts @@ -1,13 +1,15 @@ import { Module } from "@nestjs/common"; +import { AuthModule } from "../auth/auth.module"; +import { CryptoModule } from "../crypto/crypto.module"; import { DatabaseModule } from "../database/database.module"; import { CategoriesController } from "./categories.controller"; import { CategoriesService } from "./categories.service"; import { CategoriesRepository } from "./repositories/categories.repository"; @Module({ - imports: [DatabaseModule], + imports: [DatabaseModule, AuthModule, CryptoModule], controllers: [CategoriesController], providers: [CategoriesService, CategoriesRepository], - exports: [CategoriesService], + exports: [CategoriesService, CategoriesRepository], }) export class CategoriesModule {} diff --git a/backend/src/common/common.module.ts b/backend/src/common/common.module.ts index 83f544c..279b7c4 100644 --- a/backend/src/common/common.module.ts +++ b/backend/src/common/common.module.ts @@ -1,10 +1,20 @@ -import { Global, Module } from "@nestjs/common"; +import { forwardRef, Global, Module } from "@nestjs/common"; +import { ContentsModule } from "../contents/contents.module"; import { DatabaseModule } from "../database/database.module"; +import { ReportsModule } from "../reports/reports.module"; +import { SessionsModule } from "../sessions/sessions.module"; +import { UsersModule } from "../users/users.module"; import { PurgeService } from "./services/purge.service"; @Global() @Module({ - imports: [DatabaseModule], + imports: [ + DatabaseModule, + forwardRef(() => SessionsModule), + forwardRef(() => ReportsModule), + forwardRef(() => UsersModule), + forwardRef(() => ContentsModule), + ], providers: [PurgeService], exports: [PurgeService], }) diff --git a/backend/src/contents/contents.module.ts b/backend/src/contents/contents.module.ts index 971cc58..bf08949 100644 --- a/backend/src/contents/contents.module.ts +++ b/backend/src/contents/contents.module.ts @@ -12,5 +12,6 @@ import { ContentsRepository } from "./repositories/contents.repository"; imports: [DatabaseModule, S3Module, AuthModule, CryptoModule, MediaModule], controllers: [ContentsController], providers: [ContentsService, ContentsRepository], + exports: [ContentsRepository], }) export class ContentsModule {} diff --git a/backend/src/favorites/favorites.module.ts b/backend/src/favorites/favorites.module.ts index cd58de9..72d1943 100644 --- a/backend/src/favorites/favorites.module.ts +++ b/backend/src/favorites/favorites.module.ts @@ -1,13 +1,15 @@ import { Module } from "@nestjs/common"; +import { AuthModule } from "../auth/auth.module"; +import { CryptoModule } from "../crypto/crypto.module"; import { DatabaseModule } from "../database/database.module"; import { FavoritesController } from "./favorites.controller"; import { FavoritesService } from "./favorites.service"; import { FavoritesRepository } from "./repositories/favorites.repository"; @Module({ - imports: [DatabaseModule], + imports: [DatabaseModule, AuthModule, CryptoModule], controllers: [FavoritesController], providers: [FavoritesService, FavoritesRepository], - exports: [FavoritesService], + exports: [FavoritesService, FavoritesRepository], }) export class FavoritesModule {} diff --git a/backend/src/main.ts b/backend/src/main.ts index 5eb3a59..3e892ce 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -24,14 +24,31 @@ async function bootstrap() { } // Sécurité - app.use(helmet()); - app.enableCors({ - origin: - configService.get("NODE_ENV") === "production" - ? [configService.get("DOMAIN_NAME") as string] - : true, - credentials: true, - }); + app.use( + helmet({ + crossOriginResourcePolicy: { policy: "cross-origin" }, + }), + ); + const corsEnabled = Boolean(configService.get("ENABLE_CORS")); + if (corsEnabled) { + const domainName = configService.get("CORS_DOMAIN_NAME"); + app.enableCors({ + origin: (origin, callback) => { + if (!origin || domainName === "*") { + callback(null, true); + return; + } + + const allowedOrigins = domainName?.split(",").map((o) => o.trim()) || []; + if (allowedOrigins.includes(origin)) { + callback(null, true); + } else { + callback(null, false); + } + }, + credentials: true, + }); + } // Validation Globale app.useGlobalPipes( @@ -49,4 +66,4 @@ async function bootstrap() { await app.listen(port); logger.log(`Application is running on: http://localhost:${port}`); } -bootstrap(); +bootstrap().then(); diff --git a/backend/src/media/media.service.ts b/backend/src/media/media.service.ts index 982261d..ca26c08 100644 --- a/backend/src/media/media.service.ts +++ b/backend/src/media/media.service.ts @@ -5,7 +5,7 @@ import { Logger, } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; -import * as NodeClam from "clamscan"; +import NodeClam from "clamscan"; import type { IMediaService, MediaProcessingResult, diff --git a/backend/src/reports/reports.module.ts b/backend/src/reports/reports.module.ts index 6e6254a..0f4f576 100644 --- a/backend/src/reports/reports.module.ts +++ b/backend/src/reports/reports.module.ts @@ -1,4 +1,4 @@ -import { Module } from "@nestjs/common"; +import { forwardRef, Module } from "@nestjs/common"; import { AuthModule } from "../auth/auth.module"; import { CryptoModule } from "../crypto/crypto.module"; import { DatabaseModule } from "../database/database.module"; @@ -7,8 +7,9 @@ import { ReportsService } from "./reports.service"; import { ReportsRepository } from "./repositories/reports.repository"; @Module({ - imports: [DatabaseModule, AuthModule, CryptoModule], + imports: [DatabaseModule, forwardRef(() => AuthModule), CryptoModule], controllers: [ReportsController], providers: [ReportsService, ReportsRepository], + exports: [ReportsRepository, ReportsService], }) export class ReportsModule {} diff --git a/backend/src/sessions/sessions.module.ts b/backend/src/sessions/sessions.module.ts index a5c4367..70aca84 100644 --- a/backend/src/sessions/sessions.module.ts +++ b/backend/src/sessions/sessions.module.ts @@ -7,6 +7,6 @@ import { SessionsService } from "./sessions.service"; @Module({ imports: [DatabaseModule, CryptoModule], providers: [SessionsService, SessionsRepository], - exports: [SessionsService], + exports: [SessionsService, SessionsRepository], }) export class SessionsModule {} diff --git a/backend/src/tags/tags.module.ts b/backend/src/tags/tags.module.ts index 456c36a..0e21af0 100644 --- a/backend/src/tags/tags.module.ts +++ b/backend/src/tags/tags.module.ts @@ -1,13 +1,15 @@ import { Module } from "@nestjs/common"; +import { AuthModule } from "../auth/auth.module"; +import { CryptoModule } from "../crypto/crypto.module"; import { DatabaseModule } from "../database/database.module"; import { TagsRepository } from "./repositories/tags.repository"; import { TagsController } from "./tags.controller"; import { TagsService } from "./tags.service"; @Module({ - imports: [DatabaseModule], + imports: [DatabaseModule, AuthModule, CryptoModule], controllers: [TagsController], providers: [TagsService, TagsRepository], - exports: [TagsService], + exports: [TagsService, TagsRepository], }) export class TagsModule {} diff --git a/backend/src/users/users.module.ts b/backend/src/users/users.module.ts index a15fae5..21678c9 100644 --- a/backend/src/users/users.module.ts +++ b/backend/src/users/users.module.ts @@ -10,6 +10,6 @@ import { UsersService } from "./users.service"; imports: [DatabaseModule, CryptoModule, forwardRef(() => AuthModule)], controllers: [UsersController], providers: [UsersService, UsersRepository], - exports: [UsersService], + exports: [UsersService, UsersRepository], }) export class UsersModule {}