From df777c12d354f8d952b9fdf22c8eba3215a59499 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Fri, 29 May 2026 01:58:36 +0200 Subject: [PATCH] fix(outbounds): preserve TLS/Reality security on save MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OutboundFormModal.onOk built the save payload from form.validateFields(), which only returns REGISTERED Form.Item values. The security selector is a Radio.Group that writes streamSettings.security via setFieldValue with no bound Form.Item, so validateFields() dropped it — network, tlsSettings and realitySettings (all registered) survived, but the security discriminator vanished and xray-core fell back to security="none". This hit both new outbounds and re-saved ones. Read the full form store with getFieldsValue(true) for the payload (still validating first), matching how the inbound modal already does it. Closes #4634 --- frontend/src/pages/xray/OutboundFormModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/xray/OutboundFormModal.tsx b/frontend/src/pages/xray/OutboundFormModal.tsx index 34060875..8bd90bc6 100644 --- a/frontend/src/pages/xray/OutboundFormModal.tsx +++ b/frontend/src/pages/xray/OutboundFormModal.tsx @@ -393,9 +393,8 @@ export default function OutboundFormModal({ async function onOk() { if (activeKey === '2' && !applyJsonToForm()) return; - let values: OutboundFormValues; try { - values = await form.validateFields(); + await form.validateFields(); } catch { return; } @@ -403,6 +402,7 @@ export default function OutboundFormModal({ messageApi.error('Tag already used by another outbound'); return; } + const values = form.getFieldsValue(true) as OutboundFormValues; onConfirm(formValuesToWirePayload(values)); }