From 07f6883a37c8c4749ec7d248c94de9add302fe76 Mon Sep 17 00:00:00 2001 From: Wabo Date: Sat, 16 May 2026 09:46:39 -0400 Subject: [PATCH] Fix container boot crash when Google SSO env vars are not set Devise raises "Mapping omniauth_callbacks on a resource that is not omniauthable" at route-load time if `controllers[:omniauth_callbacks]` is set on `devise_for`, regardless of whether `:omniauth_callbacks` is in the `only:` list (see devise-5.0.3 lib/devise/rails/routes.rb:251). The previous routes.rb only gated the `only:` array. Adding the same gate to the `controllers:` hash so the omniauth callback controller is only declared when GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET are present. Reproduced the crash by running the image without the env vars; fix verified in both states: - No env vars: container boots, /sign_in renders 200, no Google button present. - Env vars set + admin user created: container boots, /sign_in renders 200, "Sign in with Google" form posts to /auth/google_oauth2 with the /google_g.svg logo. Co-Authored-By: Claude Opus 4.7 --- config/routes.rb | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index fbdd8531..f8ddc976 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,12 +14,21 @@ Rails.application.routes.draw do get 'up' => 'rails/health#show' get 'manifest' => 'pwa#manifest' - devise_for :users, path: '/', only: %i[sessions passwords omniauth_callbacks], - controllers: { - sessions: 'sessions', - passwords: 'passwords', - omniauth_callbacks: 'users/omniauth_callbacks' - } + # Mirror the User model's conditional :omniauthable inclusion. ENV is the + # one source of truth available at routes-load time (Wabosign-the-module + # may not be autoloadable yet) — keep this check in sync with + # config/initializers/devise.rb and app/models/user.rb. + # Devise raises if controllers[:omniauth_callbacks] is set but User isn't + # omniauthable, so the controllers hash must omit that key too. + google_sso_enabled = ENV['GOOGLE_CLIENT_ID'].present? && ENV['GOOGLE_CLIENT_SECRET'].present? + devise_actions = %i[sessions passwords] + devise_controllers = { sessions: 'sessions', passwords: 'passwords' } + if google_sso_enabled + devise_actions << :omniauth_callbacks + devise_controllers[:omniauth_callbacks] = 'users/omniauth_callbacks' + end + + devise_for :users, path: '/', only: devise_actions, controllers: devise_controllers devise_scope :user do resource :invitation, only: %i[update] do