From 66d0d81e836a7fe81882a448cf999ce4dcd57597 Mon Sep 17 00:00:00 2001 From: chenos Date: Tue, 21 Jul 2026 15:44:08 +0800 Subject: [PATCH] fix(server): support wildcard CORS origins --- .../core/server/src/__tests__/helper.test.ts | 36 +++++++++++++++++++ packages/core/server/src/helper.ts | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 packages/core/server/src/__tests__/helper.test.ts diff --git a/packages/core/server/src/__tests__/helper.test.ts b/packages/core/server/src/__tests__/helper.test.ts new file mode 100644 index 00000000000..2ba55728631 --- /dev/null +++ b/packages/core/server/src/__tests__/helper.test.ts @@ -0,0 +1,36 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { resolveCorsOrigin } from '../helper'; + +describe('resolveCorsOrigin', () => { + const origin = 'https://portal.example.com'; + + afterEach(() => { + delete process.env.CORS_ORIGIN_WHITELIST; + }); + + it('allows every origin when the whitelist contains an asterisk', () => { + process.env.CORS_ORIGIN_WHITELIST = '*'; + + expect(resolveCorsOrigin({ get: () => origin })).toBe(origin); + }); + + it('allows an asterisk alongside explicit origins', () => { + process.env.CORS_ORIGIN_WHITELIST = 'https://admin.example.com, *'; + + expect(resolveCorsOrigin({ get: () => origin })).toBe(origin); + }); + + it('keeps exact matching when the whitelist does not contain an asterisk', () => { + process.env.CORS_ORIGIN_WHITELIST = 'https://admin.example.com'; + + expect(resolveCorsOrigin({ get: () => origin })).toBe(false); + }); +}); diff --git a/packages/core/server/src/helper.ts b/packages/core/server/src/helper.ts index 134d73bb8e7..f87e049bade 100644 --- a/packages/core/server/src/helper.ts +++ b/packages/core/server/src/helper.ts @@ -39,7 +39,7 @@ export function createResourcer(options: ApplicationOptions) { return new Resourcer({ ...options.resourcer }); } -function resolveCorsOrigin(ctx: any) { +export function resolveCorsOrigin(ctx: any) { const origin = ctx.get('origin'); const disallowNoOrigin = process.env.CORS_DISALLOW_NO_ORIGIN === 'true'; const whitelistString = process.env.CORS_ORIGIN_WHITELIST; @@ -59,7 +59,7 @@ function resolveCorsOrigin(ctx: any) { .filter(Boolean), ); - if (whitelist.has(origin)) { + if (whitelist.has('*') || whitelist.has(origin)) { return origin; }