diff options
Diffstat (limited to 'app/models/user.rb')
-rw-r--r-- | app/models/user.rb | 76 |
1 files changed, 67 insertions, 9 deletions
diff --git a/app/models/user.rb b/app/models/user.rb index 3dcfd820e..167bfd605 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -42,6 +42,8 @@ # sign_in_token_sent_at :datetime # webauthn_id :string # sign_up_ip :inet +# username :string +# kobold :string # class User < ApplicationRecord @@ -90,7 +92,7 @@ class User < ApplicationRecord validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create scope :recent, -> { order(id: :desc) } - scope :pending, -> { where(approved: false) } + scope :pending, -> { where(approved: false).where.not(kobold: '') } scope :approved, -> { where(approved: true) } scope :confirmed, -> { where.not(confirmed_at: nil) } scope :enabled, -> { where(disabled: false) } @@ -100,6 +102,7 @@ class User < ApplicationRecord scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) } scope :matches_ip, ->(value) { left_joins(:session_activations).where('users.current_sign_in_ip <<= ?', value).or(left_joins(:session_activations).where('users.sign_up_ip <<= ?', value)).or(left_joins(:session_activations).where('users.last_sign_in_ip <<= ?', value)).or(left_joins(:session_activations).where('session_activations.ip <<= ?', value)) } scope :emailable, -> { confirmed.enabled.joins(:account).merge(Account.searchable) } + scope :lower_username, ->(username) { where('lower(users.username) = lower(?)', username) } before_validation :sanitize_languages before_create :set_approved @@ -114,9 +117,15 @@ class User < ApplicationRecord delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :favourite_modal, :delete_modal, :reduce_motion, :system_font_ui, :noindex, :flavour, :skin, :display_media, :hide_network, :hide_followers_count, - :expand_spoilers, :default_language, :aggregate_reblogs, :show_application, + :expand_spoilers, :default_language, :show_application, :advanced_layout, :use_blurhash, :use_pending_items, :trends, :crop_images, :disable_swiping, :default_content_type, :system_emoji_font, + :manual_publish, :style_dashed_nest, :style_underline_a, :style_css_profile, + :style_css_profile_errors, :style_css_webapp, :style_css_webapp_errors, + :style_wide_media, :style_lowercase, + :publish_in, :unpublish_in, :unpublish_delete, :boost_every, :boost_jitter, + :boost_random, :unpublish_on_delete, :rss_disabled, :home_reblogs, + :filter_unknown, :max_history_public, :max_history_private, :web_push, to: :settings, prefix: :setting, allow_nil: false attr_reader :invite_code, :sign_in_token_attempt @@ -150,7 +159,7 @@ class User < ApplicationRecord if new_user && approved? prepare_new_user! - elsif new_user + elsif new_user && user_might_not_be_a_spam_bot notify_staff_about_pending_account! end end @@ -174,7 +183,7 @@ class User < ApplicationRecord end def suspicious_sign_in?(ip) - !otp_required_for_login? && current_sign_in_at.present? && current_sign_in_at < 2.weeks.ago && !recent_ip?(ip) + !otp_required_for_login? && current_sign_in_at.present? && current_sign_in_at < 12.weeks.ago && !recent_ip?(ip) end def functional? @@ -247,14 +256,26 @@ class User < ApplicationRecord @hides_network ||= settings.hide_network end - def aggregates_reblogs? - @aggregates_reblogs ||= settings.aggregate_reblogs - end - def shows_application? @shows_application ||= settings.show_application end + def home_reblogs? + @home_reblogs ||= settings.home_reblogs + end + + def filters_unknown? + @filters_unknown ||= settings.filter_unknown + end + + def max_history_private + @max_history_private ||= settings.max_history_private.to_i + end + + def max_history_public + @max_history_public ||= [settings.max_history_public.to_i, max_history_private].min + end + # rubocop:disable Naming/MethodParameterName def token_for_app(a) return nil if a.nil? || a.owner != self @@ -308,6 +329,17 @@ class User < ApplicationRecord super end + def send_confirmation_instructions + unless approved? || user_might_not_be_a_spam_bot + invite_request&.destroy + account&.destroy + destroy + return false + end + + super + end + def reset_password!(new_password, new_password_confirmation) return false if encrypted_password.blank? @@ -427,7 +459,7 @@ class User < ApplicationRecord def notify_staff_about_pending_account! User.staff.includes(:account).find_each do |u| - next unless u.allows_pending_account_emails? + next unless u.account.actor_type == 'Person' && u.allows_pending_account_emails? AdminMailer.new_pending_account(u.account, self).deliver_later end end @@ -445,4 +477,30 @@ class User < ApplicationRecord def validate_email_dns? email_changed? && !(Rails.env.test? || Rails.env.development?) end + + def user_might_not_be_a_spam_bot + return false unless username.downcase == account.username.downcase + + update(username: account.username) unless username == account.username + invited? || (invite_request&.text.present? && kobold_hash_matches?) + end + + def kobold_hash_matches? + kobold.present? && kobold == kobold_hash + end + + def kobold_hash + value = [account.username, username.downcase, email, invite_request.text.gsub(/\r\n?/, "\n")].compact.map(&:downcase).join("\u{F0666}") + Digest::SHA512.hexdigest(value).upcase + end + + class << self + def find_by_lower_username(username) + lower_username(username).first + end + + def find_by_lower_username!(username) + lower_username(username).first! + end + end end |