mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-16 00:01:02 +00:00
main
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
930a0ed59d |
feat(inbound): DisableFlow — opt an inbound out of auto XTLS Vision (#5689) (#5698)
* feat(inbound): add DisableFlow to opt an inbound out of auto XTLS Vision Adds an inbound-level DisableFlow flag so operators can suppress automatic xtls-rprx-vision injection on a specific inbound even when its transport is flow-capable — e.g. a tunneled/CDN-fronted XHTTP+vlessenc inbound where Vision is not wanted, while keeping it on the same client's Reality inbounds. When set, the inbound reports tlsFlowCapable=false, the write path clamps each attached client's flow to empty (so flow_override stores ""), and share links/subscriptions never carry the flow for it. The flag is panel-only metadata and is never sent to xray. Closes part of #5689. * feat(inbound): DisableFlow toggle in the inbound form (frontend) Wire the DisableFlow field through the form schema + adapters and add a VLESS-gated switch in the inbound form, plus en-US strings. tsc --noEmit and eslint pass. * fix(inbound): honor DisableFlow in all emitters + on toggle; regen OpenAPI Addresses review on #5690: - Clash (clash_service.go) and JSON (json_service.go) subscription emitters now also skip the flow for a DisableFlow inbound — previously only the raw share-link path was gated, so those two still advertised it (blocking 1). - UpdateInbound now strips any flow already stored on a DisableFlow inbound's clients (settings.clients[].flow + client_inbounds.flow_override) so xray and the subscription agree; otherwise toggling DisableFlow on an existing Vision client left xray expecting a flow the client no longer sends. - Regenerated the OpenAPI + zod/types/examples artifacts for the new field and added an example tag (blocking 2; make gen-check is clean). - Added Clash + JSON DisableFlow suppression tests alongside the raw-link one. * fix(inbound): make DisableFlow durable, clamp on create, guard live config Addresses the review + completeness audit on #5690: - UpdateInbound now persists inbound.DisableFlow onto the saved row. It was only read to branch strip-vs-restore, so toggling the flag on an existing inbound never stuck and MigrationRestoreVisionFlow re-injected the flow — the exact #5689 path (editing a multi-inbound client's inbound) self-reverted. - DBInbound (frontend) declares + initializes disableFlow so ObjectUtil .cloneProps carries the API value through; the edit Switch previously always read false and re-saving silently reverted the opt-out. - AddInbound strips client flow (settings + parsed clients) when DisableFlow is set, so a created-disabled inbound never persists a flow xray would expect. - GetXrayConfig forces flow="" for DisableFlow inbounds (VLESS + Trojan) as defense-in-depth, keeping the live config and the subscription in agreement. - genTrojanLink share link honors DisableFlow too. - Drop the dead explicit flow_override clear in UpdateInbound (SyncInbound rebuilds it from the stripped settings). - Clear disableFlow in the inbound form when switching to a non-VLESS protocol. - Add disableFlow/disableFlowHelp to the remaining 12 locales. Tests: stripClientFlows unit cases; DB-backed AddInbound clamp; UpdateInbound persist+strip+resist-restore regression (fails without the persist fix); frontend DBInbound + adapter round-trip (fails without the model field). * style(inbound): drop // line comments per repo CLAUDE.md The DisableFlow work followed the surrounding code's commenting style; the repo CLAUDE.md forbids // line comments in committed Go/TS. Remove the comments I added (Go + frontend + tests) and regenerate OpenAPI/schemas, which drops the generated field descriptions sourced from the Go doc comments. No behavior change; full go test (service+sub, CGO) + frontend typecheck/vitest green; golangci-lint clean on the changed files. * fix(runtime): propagate disableFlow to nodes Preserve the inbound DisableFlow flag when syncing inbounds across nodes and when recreating central records from remote traffic snapshots. This keeps multi-node deployments from reintroducing VLESS Vision flow in node configs and share links, and updates the related tests to cover the wired field and VLESS JSON generation. |
||
|
|
82600936d6 |
fix(flow): restore XTLS Vision when an inbound becomes flow-eligible (#5520)
* fix(flow): restore XTLS Vision when an inbound becomes flow-eligible clientWithInboundFlow strips Vision from a VLESS client whenever the target inbound is not flow-eligible at client-write time — e.g. an XHTTP inbound before its vlessenc (ML-KEM) encryption is set, or a client attached to such an inbound. Nothing restored the flow once the inbound later became eligible: an inbound edit stores its settings verbatim and never re-gates the clients. So enabling encryption on an existing XHTTP inbound left every client without flow, and the generated configs, share links and subscriptions silently dropped flow=xtls-rprx-vision — most visibly on node inbounds and on any inbound where encryption was turned on after the clients existed. Restore the flow at the two points where an inbound can become eligible: - UpdateInbound: after the new stream/settings are final, re-add Vision to clients that currently carry no flow but whose intended flow (their flow_override on a sibling inbound, via EffectiveFlowByEmail) is Vision — only when the inbound is now flow-eligible. - MigrationRestoreVisionFlow: a one-time, idempotent boot migration that applies the same repair to existing installs and refreshes flow_override via SyncInbound. The repair is conservative: it never invents a flow for a client that has none anywhere, never overwrites an explicit flow, and is a no-op on healthy installs. Adds EffectiveFlowByEmail and a unit test covering keep/skip/no-op cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style(flow): serialize restored settings with MarshalIndent Match the indented JSON used by the adjacent timestamp block in UpdateInbound and the externalProxy migration, so a restored inbound's settings column keeps the same multi-line format as everything else (review nit on #5520). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * perf(flow): batch the intended-flow lookup and run it on the active tx restoreVisionFlowForEligibleInbound resolved each empty-flow client's intended flow with EffectiveFlowByEmail, which issued two queries per client (GetRecordByEmail + EffectiveFlow). A client that genuinely uses no Vision keeps an empty flow forever, so it was re-queried on every UpdateInbound and every boot — O(clients) queries per save on a Reality/TCP or XHTTP+vlessenc inbound carrying many non-Vision clients, executed inside the serialized writer transaction. Replace it with EffectiveFlowsByEmails: collect every empty-flow email first and resolve them in a single batched join over client_inbounds + clients (lowest inbound_id wins, same rule as before), chunked for the SQLite bind-var limit. Also thread the active tx through restoreVisionFlowForEligibleInbound so the read runs on the writer's own connection while it holds the lock instead of a separate pooled connection (UpdateInbound passes its tx; the boot migration passes nil → GetDB() as before). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |