feat: enhance API key management and home key controls

This commit is contained in:
lzt404 committed 2026-07-24 22:06:14 +08:00
1 parent 6018e9d8a2
commit 4f20bc77c1
5 files changed
+27 -17

No files matched your search

+1 -1
View File
@@ -635,7 +635,7 @@ export const jaOverrides = {
'kernel.versions.reinstall': '再インストール',
'kernel.versions.noBundled': 'このリリースには組み込みコアが含まれていません',
'kernel.versions.offlineInstall': 'オフラインインストール',
'kernel.access.defaultKey': '既定のキー:{key}',
'kernel.access.firstKey': '最初のキー',
'kernel.access.noConfiguredKey': 'キーが設定されていないため、現在はすべてのキーがデフォルトで許可されます',
'kernel.access.connectable': '接続可能',
'kernel.access.waiting': 'コアの起動を待っています',
+2 -2
View File
@@ -638,7 +638,7 @@ export const zhCN = {
'kernel.versions.reinstall': '重新安装',
'kernel.versions.noBundled': '当前发行包未包含内置内核',
'kernel.versions.offlineInstall': '离线安装',
'kernel.access.defaultKey': '默认密钥:{key}',
'kernel.access.firstKey': '第一个密钥',
'kernel.access.noConfiguredKey': '未设置密钥,当前默认放行所有密钥',
'kernel.access.connectable': '可连接',
'kernel.access.waiting': '等待内核启动',
@@ -1345,7 +1345,7 @@ export const en: Record<MessageKey, string> = {
'kernel.versions.reinstall': 'Reinstall',
'kernel.versions.noBundled': 'This release does not include a bundled core',
'kernel.versions.offlineInstall': 'Offline Install',
'kernel.access.defaultKey': 'Default key: {key}',
'kernel.access.firstKey': 'First key',
'kernel.access.noConfiguredKey': 'No key is configured; all keys are currently allowed by default',
'kernel.access.connectable': 'Connectable',
'kernel.access.waiting': 'Waiting for core startup',
+14 -10
View File
@@ -6,7 +6,7 @@ import { type CoreStatus, useCoreRuntime } from '../coreRuntime';
import openaiIcon from '../assets/icons/openai-light.svg';
import claudeIcon from '../assets/icons/claude.svg';
import geminiIcon from '../assets/icons/gemini.svg';
import { clientApiProfiles, DEFAULT_CLIENT_API_KEY } from '../services/clientAccess';
import { clientApiProfiles } from '../services/clientAccess';
import packageMetadata from '../../package.json';
import { useI18n } from '../i18n';
import { useAppUpdate } from '../appUpdate';
@@ -138,7 +138,8 @@ export function KernelPage({ view = 'home' }: { view?: KernelView }) {
const [installDialogOpen, setInstallDialogOpen] = useState(false);
const [cancellingInstall, setCancellingInstall] = useState(false);
const [copiedApiField, setCopiedApiField] = useState('');
const [homeApiKey, setHomeApiKey] = useState<string | null>(DEFAULT_CLIENT_API_KEY);
const [homeApiKey, setHomeApiKey] = useState<string | null | undefined>(undefined);
const [homeApiKeyError, setHomeApiKeyError] = useState(false);
const [showHomeApiKey, setShowHomeApiKey] = useState(false);
const [lanIpv4, setLanIpv4] = useState<string | null>(null);
const [lanIpChecked, setLanIpChecked] = useState(false);
@@ -347,8 +348,10 @@ export function KernelPage({ view = 'home' }: { view?: KernelView }) {
try {
const settings = await invoke<CoreConfigSummary>('get_core_config_settings');
setHomeApiKey(settings.apiKeys[0]?.apiKey ?? null);
setHomeApiKeyError(false);
} catch {
setHomeApiKey(DEFAULT_CLIENT_API_KEY);
setHomeApiKey(undefined);
setHomeApiKeyError(true);
}
};
@@ -987,7 +990,7 @@ export function KernelPage({ view = 'home' }: { view?: KernelView }) {
<div className="panel-heading client-api-heading">
<div>
<h2>API URL</h2>
{homeApiKey ? (
{typeof homeApiKey === 'string' ? (
<div className="client-api-key-actions">
<button
type="button"
@@ -996,11 +999,8 @@ export function KernelPage({ view = 'home' }: { view?: KernelView }) {
title={showHomeApiKey ? t('config.keys.hide') : t('config.keys.show')}
onClick={() => setShowHomeApiKey((visible) => !visible)}
>
<span>
{t('kernel.access.defaultKey', {
key: showHomeApiKey ? homeApiKey : '••••••',
})}
</span>
<span>{t('kernel.access.firstKey')}</span>
<code>{showHomeApiKey ? homeApiKey : '******'}</code>
{showHomeApiKey ? (
<EyeOff size={14} aria-hidden="true" />
) : (
@@ -1027,8 +1027,12 @@ export function KernelPage({ view = 'home' }: { view?: KernelView }) {
)}
</button>
</div>
) : (
) : homeApiKey === null ? (
<p className="client-api-no-key">{t('kernel.access.noConfiguredKey')}</p>
) : (
<p className={homeApiKeyError ? 'error' : undefined}>
{homeApiKeyError ? t('common.unavailable') : t('common.loading')}
</p>
)}
</div>
<span className={`state-pill ${coreRunning ? 'success' : ''}`}>
-2
View File
@@ -1,7 +1,5 @@
import { getCurrentLocale, translate } from '../i18n';
export const DEFAULT_CLIENT_API_KEY = '123456';
export type ClientApiProfile = {
id: 'openai' | 'claude' | 'gemini';
name: string;
+10 -2
View File
@@ -661,11 +661,21 @@ input:focus-visible {
}
.client-api-default-key span {
flex: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.client-api-default-key code {
min-width: 0;
overflow: hidden;
color: #2d2a26;
font-size: 12px;
text-overflow: ellipsis;
white-space: nowrap;
}
.client-api-default-key svg {
flex: none;
color: #7a746c;
@@ -673,8 +683,6 @@ input:focus-visible {
.client-api-default-key:hover span {
color: #2d2a26;
text-decoration: underline;
text-underline-offset: 2px;
}
.client-api-key-copy {