Devise - how to get user when redirecting using custom Devise :: FailureApp

I allow users to log in first without confirming their email address, but after 7 days, if they have not been verified, I will block access until they confirm their address.

(Note - this is achieved by setting config.allow_unconfirmed_access_for = 7.days in the Devise initializer)

If they reach the limit of "grace" (for example, they do not confirm and pass after 7 days), I want:

  • send them to a page explaining what is happening (I can do this part)
  • send confirmation email automatically

do # 2 I need to access a user to get an email address.

To develop, obviously, “knows” who the user is, as he knows that they have passed the validity period of the confirmation.

If the user has just tried to log in, I can get this by looking at the options. However, if the user already has an entry token in their session, then when they pass the magic week they will suddenly begin to be rejected by development. How can I access the user in this case?

 #based on #https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-when-the-user-can-not-be-authenticated #https://stackoverflow.com/questions/9223555/devise-with-confirmable-redirect-user-to-a-custom-page-when-users-tries-to-sig class CustomFailure < Devise::FailureApp def redirect_url if warden_message == :unconfirmed user = User.find_by_email(params.dig(:user,:email)) user&.send_confirmation_instructions if user.nil? #if the user had a valid login session when they passed the grace period, they will end up here !! how do I get the user in this scenario !! end confirmation_required_info_path(params: {found: !user.nil?}) elsif warden_message == :invalid new_user_session_path(user:{email: params.dig(:user,:email)}) else super end end # You need to override respond to eliminate recall def respond if http_auth? http_auth else redirect end end end 

This achieves goal # 1, but only achieves goal # 2, if if the failure is the result of a new registration

Is there direct access to the user when he has a live session, but has the expiration date been reached?

(current_user is unavailable, env ['warden']. user is nil)

Thank you

Rails 5.0.6 develop 4.2

edit: update for clarification with an example scenario where I need help:

Day 0: User is logged in with email / password. I let them in without confirming their email. They have a 7 day grace period to confirm their email.

day 2: they log out

day 7 (morning): they log in again

day 7 (later that day): they perform some actions. Their login token is still valid - the developer recognizes it, finds its user account and checks if they have verified their email address. They did not do this - therefore, the developer refuses to authorize the action, giving an error: unconfirmed

In this scenario, they fall into the application with an error. I redirect them to a page that says: "You have passed your 7-day grace period, you really need to confirm your email address now."

In the rejected application, I want to know what their email address is so that I can automatically send a confirmation email. How to get it?

Note. In this case, the developer refused authorization. current_user is zero. However, Devise clearly “knows” who the user is because he was able to find his entry in the database and verify that they went through the grace period for unconfirmed email addresses. How to access the same "knowledge"

+5
source share
1 answer

I think there are better ways to achieve the same result without creating Devise::FailureApp :

This can be achieved by overriding the confirmed? from the Devise resource extension present in the Confirmable module .

A simple example would be:

  • Add the delayed_confirmation_expiry_date datetime field to the model table using migration.

This field will be used to store the expiration date when the user first logs into your application. You will have to override the SessionsController#create method to do this so that it can call the #delay_confirmation! method #delay_confirmation! on your resource.

  1. Add the User model to your equivalent:
 # Will update the field you have added with the new temporary expiration access datetime def delay_confirmation!(expiry_datetime=7.days.from_now) self.delayed_confirmation_expiry_date = expiry_datetime self.save end # Override that will make sure that, once the user is confirmed, the delayed confirmation information is cleared def confirm(args={}) clear_delay_confirmation! super end # Self-explanatory def clear_delay_confirmation! self.delayed_confirmation_expiry_date = nil self.save end # Used on your controllers to show messages to the user warning him about the presence of the confirmation delay def confirmation_is_delayed? self.confirmed? && !self.confirmed_at.present? end # Overrides the default implementation to allow temporary access for users who haven't confirmed their accounts within the time limit def confirmed? if !self.confirmation_is_delayed? super else self.delayed_confirmation_expiry_date >= DateTime.now.in_time_zone end end 
+1
source

Source: https://habr.com/ru/post/1274578/


All Articles