From 987b67420af4330017271bd3f829920ca925fdc4 Mon Sep 17 00:00:00 2001 From: Paco Cartones <253313177+pacocartones@users.noreply.github.com> Date: Tue, 25 Aug 2026 18:11:41 +0200 Subject: [PATCH] fix(kimi-web): align health probe with executor domain (#11521) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validated in a combined 10-PR batch worktree off release/v3.8.51 tip. Fixes #11515. - Focused test: tests/unit/kimi-web-validation-11515.test.ts — 37/37 pass; live unauthenticated probe confirms www.kimi.ai/api/user returns the expected 401 boundary - typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity gates — all OK - Full-repo lint: 503 pre-existing problems confirmed identical on the pure release/v3.8.51 tip — unrelated to this diff ⚠️ base-red inherited: #11449 Thanks for aligning the health probe with the executor's actual domain plus the live verification. --- src/lib/providers/validation/webProvidersA.ts | 14 +++---- tests/unit/kimi-web-validation-11515.test.ts | 41 +++++++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 tests/unit/kimi-web-validation-11515.test.ts diff --git a/src/lib/providers/validation/webProvidersA.ts b/src/lib/providers/validation/webProvidersA.ts index 52e9aa4c0e..7c9746ccd7 100644 --- a/src/lib/providers/validation/webProvidersA.ts +++ b/src/lib/providers/validation/webProvidersA.ts @@ -26,7 +26,7 @@ export async function validateKimiWebProvider({ apiKey }: any) { if (!rawCred) { return { valid: false, - error: "Missing Kimi access_token from www.kimi.com localStorage", + error: "Missing Kimi access_token from www.kimi.ai localStorage", }; } @@ -35,17 +35,17 @@ export async function validateKimiWebProvider({ apiKey }: any) { return { valid: false, error: - "Could not find a Kimi access_token. Re-login at https://www.kimi.com and copy it from localStorage.", + "Could not find a Kimi access_token. Re-login at https://www.kimi.ai and copy it from localStorage.", }; } try { - const resp = await fetch("https://www.kimi.com/api/user", { + const resp = await fetch("https://www.kimi.ai/api/user", { headers: { Accept: "application/json, text/plain, */*", Authorization: `Bearer ${accessToken}`, - Origin: "https://www.kimi.com", - Referer: "https://www.kimi.com/", + Origin: "https://www.kimi.ai", + Referer: "https://www.kimi.ai/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36", }, @@ -55,7 +55,7 @@ export async function validateKimiWebProvider({ apiKey }: any) { return { valid: false, error: - "Kimi session is invalid or expired — re-login at https://www.kimi.com and paste a fresh access_token", + "Kimi session is invalid or expired — re-login at https://www.kimi.ai and paste a fresh access_token", }; } if (!resp.ok) { @@ -69,7 +69,7 @@ export async function validateKimiWebProvider({ apiKey }: any) { return { valid: false, error: - "Kimi session token is invalid or expired — re-login at https://www.kimi.com and paste a fresh access_token", + "Kimi session token is invalid or expired — re-login at https://www.kimi.ai and paste a fresh access_token", }; } } catch { diff --git a/tests/unit/kimi-web-validation-11515.test.ts b/tests/unit/kimi-web-validation-11515.test.ts new file mode 100644 index 0000000000..bed9f70293 --- /dev/null +++ b/tests/unit/kimi-web-validation-11515.test.ts @@ -0,0 +1,41 @@ +import { test, afterEach } from "node:test"; +import assert from "node:assert/strict"; + +import { validateKimiWebProvider } from "../../src/lib/providers/validation/webProvidersA.ts"; + +const originalFetch = globalThis.fetch; + +afterEach(() => { + globalThis.fetch = originalFetch; +}); + +function headerValue(init: RequestInit | undefined, name: string): string | undefined { + return ((init?.headers ?? {}) as Record)[name]; +} + +test("#11515 kimi-web health probe matches the executor domain and browser headers", async () => { + const calls: { url: string; init: RequestInit }[] = []; + globalThis.fetch = async (url, init = {}) => { + calls.push({ url: String(url), init }); + return new Response(JSON.stringify({ id: "kimi-user" }), { status: 200 }); + }; + + const result = await validateKimiWebProvider({ apiKey: "access_token=kimi-session" }); + + assert.deepEqual(result, { valid: true, error: null }); + assert.equal(calls.length, 1); + assert.equal(calls[0].url, "https://www.kimi.ai/api/user"); + assert.equal(headerValue(calls[0].init, "Authorization"), "Bearer kimi-session"); + assert.equal(headerValue(calls[0].init, "Origin"), "https://www.kimi.ai"); + assert.equal(headerValue(calls[0].init, "Referer"), "https://www.kimi.ai/"); +}); + +test("#11515 kimi-web auth errors identify the executor domain", async () => { + globalThis.fetch = async () => new Response("", { status: 401 }); + + const result = await validateKimiWebProvider({ apiKey: "kimi-session" }); + + assert.equal(result.valid, false); + assert.match(result.error ?? "", /https:\/\/www\.kimi\.ai/); + assert.doesNotMatch(result.error ?? "", /https:\/\/www\.kimi\.com/); +});