Skip to content

feat(auth): redirect back to the original page after sign-in #117

Description

@jaspermayone

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

  1. 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.
  2. Generalize post_login_destination to consume that value. Keep the existing /oauth/authorize case.
  3. Keep the value through session rotation. reset_session_preserving_oauth must carry the new key, the same way it carries oauth_return_to today.
  4. 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

  • Password sign-in returns the user to the protected page they requested.
  • Magic-link sign-in returns the user to the protected page they requested.
  • The existing OAuth authorize resume still works.
  • A sign-in with no stored path lands on the dashboard.
  • Open-redirect payloads are rejected and fall back to the dashboard, with test coverage.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestrubyPull requests that update ruby code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions