0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-04 10:39:43 +08:00
discourse/lib/validators/url_validator.rb
Chris Alberti bee83c8e98
FIX: Support uppercase in User Profile Website URL (#42072)
Don't prepend http:// to the beginning of user profile website if it has
a scheme but the scheme contains uppercase letters.

A user reported an error when saving their profile which turned out to
be due to the website in their profile being set to a URL starting with
"Https://".

Previously, there was a case-sensitive regex checking if the URL started
with "http" and otherwise prepending "http://", so a URL starting with
"Https://..." would become "http://Https://" and eventually fail the URL
validator. This PR changes that logic to instead parse the URL, check if
it has a scheme, and only prepend "http://" in the case where there's no
scheme.

It also fixes a small bug in the URL validator handling cases where
`URI.parse()` and the fallback to `UrlHelper.encode()` both fail. I
moved the exception handler into that method, where previously we were
rescuing it at the end of `UserUpdater.update()` and failing to produce
a proper error message.

Meta ref: /t/408630
2026-07-28 09:27:03 -05:00

26 lines
707 B
Ruby
Vendored

# frozen_string_literal: true
class UrlValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value.present?
valid =
begin
uri = URI.parse(value)
uri.is_a?(URI::HTTP) && !uri.host.nil? && uri.host.include?(".")
rescue URI::Error => e
if (e.message =~ /URI must be ascii only/)
begin
value = UrlHelper.encode(value)
retry
rescue Addressable::URI::InvalidURIError
false
end
end
end
unless valid
record.errors.add(attribute, options[:message] || I18n.t("errors.messages.invalid"))
end
end
end
end