fix: KOOK 连不上根因——空token裸账号不注册/占名 + open指向带token账号 + 前端token不覆盖真值
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

agent-119 后端:
- buildAccountAdapter: token平台(kook/telegram/weixin)BotToken空→跳过build(不注册不占名), channelAccountsFromEnv 无tokenenv不合成账号(杜绝裸kook id="")
- runtimeconfig cleanAccounts: LoadChannels/SaveChannels 丢弃token平台空token账号(清理channels.json现有裸kook, 下次保存抹掉)
- findChannel: 裸平台名(kook)回退到该平台第一个带token账号, open"kook"不再命中裸的missing token

我补 前端token掩码不就覆真值:
- openConfig 不再把'(已配置,仅掩码显示)'当token回填(setToken空)→save token空不写bot_token保留真值
- 加 tokenHint(显示'已配置留空不改'/重填换); 修之前channels.json kook:3fc8 token变掩码串的bug
全仓 build/vet/test绿+前端build绿(463行)
This commit is contained in:
Aska committed 2026-09-07 16:01:47 +08:00
1 parent 5398486fdf
commit b614633432
7 files changed
+314 -30

No files matched your search

+10 -1
View File
@@ -56,6 +56,9 @@ export function ChannelsModule(): React.ReactNode {
// Business-policy fold (blacklist/allow + rate limits) is separate from the
// connection config — it governs admission/de-noise, not the endpoint.
const [polOpen, setPolOpen] = useState(false);
// Hint shown next to the Token field when an account already has a secret
// (masked): the token input stays empty so a save does NOT overwrite it.
const [tokenHint, setTokenHint] = useState("");
const toggle = (name: string, connect: boolean) => {
setBusy(name);
@@ -103,7 +106,12 @@ export function ChannelsModule(): React.ReactNode {
const acct = (data ?? []).find((c) => platformOf(c.name) === platform)?.accounts?.[0];
setCfgId(acct?.id ?? "");
const cfg = acct?.config ?? {};
setToken(typeof cfg.bot_token === "string" && cfg.bot_token ? "(已配置,仅掩码显示)" : "");
// Do NOT put the masked placeholder into `token`: it would be written back as
// the real bot_token (overwriting the stored secret with a demo string). Keep
// token empty (save omits it → keeps the existing secret) and show a hint.
const hasToken = typeof cfg.bot_token === "string" && cfg.bot_token && !cfg.bot_token.includes("(已配置");
setToken("");
setTokenHint(hasToken ? "已配置(仅掩码显示),留空则不改动;如需更换请重新输入。" : "");
setBaseURL(typeof cfg.base_url === "string" ? cfg.base_url : "");
const plat: Record<string, string> = {};
for (const f of PLATFORM_FIELDS[platform] ?? []) {
@@ -318,6 +326,7 @@ export function ChannelsModule(): React.ReactNode {
) : null}
</span>
<input type="password" value={token} onChange={(e) => setToken(e.target.value)} placeholder="机器人 token" className={`${inputCls} border border-[var(--mu-accent)]/25`} />
{tokenHint ? <span className="block text-[11px] text-[var(--mu-text-lo)]">{tokenHint}</span> : null}
</label>
</div>
{PLATFORM_GUIDE[cfgPlatform].hint ? (