Handle cookie banner origin validation + unicity

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-04-13 16:31:08 +04:00
parent 0ce1d8039a
commit d05c3591d3
6 changed files with 124 additions and 6 deletions

View File

@@ -133,6 +133,49 @@ func GID(entityTypes ...uint16) ValidatorFunc {
}
}
// Origin validates that a string is a valid web origin (scheme + host + optional port).
// No path, query, fragment, or userinfo is allowed.
func Origin() ValidatorFunc {
return func(value any) *ValidationError {
actualValue, isNil := dereferenceValue(value)
if isNil {
return nil
}
str, ok := actualValue.(string)
if !ok {
return newValidationError(ErrorCodeInvalidFormat, "value must be a string")
}
if str == "" {
return nil
}
parsedURL, err := url.Parse(str)
if err != nil {
return newValidationError(ErrorCodeInvalidFormat, "must be a valid origin (e.g. https://example.com)")
}
if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
return newValidationError(ErrorCodeInvalidFormat, "must be a valid origin (e.g. https://example.com)")
}
if parsedURL.Host == "" {
return newValidationError(ErrorCodeInvalidFormat, "must be a valid origin (e.g. https://example.com)")
}
if parsedURL.Path != "" && parsedURL.Path != "/" {
return newValidationError(ErrorCodeInvalidFormat, "must be a valid origin (e.g. https://example.com)")
}
if parsedURL.RawQuery != "" || parsedURL.Fragment != "" || parsedURL.User != nil {
return newValidationError(ErrorCodeInvalidFormat, "must be a valid origin (e.g. https://example.com)")
}
return nil
}
}
// Domain validates that a string is a valid domain name.
func Domain() ValidatorFunc {
return func(value any) *ValidationError {