rodauth-rails 0.4.1 → 0.7.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 +42 -0
- data/README.md +187 -52
- data/lib/generators/rodauth/install_generator.rb +28 -20
- data/lib/generators/rodauth/migration/account_expiration.erb +7 -0
- data/lib/generators/rodauth/migration/active_sessions.erb +7 -0
- data/lib/generators/rodauth/migration/audit_logging.erb +16 -0
- data/lib/generators/rodauth/migration/base.erb +19 -0
- data/lib/generators/rodauth/migration/disallow_password_reuse.erb +5 -0
- data/lib/generators/rodauth/migration/email_auth.erb +7 -0
- data/lib/generators/rodauth/migration/jwt_refresh.erb +7 -0
- data/lib/generators/rodauth/migration/lockout.erb +11 -0
- data/lib/generators/rodauth/migration/otp.erb +7 -0
- data/lib/generators/rodauth/migration/password_expiration.erb +5 -0
- data/lib/generators/rodauth/migration/recovery_codes.erb +6 -0
- data/lib/generators/rodauth/migration/remember.erb +6 -0
- data/lib/generators/rodauth/migration/reset_password.erb +7 -0
- data/lib/generators/rodauth/migration/single_session.erb +5 -0
- data/lib/generators/rodauth/migration/sms_codes.erb +8 -0
- data/lib/generators/rodauth/migration/verify_account.erb +7 -0
- data/lib/generators/rodauth/migration/verify_login_change.erb +7 -0
- data/lib/generators/rodauth/migration/webauthn.erb +12 -0
- data/lib/generators/rodauth/migration_generator.rb +32 -0
- data/lib/generators/rodauth/migration_helpers.rb +69 -0
- data/lib/generators/rodauth/templates/app/controllers/rodauth_controller.rb +2 -1
- data/lib/generators/rodauth/templates/app/lib/rodauth_app.rb +18 -20
- data/lib/generators/rodauth/templates/config/initializers/sequel.rb +1 -5
- data/lib/generators/rodauth/templates/db/migrate/create_rodauth.rb +2 -176
- data/lib/rodauth/rails.rb +33 -4
- data/lib/rodauth/rails/app.rb +4 -2
- data/lib/rodauth/rails/app/flash.rb +1 -1
- data/lib/rodauth/rails/app/middleware.rb +26 -0
- data/lib/rodauth/rails/feature.rb +98 -30
- data/lib/rodauth/rails/railtie.rb +11 -0
- data/lib/rodauth/rails/tasks.rake +28 -0
- data/lib/rodauth/rails/version.rb +1 -1
- data/rodauth-rails.gemspec +3 -3
- metadata +29 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8163d64892cbebd867182d15148f3099abb3ed49ae3e07a89a5adea6606623d2
|
4
|
+
data.tar.gz: 3cc7990e0af8e5ffb2ac959f989fb45cf538490412adfc908571823e5dd7b160
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99005d6864310fa3a36f8314a13588900a5ac1559af7a77d75cb5aba66b0b829d32c83fe66a3f5a7ced098de32b39396edd666919177836bb84b35a0de3a558b
|
7
|
+
data.tar.gz: 2d66b5ab43d05b26483cb3d69181c506b19a937fa77a2d7d66a38708f6357fae7bd2e605cc0a96affdd8fed822076dccb1603577338e68620c70a816fc45db7a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,45 @@
|
|
1
|
+
## 0.7.0 (2020-11-27)
|
2
|
+
|
3
|
+
* Add `#rails_controller_eval` method for running code in context of a controller instance (@janko)
|
4
|
+
|
5
|
+
* Detect `secret_key_base` from credentials and `$SECRET_KEY_BASE` environment variable (@janko)
|
6
|
+
|
7
|
+
## 0.6.1 (2020-11-25)
|
8
|
+
|
9
|
+
* Generate the Rodauth controller for API-only Rails apps as well (@janko)
|
10
|
+
|
11
|
+
* Fix remember cookie deadline not extending in remember feature (@janko)
|
12
|
+
|
13
|
+
## 0.6.0 (2020-11-22)
|
14
|
+
|
15
|
+
* Add `Rodauth::Rails.rodauth` method for retrieving Rodauth instance outside of request context (@janko)
|
16
|
+
|
17
|
+
* Add default Action Dispatch response headers in Rodauth responses (@janko)
|
18
|
+
|
19
|
+
* Run controller rescue handlers around Rodauth actions (@janko)
|
20
|
+
|
21
|
+
* Run controller action callbacks around Rodauth actions (@janko)
|
22
|
+
|
23
|
+
## 0.5.0 (2020-11-16)
|
24
|
+
|
25
|
+
* Support more Active Record adapters in `rodauth:install` generator (@janko)
|
26
|
+
|
27
|
+
* Add `rodauth:migration` generator for creating tables of specified features (@janko)
|
28
|
+
|
29
|
+
* Use UUIDs for primary keys if so configured in Rails generators (@janko)
|
30
|
+
|
31
|
+
* Add `rodauth:routes` rake task for printing routes handled by Rodauth middleware (@janko)
|
32
|
+
|
33
|
+
## 0.4.2 (2020-11-08)
|
34
|
+
|
35
|
+
* Drop support for Ruby 2.2 (@janko)
|
36
|
+
|
37
|
+
* Bump `sequel-activerecord_connection` dependency to 1.1+ (@janko)
|
38
|
+
|
39
|
+
* Set default bcrypt hash cost to `1` in tests (@janko)
|
40
|
+
|
41
|
+
* Call `AR::Base.connection_db_config` on Rails 6.1+ in `rodauth:install` generator (@janko)
|
42
|
+
|
1
43
|
## 0.4.1 (2020-11-02)
|
2
44
|
|
3
45
|
* Don't generate `RodauthController` in API-only mode (@janko)
|
data/README.md
CHANGED
@@ -4,16 +4,39 @@ Provides Rails integration for the [Rodauth] authentication framework.
|
|
4
4
|
|
5
5
|
## Resources
|
6
6
|
|
7
|
+
Useful links:
|
8
|
+
|
7
9
|
* [Rodauth documentation](http://rodauth.jeremyevans.net/documentation.html)
|
8
|
-
* [rodauth-rails wiki](https://github.com/janko/rodauth-rails/wiki)
|
9
10
|
* [Rails demo](https://github.com/janko/rodauth-demo-rails)
|
10
11
|
|
12
|
+
Articles:
|
13
|
+
|
14
|
+
* [Rodauth: A Refreshing Authentication Solution for Ruby](https://janko.io/rodauth-a-refreshing-authentication-solution-for-ruby/)
|
15
|
+
* [Adding Authentication in Rails 6 with Rodauth](https://janko.io/adding-authentication-in-rails-with-rodauth/)
|
16
|
+
|
17
|
+
## Upgrading
|
18
|
+
|
19
|
+
### Upgrading to 0.7.0
|
20
|
+
|
21
|
+
Starting from version 0.7.0, rodauth-rails now correctly detects Rails
|
22
|
+
application's `secret_key_base` when setting default `hmac_secret`, including
|
23
|
+
when it's set via credentials or `$SECRET_KEY_BASE` environment variable. This
|
24
|
+
means authentication will be more secure by default, and Rodauth features that
|
25
|
+
require `hmac_secret` should now work automatically as well.
|
26
|
+
|
27
|
+
However, if you've already been using rodauth-rails in production, where the
|
28
|
+
`secret_key_base` is set via credentials or environment variable and `hmac_secret`
|
29
|
+
was not explicitly set, the fact that your authentication will now start using
|
30
|
+
HMACs has backwards compatibility considerations. See the [Rodauth
|
31
|
+
documentation](hmac) for instructions on how to safely transition, or just set
|
32
|
+
`hmac_secret nil` in your Rodauth configuration.
|
33
|
+
|
11
34
|
## Installation
|
12
35
|
|
13
36
|
Add the gem to your Gemfile:
|
14
37
|
|
15
38
|
```rb
|
16
|
-
gem "rodauth-rails", "~> 0.
|
39
|
+
gem "rodauth-rails", "~> 0.6"
|
17
40
|
|
18
41
|
# gem "jwt", require: false # for JWT feature
|
19
42
|
# gem "rotp", require: false # for OTP feature
|
@@ -54,7 +77,6 @@ class CreateRodauth < ActiveRecord::Migration
|
|
54
77
|
create_table :account_verification_keys do |t| ... end
|
55
78
|
create_table :account_login_change_keys do |t| ... end
|
56
79
|
create_table :account_remember_keys do |t| ... end
|
57
|
-
# ...
|
58
80
|
end
|
59
81
|
end
|
60
82
|
```
|
@@ -88,7 +110,7 @@ ActiveRecord connection.
|
|
88
110
|
require "sequel/core"
|
89
111
|
|
90
112
|
# initialize Sequel and have it reuse Active Record's database connection
|
91
|
-
DB = Sequel.
|
113
|
+
DB = Sequel.connect("postgresql://", extensions: :activerecord_connection)
|
92
114
|
```
|
93
115
|
|
94
116
|
### Rodauth app
|
@@ -112,8 +134,9 @@ end
|
|
112
134
|
|
113
135
|
### Controller
|
114
136
|
|
115
|
-
Your Rodauth app will by default use `RodauthController` for view rendering
|
116
|
-
and
|
137
|
+
Your Rodauth app will by default use `RodauthController` for view rendering,
|
138
|
+
CSRF protection, and running controller callbacks and rescue handlers around
|
139
|
+
Rodauth actions.
|
117
140
|
|
118
141
|
```rb
|
119
142
|
# app/controllers/rodauth_controller.rb
|
@@ -121,7 +144,7 @@ class RodauthController < ApplicationController
|
|
121
144
|
end
|
122
145
|
```
|
123
146
|
|
124
|
-
### Account
|
147
|
+
### Account model
|
125
148
|
|
126
149
|
Rodauth stores user accounts in the `accounts` table, so the generator will
|
127
150
|
also create an `Account` model for custom use.
|
@@ -132,10 +155,34 @@ class Account < ApplicationRecord
|
|
132
155
|
end
|
133
156
|
```
|
134
157
|
|
135
|
-
##
|
158
|
+
## Usage
|
159
|
+
|
160
|
+
### Routes
|
161
|
+
|
162
|
+
We can see the list of routes our Rodauth middleware handles:
|
163
|
+
|
164
|
+
```sh
|
165
|
+
$ rails rodauth:routes
|
166
|
+
```
|
167
|
+
```
|
168
|
+
Routes handled by RodauthApp:
|
169
|
+
|
170
|
+
/login rodauth.login_path
|
171
|
+
/create-account rodauth.create_account_path
|
172
|
+
/verify-account-resend rodauth.verify_account_resend_path
|
173
|
+
/verify-account rodauth.verify_account_path
|
174
|
+
/change-password rodauth.change_password_path
|
175
|
+
/change-login rodauth.change_login_path
|
176
|
+
/logout rodauth.logout_path
|
177
|
+
/remember rodauth.remember_path
|
178
|
+
/reset-password-request rodauth.reset_password_request_path
|
179
|
+
/reset-password rodauth.reset_password_path
|
180
|
+
/verify-login-change rodauth.verify_login_change_path
|
181
|
+
/close-account rodauth.close_account_path
|
182
|
+
```
|
136
183
|
|
137
|
-
|
138
|
-
|
184
|
+
Using this information, we could add some basic authentication links to our
|
185
|
+
navigation header:
|
139
186
|
|
140
187
|
```erb
|
141
188
|
<ul>
|
@@ -148,40 +195,45 @@ page:
|
|
148
195
|
</ul>
|
149
196
|
```
|
150
197
|
|
151
|
-
These
|
198
|
+
These routes are fully functional, feel free to visit them and interact with the
|
152
199
|
pages. The templates that ship with Rodauth aim to provide a complete
|
153
200
|
authentication experience, and the forms use [Bootstrap] markup.
|
154
201
|
|
155
|
-
|
156
|
-
|
202
|
+
### Current account
|
203
|
+
|
204
|
+
To be able to fetch currently authenticated account, let's define a
|
205
|
+
`#current_account` method that fetches the account id from session and
|
206
|
+
retrieves the corresponding account record:
|
157
207
|
|
158
208
|
```rb
|
159
209
|
# app/controllers/application_controller.rb
|
160
210
|
class ApplicationController < ActionController::Base
|
161
|
-
before_action :
|
211
|
+
before_action :current_account, if: -> { rodauth.authenticated? }
|
162
212
|
|
163
213
|
private
|
164
214
|
|
165
|
-
def
|
166
|
-
@current_account
|
215
|
+
def current_account
|
216
|
+
@current_account ||= Account.find(rodauth.session_value)
|
167
217
|
rescue ActiveRecord::RecordNotFound
|
168
218
|
rodauth.logout
|
169
219
|
rodauth.login_required
|
170
220
|
end
|
171
|
-
|
172
|
-
attr_reader :current_account
|
173
221
|
helper_method :current_account
|
174
222
|
end
|
175
223
|
```
|
224
|
+
|
225
|
+
This allows us to access the current account in controllers and views:
|
226
|
+
|
176
227
|
```erb
|
177
228
|
<p>Authenticated as: <%= current_account.email %></p>
|
178
229
|
```
|
179
230
|
|
180
231
|
### Requiring authentication
|
181
232
|
|
182
|
-
|
183
|
-
|
184
|
-
the authentication logic
|
233
|
+
We'll likely want to require authentication for certain parts of our app,
|
234
|
+
redirecting the user to the login page if they're not logged in. We can do this
|
235
|
+
in our Rodauth app's routing block, which helps keep the authentication logic
|
236
|
+
encapsulated:
|
185
237
|
|
186
238
|
```rb
|
187
239
|
# app/lib/rodauth_app.rb
|
@@ -239,9 +291,9 @@ end
|
|
239
291
|
|
240
292
|
### Views
|
241
293
|
|
242
|
-
The templates built into Rodauth are useful when getting started, but
|
243
|
-
|
244
|
-
|
294
|
+
The templates built into Rodauth are useful when getting started, but soon
|
295
|
+
you'll want to start editing the markup. You can run the following command to
|
296
|
+
copy Rodauth templates into your Rails app:
|
245
297
|
|
246
298
|
```sh
|
247
299
|
$ rails generate rodauth:views
|
@@ -265,7 +317,7 @@ $ rails generate rodauth:views --all
|
|
265
317
|
```
|
266
318
|
|
267
319
|
You can also tell the generator to create views into another directory (in this
|
268
|
-
case
|
320
|
+
case make sure to rename the Rodauth controller accordingly):
|
269
321
|
|
270
322
|
```sh
|
271
323
|
# generates views into app/views/authentication
|
@@ -300,8 +352,8 @@ end
|
|
300
352
|
|
301
353
|
### Mailer
|
302
354
|
|
303
|
-
Rodauth may send emails as part of
|
304
|
-
can be customized:
|
355
|
+
Depending on the features you've enabled, Rodauth may send emails as part of
|
356
|
+
the authentication flow. Most email settings can be customized:
|
305
357
|
|
306
358
|
```rb
|
307
359
|
# app/lib/rodauth_app.rb
|
@@ -345,8 +397,8 @@ end
|
|
345
397
|
```
|
346
398
|
|
347
399
|
You can then uncomment the lines in your Rodauth configuration to have it call
|
348
|
-
your mailer. If you've enabled additional authentication features
|
349
|
-
override their `
|
400
|
+
your mailer. If you've enabled additional authentication features that send
|
401
|
+
emails, make sure to override their `create_*_email` methods as well.
|
350
402
|
|
351
403
|
```rb
|
352
404
|
# app/lib/rodauth_app.rb
|
@@ -354,37 +406,58 @@ class RodauthApp < Rodauth::Rails::App
|
|
354
406
|
# ...
|
355
407
|
configure do
|
356
408
|
# ...
|
357
|
-
|
358
|
-
|
409
|
+
create_reset_password_email do
|
410
|
+
RodauthMailer.reset_password(email_to, reset_password_email_link)
|
359
411
|
end
|
360
|
-
|
361
|
-
|
412
|
+
create_verify_account_email do
|
413
|
+
RodauthMailer.verify_account(email_to, verify_account_email_link)
|
362
414
|
end
|
363
|
-
|
364
|
-
|
415
|
+
create_verify_login_change_email do |login|
|
416
|
+
RodauthMailer.verify_login_change(login, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_email_link)
|
365
417
|
end
|
366
|
-
|
367
|
-
|
418
|
+
create_password_changed_email do
|
419
|
+
RodauthMailer.password_changed(email_to)
|
368
420
|
end
|
369
|
-
#
|
370
|
-
#
|
421
|
+
# create_email_auth_email do
|
422
|
+
# RodauthMailer.email_auth(email_to, email_auth_email_link)
|
371
423
|
# end
|
372
|
-
#
|
373
|
-
#
|
424
|
+
# create_unlock_account_email do
|
425
|
+
# RodauthMailer.unlock_account(email_to, unlock_account_email_link)
|
374
426
|
# end
|
375
|
-
|
427
|
+
send_email do |email|
|
376
428
|
# queue email delivery on the mailer after the transaction commits
|
377
|
-
|
378
|
-
db.after_commit do
|
379
|
-
RodauthMailer.public_send(type, *args).deliver_later
|
380
|
-
end
|
381
|
-
end
|
429
|
+
db.after_commit { email.deliver_later }
|
382
430
|
end
|
383
431
|
# ...
|
384
432
|
end
|
385
433
|
end
|
386
434
|
```
|
387
435
|
|
436
|
+
This approach can be used even if you're using a 3rd-party service for
|
437
|
+
transactional emails, where emails are sent via API requests instead of
|
438
|
+
SMTP. Whatever the `create_*_email` block returns will be passed to
|
439
|
+
`send_email`, so you can be creative.
|
440
|
+
|
441
|
+
### Migrations
|
442
|
+
|
443
|
+
The install generator will create a migration for tables used by the Rodauth
|
444
|
+
features enabled by default. For any additional features, you can use the
|
445
|
+
migration generator to create the corresponding tables:
|
446
|
+
|
447
|
+
```sh
|
448
|
+
$ rails generate rodauth:migration otp sms_codes recovery_codes
|
449
|
+
```
|
450
|
+
```rb
|
451
|
+
# db/migration/*_create_rodauth_otp_sms_codes_recovery_codes.rb
|
452
|
+
class CreateRodauthOtpSmsCodesRecoveryCodes < ActiveRecord::Migration
|
453
|
+
def change
|
454
|
+
create_table :account_otp_keys do |t| ... end
|
455
|
+
create_table :account_sms_codes do |t| ... end
|
456
|
+
create_table :account_recovery_codes do |t| ... end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
```
|
460
|
+
|
388
461
|
### JSON API
|
389
462
|
|
390
463
|
JSON API support in Rodauth is provided by the [JWT feature]. First you'll need
|
@@ -416,6 +489,51 @@ the configure method.
|
|
416
489
|
Make sure to store the `jwt_secret` in a secure place, such as Rails
|
417
490
|
credentials or environment variables.
|
418
491
|
|
492
|
+
### Calling controller methods
|
493
|
+
|
494
|
+
When using Rodauth before/after hooks or generally overriding your Rodauth
|
495
|
+
configuration, in some cases you might want to call methods defined on your
|
496
|
+
controllers. You can do so with `rails_controller_eval`, for example:
|
497
|
+
|
498
|
+
```rb
|
499
|
+
# app/controllers/application_controller.rb
|
500
|
+
class ApplicationController < ActionController::Base
|
501
|
+
private
|
502
|
+
def setup_tracking(account_id)
|
503
|
+
# ... some implementation ...
|
504
|
+
end
|
505
|
+
end
|
506
|
+
```
|
507
|
+
```rb
|
508
|
+
# app/lib/rodauth_app.rb
|
509
|
+
class RodauthApp < Rodauth::Rails::App
|
510
|
+
configure do
|
511
|
+
after_create_account do
|
512
|
+
rails_controller_eval { setup_tracking(account_id) }
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|
516
|
+
```
|
517
|
+
|
518
|
+
### Rodauth instance
|
519
|
+
|
520
|
+
In some cases you might need to use Rodauth more programmatically, and perform
|
521
|
+
Rodauth operations outside of the request context. rodauth-rails gives you the
|
522
|
+
ability to retrieve the Rodauth instance:
|
523
|
+
|
524
|
+
```rb
|
525
|
+
rodauth = Rodauth::Rails.rodauth # or Rodauth::Rails.rodauth(:secondary)
|
526
|
+
|
527
|
+
rodauth.login_url #=> "https://example.com/login"
|
528
|
+
rodauth.account_from_login("user@example.com") # loads user by email
|
529
|
+
rodauth.password_match?("secret") #=> true
|
530
|
+
rodauth.setup_account_verification
|
531
|
+
rodauth.close_account
|
532
|
+
```
|
533
|
+
|
534
|
+
This Rodauth instance will be initialized with basic Rack env that allows is it
|
535
|
+
to generate URLs, using `config.action_mailer.default_url_options` options.
|
536
|
+
|
419
537
|
## How it works
|
420
538
|
|
421
539
|
### Middleware
|
@@ -460,11 +578,12 @@ end
|
|
460
578
|
The `Rodauth::Rails::App` class is a [Roda] subclass that provides Rails
|
461
579
|
integration for Rodauth:
|
462
580
|
|
463
|
-
* uses
|
464
|
-
* uses
|
581
|
+
* uses Action Dispatch flash instead of Roda's
|
582
|
+
* uses Action Dispatch CSRF protection instead of Roda's
|
465
583
|
* sets [HMAC] secret to Rails' secret key base
|
466
|
-
* uses
|
467
|
-
*
|
584
|
+
* uses Action Controller for rendering templates
|
585
|
+
* runs Action Controller callbacks & rescue handlers around Rodauth actions
|
586
|
+
* uses Action Mailer for sending emails
|
468
587
|
|
469
588
|
The `configure { ... }` method wraps configuring the Rodauth plugin, forwarding
|
470
589
|
any additional [plugin options].
|
@@ -588,6 +707,22 @@ disables the use of database functions, though you can always turn it back on.
|
|
588
707
|
use_database_authentication_functions? true
|
589
708
|
```
|
590
709
|
|
710
|
+
To create the database functions, pass the Sequel database object into the
|
711
|
+
Rodauth method for creating database functions:
|
712
|
+
|
713
|
+
```rb
|
714
|
+
# db/migrate/*_create_rodauth_database_functions.rb
|
715
|
+
class CreateRodauthDatabaseFunctions < ActiveRecord::Migration
|
716
|
+
def up
|
717
|
+
Rodauth.create_database_authentication_functions(DB)
|
718
|
+
end
|
719
|
+
|
720
|
+
def down
|
721
|
+
Rodauth.drop_database_authentication_functions(DB)
|
722
|
+
end
|
723
|
+
end
|
724
|
+
```
|
725
|
+
|
591
726
|
### Account statuses
|
592
727
|
|
593
728
|
The recommended [Rodauth migration] stores possible account status values in a
|
@@ -640,7 +775,6 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
|
|
640
775
|
|
641
776
|
[Rodauth]: https://github.com/jeremyevans/rodauth
|
642
777
|
[Sequel]: https://github.com/jeremyevans/sequel
|
643
|
-
[rendering views outside of controllers]: https://blog.bigbinary.com/2016/01/08/rendering-views-outside-of-controllers-in-rails-5.html
|
644
778
|
[feature documentation]: http://rodauth.jeremyevans.net/documentation.html
|
645
779
|
[JWT feature]: http://rodauth.jeremyevans.net/rdoc/files/doc/jwt_rdoc.html
|
646
780
|
[JWT gem]: https://github.com/jwt/ruby-jwt
|
@@ -651,3 +785,4 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
|
|
651
785
|
[Rodauth migration]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Creating+tables
|
652
786
|
[sequel-activerecord_connection]: https://github.com/janko/sequel-activerecord_connection
|
653
787
|
[plugin options]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Plugin+Options
|
788
|
+
[hmac]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-HMAC
|