diff --git a/app/controllers/settings/sharing_controller.rb b/app/controllers/settings/sharing_controller.rb index a92bd364..76a7ca76 100644 --- a/app/controllers/settings/sharing_controller.rb +++ b/app/controllers/settings/sharing_controller.rb @@ -10,10 +10,11 @@ class Settings::SharingController < ApplicationController :sharing_autoclose, :sharing_custom_url) if current_user.update(user_attributes) - flash[:success] = t(".success") + flash.now[:success] = t(".success") else - flash[:error] = t(".error") + flash.now[:error] = t(".error") end - redirect_to settings_sharing_path + + render :edit end end diff --git a/app/models/user.rb b/app/models/user.rb index 7a57479d..6370ed01 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -61,7 +61,7 @@ class User < ApplicationRecord # rubocop:disable Metrics/ClassLength end validates :email, fake_email: true, typoed_email: true - validates :sharing_custom_url, format: URI::DEFAULT_PARSER.make_regexp(%w[http https]), allow_blank: true + validates :sharing_custom_url, allow_blank: true, valid_url: true validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX, message: I18n.t("activerecord.validation.user.screen_name.format") }, diff --git a/app/validators/valid_url_validator.rb b/app/validators/valid_url_validator.rb new file mode 100644 index 00000000..0d29426c --- /dev/null +++ b/app/validators/valid_url_validator.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class ValidUrlValidator < ActiveModel::EachValidator + URI_REGEXP = URI::DEFAULT_PARSER.make_regexp(%w[http https]).freeze + + def validate_each(record, attribute, value) + return if valid?(value) + + record.errors.add(attribute, :invalid_url) + end + + def valid?(value) + return false unless URI_REGEXP.match?(value) + + URI.parse(value) # raises URI::InvalidURIError + + true + rescue URI::InvalidURIError + false + end +end diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index c8066090..d7a879ae 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -104,6 +104,9 @@ en: user: screen_name: format: "contains invalid characters" + errors: + messages: + invalid_url: "does not look like a valid URL" helpers: submit: user: diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 3263fa86..01d3fc47 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -63,6 +63,8 @@ RSpec.describe User, type: :model do include_examples "valid url", "http://insecurebutvalid.business/" include_examples "invalid url", "ftp://fileprotocols.cool/" include_examples "invalid url", "notevenanurl" + include_examples "invalid url", %(https://richtig oarger shice) # passes the regexp, but trips up URI.parse + include_examples "invalid url", %(https://österreich.gv.at) # needs to be ASCII end describe "email validation" do