rodauth-rails 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adfcbce27e52d0a53b5cd670489635c841dff9e2809c92be059286943894db6c
4
- data.tar.gz: e98584823e926c810bc66366496df5fb3c8eed0f38e291b76b9f132480941a9c
3
+ metadata.gz: 8f902ae05472454543304221221b9681c7dab3d231d6551c7e82b6c4c1570dc8
4
+ data.tar.gz: b3a1948fb603be978bddea73a44b8109f4e3c76e132b2da3a8e6aad1b36f3d14
5
5
  SHA512:
6
- metadata.gz: 845b037926a9372522da9b3507b5fd2959454bc24198f72a7832d9025ccd27f9bac3790823577e1e68c3a1e1a076472e1629825973c37cc932e2b63299e1408b
7
- data.tar.gz: af417d7bbe9732c677ca15c6796817554fe68d5f8f3db8001b56a736db33382f3efd8f86952509d038f45f449f76d3c9ea61f1a7f5a29c1cef5f45e72cf1c9ce
6
+ metadata.gz: 8547335032c3e0851406932463cd62e2377c16db2145e0da6abb8a7f20745c20f9e8d54bd2b57599e335a4f9b37078cf7f1c17caa53b4dab60105c410a401469
7
+ data.tar.gz: dd84bd6d57a4e8e78a6412a7ac38befa7d75ef693a6788014d383d3800a4535af71fa24239f8b0521cecc7c598766f48b2034a016a2a15235cfa9f9d2dd52761
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 1.11.0 (2023-08-21)
2
+
3
+ * Exclude WebAuthn JS routes in `rodauth:routes`, since those stop being relevant with custom JS (@janko)
4
+
5
+ * Separate HTTP verbs with `|` symbol in `rodauth:routes` for consistency with `rails routes` (@janko)
6
+
7
+ * Include two factor manage & auth JSON POST routes in `rodauth:routes` task (@janko)
8
+
9
+ * Make `rodauth:routes` rake task appear in `rails -T` list (@janko)
10
+
11
+ * Accept plugin options in `Rodauth::Rails.lib` (@janko)
12
+
13
+ * Support skipping loading Roda `render` plugin by passing `render: false` (@janko)
14
+
1
15
  ## 1.10.0 (2023-07-26)
2
16
 
3
17
  * Add `Rodauth::Rails.lib` for easier usage of Rodauth as a library in Rails apps (@janko)
data/README.md CHANGED
@@ -134,18 +134,18 @@ $ rails rodauth:routes
134
134
  ```
135
135
  Routes handled by RodauthApp:
136
136
 
137
- GET/POST /login rodauth.login_path
138
- GET/POST /create-account rodauth.create_account_path
139
- GET/POST /verify-account-resend rodauth.verify_account_resend_path
140
- GET/POST /verify-account rodauth.verify_account_path
141
- GET/POST /change-password rodauth.change_password_path
142
- GET/POST /change-login rodauth.change_login_path
143
- GET/POST /logout rodauth.logout_path
144
- GET/POST /remember rodauth.remember_path
145
- GET/POST /reset-password-request rodauth.reset_password_request_path
146
- GET/POST /reset-password rodauth.reset_password_path
147
- GET/POST /verify-login-change rodauth.verify_login_change_path
148
- GET/POST /close-account rodauth.close_account_path
137
+ GET|POST /login rodauth.login_path
138
+ GET|POST /create-account rodauth.create_account_path
139
+ GET|POST /verify-account-resend rodauth.verify_account_resend_path
140
+ GET|POST /verify-account rodauth.verify_account_path
141
+ GET|POST /change-password rodauth.change_password_path
142
+ GET|POST /change-login rodauth.change_login_path
143
+ GET|POST /logout rodauth.logout_path
144
+ GET|POST /remember rodauth.remember_path
145
+ GET|POST /reset-password-request rodauth.reset_password_request_path
146
+ GET|POST /reset-password rodauth.reset_password_path
147
+ GET|POST /verify-login-change rodauth.verify_login_change_path
148
+ GET|POST /close-account rodauth.close_account_path
149
149
  ```
150
150
 
151
151
  Using this information, you can add some basic authentication links to your
@@ -236,7 +236,7 @@ level. You can do this via the built-in `authenticated` routing constraint:
236
236
  ```rb
237
237
  # config/routes.rb
238
238
  Rails.application.routes.draw do
239
- constraints Rodauth::Rails.authenticated do
239
+ constraints Rodauth::Rails.authenticate do
240
240
  # ... authenticated routes ...
241
241
  end
242
242
  end
@@ -249,7 +249,7 @@ called with the Rodauth instance:
249
249
  # config/routes.rb
250
250
  Rails.application.routes.draw do
251
251
  # require multifactor authentication to be setup
252
- constraints Rodauth::Rails.authenticated { |rodauth| rodauth.uses_two_factor_authentication? } do
252
+ constraints Rodauth::Rails.authenticate { |rodauth| rodauth.uses_two_factor_authentication? } do
253
253
  # ...
254
254
  end
255
255
  end
@@ -260,7 +260,7 @@ You can specify a different Rodauth configuration by passing the configuration n
260
260
  ```rb
