diff --git a/app/controllers/france_connect/particulier_controller.rb b/app/controllers/france_connect/particulier_controller.rb index fe3c57dee..3eb3c494d 100644 --- a/app/controllers/france_connect/particulier_controller.rb +++ b/app/controllers/france_connect/particulier_controller.rb @@ -2,8 +2,9 @@ class FranceConnect::ParticulierController < ApplicationController before_action :redirect_to_login_if_fc_aborted, only: [:callback] - before_action :securely_retrieve_fci, only: [:merge, :merge_with_existing_account, :merge_with_new_account, :resend_and_renew_merge_confirmation] + before_action :securely_retrieve_fci, only: [:merge, :merge_with_existing_account, :merge_with_new_account, :resend_and_renew_merge_confirmation, :associate_user] before_action :securely_retrieve_fci_from_email_merge_token, only: [:mail_merge_with_existing_account] + before_action :set_user_by_confirmation_token, only: [:resend_confirmation, :post_resend_confirmation, :confirm_email, :connect_france_connect_particulier_redirect] def login if FranceConnectService.enabled? @@ -20,8 +21,9 @@ class FranceConnect::ParticulierController < ApplicationController preexisting_unlinked_user = User.find_by(email: sanitize(fci.email_france_connect)) if preexisting_unlinked_user.nil? - fci.associate_user!(fci.email_france_connect) - connect_france_connect_particulier(fci.user) + merge_token = fci.create_merge_token! + render :choose_email, locals: { france_connect_email: fci.email_france_connect, merge_token: } + elsif !preexisting_unlinked_user.can_france_connect? fci.destroy redirect_to new_user_session_path, alert: t('errors.messages.france_connect.forbidden_html', reset_link: new_user_password_path) @@ -35,7 +37,7 @@ class FranceConnect::ParticulierController < ApplicationController if user.can_france_connect? fci.update(updated_at: Time.zone.now) connect_france_connect_particulier(user) - else # same behaviour as redirect nicely with message when instructeur/administrateur + else fci.destroy redirect_to new_user_session_path, alert: t('errors.messages.france_connect.forbidden_html', reset_link: new_user_password_path) end @@ -46,6 +48,18 @@ class FranceConnect::ParticulierController < ApplicationController redirect_france_connect_error_connection end + def associate_user + email = use_fc_email? ? @fci.email_france_connect : params[:alternative_email] + @fci.associate_user!(email) + user = @fci.user + + @fci.delete_merge_token! + sign_only(user) + + destination_path = destination_path(user) + render :confirmation_sent, locals: { email:, destination_path: } + end + def merge end @@ -75,7 +89,7 @@ class FranceConnect::ParticulierController < ApplicationController if user.can_france_connect? @fci.update(user: user) @fci.delete_merge_token! - + user.update(email_verified_at: Time.zone.now) flash.notice = t('france_connect.particulier.flash.connection_done', application_name: Current.application_name) connect_france_connect_particulier(user) else # same behaviour as redirect nicely with message when instructeur/administrateur @@ -90,8 +104,8 @@ class FranceConnect::ParticulierController < ApplicationController if user.nil? @fci.associate_user!(sanitized_email_params) @fci.delete_merge_token! - - flash.notice = t('france_connect.particulier.flash.connection_done', application_name: Current.application_name) + @fci.send_custom_confirmation_instructions(@fci.user) + flash.notice = t('france_connect.particulier.flash.connection_done_verify_email', application_name: Current.application_name) connect_france_connect_particulier(@fci.user) else @email = sanitized_email_params @@ -113,8 +127,56 @@ class FranceConnect::ParticulierController < ApplicationController notice: t('france_connect.particulier.flash.confirmation_mail_sent') end + def confirm_email + if @user.confirmation_sent_at && 2.days.ago < @user.confirmation_sent_at + @user.update(email_verified_at: Time.zone.now, confirmation_token: nil) + @user.after_confirmation + redirect_to stored_location_for(@user) || root_path(@user), notice: 'Votre email est bien vérifié' + else + redirect_to france_connect_resend_confirmation_path(token: @user.confirmation_token), alert: "Lien de confirmation expiré. Un nouveau lien de confirmation a été envoyé." + end + end + + def resend_confirmation + if @user.email_verified_at + redirect_to root_path, alert: 'Email déjà confirmé.' + end + end + + def post_resend_confirmation + if !@user.email_verified_at + fci = FranceConnectInformation.find_by(user: @user) + fci.send_custom_confirmation_instructions(@user) + redirect_to root_path(@user), notice: "Un nouveau lien de confirmation vous a été envoyé par mail." + else + redirect_to root_path(@user), alert: "Adresse email non trouvée ou déjà confirmée." + end + end + private + def set_user_by_confirmation_token + @user = User.find_by(confirmation_token: params[:token]) + + if @user.nil? + redirect_to root_path, alert: 'Utilisateur non trouvé' and return + end + + if user_signed_in? && current_user != @user + sign_out current_user + redirect_to new_user_session_path, alert: "Veuillez vous connecter avec le compte associé à ce lien de confirmation." + end + end + + def use_fc_email? = cast_bool(params[:use_france_connect_email]) + + def sign_only(user) + sign_out(user) if user_signed_in? + sign_in(user) + end + + def destination_path(user) = stored_location_for(user) || root_path(user) + def securely_retrieve_fci_from_email_merge_token @fci = FranceConnectInformation.find_by(email_merge_token: email_merge_token_params)