rodauth-rails 0.18.1 → 1.0.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 +34 -0
- data/README.md +219 -553
- data/lib/generators/rodauth/install_generator.rb +32 -35
- data/lib/generators/rodauth/migration_generator.rb +9 -2
- data/lib/generators/rodauth/templates/INSTRUCTIONS +40 -0
- data/lib/generators/rodauth/templates/app/mailers/rodauth_mailer.rb +36 -19
- data/lib/generators/rodauth/templates/app/misc/rodauth_app.rb +38 -0
- data/lib/generators/rodauth/templates/app/{lib/rodauth_app.rb → misc/rodauth_main.rb} +9 -52
- data/lib/generators/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/change_login.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/change_password.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/close_account.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/confirm_password.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/create_account.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/email_auth.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/logout.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/otp_auth.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/otp_disable.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/otp_setup.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/remember.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/reset_password.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/sms_auth.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/sms_disable.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/sms_request.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/sms_setup.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/verify_account.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +1 -1
- data/lib/rodauth/rails/app.rb +1 -4
- data/lib/rodauth/rails/auth.rb +1 -16
- data/lib/rodauth/rails/controller_methods.rb +1 -1
- data/lib/rodauth/rails/feature/internal_request.rb +10 -4
- data/lib/rodauth/rails/feature/render.rb +8 -0
- data/lib/rodauth/rails/tasks.rake +2 -2
- data/lib/rodauth/rails/version.rb +1 -1
- data/lib/rodauth/rails.rb +9 -20
- data/rodauth-rails.gemspec +1 -1
- metadata +7 -5
data/README.md
CHANGED
@@ -8,6 +8,9 @@ Useful links:
|
|
8
8
|
|
9
9
|
* [Rodauth documentation](http://rodauth.jeremyevans.net/documentation.html)
|
10
10
|
* [Rails demo](https://github.com/janko/rodauth-demo-rails)
|
11
|
+
* [JSON API guide](https://github.com/janko/rodauth-rails/wiki/JSON-API)
|
12
|
+
* [OmniAuth guide](https://github.com/janko/rodauth-rails/wiki/OmniAuth)
|
13
|
+
* [Testing guide](https://github.com/janko/rodauth-rails/wiki/Testing)
|
11
14
|
|
12
15
|
Articles:
|
13
16
|
|
@@ -39,17 +42,12 @@ Active Record. There are good reasons for this, and to make Rodauth work
|
|
39
42
|
smoothly alongside Active Record, rodauth-rails configures Sequel to [reuse
|
40
43
|
Active Record's database connection][sequel-activerecord_connection].
|
41
44
|
|
42
|
-
## Upgrading
|
43
|
-
|
44
|
-
For instructions on upgrading from previous rodauth-rails versions, see
|
45
|
-
[UPGRADING.md](/UPGRADING.md).
|
46
|
-
|
47
45
|
## Installation
|
48
46
|
|
49
47
|
Add the gem to your Gemfile:
|
50
48
|
|
51
49
|
```rb
|
52
|
-
gem "rodauth-rails", "~> 0
|
50
|
+
gem "rodauth-rails", "~> 1.0"
|
53
51
|
|
54
52
|
# gem "jwt", require: false # for JWT feature
|
55
53
|
# gem "rotp", require: false # for OTP feature
|
@@ -74,9 +72,9 @@ $ rails generate rodauth:install --jwt # token authentication via the "Authoriza
|
|
74
72
|
$ bundle add jwt
|
75
73
|
```
|
76
74
|
|
77
|
-
This generator will create a Rodauth app with common
|
78
|
-
enabled, a database migration with tables required by
|
79
|
-
with default templates, and a few other files.
|
75
|
+
This generator will create a Rodauth app and configuration with common
|
76
|
+
authentication features enabled, a database migration with tables required by
|
77
|
+
those features, a mailer with default templates, and a few other files.
|
80
78
|
|
81
79
|
Feel free to remove any features you don't need, along with their corresponding
|
82
80
|
tables. Afterwards, run the migration:
|
@@ -85,11 +83,23 @@ tables. Afterwards, run the migration:
|
|
85
83
|
$ rails db:migrate
|
86
84
|
```
|
87
85
|
|
86
|
+
For your mailer to be able to generate email links, you'll need to set up
|
87
|
+
default URL options in each environment. Here is a possible configuration for
|
88
|
+
`config/environments/development.rb`:
|
89
|
+
|
90
|
+
```rb
|
91
|
+
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
92
|
+
```
|
93
|
+
|
88
94
|
## Usage
|
89
95
|
|
90
96
|
### Routes
|
91
97
|
|
92
|
-
|
98
|
+
Because requests to Rodauth endpoints are handled by the Rodauth middleware, and
|
99
|
+
not a Rails controller, Rodauth routes will not show in `rails routes`.
|
100
|
+
|
101
|
+
Use the `rodauth:routes` rake task to view the list of endpoints based on
|
102
|
+
currently loaded features:
|
93
103
|
|
94
104
|
```sh
|
95
105
|
$ rails rodauth:routes
|
@@ -127,19 +137,6 @@ These routes are fully functional, feel free to visit them and interact with the
|
|
127
137
|
pages. The templates that ship with Rodauth aim to provide a complete
|
128
138
|
authentication experience, and the forms use [Bootstrap] markup.
|
129
139
|
|
130
|
-
Inside Rodauth configuration and the `route` block you can access Rails route
|
131
|
-
helpers through `#rails_routes`:
|
132
|
-
|
133
|
-
```rb
|
134
|
-
class RodauthApp < Rodauth::Rails::App
|
135
|
-
configure do
|
136
|
-
# ...
|
137
|
-
login_redirect { rails_routes.activity_path }
|
138
|
-
# ...
|
139
|
-
end
|
140
|
-
end
|
141
|
-
```
|
142
|
-
|
143
140
|
### Current account
|
144
141
|
|
145
142
|
The `#current_account` method is defined in controllers and views, which
|
@@ -160,13 +157,15 @@ configurations:
|
|
160
157
|
current_account(:admin)
|
161
158
|
```
|
162
159
|
|
160
|
+
#### Custom account model
|
161
|
+
|
163
162
|
The `#current_account` method will try to infer the account model class from
|
164
163
|
the configured table name. If that fails, you can set the account model
|
165
164
|
manually:
|
166
165
|
|
167
166
|
```rb
|
168
|
-
# app/
|
169
|
-
class
|
167
|
+
# app/misc/rodauth_main.rb
|
168
|
+
class RodauthMain < Rodauth::Rails::Auth
|
170
169
|
configure do
|
171
170
|
# ...
|
172
171
|
rails_account_model Authentication::Account # custom model name
|
@@ -182,7 +181,7 @@ in your Rodauth app's routing block, which helps keep the authentication logic
|
|
182
181
|
encapsulated:
|
183
182
|
|
184
183
|
```rb
|
185
|
-
# app/
|
184
|
+
# app/misc/rodauth_app.rb
|
186
185
|
class RodauthApp < Rodauth::Rails::App
|
187
186
|
# ...
|
188
187
|
route do |r|
|
@@ -305,12 +304,33 @@ Use `--name` to generate views for a different Rodauth configuration:
|
|
305
304
|
$ rails generate rodauth:views webauthn --name admin
|
306
305
|
```
|
307
306
|
|
307
|
+
#### Page titles
|
308
|
+
|
309
|
+
The generated view templates use `content_for(:title)` to store Rodauth's page
|
310
|
+
titles, which you can then retrieve in your layout template to set the page
|
311
|
+
title:
|
312
|
+
|
313
|
+
```erb
|
314
|
+
<!-- app/views/layouts/application.html.erb -->
|
315
|
+
<!DOCTYPE html>
|
316
|
+
<html>
|
317
|
+
<head>
|
318
|
+
<title><%= content_for(:title) %></title>
|
319
|
+
<!-- ... -->
|
320
|
+
</head>
|
321
|
+
<body>
|
322
|
+
<!-- ... -->
|
323
|
+
</body>
|
324
|
+
</html>
|
325
|
+
```
|
326
|
+
|
308
327
|
#### Layout
|
309
328
|
|
310
329
|
To use different layouts for different Rodauth views, you can compare the
|
311
330
|
request path in the layout method:
|
312
331
|
|
313
332
|
```rb
|
333
|
+
# app/controllers/rodauth_controller.rb
|
314
334
|
class RodauthController < ApplicationController
|
315
335
|
layout :rodauth_layout
|
316
336
|
|
@@ -331,6 +351,15 @@ class RodauthController < ApplicationController
|
|
331
351
|
end
|
332
352
|
```
|
333
353
|
|
354
|
+
#### Turbo
|
355
|
+
|
356
|
+
[Turbo] has been disabled by default on all built-in and generated view
|
357
|
+
templates, because some Rodauth actions (multi-phase login, adding recovery
|
358
|
+
codes) aren't Turbo-compatible, as they return 200 responses on POST requests.
|
359
|
+
|
360
|
+
That being said, most of Rodauth *is* Turbo-compatible, so feel free to enable
|
361
|
+
Turbo for actions where you want to use it.
|
362
|
+
|
334
363
|
### Mailer
|
335
364
|
|
336
365
|
The install generator will create `RodauthMailer` with default email templates,
|
@@ -340,48 +369,48 @@ flow to use it.
|
|
340
369
|
```rb
|
341
370
|
# app/mailers/rodauth_mailer.rb
|
342
371
|
class RodauthMailer < ApplicationMailer
|
343
|
-
def verify_account(
|
372
|
+
def verify_account(account_id, key)
|
344
373
|
# ...
|
345
374
|
end
|
346
|
-
def reset_password(
|
375
|
+
def reset_password(account_id, key)
|
347
376
|
# ...
|
348
377
|
end
|
349
|
-
def verify_login_change(
|
378
|
+
def verify_login_change(account_id, old_login, new_login, key)
|
350
379
|
# ...
|
351
380
|
end
|
352
|
-
def password_changed(
|
381
|
+
def password_changed(account_id)
|
353
382
|
# ...
|
354
383
|
end
|
355
|
-
# def email_auth(
|
384
|
+
# def email_auth(account_id, key)
|
356
385
|
# ...
|
357
386
|
# end
|
358
|
-
# def unlock_account(
|
387
|
+
# def unlock_account(account_id, key)
|
359
388
|
# ...
|
360
389
|
# end
|
361
390
|
end
|
362
391
|
```
|
363
392
|
```rb
|
364
|
-
# app/
|
365
|
-
class
|
393
|
+
# app/misc/rodauth_main.rb
|
394
|
+
class RodauthMain < Rodauth::Rails::Auth
|
366
395
|
configure do
|
367
396
|
# ...
|
368
397
|
create_reset_password_email do
|
369
|
-
RodauthMailer.reset_password(
|
398
|
+
RodauthMailer.reset_password(account_id, reset_password_key_value)
|
370
399
|
end
|
371
400
|
create_verify_account_email do
|
372
|
-
RodauthMailer.verify_account(
|
401
|
+
RodauthMailer.verify_account(account_id, verify_account_key_value)
|
373
402
|
end
|
374
|
-
create_verify_login_change_email do |
|
375
|
-
RodauthMailer.verify_login_change(
|
403
|
+
create_verify_login_change_email do |_login|
|
404
|
+
RodauthMailer.verify_login_change(account_id, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_key_value)
|
376
405
|
end
|
377
406
|
create_password_changed_email do
|
378
|
-
RodauthMailer.password_changed(
|
407
|
+
RodauthMailer.password_changed(account_id)
|
379
408
|
end
|
380
409
|
# create_email_auth_email do
|
381
|
-
# RodauthMailer.email_auth(
|
410
|
+
# RodauthMailer.email_auth(account_id, email_auth_key_value)
|
382
411
|
# end
|
383
412
|
# create_unlock_account_email do
|
384
|
-
# RodauthMailer.unlock_account(
|
413
|
+
# RodauthMailer.unlock_account(account_id, unlock_account_key_value)
|
385
414
|
# end
|
386
415
|
send_email do |email|
|
387
416
|
# queue email delivery on the mailer after the transaction commits
|
@@ -399,44 +428,8 @@ deliveries. However, if you want to send emails synchronously, you can modify
|
|
399
428
|
the configuration to call `#deliver_now` instead.
|
400
429
|
|
401
430
|
If you're using a background processing library without an Active Job adapter,
|
402
|
-
or a 3rd-party service for sending transactional emails, this
|
403
|
-
|
404
|
-
and `#send_email`, override the `#send_*_email` methods instead, which are
|
405
|
-
required to send the email immediately. For example:
|
406
|
-
|
407
|
-
```rb
|
408
|
-
# app/workers/rodauth_mailer_worker.rb
|
409
|
-
class RodauthMailerWorker
|
410
|
-
include Sidekiq::Worker
|
411
|
-
|
412
|
-
def perform(name, *args)
|
413
|
-
email = RodauthMailer.public_send(name, *args)
|
414
|
-
email.deliver_now
|
415
|
-
end
|
416
|
-
end
|
417
|
-
```
|
418
|
-
```rb
|
419
|
-
# app/lib/rodauth_app.rb
|
420
|
-
class RodauthApp < Rodauth::Rails::App
|
421
|
-
configure do
|
422
|
-
# ...
|
423
|
-
# use `#send_*_email` method to be able to immediately enqueue email delivery
|
424
|
-
send_reset_password_email do
|
425
|
-
enqueue_email(:reset_password, email_to, reset_password_email_link)
|
426
|
-
end
|
427
|
-
# ...
|
428
|
-
auth_class_eval do
|
429
|
-
# custom method for enqueuing email delivery using our worker
|
430
|
-
def enqueue_email(name, *args)
|
431
|
-
db.after_commit do
|
432
|
-
RodauthMailerWorker.perform_async(name, *args)
|
433
|
-
end
|
434
|
-
end
|
435
|
-
end
|
436
|
-
# ...
|
437
|
-
end
|
438
|
-
end
|
439
|
-
```
|
431
|
+
or a 3rd-party service for sending transactional emails, see [this wiki
|
432
|
+
page][custom mailer worker] on how to set it up.
|
440
433
|
|
441
434
|
### Migrations
|
442
435
|
|
@@ -458,7 +451,23 @@ class CreateRodauthOtpSmsCodesRecoveryCodes < ActiveRecord::Migration
|
|
458
451
|
end
|
459
452
|
```
|
460
453
|
|
461
|
-
|
454
|
+
#### Custom migration name
|
455
|
+
|
456
|
+
You can change the default migration name:
|
457
|
+
|
458
|
+
```sh
|
459
|
+
$ rails generate rodauth:migration email_auth --name create_account_email_auth_keys
|
460
|
+
```
|
461
|
+
```rb
|
462
|
+
# db/migration/*_create_account_email_auth_keys
|
463
|
+
class CreateAccountEmailAuthKeys < ActiveRecord::Migration
|
464
|
+
def change
|
465
|
+
create_table :account_email_auth_keys do |t| ... end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
```
|
469
|
+
|
470
|
+
## Model
|
462
471
|
|
463
472
|
The `Rodauth::Rails::Model` mixin can be included into the account model, which
|
464
473
|
defines a password attribute and associations for tables used by enabled
|
@@ -470,7 +479,7 @@ class Account < ApplicationRecord
|
|
470
479
|
end
|
471
480
|
```
|
472
481
|
|
473
|
-
|
482
|
+
### Password attribute
|
474
483
|
|
475
484
|
Regardless of whether you're storing the password hash in a column in the
|
476
485
|
accounts table, or in a separate table, the `#password` attribute can be used
|
@@ -494,7 +503,7 @@ Note that the password attribute doesn't come with validations, making it
|
|
494
503
|
unsuitable for forms. It was primarily intended to allow easily creating
|
495
504
|
accounts in development console and in tests.
|
496
505
|
|
497
|
-
|
506
|
+
### Associations
|
498
507
|
|
499
508
|
The `Rodauth::Rails::Model` mixin defines associations for Rodauth tables
|
500
509
|
associated to the accounts table:
|
@@ -544,6 +553,8 @@ class Account < ApplicationRecord
|
|
544
553
|
end
|
545
554
|
```
|
546
555
|
|
556
|
+
#### Association reference
|
557
|
+
|
547
558
|
Below is a list of all associations defined depending on the features loaded:
|
548
559
|
|
549
560
|
| Feature | Association | Type | Model | Table (default) |
|
@@ -568,6 +579,12 @@ Below is a list of all associations defined depending on the features loaded:
|
|
568
579
|
| webauthn | `:webauthn_keys` | `has_many` | `WebauthnKey` | `account_webauthn_keys` |
|
569
580
|
| webauthn | `:webauthn_user_id` | `has_one` | `WebauthnUserId` | `account_webauthn_user_ids` |
|
570
581
|
|
582
|
+
Note that some Rodauth tables use composite primary keys, which Active Record
|
583
|
+
doesn't support out of the box. For associations to work properly, you might
|
584
|
+
need to add the [composite_primary_keys] gem to your Gemfile.
|
585
|
+
|
586
|
+
#### Association options
|
587
|
+
|
571
588
|
By default, all associations except for audit logs have `dependent: :destroy`
|
572
589
|
set, to allow for easy deletion of account records in the console. You can use
|
573
590
|
`:association_options` to modify global or per-association options:
|
@@ -582,31 +599,21 @@ Rodauth::Rails.model(association_options: -> (name) {
|
|
582
599
|
})
|
583
600
|
```
|
584
601
|
|
585
|
-
|
586
|
-
doesn't support out of the box. For associations to work properly, you might
|
587
|
-
need to add the [composite_primary_keys] gem to your Gemfile.
|
588
|
-
|
589
|
-
### Multiple configurations
|
602
|
+
## Multiple configurations
|
590
603
|
|
591
604
|
If you need to handle multiple types of accounts that require different
|
592
|
-
authentication logic, you can create
|
605
|
+
authentication logic, you can create new configurations for them. This
|
606
|
+
is done by creating new `Rodauth::Rails::Auth` subclasses, and registering
|
607
|
+
them under a name.
|
593
608
|
|
594
609
|
```rb
|
595
|
-
# app/
|
610
|
+
# app/misc/rodauth_app.rb
|
596
611
|
class RodauthApp < Rodauth::Rails::App
|
597
612
|
# primary configuration
|
598
|
-
configure
|
599
|
-
# ...
|
600
|
-
end
|
613
|
+
configure RodauthMain
|
601
614
|
|
602
|
-
#
|
603
|
-
configure
|
604
|
-
# ... enable features ...
|
605
|
-
prefix "/admin"
|
606
|
-
session_key_prefix "admin_"
|
607
|
-
remember_cookie_key "_admin_remember" # if using remember feature
|
608
|
-
# ...
|
609
|
-
end
|
615
|
+
# secondary configuration
|
616
|
+
configure RodauthAdmin, :admin
|
610
617
|
|
611
618
|
route do |r|
|
612
619
|
r.rodauth
|
@@ -620,100 +627,46 @@ class RodauthApp < Rodauth::Rails::App
|
|
620
627
|
end
|
621
628
|
end
|
622
629
|
```
|
623
|
-
|
624
|
-
Then in your application you can reference the secondary Rodauth instance:
|
625
|
-
|
626
630
|
```rb
|
627
|
-
|
628
|
-
```
|
629
|
-
|
630
|
-
You'll likely want to save the information of which account belongs to which
|
631
|
-
configuration to the database. One way would be to have a separate table that
|
632
|
-
stores account types:
|
633
|
-
|
634
|
-
```sh
|
635
|
-
$ rails generate migration create_account_types
|
636
|
-
```
|
637
|
-
```rb
|
638
|
-
# db/migrate/*_create_account_types.rb
|
639
|
-
class CreateAccountTypes < ActiveRecord::Migration
|
640
|
-
def change
|
641
|
-
create_table :account_types do |t|
|
642
|
-
t.references :account, foreign_key: { on_delete: :cascade }, null: false
|
643
|
-
t.string :type, null: false
|
644
|
-
end
|
645
|
-
end
|
646
|
-
end
|
647
|
-
```
|
648
|
-
```sh
|
649
|
-
$ rails db:migrate
|
650
|
-
```
|
651
|
-
|
652
|
-
Then an entry would be inserted after account creation, and optionally whenever
|
653
|
-
Rodauth retrieves accounts you could filter only those belonging to the current
|
654
|
-
configuration:
|
655
|
-
|
656
|
-
```rb
|
657
|
-
# app/lib/rodauth_app.rb
|
658
|
-
class RodauthApp < Rodauth::Rails::App
|
659
|
-
configure(:admin) do
|
660
|
-
# ...
|
661
|
-
after_create_account do
|
662
|
-
db[:account_types].insert(account_id: account_id, type: "admin")
|
663
|
-
end
|
664
|
-
auth_class_eval do
|
665
|
-
def account_ds(*)
|
666
|
-
super.join(:account_types, account_id: :id).where(type: "admin")
|
667
|
-
end
|
668
|
-
end
|
669
|
-
# ...
|
670
|
-
end
|
671
|
-
end
|
672
|
-
```
|
673
|
-
|
674
|
-
#### Named auth classes
|
675
|
-
|
676
|
-
A `configure` block inside `Rodauth::Rails::App` will internally create an
|
677
|
-
anonymous `Rodauth::Auth` subclass, and register it under the given name.
|
678
|
-
However, you can also define the auth classes explicitly, by creating
|
679
|
-
subclasses of `Rodauth::Rails::Auth`:
|
680
|
-
|
681
|
-
```rb
|
682
|
-
# app/lib/rodauth_main.rb
|
683
|
-
class RodauthMain < Rodauth::Rails::Auth
|
684
|
-
configure do
|
685
|
-
# ... main configuration ...
|
686
|
-
end
|
687
|
-
end
|
688
|
-
```
|
689
|
-
```rb
|
690
|
-
# app/lib/rodauth_admin.rb
|
631
|
+
# app/misc/rodauth_admin.rb
|
691
632
|
class RodauthAdmin < Rodauth::Rails::Auth
|
692
633
|
configure do
|
693
|
-
# ...
|
634
|
+
# ... enable features ...
|
694
635
|
prefix "/admin"
|
695
636
|
session_key_prefix "admin_"
|
637
|
+
remember_cookie_key "_admin_remember" # if using remember feature
|
696
638
|
# ...
|
639
|
+
|
640
|
+
# search views in `app/views/admin/rodauth` directory
|
641
|
+
rails_controller { Admin::RodauthController }
|
697
642
|
end
|
698
643
|
end
|
699
644
|
```
|
700
645
|
```rb
|
701
|
-
# app/
|
702
|
-
class
|
703
|
-
configure RodauthMain
|
704
|
-
configure RodauthAdmin, :admin
|
705
|
-
# ...
|
646
|
+
# app/controllers/admin/rodauth_controller.rb
|
647
|
+
class Admin::RodauthController < ApplicationController
|
706
648
|
end
|
707
649
|
```
|
708
650
|
|
709
|
-
|
710
|
-
|
711
|
-
|
651
|
+
Then in your application you can reference the secondary Rodauth instance:
|
652
|
+
|
653
|
+
```rb
|
654
|
+
rodauth(:admin).login_path #=> "/admin/login"
|
655
|
+
```
|
656
|
+
|
657
|
+
You'll likely want to save the information of which account belongs to which
|
658
|
+
configuration to the database. See [this guide][account types] on how you can do
|
659
|
+
that.
|
660
|
+
|
661
|
+
### Sharing configuration
|
662
|
+
|
663
|
+
If there are common settings that you want to share between Rodauth
|
664
|
+
configurations, you can do so via inheritance:
|
712
665
|
|
713
666
|
```rb
|
714
|
-
# app/
|
667
|
+
# app/misc/rodauth_base.rb
|
715
668
|
class RodauthBase < Rodauth::Rails::Auth
|
716
|
-
# common settings that
|
669
|
+
# common settings that are shared between multiple configurations
|
717
670
|
configure do
|
718
671
|
enable :login, :logout
|
719
672
|
login_return_to_requested_location? true
|
@@ -723,7 +676,7 @@ class RodauthBase < Rodauth::Rails::Auth
|
|
723
676
|
end
|
724
677
|
```
|
725
678
|
```rb
|
726
|
-
# app/
|
679
|
+
# app/misc/rodauth_main.rb
|
727
680
|
class RodauthMain < RodauthBase # inherit common settings
|
728
681
|
configure do
|
729
682
|
# ... customize main ...
|
@@ -731,7 +684,7 @@ class RodauthMain < RodauthBase # inherit common settings
|
|
731
684
|
end
|
732
685
|
```
|
733
686
|
```rb
|
734
|
-
# app/
|
687
|
+
# app/misc/rodauth_admin.rb
|
735
688
|
class RodauthAdmin < RodauthBase # inherit common settings
|
736
689
|
configure do
|
737
690
|
# ... customize admin ...
|
@@ -739,112 +692,67 @@ class RodauthAdmin < RodauthBase # inherit common settings
|
|
739
692
|
end
|
740
693
|
```
|
741
694
|
|
742
|
-
|
743
|
-
directly at the class level instead of inside an `auth_class_eval`:
|
744
|
-
|
745
|
-
```rb
|
746
|
-
# app/lib/rodauth_admin.rb
|
747
|
-
class RodauthAdmin < Rodauth::Rails::Auth
|
748
|
-
configure do
|
749
|
-
# ...
|
750
|
-
end
|
751
|
-
|
752
|
-
def superadmin?
|
753
|
-
Role.where(account_id: session_id, type: "superadmin").any?
|
754
|
-
end
|
755
|
-
end
|
756
|
-
```
|
757
|
-
```rb
|
758
|
-
# config/routes.rb
|
759
|
-
Rails.application.routes.draw do
|
760
|
-
constraints Rodauth::Rails.authenticated(:admin) { |rodauth| rodauth.superadmin? } do
|
761
|
-
mount Sidekiq::Web => "sidekiq"
|
762
|
-
end
|
763
|
-
end
|
764
|
-
```
|
765
|
-
|
766
|
-
### Calling controller methods
|
695
|
+
## Outside of a request
|
767
696
|
|
768
|
-
|
769
|
-
configuration, in some cases you might want to call methods defined on your
|
770
|
-
controllers. You can do so with `rails_controller_eval`, for example:
|
771
|
-
|
772
|
-
```rb
|
773
|
-
# app/controllers/application_controller.rb
|
774
|
-
class ApplicationController < ActionController::Base
|
775
|
-
private
|
776
|
-
def setup_tracking(account_id)
|
777
|
-
# ... some implementation ...
|
778
|
-
end
|
779
|
-
end
|
780
|
-
```
|
781
|
-
```rb
|
782
|
-
# app/lib/rodauth_app.rb
|
783
|
-
class RodauthApp < Rodauth::Rails::App
|
784
|
-
configure do
|
785
|
-
after_create_account do
|
786
|
-
rails_controller_eval { setup_tracking(account_id) }
|
787
|
-
end
|
788
|
-
end
|
789
|
-
end
|
790
|
-
```
|
791
|
-
|
792
|
-
### Outside of a request
|
697
|
+
### Calling actions
|
793
698
|
|
794
699
|
In some cases you might need to use Rodauth more programmatically. If you want
|
795
700
|
to perform authentication operations outside of request context, Rodauth ships
|
796
701
|
with the [internal_request] feature just for that.
|
797
702
|
|
798
703
|
```rb
|
799
|
-
# app/
|
800
|
-
class
|
704
|
+
# app/misc/rodauth_main.rb
|
705
|
+
class RodauthMain < Rodauth::Rails::Auth
|
801
706
|
configure do
|
802
707
|
enable :internal_request
|
803
708
|
end
|
804
709
|
end
|
805
710
|
```
|
806
711
|
```rb
|
807
|
-
#
|
712
|
+
# primary configuration
|
808
713
|
RodauthApp.rodauth.create_account(login: "user@example.com", password: "secret")
|
809
714
|
RodauthApp.rodauth.verify_account(account_login: "user@example.com")
|
810
715
|
|
811
716
|
# secondary configuration
|
812
|
-
RodauthApp.rodauth(:admin).close_account(account_login: "
|
717
|
+
RodauthApp.rodauth(:admin).close_account(account_login: "user@example.com")
|
813
718
|
```
|
814
719
|
|
815
720
|
The rodauth-rails gem additionally updates the internal rack env hash with your
|
816
721
|
`config.action_mailer.default_url_options`, which is used for generating email
|
817
722
|
links.
|
818
723
|
|
724
|
+
### Generating URLs
|
725
|
+
|
819
726
|
For generating authentication URLs outside of a request use the
|
820
727
|
[path_class_methods] plugin:
|
821
728
|
|
822
729
|
```rb
|
823
|
-
# app/
|
824
|
-
class
|
730
|
+
# app/misc/rodauth_main.rb
|
731
|
+
class RodauthMain < Rodauth::Rails::Auth
|
825
732
|
configure do
|
826
733
|
enable :path_class_methods
|
734
|
+
create_account_route "register"
|
827
735
|
end
|
828
736
|
end
|
829
737
|
```
|
830
738
|
```rb
|
831
|
-
#
|
832
|
-
RodauthApp.rodauth.create_account_path
|
833
|
-
RodauthApp.rodauth.verify_account_url(key: "abc123")
|
739
|
+
# primary configuration
|
740
|
+
RodauthApp.rodauth.create_account_path # => "/register"
|
741
|
+
RodauthApp.rodauth.verify_account_url(key: "abc123") #=> "https://example.com/verify-account?key=abc123"
|
834
742
|
|
835
743
|
# secondary configuration
|
836
|
-
RodauthApp.rodauth(:admin).close_account_path
|
744
|
+
RodauthApp.rodauth(:admin).close_account_path(foo: "bar") #=> "/admin/close-account?foo=bar"
|
837
745
|
```
|
838
746
|
|
839
|
-
|
747
|
+
### Calling instance methods
|
840
748
|
|
841
749
|
If you need to access Rodauth methods not exposed as internal requests, you can
|
842
750
|
use `Rodauth::Rails.rodauth` to retrieve the Rodauth instance used by the
|
843
751
|
internal_request feature:
|
844
752
|
|
845
753
|
```rb
|
846
|
-
# app/
|
847
|
-
class
|
754
|
+
# app/misc/rodauth_main.rb
|
755
|
+
class RodauthMain < Rodauth::Rails::Auth
|
848
756
|
configure do
|
849
757
|
enable :internal_request # this is required
|
850
758
|
end
|
@@ -852,7 +760,7 @@ end
|
|
852
760
|
```
|
853
761
|
```rb
|
854
762
|
account = Account.find_by!(email: "user@example.com")
|
855
|
-
rodauth = Rodauth::Rails.rodauth(account: account)
|
763
|
+
rodauth = Rodauth::Rails.rodauth(account: account) #=> #<RodauthMain::InternalRequest ...>
|
856
764
|
|
857
765
|
rodauth.compute_hmac("token") #=> "TpEJTKfKwqYvIDKWsuZhkhKlhaBXtR1aodskBAflD8U"
|
858
766
|
rodauth.open_account? #=> true
|
@@ -971,188 +879,10 @@ connection, using the [sequel-activerecord_connection] gem.
|
|
971
879
|
This means that, from the usage perspective, Sequel can be considered just
|
972
880
|
as an implementation detail of Rodauth.
|
973
881
|
|
974
|
-
## JSON API
|
975
|
-
|
976
|
-
To make Rodauth endpoints accessible via JSON API, enable the [`json`][json]
|
977
|
-
feature:
|
978
|
-
|
979
|
-
```rb
|
980
|
-
# app/lib/rodauth_app.rb
|
981
|
-
class RodauthApp < Rodauth::Rails::App
|
982
|
-
configure do
|
983
|
-
# ...
|
984
|
-
enable :json
|
985
|
-
only_json? true # accept only JSON requests (optional)
|
986
|
-
# ...
|
987
|
-
end
|
988
|
-
end
|
989
|
-
```
|
990
|
-
|
991
|
-
This will store account session data into the Rails session. If you rather want
|
992
|
-
stateless token-based authentication via the `Authorization` header, enable the
|
993
|
-
[`jwt`][jwt] feature (which builds on top of the `json` feature) and add the
|
994
|
-
[JWT gem] to the Gemfile:
|
995
|
-
|
996
|
-
```sh
|
997
|
-
$ bundle add jwt
|
998
|
-
```
|
999
|
-
```rb
|
1000
|
-
# app/lib/rodauth_app.rb
|
1001
|
-
class RodauthApp < Rodauth::Rails::App
|
1002
|
-
configure do
|
1003
|
-
# ...
|
1004
|
-
enable :jwt
|
1005
|
-
jwt_secret "<YOUR_SECRET_KEY>" # store the JWT secret in a safe place
|
1006
|
-
only_json? true # accept only JSON requests (optional)
|
1007
|
-
# ...
|
1008
|
-
end
|
1009
|
-
end
|
1010
|
-
```
|
1011
|
-
|
1012
|
-
The JWT token will be returned after each request to Rodauth routes. To also
|
1013
|
-
return the JWT token on requests to your app's routes, you can add the
|
1014
|
-
following code to your base controller:
|
1015
|
-
|
1016
|
-
```rb
|
1017
|
-
class ApplicationController < ActionController::Base
|
1018
|
-
# ...
|
1019
|
-
after_action :set_jwt_token
|
1020
|
-
|
1021
|
-
private
|
1022
|
-
|
1023
|
-
def set_jwt_token
|
1024
|
-
if rodauth.use_jwt? && rodauth.valid_jwt?
|
1025
|
-
response.headers["Authorization"] = rodauth.session_jwt
|
1026
|
-
end
|
1027
|
-
end
|
1028
|
-
# ...
|
1029
|
-
end
|
1030
|
-
```
|
1031
|
-
|
1032
|
-
## OmniAuth
|
1033
|
-
|
1034
|
-
While Rodauth doesn't yet come with [OmniAuth] integration, we can build one
|
1035
|
-
ourselves using the existing Rodauth API.
|
1036
|
-
|
1037
|
-
Let's assume we're building Facebook login. We'll start by installing the
|
1038
|
-
necessary gems, and loading the Facebook OmniAuth strategy:
|
1039
|
-
|
1040
|
-
```rb
|
1041
|
-
# Gemfile
|
1042
|
-
gem "omniauth", "~> 2.0"
|
1043
|
-
gem "omniauth-rails_csrf_protection" # https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284
|
1044
|
-
gem "omniauth-facebook"
|
1045
|
-
```
|
1046
|
-
```rb
|
1047
|
-
# config/initializers/omniauth.rb
|
1048
|
-
Rails.application.config.middleware.use OmniAuth::Builder do
|
1049
|
-
provider :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"],
|
1050
|
-
scope: "email", callback_path: "/auth/facebook/callback"
|
1051
|
-
end
|
1052
|
-
```
|
1053
|
-
|
1054
|
-
Since users might potentially want to login with multiple external providers, let's
|
1055
|
-
create an `account_identities` table that will have a many-to-one relationship
|
1056
|
-
with the `accounts` table:
|
1057
|
-
|
1058
|
-
```sh
|
1059
|
-
$ rails generate model AccountIdentity
|
1060
|
-
```
|
1061
|
-
```rb
|
1062
|
-
# db/migrate/*_create_account_identities.rb
|
1063
|
-
class CreateAccountIdentities < ActiveRecord::Migration
|
1064
|
-
def change
|
1065
|
-
create_table :account_identities do |t|
|
1066
|
-
t.references :account, null: false, foreign_key: { on_delete: :cascade }
|
1067
|
-
t.string :provider, null: false
|
1068
|
-
t.string :uid, null: false
|
1069
|
-
t.jsonb :info, null: false, default: {} # adjust JSON column type for your database
|
1070
|
-
|
1071
|
-
t.timestamps
|
1072
|
-
|
1073
|
-
t.index [:provider, :uid], unique: true
|
1074
|
-
end
|
1075
|
-
end
|
1076
|
-
end
|
1077
|
-
```
|
1078
|
-
```rb
|
1079
|
-
# app/models/account_identity.rb
|
1080
|
-
class AcccountIdentity < ApplicationRecord
|
1081
|
-
belongs_to :account
|
1082
|
-
end
|
1083
|
-
```
|
1084
|
-
```rb
|
1085
|
-
# app/models/account.rb
|
1086
|
-
class Account < ApplicationRecord
|
1087
|
-
has_many :identities, class_name: "AccountIdentity"
|
1088
|
-
end
|
1089
|
-
```
|
1090
|
-
|
1091
|
-
Next, let's add a POST button pointing to the request URL to our login form:
|
1092
|
-
|
1093
|
-
```erb
|
1094
|
-
<%= button_to "Login via Facebook", "/auth/facebook",
|
1095
|
-
method: :post, data: { turbo: false }, class: "btn btn-link p-0" %>
|
1096
|
-
```
|
1097
|
-
|
1098
|
-
Finally, let's implement the OmniAuth callback endpoint on our Rodauth
|
1099
|
-
controller:
|
1100
|
-
|
1101
|
-
```rb
|
1102
|
-
# config/routes.rb
|
1103
|
-
Rails.application.routes.draw do
|
1104
|
-
# ...
|
1105
|
-
get "/auth/:provider/callback", to: "rodauth#omniauth"
|
1106
|
-
end
|
1107
|
-
```
|
1108
|
-
```rb
|
1109
|
-
# app/controllres/rodauth_controller.rb
|
1110
|
-
class RodauthController < ApplicationController
|
1111
|
-
def omniauth
|
1112
|
-
auth = request.env["omniauth.auth"]
|
1113
|
-
|
1114
|
-
# attempt to find existing identity directly
|
1115
|
-
identity = AccountIdentity.find_by(provider: auth["provider"], uid: auth["uid"])
|
1116
|
-
|
1117
|
-
if identity
|
1118
|
-
# update any external info changes
|
1119
|
-
identity.update!(info: auth["info"])
|
1120
|
-
# set account from identity
|
1121
|
-
account = identity.account
|
1122
|
-
end
|
1123
|
-
|
1124
|
-
# attempt to find an existing account by email
|
1125
|
-
account ||= Account.find_by(email: auth["info"]["email"])
|
1126
|
-
|
1127
|
-
# disallow login if account is not verified
|
1128
|
-
if account && account.status != rodauth.account_open_status_value
|
1129
|
-
redirect_to rodauth.login_path, alert: rodauth.unverified_account_message
|
1130
|
-
return
|
1131
|
-
end
|
1132
|
-
|
1133
|
-
# create new account if it doesn't exist
|
1134
|
-
unless account
|
1135
|
-
account = Account.create!(email: auth["info"]["email"], status: rodauth.account_open_status_value)
|
1136
|
-
end
|
1137
|
-
|
1138
|
-
# create new identity if it doesn't exist
|
1139
|
-
unless identity
|
1140
|
-
account.identities.create!(provider: auth["provider"], uid: auth["uid"], info: auth["info"])
|
1141
|
-
end
|
1142
|
-
|
1143
|
-
# load the account into the rodauth instance
|
1144
|
-
rodauth.account_from_login(account.email)
|
1145
|
-
|
1146
|
-
rodauth_response do # ensures any `after_action` callbacks get called
|
1147
|
-
# sign in the loaded account
|
1148
|
-
rodauth.login("omniauth")
|
1149
|
-
end
|
1150
|
-
end
|
1151
|
-
end
|
1152
|
-
```
|
1153
|
-
|
1154
882
|
## Configuring
|
1155
883
|
|
884
|
+
### Configuration methods
|
885
|
+
|
1156
886
|
The `rails` feature rodauth-rails loads provides the following configuration
|
1157
887
|
methods:
|
1158
888
|
|
@@ -1167,6 +897,8 @@ methods:
|
|
1167
897
|
| `rails_controller` | Controller class to use for rendering and CSRF protection. |
|
1168
898
|
| `rails_account_model` | Model class connected with the accounts table. |
|
1169
899
|
|
900
|
+
### General configuration
|
901
|
+
|
1170
902
|
The `Rodauth::Rails` module has a few config settings available as well:
|
1171
903
|
|
1172
904
|
| Name | Description |
|
@@ -1185,169 +917,102 @@ end
|
|
1185
917
|
For the list of configuration methods provided by Rodauth, see the [feature
|
1186
918
|
documentation].
|
1187
919
|
|
1188
|
-
|
1189
|
-
|
1190
|
-
When developing custom extensions for Rodauth inside your Rails project, it's
|
1191
|
-
probably better to use plain modules, at least in the beginning, as Rodauth
|
1192
|
-
feature design doesn't yet work well with Zeitwerk reloading.
|
920
|
+
### Defining custom methods
|
1193
921
|
|
1194
|
-
|
1195
|
-
|
922
|
+
All Rodauth configuration methods are just syntax sugar for defining instance
|
923
|
+
methods on the auth class. You can also define your own custom methods on the
|
924
|
+
auth class:
|
1196
925
|
|
1197
926
|
```rb
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
false
|
927
|
+
class RodauthMain < Rodauth::Rails::Auth
|
928
|
+
configure do
|
929
|
+
password_match? { |password| ldap_valid?(password) }
|
1202
930
|
end
|
1203
931
|
|
1204
|
-
|
932
|
+
# Example external identities table
|
933
|
+
def identities
|
934
|
+
db[:account_identities].where(account_id: account_id).all
|
935
|
+
end
|
936
|
+
|
937
|
+
private
|
938
|
+
|
939
|
+
# Example LDAP authentication
|
940
|
+
def ldap_valid?(password)
|
1205
941
|
SimpleLdapAuthenticator.valid?(account[:email], password)
|
1206
942
|
end
|
1207
943
|
end
|
1208
944
|
```
|
1209
945
|
```rb
|
1210
|
-
|
1211
|
-
class RodauthApp < Rodauth::Rails::App
|
1212
|
-
configure do
|
1213
|
-
# ...
|
1214
|
-
auth_class_eval do
|
1215
|
-
include RodauthLdap
|
1216
|
-
end
|
1217
|
-
# ...
|
1218
|
-
end
|
1219
|
-
end
|
946
|
+
rodauth.identities #=> [{ provider: "facebook", uid: "abc123", ... }, ...]
|
1220
947
|
```
|
1221
948
|
|
1222
|
-
|
949
|
+
### Rails URL helpers
|
1223
950
|
|
1224
|
-
|
951
|
+
Inside Rodauth configuration and the `route` block you can access Rails route
|
952
|
+
helpers through `#rails_routes`:
|
1225
953
|
|
1226
954
|
```rb
|
1227
|
-
#
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
include ActiveJob::TestHelper
|
1232
|
-
driven_by :rack_test
|
1233
|
-
|
1234
|
-
test "creating and verifying an account" do
|
1235
|
-
create_account
|
1236
|
-
assert_match "An email has been sent to you with a link to verify your account", page.text
|
1237
|
-
|
1238
|
-
verify_account
|
1239
|
-
assert_match "Your account has been verified", page.text
|
955
|
+
# app/misc/rodauth_main.rb
|
956
|
+
class RodauthMain < Rodauth::Rails::Auth
|
957
|
+
configure do
|
958
|
+
login_redirect { rails_routes.activity_path }
|
1240
959
|
end
|
960
|
+
end
|
961
|
+
```
|
1241
962
|
|
1242
|
-
|
1243
|
-
create_account(verify: true)
|
1244
|
-
|
1245
|
-
logout
|
1246
|
-
assert_match "You have been logged out", page.text
|
963
|
+
### Calling controller methods
|
1247
964
|
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
965
|
+
When using Rodauth before/after hooks or generally overriding your Rodauth
|
966
|
+
configuration, in some cases you might want to call methods defined on your
|
967
|
+
controllers. You can do so with `rails_controller_eval`, for example:
|
1251
968
|
|
969
|
+
```rb
|
970
|
+
# app/controllers/application_controller.rb
|
971
|
+
class ApplicationController < ActionController::Base
|
1252
972
|
private
|
1253
|
-
|
1254
|
-
|
1255
|
-
visit "/create-account"
|
1256
|
-
fill_in "Login", with: email
|
1257
|
-
fill_in "Password", with: password
|
1258
|
-
fill_in "Confirm Password", with: password
|
1259
|
-
click_on "Create Account"
|
1260
|
-
verify_account if verify
|
1261
|
-
end
|
1262
|
-
|
1263
|
-
def verify_account
|
1264
|
-
perform_enqueued_jobs # run enqueued email deliveries
|
1265
|
-
email = ActionMailer::Base.deliveries.last
|
1266
|
-
verify_account_link = email.body.to_s[/\S+verify-account\S+/]
|
1267
|
-
visit verify_account_link
|
1268
|
-
click_on "Verify Account"
|
1269
|
-
end
|
1270
|
-
|
1271
|
-
def login(email: "user@example.com", password: "secret")
|
1272
|
-
visit "/login"
|
1273
|
-
fill_in "Login", with: email
|
1274
|
-
fill_in "Password", with: password
|
1275
|
-
click_on "Login"
|
1276
|
-
end
|
1277
|
-
|
1278
|
-
def logout
|
1279
|
-
visit "/logout"
|
1280
|
-
click_on "Logout"
|
973
|
+
def setup_tracking(account_id)
|
974
|
+
# ... some implementation ...
|
1281
975
|
end
|
1282
976
|
end
|
1283
977
|
```
|
1284
|
-
|
1285
|
-
While request tests in JSON API mode with JWT tokens could look something like
|
1286
|
-
this:
|
1287
|
-
|
1288
978
|
```rb
|
1289
|
-
#
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
assert_response :success
|
1296
|
-
assert_match "An email has been sent to you with a link to verify your account", JSON.parse(body)["success"]
|
1297
|
-
|
1298
|
-
verify_account
|
1299
|
-
assert_response :success
|
1300
|
-
assert_match "Your account has been verified", JSON.parse(body)["success"]
|
1301
|
-
end
|
1302
|
-
|
1303
|
-
test "logging in and logging out" do
|
1304
|
-
create_account(verify: true)
|
1305
|
-
|
1306
|
-
logout
|
1307
|
-
assert_response :success
|
1308
|
-
assert_match "You have been logged out", JSON.parse(body)["success"]
|
1309
|
-
|
1310
|
-
login
|
1311
|
-
assert_response :success
|
1312
|
-
assert_match "You have been logged in", JSON.parse(body)["success"]
|
979
|
+
# app/misc/rodauth_main.rb
|
980
|
+
class RodauthMain < Rodauth::Rails::Auth
|
981
|
+
configure do
|
982
|
+
after_create_account do
|
983
|
+
rails_controller_eval { setup_tracking(account_id) }
|
984
|
+
end
|
1313
985
|
end
|
986
|
+
end
|
987
|
+
```
|
1314
988
|
|
1315
|
-
|
989
|
+
### Single-file configuration
|
1316
990
|
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
end
|
991
|
+
If you would prefer to have all Rodauth logic contained inside a single file,
|
992
|
+
you call `Rodauth::Rails::App.configure` with a block, which will create an
|
993
|
+
anonymous auth class.
|
1321
994
|
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
995
|
+
```rb
|
996
|
+
# app/misc/rodauth_app.rb
|
997
|
+
class RodauthApp < Rodauth::Rails::App
|
998
|
+
# primary configuration
|
999
|
+
configure do
|
1000
|
+
enable :login, :logout, :create_account, :verify_account
|
1001
|
+
# ...
|
1327
1002
|
end
|
1328
1003
|
|
1329
|
-
|
1330
|
-
|
1004
|
+
# secondary configuration
|
1005
|
+
configure(:admin) do
|
1006
|
+
enable :email_auth, :single_session
|
1007
|
+
# ...
|
1331
1008
|
end
|
1332
1009
|
|
1333
|
-
|
1334
|
-
|
1010
|
+
route do |r|
|
1011
|
+
# ...
|
1335
1012
|
end
|
1336
1013
|
end
|
1337
1014
|
```
|
1338
1015
|
|
1339
|
-
If you're delivering emails in the background, make sure to set Active Job
|
1340
|
-
queue adapter to `:test` or `:inline`:
|
1341
|
-
|
1342
|
-
```rb
|
1343
|
-
# config/environments/test.rb
|
1344
|
-
Rails.application.configure do |config|
|
1345
|
-
# ...
|
1346
|
-
config.active_job.queue_adapter = :test # or :inline
|
1347
|
-
# ...
|
1348
|
-
end
|
1349
|
-
```
|
1350
|
-
|
1351
1016
|
## Rodauth defaults
|
1352
1017
|
|
1353
1018
|
rodauth-rails changes some of the default Rodauth settings for easier setup:
|
@@ -1454,7 +1119,6 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
|
|
1454
1119
|
[Rodauth]: https://github.com/jeremyevans/rodauth
|
1455
1120
|
[Sequel]: https://github.com/jeremyevans/sequel
|
1456
1121
|
[feature documentation]: http://rodauth.jeremyevans.net/documentation.html
|
1457
|
-
[JWT gem]: https://github.com/jwt/ruby-jwt
|
1458
1122
|
[Bootstrap]: https://getbootstrap.com/
|
1459
1123
|
[Roda]: http://roda.jeremyevans.net/
|
1460
1124
|
[HMAC]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-HMAC
|
@@ -1463,7 +1127,6 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
|
|
1463
1127
|
[sequel-activerecord_connection]: https://github.com/janko/sequel-activerecord_connection
|
1464
1128
|
[plugin options]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Plugin+Options
|
1465
1129
|
[hmac]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-HMAC
|
1466
|
-
[OmniAuth]: https://github.com/omniauth/omniauth
|
1467
1130
|
[otp]: http://rodauth.jeremyevans.net/rdoc/files/doc/otp_rdoc.html
|
1468
1131
|
[sms_codes]: http://rodauth.jeremyevans.net/rdoc/files/doc/sms_codes_rdoc.html
|
1469
1132
|
[recovery_codes]: http://rodauth.jeremyevans.net/rdoc/files/doc/recovery_codes_rdoc.html
|
@@ -1484,3 +1147,6 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
|
|
1484
1147
|
[internal_request]: http://rodauth.jeremyevans.net/rdoc/files/doc/internal_request_rdoc.html
|
1485
1148
|
[composite_primary_keys]: https://github.com/composite-primary-keys/composite_primary_keys
|
1486
1149
|
[path_class_methods]: https://rodauth.jeremyevans.net/rdoc/files/doc/path_class_methods_rdoc.html
|
1150
|
+
[account types]: https://github.com/janko/rodauth-rails/wiki/Account-Types
|
1151
|
+
[custom mailer worker]: https://github.com/janko/rodauth-rails/wiki/Custom-Mailer-Worker
|
1152
|
+
[Turbo]: https://turbo.hotwired.dev/
|