261
261
  # config/routes.rb
262
262
  Rails.application.routes.draw do
263
- constraints Rodauth::Rails.authenticated(:admin) do
263
+ constraints Rodauth::Rails.authenticate(:admin) do
264
264
  # ...
265
265
  end
266
266
  end
@@ -712,12 +712,22 @@ RodauthMain.login(login: "email@example.com", password: "secret123")
712
712
  RodauthMain.close_account(account_login: "email@example.com")
713
713
  ```
714
714
 
715
- Note that you'll want to skip requiring `rodauth-rails` on Rails boot, so that it doesn't insert the middleware automatically, and remove the initializer.
715
+ Note that you'll want to skip requiring `rodauth-rails` on Rails boot, to avoid it automatically inserting the Rodauth middleware, and remove some unnecessary files generated by the install generator.
716
716
 
717
717
  ```rb
718
718
  # Gemfile
719
719
  gem "rodauth-rails", require: false
720
720
  ```
721
+ ```sh
722
+ $ rm config/initializers/rodauth.rb app/misc/rodauth_app.rb app/controllers/rodauth_controller.rb
723
+ ```
724
+
725
+ The `Rodauth::Rails.lib` call will forward any Rodauth [plugin options] passed to it:
726
+
727
+ ```rb
728
+ # skips loading Roda render plugin and Tilt gem (used for rendering built-in templates)
729
+ Rodauth::Rails.lib(render: false) { ... }
730
+ ```
721
731
 
722
732
  ## Testing
723
733
 
@@ -929,7 +939,7 @@ class RodauthApp < Rodauth::Rails::App
929
939
  configure(:admin) { ... }
930
940
 
931
941
  # plugin options
932
- configure(RodauthMain, json: :only)
942
+ configure(RodauthMain, json: :only, render: false)
933
943
  end
934
944
  ```
935
945
 
@@ -18,16 +18,17 @@ module Rodauth
18
18
  end
19
19
 
20
20
  plugin :hooks
21
- plugin :render, layout: false
22
21
  plugin :pass
23
22
 
24
23
  def self.configure(*args, **options, &block)
25
24
  auth_class = args.shift if args[0].is_a?(Class)
26
- name = args.shift if args[0].is_a?(Symbol)
25
+ auth_class ||= Class.new(Rodauth::Rails::Auth)
26
+ name = args.shift if args[0].is_a?(Symbol)
27
27
 
28
28
  fail ArgumentError, "need to pass optional Rodauth::Auth subclass and optional configuration name" if args.any?
29
29
 
30
- auth_class ||= Class.new(Rodauth::Rails::Auth)
30
+ # we'll render Rodauth's built-in view templates within Rails layouts
31
+ plugin :render, layout: false unless options[:render] == false
31
32
 
32
33
  plugin :rodauth, auth_class: auth_class, name: name, csrf: false, flash: false, json: true, **options, &block
33
34
 
