diff --git a/app/models/concerns/email_verifable.rb b/app/models/concerns/email_verifable.rb index 1da52dcf3..f24c37934 100644 --- a/app/models/concerns/email_verifable.rb +++ b/app/models/concerns/email_verifable.rb @@ -1,15 +1,20 @@ module EmailVerifable extend ActiveSupport::Concern + included do + has_many :email_address_verifications, as: :email_verifable + end + def email_verification - EmailAddressVerification.find_or_create_by(email: unicode_email, domain: domain(email)) + # EmailAddressVerification.find_or_create_by(email: unicode_email, domain: domain(email)) + email_address_verification end def billing_email_verification - return unless attribute_names.include?('billing_email') - - EmailAddressVerification.find_or_create_by(email: unicode_billing_email, - domain: domain(billing_email)) + # return unless attribute_names.include?('billing_email') + # + # EmailAddressVerification.find_or_create_by(email: unicode_billing_email, + # domain: domain(billing_email)) end def email_verification_failed? diff --git a/app/models/contact.rb b/app/models/contact.rb index f33c22c74..eebb1ccd5 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -25,8 +25,8 @@ class Contact < ApplicationRecord alias_attribute :copy_from_id, :original_id # Old attribute name; for PaperTrail scope :email_verification_failed, lambda { - joins('LEFT JOIN email_address_verifications emv ON contacts.email = emv.email') - .where('success = false and verified_at IS NOT NULL') + # joins('LEFT JOIN email_address_verifications emv ON contacts.email = emv.email') + # .where('success = false and verified_at IS NOT NULL') } NAME_REGEXP = /([\u00A1-\u00B3\u00B5-\u00BF\u0021-\u0026\u0028-\u002C\u003A-\u0040]| diff --git a/app/models/email_address_verification.rb b/app/models/email_address_verification.rb index 4eba0f3e9..cf207a7c2 100644 --- a/app/models/email_address_verification.rb +++ b/app/models/email_address_verification.rb @@ -1,50 +1,15 @@ class EmailAddressVerification < ApplicationRecord - RECENTLY_VERIFIED_PERIOD = 1.month - after_save :check_force_delete + belongs_to :email_verifable, polymorphic: true - scope :not_verified_recently, lambda { - where('verified_at IS NULL or verified_at < ?', verification_period) - } + RECENTLY_VERIFIED_PERIOD = 1.year.freeze + SCAN_CYCLES = 3.freeze + # after_save :check_force_delete - scope :verified_recently, lambda { - where('verified_at IS NOT NULL and verified_at >= ?', verification_period).where(success: true) - } scope :verification_failed, lambda { where.not(verified_at: nil).where(success: false) } - scope :by_domain, ->(domain_name) { where(domain: domain_name) } - - def recently_verified? - verified_at.present? && - verified_at > verification_period - end - - def verification_period - self.class.verification_period - end - - def self.verification_period - Time.zone.now - RECENTLY_VERIFIED_PERIOD - end - - def not_verified? - verified_at.blank? && !success - end - - def failed? - bounce_present? || (verified_at.present? && !success) - end - - def verified? - success - end - - def bounce_present? - BouncedMailAddress.find_by(email: email).present? - end - def check_force_delete return unless failed? diff --git a/db/migrate/20210628090353_add_polymorphic_relation_to_email_address_verification.rb b/db/migrate/20210628090353_add_polymorphic_relation_to_email_address_verification.rb new file mode 100644 index 000000000..5d2d8defa --- /dev/null +++ b/db/migrate/20210628090353_add_polymorphic_relation_to_email_address_verification.rb @@ -0,0 +1,31 @@ +class AddPolymorphicRelationToEmailAddressVerification < ActiveRecord::Migration[6.1] + def change + remove_column :email_address_verifications, :email, :string + remove_column :email_address_verifications, :success, :boolean + remove_column :email_address_verifications, :domain, :string + + change_table 'email_address_verifications' do |t| + t.references :email_verifable, polymorphic: true + t.jsonb :result + t.integer :times_scanned + end + + reversible do |change| + change.up do + EmailAddressVerification.destroy_all + + execute <<-SQL + CREATE TYPE email_verification_type AS ENUM ('regex', 'mx', 'smtp'); + SQL + + add_column :email_address_verifications, :type, :email_verification_type + end + + change.down do + execute <<-SQL + DROP TYPE email_verification_type; + SQL + end + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 54d740fa5..a6ecff82f 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -65,6 +65,17 @@ CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public; COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions'; +-- +-- Name: email_verification_type; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public.email_verification_type AS ENUM ( + 'regex', + 'mx', + 'smtp' +); + + -- -- Name: generate_zonefile(character varying); Type: FUNCTION; Schema: public; Owner: - -- @@ -963,10 +974,12 @@ ALTER SEQUENCE public.domains_id_seq OWNED BY public.domains.id; CREATE TABLE public.email_address_verifications ( id bigint NOT NULL, - email public.citext NOT NULL, verified_at timestamp without time zone, - success boolean DEFAULT false NOT NULL, - domain public.citext NOT NULL + email_verifable_type character varying, + email_verifable_id bigint, + result jsonb, + times_scanned integer, + type public.email_verification_type ); @@ -3986,13 +3999,6 @@ CREATE INDEX index_domain_transfers_on_domain_id ON public.domain_transfers USIN CREATE INDEX index_domains_on_delete_date ON public.domains USING btree (delete_date); --- --- Name: index_domains_on_json_statuses_history; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_domains_on_json_statuses_history ON public.domains USING gin (json_statuses_history); - - -- -- Name: index_domains_on_name; Type: INDEX; Schema: public; Owner: - -- @@ -4043,10 +4049,10 @@ CREATE INDEX index_domains_on_statuses ON public.domains USING gin (statuses); -- --- Name: index_email_address_verifications_on_domain; Type: INDEX; Schema: public; Owner: - +-- Name: index_email_address_verifications_on_email_verifable; Type: INDEX; Schema: public; Owner: - -- -CREATE INDEX index_email_address_verifications_on_domain ON public.email_address_verifications USING btree (domain); +CREATE INDEX index_email_address_verifications_on_email_verifable ON public.email_address_verifications USING btree (email_verifable_type, email_verifable_id); -- @@ -5161,6 +5167,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200921084356'), ('20210215101019'), ('20210616112332'), +('20210628090353'), ('20210708131814'); diff --git a/lib/tasks/verify_email.rake b/lib/tasks/verify_email.rake index daffabf19..027e111a9 100644 --- a/lib/tasks/verify_email.rake +++ b/lib/tasks/verify_email.rake @@ -1,12 +1,12 @@ namespace :verify_email do desc 'Stars verifying email jobs for all the domain' task all_domains: :environment do - verifications_by_domain = EmailAddressVerification.not_verified_recently.group_by(&:domain) - verifications_by_domain.each do |_domain, verifications| - ver = verifications.sample # Verify random email to not to clog the SMTP servers - VerifyEmailsJob.perform_later(ver.id) - next - end + # verifications_by_domain = EmailAddressVerification.not_verified_recently.group_by(&:domain) + # verifications_by_domain.each do |_domain, verifications| + # ver = verifications.sample # Verify random email to not to clog the SMTP servers + # VerifyEmailsJob.perform_later(ver.id) + # next + # end end # Need to be run like 'bundle exec rake verify_email:domain['gmail.com']' @@ -16,8 +16,8 @@ namespace :verify_email do task :domain, [:domain_name] => [:environment] do |_task, args| args.with_defaults(domain_name: 'internet.ee') - verifications_by_domain = EmailAddressVerification.not_verified_recently - .by_domain(args[:domain_name]) - verifications_by_domain.map { |ver| VerifyEmailsJob.perform_later(ver.id) } + # verifications_by_domain = EmailAddressVerification.not_verified_recently + # .by_domain(args[:domain_name]) + # verifications_by_domain.map { |ver| VerifyEmailsJob.perform_later(ver.id) } end end