feat(web-proxy): per-interface opt-out of URL rewriting#302
Merged
Conversation
Since v0.42.0 the Web Interfaces card reverse-proxies every absolute
http(s) root URL and the SPA opens the proxy port instead of the
operator's configured URL, with no opt-out. This breaks NAT/reverse-
proxy setups where only fixed published ports are reachable.
- Add webInterface.NoProxy (JSON "noProxy"), preserved through the
saveWebInterfaces {Label,URL} rebuild that previously dropped any
field not explicitly copied.
- Guard schemeAndDialFor (the single source of truth for both
resolveProxyTargets and withProxyPorts) so a NoProxy entry yields no
dial target and no proxy port; echo NoProxy back via webInterfaceOut
so the edit form reflects the persisted flag.
- Frontend: add noProxy to the WebInterface type and a checkbox in the
Web Interfaces edit form ("Open directly (don't proxy)"); no change
needed in InterfaceRow — it already opens item.url when proxyPort is
unset. Add the i18n key to all 10 locales.
Addresses #261
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a per-Web-Interface opt-out flag so operators can prevent the mesh web-proxy from rewriting/opening a link via dynamically assigned proxy ports, which is important for NAT / reverse-proxy deployments where only fixed published ports are reachable.
Changes:
- Backend: adds
NoProxyto the Web Interfaces model and short-circuitsschemeAndDialForso opted-out entries never get proxy targets/ports assigned. - Backend API: echoes
noProxyback to the SPA and persists it through save/load. - Frontend: adds an “Open directly (don’t proxy)” checkbox, wires
noProxythrough edit/save/load, and updates all locale strings.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
web/src/tabs/BattlegroupTab/components/WebInterfacesCard.tsx |
Adds a per-row checkbox and persists noProxy in the edit/save flow. |
web/src/api/client.ts |
Extends WebInterface type with optional noProxy. |
web/src/locales/*/translation.json |
Adds serverHealth.ifaceNoProxy string across all locales. |
cmd/dune-admin/web_proxy.go |
Treats NoProxy as non-proxyable; echoes noProxy in API output. |
cmd/dune-admin/web_proxy_test.go |
Adds coverage ensuring NoProxy prevents proxy target/port assignment and is echoed back. |
cmd/dune-admin/web_interfaces.go |
Persists NoProxy in the stored web interfaces file and keeps validation unchanged. |
cmd/dune-admin/web_interfaces_test.go |
Adds round-trip test coverage for persisting/loading NoProxy. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
NoProxyto each Web Interfaces entry so operators behind NAT/a reverse proxy (only fixed published ports reachable) can force an entry to open its configured URL as-is instead of the mesh proxy's rewritten port.schemeAndDialFor(the single source of truth forresolveProxyTargets/withProxyPorts) short-circuits onNoProxy, so no proxy target/port is ever created for an opted-out entry.noProxyround-trips through save/load and the API response.Test plan
make verify(fmt-check, vet, test-race, lint) — pass;vulncheckfails on a pre-existing, unrelated marketbot dependency (golang.org/x/text GO-2026-5970, also present on main)make gosec— 0 issuescd web && pnpm build && pnpm lint && pnpm exec vitest run— pass (81/81 tests, incl. i18n locale parity)Note for reviewers
Overlaps
#275(also touches web-proxy internals) in an additive-only way —web_interfaces.go/web_proxy.gostruct fields,client.tstype,WebInterfacesCard.tsxedit row, and locale files. Should merge cleanly by keeping both sides' additions.Addresses #261