fix(sub): preserve external link names in Clash/JSON (#6049)

expandEntry cleared Name for external subscriptions and single links
with empty remark, so Clash/JSON fell back to the client email. Keep
each link's original name (#fragment / vmess ps); use the row remark
when set. Pass remark from the client form for single external links.

Fixes #6032
This commit is contained in:
H-TTTTT
2026-07-21 21:50:33 +08:00
committed by GitHub
parent c80e5e276b
commit 11f602fe04
3 changed files with 85 additions and 6 deletions
+29
View File
@@ -98,6 +98,35 @@ func TestExpandEntryLinkAppliesRemark(t *testing.T) {
}
}
func TestExpandEntryLinkFallsBackToOriginalName(t *testing.T) {
got := expandEntry(externalLinkEntry{Kind: model.ExternalLinkKindLink, Value: "trojan://pw@b.com:8443#orig", Remark: ""})
if len(got) != 1 || got[0].Name != "orig" {
t.Fatalf("expandEntry empty remark = %#v, want Name=orig", got)
}
}
func TestLinkDisplayName(t *testing.T) {
payload := map[string]any{"v": "2", "ps": "NL-Node", "add": "1.2.3.4", "port": "443", "id": "uuid"}
b, _ := json.Marshal(payload)
vmess := "vmess://" + base64.StdEncoding.EncodeToString(b)
cases := []struct {
link string
want string
}{
{"vless://uuid@a.com:443#one", "one"},
{"trojan://pw@b.com:8443#" + url.PathEscape("DE Node"), "DE Node"},
{vmess, "NL-Node"},
{"ss://def", ""},
{"", ""},
}
for _, c := range cases {
if got := linkDisplayName(c.link); got != c.want {
t.Errorf("linkDisplayName(%q) = %q, want %q", c.link, got, c.want)
}
}
}
func TestClashProxyFromExternalTrojanReality(t *testing.T) {
link := "trojan://provider-pass@37.27.201.56:8443?type=tcp&security=reality&sni=aws.amazon.com&pbk=PBK&sid=298b44&fp=chrome#srv"
svc := NewSubClashService(false, "", NewSubService(""))