(ctx *ValidationContext, websiteURL string)
| 151 | } |
| 152 | |
| 153 | func validateWebsiteURL(ctx *ValidationContext, websiteURL string) *ValidationResult { |
| 154 | result := &ValidationResult{Valid: true, Issues: []ValidationIssue{}} |
| 155 | |
| 156 | // Skip validation if website URL is not provided (optional field) |
| 157 | if websiteURL == "" { |
| 158 | return result |
| 159 | } |
| 160 | |
| 161 | // Parse the URL to ensure it's valid |
| 162 | parsedURL, err := url.Parse(websiteURL) |
| 163 | if err != nil { |
| 164 | issue := NewValidationIssueFromError( |
| 165 | ValidationIssueTypeSemantic, |
| 166 | ctx.String(), |
| 167 | fmt.Errorf("invalid websiteUrl: %w", err), |
| 168 | "invalid-website-url", |
| 169 | ) |
| 170 | result.AddIssue(issue) |
| 171 | return result |
| 172 | } |
| 173 | |
| 174 | // Ensure it's an absolute URL with valid scheme |
| 175 | if !parsedURL.IsAbs() { |
| 176 | issue := NewValidationIssue( |
| 177 | ValidationIssueTypeSemantic, |
| 178 | ctx.String(), |
| 179 | fmt.Sprintf("websiteUrl must be absolute (include scheme): %s", websiteURL), |
| 180 | ValidationIssueSeverityError, |
| 181 | "website-url-must-be-absolute", |
| 182 | ) |
| 183 | result.AddIssue(issue) |
| 184 | } |
| 185 | |
| 186 | // Only allow HTTPS scheme for security |
| 187 | if parsedURL.Scheme != SchemeHTTPS { |
| 188 | issue := NewValidationIssue( |
| 189 | ValidationIssueTypeSemantic, |
| 190 | ctx.String(), |
| 191 | fmt.Sprintf("websiteUrl must use https scheme: %s", websiteURL), |
| 192 | ValidationIssueSeverityError, |
| 193 | "website-url-invalid-scheme", |
| 194 | ) |
| 195 | result.AddIssue(issue) |
| 196 | } |
| 197 | |
| 198 | // Reject characters that aren't valid in a URI per RFC 3986 and that have |
| 199 | // caused rendering issues when websiteUrl flows into the catalogue UI's |
| 200 | // href attributes. Publishers should percent-encode these in the source URL. |
| 201 | if i := strings.IndexAny(websiteURL, "\"'<> \t\n\r"); i >= 0 { |
| 202 | issue := NewValidationIssue( |
| 203 | ValidationIssueTypeSemantic, |
| 204 | ctx.String(), |
| 205 | fmt.Sprintf("websiteUrl contains an invalid character %q at position %d: %s", websiteURL[i], i, websiteURL), |
| 206 | ValidationIssueSeverityError, |
| 207 | "website-url-invalid-characters", |
| 208 | ) |
| 209 | result.AddIssue(issue) |
| 210 | } |
no test coverage detected
searching dependent graphs…