Skip to content

Fix lockout from stale session[:current_role] when a different user signs in - #5690

Merged
awwaiid merged 1 commit into
mainfrom
fix-stale-session-role-on-sign-in
Aug 29, 2026
Merged

awwaiid merged 1 commit into
mainfrom
fix-stale-session-role-on-sign-in

Conversation

@awwaiid

@awwaiid awwaiid commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Description

Signing in as one user and then signing in as a different user in the same browser (without signing out first) locks the second user out of the app entirely with an infinite redirect loop. The only escape is clearing cookies.

Cause: Users::SessionsController#create runs sign_out_if_signed_in, which is a scoped sign_out — it clears the Warden user but keeps the rest of the session, so session[:current_role] from the previous user survives into the new login. session[:current_role] ||= ... then sees a present value and leaves it alone.

ApplicationController#current_role did a global Role.find_by(id: session[:current_role]), so it happily returned a role the newly signed-in user does not hold. current_organization derived from that foreign role, authorize_user failed for every page — including the dashboard it redirects to — and the browser looped until ERR_TOO_MANY_REDIRECTS.

This was hit organically by two of us while doing local QA on another branch.

Fix, in two parts:

  • current_role scopes the session-role lookup to current_user.roles, so a role the user doesn't hold is ignored and it falls back to UsersRole.current_role_for. This alone stops the lockout.
  • SessionsController#create deletes a leftover session[:current_role] that doesn't belong to the newly signed-in user, so the session doesn't keep carrying another user's role around.

Type of change

Bug fix.

How Has This Been Tested?

Two new specs, both confirmed failing before the fix and passing after:

  • spec/requests/sessions_requests_spec.rb — signing in as a second user in the same session reaches a successful dashboard and stores that user's own role.
  • spec/controllers/application_controller_spec.rb — current_role uses a session role the user holds, and ignores one belonging to another user.

Also verified manually in a browser against local seed data: sign in as org_admin1@example.com, then sign in as org_admin2@example.com without signing out. On main the second login dead-ends in a redirect loop; with this change it lands on the SF Diaper Bank dashboard, and /dashboard continues to load correctly.

Full spec/requests/sessions_requests_spec.rb, spec/controllers/application_controller_spec.rb, spec/requests/users_requests_spec.rb and spec/requests/dashboard_requests_spec.rb pass (the existing session-role-preference cases around last-used and revoked roles still hold). Rubocop clean on the changed files.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AoUPX63nd1LSkKDPEiQ7jt

Users::SessionsController signs out an already-signed-in user with a
scoped sign_out, which keeps the rest of the session intact, so
session[:current_role] from the previous user survives into the new
login. current_role then resolved to a role the new user does not
hold, authorize_user failed on every page including the dashboard,
and the user was stuck in a redirect loop until they cleared cookies.

Scope the session role lookup to the current user's own roles, and
drop a leftover session role that does not belong to the newly
signed-in user.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AoUPX63nd1LSkKDPEiQ7jt
@awwaiid
awwaiid merged commit 2384108 into main Aug 29, 2026
22 checks passed
@awwaiid
awwaiid deleted the fix-stale-session-role-on-sign-in branch August 29, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant