fix(sub): default VLESS client encryption to none when the inbound has none stored (#6781)

VLESS inbounds whose settings carry no "encryption" key (rows saved by
panels before the field existed, or inbounds added over the API with only
"decryption":"none", as the API docs example does) produced a JSON
subscription outbound with "encryption": "". Xray refuses to load that
config ("VLESS users: please add/set \"encryption\":\"none\" for every
user"), so every VLESS entry of the JSON subscription was unusable. The
share link left the parameter out instead.

Treat a missing or empty value as "none" for both outputs, matching the
frontend inbound schema default and the docs link generator.
This commit is contained in:
Jay Hemnani
2026-10-12 14:33:47 +05:30
committed by GitHub
parent f55938ba0a
commit d43e0c7ead
3 changed files with 44 additions and 9 deletions
+10 -4
View File
@@ -1193,6 +1193,15 @@ func vlessEncryptionEnabled(settings map[string]any) bool {
return false
}
// vlessClientEncryption reads the client-side VLESS encryption from inbound settings. Inbounds
// stored without the field (older panels, API adds) mean "none", as the frontend schema does.
func vlessClientEncryption(settings map[string]any) string {
if encryption, _ := settings["encryption"].(string); encryption != "" {
return encryption
}
return "none"
}
// vlessFlowAllowed mirrors inboundCanEnableTlsFlow in internal/web/service: Vision runs over
// TLS/REALITY on raw TCP, or inside VLESS encryption on any transport.
func vlessFlowAllowed(network, security string, settings map[string]any) bool {
@@ -1218,11 +1227,8 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
params := make(map[string]string)
params["type"] = streamNetwork
// Add encryption parameter for VLESS from inbound settings
settings := s.linkSettings(inbound)
if encryption, ok := settings["encryption"].(string); ok {
params["encryption"] = encryption
}
params["encryption"] = vlessClientEncryption(settings)
applyShareNetworkParams(stream, streamNetwork, params)
if finalmask, ok := stream["finalmask"].(map[string]any); ok {