agent-111 JWT过期重置+系统设置去占位: - ws.ts 识别401/过期 markAuthExpired(清token+停重连+expired态),isTokenExpired;wsParse.ts拆出压行371;scheduleReconnect有token未过期才重连 - api.ts REST 401→auth_expired+清token+引导重登;login走skipAuthExpired密码错不误清 - types.ts WsStatus加expired;TopBar/Nav expired显示登录过期;System.tsx去alert占位改4张事实卡+合并Notice agent-113 用户端登录页: - components/Login.tsx Miuix登录卡(用户名/密码→login()→setAuthToken);App !getAuthToken()→<Login>;AdminApp LoginGate指向 agent-112 系统设置前三个(owner+审计): - auth.APIKey.RevokeAll(吊销全部key);auth.JWTService.RotateSecret(≥32校验+并发安全+新密钥不回显) - gateway admin_system.go: POST revoke-keys/rotate-jwt/backup(VACUUM INTO)/restore(防路径穿越+恢复前自动备份+原子替换+需重启) - wire.go 传DatabasePath;全仓 build/vet/test绿+交叉编译;api-client v0.17系统设置契约 实机验证: 登录(role=owner)+revoke-keys 200+渠道列表含kook; 全仓绿+前端build绿; .env密码仅登录验证不打印
66 lines
3.2 KiB
TypeScript
66 lines
3.2 KiB
TypeScript
import { getStoredRole } from "../../lib/api";
|
|
import { KeyValueRow, Notice, PageHeader } from "../components";
|
|
import { Surface, Tag } from "../../components/primitives";
|
|
import { Icon } from "../../components/Icon";
|
|
|
|
/**
|
|
* 系统设置 (design/10)。后端 M10+ 才提供真实的密钥轮换/备份/环境变量写入等
|
|
* 系统级操作;在此之前只呈现**诚实的只读配置事实**,并把尚未实现的操作合并成
|
|
* 一条「未实现」说明——不做满屏点击后 `alert` 的占位按钮。
|
|
*/
|
|
export function SystemModule(): React.ReactNode {
|
|
const isOwner = getStoredRole() === "owner";
|
|
|
|
return (
|
|
<div className="space-y-5">
|
|
<PageHeader title="系统设置" subtitle="安全(密钥/JWT) + 运行时 + 存储 + 环境变量(只读);可写系统操作见末条说明" />
|
|
|
|
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
|
|
<Surface className="space-y-1">
|
|
<SectionTitle icon={<Icon name="shield" size={18} />} title="安全 & 密钥" ownerOnly />
|
|
<KeyValueRow label="JWT 密钥" value="••••••••" mono />
|
|
<KeyValueRow label="鉴权" value="JWT + RBAC + API key" />
|
|
<KeyValueRow label="审计" value="who / what / when / result" />
|
|
</Surface>
|
|
|
|
<Surface className="space-y-1">
|
|
<SectionTitle icon={<Icon name="storage" size={18} />} title="存储" />
|
|
<KeyValueRow label="默认" value="SQLite" />
|
|
<KeyValueRow label="可选增强" value="PG / pgvector(语义/向量路径)" />
|
|
<KeyValueRow label="单二进制 / 单端口" value=":8080 · 零跨进程 IPC" />
|
|
</Surface>
|
|
|
|
<Surface className="space-y-1">
|
|
<SectionTitle icon={<Icon name="package" size={18} />} title="环境变量" />
|
|
<KeyValueRow label="SERVER_HOST" value="0.0.0.0" mono />
|
|
<KeyValueRow label="SERVER_PORT" value="8080" mono />
|
|
<KeyValueRow label="AUTH_ADMIN_USER/PASS" value="••••••••" mono />
|
|
</Surface>
|
|
|
|
<Surface className="space-y-1">
|
|
<SectionTitle icon={<Icon name="refresh" size={18} />} title="运行时" />
|
|
<KeyValueRow label="部署形态" value="单二进制 · 单端口 · 零跨进程 IPC" />
|
|
<KeyValueRow label="日志级别" value="后端配置,面板暂不可改(M10+)" />
|
|
</Surface>
|
|
</div>
|
|
|
|
<Notice tone="warn">
|
|
以下系统操作后端暂未实现(M10+ 落地),当前不可用:轮换 JWT 密钥 · 吊销全部 API
|
|
key · 备份/恢复 · 编辑环境变量 · 重启服务 · 检查更新。均为真实读写,未实现前不做占位。
|
|
</Notice>
|
|
|
|
{!isOwner ? <Notice tone="warn">安全 / 密钥 / 系统设置类敏感操作仅 owner 可执行;当前角色 {getStoredRole()}。</Notice> : null}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function SectionTitle({ icon, title, ownerOnly = false }: { icon: React.ReactNode; title: string; ownerOnly?: boolean }): React.ReactNode {
|
|
return (
|
|
<h3 className="flex items-center gap-2 text-sm font-semibold">
|
|
<span className="text-[var(--mu-accent)]">{icon}</span>
|
|
<span>{title}</span>
|
|
{ownerOnly ? <Tag tone="warn">owner</Tag> : null}
|
|
</h3>
|
|
);
|
|
}
|