From d9ef2152b78ed8b09a34c1f25205348a5d024e4d Mon Sep 17 00:00:00 2001 From: abdou6666 Date: Thu, 23 Jan 2025 15:44:22 +0100 Subject: [PATCH] fix: cors issue for http server --- api/src/main.ts | 11 +++++++++- api/src/setting/services/setting.service.ts | 23 ++++++++++++++++++++- api/src/utils/constants/cache.ts | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/api/src/main.ts b/api/src/main.ts index 1f30cb70..d2e2a4cd 100644 --- a/api/src/main.ts +++ b/api/src/main.ts @@ -22,6 +22,7 @@ import { HexabotModule } from './app.module'; import { config } from './config'; import { LoggerService } from './logger/logger.service'; import { seedDatabase } from './seeder'; +import { SettingService } from './setting/services/setting.service'; import { swagger } from './swagger'; import { getSessionStore } from './utils/constants/session-store'; import { ObjectIdPipe } from './utils/pipes/object-id.pipe'; @@ -43,8 +44,16 @@ async function bootstrap() { app.use(bodyParser.urlencoded({ verify: rawBodyBuffer, extended: true })); app.use(bodyParser.json({ verify: rawBodyBuffer })); + const settingService = app.get(SettingService); + const allowedDomains = await settingService.getAllowedDomains(); app.enableCors({ - origin: config.security.cors.allowOrigins, + origin: (origin, callback) => { + if (!origin || allowedDomains.has(origin)) { + callback(null, true); + } else { + callback(new Error('Not allowed by CORS')); + } + }, methods: config.security.cors.methods, credentials: config.security.cors.allowCredentials, allowedHeaders: config.security.cors.headers.split(','), diff --git a/api/src/setting/services/setting.service.ts b/api/src/setting/services/setting.service.ts index 022519c4..3219dc31 100644 --- a/api/src/setting/services/setting.service.ts +++ b/api/src/setting/services/setting.service.ts @@ -14,7 +14,10 @@ import { Cache } from 'cache-manager'; import { config } from '@/config'; import { Config } from '@/config/types'; import { LoggerService } from '@/logger/logger.service'; -import { SETTING_CACHE_KEY } from '@/utils/constants/cache'; +import { + ALLOWED_DOMAINS_CACHE_KEY, + SETTING_CACHE_KEY, +} from '@/utils/constants/cache'; import { Cacheable } from '@/utils/decorators/cacheable.decorator'; import { BaseService } from '@/utils/generics/base-service'; @@ -110,6 +113,7 @@ export class SettingService extends BaseService { */ async clearCache() { this.cacheManager.del(SETTING_CACHE_KEY); + this.cacheManager.del(ALLOWED_DOMAINS_CACHE_KEY); } /** @@ -121,6 +125,23 @@ export class SettingService extends BaseService { this.clearCache(); } + /** + * Retrieves allowed_domains from the cache if available, or loads them from the + * repository and caches the result. + * + * @returns A promise that resolves to a Set of`allowed_domains` string. + */ + @Cacheable(ALLOWED_DOMAINS_CACHE_KEY) + async getAllowedDomains() { + // combines all allowed_doamins and whitelist them for cors + const settings = await this.find({ label: 'allowed_domains' }); + + const whiteListedOrigins = new Set( + settings.flatMap((setting) => setting.value.split(',')), + ); + return whiteListedOrigins; + } + /** * Retrieves settings from the cache if available, or loads them from the * repository and caches the result. diff --git a/api/src/utils/constants/cache.ts b/api/src/utils/constants/cache.ts index 2b70d490..1f4467cc 100644 --- a/api/src/utils/constants/cache.ts +++ b/api/src/utils/constants/cache.ts @@ -16,3 +16,5 @@ export const MENU_CACHE_KEY = 'menu'; export const LANGUAGES_CACHE_KEY = 'languages'; export const DEFAULT_LANGUAGE_CACHE_KEY = 'default_language'; + +export const ALLOWED_DOMAINS_CACHE_KEY = 'allowed-domains';