API for updating attribution domains (#32730)

This commit is contained in:
Christian Schmidt 2025-01-17 09:18:55 +01:00 committed by GitHub
parent 3af6739f21
commit a3baae0b99
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
108 changed files with 141 additions and 251 deletions

View file

@ -33,6 +33,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
:discoverable,
:hide_collections,
:indexable,
attribution_domains: [],
fields_attributes: [:name, :value]
)
end

View file

@ -18,7 +18,9 @@ class Settings::VerificationsController < Settings::BaseController
private
def account_params
params.require(:account).permit(:attribution_domains_as_text)
params.require(:account).permit(:attribution_domains).tap do |params|
params[:attribution_domains] = params[:attribution_domains].split if params[:attribution_domains]
end
end
def set_account

View file

@ -4,21 +4,9 @@ module Account::AttributionDomains
extend ActiveSupport::Concern
included do
validates :attribution_domains_as_text, domain: { multiline: true }, lines: { maximum: 100 }, if: -> { local? && will_save_change_to_attribution_domains? }
end
normalizes :attribution_domains, with: ->(arr) { arr.filter_map { |str| str.to_s.strip.delete_prefix('http://').delete_prefix('https://').delete_prefix('*.').presence }.uniq }
def attribution_domains_as_text
self[:attribution_domains].join("\n")
end
def attribution_domains_as_text=(str)
self[:attribution_domains] = str.split.filter_map do |line|
line
.strip
.delete_prefix('http://')
.delete_prefix('https://')
.delete_prefix('*.')
end
validates :attribution_domains, domain: true, length: { maximum: 100 }, if: -> { local? && will_save_change_to_attribution_domains? }
end
def can_be_attributed_from?(domain)

View file

@ -18,6 +18,7 @@ class REST::CredentialAccountSerializer < REST::AccountSerializer
hide_collections: object.hide_collections,
discoverable: object.discoverable,
indexable: object.indexable,
attribution_domains: object.attribution_domains,
}
end

View file

@ -9,18 +9,21 @@ class DomainValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.blank?
(options[:multiline] ? value.split : [value]).each do |domain|
_, domain = domain.split('@') if options[:acct]
Array.wrap(value).each do |domain|
if options[:acct]
_, domain = domain.split('@')
next if domain.blank?
end
next if domain.blank?
record.errors.add(attribute, options[:multiline] ? :invalid_domain_on_line : :invalid, value: domain) unless compliant?(domain)
record.errors.add(attribute, value.is_a?(Enumerable) ? :invalid_domain_on_line : :invalid, value: domain) unless compliant?(domain)
end
end
private
def compliant?(value)
return false if value.blank?
uri = Addressable::URI.new
uri.host = value
uri.normalized_host.size < MAX_DOMAIN_LENGTH && uri.normalized_host.split('.').all? { |label| label.size.between?(MIN_LABEL_LENGTH, MAX_LABEL_LENGTH) && label =~ ALLOWED_CHARACTERS_RE }

View file

@ -1,9 +0,0 @@
# frozen_string_literal: true
class LinesValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.blank?
record.errors.add(attribute, :too_many_lines, limit: options[:maximum]) if options[:maximum].present? && value.split.size > options[:maximum]
end
end

View file

@ -65,7 +65,7 @@
%p.lead= t('author_attribution.then_instructions')
.fields-group
= f.input :attribution_domains_as_text, as: :text, wrapper: :with_block_label, input_html: { placeholder: "example1.com\nexample2.com\nexample3.com", rows: 4, autocapitalize: 'none', autocorrect: 'off' }
= f.input :attribution_domains, as: :text, wrapper: :with_block_label, input_html: { value: @account.attribution_domains.join("\n"), placeholder: "example1.com\nexample2.com\nexample3.com", rows: 4, autocapitalize: 'none', autocorrect: 'off' }
.actions
= f.button :button, t('generic.save_changes'), type: :submit