Files
l-ui/frontend/src/pages/hosts/json-forms/HostSockoptForm.tsx
T
Muse 277838d7ca ITEM6 B4: frontend reshaping — xray page retired, stats switches to settings, template read paths closed
- Delete the xray settings page (routes/menu/title), geodata UI/service,
  XraySettingController/Service and routing-sync write paths; the stored
  xrayTemplateConfig row loses its last readers (GetXrayConfigTemplate now
  returns the embedded factory template; B1 already deleted the row).
- Settings GeneralTab gains the four trafficStatsSwitches switches
  (settings.trafficStatsSwitches, B1) with the dual warning copy; entity
  AllSetting carries the key end to end (TestTrafficStatsSwitchesPlumbing).
- Tag-directory consumers (panelOutbound, mtproto egress, node/host
  outbound pickers) move from POST /xray/ to GET /server/outboundDirectory.
- Shared Mux/Sockopt forms and balancer helpers relocated to lib/xray;
  converter preserves sniffing ips/domains exclusions into the panel
  sidecar instead of dropping them (B2 gap closed by retention).
- Freedom final-rules DB fix seeders retired; getDefaultJsonConfig
  endpoint removed (no in-repo consumer); locales pruned to referenced
  keys (pages.xray 331 -> 68) plus the five new settings keys.
2026-10-22 23:40:54 +00:00

54 lines
2.2 KiB
TypeScript

import { SockoptForm } from '@/lib/xray/forms/outbound/transport';
import { useOutboundTagGroups } from '@/api/queries/useOutboundTags';
import OutboundSubtreeJsonForm from './OutboundSubtreeJsonForm';
import { serializeOverride } from './helpers';
/*
* Sockopt override editor — reuses the outbound SockoptForm (which carries its
* own enable Switch and writes streamSettings.sockopt). Serialized to the host's
* sockoptParams JSON string.
*
* A host is the client/dialer side, so the inbound-only sockopt keys are dropped
* from the output. Verified against xray-core transport/internet/sockopt_*.go:
* only V6Only and the handler-level acceptProxyProtocol / trustedXForwardedFor
* are inbound-only — tproxy (IP_TRANSPARENT) and keepalive/interface ARE applied
* on the outbound/dialer socket, so they stay. The outbound form no longer shows
* the inbound-only keys, but its default object still seeds them, so strip here.
*/
const INBOUND_ONLY_SOCKOPT = ['acceptProxyProtocol', 'V6Only', 'trustedXForwardedFor'];
function serializeClientSockopt(sockopt: unknown): string {
if (!sockopt || typeof sockopt !== 'object') return serializeOverride(sockopt);
const copy = { ...(sockopt as Record<string, unknown>) };
for (const key of INBOUND_ONLY_SOCKOPT) delete copy[key];
return serializeOverride(copy);
}
export default function HostSockoptForm({
value,
onChange,
}: {
value?: string;
onChange?: (next: string) => void;
}) {
/*
* Populate the dialerProxy dropdown with the panel's outbound tags (a host can
* chain through one of the subscription's outbounds by tag). dialerProxy chains
* through a single outbound, so balancers (routing targets) are excluded — only
* the outbound group is used; blackhole is dropped too (chaining to it just
* drops the traffic).
*/
const { data: tagGroups } = useOutboundTagGroups({ excludeBlackhole: true });
const outboundTags = tagGroups?.outbounds ?? [];
return (
<OutboundSubtreeJsonForm
value={value}
onChange={onChange}
path={['streamSettings', 'sockopt']}
serialize={serializeClientSockopt}
render={() => <SockoptForm outboundTags={outboundTags} />}
/>
);
}