mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-18 21:22:28 +03:00
fix(providers): test token-backed web sessions (#10519)
* fix(providers): test token-backed web sessions * fix(providers): restrict token-web-session test dispatch to validated providers Narrow shouldUseApiKeyConnectionTest to the token-kind web-session providers that actually have a token-aware connection validator (deepseek-web, kimi-web, tinycms-web, copilot-m365-web, copilot-web, zai-web). WEB_SESSION_CREDENTIAL_REQUIREMENTS marks more providers as kind: "token" than have a matching validator in SPECIALTY_VALIDATORS (hailuo-web, microsoft-designer-web, t3-chat-web, promptql) — those were falling through to the generic cookie-based validateWebCookieProvider probe, which sends the stored credential as a Cookie header and treats most non-401/403 responses as valid, so an invalid token could be reported as a healthy connection. Add regression coverage for hailuo-web and promptql (plus microsoft-designer-web and t3-chat-web) proving they stay off the API-key test path, and for every currently validated token-kind provider proving they still use it. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- **fix(providers):** test token-backed web sessions through their provider validator instead of the OAuth path ([#10519](https://github.com/diegosouzapw/OmniRoute/pull/10519)) — thanks @Zartharas
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
shouldFallbackToPublicCodeSuggestions,
|
||||
} from "@/lib/oauth/gitlab";
|
||||
import { providerAllowsOptionalApiKey } from "@/shared/constants/providers";
|
||||
import { shouldUseApiKeyConnectionTest } from "./webSessionTestDispatch";
|
||||
import { removeConnectionHealth } from "@omniroute/open-sse/services/apiKeyRotator.ts";
|
||||
import { classifyAmbiguousOrAuthError, type ClassifyFailureArgs } from "./mistralAmbiguousAuth";
|
||||
import { buildApiKeyConnectionTestResult } from "./apiKeyTestResult";
|
||||
@@ -761,7 +762,7 @@ export async function testSingleConnection(connectionId: string, validationModel
|
||||
refreshed: false,
|
||||
diagnosis: (runtime as any).diagnosis,
|
||||
};
|
||||
} else if (connection.authType === "apikey") {
|
||||
} else if (shouldUseApiKeyConnectionTest(connection.authType, provider)) {
|
||||
const enrichedConnection = validationModelId
|
||||
? {
|
||||
...connection,
|
||||
|
||||
36
src/app/api/providers/[id]/test/webSessionTestDispatch.ts
Normal file
36
src/app/api/providers/[id]/test/webSessionTestDispatch.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { getWebSessionCredentialRequirement } from "@/shared/providers/webSessionCredentials";
|
||||
|
||||
/**
|
||||
* Token-kind web-session providers (`getWebSessionCredentialRequirement(...).kind ===
|
||||
* "token"`) that actually have a token-aware connection validator wired up in
|
||||
* `src/lib/providers/validation.ts`'s `SPECIALTY_VALIDATORS` map — either a dedicated
|
||||
* `validate*WebProvider` entry, or (zai-web) a token-aware branch inside the generic
|
||||
* `validateWebCookieProvider` probe (`src/lib/providers/validation/webCookie.ts`).
|
||||
*
|
||||
* `WEB_SESSION_CREDENTIAL_REQUIREMENTS` currently marks more providers as `kind: "token"`
|
||||
* than have a matching validator (e.g. hailuo-web, microsoft-designer-web, t3-chat-web,
|
||||
* promptql). Those fall through to `validateWebCookieProvider`'s generic probe, which
|
||||
* sends the stored credential as a `Cookie` header and treats most non-401/403 responses
|
||||
* as valid — the wrong wire format for a token-authenticated provider, so an invalid
|
||||
* token can be reported as a healthy connection. Keep this set in sync with
|
||||
* `SPECIALTY_VALIDATORS` (and the zai-web branch in `webCookie.ts`): add a provider here
|
||||
* only after it has a real token-aware validator.
|
||||
*/
|
||||
const TOKEN_AWARE_VALIDATED_WEB_SESSION_PROVIDERS = new Set([
|
||||
"deepseek-web",
|
||||
"kimi-web",
|
||||
"tinycms-web",
|
||||
"copilot-m365-web",
|
||||
"copilot-web",
|
||||
"zai-web",
|
||||
]);
|
||||
|
||||
export function shouldUseApiKeyConnectionTest(authType: unknown, providerId: unknown): boolean {
|
||||
if (authType === "apikey") return true;
|
||||
if (authType !== "cookie") return false;
|
||||
if (getWebSessionCredentialRequirement(providerId)?.kind !== "token") return false;
|
||||
return (
|
||||
typeof providerId === "string" &&
|
||||
TOKEN_AWARE_VALIDATED_WEB_SESSION_PROVIDERS.has(providerId)
|
||||
);
|
||||
}
|
||||
48
tests/unit/provider-test-token-web-session-dispatch.test.ts
Normal file
48
tests/unit/provider-test-token-web-session-dispatch.test.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const { shouldUseApiKeyConnectionTest } =
|
||||
await import("../../src/app/api/providers/[id]/test/webSessionTestDispatch.ts");
|
||||
|
||||
test("normal API-key connections keep the API-key test path", () => {
|
||||
assert.equal(shouldUseApiKeyConnectionTest("apikey", "openai"), true);
|
||||
});
|
||||
|
||||
test("token-kind cookie-auth web sessions use the API-key test path", () => {
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "deepseek-web"), true);
|
||||
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "zai-web"), true);
|
||||
});
|
||||
|
||||
test("cookie-kind web sessions do not use the API-key test path", () => {
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "chatgpt-web"), false);
|
||||
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "claude-web"), false);
|
||||
});
|
||||
|
||||
test("token-kind web sessions WITHOUT a token-aware validator stay off the API-key test path", () => {
|
||||
// hailuo-web and promptql are `kind: "token"` in WEB_SESSION_CREDENTIAL_REQUIREMENTS,
|
||||
// but neither has an entry in validation.ts's SPECIALTY_VALIDATORS map (nor a
|
||||
// token-aware branch like zai-web's in validateWebCookieProvider). Routing them through
|
||||
// the API-key test path would dispatch to the generic cookie probe, which sends the
|
||||
// stored token as a `Cookie` header and treats most non-401/403 responses as valid —
|
||||
// an invalid hailuo-web/promptql token could be reported as a healthy connection.
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "hailuo-web"), false);
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "promptql"), false);
|
||||
|
||||
// Same reasoning applies to the other two token-kind providers with no validator.
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "microsoft-designer-web"), false);
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", "t3-chat-web"), false);
|
||||
});
|
||||
|
||||
test("every token-kind web session with a real token-aware validator uses the API-key test path", () => {
|
||||
for (const providerId of ["deepseek-web", "kimi-web", "tinycms-web", "copilot-m365-web", "copilot-web", "zai-web"]) {
|
||||
assert.equal(shouldUseApiKeyConnectionTest("cookie", providerId), true, providerId);
|
||||
}
|
||||
});
|
||||
|
||||
test("other auth types are not broadened", () => {
|
||||
assert.equal(shouldUseApiKeyConnectionTest("oauth", "deepseek-web"), false);
|
||||
|
||||
assert.equal(shouldUseApiKeyConnectionTest(null, "deepseek-web"), false);
|
||||
});
|
||||
Reference in New Issue
Block a user