rodauth-rails 0.1.3 → 0.4.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 +54 -0
- data/README.md +60 -44
- data/lib/generators/rodauth/install_generator.rb +27 -11
- data/lib/generators/rodauth/templates/{lib → app/lib}/rodauth_app.rb +34 -24
- data/lib/generators/rodauth/templates/app/views/rodauth/_login_form_footer.html.erb +0 -15
- data/lib/generators/rodauth/templates/app/views/rodauth/_password_field.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/logout.html.erb +0 -2
- data/lib/generators/rodauth/templates/app/views/rodauth/otp_auth.html.erb +0 -9
- data/lib/generators/rodauth/templates/config/initializers/sequel.rb +5 -10
- data/lib/generators/rodauth/templates/db/migrate/create_rodauth.rb +17 -8
- data/lib/generators/rodauth/views_generator.rb +20 -21
- data/lib/rodauth/rails.rb +1 -1
- data/lib/rodauth/rails/app.rb +5 -4
- data/lib/rodauth/rails/app/flash.rb +1 -1
- data/lib/rodauth/rails/feature.rb +8 -16
- data/lib/rodauth/rails/version.rb +5 -0
- data/rodauth-rails.gemspec +5 -3
- metadata +12 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd5d6b153ae21b024570d612aff57a2c0d6f090f2215723b25bbc362ee743c9b
|
4
|
+
data.tar.gz: e6aac1fe20d00bd4c94559c74dbc56bd971da4404d086ec3193db8e06fe2a3bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83a5c386eaf39c7aa9b0536e9aed25e8a61bc069e2388bee556b28e9ee00941528fd5431199711d77a28212d281376258ecf0b914d6aa928954d8d99543b827b
|
7
|
+
data.tar.gz: 815d7fee34954d2f512e4532d02bb9d183ad9bde92fc622d522c517cd9db575c8fef98c857dce81c8329cd1798481b8e2f4609390b2472d83825d393886a3576
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
## 0.4.0 (2020-11-02)
|
2
|
+
|
3
|
+
* Support Rails API-only mode (@janko)
|
4
|
+
|
5
|
+
* Make `rodauth:install` create `rodauth_app.rb` in `app/lib/` directory (@janko)
|
6
|
+
|
7
|
+
## 0.3.1 (2020-10-25)
|
8
|
+
|
9
|
+
* Depend on sequel-activerecord_connection 1.0+ (@janko)
|
10
|
+
|
11
|
+
## 0.3.0 (2020-09-18)
|
12
|
+
|
13
|
+
* Handle custom configured database migration paths in install generator (@janko)
|
14
|
+
|
15
|
+
* Allow specifying features as plain arguments in `rodauth:views` generator (@janko)
|
16
|
+
|
17
|
+
* Add some missing foreign key constraints in generated migration file (@janko)
|
18
|
+
|
19
|
+
## 0.2.1 (2020-07-26)
|
20
|
+
|
21
|
+
* Fix incorrect JDBC connect syntax in `sequel.rb` template on JRuby (@janko)
|
22
|
+
|
23
|
+
## 0.2.0 (2020-07-26)
|
24
|
+
|
25
|
+
* Drop support for Rodauth 1.x (@janko)
|
26
|
+
|
27
|
+
* Change `rodauth_app.rb` template to send emails in the background after transaction commit (@janko)
|
28
|
+
|
29
|
+
* Bump `sequel-activerecord_connection` dependency to `~> 0.3` (@janko)
|
30
|
+
|
31
|
+
* Use the JDBC adapter in sequel.rb initializer when on JRuby (@janko)
|
32
|
+
|
33
|
+
## 0.1.3 (2020-07-04)
|
34
|
+
|
35
|
+
* Remove insecure MFA integration with remember feature suggestion in `lib/rodauth_app.rb` (@janko, @nicolas-besnard)
|
36
|
+
|
37
|
+
* Use correct password autocomplete value on Rodauth 2.1+ (@janko)
|
38
|
+
|
39
|
+
* Enable skipping CSRF protection on Rodauth 2.1+ by overriding `#check_csrf?` (@janko)
|
40
|
+
|
41
|
+
* Don't generate Sequel initializer if Sequel connection exists (@janko)
|
42
|
+
|
43
|
+
* Fix typo in remember view template (@nicolas-besnard)
|
44
|
+
|
45
|
+
* Fix some more typos in `lib/rodauth_app.rb` (@janko)
|
46
|
+
|
47
|
+
## 0.1.2 (2020-05-14)
|
48
|
+
|
49
|
+
* Fix some typos in comment suggestions in `lib/rodauth_app.rb` (@janko)
|
50
|
+
|
51
|
+
## 0.1.1 (2020-05-09)
|
52
|
+
|
53
|
+
* Include view templates in the gem (@janko)
|
54
|
+
* Use `Login` labels to be consistent with Rodauth (@janko)
|
data/README.md
CHANGED
@@ -13,7 +13,12 @@ Provides Rails integration for the [Rodauth] authentication framework.
|
|
13
13
|
Add the gem to your Gemfile:
|
14
14
|
|
15
15
|
```rb
|
16
|
-
gem "rodauth-rails", "~> 0.
|
16
|
+
gem "rodauth-rails", "~> 0.3"
|
17
|
+
|
18
|
+
# gem "jwt", require: false # for JWT feature
|
19
|
+
# gem "rotp", require: false # for OTP feature
|
20
|
+
# gem "rqrcode", require: false # for OTP feature
|
21
|
+
# gem "webauthn", require: false # for WebAuthn feature
|
17
22
|
```
|
18
23
|
|
19
24
|
Then run `bundle install`.
|
@@ -29,7 +34,7 @@ The generator will create the following files:
|
|
29
34
|
* Rodauth migration at `db/migrate/*_create_rodauth.rb`
|
30
35
|
* Rodauth initializer at `config/initializers/rodauth.rb`
|
31
36
|
* Sequel initializer at `config/initializers/sequel.rb` for ActiveRecord integration
|
32
|
-
* Rodauth app at `lib/rodauth_app.rb`
|
37
|
+
* Rodauth app at `app/lib/rodauth_app.rb`
|
33
38
|
* Rodauth controller at `app/controllers/rodauth_controller.rb`
|
34
39
|
* Account model at `app/models/account.rb`
|
35
40
|
|
@@ -82,20 +87,18 @@ ActiveRecord connection.
|
|
82
87
|
# config/initializers/sequel.rb
|
83
88
|
require "sequel/core"
|
84
89
|
|
85
|
-
# initialize
|
86
|
-
DB = Sequel.postgres(
|
87
|
-
# have Sequel use ActiveRecord's connection for database interaction
|
88
|
-
DB.extension :activerecord_connection
|
90
|
+
# initialize Sequel and have it reuse Active Record's database connection
|
91
|
+
DB = Sequel.postgres(extensions: :activerecord_connection)
|
89
92
|
```
|
90
93
|
|
91
94
|
### Rodauth app
|
92
95
|
|
93
|
-
Your Rodauth app is created in the `lib/` directory,
|
94
|
-
set of authentication features enabled, as well as extensive examples
|
95
|
-
you can configure authentication behaviour.
|
96
|
+
Your Rodauth app is created in the `app/lib/` directory, and comes with a
|
97
|
+
default set of authentication features enabled, as well as extensive examples
|
98
|
+
on ways you can configure authentication behaviour.
|
96
99
|
|
97
100
|
```rb
|
98
|
-
# lib/rodauth_app.rb
|
101
|
+
# app/lib/rodauth_app.rb
|
99
102
|
class RodauthApp < Rodauth::Rails::App
|
100
103
|
configure do
|
101
104
|
# authentication configuration
|
@@ -107,19 +110,6 @@ class RodauthApp < Rodauth::Rails::App
|
|
107
110
|
end
|
108
111
|
```
|
109
112
|
|
110
|
-
Note that Rails doesn't autoload files in the `lib/` directory by default, so
|
111
|
-
make sure to add `lib/` to your `config.autoload_paths`:
|
112
|
-
|
113
|
-
```rb
|
114
|
-
# config/application.rb
|
115
|
-
module YourApp
|
116
|
-
class Application < Rails::Application
|
117
|
-
# ...
|
118
|
-
config.autoload_paths += %W[#{config.root}/lib]
|
119
|
-
end
|
120
|
-
end
|
121
|
-
```
|
122
|
-
|
123
113
|
### Controller
|
124
114
|
|
125
115
|
Your Rodauth app will by default use `RodauthController` for view rendering
|
@@ -162,17 +152,24 @@ These links are fully functional, feel free to visit them and interact with the
|
|
162
152
|
pages. The templates that ship with Rodauth aim to provide a complete
|
163
153
|
authentication experience, and the forms use [Bootstrap] markup.
|
164
154
|
|
165
|
-
Let's also
|
166
|
-
|
155
|
+
Let's also load the account record for authenticated requests and expose it via
|
156
|
+
`#current_account`:
|
167
157
|
|
168
158
|
```rb
|
169
159
|
# app/controllers/application_controller.rb
|
170
160
|
class ApplicationController < ActionController::Base
|
161
|
+
before_action :load_account, if: -> { rodauth.authenticated? }
|
162
|
+
|
171
163
|
private
|
172
164
|
|
173
|
-
def
|
174
|
-
@current_account
|
165
|
+
def load_account
|
166
|
+
@current_account = Account.find(rodauth.session_value)
|
167
|
+
rescue ActiveRecord::RecordNotFound
|
168
|
+
rodauth.logout
|
169
|
+
rodauth.login_required
|
175
170
|
end
|
171
|
+
|
172
|
+
attr_reader :current_account
|
176
173
|
helper_method :current_account
|
177
174
|
end
|
178
175
|
```
|
@@ -258,7 +255,7 @@ You can pass a list of Rodauth features to the generator to create views for
|
|
258
255
|
these features (this will not remove any existing views):
|
259
256
|
|
260
257
|
```sh
|
261
|
-
$ rails generate rodauth:views
|
258
|
+
$ rails generate rodauth:views login create_account lockout otp
|
262
259
|
```
|
263
260
|
|
264
261
|
Or you can generate views for all features:
|
@@ -358,23 +355,31 @@ class RodauthApp < Rodauth::Rails::App
|
|
358
355
|
configure do
|
359
356
|
# ...
|
360
357
|
send_reset_password_email do
|
361
|
-
|
358
|
+
mailer_send(:reset_password, email_to, reset_password_email_link)
|
362
359
|
end
|
363
360
|
send_verify_account_email do
|
364
|
-
|
361
|
+
mailer_send(:verify_account, email_to, verify_account_email_link)
|
365
362
|
end
|
366
363
|
send_verify_login_change_email do |login|
|
367
|
-
|
364
|
+
mailer_send(:verify_login_change, login, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_email_link)
|
368
365
|
end
|
369
366
|
send_password_changed_email do
|
370
|
-
|
367
|
+
mailer_send(:password_changed, email_to)
|
371
368
|
end
|
372
369
|
# send_email_auth_email do
|
373
|
-
#
|
370
|
+
# mailer_send(:email_auth, email_to, email_auth_email_link)
|
374
371
|
# end
|
375
372
|
# send_unlock_account_email do
|
376
|
-
#
|
373
|
+
# mailer_send(:unlock_account, email_to, unlock_account_email_link)
|
377
374
|
# end
|
375
|
+
auth_class_eval do
|
376
|
+
# queue email delivery on the mailer after the transaction commits
|
377
|
+
def mailer_send(type, *args)
|
378
|
+
db.after_commit do
|
379
|
+
RodauthMailer.public_send(type, *args).deliver_later
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
378
383
|
# ...
|
379
384
|
end
|
380
385
|
end
|
@@ -399,7 +404,7 @@ The Rodauth app stores the `Rodauth::Auth` instance in the Rack env hash, which
|
|
399
404
|
is then available in your Rails app:
|
400
405
|
|
401
406
|
```rb
|
402
|
-
request.env["rodauth"]
|
407
|
+
request.env["rodauth"] #=> #<Rodauth::Auth>
|
403
408
|
request.env["rodauth.secondary"] #=> #<Rodauth::Auth> (if using multiple configurations)
|
404
409
|
```
|
405
410
|
|
@@ -409,13 +414,13 @@ and controllers:
|
|
409
414
|
```rb
|
410
415
|
class MyController < ApplicationController
|
411
416
|
def my_action
|
412
|
-
rodauth
|
417
|
+
rodauth #=> #<Rodauth::Auth>
|
413
418
|
rodauth(:secondary) #=> #<Rodauth::Auth> (if using multiple configurations)
|
414
419
|
end
|
415
420
|
end
|
416
421
|
```
|
417
422
|
```erb
|
418
|
-
<% rodauth
|
423
|
+
<% rodauth #=> #<Rodauth::Auth> %>
|
419
424
|
<% rodauth(:secondary) #=> #<Rodauth::Auth> (if using multiple configurations) %>
|
420
425
|
```
|
421
426
|
|
@@ -431,11 +436,11 @@ integration for Rodauth:
|
|
431
436
|
* uses ActionMailer for sending emails
|
432
437
|
|
433
438
|
The `configure { ... }` method wraps configuring the Rodauth plugin, forwarding
|
434
|
-
any additional [options].
|
439
|
+
any additional [plugin options].
|
435
440
|
|
436
441
|
```rb
|
437
442
|
configure { ... } # defining default Rodauth configuration
|
438
|
-
configure(json: true)
|
443
|
+
configure(json: true) { ... } # passing options to the Rodauth plugin
|
439
444
|
configure(:secondary) { ... } # defining multiple Rodauth configurations
|
440
445
|
```
|
441
446
|
|
@@ -487,18 +492,26 @@ end
|
|
487
492
|
|
488
493
|
## Working with JWT
|
489
494
|
|
490
|
-
To
|
495
|
+
To use Rodauth's [JWT feature], you'll need to load Roda's JSON support in
|
496
|
+
`configure`:
|
491
497
|
|
492
498
|
```rb
|
493
499
|
# lib/rodauth_app.rb
|
494
500
|
class RodauthApp < Rodauth::Rails::App
|
495
501
|
configure(json: true) do
|
496
502
|
enable :jwt
|
503
|
+
jwt_secret "...your secret key..."
|
497
504
|
# your configuration
|
498
505
|
end
|
499
506
|
end
|
500
507
|
```
|
501
508
|
|
509
|
+
Make sure to store the `jwt_secret` in a secure place, such as Rails
|
510
|
+
credentials or environment variables.
|
511
|
+
|
512
|
+
Rodauth's JWT feature depends on the [JWT gem], so make sure to add it to your
|
513
|
+
Gemfile.
|
514
|
+
|
502
515
|
## Testing
|
503
516
|
|
504
517
|
If you're writing system tests, it's generally better to go through the actual
|
@@ -595,10 +608,14 @@ create_table :accounts do |t|
|
|
595
608
|
end
|
596
609
|
```
|
597
610
|
```diff
|
611
|
+
configure do
|
612
|
+
# ...
|
598
613
|
- account_status_column :status
|
599
614
|
- account_unverified_status_value "unverified"
|
600
615
|
- account_open_status_value "verified"
|
601
616
|
- account_closed_status_value "closed"
|
617
|
+
# ...
|
618
|
+
end
|
602
619
|
```
|
603
620
|
|
604
621
|
## License
|
@@ -616,13 +633,12 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
|
|
616
633
|
[Sequel]: https://github.com/jeremyevans/sequel
|
617
634
|
[rendering views outside of controllers]: https://blog.bigbinary.com/2016/01/08/rendering-views-outside-of-controllers-in-rails-5.html
|
618
635
|
[feature documentation]: http://rodauth.jeremyevans.net/documentation.html
|
619
|
-
[
|
620
|
-
[
|
636
|
+
[JWT feature]: http://rodauth.jeremyevans.net/rdoc/files/doc/jwt_rdoc.html
|
637
|
+
[JWT gem]: https://github.com/jwt/ruby-jwt
|
621
638
|
[Bootstrap]: https://getbootstrap.com/
|
622
639
|
[Roda]: http://roda.jeremyevans.net/
|
623
640
|
[HMAC]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-HMAC
|
624
641
|
[database authentication functions]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Password+Hash+Access+Via+Database+Functions
|
625
|
-
[multiple configurations]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-With+Multiple+Configurations
|
626
|
-
[views]: /app/views/rodauth
|
627
642
|
[Rodauth migration]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Creating+tables
|
628
643
|
[sequel-activerecord_connection]: https://github.com/janko/sequel-activerecord_connection
|
644
|
+
[plugin options]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Plugin+Options
|
@@ -1,12 +1,13 @@
|
|
1
1
|
require "rails/generators/base"
|
2
|
-
require "rails/generators/migration"
|
3
|
-
|
2
|
+
require "rails/generators/active_record/migration"
|
3
|
+
|
4
|
+
require "securerandom"
|
4
5
|
|
5
6
|
module Rodauth
|
6
7
|
module Rails
|
7
8
|
module Generators
|
8
9
|
class InstallGenerator < ::Rails::Generators::Base
|
9
|
-
include ::
|
10
|
+
include ::ActiveRecord::Generators::Migration
|
10
11
|
|
11
12
|
source_root "#{__dir__}/templates"
|
12
13
|
namespace "rodauth:install"
|
@@ -14,7 +15,7 @@ module Rodauth
|
|
14
15
|
def create_rodauth_migration
|
15
16
|
return unless defined?(ActiveRecord::Base)
|
16
17
|
|
17
|
-
migration_template "db/migrate/create_rodauth.rb", "
|
18
|
+
migration_template "db/migrate/create_rodauth.rb", File.join(db_migrate_path, "create_rodauth.rb")
|
18
19
|
end
|
19
20
|
|
20
21
|
def create_rodauth_initializer
|
@@ -23,14 +24,14 @@ module Rodauth
|
|
23
24
|
|
24
25
|
def create_sequel_initializer
|
25
26
|
return unless defined?(ActiveRecord::Base)
|
26
|
-
return unless %w[postgresql mysql2 sqlite3].include?(
|
27
|
+
return unless %w[postgresql mysql2 sqlite3].include?(activerecord_adapter)
|
27
28
|
return if defined?(Sequel) && !Sequel::DATABASES.empty?
|
28
29
|
|
29
30
|
template "config/initializers/sequel.rb"
|
30
31
|
end
|
31
32
|
|
32
33
|
def create_rodauth_app
|
33
|
-
template "lib/rodauth_app.rb"
|
34
|
+
template "app/lib/rodauth_app.rb"
|
34
35
|
end
|
35
36
|
|
36
37
|
def create_rodauth_controller
|
@@ -45,20 +46,35 @@ module Rodauth
|
|
45
46
|
|
46
47
|
private
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def db_migrate_path
|
50
|
+
return "db/migrate" unless ActiveRecord.version >= Gem::Version.new("5.0")
|
51
|
+
|
52
|
+
super
|
51
53
|
end
|
52
54
|
|
53
55
|
def migration_version
|
54
|
-
if ActiveRecord.version >= Gem::Version.new("5.0
|
56
|
+
if ActiveRecord.version >= Gem::Version.new("5.0")
|
55
57
|
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
59
|
-
def
|
61
|
+
def sequel_adapter
|
62
|
+
case activerecord_adapter
|
63
|
+
when "postgresql" then "postgres#{"ql" if RUBY_ENGINE == "jruby"}"
|
64
|
+
when "mysql2" then "mysql#{"2" unless RUBY_ENGINE == "jruby"}"
|
65
|
+
when "sqlite3" then "sqlite"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def activerecord_adapter
|
60
70
|
ActiveRecord::Base.connection_config.fetch(:adapter)
|
61
71
|
end
|
72
|
+
|
73
|
+
def api_only?
|
74
|
+
return false if ::Rails.gem_version < Gem::Version.new("5.0")
|
75
|
+
|
76
|
+
::Rails.application.config.api_only
|
77
|
+
end
|
62
78
|
end
|
63
79
|
end
|
64
80
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class RodauthApp < Rodauth::Rails::App
|
2
|
-
configure do
|
2
|
+
configure<%= " json: :only" if api_only? %> do
|
3
3
|
# List of authentication features that are loaded.
|
4
4
|
enable :create_account, :verify_account, :verify_account_grace_period,
|
5
|
-
:login, :
|
5
|
+
:login, :logout, <%= api_only? ? ":jwt" : ":remember" %>,
|
6
6
|
:reset_password, :change_password, :change_password_notify,
|
7
7
|
:change_login, :verify_login_change,
|
8
8
|
:close_account
|
@@ -38,30 +38,47 @@ class RodauthApp < Rodauth::Rails::App
|
|
38
38
|
|
39
39
|
# Redirect to the app from login and registration pages if already logged in.
|
40
40
|
# already_logged_in { redirect login_redirect }
|
41
|
+
<% if api_only? -%>
|
42
|
+
|
43
|
+
# ==> JWT
|
44
|
+
# Set JWT secret, which is used to cryptographically protect the token.
|
45
|
+
jwt_secret "<%= SecureRandom.hex(64) %>"
|
46
|
+
|
47
|
+
# Don't require login confirmation param.
|
48
|
+
require_login_confirmation? false
|
49
|
+
|
50
|
+
# Don't require password confirmation param.
|
51
|
+
require_password_confirmation? false
|
52
|
+
<% end -%>
|
41
53
|
|
42
54
|
# ==> Emails
|
43
55
|
# Uncomment the lines below once you've imported mailer views.
|
44
56
|
# send_reset_password_email do
|
45
|
-
#
|
57
|
+
# mailer_send(:reset_password, email_to, reset_password_email_link)
|
46
58
|
# end
|
47
59
|
# send_verify_account_email do
|
48
|
-
#
|
60
|
+
# mailer_send(:verify_account, email_to, verify_account_email_link)
|
49
61
|
# end
|
50
62
|
# send_verify_login_change_email do |login|
|
51
|
-
#
|
63
|
+
# mailer_send(:verify_login_change, login, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_email_link)
|
52
64
|
# end
|
53
65
|
# send_password_changed_email do
|
54
|
-
#
|
66
|
+
# mailer_send(:password_changed, email_to)
|
55
67
|
# end
|
56
68
|
# # send_email_auth_email do
|
57
|
-
# #
|
69
|
+
# # mailer_send(:email_auth, email_to, email_auth_email_link)
|
58
70
|
# # end
|
59
71
|
# # send_unlock_account_email do
|
60
|
-
|
61
|
-
# # @unlock_account_key_value = get_unlock_account_key
|
62
|
-
<% end -%>
|
63
|
-
# # RodauthMailer.unlock_account(email_to, unlock_account_email_link).deliver_now
|
72
|
+
# # mailer_send(:unlock_account, email_to, unlock_account_email_link)
|
64
73
|
# # end
|
74
|
+
# auth_class_eval do
|
75
|
+
# # queue email delivery on the mailer after the transaction commits
|
76
|
+
# def mailer_send(type, *args)
|
77
|
+
# db.after_commit do
|
78
|
+
# RodauthMailer.public_send(type, *args).deliver_later
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
# end
|
65
82
|
|
66
83
|
# In the meantime you can tweak settings for emails created by Rodauth
|
67
84
|
# email_subject_prefix "[MyApp] "
|
@@ -70,10 +87,12 @@ class RodauthApp < Rodauth::Rails::App
|
|
70
87
|
# reset_password_email_body { "Click here to reset your password: #{reset_password_email_link}" }
|
71
88
|
|
72
89
|
# ==> Flash
|
90
|
+
<% unless api_only? -%>
|
73
91
|
# Match flash keys with ones already used in the Rails app.
|
74
92
|
# flash_notice_key :success # default is :notice
|
75
93
|
# flash_error_key :error # default is :alert
|
76
94
|
|
95
|
+
<% end -%>
|
77
96
|
# Override default flash messages.
|
78
97
|
# create_account_notice_flash "Your account has been created. Please verify your account by visiting the confirmation link sent to your email address."
|
79
98
|
# require_login_error_flash "Login is required for accessing this page"
|
@@ -88,6 +107,7 @@ class RodauthApp < Rodauth::Rails::App
|
|
88
107
|
|
89
108
|
# Change minimum number of password characters required when creating an account.
|
90
109
|
# password_minimum_length 8
|
110
|
+
<% unless api_only? -%>
|
91
111
|
|
92
112
|
# ==> Remember Feature
|
93
113
|
# Remember all logged in users.
|
@@ -98,6 +118,7 @@ class RodauthApp < Rodauth::Rails::App
|
|
98
118
|
|
99
119
|
# Extend user's remember period when remembered via a cookie
|
100
120
|
extend_remember_deadline? true
|
121
|
+
<% end -%>
|
101
122
|
|
102
123
|
# ==> Hooks
|
103
124
|
# Validate custom fields in the create account form.
|
@@ -131,19 +152,6 @@ class RodauthApp < Rodauth::Rails::App
|
|
131
152
|
# reset_password_deadline_interval Hash[hours: 6]
|
132
153
|
# verify_login_change_deadline_interval Hash[days: 2]
|
133
154
|
# remember_deadline_interval Hash[days: 30]
|
134
|
-
|
135
|
-
# ==> Extending
|
136
|
-
# Define any additional methods you want for the Rodauth object.
|
137
|
-
# auth_class_eval do
|
138
|
-
# def my_send_email(name, *args)
|
139
|
-
# AuthenticationMailer.public_send(name, *args).deliver_later
|
140
|
-
# end
|
141
|
-
# end
|
142
|
-
#
|
143
|
-
# Then use the new custom method in configuration blocks.
|
144
|
-
# send_reset_password_email do
|
145
|
-
# my_send_email(:reset_password, email_to, reset_password_email_link)
|
146
|
-
# end
|
147
155
|
end
|
148
156
|
|
149
157
|
# ==> Multiple configurations
|
@@ -155,8 +163,10 @@ class RodauthApp < Rodauth::Rails::App
|
|
155
163
|
# end
|
156
164
|
|
157
165
|
route do |r|
|
166
|
+
<% unless api_only? -%>
|
158
167
|
rodauth.load_memory # autologin remembered users
|
159
168
|
|
169
|
+
<% end -%>
|
160
170
|
r.rodauth # route rodauth requests
|
161
171
|
|
162
172
|
# ==> Authenticating Requests
|
@@ -1,4 +1,3 @@
|
|
1
|
-
<% if Rodauth::MAJOR >= 2 -%>
|
2
1
|
<%% unless rodauth.login_form_footer_links.empty? %>
|
3
2
|
<h2>Other Options</h2>
|
4
3
|
<ul>
|
@@ -7,17 +6,3 @@
|
|
7
6
|
<%% end %>
|
8
7
|
</ul>
|
9
8
|
<%% end %>
|
10
|
-
<% else -%>
|
11
|
-
<%% if rodauth.features.include?(:create_account) %>
|
12
|
-
<p><%%= link_to "Create a New Account", rodauth.create_account_path %></p>
|
13
|
-
<%% end %>
|
14
|
-
<%% if rodauth.features.include?(:reset_password) %>
|
15
|
-
<p><%%= link_to "Forgot Password?", rodauth.reset_password_request_path %></p>
|
16
|
-
<%% end %>
|
17
|
-
<%% if rodauth.features.include?(:email_auth) && rodauth.valid_login_entered? %>
|
18
|
-
<%%= render "email_auth_request_form" %>
|
19
|
-
<%% end %>
|
20
|
-
<%% if rodauth.features.include?(:verify_account) %>
|
21
|
-
<p><%%= link_to "Resend Verify Account Information", rodauth.verify_account_resend_path %></p>
|
22
|
-
<%% end %>
|
23
|
-
<% end -%>
|
@@ -1,4 +1,4 @@
|
|
1
1
|
<div class="form-group">
|
2
2
|
<%%= label_tag "password", "Password" %>
|
3
|
-
<%%= render "field", name: rodauth.password_param, id: "password", type: :password, value: "", autocomplete:
|
3
|
+
<%%= render "field", name: rodauth.password_param, id: "password", type: :password, value: "", autocomplete: rodauth.password_field_autocomplete_value %>
|
4
4
|
</div>
|
@@ -2,12 +2,3 @@
|
|
2
2
|
<%%= render "otp_auth_code_field" %>
|
3
3
|
<%%= render "submit", value: "Authenticate Using TOTP" %>
|
4
4
|
<%% end %>
|
5
|
-
<% if Rodauth::MAJOR == 1 -%>
|
6
|
-
|
7
|
-
<%% if rodauth.features.include?(:sms_codes) && rodauth.sms_available? %>
|
8
|
-
<p><%%= link_to "Authenticate using SMS code", rodauth.sms_request_path %></p>
|
9
|
-
<%% end %>
|
10
|
-
<%% if rodauth.features.include?(:recovery_codes) %>
|
11
|
-
<p><%%= link_to "Authenticate using recovery code", rodauth.recovery_auth_path %></p>
|
12
|
-
<%% end %>
|
13
|
-
<% end -%>
|
@@ -1,13 +1,8 @@
|
|
1
1
|
require "sequel/core"
|
2
2
|
|
3
|
-
# initialize
|
4
|
-
<%
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
DB = Sequel.mysql2(test: false)
|
9
|
-
<% when "sqlite3" -%>
|
10
|
-
DB = Sequel.sqlite(test: false)
|
3
|
+
# initialize Sequel and have it reuse Active Record's database connection
|
4
|
+
<% if RUBY_ENGINE == "jruby" -%>
|
5
|
+
DB = Sequel.connect("jdbc:<%= sequel_adapter %>://", extensions: :activerecord_connection)
|
6
|
+
<% else -%>
|
7
|
+
DB = Sequel.<%= sequel_adapter %>(extensions: :activerecord_connection)
|
11
8
|
<% end -%>
|
12
|
-
# have Sequel use ActiveRecord's connection for database interaction
|
13
|
-
DB.extension :activerecord_connection
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class CreateRodauth < ActiveRecord::Migration<%= migration_version %>
|
2
2
|
def change
|
3
|
-
<% if
|
3
|
+
<% if activerecord_adapter == "postgresql" -%>
|
4
4
|
enable_extension "citext"
|
5
5
|
|
6
6
|
<% end -%>
|
7
7
|
create_table :accounts do |t|
|
8
|
-
<% case
|
8
|
+
<% case activerecord_adapter -%>
|
9
9
|
<% when "postgresql" -%>
|
10
10
|
t.citext :email, null: false, index: { unique: true, where: "status IN ('verified', 'unverified')" }
|
11
11
|
<% else -%>
|
@@ -44,19 +44,28 @@ class CreateRodauth < ActiveRecord::Migration<%= migration_version %>
|
|
44
44
|
t.datetime :deadline, null: false
|
45
45
|
end
|
46
46
|
|
47
|
+
<% unless api_only? -%>
|
47
48
|
# Used by the remember me feature
|
48
49
|
create_table :account_remember_keys do |t|
|
49
50
|
t.foreign_key :accounts, column: :id
|
50
51
|
t.string :key, null: false
|
51
52
|
t.datetime :deadline, null: false
|
52
53
|
end
|
54
|
+
<% else -%>
|
55
|
+
# # Used by the remember me feature
|
56
|
+
# create_table :account_remember_keys do |t|
|
57
|
+
# t.foreign_key :accounts, column: :id
|
58
|
+
# t.string :key, null: false
|
59
|
+
# t.datetime :deadline, null: false
|
60
|
+
# end
|
61
|
+
<% end -%>
|
53
62
|
|
54
63
|
# # Used by the audit logging feature
|
55
64
|
# create_table :account_authentication_audit_logs do |t|
|
56
|
-
# t.references :account, null: false
|
65
|
+
# t.references :account, foreign_key: true, null: false
|
57
66
|
# t.datetime :at, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
58
67
|
# t.text :message, null: false
|
59
|
-
<% case
|
68
|
+
<% case activerecord_adapter -%>
|
60
69
|
<% when "postgresql" -%>
|
61
70
|
# t.jsonb :metadata
|
62
71
|
<% when "sqlite3", "mysql2" -%>
|
@@ -70,7 +79,7 @@ class CreateRodauth < ActiveRecord::Migration<%= migration_version %>
|
|
70
79
|
|
71
80
|
# # Used by the jwt refresh feature
|
72
81
|
# create_table :account_jwt_refresh_keys do |t|
|
73
|
-
# t.references :account, null: false
|
82
|
+
# t.references :account, foreign_key: true, null: false
|
74
83
|
# t.string :key, null: false
|
75
84
|
# t.datetime :deadline, null: false
|
76
85
|
# t.index :account_id, name: "account_jwt_rk_account_id_idx"
|
@@ -78,7 +87,7 @@ class CreateRodauth < ActiveRecord::Migration<%= migration_version %>
|
|
78
87
|
|
79
88
|
# # Used by the disallow_password_reuse feature
|
80
89
|
# create_table :account_previous_password_hashes do |t|
|
81
|
-
# t.references :account
|
90
|
+
# t.references :account, foreign_key: true
|
82
91
|
# t.string :password_hash, null: false
|
83
92
|
# end
|
84
93
|
|
@@ -124,7 +133,7 @@ class CreateRodauth < ActiveRecord::Migration<%= migration_version %>
|
|
124
133
|
|
125
134
|
# # Used by the active sessions feature
|
126
135
|
# create_table :account_active_session_keys, primary_key: [:account_id, :session_id] do |t|
|
127
|
-
# t.references :account
|
136
|
+
# t.references :account, foreign_key: true
|
128
137
|
# t.string :session_id
|
129
138
|
# t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
130
139
|
# t.datetime :last_use, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
@@ -136,7 +145,7 @@ class CreateRodauth < ActiveRecord::Migration<%= migration_version %>
|
|
136
145
|
# t.string :webauthn_id, null: false
|
137
146
|
# end
|
138
147
|
# create_table :account_webauthn_keys, primary_key: [:account_id, :webauthn_id] do |t|
|
139
|
-
# t.references :account
|
148
|
+
# t.references :account, foreign_key: true
|
140
149
|
# t.string :webauthn_id
|
141
150
|
# t.string :public_key, null: false
|
142
151
|
# t.integer :sign_count, null: false
|
@@ -7,6 +7,21 @@ module Rodauth
|
|
7
7
|
source_root "#{__dir__}/templates"
|
8
8
|
namespace "rodauth:views"
|
9
9
|
|
10
|
+
argument :features, optional: true, type: :array,
|
11
|
+
desc: "Rodauth features to generate views for (login, create_account, reset_password, verify_account etc.)",
|
12
|
+
default: %w[login logout create_account verify_account reset_password change_password change_login verify_login_change close_account]
|
13
|
+
|
14
|
+
class_option :features, type: :array,
|
15
|
+
desc: "[DEPRECATED] Rodauth features to generate views for (login, create_account, reset_password, verify_account etc.)"
|
16
|
+
|
17
|
+
class_option :all, aliases: "-a", type: :boolean,
|
18
|
+
desc: "Generates views for all Rodauth features",
|
19
|
+
default: false
|
20
|
+
|
21
|
+
class_option :directory, aliases: "-d", type: :string,
|
22
|
+
desc: "The directory under app/views/* into which to create views",
|
23
|
+
default: "rodauth"
|
24
|
+
|
10
25
|
VIEWS = {
|
11
26
|
login: %w[
|
12
27
|
_field _field_error _login_field _login_display _password_field
|
@@ -83,34 +98,18 @@ module Rodauth
|
|
83
98
|
webauthn: :two_factor_base,
|
84
99
|
}
|
85
100
|
|
86
|
-
class_option :features, type: :array,
|
87
|
-
desc: "Rodauth features to generate views for (login, create_account, reset_password, verify_account etc.)",
|
88
|
-
default: %w[login logout create_account verify_account reset_password change_password change_login verify_login_change close_account]
|
89
|
-
|
90
|
-
class_option :all, aliases: "-a", type: :boolean,
|
91
|
-
desc: "Generates views for all Rodauth features",
|
92
|
-
default: false
|
93
|
-
|
94
|
-
class_option :directory, aliases: "-d", type: :string,
|
95
|
-
desc: "The directory under app/views/* into which to create views",
|
96
|
-
default: "rodauth"
|
97
|
-
|
98
101
|
def create_views
|
99
|
-
|
102
|
+
if options[:all]
|
103
|
+
features = VIEWS.keys
|
104
|
+
else
|
105
|
+
features = (options[:features] || self.features).map(&:to_sym)
|
106
|
+
end
|
100
107
|
|
101
108
|
views = features.inject([]) do |list, feature|
|
102
109
|
list |= VIEWS[feature] || []
|
103
110
|
list |= VIEWS[DEPENDENCIES[feature]] || []
|
104
111
|
end
|
105
112
|
|
106
|
-
if Rodauth::MAJOR == 1
|
107
|
-
views -= %w[
|
108
|
-
multi_phase_login _global_logout_field
|
109
|
-
two_factor_manage two_factor_auth two_factor_disable
|
110
|
-
webauthn_setup webauthn_auth webauthn_remove
|
111
|
-
]
|
112
|
-
end
|
113
|
-
|
114
113
|
views.each do |view|
|
115
114
|
template "app/views/rodauth/#{view}.html.erb",
|
116
115
|
"app/views/#{options[:directory].underscore}/#{view}.html.erb"
|
data/lib/rodauth/rails.rb
CHANGED
data/lib/rodauth/rails/app.rb
CHANGED
@@ -4,15 +4,16 @@ module Rodauth
|
|
4
4
|
module Rails
|
5
5
|
# The superclass for creating a Rodauth middleware.
|
6
6
|
class App < Roda
|
7
|
-
require "rodauth/rails/app/flash"
|
8
|
-
|
9
7
|
plugin :middleware
|
10
8
|
plugin :hooks
|
11
9
|
plugin :render, layout: false
|
12
10
|
|
13
|
-
plugin Flash
|
14
|
-
|
15
11
|
def self.configure(name = nil, **options, &block)
|
12
|
+
unless options[:json] == :only
|
13
|
+
require "rodauth/rails/app/flash"
|
14
|
+
plugin Flash
|
15
|
+
end
|
16
|
+
|
16
17
|
plugin :rodauth, name: name, csrf: false, flash: false, **options do
|
17
18
|
# load the Rails integration
|
18
19
|
enable :rails
|
@@ -28,22 +28,14 @@ module Rodauth
|
|
28
28
|
super
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
31
|
+
# Verify Rails' authenticity token.
|
32
|
+
def check_csrf
|
33
|
+
rails_check_csrf!
|
34
|
+
end
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
else
|
42
|
-
# Verify Rails' authenticity token before each Rodauth route.
|
43
|
-
def before_rodauth
|
44
|
-
rails_check_csrf!
|
45
|
-
super
|
46
|
-
end
|
36
|
+
# Have Rodauth call #check_csrf automatically.
|
37
|
+
def check_csrf?
|
38
|
+
true
|
47
39
|
end
|
48
40
|
|
49
41
|
# Render Rails CSRF tags in Rodauth templates.
|
@@ -100,7 +92,7 @@ module Rodauth
|
|
100
92
|
request = ActionDispatch::Request.new(scope.env)
|
101
93
|
instance = rails_controller.new
|
102
94
|
|
103
|
-
if ActionPack.version >= Gem::Version.new("5.0
|
95
|
+
if ActionPack.version >= Gem::Version.new("5.0")
|
104
96
|
instance.set_request! request
|
105
97
|
instance.set_response! rails_controller.make_response!(request)
|
106
98
|
else
|
data/rodauth-rails.gemspec
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require_relative "lib/rodauth/rails/version"
|
2
|
+
|
1
3
|
Gem::Specification.new do |spec|
|
2
4
|
spec.name = "rodauth-rails"
|
3
|
-
spec.version =
|
5
|
+
spec.version = Rodauth::Rails::VERSION
|
4
6
|
spec.authors = ["Janko Marohnić"]
|
5
7
|
spec.email = ["janko.marohnic@gmail.com"]
|
6
8
|
|
@@ -15,8 +17,8 @@ Gem::Specification.new do |spec|
|
|
15
17
|
spec.require_paths = ["lib"]
|
16
18
|
|
17
19
|
spec.add_dependency "railties", ">= 4.2", "< 7"
|
18
|
-
spec.add_dependency "rodauth", "
|
19
|
-
spec.add_dependency "sequel-activerecord_connection", "~> 0
|
20
|
+
spec.add_dependency "rodauth", "~> 2.1"
|
21
|
+
spec.add_dependency "sequel-activerecord_connection", "~> 1.0"
|
20
22
|
spec.add_dependency "tilt"
|
21
23
|
spec.add_dependency "bcrypt"
|
22
24
|
end
|
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: 0.
|
4
|
+
version: 0.4.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: 2020-
|
11
|
+
date: 2020-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -34,36 +34,30 @@ dependencies:
|
|
34
34
|
name: rodauth
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- - "
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '1.23'
|
40
|
-
- - "<"
|
37
|
+
- - "~>"
|
41
38
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
39
|
+
version: '2.1'
|
43
40
|
type: :runtime
|
44
41
|
prerelease: false
|
45
42
|
version_requirements: !ruby/object:Gem::Requirement
|
46
43
|
requirements:
|
47
|
-
- - "
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '1.23'
|
50
|
-
- - "<"
|
44
|
+
- - "~>"
|
51
45
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
46
|
+
version: '2.1'
|
53
47
|
- !ruby/object:Gem::Dependency
|
54
48
|
name: sequel-activerecord_connection
|
55
49
|
requirement: !ruby/object:Gem::Requirement
|
56
50
|
requirements:
|
57
51
|
- - "~>"
|
58
52
|
- !ruby/object:Gem::Version
|
59
|
-
version: '0
|
53
|
+
version: '1.0'
|
60
54
|
type: :runtime
|
61
55
|
prerelease: false
|
62
56
|
version_requirements: !ruby/object:Gem::Requirement
|
63
57
|
requirements:
|
64
58
|
- - "~>"
|
65
59
|
- !ruby/object:Gem::Version
|
66
|
-
version: '0
|
60
|
+
version: '1.0'
|
67
61
|
- !ruby/object:Gem::Dependency
|
68
62
|
name: tilt
|
69
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,11 +93,13 @@ executables: []
|
|
99
93
|
extensions: []
|
100
94
|
extra_rdoc_files: []
|
101
95
|
files:
|
96
|
+
- CHANGELOG.md
|
102
97
|
- LICENSE.txt
|
103
98
|
- README.md
|
104
99
|
- lib/generators/rodauth/install_generator.rb
|
105
100
|
- lib/generators/rodauth/mailer_generator.rb
|
106
101
|
- lib/generators/rodauth/templates/app/controllers/rodauth_controller.rb
|
102
|
+
- lib/generators/rodauth/templates/app/lib/rodauth_app.rb
|
107
103
|
- lib/generators/rodauth/templates/app/mailers/rodauth_mailer.rb
|
108
104
|
- lib/generators/rodauth/templates/app/models/account.rb
|
109
105
|
- lib/generators/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb
|
@@ -169,7 +165,6 @@ files:
|
|
169
165
|
- lib/generators/rodauth/templates/config/initializers/rodauth.rb
|
170
166
|
- lib/generators/rodauth/templates/config/initializers/sequel.rb
|
171
167
|
- lib/generators/rodauth/templates/db/migrate/create_rodauth.rb
|
172
|
-
- lib/generators/rodauth/templates/lib/rodauth_app.rb
|
173
168
|
- lib/generators/rodauth/views_generator.rb
|
174
169
|
- lib/rodauth-rails.rb
|
175
170
|
- lib/rodauth/features/rails.rb
|
@@ -180,6 +175,7 @@ files:
|
|
180
175
|
- lib/rodauth/rails/feature.rb
|
181
176
|
- lib/rodauth/rails/middleware.rb
|
182
177
|
- lib/rodauth/rails/railtie.rb
|
178
|
+
- lib/rodauth/rails/version.rb
|
183
179
|
- rodauth-rails.gemspec
|
184
180
|
homepage: https://github.com/janko/rodauth-rails
|
185
181
|
licenses:
|
@@ -200,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
196
|
- !ruby/object:Gem::Version
|
201
197
|
version: '0'
|
202
198
|
requirements: []
|
203
|
-
rubygems_version: 3.1.
|
199
|
+
rubygems_version: 3.1.4
|
204
200
|
signing_key:
|
205
201
|
specification_version: 4
|
206
202
|
summary: Provides Rails integration for Rodauth.
|