@@ -0,0 +1,70 @@
1
+ module Rodauth
2
+ module Rails
3
+ module Tasks
4
+ class Routes
5
+ IGNORE = [:webauthn_setup_js, :webauthn_auth_js, :webauthn_autofill_js]
6
+ JSON_POST = [:two_factor_manage, :two_factor_auth]
7
+
8
+ attr_reader :auth_class
9
+
10
+ def initialize(auth_class)
11
+ @auth_class = auth_class
12
+ end
13
+
14
+ def call
15
+ routes = auth_class.route_hash.map do |path, handle_method|
16
+ route_name = handle_method.to_s.sub(/\Ahandle_/, "").to_sym
17
+ next if IGNORE.include?(route_name)
18
+ verbs = route_verbs(route_name)
19
+
20
+ [
21
+ verbs.join("|"),
22
+ "#{rodauth.prefix}#{path}",
23
+ "rodauth#{configuration_name && "(:#{configuration_name})"}.#{route_name}_path",
24
+ ]
25
+ end
26
+
27
+ routes.compact!
28
+ padding = routes.transpose.map { |string| string.map(&:length).max }
29
+
30
+ output_lines = routes.map do |columns|
31
+ [columns[0].ljust(padding[0]), columns[1].ljust(padding[1]), columns[2]].join(" ")
32
+ end
33
+
34
+ puts "\n #{output_lines.join("\n ")}"
35
+ end
36
+
37
+ private
38
+
39
+ def route_verbs(route_name)
40
+ file_path, start_line = rodauth.method(:"_handle_#{route_name}").source_location
41
+ lines = File.foreach(file_path).to_a
42
+ indentation = lines[start_line - 1][/^\s+/]
43
+ verbs = []
44
+
45
+ lines[start_line..-1].each do |code|
46
+ verbs << :GET if code.include?("r.get") && !rodauth.only_json?
47
+ verbs << :POST if code.include?("r.post")
48
+ break if code.start_with?("#{indentation}end")
49
+ end
50
+
51
+ verbs << :POST if rodauth.features.include?(:json) && JSON_POST.include?(route_name)
52
+ verbs
53
+ end
54
+
55
+ def rodauth
56
+ auth_class.new(scope)
57
+ end
58
+
59
+ def scope
60
+ auth_class.roda_class.new({})
61
+ end
62
+
63
+ def configuration_name
64
+ auth_class.configuration_name
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
@@ -1,42 +1,12 @@
1
+ require "rodauth/rails/tasks/routes"
2
+
1
3
  namespace :rodauth do
4
+ desc "Lists endpoints that will be routed by your Rodauth app"
2
5
  task routes: :environment do
3
- app = Rodauth::Rails.app
4
-
5
- puts "Routes handled by #{app}:"
6
-
7
- app.opts[:rodauths].each do |configuration_name, auth_class|
8
- rodauth = auth_class.allocate
9
- only_json = rodauth.method(:only_json?).owner != Rodauth::Base && rodauth.only_json?
10
-
11
- routes = auth_class.route_hash.map do |path, handle_method|
12
- file_path, start_line = rodauth.method(:"_#{handle_method}").source_location
13
- lines = File.foreach(file_path).to_a
14
- indentation = lines[start_line - 1][/^\s+/]
15
- verbs = []
16
-
17
- lines[start_line..-1].each do |code|
18
- verbs << :GET if code.include?("r.get") && !only_json
19
- verbs << :POST if code.include?("r.post")
20
- break if code.start_with?("#{indentation}end")
21
- end
22
-
23
- path_method = "#{handle_method.to_s.sub(/\Ahandle_/, "")}_path"
24
-
25
- [
26
- verbs.join("/"),
27
- "#{rodauth.prefix}#{path}",
28
- "rodauth#{configuration_name && "(:#{configuration_name})"}.#{path_method}",
29
- ]
30
- end
31
-
32
- verbs_padding = routes.map { |verbs, _, _| verbs.length }.max
33
- path_padding = routes.map { |_, path, _| path.length }.max
34
-
35
- route_lines = routes.map do |verbs, path, code|
36
- "#{verbs.ljust(verbs_padding)} #{path.ljust(path_padding)} #{code}"
37
- end
6
+ puts "Routes handled by #{Rodauth::Rails.app}:"
38
7
 
39
- puts "\n #{route_lines.join("\n ")}" unless route_lines.empty?
8
+ Rodauth::Rails.app.opts[:rodauths].each_value do |auth_class|
9
+ Rodauth::Rails::Tasks::Routes.new(auth_class).call
40
10
  end
41
11
  end
42
12
  end
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "1.10.0"
3
+ VERSION = "1.11.0"
4
4
  end
5
5
  end
data/lib/rodauth/rails.rb CHANGED
@@ -16,9 +16,9 @@ module Rodauth
16
16
  @middleware = true
17
17
 
18
18
  class << self
19
- def lib(&block)
19
+ def lib(**options, &block)
20
20
  c = Class.new(Rodauth::Rails::App)
21
- c.configure(json: false) do
21
+ c.configure(json: false, **options) do
22
22
  enable :internal_request
23
23
  instance_exec(&block)
24
24
  end
@@ -57,8 +57,17 @@ module Rodauth
57
57
  Rodauth::Model.new(app.rodauth!(name), **options)
58
58
  end
59
59
 
60
- # routing constraint that requires authentication
60
+ # Routing constraint that requires authenticated account.
61
+ def authenticate(name = nil, &condition)
62
+ lambda do |request|
63
+ rodauth = request.env.fetch ["rodauth", *name].join(".")
64
+ rodauth.require_account
65
+ condition.nil? || condition.call(rodauth)
66
+ end
67
+ end
68
+
61
69
  def authenticated(name = nil, &condition)
70
+ warn "Rodauth::Rails.authenticated has been deprecated in favor of Rodauth::Rails.authenticate, which additionally requires existence of the account record."
62
71
  lambda do |request|
63
72
  rodauth = request.env.fetch ["rodauth", *name].join(".")
64
73
  rodauth.require_authentication
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.10.0
4
+ version: 1.11.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-07-26 00:00:00.000000000 Z
11
+ date: 2023-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -328,6 +328,7 @@ files:
328
328
  - lib/rodauth/rails/model.rb
329
329
  - lib/rodauth/rails/railtie.rb
330
330
  - lib/rodauth/rails/tasks.rake
331
+ - lib/rodauth/rails/tasks/routes.rb
331
332
  - lib/rodauth/rails/test.rb
332
333
  - lib/rodauth/rails/test/controller.rb
333
334
  - lib/rodauth/rails/version.rb
@@ -351,7 +352,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
351
352
  - !ruby/object:Gem::Version
352
353
  version: '0'
353
354
  requirements: []
354
- rubygems_version: 3.4.12
355
+ rubygems_version: 3.4.10
355
356
  signing_key:
356
357
  specification_version: 4
357
358
  summary: Provides Rails integration for Rodauth.