mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
feat(kimchi): add Kimchi OAuth provider support
Add Kimchi as a browser-token OAuth provider routed through its OpenAI-compatible gateway. Discover live models for /v1/models and provider models, normalize Claude-compatible requests, and wire up provider connection tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
2d94fffe3b
commit
8a664d619d
@@ -65,7 +65,7 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess,
|
||||
setError(err.message);
|
||||
setStep("error");
|
||||
}
|
||||
}, [authData, provider, onSuccess]);
|
||||
}, [authData, provider, onSuccess, oauthMeta]);
|
||||
|
||||
const completeXaiManualCode = useCallback(async (code) => {
|
||||
if (!authData?.state) return;
|
||||
@@ -387,7 +387,7 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess,
|
||||
const handleCallback = async (data) => {
|
||||
if (callbackProcessedRef.current) return; // Already processed
|
||||
|
||||
const { code, state, error: callbackError, errorDescription } = data;
|
||||
const { code, token, state, error: callbackError, errorDescription } = data;
|
||||
|
||||
if (callbackError) {
|
||||
callbackProcessedRef.current = true;
|
||||
@@ -396,9 +396,9 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess,
|
||||
return;
|
||||
}
|
||||
|
||||
if (code) {
|
||||
if (token || code) {
|
||||
callbackProcessedRef.current = true;
|
||||
await exchangeTokens(code, state);
|
||||
await exchangeTokens(token || code, state);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -477,8 +477,14 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess,
|
||||
return;
|
||||
}
|
||||
|
||||
if (provider === "kimchi" && input && !input.includes("://") && !input.includes("?")) {
|
||||
await exchangeTokens(input, null);
|
||||
return;
|
||||
}
|
||||
|
||||
const url = new URL(input);
|
||||
const code = url.searchParams.get("code");
|
||||
const token = url.searchParams.get("token");
|
||||
const state = url.searchParams.get("state");
|
||||
const errorParam = url.searchParams.get("error");
|
||||
|
||||
@@ -486,11 +492,17 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess,
|
||||
throw new Error(url.searchParams.get("error_description") || errorParam);
|
||||
}
|
||||
|
||||
if (!code) {
|
||||
throw new Error(provider === "xai" ? "Paste the callback URL or copied xAI code" : "No authorization code found in URL");
|
||||
if (!code && !token) {
|
||||
throw new Error(
|
||||
provider === "xai"
|
||||
? "Paste the callback URL or copied xAI code"
|
||||
: provider === "kimchi"
|
||||
? "No Kimchi token found in URL"
|
||||
: "No authorization code found in URL"
|
||||
);
|
||||
}
|
||||
|
||||
await exchangeTokens(code, state);
|
||||
await exchangeTokens(token || code, state);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
setStep("error");
|
||||
@@ -509,11 +521,14 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess,
|
||||
|
||||
if (!provider || !providerInfo) return null;
|
||||
const isXaiProvider = provider === "xai";
|
||||
const isKimchiProvider = provider === "kimchi";
|
||||
const deviceLoginUrl = deviceData?.verification_uri_complete || deviceData?.verification_uri || "";
|
||||
const modalTitle = isXaiProvider ? "Connect Grok Build OAuth" : `Connect ${providerInfo.name}`;
|
||||
const manualPlaceholder = isXaiProvider
|
||||
? "http://127.0.0.1:56121/callback?code=... or copied code"
|
||||
: placeholderUrl;
|
||||
: isKimchiProvider
|
||||
? `${placeholderUrl.replace("code=...", "token=...")} or copied token`
|
||||
: placeholderUrl;
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} title={modalTitle} onClose={handleClose} size="lg">
|
||||
@@ -554,11 +569,13 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess,
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">
|
||||
Step 2: Paste the {provider === "xai" ? "callback URL or copied code" : "callback URL"} here
|
||||
Step 2: Paste the {provider === "xai" ? "callback URL or copied code" : isKimchiProvider ? "callback URL or copied token" : "callback URL"} here
|
||||
</p>
|
||||
<p className="text-xs text-text-muted mb-2">
|
||||
{provider === "xai"
|
||||
? "If xAI shows a code instead of redirecting, paste that code here."
|
||||
: isKimchiProvider
|
||||
? "After authorization, copy the full callback URL or token from your browser."
|
||||
: "After authorization, copy the full URL from your browser."}
|
||||
</p>
|
||||
<Input
|
||||
|
||||
Reference in New Issue
Block a user