Skip to content

Sync features/fixes from decolua/9router (v0.4.18 → v0.4.33)#17

Draft
quangdang46 wants to merge 1 commit into
mainfrom
devin/1778594708-sync-from-9router
Draft

Sync features/fixes from decolua/9router (v0.4.18 → v0.4.33)#17
quangdang46 wants to merge 1 commit into
mainfrom
devin/1778594708-sync-from-9router

Conversation

@quangdang46
Copy link
Copy Markdown
Owner

Summary

Incremental port of changes from upstream decolua/9router (currently at v0.4.33) into openproxy (currently at v0.4.16). Both repos share a feature set but run on different stacks (9router is Next.js+JS, openproxy is Rust BE + Astro FE), so this is a port, not a merge.

This PR is opened as a draft and will be filled in incrementally over multiple commits. Each commit is a self-contained slice you can review independently. The first commit lands the security and bug fixes; subsequent commits add features.

Inventory

  • Security & bug fixes (this commit): CWE-1385 OAuth callback postMessage scope, dark-theme dropdown readability, DATA_DIR EACCES fallback, Fal.ai key-test endpoint, developer→system role normalization.
  • Medium features (queued): Cline / Kilo Code / OpenClaw tool cards, bulk API key import, Done button in ModelSelectModal, Codex GPT-5.5 image, APIKEY sort-by-usage + top-20 collapse, SSE stream stall timeout, local Material Symbols, header search store wire-up.
  • Big features (queued): OIDC dashboard SSO, STT pipeline + /v1/audio/transcriptions, Gemini TTS dedicated provider, GLM + MiniMax usage quota fetchers, MCP stdio→SSE bridge, Cowork settings expansion, Tailscale TUN routes, GitBook docs, provider icons refresh.
  • Skipped (don't apply to this stack): bun:sqlite adapter, Windows PowerShell tray rewrite, CWE-295 TLS verify on DNS-bypass fetch (Rust uses reqwest with default verification), PORT env model-test fetch (already correct on Rust side).

Commit 1 — security & bug fixes (landed)

  • web/src/components/page.tsx: scope OAuth callback postMessage targets to the already-computed expectedOrigins allowlist instead of '*'. Closes CWE-1385 leak of OAuth code/state to drive-by openers. (9router #998 part 1)
  • web/src/shared/components/styles/global.css: add select { color-scheme } + .dark select option { background-color, color } so native options aren't rendered dark-on-dark in Chrome/Firefox dark theme. (9router #997) src/db/mod.rs: when DATA_DIR is set but not writable, log a warning and fall back to the default ~/.openproxy instead of crashing on startup. Other I/O errors still propagate. (9router #1005) web/src/shared/constants/providers.ts: Fal.ai connection test now GETs https://api.fal.ai/v1/models?limit=1 (stable) instead of POSTing to a model-specific queue URL. (9router 0.4.29) src/core/executor/api_key.rs: in transform_request, normalize role: 'developer' -> role: 'system' for OpenAI-format providers (Deepseek, Groq, Mistral, Perplexity, Together, Fireworks, Cerebras, xAI, NVIDIA, …) which 400 on the OpenAI Responses-style developer role. Includes 4 unit tests. (9router #1011, closes upstream #773) Review & Testing Checklist for Human This PR will eventually be very large; expect to review it in slices as each commit lands. [ ] CWE-1385 fix — open OAuth flow via popup, confirm it still completes successfully (the popup origin is in the allowlist so the message should still be delivered). [ ] DATA_DIR fallback — set DATA_DIR=/root/notwritable as a non-root user; openproxy should warn and start with data in ~/.openproxy rather than panicking. [ ] developer→system normalization — send a POST /v1/chat/completions to a Deepseek- or Groq-backed model with role:'developer' and confirm it does NOT get rejected by the upstream as an invalid role. [ ] Dark theme dropdowns — navigate to /dashboard/usage in dark mode and confirm provider filter / page size / table-view selectors render with readable option text in the native dropdown. [ ] Fal.ai validation — add a Fal.ai API key in the provider page and click 'Test'; should return success. Notes I'll keep pushing commits to this branch as I work through the inventory, and flip to non-draft when the scope is complete. Each commit's diff is self-contained — feel free to squash/merge or cherry-pick individual commits at any point. Refs upstream: decolua/9router commits 52c38cf, c7c1074, a48fa4e, 80a2bfc.

…, DATA_DIR EACCES, Fal.ai endpoint, developer role)

- web/src/components/page.tsx: scope OAuth callback postMessage to the
  existing expectedOrigins allowlist instead of '*' (CWE-1385, 9router #998).
  The wildcard origin leaked the live OAuth code/state to any page that
  could open the popup against the well-known redirect_uri.

- web/src/shared/components/styles/global.css: add explicit color-scheme
  rules for <select> in dark mode so option text isn't rendered dark-on-dark
  on Chrome/Firefox (9router #997).

- src/db/mod.rs: when DATA_DIR is set but not writable, fall back to the
  default ~/.openproxy data dir instead of crashing on startup. Other I/O
  errors (read-only filesystem, disk full, etc.) still propagate (9router
  #1005).

- web/src/shared/constants/providers.ts: Fal.ai key test now hits
  https://api.fal.ai/v1/models?limit=1 (stable GET) instead of POSTing to
  a model-specific queue URL that was unreliable for validation (9router 0.4.29).

- src/core/executor/api_key.rs: normalize role: 'developer' -> 'system'
  in transform_request so Deepseek / Groq / Mistral / Perplexity / Together /
  Fireworks / Cerebras / xAI / NVIDIA / etc. don't 400 on the OpenAI
  Responses-style 'developer' role (9router #1011 / #773). Includes 4 unit
  tests.

The 9router CWE-295 DNS-bypass-fetch fix (#998 part 2) doesn't apply here —
the Rust stack uses reqwest with default TLS verification everywhere; no
'dangerous_accept_invalid_certs'/'rejectUnauthorized: false' codepath
exists. Similarly the 9router PORT-env model-test fix (#1014) doesn't
apply — openproxy's internal_base_url already reads $PORT.

Refs: decolua/9router commits 52c38cf, c7c1074, a48fa4e, 80a2bfc, b1f9...
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