mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-28 00:24:19 +00:00
fix(inbound): offer node share-address strategy only when a node exists
The `node` share-address strategy resolves to an address only when the inbound can live on a node; for a local inbound it is always empty and behaves like `listen`. Drop the `node` option from the picker unless an enabled, node-eligible node exists, and coerce the value to `listen` otherwise so the Select never shows an option that does nothing.
This commit is contained in:
@@ -176,6 +176,10 @@ export default function InboundFormModal({
|
||||
const selectableNodes = (availableNodes || []).filter((n) => n.enable);
|
||||
const protocol = (Form.useWatch('protocol', form) ?? '') as string;
|
||||
const isNodeEligible = NODE_ELIGIBLE_PROTOCOLS.has(protocol);
|
||||
// The `node` share-address strategy only means something when the inbound can
|
||||
// actually live on a node — otherwise the node address it would resolve to is
|
||||
// always empty. Offer it only then; `listen`/`custom` work for local inbounds.
|
||||
const nodeShareOptionAvailable = selectableNodes.length > 0 && isNodeEligible;
|
||||
const sniffingEnabled = Form.useWatch(['sniffing', 'enabled'], form) ?? false;
|
||||
const vlessEncryption = Form.useWatch(['settings', 'encryption'], form) ?? '';
|
||||
const ssMethod = Form.useWatch(['settings', 'method'], form);
|
||||
@@ -370,6 +374,18 @@ export default function InboundFormModal({
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [open, wPort, wNodeId, protocol, network, mixedUdpOn, wSsNetwork, wTunnelNetwork]);
|
||||
|
||||
// Keep the strategy value inside the visible option set: when `node` isn't
|
||||
// offered (no node, or a protocol that can't deploy to one) fall back to
|
||||
// `listen`, which yields the same link for a local inbound. Mirrors how the
|
||||
// protocol reset drops a nodeId that no longer applies.
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
if (!nodeShareOptionAvailable && shareAddrStrategy === 'node') {
|
||||
form.setFieldValue('shareAddrStrategy', 'listen');
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [open, nodeShareOptionAvailable, shareAddrStrategy]);
|
||||
|
||||
// Why: protocol picker reset cascades through the form — clearing the
|
||||
// settings DU branch and dropping a nodeId that no longer applies. The
|
||||
// legacy modal did this imperatively in onProtocolChange; here we hook
|
||||
@@ -532,10 +548,12 @@ export default function InboundFormModal({
|
||||
extra={t('pages.inbounds.form.shareAddrStrategyHelp')}
|
||||
>
|
||||
<Select
|
||||
options={SHARE_ADDR_STRATEGIES.map((strategy) => ({
|
||||
value: strategy,
|
||||
label: t(`pages.inbounds.form.shareAddrStrategyOptions.${strategy}`),
|
||||
}))}
|
||||
options={SHARE_ADDR_STRATEGIES
|
||||
.filter((strategy) => strategy !== 'node' || nodeShareOptionAvailable)
|
||||
.map((strategy) => ({
|
||||
value: strategy,
|
||||
label: t(`pages.inbounds.form.shareAddrStrategyOptions.${strategy}`),
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user