Panel redesign, per-server I1 masking, node minimum version 0.5.0, installer output
ci / check (push) Successful in 23m54s
ci / check (push) Successful in 23m54s
- UI: settings tab with sections (server, API keys, Prometheus, audit, migrate, about); server settings moved there; master keys table rework (menu, chips, version, compact phone cards); three-state node version chip - I1: random per-server template (DNS / QUIC Initial / STUN) kept in users.db, GET/POST /api/masking, change from the master keys banner - Hub rejects nodes older than 0.5.0 (close 4026), /ui/nodes reports outdated - install.sh: spinner for long commands (full output in the log), step progress bar, cards; installs older than 0.5.0 require a full reinstall with data reset - Bump to Beta 0.5.0
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package ctrl
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGenI1Templates(t *testing.T) {
|
||||
seen := map[string]bool{}
|
||||
for i := 0; i < 500; i++ {
|
||||
v := GenI1()
|
||||
b, ok := i1Bytes(v)
|
||||
if !ok {
|
||||
t.Fatalf("шаблон не разбирается: %q", v)
|
||||
}
|
||||
kind, label := DescribeI1(v)
|
||||
seen[kind] = true
|
||||
switch kind {
|
||||
case "dns":
|
||||
if !strings.HasPrefix(v, "<r 2>") || !strings.HasPrefix(label, "DNS-запрос к ") {
|
||||
t.Fatalf("DNS: %q → %q", v, label)
|
||||
}
|
||||
case "quic":
|
||||
if n := len(b); n != 1200 && n != 1250 && n != 1252 {
|
||||
t.Fatalf("QUIC длиной %d: %q", n, v)
|
||||
}
|
||||
case "stun":
|
||||
if len(b) != 20 && len(b) != 28 {
|
||||
t.Fatalf("STUN длиной %d: %q", len(b), v)
|
||||
}
|
||||
default:
|
||||
t.Fatalf("неожиданный вид %q: %q", kind, v)
|
||||
}
|
||||
// Только <b>/<r>, без пробелов вне тегов — так I1 пишут и клиенты AmneziaVPN.
|
||||
if strings.Contains(strings.NewReplacer("<b ", "", "<r ", "").Replace(v), " ") {
|
||||
t.Fatalf("лишние пробелы: %q", v)
|
||||
}
|
||||
}
|
||||
for _, k := range []string{"dns", "quic", "stun"} {
|
||||
if !seen[k] {
|
||||
t.Fatalf("шаблон %s ни разу не выпал", k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDescribeI1(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
DefaultParams().I1: "DNS-ответ от icloud.com",
|
||||
"": "без маскировки",
|
||||
"<c><t>": "свой шаблон",
|
||||
"<b 0xdeadbeef>": "свой шаблон",
|
||||
}
|
||||
for in, want := range cases {
|
||||
if _, got := DescribeI1(in); got != want {
|
||||
t.Errorf("DescribeI1(%q) = %q, want %q", in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user