mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 05:12:11 +03:00
fix(qoder): bifurcate validation by token type — PAT→Cosy, regular API key→dashscope (#3149)
Bifurcate Qoder validation by token type (PAT→Cosy, regular→dashscope) +regression test. Integrated into release/v3.8.10.
This commit is contained in:
committed by
GitHub
parent
d3c753ecbe
commit
28b44b01d4
@@ -3718,8 +3718,43 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi
|
||||
// ── Specialty provider validation ──
|
||||
const SPECIALTY_VALIDATORS = {
|
||||
jules: validateJulesProvider,
|
||||
qoder: ({ apiKey, providerSpecificData }: any) =>
|
||||
validateQoderCliPat({ apiKey, providerSpecificData }),
|
||||
qoder: async ({ apiKey, providerSpecificData }: any) => {
|
||||
// Bifurcate validation: PAT tokens use Cosy auth against api1.qoder.sh;
|
||||
// regular API keys validate against dashscope (OpenAI-compatible endpoint).
|
||||
const key = (apiKey || "").trim();
|
||||
if (key.startsWith("pt-")) {
|
||||
return validateQoderCliPat({ apiKey: key, providerSpecificData });
|
||||
}
|
||||
// Non-PAT token → validate against dashscope (Alibaba Cloud).
|
||||
// The executor routes these tokens to dashscope.aliyuncs.com, so the
|
||||
// validation must test against dashscope, NOT the Cosy PAT endpoint.
|
||||
try {
|
||||
const dashscopeUrl =
|
||||
"https://dashscope.aliyuncs.com/compatible-mode/v1/models";
|
||||
const res = await validationRead(
|
||||
dashscopeUrl,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${key}`,
|
||||
},
|
||||
},
|
||||
false
|
||||
);
|
||||
if (res.ok) return { valid: true, error: null };
|
||||
if (res.status === 401 || res.status === 403) {
|
||||
return {
|
||||
valid: false,
|
||||
error:
|
||||
"Invalid Qoder API key. Make sure you're using a valid API key from Qoder / Alibaba Cloud Dashscope.",
|
||||
};
|
||||
}
|
||||
// 4xx/5xx other than auth — treat as valid bypass to prevent false
|
||||
// negatives from transient dashscope issues (consistent with PAT path).
|
||||
return { valid: true, error: null };
|
||||
} catch (err: unknown) {
|
||||
return toValidationErrorResult(err);
|
||||
}
|
||||
},
|
||||
"command-code": validateCommandCodeProvider,
|
||||
deepgram: validateDeepgramProvider,
|
||||
assemblyai: validateAssemblyAIProvider,
|
||||
|
||||
@@ -188,3 +188,43 @@ test("#2545 gemini validation does not produce /models/models", async () => {
|
||||
`outbound URL must hit a single /models segment — got ${calls.join(", ")}`
|
||||
);
|
||||
});
|
||||
|
||||
test("qoder regular API key validates against dashscope, not the Cosy PAT endpoint (#3149)", async () => {
|
||||
const calls: string[] = [];
|
||||
globalThis.fetch = async (url: any, init: any) => {
|
||||
calls.push(String(url));
|
||||
const auth = new Headers(init?.headers as HeadersInit | undefined).get("authorization");
|
||||
assert.equal(auth, "Bearer sk-qoder-regular", "dashscope probe must forward the API key");
|
||||
return new Response(JSON.stringify({ data: [] }), { status: 200 });
|
||||
};
|
||||
|
||||
const result = await validateProviderApiKey({
|
||||
provider: "qoder",
|
||||
apiKey: "sk-qoder-regular",
|
||||
providerSpecificData: {},
|
||||
});
|
||||
|
||||
assert.equal(result.valid, true);
|
||||
assert.ok(
|
||||
calls.some((u) => u.includes("dashscope.aliyuncs.com/compatible-mode/v1/models")),
|
||||
`regular qoder key must validate against dashscope — got ${calls.join(", ")}`
|
||||
);
|
||||
assert.ok(
|
||||
!calls.some((u) => u.includes("api1.qoder.sh")),
|
||||
"regular (non-PAT) key must not hit the Cosy PAT endpoint"
|
||||
);
|
||||
});
|
||||
|
||||
test("qoder regular API key surfaces an auth error when dashscope rejects it (#3149)", async () => {
|
||||
globalThis.fetch = async () =>
|
||||
new Response(JSON.stringify({ error: { message: "invalid api key" } }), { status: 401 });
|
||||
|
||||
const result = await validateProviderApiKey({
|
||||
provider: "qoder",
|
||||
apiKey: "sk-qoder-bad",
|
||||
providerSpecificData: {},
|
||||
});
|
||||
|
||||
assert.equal(result.valid, false);
|
||||
assert.match(result.error, /Qoder|Dashscope|API key/i);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user