# frozen_string_literal: true class FranceConnectInformation < ApplicationRecord MERGE_VALIDITY = 15.minutes CONFIRMATION_EMAIL_VALIDITY = 2.days belongs_to :user, optional: true validates :france_connect_particulier_id, presence: true, allow_blank: false, allow_nil: false def safely_associate_user!(email) begin user = User.create!( email: email.downcase, password: Devise.friendly_token[0, 20], confirmed_at: Time.zone.now ) rescue ActiveRecord::RecordNotUnique # ignore this exception because we check before if user is nil. # exception can be raised in race conditions, when FranceConnect calls callback 2 times. # At the 2nd call, user is nil but exception is raised at the creation of the user # because the first call has already created a user end clean_tokens_and_requested_email update_attribute('user_id', user.id) save! end def safely_update_user(user:) self.user = user clean_tokens_and_requested_email save! end def send_custom_confirmation_instructions token = SecureRandom.hex(10) user.update!(confirmation_token: token, confirmation_sent_at: Time.zone.now) UserMailer.custom_confirmation_instructions(user, token).deliver_later end def create_merge_token! merge_token = SecureRandom.uuid update(merge_token:, merge_token_created_at: Time.zone.now) merge_token end def create_email_merge_token! email_merge_token = SecureRandom.uuid update(email_merge_token:, email_merge_token_created_at: Time.zone.now) email_merge_token end def valid_for_merge? (MERGE_VALIDITY.ago < merge_token_created_at) && user_id.nil? end def valid_for_email_merge? (MERGE_VALIDITY.ago < email_merge_token_created_at) && user_id.nil? end def delete_email_merge_token! update(email_merge_token: nil, email_merge_token_created_at: nil) end def clean_tokens_and_requested_email self.merge_token = nil self.merge_token_created_at = nil self.email_merge_token = nil self.email_merge_token_created_at = nil self.requested_email = nil end def full_name [given_name, family_name].compact.join(" ") end end