rodauth-rails 1.12.0 → 1.14.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: 1dac2131f831b908d4bfd7a3367b310bd04b4141202b16f5e98d80e769972e32
4
- data.tar.gz: 1742fb2bb8fb16c221a4f09d5a5f53bdc898475383f91311100571e4902c8700
3
+ metadata.gz: a85a9d6a32ae95b8508024caebfa807fae2ab58841bfe2d8d2d6d382f3f336b2
4
+ data.tar.gz: bae2d174023325da77e494431246c5b4269e803be35157c084b5e35cc084c090
5
5
  SHA512:
6
- metadata.gz: 53dc0c219dc640431b553c8e843cc728ee1aff0c57a759dfebb0254a9e885a193ab1c3dff8d6fba6ba8423abdc49e9d6e38c14125a48a82954c42942b4a16838
7
- data.tar.gz: 07ea61d890bb27ae8cbaed4c203366ddb07c152b5f76272e2acec9865e1c7ec72472aef8b20e2a112ad831ab3bc69602f443fc80ffcb0f6b1754f1b3d317cff4
6
+ metadata.gz: 20ff48cdfa007d82233bd5e46bb09b31b6b1dc0ffa4669303b5c7bec19c3fdb36cda03b38ce36199eb4241433e4f2c118dd729544bda62a7b3c949c6af313a5e
7
+ data.tar.gz: 7930be938efaa027572fd487067b925eafc286e5f356db1781e0892cf62d30f2aef72ac4a1b854b17fee07679d38975c5fe29a15509dbf180e88bc973ba3457e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ ## 1.14.0 (2024-04-09)
2
+
3
+ * Allow declaring controller callbacks for specific Rodauth routes via `:only` and `:except` keyword arguments (@janko)
4
+
5
+ * Instrument Rodauth controller and route name instead of `RodauthApp#call` on Rodauth requests (@janko)
6
+
7
+ * Remove custom `#inspect` from Rodauth app middleware subclass in favour of Ruby 3.3+ `Module#set_temporary_name` (@janko)
8
+
9
+ * Fix `data-turbo="false"` being added in the wrong place in reset password request form on login validation errors (@janko)
10
+
11
+ * Fix format being inferred from `Accept` header instead URL path when calling `http_basic_auth` in the Rodauth middleware (@janko)
12
+
13
+ * Allow referencing custom column attributes on `rails_account` before the account is persisted (@janko)
14
+
15
+ * Retrieve auth class through the Rodauth app in generated account fixtures (@janko)
16
+
17
+ * Use `include Rodauth::Rails.model` again in generated account model (@janko)
18
+
19
+ * Avoid generated `convert_token_id_to_integer?` causing tokens to get silently rejected after switching to UUIDs (@janko)
20
+
21
+ * Allow referencing custom column attributes on `rails_account` during account creation (@janko)
22
+
23
+ * Drop support for Ruby 2.3 and 2.4 (@janko)
24
+
25
+ ## 1.13.0 (2023-12-25) :christmas_tree:
26
+
27
+ * Add `#rodauth` method to controller test helpers (@janko)
28
+
29
+ * When session middleware is required by Rodauth but missing, point to Rails docs instead of Roda (@janko)
30
+
31
+ * Set `login_confirm_param` to `"email-confirm"` in default configuration for consistency (@janko)
32
+
33
+ * Set `convert_token_id_to_integer?` in default configuration to avoid DB queries on boot (@janko)
34
+
1
35
  ## 1.12.0 (2023-10-20)
2
36
 
3
37
  * Allow generating view template for `confirm_password` feature (igor-alexandrov)
