Repository navigation
Commit 716f35d
committed
feat: release 4.10.0 — admin-plane auth, reliability hardening, dashboard SPA extraction
Fixes
- Quota burn-rate projection UI was dead code: renderUsageForAccount referenced
a #window5hProjection element that never existed in the HTML. Element added.
- Inline thinking-tag stripping used mangled delimiters (' thinking' /
' response', leftovers of HTML-stripped <think> tags), misrouting any reply
containing the English word "thinking" into reasoning_content while never
matching real tags. Rewritten as a cross-delta state machine on
<think>/<thinking> with regression tests.
- Upstream usage fetches (whoami/credits/subscriptions/summary) had no timeout;
now 15s via AbortSignal.timeout so a hung upstream cannot stall login,
dashboard aggregation or quota sampling.
- Integration tests skipped (with a hint to build) when dist/ is missing
instead of failing "Proxy did not become ready in time" on fresh clones.
Security
- PROXY_API_KEY now also protects the admin surface /api/*, not just /v1/* —
closes LAN access to account management when bound to 0.0.0.0. Dashboard
prompts for the key on first 401 (per-tab sessionStorage, auto-retry,
debounce after cancel).
- Prominent exposure warning: /api/status exposes boundNonLoopback; overview
card turns red "未鉴权暴露!" and startup logs warn when bound non-loopback
without a key.
- Constant-time PROXY_API_KEY comparison (crypto.timingSafeEqual).
- Cross-site admin drive-by guard: /api/* mutations require Origin === host
when an Origin header is present (non-browser clients unaffected).
- SSRF guard covers 100.64.0.0/10 (CGNAT) and 198.18.0.0/15.
Reliability
- Crash policy: uncaught exceptions/rejections still log, but 3 within 5
minutes exit(1) for supervisor restart instead of limping along.
- Log persistence: full log appended to logs/proxy.log (COMMANDCODE_LOG_PATH,
5MB rotation to .old). Path resolution centralised in utils/paths.ts.
- TraceId threading: non-stream chat pre-generates traceId shared by response
id, error logs and usage records; stream/fatal errors log Trace, upstream
errors log Thread (= x-session-id).
- fetchLiveUsageStatsCached (45s TTL + in-flight dedupe) for dashboard
overview/aggregate: usage tab re-fetches drop from ~2.9s to ~1ms; login and
quota rotation keep using the uncached fetcher.
- usage-history.jsonl size rotation at 20MB (USAGE_HISTORY_MAX_MB), keeping
the newer half.
- CJK-aware token fallback estimation (estimateTextTokens) for both input and
output paths — previously 4-chars-per-token underestimated Chinese ~4x.
Dashboard
- SPA extracted from a 1400-line template string into public/index.html;
dashboard.ts down to 404 lines and the frontend is editable/testable on its
own. Route serves the file per request (byte-identical to the previous
output). pkg assets now include public/**/*.
- Native alert()/confirm() replaced with in-theme toasts and a confirm modal
(Enter/Esc supported).
- Localized static assets: tailwind / font-awesome / chart.js (+ fonts) served
from /assets/vendor/* — no CDN dependency; path-traversal guarded.
- Live log polling while the logs tab is active; polling pauses when the page
is hidden; login modal Enter/Esc; account buttons via event delegation;
favicon added; models tab notes the 1 USD ≈ ¥6.72 display conversion.
Engineering
- GitHub Actions CI: npm ci → typecheck → build → vitest run on push/PR.
- parsePricingFromHtml exported and pinned by synthetic RSC fixtures (chunk
joining, cache rates, peak/off-peak retention, onGoPlan vs "all", malformed
input) so upstream page redesigns turn tests red instead of failing silently.
- resolveModelName locked by table-driven tests via a new setCachedModelsForTest
hook; auth contract covered by fastify.inject tests (tests/auth.test.ts).
- Shared SSE/parse/persist helpers for chat/messages in routes/sse-common.ts.
Version: 4.9.2 → 4.10.0. Tests: 216 passing (incl. 31 integration against the
built dist); tsc --noEmit clean.1 parent feb7f32 commit 716f35d
29 files changed
Lines changed: 8363 additions & 7609 deletions
File tree
- .github/workflows
- public
- vendor
- webfonts
- src
- adapters/commandcode
- routes
- utils
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
5 | 45 | | |
6 | 46 | | |
7 | 47 | | |
| |||
0 commit comments