From 591a03ff96f9d61d8ae396ab919168bcbf4f7220 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Tue, 26 May 2026 02:11:51 +0200 Subject: [PATCH] feat(frontend): protocol tab Shadowsocks section (Pattern A) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the Shadowsocks sub-form: method picker (from SSMethodSchema's seven schema-aligned options), conditional password input gated on isSS2022, network picker (tcp/udp/tcp,udp), ivCheck toggle. Method change cascades through the Select's onChange — regenerating the inbound-level password via RandomUtil.randomShadowsocksPassword. The shadowsockses[] multi-user list reset is deferred until the clients-management section lands. Uses isSS2022 from lib/xray/protocol-capabilities to gate the password field exactly the way the legacy modal did — keeps the form behavior identical without referencing the legacy class. SSMethodSchema.options drives the Select rather than the legacy SSMethods const (which the inbound modal pulled from models/inbound.ts). This commits to the schema-aligned 7-entry list for inbound; the outbound divergence (9 entries with legacy aliases) is still pending in OutboundFormModal — defer the UX decision to that rewrite. --- .../pages/inbounds/InboundFormModal.new.tsx | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/inbounds/InboundFormModal.new.tsx b/frontend/src/pages/inbounds/InboundFormModal.new.tsx index eb3f7f40..1c182e97 100644 --- a/frontend/src/pages/inbounds/InboundFormModal.new.tsx +++ b/frontend/src/pages/inbounds/InboundFormModal.new.tsx @@ -16,6 +16,7 @@ import { Typography, message, } from 'antd'; +import { SyncOutlined } from '@ant-design/icons'; import { HttpUtil, NumberFormatter, RandomUtil, SizeFormatter } from '@/utils'; import { @@ -23,6 +24,8 @@ import { formValuesToWirePayload, } from '@/lib/xray/inbound-form-adapter'; import { createDefaultInboundSettings } from '@/lib/xray/inbound-defaults'; +import { isSS2022 } from '@/lib/xray/protocol-capabilities'; +import { SSMethodSchema } from '@/schemas/protocols/inbound/shadowsocks'; import { InboundFormBaseSchema, InboundFormSchema, @@ -95,6 +98,11 @@ export default function InboundFormModalNew({ const isNodeEligible = NODE_ELIGIBLE_PROTOCOLS.has(protocol); const sniffingEnabled = Form.useWatch(['sniffing', 'enabled'], form) ?? false; const vlessEncryption = Form.useWatch(['settings', 'encryption'], form) ?? ''; + const ssMethod = Form.useWatch(['settings', 'method'], form); + const isSSWith2022 = isSS2022({ + protocol, + settings: typeof ssMethod === 'string' ? { method: ssMethod } : {}, + }); const matchesVlessAuth = ( block: { id?: string; label?: string } | undefined | null, @@ -326,6 +334,61 @@ export default function InboundFormModalNew({ const protocolTab = ( <> + {protocol === Protocols.SHADOWSOCKS && ( + <> + + + + {isSSWith2022 && ( + + Password{' '} + { + const method = form.getFieldValue(['settings', 'method']); + form.setFieldValue( + ['settings', 'password'], + RandomUtil.randomShadowsocksPassword(method as string), + ); + }} + /> + + } + > + + + )} + + + + + + + + )} + {protocol === Protocols.VLESS && ( <> @@ -437,7 +500,7 @@ export default function InboundFormModalNew({ >