activeadmin-oidc 2.2.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c594b010c852e97fc78daab9679704e733ed49341d26cc6763942e3aa081e47
4
- data.tar.gz: 66c0b9c1f7557dfb9edac28392547070641c2164df4d9963018e8c8c9d3e116d
3
+ metadata.gz: 4482b8503e17fed870824c6a6d10bf09d5f5653a065edf1bdbf179f0cb5a8ebb
4
+ data.tar.gz: 6d8f00973fd12b22497e3d82a7b80f684e5ffc54ffa15f2a8b93493e825f76c4
5
5
  SHA512:
6
- metadata.gz: 15fde3a273751c975c14f9bbbc43b6984796049e86649a25d6b257075834e249fb48bbafa67f9b3da0e2c12c780c0b8ba9097ba469d596742ec44a18114febcf
7
- data.tar.gz: a8a9449b8a4b8871af049b1e55071820045f307cec42fda3850db0e999894bd14996f3c1a5d60737326fe95cad726ef6cb04c21e1ac37d1c54e93713b04c8a2a
6
+ metadata.gz: daf83b73aaabff38e15b6c6e3ea4c3eb54c10f20e6736b543db6b0d603843ed605f8aa6e6bfe2ca31dab2e6c82a883abecd3a23a3fbd7cd233551206132db065
7
+ data.tar.gz: 625cd770049d4e7e4af7211a78fa1ffcd2cc0ddf603228935c0a620e2439cb9ba553c07d9cc6e38187e8a2d8b55ff4884f610e37864b366f4cc6259a2cec0cd4
data/README.md CHANGED
@@ -50,16 +50,25 @@ OIDC is the only authentication mechanism — `:database_authenticatable`, `encr
50
50
 
51
51
  If `devise_for :admin_users` lives inside a Rails engine (not the main app routes), set `Devise.router_name = :<engine_name>` in `config/initializers/devise.rb` and pass the same option to `devise_for`. The gem reads `Devise.available_router_name` and mounts its session routes inside that engine's route set, so `<Engine>.routes.url_helpers.new_<scope>_session_path` resolves correctly.
52
52
 
53
- For **isolated** engines (`isolate_namespace ...`) mounted at a prefix (e.g. `mount AdminPanel::Engine => '/admin'`), the engine prepends its mount path to every internal route. The gem's default `login_path = '/admin/login'` would then become `/admin/admin/login`. Configure engine-relative paths in `config/initializers/activeadmin_oidc.rb`:
53
+ For **isolated** engines (`isolate_namespace ...`) mounted at a prefix (e.g. `mount AdminPanel::Engine => '/admin'`), the engine prepends its mount path to every internal route, so the derived `login_path` of `/admin/login` would become `/admin/admin/login`. Configure engine-relative paths in `config/initializers/activeadmin_oidc.rb`:
54
54
 
55
55
  ```ruby
56
56
  ActiveAdmin::Oidc.configure do |c|
57
- c.login_path = '/login'
58
- c.logout_path = '/logout'
57
+ c.login_path = '/login'
58
+ c.logout_path = '/logout'
59
+ c.omniauth_route_prefix = '/auth'
59
60
  end
