fix(sub): emit JSON-subscription pinnedPeerCertSha256 as comma-separated string

xray-core now parses tlsSettings.pinnedPeerCertSha256 as a comma-separated
string rather than a []string array. The JSON subscription still emitted the
array form, which current xray-core-backed v2ray clients reject on import.
Join the panel's stored pins into the string form, matching the raw share-link
path (pcs/pinSHA256). Fixes #5401.
This commit is contained in:
MHSanaei
2026-06-17 17:07:10 +02:00
parent 3088e96493
commit d6cddaff12
2 changed files with 20 additions and 2 deletions
+4 -2
View File
@@ -297,8 +297,10 @@ func (s *SubJsonService) tlsData(tData map[string]any) map[string]any {
if ech, ok := tlsClientSettings["echConfigList"].(string); ok && ech != "" {
tlsData["echConfigList"] = ech
}
if pins, ok := tlsClientSettings["pinnedPeerCertSha256"].([]any); ok && len(pins) > 0 {
tlsData["pinnedPeerCertSha256"] = pins
// xray-core now parses pinnedPeerCertSha256 as a comma-separated string, not
// an array; emit the joined form so v2ray clients can import the config (#5401).
if pins, ok := pinnedSha256List(tlsClientSettings); ok {
tlsData["pinnedPeerCertSha256"] = strings.Join(pins, ",")
}
return tlsData
}
+16
View File
@@ -102,6 +102,22 @@ func TestSubJsonServiceNoFinalMaskWhenEmpty(t *testing.T) {
}
}
// xray-core parses tlsSettings.pinnedPeerCertSha256 as a comma-separated string;
// the JSON subscription must emit that form, not an array, or v2ray clients fail
// to import the config (#5401).
func TestSubJsonServicePinnedCertJoinedToString(t *testing.T) {
svc := NewSubJsonService("", "", "", nil)
stream := svc.streamData(`{"network":"tcp","security":"tls","tlsSettings":{"serverName":"a.example.com","settings":{"pinnedPeerCertSha256":["aa11","bb22"]}}}`)
tls, _ := stream["tlsSettings"].(map[string]any)
if tls == nil {
t.Fatalf("tlsSettings missing: %#v", stream)
}
if got := tls["pinnedPeerCertSha256"]; got != "aa11,bb22" {
t.Fatalf("pinnedPeerCertSha256 = %#v, want comma-separated string \"aa11,bb22\"", got)
}
}
func TestSubJsonServiceVlessFlattened(t *testing.T) {
inbound := &model.Inbound{Listen: "1.2.3.4", Port: 443, Protocol: model.VLESS, Settings: `{"encryption":"none"}`}
client := model.Client{ID: "uuid-1", Flow: "xtls-rprx-vision"}