diff --git a/lib/features/auth/views/authentication_page.dart b/lib/features/auth/views/authentication_page.dart index 00752e4..55b0f8a 100644 --- a/lib/features/auth/views/authentication_page.dart +++ b/lib/features/auth/views/authentication_page.dart @@ -399,7 +399,7 @@ class _AuthenticationPageState extends ConsumerState { icon: Platform.isIOS ? CupertinoIcons.lock_shield : Icons.vpn_key_outlined, - label: AppLocalizations.of(context)!.apiKey, + label: AppLocalizations.of(context)!.token, isSelected: _useApiKey, onTap: () => setState(() => _useApiKey = true), ), @@ -480,24 +480,43 @@ class _AuthenticationPageState extends ConsumerState { ); } + /// Validates that a token is a JWT and not an API key. + /// API keys (sk-, api-, key-) don't work with WebSocket authentication. + String? _validateJwtToken(String? value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context)!.validationMissingRequired; + } + + final trimmed = value.trim(); + final lowerTrimmed = trimmed.toLowerCase(); + + // Reject API keys - they don't work with socket authentication + // Case-insensitive check to catch SK-, API-, KEY- variants + if (lowerTrimmed.startsWith('sk-') || + lowerTrimmed.startsWith('api-') || + lowerTrimmed.startsWith('key-')) { + return AppLocalizations.of(context)!.apiKeyNotSupported; + } + + // Check minimum length + if (trimmed.length < 10) { + return AppLocalizations.of(context)!.tokenTooShort; + } + + return null; + } + Widget _buildApiKeyForm() { return Column( key: const ValueKey('api_key_form'), children: [ AccessibleFormField( - label: AppLocalizations.of(context)!.apiKey, - hint: 'sk-...', + label: AppLocalizations.of(context)!.token, + hint: 'eyJ...', controller: _apiKeyController, - validator: InputValidationService.combine([ - InputValidationService.validateRequired, - (value) => InputValidationService.validateMinLength( - value, - 10, - fieldName: AppLocalizations.of(context)!.apiKey, - ), - ]), + validator: _validateJwtToken, obscureText: _obscurePassword, - semanticLabel: AppLocalizations.of(context)!.enterApiKey, + semanticLabel: AppLocalizations.of(context)!.enterToken, prefixIcon: Icon( Platform.isIOS ? CupertinoIcons.lock_shield @@ -520,6 +539,13 @@ class _AuthenticationPageState extends ConsumerState { isRequired: true, autofillHints: const [AutofillHints.password], ), + const SizedBox(height: Spacing.sm), + Text( + AppLocalizations.of(context)!.tokenHint, + style: context.conduitTheme.bodySmall?.copyWith( + color: context.conduitTheme.textSecondary, + ), + ), ], ); } @@ -591,7 +617,7 @@ class _AuthenticationPageState extends ConsumerState { text: _isSigningIn ? AppLocalizations.of(context)!.signingIn : _useApiKey - ? AppLocalizations.of(context)!.signInWithApiKey + ? AppLocalizations.of(context)!.signInWithToken : AppLocalizations.of(context)!.signIn, icon: _isSigningIn ? null diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index b74147c..1df3ba1 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -46,9 +46,11 @@ "enterCredentials": "Gib deine Anmeldedaten ein, um auf deine KI-Unterhaltungen zuzugreifen", "credentials": "Zugangsdaten", "apiKey": "API-Schlüssel", + "token": "Token", "usernameOrEmail": "Benutzername oder E‑Mail", "password": "Passwort", "signInWithApiKey": "Mit API-Schlüssel anmelden", + "signInWithToken": "Mit Token anmelden", "connectToServer": "Mit Server verbinden", "enterServerAddress": "Gib die Adresse deines Open-WebUI-Servers ein, um zu beginnen", "serverUrl": "Server-URL", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "Gib deinen Benutzernamen oder deine E‑Mail ein", "passwordHint": "Gib dein Passwort ein", "enterApiKey": "Gib deinen API-Schlüssel ein", + "enterToken": "Gib dein JWT-Token ein", + "tokenHint": "Verwende ein JWT-Token aus Browser-Cookies oder API-Login. API-Schlüssel (sk-...) werden für Streaming nicht unterstützt.", + "apiKeyNotSupported": "API-Schlüssel (sk-...) werden nicht unterstützt. Bitte verwende stattdessen ein JWT-Token.", + "tokenTooShort": "Token ist zu kurz", "signingIn": "Anmeldung läuft...", "advancedSettings": "Erweiterte Einstellungen", "customHeaders": "Benutzerdefinierte Header", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 0de9784..108e8de 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -216,6 +216,10 @@ "@apiKey": { "description": "Label for API key input field." }, + "token": "Token", + "@token": { + "description": "Label for JWT token input field." + }, "usernameOrEmail": "Username or Email", "@usernameOrEmail": { "description": "Label for username/email input field." @@ -228,6 +232,10 @@ "@signInWithApiKey": { "description": "Alternative sign-in method using an API key." }, + "signInWithToken": "Sign in with Token", + "@signInWithToken": { + "description": "Alternative sign-in method using a JWT token." + }, "connectToServer": "Connect to Server", "@connectToServer": { "description": "Call-to-action button for server connection." @@ -1004,6 +1012,22 @@ "@enterApiKey": { "description": "Hint text for API key input." }, + "enterToken": "Enter your JWT token", + "@enterToken": { + "description": "Hint text for JWT token input." + }, + "tokenHint": "Use a JWT token from browser cookies or API login. API keys (sk-...) are not supported for streaming.", + "@tokenHint": { + "description": "Help text explaining what type of token to use." + }, + "apiKeyNotSupported": "API keys (sk-...) are not supported. Please use a JWT token instead.", + "@apiKeyNotSupported": { + "description": "Error message when user tries to use an API key instead of JWT token." + }, + "tokenTooShort": "Token is too short", + "@tokenTooShort": { + "description": "Error message when token is too short." + }, "signingIn": "Signing in...", "@signingIn": { "description": "Status message shown while signing in." diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index d7f2474..df054c1 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -46,9 +46,11 @@ "enterCredentials": "Ingresa tus credenciales para acceder a tus conversaciones de IA", "credentials": "Credenciales", "apiKey": "Clave API", + "token": "Token", "usernameOrEmail": "Usuario o correo electrónico", "password": "Contraseña", "signInWithApiKey": "Iniciar sesión con clave API", + "signInWithToken": "Iniciar sesión con token", "connectToServer": "Conectar al servidor", "enterServerAddress": "Ingresa la dirección de tu servidor Open-WebUI para comenzar", "serverUrl": "URL del servidor", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "Ingresa tu usuario o correo electrónico", "passwordHint": "Ingresa tu contraseña", "enterApiKey": "Ingresa tu clave API", + "enterToken": "Ingresa tu token JWT", + "tokenHint": "Usa un token JWT de las cookies del navegador o del inicio de sesión API. Las claves API (sk-...) no son compatibles con streaming.", + "apiKeyNotSupported": "Las claves API (sk-...) no son compatibles. Por favor usa un token JWT en su lugar.", + "tokenTooShort": "El token es demasiado corto", "signingIn": "Iniciando sesión...", "advancedSettings": "Configuración avanzada", "customHeaders": "Encabezados personalizados", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index d3f8cee..c370ec0 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -46,9 +46,11 @@ "enterCredentials": "Entrez vos identifiants pour accéder à vos conversations IA", "credentials": "Identifiants", "apiKey": "Clé API", + "token": "Jeton", "usernameOrEmail": "Nom d'utilisateur ou e‑mail", "password": "Mot de passe", "signInWithApiKey": "Se connecter avec une clé API", + "signInWithToken": "Se connecter avec un jeton", "connectToServer": "Se connecter au serveur", "enterServerAddress": "Saisissez l'adresse de votre serveur Open-WebUI pour commencer", "serverUrl": "URL du serveur", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "Entrez votre nom d'utilisateur ou e‑mail", "passwordHint": "Entrez votre mot de passe", "enterApiKey": "Entrez votre clé API", + "enterToken": "Entrez votre jeton JWT", + "tokenHint": "Utilisez un jeton JWT des cookies du navigateur ou de la connexion API. Les clés API (sk-...) ne sont pas prises en charge pour le streaming.", + "apiKeyNotSupported": "Les clés API (sk-...) ne sont pas prises en charge. Veuillez utiliser un jeton JWT à la place.", + "tokenTooShort": "Le jeton est trop court", "signingIn": "Connexion en cours...", "advancedSettings": "Paramètres avancés", "customHeaders": "En-têtes personnalisés", diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index f8bde04..aa5f082 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -46,9 +46,11 @@ "enterCredentials": "Inserisci le credenziali per accedere alle conversazioni IA", "credentials": "Credenziali", "apiKey": "Chiave API", + "token": "Token", "usernameOrEmail": "Username o e‑mail", "password": "Password", "signInWithApiKey": "Accedi con chiave API", + "signInWithToken": "Accedi con token", "connectToServer": "Connetti al server", "enterServerAddress": "Inserisci l'indirizzo del server Open-WebUI per iniziare", "serverUrl": "URL del server", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "Inserisci il tuo username o e‑mail", "passwordHint": "Inserisci la password", "enterApiKey": "Inserisci la tua chiave API", + "enterToken": "Inserisci il tuo token JWT", + "tokenHint": "Usa un token JWT dai cookie del browser o dal login API. Le chiavi API (sk-...) non sono supportate per lo streaming.", + "apiKeyNotSupported": "Le chiavi API (sk-...) non sono supportate. Per favore usa un token JWT.", + "tokenTooShort": "Il token è troppo corto", "signingIn": "Accesso in corso...", "advancedSettings": "Impostazioni avanzate", "customHeaders": "Header personalizzati", diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index 93f7199..881fe3f 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -87,9 +87,11 @@ "enterCredentials": "AI 대화에 액세스하려면 자격 증명을 입력하세요", "credentials": "자격 증명", "apiKey": "API 키", + "token": "토큰", "usernameOrEmail": "사용자 이름 또는 이메일", "password": "비밀번호", "signInWithApiKey": "API 키로 로그인", + "signInWithToken": "토큰으로 로그인", "connectToServer": "서버 연결", "enterServerAddress": "시작하려면 Open-WebUI 서버 주소를 입력하세요", "serverUrl": "서버 URL", @@ -335,6 +337,10 @@ "usernameOrEmailHint": "사용자 이름 또는 이메일을 입력하세요", "passwordHint": "비밀번호를 입력하세요", "enterApiKey": "API 키를 입력하세요", + "enterToken": "JWT 토큰을 입력하세요", + "tokenHint": "브라우저 쿠키 또는 API 로그인에서 JWT 토큰을 사용하세요. API 키(sk-...)는 스트리밍에 지원되지 않습니다.", + "apiKeyNotSupported": "API 키(sk-...)는 지원되지 않습니다. JWT 토큰을 사용하세요.", + "tokenTooShort": "토큰이 너무 짧습니다", "signingIn": "로그인 중...", "advancedSettings": "고급 설정", "customHeaders": "사용자 정의 헤더", diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index b706083..c8e2534 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -46,9 +46,11 @@ "enterCredentials": "Voer je inloggegevens in om toegang te krijgen tot je AI-gesprekken", "credentials": "Inloggegevens", "apiKey": "API-sleutel", + "token": "Token", "usernameOrEmail": "Gebruikersnaam of e-mail", "password": "Wachtwoord", "signInWithApiKey": "Inloggen met API-sleutel", + "signInWithToken": "Inloggen met token", "connectToServer": "Verbinden met server", "enterServerAddress": "Voer je Open-WebUI serveradres in om te beginnen", "serverUrl": "Server-URL", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "Voer je gebruikersnaam of e-mail in", "passwordHint": "Voer je wachtwoord in", "enterApiKey": "Voer je API-sleutel in", + "enterToken": "Voer je JWT-token in", + "tokenHint": "Gebruik een JWT-token van browsercookies of API-login. API-sleutels (sk-...) worden niet ondersteund voor streaming.", + "apiKeyNotSupported": "API-sleutels (sk-...) worden niet ondersteund. Gebruik in plaats daarvan een JWT-token.", + "tokenTooShort": "Token is te kort", "signingIn": "Inloggen...", "advancedSettings": "Geavanceerde instellingen", "customHeaders": "Aangepaste headers", diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 41cd196..b522c67 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -46,9 +46,11 @@ "enterCredentials": "Введите свои учетные данные для доступа к вашим разговорам с ИИ", "credentials": "Учетные данные", "apiKey": "API-ключ", + "token": "Токен", "usernameOrEmail": "Имя пользователя или email", "password": "Пароль", "signInWithApiKey": "Войти с помощью API-ключа", + "signInWithToken": "Войти с помощью токена", "connectToServer": "Подключиться к серверу", "enterServerAddress": "Введите адрес вашего сервера Open-WebUI для начала", "serverUrl": "URL сервера", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "Введите ваше имя пользователя или email", "passwordHint": "Введите ваш пароль", "enterApiKey": "Введите ваш API-ключ", + "enterToken": "Введите ваш JWT-токен", + "tokenHint": "Используйте JWT-токен из cookies браузера или входа через API. API-ключи (sk-...) не поддерживаются для потоковой передачи.", + "apiKeyNotSupported": "API-ключи (sk-...) не поддерживаются. Пожалуйста, используйте JWT-токен.", + "tokenTooShort": "Токен слишком короткий", "signingIn": "Вход...", "advancedSettings": "Расширенные настройки", "customHeaders": "Пользовательские заголовки", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 4148d33..69f9760 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -46,9 +46,11 @@ "enterCredentials": "输入您的凭据以访问您的 AI 对话", "credentials": "凭据", "apiKey": "API 密钥", + "token": "令牌", "usernameOrEmail": "用户名或电子邮件", "password": "密码", "signInWithApiKey": "使用 API 密钥登录", + "signInWithToken": "使用令牌登录", "connectToServer": "连接到服务器", "enterServerAddress": "输入您的 Open-WebUI 服务器地址以开始", "serverUrl": "服务器 URL", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "输入您的用户名或电子邮件", "passwordHint": "输入您的密码", "enterApiKey": "输入您的 API 密钥", + "enterToken": "输入您的 JWT 令牌", + "tokenHint": "请使用浏览器 cookie 或 API 登录中的 JWT 令牌。API 密钥 (sk-...) 不支持流式传输。", + "apiKeyNotSupported": "不支持 API 密钥 (sk-...)。请改用 JWT 令牌。", + "tokenTooShort": "令牌太短", "signingIn": "正在登录...", "advancedSettings": "高级设置", "customHeaders": "自定义标头", diff --git a/lib/l10n/app_zh_Hant.arb b/lib/l10n/app_zh_Hant.arb index 9b8433c..30ce779 100644 --- a/lib/l10n/app_zh_Hant.arb +++ b/lib/l10n/app_zh_Hant.arb @@ -46,9 +46,11 @@ "enterCredentials": "輸入您的憑據以訪問您的 AI 對話", "credentials": "憑據", "apiKey": "API 密鑰", + "token": "令牌", "usernameOrEmail": "用戶名或電子郵件", "password": "密碼", "signInWithApiKey": "使用 API 密鑰登錄", + "signInWithToken": "使用令牌登錄", "connectToServer": "連接到服務器", "enterServerAddress": "輸入您的 Open-WebUI 服務器地址以開始", "serverUrl": "服務器 URL", @@ -225,6 +227,10 @@ "usernameOrEmailHint": "輸入您的用戶名或電子郵件", "passwordHint": "輸入您的密碼", "enterApiKey": "輸入您的 API 密鑰", + "enterToken": "輸入您的 JWT 令牌", + "tokenHint": "請使用瀏覽器 cookie 或 API 登入中的 JWT 令牌。API 密鑰 (sk-...) 不支援串流。", + "apiKeyNotSupported": "不支援 API 密鑰 (sk-...)。請改用 JWT 令牌。", + "tokenTooShort": "令牌太短", "signingIn": "正在登錄...", "advancedSettings": "高級設置", "customHeaders": "自定義標頭",