discourse/app/models/user_field.rb
Matt Marjanović aa4ff47208
FEATURE: Allow target attribute in links in user_field descriptions (#19102)
This change adds `target` to the set of attributes allowed by the
HTML sanitizer which is applied to the description of a user_field.

The rationale for this change:

 * If one puts a link (<a>...</a>) in the description of a user_field
   that is present and/or required at sign-up, the expectation is that
   a prospective new user will click on that link during sign-up.
 * Without an appropriate `target` attribute on the link, the new page
   will be loaded in the same window/tab as the sign-up form, but this
   will obliterate any fields that the user had already filled-out on
   the form.  (E.g., hitting the back-button will return to an
   empty form.)
 * Such UX behavior is incredibly aggravating to new users.

This change allows an admin to add a `target` attribute to links, to
instruct the browser to open them in a different window/tab, leaving
a sign-up form intact.
2023-01-06 10:18:35 -03:00

55 lines
1.7 KiB
Ruby

# frozen_string_literal: true
class UserField < ActiveRecord::Base
include AnonCacheInvalidator
include HasSanitizableFields
validates_presence_of :description, :field_type
validates_presence_of :name, unless: -> { field_type == "confirm" }
has_many :user_field_options, dependent: :destroy
has_one :directory_column, dependent: :destroy
accepts_nested_attributes_for :user_field_options
before_save :sanitize_description
after_save :queue_index_search
scope :public_fields, -> { where(show_on_profile: true).or(where(show_on_user_card: true)) }
def self.max_length
2048
end
def queue_index_search
SearchIndexer.queue_users_reindex(UserCustomField.where(name: "user_field_#{self.id}").pluck(:user_id))
end
private
def sanitize_description
if description_changed?
self.description = sanitize_field(self.description, additional_attributes: ['target'])
end
end
end
# == Schema Information
#
# Table name: user_fields
#
# id :integer not null, primary key
# name :string not null
# field_type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# editable :boolean default(FALSE), not null
# description :string not null
# required :boolean default(TRUE), not null
# show_on_profile :boolean default(FALSE), not null
# position :integer default(0)
# show_on_user_card :boolean default(FALSE), not null
# external_name :string
# external_type :string
# searchable :boolean default(FALSE), not null
#