81 lines
1.9 KiB
Ruby
81 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class EmailAddress < ApplicationRecord
|
|
belongs_to :user, inverse_of: :email_address
|
|
|
|
validates :address, presence: true, confirmation: true, format: { with: EmailValidator::EMAIL_REGEX }
|
|
validates :normalized_address, uniqueness: true
|
|
validates :user_id, uniqueness: true
|
|
validate :validate_deliverable, on: :deliverable
|
|
|
|
def self.visible(user)
|
|
if user.is_moderator?
|
|
where(user: User.where("level < ?", user.level).or(User.where(id: user.id)))
|
|
else
|
|
none
|
|
end
|
|
end
|
|
|
|
def address=(value)
|
|
self.normalized_address = EmailValidator.normalize(value) || address
|
|
super
|
|
end
|
|
|
|
def is_restricted?
|
|
EmailValidator.is_restricted?(normalized_address)
|
|
end
|
|
|
|
def is_normalized?
|
|
address == normalized_address
|
|
end
|
|
|
|
def is_valid?
|
|
EmailValidator.is_valid?(address)
|
|
end
|
|
|
|
def self.restricted(restricted = true)
|
|
domains = EmailValidator::NONDISPOSABLE_DOMAINS
|
|
domain_regex = domains.map { |domain| Regexp.escape(domain) }.join("|")
|
|
|
|
if restricted.to_s.truthy?
|
|
where_not_regex(:normalized_address, "@(#{domain_regex})$")
|
|
elsif restricted.to_s.falsy?
|
|
where_regex(:normalized_address, "@(#{domain_regex})$")
|
|
else
|
|
all
|
|
end
|
|
end
|
|
|
|
def self.search(params)
|
|
q = search_attributes(params, :id, :created_at, :updated_at, :user, :address, :normalized_address, :is_verified, :is_deliverable)
|
|
|
|
q = q.restricted(params[:is_restricted])
|
|
|
|
q.apply_default_order(params)
|
|
end
|
|
|
|
def validate_deliverable
|
|
if EmailValidator.undeliverable?(address)
|
|
errors.add(:address, "is invalid or does not exist")
|
|
end
|
|
end
|
|
|
|
def verify!
|
|
transaction do
|
|
update!(is_verified: true)
|
|
|
|
if user.is_restricted? && !is_restricted?
|
|
user.update!(level: User::Levels::MEMBER, is_verified: is_verified?)
|
|
end
|
|
end
|
|
end
|
|
|
|
def verification_key
|
|
signed_id(purpose: "verify")
|
|
end
|
|
|
|
def self.available_includes
|
|
[:user]
|
|
end
|
|
end
|