From 367ae2fb97e5735950f8d386fcab20831b39bf86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouzbeh=E2=80=A0?= <78313022+rqzbeh@users.noreply.github.com> Date: Sat, 22 Aug 2026 22:43:26 +0330 Subject: [PATCH] fix(search): enforce blockedProviders setting on search endpoint (#11100) (#11125) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picked the three value commits onto the current tip, dropping the stale base-red sync commits. Focused tests: search-blocked-providers-11100 + search-registry/searxng-loopback/chat-guard/x-search suites 65/65. Fixes #11100 (endpoint half) — GET /v1/search now honors blockedProviders via getAllSearchProviders. Thank you @rqzbeh! --- open-sse/config/searchRegistry.ts | 16 ++++++++++------ src/app/api/v1/search/route.ts | 4 +--- .../unit/search-blocked-providers-11100.test.ts | 11 +++++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 tests/unit/search-blocked-providers-11100.test.ts diff --git a/open-sse/config/searchRegistry.ts b/open-sse/config/searchRegistry.ts index b3ab36ccd9..28136655fe 100644 --- a/open-sse/config/searchRegistry.ts +++ b/open-sse/config/searchRegistry.ts @@ -10,6 +10,8 @@ * perplexity-search reuses credentials from the "perplexity" chat provider. */ +import { isProviderBlockedByIdOrAlias } from "@/shared/utils/noAuthProviders"; + export interface SearchProviderConfig { id: string; name: string; @@ -394,16 +396,18 @@ export function supportsSearchType( /** * Get all search providers as a flat list */ -export function getAllSearchProviders(): Array<{ +export function getAllSearchProviders(blockedProviders: string[] = []): Array<{ id: string; name: string; searchTypes: string[]; }> { - return Object.values(SEARCH_PROVIDERS).map((p) => ({ - id: p.id, - name: p.name, - searchTypes: p.searchTypes, - })); + return Object.values(SEARCH_PROVIDERS) + .filter((p) => !p.disabled && !isProviderBlockedByIdOrAlias(p.id, blockedProviders)) + .map((p) => ({ + id: p.id, + name: p.name, + searchTypes: p.searchTypes, + })); } /** diff --git a/src/app/api/v1/search/route.ts b/src/app/api/v1/search/route.ts index adb888dff7..313b72dece 100644 --- a/src/app/api/v1/search/route.ts +++ b/src/app/api/v1/search/route.ts @@ -58,9 +58,7 @@ export async function OPTIONS() { export async function GET() { const settings = await getSettings().catch(() => ({} as any)); const blockedProviders = settings?.blockedProviders || []; - const providers = getAllSearchProviders().filter( - (p) => !isProviderBlockedByIdOrAlias(p.id, blockedProviders) - ); + const providers = getAllSearchProviders(blockedProviders); const timestamp = Math.floor(Date.now() / 1000); const data = providers.map((p) => ({ diff --git a/tests/unit/search-blocked-providers-11100.test.ts b/tests/unit/search-blocked-providers-11100.test.ts new file mode 100644 index 0000000000..1c5c775e86 --- /dev/null +++ b/tests/unit/search-blocked-providers-11100.test.ts @@ -0,0 +1,11 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { getAllSearchProviders } from "../../open-sse/config/searchRegistry.ts"; + +test("getAllSearchProviders filters out blocked providers", () => { + const all = getAllSearchProviders(); + assert.ok(all.some((p) => p.id === "serper-search")); + + const filtered = getAllSearchProviders(["serper-search"]); + assert.equal(filtered.some((p) => p.id === "serper-search"), false); +});