mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 18:18:21 +00:00
fix(cliproxy): harden kiro device-code auth flow consistency
This commit is contained in:
1 parent
84e0bce99e
commit
826a42d8d6
9 files changed
+122
-43
No files matched your search
@@ -15,19 +15,19 @@ import { AccountInfo } from '../account-manager';
|
||||
* - Gemini: Authorization Code Flow with local callback server on port 8085
|
||||
* - Codex: Authorization Code Flow with local callback server on port 1455
|
||||
* - Agy: Authorization Code Flow with local callback server on port 51121
|
||||
* - Kiro: Authorization Code Flow with local callback server on port 9876
|
||||
* - iFlow: Authorization Code Flow with local callback server on port 11451
|
||||
* - Claude: Authorization Code Flow with local callback server on port 54545 (Anthropic OAuth)
|
||||
* - Kiro: Device Code Flow (polling-based, NO callback port needed)
|
||||
* - Qwen: Device Code Flow (polling-based, NO callback port needed)
|
||||
* - GHCP: Device Code Flow (polling-based, NO callback port needed)
|
||||
*/
|
||||
export const OAUTH_CALLBACK_PORTS: Partial<Record<CLIProxyProvider, number>> = {
|
||||
gemini: 8085,
|
||||
kiro: 9876,
|
||||
codex: 1455,
|
||||
agy: 51121,
|
||||
iflow: 11451,
|
||||
claude: 54545,
|
||||
// kiro: Device Code Flow - no callback port
|
||||
// qwen: Device Code Flow - no callback port
|
||||
// ghcp: Device Code Flow - no callback port
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* - Codex: 1455
|
||||
* - Agy: 51121
|
||||
* - iFlow: 11451
|
||||
* - Kiro: 9876
|
||||
* - Kiro: Device Code Flow (no port needed)
|
||||
* - Claude: 54545
|
||||
* - Qwen: Device Code Flow (no port needed)
|
||||
* - GHCP: Device Code Flow (no port needed)
|
||||
@@ -26,40 +26,44 @@ import {
|
||||
} from '../utils/port-utils';
|
||||
import { CLIProxyProvider } from '../cliproxy/types';
|
||||
import { CLIPROXY_PROFILES } from '../auth/profile-detector';
|
||||
import {
|
||||
CLIPROXY_PROVIDER_IDS,
|
||||
getOAuthCallbackPort,
|
||||
getOAuthFlowType,
|
||||
type OAuthFlowType as ProviderOAuthFlowType,
|
||||
} from '../cliproxy/provider-capabilities';
|
||||
|
||||
/**
|
||||
* OAuth callback ports for each provider
|
||||
* Extracted from CLIProxyAPI source
|
||||
* Build provider-indexed records from canonical provider capabilities.
|
||||
* Keeps diagnostics in sync with runtime OAuth flow metadata.
|
||||
*/
|
||||
export const OAUTH_CALLBACK_PORTS: Record<CLIProxyProvider, number | null> = {
|
||||
gemini: 8085,
|
||||
codex: 1455,
|
||||
agy: 51121,
|
||||
qwen: null, // Device Code Flow - no callback port
|
||||
iflow: 11451, // Authorization Code Flow
|
||||
kiro: 9876, // Authorization Code Flow
|
||||
ghcp: null, // Device Code Flow - no callback port
|
||||
claude: 54545, // Authorization Code Flow (Anthropic OAuth)
|
||||
};
|
||||
function buildProviderMap<T>(
|
||||
valueFor: (provider: CLIProxyProvider) => T
|
||||
): Record<CLIProxyProvider, T> {
|
||||
return CLIPROXY_PROVIDER_IDS.reduce(
|
||||
(acc, provider) => {
|
||||
acc[provider] = valueFor(provider);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<CLIProxyProvider, T>
|
||||
);
|
||||
}
|
||||
|
||||
export const OAUTH_CALLBACK_PORTS: Record<CLIProxyProvider, number | null> = buildProviderMap(
|
||||
(provider) => getOAuthCallbackPort(provider)
|
||||
);
|
||||
|
||||
/**
|
||||
* OAuth flow types
|
||||
*/
|
||||
export type OAuthFlowType = 'authorization_code' | 'device_code';
|
||||
export type OAuthFlowType = ProviderOAuthFlowType;
|
||||
|
||||
/**
|
||||
* OAuth flow type per provider
|
||||
*/
|
||||
export const OAUTH_FLOW_TYPES: Record<CLIProxyProvider, OAuthFlowType> = {
|
||||
gemini: 'authorization_code',
|
||||
codex: 'authorization_code',
|
||||
agy: 'authorization_code',
|
||||
qwen: 'device_code',
|
||||
iflow: 'authorization_code',
|
||||
kiro: 'authorization_code',
|
||||
ghcp: 'device_code',
|
||||
claude: 'authorization_code',
|
||||
};
|
||||
export const OAUTH_FLOW_TYPES: Record<CLIProxyProvider, OAuthFlowType> = buildProviderMap(
|
||||
(provider) => getOAuthFlowType(provider)
|
||||
);
|
||||
|
||||
/**
|
||||
* Port diagnostic result
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
CLIPROXY_CALLBACK_PROVIDER_MAP,
|
||||
CLIPROXY_AUTH_URL_PROVIDER_MAP,
|
||||
} from '../../cliproxy/auth/auth-types';
|
||||
import { getOAuthFlowType } from '../../cliproxy/provider-capabilities';
|
||||
import type { CLIProxyProvider } from '../../cliproxy/types';
|
||||
import { CLIPROXY_PROFILES } from '../../auth/profile-detector';
|
||||
|
||||
@@ -46,6 +47,13 @@ const router = Router();
|
||||
// Valid providers list - derived from canonical CLIPROXY_PROFILES
|
||||
const validProviders: CLIProxyProvider[] = [...CLIPROXY_PROFILES];
|
||||
|
||||
export function getStartUrlUnsupportedReason(provider: CLIProxyProvider): string | null {
|
||||
if (getOAuthFlowType(provider) === 'device_code') {
|
||||
return `Provider '${provider}' uses Device Code flow. Use /api/cliproxy/auth/${provider}/start instead.`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/cliproxy/auth - Get auth status for built-in CLIProxy profiles
|
||||
* Also fetches CLIProxyAPI stats to update lastUsedAt for active providers
|
||||
@@ -557,6 +565,11 @@ router.post('/:provider/start-url', async (req: Request, res: Response): Promise
|
||||
res.status(400).json({ error: `Invalid provider: ${provider}` });
|
||||
return;
|
||||
}
|
||||
const unsupportedReason = getStartUrlUnsupportedReason(provider as CLIProxyProvider);
|
||||
if (unsupportedReason) {
|
||||
res.status(400).json({ error: unsupportedReason });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const authUrlProvider =
|
||||
|
||||
Reference in new issue
Block a user