60
61
  ```
61
62
 
62
- Non-isolated engines don't need this override.
63
+ `omniauth_route_prefix` is the same idea applied to the routes Devise draws for
64
+ OmniAuth. It is separate from `omniauth_path_prefix` because the two are not the
65
+ same string here: the OmniAuth middleware sits in the *application's* Rack stack
66
+ and sees `/admin/auth/oidc` with the mount prefix still attached, while the route
67
+ Devise declares for the callback is inside the engine and gets `/admin` prepended
68
+ to it. Set only `omniauth_path_prefix` and the callback route lands on
69
+ `/admin/admin/auth/oidc/callback`, so the redirect the middleware issues 404s.
70
+
71
+ Non-isolated engines mounted at `/` don't need any of these overrides.
63
72
 
64
73
  ### 3. `config/initializers/activeadmin_oidc.rb` (generated)
65
74
 
@@ -73,7 +82,7 @@ The gem's Rails engine handles several things so host apps don't have to:
73
82
  * **Callback controller** — the engine patches `ActiveAdmin::Devise.controllers` to route OmniAuth callbacks to the gem's controller. No manual `controllers: { omniauth_callbacks: ... }` needed in `routes.rb`.
74
83
  * **Login view override** — the engine prepends an SSO-only login page (no email/password fields) to the sessions controller's view path. If your host app ships its own `app/views/active_admin/devise/sessions/new.html.erb`, the gem detects it and backs off — your view wins.
75
84
  * **Session routes** — the engine mounts `GET /admin/login` (renders the SSO landing page) and `DELETE /admin/logout` under `devise_scope`, with the scope name derived from `config.admin_user_class`. Devise normally generates session routes as a side effect of `:database_authenticatable`; without that module the route helpers would not exist and ActiveAdmin's login redirect would 404.
76
- * **Path prefix** — the engine sets `Devise.omniauth_path_prefix` and `OmniAuth.config.path_prefix` to `/admin/auth` so the middleware intercepts requests under ActiveAdmin's mount point. Compatible with Rails 7.2+ and Rails 8's lazy route loading.
85
+ * **Path prefix** — the engine registers the strategy with `path_prefix: '/admin/auth'` so the middleware intercepts requests under ActiveAdmin's mount point, and sets `Devise.omniauth_path_prefix` to the prefix Devise declares its routes with. Compatible with Rails 7.2+ and Rails 8's lazy route loading.
77
86
  * **Parameter filtering** — `code`, `id_token`, `access_token`, `refresh_token`, `state`, and `nonce` are added to `Rails.application.config.filter_parameters`.
78
87
 
79
88
  ## Configuration
@@ -137,12 +146,41 @@ end
137
146
  | `identity_attribute` | `:email` | AdminUser column used for lookup/adoption |
138
147
  | `identity_claim` | `:email` | Claim key read from the id_token/userinfo |
139
148
  | `admin_user_class` | `"AdminUser"` | String or Class for the host's admin user model |
149
+ | `login_path` | `/<namespace>/login` | SSO landing page path; derived from ActiveAdmin's namespace |
150
+ | `logout_path` | `/<namespace>/logout` | Sign-out path; derived from ActiveAdmin's namespace |
151
+ | `omniauth_path_prefix` | `/<namespace>/auth` | Browser-visible path the OmniAuth middleware listens on; derived from ActiveAdmin's namespace |
152
+ | `omniauth_route_prefix` | `omniauth_path_prefix` | Prefix Devise declares its OmniAuth routes with; differs only for engine-mounted hosts |
140
153
  | `login_button_label` | `"Sign in with SSO"` | Label on the login-page button |
141
154
  | `access_denied_message` | generic | Flash shown on any denial |
142
155
  | `on_login` | — (required) | Authorization hook; see below |
143
156
 
144
157
  `stub_dev_env_login!` is a method, not an option — see "Stub login" below.
145
158
 
159
+ ## ActiveAdmin's namespace
160
+
161
+ Everything the gem mounts hangs off ActiveAdmin's namespace, and all of it is
162
+ derived from `ActiveAdmin.application.default_namespace` rather than assumed to
163
+ be `admin`. A host that renames it:
164
+
165
+ ```ruby
166
+ # config/initializers/active_admin.rb
167
+ config.default_namespace = :backoffice
168
+ ```
169
+
170
+ gets `/backoffice/login`, `/backoffice/logout`, the OmniAuth middleware at
171
+ `/backoffice/auth`, and a post-sign-in redirect to `/backoffice` — no gem
172
+ configuration needed. ActiveAdmin's root namespace (`config.default_namespace =
173
+ false`) mounts everything at the top level: `/login`, `/auth`, `/`.
174
+
175
+ Each is still overridable. Isolated engines *have* to override them, since the
176
+ engine's mount prefix is prepended to every path declared inside it — see
177
+ [Engine-mounted Devise](#engine-mounted-devise).
178
+
179
+ `omniauth_route_prefix` is what the gem assigns to `Devise.omniauth_path_prefix`,
180
+ and it is skipped entirely if your app already assigned that in
181
+ `config/initializers/devise.rb`. `omniauth_path_prefix` is passed to the OmniAuth
182
+ strategy directly, so it stays correct regardless.
183
+
146
184
  ## The `on_login` hook
147
185
 
148
186
  `on_login` is the **only** place authorization lives. The gem handles authentication (the user proved who they are via the IdP); deciding whether that user is allowed into the admin panel — and what they can see once they are in — is the host application's problem. The gem does not ship a role model.
@@ -247,7 +285,7 @@ AdminUser.last.oidc_raw_info
247
285
 
248
286
  * A login button is added to the ActiveAdmin sessions page via a prepended view override — no templates to edit.
249
287
  * Clicking it POSTs to `/admin/auth/oidc` with a Rails CSRF token. The gem loads `omniauth-rails_csrf_protection` so OmniAuth 2.x delegates its authenticity check to Rails' forgery protection and `button_to` just works.
250
- * After a successful callback the user is signed in and redirected to `/admin` (not the host app's `/`, which may not exist).
288
+ * After a successful callback the user is signed in and redirected to ActiveAdmin's namespace root (not the host app's `/`, which may not exist). The path comes from ActiveAdmin's own route helper, so a renamed `config.default_namespace` or an engine-mounted ActiveAdmin lands correctly; `/admin` is only the fallback when that helper cannot be resolved.
251
289
  * **Disabled/locked users are rejected.** Devise's `active_for_authentication?` is checked after provisioning but before sign-in. If your model overrides this method (e.g. to check an `enabled` flag or Devise's `:lockable` module), the guard fires on OIDC sign-in too — the user sees an appropriate flash and is redirected to the login page.
252
290
  * In development, `stub_dev_env_login!` repoints that same button at a local sign-in that never contacts the IdP — see "Stub login" below.
253
291
  * Logout goes through Devise's stock session destroy. No RP-initiated single-logout ping to the IdP — override the destroy action in your host app if you need that.
@@ -105,28 +105,53 @@ module ActiveAdmin
105
105
  # sign-in instead of Devise's default (host app root). Hosts
106
106
  # that don't define a `/` route would otherwise hit a routing
107
107
  # error immediately after login, and even when `/` does exist
108
- # it's rarely what an admin user wants to see. ActiveAdmin
109
- # always mounts at `/admin`, so we go there directly.
108
+ # it's rarely what an admin user wants to see.
110
109
  def after_sign_in_path_for(resource)
111
- stored_location_for(resource) || '/admin'
110
+ stored_location_for(resource) || active_admin_root_path
111
+ end
112
+
113
+ # Resolved from ActiveAdmin's own route helper rather than
114
+ # assumed to be '/admin'. Two things move it: a host can rename
115
+ # the namespace (`config.default_namespace = :backoffice`), and
116
+ # an engine-mounted ActiveAdmin prefixes every path it declares
117
+ # with the engine's mount point -- so the real root can be
118
+ # '/admin/admin' or anything else entirely. Routing a signed-in
119
+ # admin to a 404 is a poor reward for a successful login.
120
+ def active_admin_root_path
121
+ send(devise_router_name(resource_name)).public_send(active_admin_root_helper)
122
+ rescue NameError, ::ActionController::UrlGenerationError
123
+ # The host has ActiveAdmin's routes somewhere we can't see (or
124
+ # hasn't drawn them at all). Its namespace prefix is the best
125
+ # remaining guess at where the admin panel lives -- except for
126
+ # the root namespace, where that prefix is '' and would make an
127
+ # empty, unredirectable Location.
128
+ ActiveAdmin::Oidc.config.active_admin_namespace_prefix.presence || '/'
129
+ end
130
+
131
+ # ActiveAdmin names its namespace root helper `<namespace>_root_path`,
132
+ # except for the root namespace where it is plain `root_path`.
133
+ def active_admin_root_helper
134
+ namespace = ActiveAdmin::Oidc.config.active_admin_namespace
135
+ namespace ? :"#{namespace}_root_path" : :root_path
112
136
  end
113
137
 
114
138
  # Devise's `new_session_path(scope)` is only generated when
115
139
  # `:database_authenticatable` is in the mapping's `used_helpers`,
116
140
  # so an OIDC-only model never gets it. The engine mounts
117
- # `new_<scope>_session_path` itself, but the helper lives on
118
- # whichever route set Devise's URL helper dispatcher points at:
119
- # the per-mapping `router_name` (set by
120
- # `devise_for :scope, router_name: :engine`) when present,
121
- # otherwise the global `Devise.available_router_name`
122
- # (set by `Devise.router_name = :engine`), which defaults to
123
- # `:main_app`. Replicate that dispatcher here so the helper is
124
- # resolved on the right context (Rails.application proxy or
125
- # mounted engine proxy).
141
+ # `new_<scope>_session_path` itself, but on whichever route set
142
+ # `devise_router_name` resolves to.
126
143
  def after_omniauth_failure_path_for(scope)
127
- router_name = ::Devise.mappings[scope].router_name ||
128
- ::Devise.available_router_name
129
- send(router_name).public_send(:"new_#{scope}_session_path")
144
+ send(devise_router_name(scope)).public_send(:"new_#{scope}_session_path")
145
+ end
146
+
147
+ # Devise's URL helpers live on the per-mapping `router_name` (set
148
+ # by `devise_for :scope, router_name: :engine`) when present,
149
+ # otherwise on the global `Devise.available_router_name` (set by
150
+ # `Devise.router_name = :engine`), which defaults to `:main_app`.
151
+ # Replicate that dispatcher here so helpers resolve on the right
152
+ # context (Rails.application proxy or mounted engine proxy).
153
+ def devise_router_name(scope)
154
+ ::Devise.mappings[scope]&.router_name || ::Devise.available_router_name
130
155
  end
131
156
  end
132
157
  end
@@ -11,19 +11,23 @@ module ActiveAdmin
11
11
  DEFAULT_ADMIN_USER_CLASS = 'AdminUser'
12
12
  DEFAULT_ACCESS_DENIED_MESSAGE =
13
13
  'Your account has no permission to access this admin panel.'
14
- DEFAULT_LOGIN_PATH = '/admin/login'
15
- DEFAULT_LOGOUT_PATH = '/admin/logout'
16
14
  DEFAULT_STUB_DEV_ENV_LOGIN_CLAIMS = {
17
15
  'sub' => 'stub-uid',
18
16
  'email' => 'stub-dev@example.com'
19
17
  }.freeze
18
+ # Stands in for ActiveAdmin's namespace when ActiveAdmin is not
19
+ # loaded (plain unit specs, scripts) and it therefore cannot be
20
+ # read. Everything else derives from
21
+ # `ActiveAdmin.application.default_namespace`.
22
+ FALLBACK_NAMESPACE = :admin
20
23
 
21
24
  attr_accessor :issuer, :client_id, :client_secret, :scope,
22
25
  :redirect_uri,
23
26
  :login_button_label, :timeout,
24
27
  :identity_attribute, :identity_claim,
25
- :access_denied_message, :on_login, :admin_user_class,
26
- :login_path, :logout_path
28
+ :access_denied_message, :on_login, :admin_user_class
29
+ attr_writer :login_path, :logout_path,
30
+ :omniauth_path_prefix, :omniauth_route_prefix
27
31
 
28
32
  # Readers, not writers: stub login is turned on through
29
33
  # `stub_dev_env_login!` so the environment check cannot be skipped.
@@ -47,8 +51,10 @@ module ActiveAdmin
47
51
  @identity_claim = DEFAULT_IDENTITY_CLAIM
48
52
  @access_denied_message = DEFAULT_ACCESS_DENIED_MESSAGE
49
53
  @admin_user_class = DEFAULT_ADMIN_USER_CLASS
50
- @login_path = DEFAULT_LOGIN_PATH
51
- @logout_path = DEFAULT_LOGOUT_PATH
54
+ @login_path = nil
55
+ @logout_path = nil
56
+ @omniauth_path_prefix = nil
57
+ @omniauth_route_prefix = nil
52
58
  @on_login = nil
53
59
  @pkce_override = nil
54
60
  @stub_dev_env_login = false
@@ -56,6 +62,82 @@ module ActiveAdmin
56
62
  self
57
63
  end
58
64
 
65
+ # The paths below all hang off ActiveAdmin's namespace, which the
66
+ # host can rename (`config.default_namespace = :backoffice`) -- in
67
+ # which case there is no /admin anywhere in the app and every
68
+ # hardcoded one would 404. They are computed on read rather than in
69
+ # `reset!` because the gem's own initializer may run before the
70
+ # host's `ActiveAdmin.setup` block.
71
+ #
72
+ # `login_path` and `logout_path` are declared inside whichever route
73
+ # set holds the host's Devise mapping, so an engine-mounted host has
74
+ # to override them engine-relative -- the mount prefix is prepended
75
+ # on top of whatever is written here.
76
+ def login_path
77
+ @login_path || "#{active_admin_namespace_prefix}/login"
78
+ end
79
+
80
+ def logout_path
81
+ @logout_path || "#{active_admin_namespace_prefix}/logout"
82
+ end
83
+
84
+ # Where the OmniAuth middleware listens. This one is a real,
85
+ # browser-visible path: the middleware sits in the application's
86
+ # Rack stack and sees the URL before any engine mount prefix has
87
+ # been stripped.
88
+ def omniauth_path_prefix
89
+ @omniauth_path_prefix || "#{active_admin_namespace_prefix}/auth"
90
+ end
91
+
92
+ # A host that set only `Devise.omniauth_path_prefix` meant one
93
+ # prefix, so it becomes ours too. An explicit value set here still
94
+ # wins: engine-mounted hosts need the two to differ by the mount
95
+ # prefix.
96
+ def adopt_devise_omniauth_path_prefix(prefix)
97
+ @omniauth_path_prefix ||= prefix.presence
98
+ end
99
+
100
+ # What Devise declares its OmniAuth request/callback routes with.
101
+ # Devise reuses a single setting for both jobs, and the two differ
102
+ # by exactly the mount prefix when `devise_for` lives inside a
103
+ # mounted engine -- so an engine-mounted host sets this
104
+ # engine-relative ('/auth'), the same way it does `login_path`.
105
+ def omniauth_route_prefix
106
+ @omniauth_route_prefix || omniauth_path_prefix
107
+ end
108
+
109
+ # ActiveAdmin's namespace as a Symbol, or nil for the root
110
+ # namespace (`default_namespace = false`), which mounts everything
111
+ # at the top level.
112
+ def active_admin_namespace
113
+ namespace = active_admin_default_namespace
114
+ return nil if namespace.blank? || namespace.to_sym == :root
115
+
116
+ # `.underscore` to match ActiveAdmin: `Namespace#initialize` does
117
+ # `name.to_s.underscore`, so `default_namespace = :"admin-panel"`
118
+ # routes under /admin_panel. Deriving from the raw value would
119
+ # mount the login page at /admin-panel and 404 after sign-in.
120
+ namespace.to_s.underscore.to_sym
121
+ end
122
+
123
+ # Narrow on purpose: `NoMethodError` is what "ActiveAdmin is not
124
+ # loaded, or not set up yet" surfaces as. Anything else -- a host
125
+ # initializer blowing up inside its own `default_namespace`
126
+ # override, say -- is a real misconfiguration and must not be
127
+ # quietly turned into a wrong path.
128
+ def active_admin_default_namespace
129
+ return FALLBACK_NAMESPACE unless defined?(::ActiveAdmin) && ::ActiveAdmin.respond_to?(:application)
130
+
131
+ ::ActiveAdmin.application.default_namespace
132
+ rescue NoMethodError
133
+ FALLBACK_NAMESPACE
134
+ end
135
+
136
+ def active_admin_namespace_prefix
137
+ namespace = active_admin_namespace
138
+ namespace ? "/#{namespace}" : ''
139
+ end
140
+
59
141
  def pkce
