mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-04 02:17:49 +00:00
feat(cliproxy): allow optional provider nicknames
- stop requiring manual unique nicknames for no-email providers by default - preserve explicit nickname validation and same-account reauth semantics - persist optional nicknames through dashboard manual callback flows
This commit is contained in:
@@ -41,7 +41,6 @@ import {
|
||||
DEFAULT_KIRO_AUTH_METHOD,
|
||||
getKiroAuthMethodOption,
|
||||
isDeviceCodeProvider,
|
||||
isNicknameRequiredProvider,
|
||||
KIRO_AUTH_METHOD_OPTIONS,
|
||||
} from '@/lib/provider-config';
|
||||
import type { KiroAuthMethod } from '@/lib/provider-config';
|
||||
@@ -89,7 +88,6 @@ export function AddAccountDialog({
|
||||
const isAgyRiskChecklistComplete = isAntigravityRiskChecklistComplete(agyRiskChecklist);
|
||||
const isGeminiRiskAcknowledged = normalizeRiskPhrase(riskAcknowledgementText) === RISK_ACK_PHRASE;
|
||||
const defaultDeviceCode = isDeviceCodeProvider(provider);
|
||||
const requiresNickname = isNicknameRequiredProvider(provider);
|
||||
const kiroMethodOption = getKiroAuthMethodOption(kiroAuthMethod);
|
||||
const isDeviceCode = isKiro ? kiroMethodOption.flowType === 'device_code' : defaultDeviceCode;
|
||||
const isPending = authFlow.isAuthenticating || kiroImportMutation.isPending;
|
||||
@@ -266,10 +264,6 @@ export function AddAccountDialog({
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (requiresNickname && !nicknameTrimmed) {
|
||||
setLocalError(`Nickname is required for ${displayName} accounts.`);
|
||||
return;
|
||||
}
|
||||
setLocalError(null);
|
||||
wasAuthenticatingRef.current = true;
|
||||
authFlow.startAuth(provider, {
|
||||
@@ -394,11 +388,7 @@ export function AddAccountDialog({
|
||||
{/* Nickname input - only show before auth starts */}
|
||||
{!showAuthUI && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="nickname">
|
||||
{requiresNickname
|
||||
? t('addAccountDialog.nicknameRequired')
|
||||
: t('addAccountDialog.nicknameOptional')}
|
||||
</Label>
|
||||
<Label htmlFor="nickname">{t('addAccountDialog.nicknameOptional')}</Label>
|
||||
<div className="flex items-center gap-2">
|
||||
<User className="w-4 h-4 text-muted-foreground" />
|
||||
<Input
|
||||
@@ -414,9 +404,7 @@ export function AddAccountDialog({
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{requiresNickname
|
||||
? t('addAccountDialog.nicknameRequiredHint')
|
||||
: t('addAccountDialog.nicknameOptionalHint')}
|
||||
{t('addAccountDialog.nicknameOptionalHint')}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -554,7 +542,6 @@ export function AddAccountDialog({
|
||||
disabled={
|
||||
isPending ||
|
||||
isAgyBypassStatePending ||
|
||||
(requiresNickname && !nicknameTrimmed) ||
|
||||
(requiresAgyResponsibilityFlow && !isAgyRiskChecklistComplete) ||
|
||||
(requiresSafetyAcknowledgement && !isGeminiRiskAcknowledged)
|
||||
}
|
||||
|
||||
+4
-4
@@ -473,7 +473,7 @@ const resources = {
|
||||
nicknameRequiredHint:
|
||||
'Required for this provider. Use a unique friendly name (e.g., work, personal).',
|
||||
nicknameOptionalHint:
|
||||
'A friendly name to identify this account. Auto-generated from email if left empty.',
|
||||
'A friendly name to identify this account. Leave blank to use a safe generated identifier.',
|
||||
waitingForAuth: 'Waiting for authentication...',
|
||||
deviceCodeHint:
|
||||
'A verification code dialog will appear shortly. Enter the code on the provider website.',
|
||||
@@ -1632,7 +1632,7 @@ const resources = {
|
||||
nicknameOptional: '昵称(选填)',
|
||||
nicknamePlaceholder: '例如:工作、个人',
|
||||
nicknameRequiredHint: '该提供商必填。请使用唯一易记名称(如工作、个人)。',
|
||||
nicknameOptionalHint: '用于区分账号的友好名称。留空将根据邮箱自动生成。',
|
||||
nicknameOptionalHint: '用于区分账号的友好名称。留空将自动生成安全标识。',
|
||||
waitingForAuth: '等待认证中...',
|
||||
deviceCodeHint: '验证码对话框即将出现,请在提供商网站输入验证码。',
|
||||
browserHint: '在浏览器中完成认证后,本对话框将自动关闭。',
|
||||
@@ -2804,7 +2804,7 @@ const resources = {
|
||||
nicknameRequiredHint:
|
||||
'Bắt buộc với nhà cung cấp này. Dùng tên thân thiện duy nhất (ví dụ: work, personal).',
|
||||
nicknameOptionalHint:
|
||||
'Một cái tên thân thiện để xác định tài khoản này. Tự động tạo từ email nếu để trống.',
|
||||
'Tên thân thiện để nhận biết tài khoản này. Để trống để dùng mã nhận dạng an toàn do hệ thống tạo.',
|
||||
waitingForAuth: 'Đang chờ xác thực...',
|
||||
deviceCodeHint:
|
||||
'Hộp thoại mã xác minh sẽ sớm xuất hiện. Nhập mã trên trang web của nhà cung cấp.',
|
||||
@@ -4004,7 +4004,7 @@ const resources = {
|
||||
nicknameRequiredHint:
|
||||
'このプロバイダーでは必須です。重複しないわかりやすい名前を付けてください(例: work, personal)。',
|
||||
nicknameOptionalHint:
|
||||
'このアカウントを識別しやすい名前です。空欄ならメールアドレスから自動生成されます。',
|
||||
'このアカウントを識別しやすい名前です。空欄の場合は安全な識別子を自動生成します。',
|
||||
waitingForAuth: '認証を待機中...',
|
||||
deviceCodeHint:
|
||||
'確認コードのダイアログがまもなく表示されます。プロバイダーのサイトでコードを入力してください。',
|
||||
|
||||
@@ -233,15 +233,6 @@ export function getDeviceCodeProviderInstruction(provider: unknown): string {
|
||||
return 'Complete the authorization in your browser.';
|
||||
}
|
||||
|
||||
/** Providers that require nickname because token payload may not include email. */
|
||||
export const NICKNAME_REQUIRED_PROVIDERS: CLIProxyProvider[] = ['ghcp', 'kiro'];
|
||||
|
||||
/** Check if provider requires user-supplied nickname in auth flow */
|
||||
export function isNicknameRequiredProvider(provider: unknown): boolean {
|
||||
const normalized = normalizeProviderInput(provider);
|
||||
return isValidProvider(normalized) && NICKNAME_REQUIRED_PROVIDERS.includes(normalized);
|
||||
}
|
||||
|
||||
/** Kiro auth methods exposed in CCS UI (aligned with CLIProxyAPIPlus support). */
|
||||
export const KIRO_AUTH_METHODS = ['aws', 'aws-authcode', 'google', 'github'] as const;
|
||||
export type KiroAuthMethod = (typeof KIRO_AUTH_METHODS)[number];
|
||||
|
||||
Reference in New Issue
Block a user