feat: logical return_to redirects post user action (#121)#130
feat: logical return_to redirects post user action (#121)#130trixy-the-ai-bot wants to merge 11 commits into
Conversation
- Add `safe_return_to` helper to ApplicationController (validates local-only URLs) - PaymentsController#create and InvoicesController#create redirect to `return_to` param on success, falling back to their default paths - Add `return_to` hidden field to payment and invoice forms so the param survives POST - Thread `return_to: request.fullpath` through all action-initiating links in leases#show, payments#index, and invoices#index - Add `‹` back button before the page title on leases, properties, tenants, and owners show pages - Add request specs covering: return_to redirect, default fallback, and external URL rejection (security) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…llers - Add empty line after guard clause in safe_return_to (Layout/EmptyLineAfterGuardClause) - Extract respond_to_create private method to reduce create method length and ABC complexity (Metrics/MethodLength, Metrics/AbcSize) - Fix line length by extracting redirect_path local variable (Layout/LineLength) - Fix :unprocessable_entity → :unprocessable_content in JSON error response (Rails/HttpStatusNameConsistency) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CI failures addressed. Fixed five RuboCop violations across |
|
A JS based |
Extract failure-format handling into respond_to_create_failure to bring respond_to_create within Metrics/AbcSize (≤17) and Metrics/MethodLength (≤10). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CI failures addressed. The |
Swap `link_to "‹", :back` (HTTP Referer-based) for a Stimulus `back` controller that calls `history.back()`, giving a more reliable UX by querying the browser's own history stack. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Review comments addressed. A new Stimulus controller ( |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CI failures addressed. The lint failure was a |
|
By history I meant go back in history until you hit a navigational check point. Not just the previous, which might be a form. |
Rubocop Style/BlockDelimiters and Layout violations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CI failures addressed. Fixed a Rubocop violation in |
Replace simple history.back() with a checkpoint-aware back navigation. A new history-tracker controller (mounted on <body>) records each page visit in sessionStorage, but only pushes "checkpoint" pages – index and show pages. New/edit form pages are excluded via URL pattern matching. The back controller now walks the checkpoint stack to find the last entry that differs from the current page, navigating directly there. This means clicking ‹ on a show page always lands on a natural navigation point, never an intermediate form, even if the user arrived via a create/update flow. Falls back to window.history.back() when the stack is empty (e.g., fresh session). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Review comments addressed. A new |
…Length Extract redirect URL to a local variable to collapse the multi-line redirect_to call and bring the method within the 10-line limit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CI failures addressed. The fix refactored |
|
param and hidden field based return to is no longer needed. |
|
Failed to address review comments: Agent exited with code 1 |
The browser history-based back navigation (history_tracker_controller + back_controller) replaces the need for return_to URL params and hidden form fields. Removed safe_return_to helper, all return_to param passing in links, hidden_field_tag in forms, and related specs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Review comments addressed. The |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
CI failures addressed. Two RuboCop layout violations were fixed: a trailing blank line inside the class body in |
Summary
Closes #121
safe_return_tohelper added toApplicationController— validates thatreturn_toURLs are local paths only (rejects any URL with a host component), preventing open redirect attacksPaymentsController#createandInvoicesController#createnow redirect toparams[:return_to]on success, falling back to their previous defaults (payments_pathandinvoice_path(@invoice)respectively)return_tofield added to payment and invoice forms so the param survives the POST requestleases#show,payments#index, andinvoices#indexto passreturn_to: request.fullpath— Renew and New Lease links are intentionally left unchanged (natural redirect exceptions)‹back button added before the page title onleases,properties,tenants, andownersshow pages as an escape hatch for natural redirect flowsTest plan
payments#createwithreturn_to: lease_path→ redirects to leasepayments#createwithoutreturn_to→ redirects topayments_path(unchanged default)invoices#createwithreturn_to: lease_path→ redirects to leaseinvoices#createwithoutreturn_to→ redirects toinvoice_path(unchanged default)return_to: "http://evil.com"→ redirects to fallback, not external URL🤖 Generated with Claude Code