thoughtbot / clearance

Rails authentication with email & password.

Home Page:https://thoughtbot.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clearance cookie expiration doesn't respect time travel in tests

pangolingo opened this issue · comments

Steps to reproduce

  1. integrate Clearance into an app
  2. write a system test for the app
  3. in the system test, use time travel to travel back in time 2 years
  4. in the system test, perform a login

Expected behavior

The user will be successfully logged in

Actual behavior

The login fails with a message:

We were not able to create this account. Try using a different email address or password.

(This is the flashes.failure_on_signup message)

Workarounds

We can successfully work around this issue a few ways:

  1. be sure not to time travel back more than a year ago
  2. adjust the cookie expiration time to be very long: config.cookie_expiration = lambda { |cookies| 9999.years.from_now.utc }

Notes

I encountered this on an app I'm working on, but I also found it mentioned in an issue on an internal thoughtbot repo. This was the workaround used there to avoid traveling too far back in time:

current_year = Time.zone.now.year
travel_to Time.new(current_year, 1, 1, 17, 10, 0, eastern_time_utc_offset)

Here's a shortened version of the test that caused these errors:

scenario "can change to a quarterly cashflow summary" do
      user = create_onboarded_user
     
      travel_to Date.new(2022, 3, 14)

      sign_in_with user.email, user.password
      visit dashboard_index_path

      expect(page).to have_content("Dashboard")
end

Here's the Clearance config used:

# config/initializers/clearance.rb
Clearance.configure do |config|
  config.allow_sign_up = true
  if Rails.env.production?
    config.cookie_expiration = lambda { |cookies| 1.month.from_now.utc }
  end
  config.mailer_sender = ENV.fetch("CLEARANCE_MAILER_SENDER")

  config.redirect_url = "/onboarding/get_started"

  config.rotate_csrf_on_sign_in = true
  config.routes = false
  config.secure_cookie = Rails.env.production?
  config.signed_cookie = true
end