mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 20:54:14 +00:00
Stand up the remaining Step 2 families. NetworkSettingsSchema is a 6-branch DU on `network` covering tcp/kcp/ws/grpc/httpupgrade/xhttp, with asymmetric per-network wire keys (tcpSettings, wsSettings, ...) preserved exactly so fixtures round-trip byte-identical. SecuritySettingsSchema is a 3-branch DU on `security` covering none/tls/reality. TLS certs use a file-vs-inline union; uTLS fingerprints are shared between TLS and Reality via a single primitive enum. Hysteria-as-network, finalmask, and sockopt are not in the plan's Step 2 inventory and are deferred to Step 6 (Tighten) - they're orthogonal extras on the stream root, not network-discriminated branches. Resolves a Security identifier collision in protocols/index.ts by re-exporting the type alias as SecurityKind (the `Security` name is taken by the namespace re-export).
47 lines
1.9 KiB
TypeScript
47 lines
1.9 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
// Xray's V2-style header map: { Host: ['example.com', ...], ... }. Each
|
|
// header name maps to a string[] because HTTP allows repeated headers
|
|
// (Accept, Cookie, etc.). The panel renders these as a flat name/value
|
|
// table internally and flattens to this map on save via toV2Headers.
|
|
export const V2HeaderMapSchema = z.record(z.string(), z.array(z.string()));
|
|
export type V2HeaderMap = z.infer<typeof V2HeaderMapSchema>;
|
|
|
|
export const TcpRequestSchema = z.object({
|
|
version: z.string().default('1.1'),
|
|
method: z.string().default('GET'),
|
|
path: z.array(z.string()).min(1).default(['/']),
|
|
headers: V2HeaderMapSchema.default({}),
|
|
});
|
|
export type TcpRequest = z.infer<typeof TcpRequestSchema>;
|
|
|
|
export const TcpResponseSchema = z.object({
|
|
version: z.string().default('1.1'),
|
|
status: z.string().default('200'),
|
|
reason: z.string().default('OK'),
|
|
headers: V2HeaderMapSchema.default({}),
|
|
});
|
|
export type TcpResponse = z.infer<typeof TcpResponseSchema>;
|
|
|
|
// TCP stream `header` is the obfuscation header. type='none' (the wire
|
|
// representation just omits `header` entirely) or type='http' (HTTP-1.1
|
|
// camouflage with request/response sub-objects).
|
|
export const TcpHeaderHttpSchema = z.object({
|
|
type: z.literal('http'),
|
|
request: TcpRequestSchema.optional(),
|
|
response: TcpResponseSchema.optional(),
|
|
});
|
|
export const TcpHeaderNoneSchema = z.object({ type: z.literal('none') });
|
|
export const TcpHeaderSchema = z.discriminatedUnion('type', [
|
|
TcpHeaderNoneSchema,
|
|
TcpHeaderHttpSchema,
|
|
]);
|
|
export type TcpHeader = z.infer<typeof TcpHeaderSchema>;
|
|
|
|
// Top-level TCP stream payload. `acceptProxyProtocol` only appears on the
|
|
// wire when true (panel omits it when false), so we treat it as optional.
|
|
export const TcpStreamSettingsSchema = z.object({
|
|
acceptProxyProtocol: z.literal(true).optional(),
|
|
header: TcpHeaderSchema.optional(),
|
|
});
|
|
export type TcpStreamSettings = z.infer<typeof TcpStreamSettingsSchema>;
|