mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 22:32:12 +03:00
fix(kimi-web): migrate to www.kimi.com Connect-RPC API (kimi.moonshot.cn retired) (#5858)
Integrated into release/v3.8.43
This commit is contained in:
@@ -4836,7 +4836,7 @@
|
||||
"v0VercelWebLabel": "v0 Vercel Web",
|
||||
"v0VercelWebDesc": "AI code generation via v0.dev",
|
||||
"kimiWebLabel": "Kimi Web",
|
||||
"kimiWebDesc": "Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "Doubao Web",
|
||||
"doubaoWebDesc": "ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "v0 Vercel Web",
|
||||
"v0VercelWebDesc": "Генерация кода ИИ через v0.dev",
|
||||
"kimiWebLabel": "Kimi Web",
|
||||
"kimiWebDesc": "Китайский рынок AI чата через kimi.moonshot.cn",
|
||||
"kimiWebDesc": "Чат Moonshot AI через www.kimi.com (международная версия, Connect-RPC API)",
|
||||
"doubaoWebLabel": "Doubao Web",
|
||||
"doubaoWebDesc": "Чат AI ByteDance через doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4811,7 +4811,7 @@
|
||||
"v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
|
||||
"v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
|
||||
"kimiWebLabel": "__MISSING__:Kimi Web",
|
||||
"kimiWebDesc": "__MISSING__:Chinese market AI chat via kimi.moonshot.cn",
|
||||
"kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
|
||||
"doubaoWebLabel": "__MISSING__:Doubao Web",
|
||||
"doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com"
|
||||
},
|
||||
|
||||
@@ -4667,7 +4667,7 @@
|
||||
"v0VercelWebLabel": "v0 Vercel Web",
|
||||
"v0VercelWebDesc": "通过 v0.dev 的 AI 代码生成",
|
||||
"kimiWebLabel": "Kimi Web",
|
||||
"kimiWebDesc": "通过 kimi.moonshot.cn 访问中国市场的 AI 聊天",
|
||||
"kimiWebDesc": "通过 www.kimi.com 访问 Moonshot AI 聊天(国际版,Connect-RPC API)",
|
||||
"doubaoWebLabel": "豆包网",
|
||||
"doubaoWebDesc": "字节跳动 AI 聊天通过 doubao.com",
|
||||
"Account Deactivated": "账户已停用",
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
validateChatGptWebProvider,
|
||||
validatePerplexityWebProvider,
|
||||
validateBlackboxWebProvider,
|
||||
validateKimiWebProvider,
|
||||
} from "./validation/webProvidersA";
|
||||
import {
|
||||
validateMuseSparkWebProvider,
|
||||
@@ -349,6 +350,7 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi
|
||||
"deepseek-web": validateDeepSeekWebProvider,
|
||||
"grok-web": validateGrokWebProvider,
|
||||
"qwen-web": validateQwenWebProvider,
|
||||
"kimi-web": validateKimiWebProvider,
|
||||
"chatgpt-web": validateChatGptWebProvider,
|
||||
"perplexity-web": validatePerplexityWebProvider,
|
||||
"blackbox-web": validateBlackboxWebProvider,
|
||||
|
||||
@@ -8,10 +8,85 @@ import {
|
||||
buildGrokCookieHeader,
|
||||
buildQwenCookieHeader,
|
||||
extractCookieValue,
|
||||
extractKimiJwt,
|
||||
extractQwenToken,
|
||||
normalizeSessionCookieHeader,
|
||||
} from "@/lib/providers/webCookieAuth";
|
||||
|
||||
// kimi-web uses the international `www.kimi.com` Connect-RPC API. The legacy
|
||||
// `kimi.moonshot.cn` domain now 307-redirects every non-CN visitor, and even
|
||||
// if you bypass the redirect the old `/api/chat` REST endpoint is gone. The
|
||||
// SPA exposes a profile probe at `GET /api/user` that returns the user object
|
||||
// at the top level when the `Authorization: Bearer <JWT>` header is valid.
|
||||
//
|
||||
// Auth source: the `kimi-auth` cookie set after login. The user pastes the
|
||||
// full Cookie header; we extract `kimi-auth` and send it as both the Bearer
|
||||
// token and a `Cookie: kimi-auth=<jwt>` replay (the latter is what the SPA
|
||||
// does, though the upstream only consults the Authorization header in
|
||||
// practice — verified by stripping one of the two at a time).
|
||||
export async function validateKimiWebProvider({ apiKey }: any) {
|
||||
const rawCred = String(apiKey ?? "").trim();
|
||||
if (!rawCred) {
|
||||
return {
|
||||
valid: false,
|
||||
error:
|
||||
"Missing Kimi session — paste the full Cookie header from www.kimi.com (must contain kimi-auth=<JWT>)",
|
||||
};
|
||||
}
|
||||
|
||||
const jwt = extractKimiJwt(rawCred);
|
||||
if (!jwt) {
|
||||
return {
|
||||
valid: false,
|
||||
error:
|
||||
"Could not find a kimi-auth JWT in the pasted value. Re-login at https://www.kimi.com and copy the full Cookie header.",
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const resp = await fetch("https://www.kimi.com/api/user", {
|
||||
headers: {
|
||||
Accept: "application/json, text/plain, */*",
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
Cookie: `kimi-auth=${jwt}`,
|
||||
Origin: "https://www.kimi.com",
|
||||
Referer: "https://www.kimi.com/",
|
||||
"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",
|
||||
},
|
||||
});
|
||||
|
||||
if (resp.status === 401 || resp.status === 403) {
|
||||
return {
|
||||
valid: false,
|
||||
error:
|
||||
"Kimi session is invalid or expired — re-login at https://www.kimi.com and paste a fresh Cookie header",
|
||||
};
|
||||
}
|
||||
if (!resp.ok) {
|
||||
return { valid: false, error: `Kimi returned HTTP ${resp.status}` };
|
||||
}
|
||||
|
||||
// Profile response: `{ id, name, email, region, ... }` at the top level.
|
||||
try {
|
||||
const data = await resp.json();
|
||||
if (!data?.id) {
|
||||
return {
|
||||
valid: false,
|
||||
error:
|
||||
"Kimi session token is invalid or expired — re-login at https://www.kimi.com and paste a fresh Cookie header",
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
return { valid: false, error: "Kimi returned invalid JSON response" };
|
||||
}
|
||||
|
||||
return { valid: true, error: null };
|
||||
} catch (error) {
|
||||
return toValidationErrorResult(error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function validateDeepSeekWebProvider({ apiKey }: any) {
|
||||
if (!apiKey) {
|
||||
return {
|
||||
|
||||
@@ -106,6 +106,38 @@ export function extractQwenToken(rawValue: string): string {
|
||||
return match ? match[1] : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the `kimi-auth` JWT out of whatever the user pasted for the
|
||||
* international Kimi consumer chat (www.kimi.com).
|
||||
*
|
||||
* Accepts (all return the same JWT string):
|
||||
* - bare JWT `eyJhbGci...sig`
|
||||
* - full Cookie header `_ga=...; kimi-auth=eyJ...; theme=dark`
|
||||
* - `Cookie:` / `Authorization: Bearer` prefixed forms
|
||||
* - stray `Bearer eyJ...` without a header label
|
||||
*
|
||||
* Returns "" if no JWT can be located.
|
||||
*/
|
||||
export function extractKimiJwt(rawValue: string): string {
|
||||
const trimmed = stripCookieInputPrefix(rawValue);
|
||||
if (!trimmed) return "";
|
||||
|
||||
// Bare JWT — three base64url segments separated by dots.
|
||||
if (/^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(trimmed)) {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
// Cookie-style pair: pull `kimi-auth=<value>` out of the blob.
|
||||
const match = trimmed.match(/(?:^|[\s;])kimi-auth=([^;\s]+)/);
|
||||
if (match) return match[1];
|
||||
|
||||
// Last resort: a `Bearer <jwt>` pasted without the header label.
|
||||
const bearer = trimmed.match(/bearer\s+(eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)/i);
|
||||
if (bearer) return bearer[1];
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
export function normalizeSessionCookieHeaders(
|
||||
rawValues: Array<string | null | undefined>,
|
||||
defaultCookieName: string
|
||||
|
||||
@@ -242,8 +242,8 @@ export const WEB_COOKIE_PROVIDERS = {
|
||||
icon: "auto_awesome",
|
||||
color: "#2563EB",
|
||||
textIcon: "KW",
|
||||
website: "https://kimi.moonshot.cn",
|
||||
authHint: "Paste your session cookie from kimi.moonshot.cn (DevTools → Application → Cookies)",
|
||||
website: "https://www.kimi.com",
|
||||
authHint: "Paste your Cookie header from www.kimi.com (must contain kimi-auth=...). Find it via DevTools → Network → request → Cookie.",
|
||||
subscriptionRisk: true,
|
||||
riskNoticeVariant: "webCookie",
|
||||
},
|
||||
|
||||
@@ -164,10 +164,10 @@ export const WEB_SESSION_CREDENTIAL_REQUIREMENTS = {
|
||||
},
|
||||
"kimi-web": {
|
||||
kind: "cookie",
|
||||
credentialName: "session",
|
||||
placeholder: "session=... or full Cookie header from kimi.moonshot.cn",
|
||||
credentialName: "kimi-auth",
|
||||
placeholder: "kimi-auth=eyJ... (full Cookie header from www.kimi.com)",
|
||||
acceptsFullCookieHeader: true,
|
||||
storageKeys: ["cookie", "session"],
|
||||
storageKeys: ["cookie", "kimi-auth", "session"],
|
||||
},
|
||||
"doubao-web": {
|
||||
kind: "cookie",
|
||||
|
||||
Reference in New Issue
Block a user