mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-06 04:19:34 +00:00
The external proxy "Host" field was bound to dest (the connection address that becomes the link host) but labeled "Host", misleading users into thinking it set a transport host header. Relabel it to "Address" to match what it actually controls. Add per-entry ECH (echConfigList) to the external proxy schema, form (shown under Force TLS = TLS), the TS link generator, and the Go sub services: ech is emitted on share links and vmess objects, and written into the stream so the JSON subscription picks it up via the existing tlsData reader.
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
import { PortSchema } from '@/schemas/primitives';
|
|
|
|
import { AlpnSchema, UtlsFingerprintSchema } from '@/schemas/protocols/security/tls';
|
|
|
|
export const ExternalProxyForceTlsSchema = z.enum(['same', 'tls', 'none']);
|
|
export type ExternalProxyForceTls = z.infer<typeof ExternalProxyForceTlsSchema>;
|
|
|
|
// An inbound can advertise external proxy fronts (CDN edges, mirror nodes)
|
|
// that share its config but vary the dest+port+SNI for the share link. The
|
|
// panel form ships rows of this shape; link generators iterate them when
|
|
// stream.externalProxy is non-empty.
|
|
export const ExternalProxyEntrySchema = z.object({
|
|
forceTls: ExternalProxyForceTlsSchema.default('same'),
|
|
dest: z.string().default(''),
|
|
port: PortSchema.default(443),
|
|
remark: z.string().default(''),
|
|
sni: z.string().optional(),
|
|
fingerprint: z.preprocess(
|
|
(val) => (val === '' ? undefined : val),
|
|
UtlsFingerprintSchema.optional(),
|
|
),
|
|
alpn: z.array(AlpnSchema).optional(),
|
|
pinnedPeerCertSha256: z.array(z.string()).optional(),
|
|
echConfigList: z.string().optional(),
|
|
});
|
|
export type ExternalProxyEntry = z.infer<typeof ExternalProxyEntrySchema>;
|