60
142
  return @pkce_override unless @pkce_override.nil?
61
143
 
@@ -117,7 +199,10 @@ module ActiveAdmin
117
199
  def login_submit_path
118
200
  return "#{login_path}/stub" if stub_dev_env_login_enabled?
119
201
 
120
- "#{::OmniAuth.config.path_prefix}/#{Engine::PROVIDER_NAME}"
202
+ # `omniauth_path_prefix`, not `OmniAuth.config.path_prefix`:
203
+ # under an engine mount those two differ by the mount prefix,
204
+ # and this one is the browser-visible path the form posts to.
205
+ "#{omniauth_path_prefix}/#{Engine::PROVIDER_NAME}"
121
206
  end
122
207
 
123
208
  def validate!
@@ -7,6 +7,12 @@ module ActiveAdmin
7
7
  class Engine < ::Rails::Engine
8
8
  PROVIDER_NAME = :oidc
9
9
 
10
+ # True once the host has supplied the minimum OIDC credentials.
11
+ def self.configured?
12
+ cfg = ActiveAdmin::Oidc.config
13
+ cfg.issuer.present? && cfg.client_id.present?
14
+ end
15
+
10
16
  # True when the host's AdminUser model includes :omniauthable.
11
17
  # Used to gate controller registration and view overrides so the
