rodauth-rails 1.10.0 → 1.11.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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +27 -17
- data/lib/rodauth/rails/app.rb +4 -3
- data/lib/rodauth/rails/tasks/routes.rb +70 -0
- data/lib/rodauth/rails/tasks.rake +6 -36
- data/lib/rodauth/rails/version.rb +1 -1
- data/lib/rodauth/rails.rb +12 -3
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f902ae05472454543304221221b9681c7dab3d231d6551c7e82b6c4c1570dc8
|
4
|
+
data.tar.gz: b3a1948fb603be978bddea73a44b8109f4e3c76e132b2da3a8e6aad1b36f3d14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
138
|
-
GET
|
139
|
-
GET
|
140
|
-
GET
|
141
|
-
GET
|
142
|
-
GET
|
143
|
-
GET
|
144
|
-
GET
|
145
|
-
GET
|
146
|
-
GET
|
147
|
-
GET
|
148
|
-
GET
|
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.
|
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.
|
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.
|
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,
|
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
|
|
data/lib/rodauth/rails/app.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
#
|
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.
|
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-
|
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.
|
355
|
+
rubygems_version: 3.4.10
|
355
356
|
signing_key:
|
356
357
|
specification_version: 4
|
357
358
|
summary: Provides Rails integration for Rodauth.
|