package main import ( "strings" "testing" ) func TestParseAuthorizeURLAllowedOrigins(t *testing.T) { tests := []struct { name string api string expected string }{ {name: "localhost", api: "http%3A%2F%2Flocalhost", expected: "http://localhost"}, {name: "localhost trailing slash", api: "http%3A%2F%2Flocalhost%2F", expected: "http://localhost"}, {name: "lan address", api: "http%3A%2F%2F192.168.10.6", expected: "http://192.168.10.6"}, {name: "production ks.khhao.com", api: "https%3A%2F%2Fks.khhao.com", expected: "https://ks.khhao.com"}, {name: "production uppercase host", api: "https%3A%2F%2FKS.KHHAO.COM", expected: "https://ks.khhao.com"}, {name: "legacy production order.khhao.com", api: "https%3A%2F%2Forder.khhao.com", expected: "https://order.khhao.com"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { raw := "dcauth://authorize?app=order_site&challenge_id=challenge-id&challenge=challenge-value&api=" + tt.api target, err := parseAuthorizeURL(raw) if err != nil { t.Fatalf("parseAuthorizeURL() error = %v", err) } if target.APIBase != tt.expected { t.Fatalf("APIBase = %q, want %q", target.APIBase, tt.expected) } }) } } func TestParseAuthorizeURLRejectsUnknownOrigin(t *testing.T) { tests := []struct { name string api string }{ {name: "unknown host", api: "http%3A%2F%2Fexample.com"}, {name: "lookalike suffix", api: "https%3A%2F%2Fks.khhao.com.evil.com"}, {name: "lookalike prefix", api: "https%3A%2F%2Fevil-ks.khhao.com"}, {name: "unexpected port", api: "https%3A%2F%2Fks.khhao.com%3A8443"}, {name: "plain http production host", api: "http%3A%2F%2Fks.khhao.com"}, {name: "userinfo trick", api: "https%3A%2F%2Fks.khhao.com%40evil.com"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { raw := "dcauth://authorize?app=order_site&challenge_id=challenge-id&challenge=challenge-value&api=" + tt.api if _, err := parseAuthorizeURL(raw); err == nil { t.Fatalf("parseAuthorizeURL() accepted %q", tt.api) } }) } } func TestBuildAuthorizationCanonicalUsesDeviceCodeOnly(t *testing.T) { id := identity{deviceID: "D1-ABCD-EFGH-JKLM-NPQR"} target := authorizeTarget{ App: "order_site", ChallengeID: "challenge-id", Challenge: "challenge-value", } got := buildAuthorizationCanonical(id, target, 1700000000) want := "dcauth.v2\norder_site\nchallenge-id\nchallenge-value\nD1-ABCD-EFGH-JKLM-NPQR\n1700000000" if got != want { t.Fatalf("canonical = %q, want %q", got, want) } if strings.Contains(got, "M1-") || strings.Contains(strings.ToLower(got), "machine") { t.Fatalf("canonical still contains machine code data: %q", got) } }