12
18
  # gem is a no-op when OIDC is not enabled on the model.
@@ -77,21 +83,42 @@ module ActiveAdmin
77
83
  # Automatically register the OmniAuth :openid_connect strategy with
78
84
  # Devise when the gem is configured, so host apps don't have to
79
85
  # duplicate the config.omniauth boilerplate in devise.rb.
80
- # Runs before Devise's own initializer so the strategy is available
81
- # when the model calls `devise :omniauthable`.
82
- initializer 'activeadmin_oidc.register_omniauth_strategy', before: 'devise.omniauth' do
86
+ #
87
+ # Ordered after the host's config/initializers (where
88
+ # `ActiveAdmin.setup` and `Devise.setup` live, so the namespace and
89
+ # any explicit host overrides are readable) and before
90
+ # `devise.omniauth`, which both needs the strategy registered and
91
+ # builds the middleware from these args.
92
+ #
93
+ # `path_prefix` is passed per-strategy rather than left to
94
+ # `OmniAuth.config.path_prefix`, because Devise overwrites that
95
+ # global at route-draw time with `Devise.omniauth_path_prefix` --
96
+ # the value it *declares its routes* with, which for a mounted
97
+ # engine is the same path minus the mount prefix. Setting the two
98
+ # independently through the global is impossible: Devise raises
99
+ # "Wrong OmniAuth configuration" whenever they disagree.
100
+ initializer 'activeadmin_oidc.register_omniauth_strategy',
101
+ after: :load_config_initializers, before: 'devise.omniauth' do
83
102
  cfg = ActiveAdmin::Oidc.config
