From e7ffae5329abdad673bfbceb7432c8020abe650e Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Fri, 5 Jun 2026 11:01:51 +0200 Subject: [PATCH] fix(outbound): import ech and pcs from TLS share links The vless/trojan link parser's TLS branch read only sni/fp/alpn, so the ech (echConfigList) and pcs (pinnedPeerCertSha256) query params were dropped on import even though buildStream allocates both fields. Read them in applySecurityParams to match the inbound link generator and the hysteria2 parser. --- frontend/src/lib/xray/outbound-link-parser.ts | 2 ++ frontend/src/test/outbound-link-parser.test.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/frontend/src/lib/xray/outbound-link-parser.ts b/frontend/src/lib/xray/outbound-link-parser.ts index 973ad270..89c9c92b 100644 --- a/frontend/src/lib/xray/outbound-link-parser.ts +++ b/frontend/src/lib/xray/outbound-link-parser.ts @@ -203,6 +203,8 @@ function applySecurityParams(stream: Raw, params: URLSearchParams): void { tls.fingerprint = params.get('fp') ?? ''; const alpn = params.get('alpn'); if (alpn) tls.alpn = alpn.split(','); + tls.echConfigList = params.get('ech') ?? ''; + tls.pinnedPeerCertSha256 = params.get('pcs') ?? ''; } else if (stream.security === 'reality') { const reality = stream.realitySettings as Raw; reality.serverName = params.get('sni') ?? ''; diff --git a/frontend/src/test/outbound-link-parser.test.ts b/frontend/src/test/outbound-link-parser.test.ts index d3985f45..e630bf96 100644 --- a/frontend/src/test/outbound-link-parser.test.ts +++ b/frontend/src/test/outbound-link-parser.test.ts @@ -360,6 +360,21 @@ describe('parseVlessLink — extra / fm / x_padding_bytes (B20)', () => { const stream = parsed!.streamSettings as Record; expect((stream.xhttpSettings as Record).mode).toBe('auto'); }); + + it('round-trips ech and pcs from a TLS vless link', () => { + const ech = 'AFb+DQBSAAAgACAL7gYwrvaSFCIEs34G3SkfpuIbjMuYQxAiJsPK1oO7cwAkAAEAAQABAAIAAQADAAIAAQACAAIAAgADAAMAAQADAAIAAwADAAMxMjMAAA=='; + const pcs = '6fbc15ba46dfed152ad6c8d2129dd774707dd667a9ab4965476fa0f79ba82670'; + const link = 'vless://e3d307ae-c074-4aa3-af08-4f9e0f1d298b@localhost:15282?' + + 'alpn=h3&ech=' + encodeURIComponent(ech) + '&encryption=none&fp=firefox&host=&' + + 'mode=packet-up&path=%2F&pcs=' + pcs + '&security=tls&sni=123&type=xhttp#i5sboxj07w'; + const parsed = parseVlessLink(link); + expect(parsed).not.toBeNull(); + const tls = (parsed!.streamSettings as Record).tlsSettings as Record; + expect(tls.echConfigList).toBe(ech); + expect(tls.pinnedPeerCertSha256).toBe(pcs); + expect(tls.serverName).toBe('123'); + expect(tls.fingerprint).toBe('firefox'); + }); }); describe('parseWireguardLink', () => {