mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-02 04:02:07 +03:00
d8221a8153
The Host VLESS Route field was stored and shown in the panel but never applied to any generated subscription (raw, JSON, Clash), so the UUID was emitted unmodified (#5655). Xray reads the route from the UUID's 3rd group (bytes 6-7, net.PortFromBytes) and masks those bytes to zero before authenticating, so a value can be baked into the share/JSON/Clash UUIDs without breaking the user match. A shared applyVlessRoute helper encodes a single 0-65535 value as the 3rd group; empty/invalid/non-UUID input is left unchanged, so legacy data never yields a broken link and no DB migration is needed. The field was wrongly validated as a multi-segment port spec (that form belongs to the separate server-side routing rule). It is now a single value 0-65535, with frontend validation, link-preview parity (genVlessLink/hostToExternalProxyEntry), hint + error translations across all 13 locales, and tests on every path. Closes #5655
55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import type { ExternalProxyEntry } from '@/schemas/protocols/stream/external-proxy';
|
|
import type { HostFormValues } from '@/schemas/api/host';
|
|
|
|
// The subset of a host that affects its share link. Mirrors the fields the
|
|
// backend's hostToExternalProxyMap reads.
|
|
export type HostLinkInput = Pick<
|
|
HostFormValues,
|
|
| 'security'
|
|
| 'address'
|
|
| 'port'
|
|
| 'remark'
|
|
| 'sni'
|
|
| 'alpn'
|
|
| 'fingerprint'
|
|
| 'pinnedPeerCertSha256'
|
|
| 'verifyPeerCertByName'
|
|
| 'echConfigList'
|
|
| 'overrideSniFromAddress'
|
|
| 'keepSniBlank'
|
|
| 'vlessRoute'
|
|
>;
|
|
|
|
// hostToExternalProxyEntry projects a host onto the ExternalProxyEntry shape the
|
|
// share-link preview generators already understand — the frontend mirror of the
|
|
// backend's hostToExternalProxyMap. security "reality"/"same" keep the inbound's
|
|
// base TLS (forceTls "same"); the preview falls back to port 443 when the host
|
|
// inherits the inbound port (port 0).
|
|
export function hostToExternalProxyEntry(host: HostLinkInput): ExternalProxyEntry {
|
|
const forceTls = host.security === 'tls' || host.security === 'none' ? host.security : 'same';
|
|
|
|
let sni: string | undefined;
|
|
if (host.keepSniBlank) {
|
|
sni = undefined;
|
|
} else if (host.overrideSniFromAddress) {
|
|
sni = host.address || undefined;
|
|
} else {
|
|
sni = host.sni || undefined;
|
|
}
|
|
|
|
return {
|
|
forceTls,
|
|
dest: host.address || '',
|
|
port: host.port && host.port > 0 ? host.port : 443,
|
|
remark: host.remark || '',
|
|
sni,
|
|
fingerprint: host.fingerprint,
|
|
alpn: host.alpn && host.alpn.length > 0 ? host.alpn : undefined,
|
|
pinnedPeerCertSha256:
|
|
host.pinnedPeerCertSha256 && host.pinnedPeerCertSha256.length > 0 ? host.pinnedPeerCertSha256 : undefined,
|
|
verifyPeerCertByName: host.verifyPeerCertByName || undefined,
|
|
echConfigList: host.echConfigList || undefined,
|
|
vlessRoute: host.vlessRoute || undefined,
|
|
};
|
|
}
|