Fix production 404: add login page for OmniAuth POST requirement #151

Merged
ldraney merged 1 commit from fix/login-page-redirect into main 2026-06-07 03:57:00 +00:00
Owner

Summary

  • authenticate_user! redirected to GET /auth/keycloak, but OmniAuth 2.x only accepts POST — 404 on every protected route in production
  • Adds a proper /login page with POST form button, sprout icon, tagline
  • Hides auth bar and bottom nav on login page via is-login body class

Changes

  • app/controllers/application_controller.rb: redirect to login_path instead of /auth/keycloak
  • app/controllers/sessions_controller.rb: add new action for login page
  • config/routes.rb: add GET /login route
  • app/views/sessions/new.html.erb: new login page with icon, tagline, POST button, flash alert
  • app/views/layouts/application.html.erb: add is-login body class for sessions#new
  • app/assets/stylesheets/application.css: login page styles, hide chrome on login
  • spec/requests/sessions_spec.rb: add login page specs, update assertion text
  • spec/requests/{crew,person,role_access,feature_flags}_spec.rb: update redirect expectations to /login

Test Plan

  • Tests pass locally (198 examples, 0 failures)
  • Login page renders at /login without authentication
  • POST form submits to /auth/keycloak correctly
  • Flash alerts display on auth failure
  • All redirect expectations updated from /auth/keycloak to /login
  • Visual verification in browser at mobile viewport (390x844)
  • No regressions in OmniAuth callback, logout, or role-based access

Review Checklist

  • Passed automated review-fix loop
  • No secrets committed
  • No unnecessary file changes
  • Commit messages are descriptive
  • Feature flag needed? No — bug fix for broken auth redirect
  • Closes #150
  • ldraney/landscaping-assistant #149 — follow-up spike for smoke tests and observability
  • project-landscaping-assistant
## Summary - `authenticate_user!` redirected to `GET /auth/keycloak`, but OmniAuth 2.x only accepts POST — 404 on every protected route in production - Adds a proper `/login` page with POST form button, sprout icon, tagline - Hides auth bar and bottom nav on login page via `is-login` body class ## Changes - `app/controllers/application_controller.rb`: redirect to `login_path` instead of `/auth/keycloak` - `app/controllers/sessions_controller.rb`: add `new` action for login page - `config/routes.rb`: add `GET /login` route - `app/views/sessions/new.html.erb`: new login page with icon, tagline, POST button, flash alert - `app/views/layouts/application.html.erb`: add `is-login` body class for sessions#new - `app/assets/stylesheets/application.css`: login page styles, hide chrome on login - `spec/requests/sessions_spec.rb`: add login page specs, update assertion text - `spec/requests/{crew,person,role_access,feature_flags}_spec.rb`: update redirect expectations to `/login` ## Test Plan - [x] Tests pass locally (198 examples, 0 failures) - [x] Login page renders at `/login` without authentication - [x] POST form submits to `/auth/keycloak` correctly - [x] Flash alerts display on auth failure - [x] All redirect expectations updated from `/auth/keycloak` to `/login` - [x] Visual verification in browser at mobile viewport (390x844) - [x] No regressions in OmniAuth callback, logout, or role-based access ## Review Checklist - [ ] Passed automated review-fix loop - [ ] No secrets committed - [ ] No unnecessary file changes - [ ] Commit messages are descriptive - [ ] Feature flag needed? No — bug fix for broken auth redirect ## Related Notes - Closes #150 - `ldraney/landscaping-assistant #149` — follow-up spike for smoke tests and observability - `project-landscaping-assistant`
Fix production 404: add login page for OmniAuth POST requirement
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
CI / scan_ruby (pull_request) Has been cancelled
CI / scan_js (pull_request) Has been cancelled
CI / lint (pull_request) Has been cancelled
b4f3779488
authenticate_user! redirected to GET /auth/keycloak, but OmniAuth 2.x
only accepts POST on the request phase. This caused a 404 for every
unauthenticated user in production.

Adds a proper /login page with a POST form button, redirects
unauthenticated users there instead. Hides auth bar and bottom nav
on the login page for a clean first impression.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

Review — PR #151

Verdict: APPROVED

Core fix

Correct. redirect_to login_path replaces the broken redirect_to "/auth/keycloak", allow_other_host: true. The /login page uses button_to with method: :post, which generates a proper POST form — exactly what OmniAuth 2.x requires.

Route

get "/login", to: "sessions#new", as: :login placed correctly in the auth section. skip_before_action :authenticate_user! on SessionsController ensures no redirect loop.

View

Clean ERB. Inline SVGs for the sprout icon and login arrow match the nav icon style. data: { turbo: false } on the button is correct — OmniAuth handles its own redirect chain outside Turbo.

Layout

is-login body class via controller_name == 'sessions' && action_name == 'new' is a clean conditional. CSS hides auth-bar and bottom-nav rather than server-side conditional — acceptable tradeoff (simpler code, no layout duplication).

CSS

Follows design system: tokens for colors, spacing, radius. Component section header follows the convention. Two minor notes (non-blocking):

  • box-shadow uses hardcoded rgba(37, 99, 235, ...) — no shadow token exists, so this is acceptable
  • min-height: 85vh for centering is appropriate for a full-page login

Tests

  • All 6 redirect expectations updated from /auth/keycloak to /login across 4 spec files
  • 2 new login page specs cover rendering and unauthenticated access
  • 198 examples, 0 failures

No issues found

  • No secrets
  • No unnecessary file changes
  • No feature flag needed (bug fix)
  • Commit message is descriptive with root cause context
## Review — PR #151 **Verdict: APPROVED** ### Core fix Correct. `redirect_to login_path` replaces the broken `redirect_to "/auth/keycloak", allow_other_host: true`. The `/login` page uses `button_to` with `method: :post`, which generates a proper POST form — exactly what OmniAuth 2.x requires. ### Route `get "/login", to: "sessions#new", as: :login` placed correctly in the auth section. `skip_before_action :authenticate_user!` on `SessionsController` ensures no redirect loop. ### View Clean ERB. Inline SVGs for the sprout icon and login arrow match the nav icon style. `data: { turbo: false }` on the button is correct — OmniAuth handles its own redirect chain outside Turbo. ### Layout `is-login` body class via `controller_name == 'sessions' && action_name == 'new'` is a clean conditional. CSS hides auth-bar and bottom-nav rather than server-side conditional — acceptable tradeoff (simpler code, no layout duplication). ### CSS Follows design system: tokens for colors, spacing, radius. Component section header follows the convention. Two minor notes (non-blocking): - `box-shadow` uses hardcoded `rgba(37, 99, 235, ...)` — no shadow token exists, so this is acceptable - `min-height: 85vh` for centering is appropriate for a full-page login ### Tests - All 6 redirect expectations updated from `/auth/keycloak` to `/login` across 4 spec files - 2 new login page specs cover rendering and unauthenticated access - 198 examples, 0 failures ### No issues found - No secrets - No unnecessary file changes - No feature flag needed (bug fix) - Commit message is descriptive with root cause context
ldraney deleted branch fix/login-page-redirect 2026-06-07 03:57:00 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/landscaping-assistant!151
No description provided.