From bc8e3c35dd9fc22ac815151d3618fba25c495f3c Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Fri, 24 May 2024 14:04:22 +0200 Subject: [PATCH 1/6] Feat(User): add email_verified_at column --- .../20240524120336_add_email_verified_at_column_to_users.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240524120336_add_email_verified_at_column_to_users.rb diff --git a/db/migrate/20240524120336_add_email_verified_at_column_to_users.rb b/db/migrate/20240524120336_add_email_verified_at_column_to_users.rb new file mode 100644 index 00000000000..176b9d2abcf --- /dev/null +++ b/db/migrate/20240524120336_add_email_verified_at_column_to_users.rb @@ -0,0 +1,5 @@ +class AddEmailVerifiedAtColumnToUsers < ActiveRecord::Migration[7.0] + def change + add_column :users, :email_verified_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 22ee0febd71..ff7db2e6039 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_04_17_053843) do +ActiveRecord::Schema[7.0].define(version: 2024_05_24_120336) do # These are extensions that must be enabled in order to support this database enable_extension "pg_buffercache" enable_extension "pg_stat_statements" @@ -1137,6 +1137,7 @@ t.datetime "current_sign_in_at", precision: nil t.string "current_sign_in_ip" t.string "email", default: "", null: false + t.datetime "email_verified_at" t.string "encrypted_password", default: "", null: false t.integer "failed_attempts", default: 0, null: false t.datetime "inactive_close_to_expiration_notice_sent_at" From 841c1cc8458dafdf56d22012e77489f7af4fe809 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Mon, 27 May 2024 09:59:48 +0200 Subject: [PATCH 2/6] Feat(user): verify user email during devise confirmation --- app/models/user.rb | 1 + spec/models/user_spec.rb | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/app/models/user.rb b/app/models/user.rb index 3a9aebfb2e2..f3e4f6b474b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -63,6 +63,7 @@ def send_confirmation_instructions # Callback provided by Devise def after_confirmation + update!(email_verified_at: Time.zone.now) link_invites! end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 336d7888616..958346a4787 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -16,6 +16,12 @@ user.confirm expect(user.reload.invites.size).to eq(2) end + + it 'verifies its email' do + expect(user.email_verified_at).to be_nil + user.confirm + expect(user.email_verified_at).to be_present + end end describe '#owns?' do From fa06d17169464488ecb70baa54d623aa51b6e12e Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Mon, 27 May 2024 10:01:14 +0200 Subject: [PATCH 3/6] Feat(user): set email_verified_at when setting confirmed_at --- app/models/user.rb | 4 ++-- db/seeds.rb | 3 ++- spec/models/france_connect_information_spec.rb | 1 + spec/models/user_spec.rb | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index f3e4f6b474b..d047ab1d1c8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -99,7 +99,7 @@ def remind_invitation! def self.create_or_promote_to_instructeur(email, password, administrateurs: []) user = User - .create_with(password: password, confirmed_at: Time.zone.now) + .create_with(password: password, confirmed_at: Time.zone.now, email_verified_at: Time.zone.now) .find_or_create_by(email: email) if user.valid? @@ -138,7 +138,7 @@ def self.create_or_promote_to_administrateur(email, password) def self.create_or_promote_to_expert(email, password) user = User - .create_with(password: password, confirmed_at: Time.zone.now) + .create_with(password: password, confirmed_at: Time.zone.now, email_verified_at: Time.zone.now) .find_or_create_by(email: email) if user.valid? diff --git a/db/seeds.rb b/db/seeds.rb index 52f97d02fd0..1a021ad233f 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -13,7 +13,8 @@ user = User.create!( email: default_user, password: default_password, - confirmed_at: Time.zone.now + confirmed_at: Time.zone.now, + email_verified_at: Time.zone.now ) user.create_instructeur! user.create_administrateur! diff --git a/spec/models/france_connect_information_spec.rb b/spec/models/france_connect_information_spec.rb index 621c729b3f1..1dcb149cca9 100644 --- a/spec/models/france_connect_information_spec.rb +++ b/spec/models/france_connect_information_spec.rb @@ -19,6 +19,7 @@ it do subject expect(fci.user.email).to eq('a@email.com') + expect(fci.user.email_verified_at).to be_present end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 958346a4787..409507d37a5 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -117,6 +117,7 @@ user = subject expect(user.valid_password?(password)).to be true expect(user.confirmed_at).to be_present + expect(user.email_verified_at).to be_present expect(user.instructeur).to be_present end @@ -190,6 +191,7 @@ user = subject expect(user.valid_password?(password)).to be true expect(user.confirmed_at).to be_present + expect(user.email_verified_at).to be_present expect(user.expert).to be_present end end @@ -220,6 +222,18 @@ end end + describe '.create_or_promote_to_gestionnaire' do + let(:email) { 'inst1@gmail.com' } + let(:password) { 'un super password !' } + + subject { User.create_or_promote_to_gestionnaire(email, password) } + + it 'verifies its email' do + user = subject + expect(user.email_verified_at).to be_present + end + end + describe 'invite_administrateur!' do let(:super_admin) { create(:super_admin) } let(:administrateur) { create(:administrateur) } From dbf6459b4b124eb8bb77603faa288085a75976a2 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Mon, 27 May 2024 11:08:14 +0200 Subject: [PATCH 4/6] feat(User): add email_verified_at column to individual (in case of mandant) --- ...0527090508_add_email_verified_at_column_to_individuals.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240527090508_add_email_verified_at_column_to_individuals.rb diff --git a/db/migrate/20240527090508_add_email_verified_at_column_to_individuals.rb b/db/migrate/20240527090508_add_email_verified_at_column_to_individuals.rb new file mode 100644 index 00000000000..b77aea27340 --- /dev/null +++ b/db/migrate/20240527090508_add_email_verified_at_column_to_individuals.rb @@ -0,0 +1,5 @@ +class AddEmailVerifiedAtColumnToIndividuals < ActiveRecord::Migration[7.0] + def change + add_column :individuals, :email_verified_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index ff7db2e6039..74b41f6c708 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_05_24_120336) do +ActiveRecord::Schema[7.0].define(version: 2024_05_27_090508) do # These are extensions that must be enabled in order to support this database enable_extension "pg_buffercache" enable_extension "pg_stat_statements" @@ -752,6 +752,7 @@ t.datetime "created_at", precision: nil t.integer "dossier_id" t.string "email" + t.datetime "email_verified_at" t.string "gender" t.string "nom" t.string "notification_method" From 1cf9535bea66b2e26573eeff8d0bd44acfbf9bf6 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Mon, 27 May 2024 11:22:52 +0200 Subject: [PATCH 5/6] feat(User): verify mandat email during creation --- app/controllers/users/dossiers_controller.rb | 2 ++ spec/controllers/users/dossiers_controller_spec.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index e6a64f2cd3f..592f16f2cd0 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -149,6 +149,8 @@ def update_identite @no_description = true if @dossier.update(dossier_params) && @dossier.individual.valid? + # TODO: remove this after proper mandat email validation + @dossier.individual.update!(email_verified_at: Time.zone.now) @dossier.update!(autorisation_donnees: true, identity_updated_at: Time.zone.now) flash.notice = t('.identity_saved') diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 8dd165c016c..8d3b702f98e 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -211,6 +211,7 @@ expect(individual.errors.full_messages).to be_empty expect(individual.notification_method).to eq('email') expect(individual.email).to eq('mickey@gmail.com') + expect(individual.email_verified_at).to be_present expect(response).to redirect_to(brouillon_dossier_path(dossier)) end From 555df3a6d82b3d6e3bc5f8a906fa89162bb5c8a1 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Mon, 27 May 2024 11:37:09 +0200 Subject: [PATCH 6/6] feat(User): add maintenance task to backfill email_verified_at --- ...prefill_individual_email_verified_at_task.rb | 17 +++++++++++++++++ .../prefill_user_email_verified_at_task.rb | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 app/tasks/maintenance/prefill_individual_email_verified_at_task.rb create mode 100644 app/tasks/maintenance/prefill_user_email_verified_at_task.rb diff --git a/app/tasks/maintenance/prefill_individual_email_verified_at_task.rb b/app/tasks/maintenance/prefill_individual_email_verified_at_task.rb new file mode 100644 index 00000000000..fa6e045d23e --- /dev/null +++ b/app/tasks/maintenance/prefill_individual_email_verified_at_task.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# We are going to confirm the various email addresses of the users in the system. +# Individual model (mandant) needs their email_verified_at attribute to be set in order to receive emails. +# This task sets the email_verified_at attribute to the current time for all the individual to be backward compatible +# See https://github.com/demarches-simplifiees/demarches-simplifiees.fr/issues/10450 +module Maintenance + class PrefillIndividualEmailVerifiedAtTask < MaintenanceTasks::Task + def collection + Individual.in_batches + end + + def process(batch_of_individuals) + batch_of_individuals.update_all(email_verified_at: Time.zone.now) + end + end +end diff --git a/app/tasks/maintenance/prefill_user_email_verified_at_task.rb b/app/tasks/maintenance/prefill_user_email_verified_at_task.rb new file mode 100644 index 00000000000..ad3ba6f5b92 --- /dev/null +++ b/app/tasks/maintenance/prefill_user_email_verified_at_task.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# We are going to confirm the various email addresses of the users in the system. +# User model needs their email_verified_at attribute to be set in order to receive emails. +# This task sets the email_verified_at attribute to the current time for all users to be backward compatible +# See https://github.com/demarches-simplifiees/demarches-simplifiees.fr/issues/10450 +module Maintenance + class PrefillUserEmailVerifiedAtTask < MaintenanceTasks::Task + def collection + User.in_batches + end + + def process(batch_of_users) + batch_of_users.update_all(email_verified_at: Time.zone.now) + end + end +end