diff --git a/app/models/proxy.py b/app/models/proxy.py
index 83176e1d..26d585cd 100644
--- a/app/models/proxy.py
+++ b/app/models/proxy.py
@@ -14,7 +14,7 @@ class VMessSettings(BaseModel):
class XTLSFlows(StrEnum):
NONE = ""
VISION = "xtls-rprx-vision"
-
+ VISION_UDP = "xtls-rprx-vision-udp443"
class VlessSettings(BaseModel):
id: UUID = Field(default_factory=uuid4)
diff --git a/app/node/user.py b/app/node/user.py
index 3a5fbce7..2c3fe78c 100644
--- a/app/node/user.py
+++ b/app/node/user.py
@@ -48,12 +48,16 @@ def _serialize_user_for_node(id: int, username: str, user_settings: dict, inboun
shadowsocks_settings = user_settings.get("shadowsocks", {})
hysteria_settings = user_settings.get("hysteria", {})
+ vless_flow = vless_settings.get("flow")
+ if vless_flow == "xtls-rprx-vision-udp443":
+ vless_flow = "xtls-rprx-vision"
+
return create_user(
f"{id}.{username}",
create_proxy(
vmess_id=vmess_settings.get("id"),
vless_id=vless_settings.get("id"),
- vless_flow=vless_settings.get("flow"),
+ vless_flow=vless_flow,
trojan_password=trojan_settings.get("password"),
shadowsocks_password=shadowsocks_settings.get("password"),
shadowsocks_method=shadowsocks_settings.get("method"),
diff --git a/dashboard/src/components/dialogs/user-modal.tsx b/dashboard/src/components/dialogs/user-modal.tsx
index 74da1128..b7f0247f 100644
--- a/dashboard/src/components/dialogs/user-modal.tsx
+++ b/dashboard/src/components/dialogs/user-modal.tsx
@@ -1195,7 +1195,7 @@ export default function UserModal({ isDialogOpen, onOpenChange, form, editingUse
},
vless: {
id: uuidv4(),
- flow: '' as '' | 'xtls-rprx-vision' | undefined,
+ flow: '' as '' | 'xtls-rprx-vision' | 'xtls-rprx-vision-udp443' | undefined,
},
trojan: {
password: generatePassword(),
@@ -1894,6 +1894,7 @@ export default function UserModal({ isDialogOpen, onOpenChange, form, editingUse
{t('userDialog.proxySettings.flow.none', { defaultValue: 'None' })}
xtls-rprx-vision
+ xtls-rprx-vision-udp443
diff --git a/dashboard/src/components/dialogs/user-template-modal.tsx b/dashboard/src/components/dialogs/user-template-modal.tsx
index f863f1fe..9410c32e 100644
--- a/dashboard/src/components/dialogs/user-template-modal.tsx
+++ b/dashboard/src/components/dialogs/user-template-modal.tsx
@@ -503,6 +503,7 @@ export default function UserTemplateModal({ isDialogOpen, onOpenChange, form, ed
{t('userDialog.proxySettings.flow.none', { defaultValue: 'None' })}
xtls-rprx-vision
+ xtls-rprx-vision-udp443
@@ -526,4 +527,3 @@ export default function UserTemplateModal({ isDialogOpen, onOpenChange, form, ed
)
}
-
diff --git a/dashboard/src/components/forms/user-form.ts b/dashboard/src/components/forms/user-form.ts
index 2eeb8ae0..5fc7cb23 100644
--- a/dashboard/src/components/forms/user-form.ts
+++ b/dashboard/src/components/forms/user-form.ts
@@ -3,7 +3,7 @@ import { z } from 'zod'
export const userStatusEnum = z.enum(['active', 'disabled', 'limited', 'expired', 'on_hold'])
export const userDataLimitResetStrategyEnum = z.enum(['no_reset', 'day', 'week', 'month', 'year'])
-export const xtlsFlowsEnum = z.enum(['', 'xtls-rprx-vision'])
+export const xtlsFlowsEnum = z.enum(['', 'xtls-rprx-vision', 'xtls-rprx-vision-udp443'])
export const shadowsocksMethodsEnum = z.enum(['aes-128-gcm', 'aes-256-gcm', 'chacha20-ietf-poly1305', 'xchacha20-poly1305'])
export const vMessSettingsSchema = z.object({
diff --git a/dashboard/src/components/forms/user-template-form.ts b/dashboard/src/components/forms/user-template-form.ts
index eb8a0e37..fad1c59c 100644
--- a/dashboard/src/components/forms/user-template-form.ts
+++ b/dashboard/src/components/forms/user-template-form.ts
@@ -12,7 +12,7 @@ export const userTemplateFormSchema = z.object({
method: z
.enum([ShadowsocksMethods['aes-128-gcm'], ShadowsocksMethods['aes-256-gcm'], ShadowsocksMethods['chacha20-ietf-poly1305'], ShadowsocksMethods['xchacha20-poly1305']])
.default(ShadowsocksMethods['chacha20-ietf-poly1305']),
- flow: z.enum([XTLSFlows[''], XTLSFlows['xtls-rprx-vision']]).default(XTLSFlows['']),
+ flow: z.enum([XTLSFlows[''], XTLSFlows['xtls-rprx-vision'], XTLSFlows['xtls-rprx-vision-udp443']]).default(XTLSFlows['']),
groups: z.array(z.number()).min(1, 'Groups is required'),
data_limit_reset_strategy: z
.enum([
diff --git a/dashboard/src/service/api/index.ts b/dashboard/src/service/api/index.ts
index de0900ac..711a4b47 100644
--- a/dashboard/src/service/api/index.ts
+++ b/dashboard/src/service/api/index.ts
@@ -317,6 +317,7 @@ export type XTLSFlows = (typeof XTLSFlows)[keyof typeof XTLSFlows]
export const XTLSFlows = {
'': '',
'xtls-rprx-vision': 'xtls-rprx-vision',
+ 'xtls-rprx-vision-udp443': 'xtls-rprx-vision-udp443',
} as const
export type XMuxSettingsOutputHKeepAlivePeriod = number | null