mirror of
https://github.com/discourse/discourse.git
synced 2026-08-04 10:39:43 +08:00
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
26 lines
707 B
Ruby
Vendored
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
|