fix(outbounds): support proxyProtocol on freedom outbound

Xray's freedom outbound accepts a numeric proxyProtocol (0 disabled,
1 or 2 for the PROXY protocol version), but the panel had no field for
it and the typed form adapter dropped the key on save — so a value set
via the JSON editor disappeared the moment the outbound was saved.

Model proxyProtocol through the freedom wire schema, the form schema,
and both adapter directions (clamped to 0/1/2, omitted from the wire
when 0), and add a Select (none / v1 / v2) to the freedom section of
the outbound form. Add round-trip test coverage and the proxyProtocol
label across all locales.

Closes #4486
This commit is contained in:
MHSanaei
2026-05-29 17:18:21 +02:00
parent 5d0081a3b9
commit 62c293e034
18 changed files with 39 additions and 0 deletions
@@ -235,16 +235,26 @@ describe('outbound-form-adapter: round-trip', () => {
settings: {
domainStrategy: 'UseIPv4',
redirect: '1.1.1.1',
proxyProtocol: 2,
fragment: { packets: 'tlshello', length: '100-200' },
},
}));
expect(filled.settings).toMatchObject({
domainStrategy: 'UseIPv4',
redirect: '1.1.1.1',
proxyProtocol: 2,
fragment: { packets: 'tlshello', length: '100-200' },
});
});
it('freedom omits proxyProtocol when disabled (0)', () => {
const round = formValuesToWirePayload(rawOutboundToFormValues({
protocol: 'freedom',
settings: { proxyProtocol: 0 },
}));
expect((round.settings as { proxyProtocol?: number }).proxyProtocol).toBeUndefined();
});
it('mux is only emitted when enabled AND protocol/network/flow allow it', () => {
// Disabled mux: omitted
const disabled = formValuesToWirePayload(rawOutboundToFormValues({