Skip to content

feat: web dashboard, multi-account pool, one-click extension, auth import#2

Open
danscMax wants to merge 10 commits into
ForgetMeAI:mainfrom
danscMax:foundation
Open

feat: web dashboard, multi-account pool, one-click extension, auth import#2
danscMax wants to merge 10 commits into
ForgetMeAI:mainfrom
danscMax:foundation

Conversation

@danscMax

@danscMax danscMax commented Jun 8, 2026

Copy link
Copy Markdown

Что это

Базовый слой возможностей поверх текущего main:

  • Встроенный веб-дашборд (/dashboard) — чат-плейграунд + управление аккаунтами и обзор
  • Мультиаккаунт-пул с round-robin ротацией и авто-пометкой rate-limit/invalid (accountManager.js, deepseek-accounts.json)
  • Импорт авторизации из browser cURL и HAR (lib/parseAuth.js, scripts/auth_from_*.js)
  • Браузерное расширение (Firefox/Chrome) — добавление аккаунта в один клик через перехват webRequest
  • Фиксы: отключён сломанный web-search, укреплён wasmUrl fallback, чистый Chrome-for-Testing профиль

Это фундамент; поверх него отдельными PR пойдут точечные улучшения (полировка UI, надёжность, удобство).

Проверка

  • SKIP_ACCOUNT_MENU=1 node server.jsGET / (health), GET /v1/models
  • /dashboard — чат + аккаунты

🤖 Generated with Claude Code

danscMax and others added 10 commits June 7, 2026 11:11
Add GET /dashboard (serves public/dashboard.html) and GET /api/auth-status (JWT exp decode + presence flags) to server.js. New single-file dashboard: streaming chat with markdown (marked+DOMPurify via CDN with SRI), DeepSeek reasoning panel (reasoning_content), web-search toggle, model selector; overview tab with connection info (cURL/Python), model list with capability badges, and auth status. No new runtime deps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add scripts/auth_from_curl.js: parses a 'Copy as cURL' request (Chrome/Firefox/Edge, single or double quotes) and writes deepseek-auth.json (token/cookie/hif). Lets users authorize from THEIR own logged-in browser instead of the isolated Chrome-for-Testing profile (which has no Google accounts) and works in Firefox too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add scripts/auth_from_har.js: parses a full HAR export, auto-picks the best chat.deepseek.com/api request with Authorization: Bearer, extracts token/cookie/hif and real wasmUrl into deepseek-auth.json. Complements the cURL importer for users who export HAR from DevTools.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Web-search (deepseek-chat-search) is removed from the dashboard model controls: DeepSeek Web currently returns an empty response for search-enabled requests (server retries 10x then gives up). Chat picks the model directly from the selector now. auth_from_curl/har: keep the working wasmUrl from the previous deepseek-auth.json instead of always falling back to a hardcoded (eventually stale) default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add accountManager.js (round-robin pool in deepseek-accounts.json, migrates from single deepseek-auth.json) and lib/parseAuth.js (shared cURL/HAR parser). server.js: per-account headers/POW, askWithRotation wrapper that rotates on HTTP 429 (rate limit тЖТ cooldown), 401/403 (invalid), request errors, and hidden-limit empty responses; returns 503 when all accounts exhausted. New localhost-gated endpoints GET /api/accounts, POST /api/accounts/import (cURL/HAR), POST /:id/check, DELETE /:id. Dashboard: Accounts tab (status bars, import, check/delete). Auth scripts now add to the pool. Cooldown via DEEPSEEK_RATELIMIT_HOURS (default 6).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…Firefox/Chrome)

Extension popup gets a primary button that collects creds (token+httpOnly cookies+hif) and POSTs them to http://localhost:9655/api/accounts/import in one click. Manifest: browser_specific_settings.gecko for Firefox, localhost host_permissions, removed missing icon refs. server parseAuth now also accepts a ready JSON body (what the extension sends), not only cURL/HAR. Added extension README with Firefox/Chrome install steps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…der capture

Firefox stable disables background.service_worker, so declare both service_worker (Chrome) and scripts (Firefox). The cookie-based collection missed token (it's in the Authorization header, not a cookie), some cookies, and hif (x-hif-* request headers). Switched to webRequest.onBeforeSendHeaders on chat.deepseek.com/api/* to capture exactly what HAR/cURL would тАФ token + full cookie + hif. UX: send one message in DeepSeek, then click Add. Removed content.js (no longer needed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DeepSeek returns HTTP 200 + {code:40003,data:null} for an invalid/expired token (not 401), so the old code crashed on data.biz_data and askWithRotation caught it as a generic error -> markRateLimited, masking dead creds as a temporary cap. Added parseBizData() + DeepSeekAuthError so auth-error codes (40003/40300/40301) mark the account invalid while other failures stay a temporary rate-limit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…idation

Popup now shows the account pool (GET /api/accounts) with per-account status badges (OK/INVALID/WAIT) and check/delete actions, auto-validates each account right after import via /check, shows the account email, and warns on duplicate imports instead of a bare error. Pool UI is built with DOM APIs (no innerHTML) to avoid XSS.

Backend: server resolves email via users/current on import and lazily backfills it on /check; addAccount stores email and returns existingId on duplicate; GET /api/accounts exposes email; accountManager gains setEmail. parseAuth.js and background.js unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The account-management block was guarded only by an IP check (isLocal), which does not stop CSRF: a malicious page can cross-origin POST to http://localhost:9655/api/accounts/import with a simple content-type (no preflight) and inject attacker-controlled credentials into the victim's pool (or delete/relabel accounts).

Add isCrossOrigin(): reject /api/accounts/* whose Origin/Referer host doesn't match the server host. Non-browser clients (no Origin/Referer) are allowed, so CLI/scripts and the same-origin dashboard keep working.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant