diff --git a/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx b/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx index 5c45dc81b..3652dfa7d 100644 --- a/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx +++ b/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx @@ -88,6 +88,20 @@ function validateGeckoPacketSize(_rule: unknown, value: unknown): Promise ); } +// xray-core's salamander smPSKMinLen counts bytes; a shorter password loads, then the listener +// (stopping Xray) or the dial fails, so the backend refuses it at save too. +const SALAMANDER_MIN_PSK_BYTES = 4; + +function validateSalamanderPassword(_rule: unknown, value: unknown): Promise { + const bytes = new TextEncoder().encode(typeof value === 'string' ? value : '').length; + if (bytes >= SALAMANDER_MIN_PSK_BYTES) return Promise.resolve(); + return Promise.reject( + new Error( + `Use at least ${SALAMANDER_MIN_PSK_BYTES} bytes; xray-core refuses a shorter password`, + ), + ); +} + function asPath(name: NamePath): (string | number)[] { return Array.isArray(name) ? [...name] : [name]; } @@ -1198,7 +1212,11 @@ function SalamanderUdpMaskSettings({ - +