Summary
After sign-in, Weave always sends the user to the dashboard. It does not send the user back to the page that asked for the login.
Requested by @taciturnaxolotl in Slack (Aug 4):
one thing that might be nice for weave is redirect back to the original login point
Current behavior
ApplicationController#authenticate_user! redirects to /login and keeps no record of the requested path:
https://github.com/patchworklabsorg/weave/blob/main/app/controllers/application_controller.rb#L125-L134
The only path that survives a login is an in-progress OAuth authorize request. Doorkeeper.configure's resource_owner_authenticator stores session[:oauth_return_to], and AuthController#post_login_destination consumes it:
config/initializers/doorkeeper.rb:22
app/controllers/auth_controller.rb:291-293
post_login_destination accepts only paths that start with /oauth/authorize. Every other destination falls back to root_path.
Expected behavior
A user who opens a protected page while signed out must return to that page after sign-in. Example: open /settings/sessions, sign in, land on /settings/sessions — not the dashboard.
Proposed change
- Store the requested path in
authenticate_user! (and authenticate_user_without_email_verification!) before the redirect to /login. Store only GET, non-Turbo-Frame, HTML requests.
- Generalize
post_login_destination to consume that value. Keep the existing /oauth/authorize case.
- Keep the value through session rotation.
reset_session_preserving_oauth must carry the new key, the same way it carries oauth_return_to today.
- Keep the value through the magic-link round trip. The user leaves for an email client and comes back on a fresh request, so the path must live in the session or in the magic-link token.
Security
The stored value goes straight into redirect_to, so it must not become an open redirect. Accept only a local, relative path:
- Reject any value with a scheme or a host (
//evil.com, https://evil.com, backslash variants).
- Require a leading
/.
- Reject
/login, /logout, and the magic-link consume paths, to prevent a redirect loop.
Please add tests for each rejected form.
Acceptance criteria
Summary
After sign-in, Weave always sends the user to the dashboard. It does not send the user back to the page that asked for the login.
Requested by @taciturnaxolotl in Slack (Aug 4):
Current behavior
ApplicationController#authenticate_user!redirects to/loginand keeps no record of the requested path:https://github.com/patchworklabsorg/weave/blob/main/app/controllers/application_controller.rb#L125-L134
The only path that survives a login is an in-progress OAuth authorize request.
Doorkeeper.configure'sresource_owner_authenticatorstoressession[:oauth_return_to], andAuthController#post_login_destinationconsumes it:config/initializers/doorkeeper.rb:22app/controllers/auth_controller.rb:291-293post_login_destinationaccepts only paths that start with/oauth/authorize. Every other destination falls back toroot_path.Expected behavior
A user who opens a protected page while signed out must return to that page after sign-in. Example: open
/settings/sessions, sign in, land on/settings/sessions— not the dashboard.Proposed change
authenticate_user!(andauthenticate_user_without_email_verification!) before the redirect to/login. Store onlyGET, non-Turbo-Frame, HTML requests.post_login_destinationto consume that value. Keep the existing/oauth/authorizecase.reset_session_preserving_oauthmust carry the new key, the same way it carriesoauth_return_totoday.Security
The stored value goes straight into
redirect_to, so it must not become an open redirect. Accept only a local, relative path://evil.com,https://evil.com, backslash variants)././login,/logout, and the magic-link consume paths, to prevent a redirect loop.Please add tests for each rejected form.
Acceptance criteria