84
- next if cfg.issuer.blank? || cfg.client_id.blank?
103
+ next unless Engine.configured?
85
104
 
86
105
  require 'omniauth_openid_connect'
87
106
 
88
- ::Devise.setup do |devise|
89
- # ActiveAdmin mounts Devise under /admin, so OmniAuth middleware
90
- # must intercept /admin/auth/:provider.
91
- devise.omniauth_path_prefix ||= '/admin/auth'
107
+ # `||=` semantics preserved: a host that set the prefix in its
108
+ # own devise.rb keeps it. Read by Devise when the routes are
109
+ # drawn, which happens later still.
110
+ host_prefix = ::Devise.omniauth_path_prefix
111
+ ::Devise.omniauth_path_prefix ||= cfg.omniauth_route_prefix
112
+
113
+ # Devise's setting decides where the routes are DRAWN; the
114
+ # strategy's `path_prefix` decides where the middleware LISTENS,
115
+ # and the login view posts to it. If they differ, sign-in 404s.
116
+ cfg.adopt_devise_omniauth_path_prefix(host_prefix)
92
117
 
118
+ ::Devise.setup do |devise|
93
119
  devise.omniauth :openid_connect,
94
120
  name: PROVIDER_NAME,
121
+ path_prefix: cfg.omniauth_path_prefix,
95
122
  scope: (cfg.scope || 'openid email profile').split,