data/README.md CHANGED
@@ -10,6 +10,7 @@ Provides Rails integration for the [Rodauth] authentication framework.
10
10
  * [Rails demo](https://github.com/janko/rodauth-demo-rails)
11
11
  * [JSON API guide](https://github.com/janko/rodauth-rails/wiki/JSON-API)
12
12
  * [OmniAuth guide](https://github.com/janko/rodauth-rails/wiki/OmniAuth)
13
+ * [JSON Request Documentation for Rodauth](https://documenter.getpostman.com/view/26686011/2s9YC7SWn9)
13
14
 
14
15
  🎥 Screencasts:
15
16
 
@@ -22,7 +23,7 @@ Provides Rails integration for the [Rodauth] authentication framework.
22
23
  * [Rodauth: A Refreshing Authentication Solution for Ruby](https://janko.io/rodauth-a-refreshing-authentication-solution-for-ruby/)
23
24
  * [Rails Authentication with Rodauth](https://janko.io/adding-authentication-in-rails-with-rodauth/)
24
25
  * [Multifactor Authentication in Rails with Rodauth](https://janko.io/adding-multifactor-authentication-in-rails-with-rodauth/)
25
- * [How to build an OIDC provider using rodauth-oauth on Rails](https://honeyryderchuck.gitlab.io/httpx/2021/03/15/oidc-provider-on-rails-using-rodauth-oauth.html)
26
+ * [How to build an OIDC provider using rodauth-oauth on Rails](https://honeyryderchuck.gitlab.io/2021/03/15/oidc-provider-on-rails-using-rodauth-oauth.html)
26
27
  * [What It Took to Build a Rails Integration for Rodauth](https://janko.io/what-it-took-to-build-a-rails-integration-for-rodauth/)
27
28
  * [Social Login in Rails with Rodauth](https://janko.io/social-login-in-rails-with-rodauth/)
28
29
  * [Passkey Authentication with Rodauth](https://janko.io/passkey-authentication-with-rodauth/)
@@ -152,7 +153,7 @@ navigation header:
152
153
 
153
154
  ```erb
154
155
  <% if rodauth.logged_in? %>
155
- <%= link_to "Sign out", rodauth.logout_path, data: { turbo_method: :post } %>
156
+ <%= button_to "Sign out", rodauth.logout_path, method: :post %>
156
157
  <% else %>
157
158
  <%= link_to "Sign in", rodauth.login_path %>
158
159
  <%= link_to "Sign up", rodauth.create_account_path %>
@@ -252,7 +253,7 @@ end
252
253
  ```
253
254
  ```rb
254
255
  class RodauthController < ApplicationController
255
- before_action :set_locale # executes before Rodauth endpoints
256
+ before_action :verify_captcha, only: :login, if: -> { request.post? } # executes before Rodauth endpoints
256
257
  rescue_from("MyApp::SomeError") { |exception| ... } # rescues around Rodauth endpoints
257
258
  end
258
259
  ```
@@ -281,7 +282,7 @@ class RodauthMain < Rodauth::Rails::Auth
281
282
  after_login { rails_cookies.permanent[:last_account_id] = account_id }
282
283
  end
283
284
  end
284
- ```
285
+ ```
285
286
 
286
287
  ## Views
287
288
 
@@ -420,7 +421,7 @@ tables used by enabled authentication features.
420
421
 
421
422
  ```rb
422
423
  class Account < ActiveRecord::Base # Sequel::Model
423
- include Rodauth::Model(RodauthMain)
424
+ include Rodauth::Rails.model # or `Rodauth::Rails.model(:admin)`
424
425
  end
425
426
  ```
426
427
  ```rb
@@ -592,7 +593,7 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest
592
593
  post "/logout"
593
594
  assert_redirected_to "/"
594
595
  end
595
-
596
+
596
597
  test "required authentication" do
597
598
  get :index
598
599
 
@@ -616,7 +617,7 @@ end
616
617
  ```
617
618
 
618
619
  For more examples and information about testing with rodauth, see
619
- [this wiki page about testing](https://github.com/janko/rodauth-rails/wiki/Testing).
620
+ [this wiki page about testing](https://github.com/janko/rodauth-rails/wiki/Testing).
620
621
 
621
622
  ## Configuring
622
623
 
@@ -633,6 +634,15 @@ The `rails` feature rodauth-rails loads provides the following configuration met
633
634
  | `rails_controller` | Controller class to use for rendering and CSRF protection. |
634
635
  | `rails_account_model` | Model class connected with the accounts table. |
635
636
 
637
+ ```rb
638
+ class RodauthMain < Rodauth::Rails::Auth
639
+ configure do
640
+ rails_account_model { MyApp::Account }
641
+ rails_controller { MyApp::RodauthController }
642
+ end
643
+ end
644
+ ```
645
+
636
646
  ### Manually inserting middleware
637
647
 
638
648
  You can choose to insert the Rodauth middleware somewhere earlier than
@@ -643,7 +653,7 @@ Rodauth::Rails.configure do |config|
643
653
  config.middleware = false # disable auto-insertion
644
654
  end
645
655
 
646
- Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
656
+ Rails.configuration.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
647
657
  ```
648
658
 
649
659
  ## How it works
@@ -66,7 +66,7 @@ module Rodauth
66
66
  end
67
67
 
68
68
  def create_fixtures
69
- generator_options = ::Rails.application.config.generators.options
69
+ generator_options = ::Rails.configuration.generators.options
70
70
  if generator_options[:test_unit][:fixture] && generator_options[:test_unit][:fixture_replacement].nil?
71
71
  test_dir = generator_options[:rails][:test_framework] == :rspec ? "spec" : "test"
72
72
  template "test/fixtures/accounts.yml", "#{test_dir}/fixtures/#{table_prefix.pluralize}.yml"
@@ -107,11 +107,11 @@ module Rodauth
107
107
  end
108
108
 
109
109
  def session_store?
110
- !!::Rails.application.config.session_store
110
+ !!::Rails.configuration.session_store
111
111
  end
112
112
 
113
113
  def api_only?
114
- ::Rails.application.config.api_only
114
+ ::Rails.configuration.api_only
115
115
  end
116
116
 
117
117
  def sequel_adapter
@@ -120,7 +120,7 @@ module Rodauth
120
120
  end
121
121
 
122
122
  def primary_key_type(key = :id)
123
- generators = ::Rails.application.config.generators
123
+ generators = ::Rails.configuration.generators
124
124
  column_type = generators.options[:active_record][:primary_key_type]
125
125
 
126
126
  if key
@@ -20,6 +20,9 @@ class RodauthMain < Rodauth::Rails::Auth
20
20
  db Sequel.<%= sequel_adapter %>(extensions: :activerecord_connection, keep_reference: false)
21
21
  <% end -%>
22
22
 
23
+ # Avoid DB query that checks accounts table schema at boot time.
24
+ convert_token_id_to_integer? { <%= table_prefix.camelize %>.columns_hash["id"].type == :integer }
25
+
23
26
  <% end -%>
24
27
  # Change prefix of table and foreign key column names from default "account"
25
28
  <% if table -%>
@@ -86,6 +89,7 @@ class RodauthMain < Rodauth::Rails::Auth
86
89
 
87
90
  # Change some default param keys.
88
91
  login_param "email"
92
+ login_confirm_param "email-confirm"
89
93
  # password_confirm_param "confirm_password"
90
94
 
91
95
  # Redirect back to originally requested location after authentication.
@@ -1,6 +1,6 @@
1
1
  <% if defined?(ActiveRecord::Railtie) -%>
2
2
  class <%= table_prefix.camelize %> < ApplicationRecord
3
- include Rodauth::Model(RodauthMain)
3
+ include Rodauth::Rails.model
4
4
  <% if ActiveRecord.version >= Gem::Version.new("7.0") -%>
5
5
  enum :status, unverified: 1, verified: 2, closed: 3
6
6
  <% else -%>
@@ -9,7 +9,7 @@ class <%= table_prefix.camelize %> < ApplicationRecord
9
9
  end
10
10
  <% else -%>
11
11
  class <%= table_prefix.camelize %> < Sequel::Model
12
- include Rodauth::Model(RodauthMain)
12
+ include Rodauth::Rails.model
13
13
  plugin :enum
14
14
  enum :status, unverified: 1, verified: 2, closed: 3
15
15
  end
@@ -1,10 +1,10 @@
1
1
  # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
2
  one:
3
3
  email: freddie@queen.com
4
- password_hash: <%%= RodauthMain.allocate.password_hash("password") %>
4
+ password_hash: <%%= RodauthApp.rodauth.allocate.password_hash("password") %>
5
5
  status: verified
6
6
 
7
7
  two:
8
8
  email: brian@queen.com
9
- password_hash: <%%= RodauthMain.allocate.password_hash("password") %>
9
+ password_hash: <%%= RodauthApp.rodauth.allocate.password_hash("password") %>
10
10
  status: verified
@@ -121,7 +121,7 @@ module Rodauth
121
121
  end
122
122
 
123
123
  def tailwind?
124
- ::Rails.application.config.generators.options[:rails][:template_engine] == :tailwindcss ||
124
+ ::Rails.configuration.generators.options[:rails][:template_engine] == :tailwindcss ||
125
125
  options[:css]&.downcase&.start_with?("tailwind")
126
126
  end
127
127
  end
@@ -5,18 +5,7 @@ module Rodauth
5
5
  module Rails
6
6
  # The superclass for creating a Rodauth middleware.
7
7
  class App < Roda
8
- plugin :middleware, forward_response_headers: true, next_if_not_found: true do |middleware|
9
- middleware.class_eval do
10
- def self.inspect
11
- "#{superclass}::Middleware"
12
- end
13
-
14
- def inspect
15
- "#<#{self.class.inspect} request=#{request.inspect} response=#{response.inspect}>"
16
- end
17
- end
18
- end
19
-
8
+ plugin :middleware, forward_response_headers: true, next_if_not_found: true
20
9
  plugin :hooks
21
10
  plugin :pass
22
11
 
@@ -63,13 +52,7 @@ module Rodauth
63
52
  end
64
53
 
65
54
  def self.rodauth!(name)
66
- rodauth(name) or fail ArgumentError, "unknown rodauth configuration: #{name.inspect}"
67
- end
68
-
69
- # The newrelic_rpm gem expects this when we pass the roda class as
70
- # :controller in instrumentation payload.
71
- def self.controller_path
72
- name.underscore
55
+ rodauth(name) or fail Rodauth::Rails::Error, "unknown rodauth configuration: #{name.inspect}"
73
56
  end
74
57
 
75
58
  module RequestMethods
@@ -32,7 +32,7 @@ module Rodauth
32
32
  end
33
33
 
34
34
  def rails_controller
35
- if only_json? && ::Rails.application.config.api_only
35
+ if only_json? && ::Rails.configuration.api_only
36
36
  ActionController::API
37
37
  else
38
38
  ActionController::Base
@@ -49,11 +49,21 @@ module Rodauth
49
49
 
50
50
  delegate :rails_routes, :rails_cookies, :rails_request, to: :scope
51
51
 
52
+ def session
53
+ super
54
+ rescue Roda::RodaError
55
+ fail Rodauth::Rails::Error, "There is no session middleware configured, see instructions on how to add it: https://guides.rubyonrails.org/api_app.html#using-session-middlewares"
56
+ end
57
+
52
58
  private
53
59
 
54
60
  def instantiate_rails_account
55
61
  if defined?(ActiveRecord::Base) && rails_account_model < ActiveRecord::Base
56
- rails_account_model.instantiate(account.stringify_keys)
62
+ if account[account_id_column]
63
+ rails_account_model.instantiate(account.stringify_keys)
64
+ else
65
+ rails_account_model.new(account)
66
+ end
57
67
  elsif defined?(Sequel::Model) && rails_account_model < Sequel::Model
58
68
  rails_account_model.load(account)
59
69
  else
@@ -7,6 +7,8 @@ module Rodauth
7
7
  private
8
8
 
9
9
  def _around_rodauth
10
+ rails_controller_instance.instance_variable_set(:@_action_name, current_route.to_s)
11
+
10
12
  rails_controller_around { super }
11
13
  end
12
14
 
@@ -34,8 +34,8 @@ module Rodauth
34
34
  request = rails_request
35
35
 
36
36
  raw_payload = {
37
- controller: self.class.roda_class.name,
38
- action: "call",
37
+ controller: rails_controller.name,
38
+ action: current_route.to_s,
39
39
  request: request,
40
40
  params: request.filtered_parameters,
41
41
  headers: request.headers,
@@ -47,20 +47,18 @@ module Rodauth
47
47
  ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload)
48
48
 
49
49
  ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
50
- begin
51
- result = catch(:halt) { yield }
50
+ result = catch(:halt) { yield }
52
51
 
53
- response = ActionDispatch::Response.new(*(result || [404, {}, []]))
54
- payload[:response] = response
55
- payload[:status] = response.status
52
+ response = ActionDispatch::Response.new(*(result || [404, {}, []]))
53
+ payload[:response] = response
54
+ payload[:status] = response.status
56
55
 
57
- throw :halt, result if result
58
- rescue => error
59
- payload[:status] = ActionDispatch::ExceptionWrapper.status_code_for_exception(error.class.name)
60
- raise
61
- ensure
62
- rails_controller_eval { append_info_to_payload(payload) }
63
- end
56
+ throw :halt, result if result
57
+ rescue => error
58
+ payload[:status] = ActionDispatch::ExceptionWrapper.status_code_for_exception(error.class.name)
59
+ raise
60
+ ensure
61
+ rails_controller_eval { append_info_to_payload(payload) }
64
62
  end
65
63
  end
66
64
 
@@ -47,7 +47,7 @@ module Rodauth
47
47
  def rails_url_options
48
48
  return nil unless defined?(ActionMailer)
49
49
 
50
- ::Rails.application.config.action_mailer.default_url_options or
50
+ ::Rails.configuration.action_mailer.default_url_options or
51
51
  fail Error, "There is no information to set the URL host from. Please set config.action_mailer.default_url_options in your Rails application, or configure #domain and #base_url in your Rodauth configuration."
52
52
  end
53
53
  end
@@ -46,17 +46,16 @@ module Rodauth
46
46
  end
47
47
 
48
48
  # Only look up template formats that the current request is accepting.
49
- def _rails_controller_instance
50
- controller = super
51
- controller.formats = rails_request.formats.map(&:ref).compact
52
- controller
49
+ def before_rodauth
50
+ super
51
+ rails_controller_instance.formats = rails_request.formats.map(&:ref).compact
53
52
  end
54
53
 
55
54
  # Not all Rodauth actions are Turbo-compatible (some form submissions
56
55
  # render 200 HTML responses), so we disable Turbo on all Rodauth forms.
57
56
  def _view(meth, *)
58
57
  html = super
59
- html = html.gsub(/<form(.+)>/, '<form\1 data-turbo="false">') if meth == :view
58
+ html = html.gsub(/<form([^>]+)>/, '<form\1 data-turbo="false">') if meth == :view
60
59
  html
61
60
  end
62
61
 
@@ -21,9 +21,9 @@ module Rodauth
21
21
 
22
22
  # Check whether it's a request to an asset managed by Sprockets or Propshaft.
23
23
  def asset_request?(env)
24
- return false unless ::Rails.application.config.respond_to?(:assets)
24
+ return false unless ::Rails.configuration.respond_to?(:assets)
25
25
 
26
- env["PATH_INFO"] =~ %r(\A/{0,2}#{::Rails.application.config.assets.prefix})
26
+ env["PATH_INFO"] =~ %r(\A/{0,2}#{::Rails.configuration.assets.prefix})
27
27
  end
28
28
  end
29
29
  end
@@ -13,7 +13,7 @@ module Rodauth
13
13
 
14
14
  def call
15
15
  routes = auth_class.route_hash.map do |path, handle_method|
16
- route_name = handle_method.to_s.sub(/\Ahandle_/, "").to_sym
16
+ route_name = handle_method.to_s.delete_prefix("handle_").to_sym
17
17
  next if IGNORE.include?(route_name)
18
18
  verbs = route_verbs(route_name)
19
19
 
@@ -35,6 +35,10 @@ module Rodauth
35
35
 
36
36
  response
37
37
  end
38
+
39
+ def rodauth(name = nil)
40
+ @controller.rodauth(name)
41
+ end
38
42
  end
39
43
  end
40
44
  end
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "1.12.0"
3
+ VERSION = "1.14.0"
4
4
  end
5
5
  end
@@ -11,14 +11,14 @@ Gem::Specification.new do |spec|
11
11
  spec.homepage = "https://github.com/janko/rodauth-rails"
12
12
  spec.license = "MIT"
13
13
 
14
- spec.required_ruby_version = ">= 2.3"
14
+ spec.required_ruby_version = ">= 2.5"
15
15
 
16
16
  spec.files = Dir["README.md", "LICENSE.txt", "CHANGELOG.md", "lib/**/*", "*.gemspec"]
17
17
  spec.require_paths = ["lib"]
18
18
 
19
19
  spec.add_dependency "railties", ">= 5.0", "< 8"
20
- spec.add_dependency "rodauth", "~> 2.30"
21
- spec.add_dependency "roda", "~> 3.73"
20
+ spec.add_dependency "rodauth", "~> 2.34"
21
+ spec.add_dependency "roda", "~> 3.76"
22
22
  spec.add_dependency "sequel-activerecord_connection", "~> 1.1"
23
23
  spec.add_dependency "rodauth-model", "~> 0.2"
24
24
  spec.add_dependency "tilt"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.0
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-20 00:00:00.000000000 Z
11
+ date: 2024-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -36,28 +36,28 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '2.30'
39
+ version: '2.34'
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '2.30'
46
+ version: '2.34'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: roda
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '3.73'
53
+ version: '3.76'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '3.73'
60
+ version: '3.76'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: sequel-activerecord_connection
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -345,14 +345,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
345
345
  requirements:
346
346
  - - ">="
347
347
  - !ruby/object:Gem::Version
348
- version: '2.3'
348
+ version: '2.5'
349
349
  required_rubygems_version: !ruby/object:Gem::Requirement
350
350
  requirements:
351
351
  - - ">="
352
352
  - !ruby/object:Gem::Version
353
353
  version: '0'
354
354
  requirements: []
355
- rubygems_version: 3.4.10
355
+ rubygems_version: 3.5.3
356
356
  signing_key:
357
357
  specification_version: 4
358
358
  summary: Provides Rails integration for Rodauth.