fix(frontend): TProxy schema, VLESS+XHTTP flow links, clearable Jalali date picker (#5339, #5322, #5313)

- #5339: accept transportless tunnel/TProxy streamSettings that carry no
  `security` key by adding a transportless branch to SecuritySettingsSchema,
  mirroring NetworkSettingsSchema. Fixes "streamSettings.security Invalid input".
- #5322: emit XTLS Vision `flow` in panel VLESS share links for XHTTP+vlessenc
  via the shared canEnableTlsFlow predicate, so panel links match the form and
  the subscription output.
- #5313: give the Jalali expiry date picker a working clear (X) button
  (remount on clear, since the library reads `value` only on mount) and a blank
  placeholder instead of the library's hardcoded Persian text.
This commit is contained in:
MHSanaei
2026-06-15 17:20:54 +02:00
parent cdaf5f80db
commit f00512d12e
5 changed files with 187 additions and 9 deletions
@@ -15,9 +15,18 @@ export type Security = z.infer<typeof SecuritySchema>;
// 'none' neither key appears. The Xray panel's StreamSettings class emits
// `undefined` for the inactive branch which strips the key during JSON
// serialization, so this DU faithfully describes what's on disk.
export const SecuritySettingsSchema = z.discriminatedUnion('security', [
z.object({ security: z.literal('none') }),
z.object({ security: z.literal('tls'), tlsSettings: TlsStreamSettingsSchema }),
z.object({ security: z.literal('reality'), realitySettings: RealityStreamSettingsSchema }),
//
// Tunnel (dokodemo-door / TProxy) is transportless and may carry only
// `sockopt` — its streamSettings has no `security` key at all. The
// transportless branch accepts that shape, mirroring NetworkSettingsSchema's
// `network: never().optional()` handling. A present-but-invalid security
// still fails both branches so a typo can't slip through.
export const SecuritySettingsSchema = z.union([
z.discriminatedUnion('security', [
z.object({ security: z.literal('none') }),
z.object({ security: z.literal('tls'), tlsSettings: TlsStreamSettingsSchema }),
z.object({ security: z.literal('reality'), realitySettings: RealityStreamSettingsSchema }),
]),
z.object({ security: z.never().optional() }),
]);
export type SecuritySettings = z.infer<typeof SecuritySettingsSchema>;