96
123
  response_type: :code,
97
124
  issuer: cfg.issuer,
@@ -106,15 +133,6 @@ module ActiveAdmin
106
133
  host: nil
107
134
  }.compact
108
135
  end
109
-
110
- # Devise propagates omniauth_path_prefix to
111
- # OmniAuth.config.path_prefix during route generation
112
- # (set_omniauth_path_prefix!). On Rails 8 routes load lazily,
113
- # so the OmniAuth middleware may process requests before routes
114
- # are drawn and miss the prefix. Set it eagerly here.
115
- # Must happen AFTER `devise.omniauth` because that call
116
- # triggers autoload of devise/omniauth which nils the value.
117
- ::OmniAuth.config.path_prefix = ::Devise.omniauth_path_prefix
118
136
  end
119
137
 
120
138
  initializer 'activeadmin_oidc.filter_parameters' do |app|
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveAdmin
4
4
  module Oidc
5
- VERSION = "2.2.1"
5
+ VERSION = "3.0.0"
6
6
  end
7
7
  end
@@ -18,6 +18,17 @@ require "active_admin/version"
18
18
  # at file load, so pull in the minimal Railtie base class first — this
19
19
  # keeps the require safe even in spec_helper contexts where the full
20
20
  # Rails stack hasn't been initialized yet.
21
+ #
22
+ # The delegation core ext has to come first. railties 8.1's
23
+ # `rails/initializable.rb` calls `delegate_missing_to` in the body of
24
+ # `Rails::Initializable::Collection` but only requires "tsort", and
25
+ # `rails/railtie.rb` requires `rails/initializable` before any
26
+ # ActiveSupport core ext. So on Rails 8.1 a bare `require
27
+ # "rails/railtie"` raises `NoMethodError: undefined method
28
+ # 'delegate_missing_to'`. Requiring the one core ext it needs keeps the
29
+ # intent above intact — we still load only the minimal Railtie base
30
+ # class, not all of Rails.
31
+ require "active_support/core_ext/module/delegation"
21
32
  require "rails/railtie"
22
33
  require "omniauth/rails_csrf_protection"
23
34
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeadmin-oidc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Fedoronchuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-03 00:00:00.000000000 Z
11
+ date: 2026-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeadmin
@@ -288,7 +288,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
288
288
  requirements:
289
289
  - - ">="
290
290
  - !ruby/object:Gem::Version
291
- version: 3.2.0
291
+ version: 3.3.0
292
292
  required_rubygems_version: !ruby/object:Gem::Requirement
293
293
  requirements:
294
294
  - - ">="