mirror of
https://github.com/tinyauthapp/tinyauth.git
synced 2026-09-06 14:23:36 +08:00
fix: no need for idna conversion in domain validator
This commit is contained in:
@@ -38,7 +38,16 @@ func SafeParseAppURL(str string) (string, error) {
|
|||||||
return "", fmt.Errorf("ip addresses not allowed")
|
return "", fmt.Errorf("ip addresses not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
hostname, err = idna.Lookup.ToASCII(hostname)
|
i := idna.New(
|
||||||
|
idna.MapForLookup(),
|
||||||
|
idna.Transitional(false),
|
||||||
|
idna.BidiRule(),
|
||||||
|
idna.StrictDomainName(false),
|
||||||
|
idna.CheckHyphens(true),
|
||||||
|
idna.CheckJoiners(false),
|
||||||
|
)
|
||||||
|
|
||||||
|
hostname, err = i.ToASCII(hostname)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to convert hostname to ascii: %w", err)
|
return "", fmt.Errorf("failed to convert hostname to ascii: %w", err)
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ func TestSafeParseAPPURL(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expected, result)
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
|
// Underscores
|
||||||
|
appURL = "http://sub_tinyauth.app"
|
||||||
|
expected = "http://sub_tinyauth.app"
|
||||||
|
result, err = utils.SafeParseAppURL(appURL)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, expected, result)
|
||||||
|
|
||||||
// Lowercase
|
// Lowercase
|
||||||
appURL = "HTTP://SUb.tinyAUth.aPP"
|
appURL = "HTTP://SUb.tinyAUth.aPP"
|
||||||
expected = "http://sub.tinyauth.app"
|
expected = "http://sub.tinyauth.app"
|
||||||
@@ -66,7 +73,7 @@ func TestSafeParseAPPURL(t *testing.T) {
|
|||||||
assert.ErrorContains(t, err, "invalid url")
|
assert.ErrorContains(t, err, "invalid url")
|
||||||
|
|
||||||
// Invalid punycode
|
// Invalid punycode
|
||||||
appURL = "http://ab--cd.example.com"
|
appURL = "http://xn--h-kva.example.com"
|
||||||
_, err = utils.SafeParseAppURL(appURL)
|
_, err = utils.SafeParseAppURL(appURL)
|
||||||
assert.ErrorContains(t, err, "failed to convert hostname to ascii")
|
assert.ErrorContains(t, err, "failed to convert hostname to ascii")
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/net/idna"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
@@ -114,23 +112,11 @@ func (v *DomainValidator) getURL(i string) (*url.URL, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *DomainValidator) getHostname(hostname string) (string, error) {
|
func (v *DomainValidator) getHostname(hostname string) (string, error) {
|
||||||
hostname = strings.ToLower(hostname)
|
|
||||||
hostname = strings.TrimSuffix(hostname, ".")
|
|
||||||
if net.ParseIP(hostname) != nil {
|
if net.ParseIP(hostname) != nil {
|
||||||
return "", fmt.Errorf("ip addresses are not supported")
|
return "", fmt.Errorf("ip addresses are not supported")
|
||||||
}
|
}
|
||||||
i := idna.New(
|
hostname = strings.ToLower(hostname)
|
||||||
idna.MapForLookup(),
|
hostname = strings.TrimSuffix(hostname, ".")
|
||||||
idna.Transitional(false),
|
|
||||||
idna.BidiRule(),
|
|
||||||
idna.StrictDomainName(false),
|
|
||||||
idna.CheckHyphens(false),
|
|
||||||
idna.CheckJoiners(false),
|
|
||||||
)
|
|
||||||
hostname, err := i.ToASCII(hostname)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to convert hostname to ascii: %w", err)
|
|
||||||
}
|
|
||||||
return hostname, nil
|
return hostname, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,16 +50,6 @@ func TestDomainValidator_SafeHostname(t *testing.T) {
|
|||||||
input: "https://example.com",
|
input: "https://example.com",
|
||||||
expected: "example.com",
|
expected: "example.com",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "Domain with underscores should pass",
|
|
||||||
input: "https://my_domain.com",
|
|
||||||
expected: "my_domain.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Domain with leading hyphen should pass",
|
|
||||||
input: "https://-my-domain.com",
|
|
||||||
expected: "-my-domain.com",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "Domain without scheme should parse if scheme is disabled",
|
description: "Domain without scheme should parse if scheme is disabled",
|
||||||
input: "example.com",
|
input: "example.com",
|
||||||
@@ -111,18 +101,6 @@ func TestDomainValidator_SafeHostname(t *testing.T) {
|
|||||||
assert.ErrorContains(t, e, "ip addresses are not supported")
|
assert.ErrorContains(t, e, "ip addresses are not supported")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "Domains with unicode characters should be allowed",
|
|
||||||
input: "bücher.example.com",
|
|
||||||
expected: "xn--bcher-kva.example.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Invalid IDNA domain should fail",
|
|
||||||
input: "xn--r-kva.example.com",
|
|
||||||
errorFunc: func(t *testing.T, e error) {
|
|
||||||
assert.ErrorContains(t, e, "invalid label")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "With port enabled without any port should work",
|
description: "With port enabled without any port should work",
|
||||||
options: DomainValidatorOptions{WithPort: true},
|
options: DomainValidatorOptions{WithPort: true},
|
||||||
@@ -204,22 +182,6 @@ func TestDomainValidator_Validate(t *testing.T) {
|
|||||||
expected: "https://example.com:443",
|
expected: "https://example.com:443",
|
||||||
actual: "https://example.com:443",
|
actual: "https://example.com:443",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "Failure to format expected domain should fail",
|
|
||||||
expected: "xn--r-kva.example.com",
|
|
||||||
actual: "example.com",
|
|
||||||
errorFunc: func(t *testing.T, e error) {
|
|
||||||
assert.ErrorContains(t, e, "idna: invalid label")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Failure to format check domain should fail",
|
|
||||||
expected: "example.com",
|
|
||||||
actual: "xn--r-kva.example.com",
|
|
||||||
errorFunc: func(t *testing.T, e error) {
|
|
||||||
assert.ErrorContains(t, e, "idna: invalid label")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "Valid domains with matching schemes and ports should pass",
|
description: "Valid domains with matching schemes and ports should pass",
|
||||||
options: DomainValidatorOptions{WithScheme: true, AllowedSchemes: []string{"https", "http"}, WithPort: true},
|
options: DomainValidatorOptions{WithScheme: true, AllowedSchemes: []string{"https", "http"}, WithPort: true},
|
||||||
@@ -246,16 +208,6 @@ func TestDomainValidator_Validate(t *testing.T) {
|
|||||||
actual: "example.com",
|
actual: "example.com",
|
||||||
expected: "example.com",
|
expected: "example.com",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "Unicode valid domains should pass",
|
|
||||||
expected: "xn--bcher-kva.example.com",
|
|
||||||
actual: "bücher.example.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "Unicode valid domains should pass (reverse)",
|
|
||||||
expected: "bücher.example.com",
|
|
||||||
actual: "xn--bcher-kva.example.com",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "Non matching hostnames should fail",
|
description: "Non matching hostnames should fail",
|
||||||
expected: "example.com",
|
expected: "example.com",
|
||||||
|
|||||||
Reference in New Issue
Block a user