feat(api-tokens): add PAT management UI, CSRF handling, and auth-loading fixes

Add an API tokens management route to create, list, and revoke PATs, showing
the plaintext token once on creation with scope and server-id selection.

Mirror the nz-csrf cookie into the X-CSRF-Token header on unsafe fetcher
methods (POST/PUT/PATCH/DELETE) for the server-side double-submit check, and
self-heal expired sessions via refresh-token without a recursive fetch loop.

Gate protected routes behind resolved auth state to avoid pre-auth SWR fetches,
and fix the login loading/race so stale probes cannot clobber the session.

Add i18n keys for the new screens across all locales.

Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
This commit is contained in:
naiba
2026-05-30 15:56:53 +00:00
co-authored by cloudcode
parent f47d4a8772
commit f07c557029
37 changed files with 2041 additions and 69 deletions
+27 -1
View File
@@ -162,6 +162,7 @@
"UseDirectConnectingIP": "使用直连 IP",
"IPChangeNotification": "IP变更通知",
"FullIPNotification": "在通知消息中显示完整的 IP 地址",
"EnableMCP": "启用 MCP 接入(默认关闭;启用前请确认已审阅 API 令牌 scope 与服务器白名单)",
"LoginFailed": "登录失败",
"BruteForceAttackingToken": "暴力攻击令牌",
"BruteForceAttackingAgentSecret": "暴力攻击代理秘密",
@@ -288,5 +289,30 @@
"StatusFailed": "已失败",
"StatusTimeout": "已超时",
"StatusCancelled": "已取消"
}
},
"ApiTokens": "API 令牌",
"CreateApiToken": "创建 API 令牌",
"CreateApiTokenDescription": "令牌用于 MCP 和外部客户端以你的身份调用 API,权限不能超过你本人。",
"ConfirmDeleteApiToken": "确定吊销 API 令牌 '{{name}}'?此操作不可撤销。",
"ApiTokenRevoked": "API 令牌已吊销。",
"ApiTokenCreated": "API 令牌已创建",
"ApiTokenRevealOnce": "请立即复制此令牌,离开后将无法再次查看。",
"ApiTokenStoreSafely": "请像密码一样妥善保管。任何持有者都可在 scope 内以你的身份操作。",
"ApiTokenServers": "服务器",
"ApiTokenAllServers": "全部可访问",
"ApiTokenNever": "永不",
"ApiTokenExpiresAt": "过期时间",
"ApiTokenLastUsed": "最近使用",
"ApiTokenServerIDs": "限定服务器 ID(可选)",
"ApiTokenServerIDsPlaceholder": "逗号分隔,例如 1,2,3",
"ApiTokenExpiresInDays": "有效期(天,0 = 永不过期)",
"ApiTokenScopeRequired": "至少选择一个 scope。",
"ApiTokenServersInvalid": "服务器 ID 必须为正整数。",
"ApiTokenExpiryInvalid": "天数必须在 0 到 3650 之间。",
"NameRequired": "名称必填。",
"Revoke": "吊销",
"Copy": "复制",
"Copied": "已复制到剪贴板",
"Done": "完成",
"Scopes": "权限"
}