From 82cdb31c555ff081d4f8c98ae9f838b77360c72b Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 12 Nov 2024 11:29:47 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20add=20backend=20configuration=20adjustm?= =?UTF-8?q?ents=20to=20AdminService=20for=20front=E2=80=A6=20(#1491)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add backend configuration adjustments to AdminService for frontend compatibility * improve unit test for admin service * minor type change * updated README for the new env var --------- Co-authored-by: Max Novelli --- README.md | 1 + src/admin/admin.module.ts | 3 ++- src/admin/admin.service.spec.ts | 46 +++++++++++++++++++++++---------- src/admin/admin.service.ts | 19 +++++++++++++- src/config/configuration.ts | 1 + src/main.ts | 12 ++++++--- 6 files changed, 64 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b1ffe56a3..1f4c418bb 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,7 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `ES_REFRESH` | string | | If set to `wait_for`, Elasticsearch will wait till data is inserted into the specified index before returning a response. | false | | `LOGGERS_CONFIG_FILE` | string | | The file name for loggers configuration, located in the project root directory. | "loggers.json" | | `SWAGGER_PATH` | string | Yes | swaggerPath is the path where the swagger UI will be available| "explorer"| +| `MAX_FILE_UPLOAD_SIZE` | string | Yes | Maximum allowed file upload size | "16mb"| ## Migrating from the old SciCat Backend diff --git a/src/admin/admin.module.ts b/src/admin/admin.module.ts index e0f55e609..abf43368b 100644 --- a/src/admin/admin.module.ts +++ b/src/admin/admin.module.ts @@ -1,10 +1,11 @@ import { Module } from "@nestjs/common"; import { AdminService } from "./admin.service"; import { AdminController } from "./admin.controller"; +import { ConfigModule } from "@nestjs/config"; @Module({ controllers: [AdminController], - imports: [], + imports: [ConfigModule], providers: [AdminService], exports: [AdminService], }) diff --git a/src/admin/admin.service.spec.ts b/src/admin/admin.service.spec.ts index 5b6c3c628..a138a3a38 100644 --- a/src/admin/admin.service.spec.ts +++ b/src/admin/admin.service.spec.ts @@ -1,27 +1,29 @@ -import { getModelToken } from "@nestjs/mongoose"; import { Test, TestingModule } from "@nestjs/testing"; +import { ConfigService } from "@nestjs/config"; import { AdminService } from "./admin.service"; import config from "../config/frontend.config.json"; +import theme from "../config/frontend.theme.json"; -const mockConfig: Record = config; - -describe("PoliciesService", () => { +describe("AdminService", () => { let service: AdminService; + const mockConfigService = { + get: jest.fn((propertyPath: string) => { + const config = { + maxFileUploadSizeInMb: "12mb", + } as Record; + + return config[propertyPath]; + }), + }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ + AdminService, { - provide: getModelToken("Policy"), - useValue: { - new: jest.fn().mockResolvedValue(mockConfig), - constructor: jest.fn().mockResolvedValue(mockConfig), - find: jest.fn(), - create: jest.fn(), - exec: jest.fn(), - }, + provide: ConfigService, + useValue: mockConfigService, }, - AdminService, ], }).compile(); @@ -31,4 +33,22 @@ describe("PoliciesService", () => { it("should be defined", () => { expect(service).toBeDefined(); }); + + describe("getConfig", () => { + it("should return modified config", async () => { + const result = await service.getConfig(); + + expect(result).toEqual({ + ...config, + maxFileUploadSizeInMb: "12mb", + }); + }); + }); + + describe("getTheme", () => { + it("should return theme config", async () => { + const result = await service.getTheme(); + expect(result).toEqual(theme); + }); + }); }); diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index 970ad4b3d..eccad92ab 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -1,14 +1,31 @@ import { Injectable } from "@nestjs/common"; import config from "../config/frontend.config.json"; import theme from "../config/frontend.theme.json"; +import { ConfigService } from "@nestjs/config"; @Injectable() export class AdminService { + constructor(private configService: ConfigService) {} + async getConfig(): Promise | null> { - return config; + const modifiedConfig = this.applyBackendConfigAdjustments(); + + return modifiedConfig; } async getTheme(): Promise | null> { return theme; } + + // NOTE: Adjusts backend config values for frontend use (e.g., file upload limits). + // Add future backend-dependent adjustments here as needed. + private applyBackendConfigAdjustments(): Record { + const postEncodedMaxFileUploadSize = + this.configService.get("maxFileUploadSizeInMb") || "16mb"; + + return { + ...config, + maxFileUploadSizeInMb: postEncodedMaxFileUploadSize, + }; + } } diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 94a190d89..1fc02fbdc 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -58,6 +58,7 @@ const configuration = () => { }); const config = { + maxFileUploadSizeInMb: process.env.MAX_FILE_UPLOAD_SIZE || "16mb", // 16MB by default versions: { api: "3", }, diff --git a/src/main.ts b/src/main.ts index 3af41b802..41ba21153 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,4 @@ import session from "express-session"; -import { json } from "body-parser"; import { NestFactory } from "@nestjs/core"; import { DocumentBuilder, @@ -10,9 +9,10 @@ import { AppModule } from "./app.module"; import { Logger, ValidationPipe, VersioningType } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; import { AllExceptionsFilter, ScicatLogger } from "./loggers/logger.service"; +import { NestExpressApplication } from "@nestjs/platform-express"; async function bootstrap() { - const app = await NestFactory.create(AppModule, { + const app = await NestFactory.create(AppModule, { bufferLogs: true, }); const configService: ConfigService, false> = app.get( @@ -84,7 +84,13 @@ async function bootstrap() { }), ); - app.use(json({ limit: "16mb" })); + const fileUploadLimitInMb = configService.get("fileUploadLimitInMb"); + + app.useBodyParser("json", { limit: fileUploadLimitInMb }); + app.useBodyParser("urlencoded", { + limit: fileUploadLimitInMb, + extended: true, + }); const expressSessionSecret = configService.get( "expressSessionSecret",