rodauth-rails 1.8.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +155 -243
  4. data/lib/generators/rodauth/install_generator.rb +1 -1
  5. data/lib/generators/rodauth/migration/active_record/active_sessions.erb +2 -2
  6. data/lib/generators/rodauth/migration/active_record/audit_logging.erb +2 -2
  7. data/lib/generators/rodauth/migration/active_record/email_auth.erb +1 -1
  8. data/lib/generators/rodauth/migration/active_record/otp.erb +1 -1
  9. data/lib/generators/rodauth/migration/active_record/password_expiration.erb +1 -1
  10. data/lib/generators/rodauth/migration/active_record/reset_password.erb +1 -1
  11. data/lib/generators/rodauth/migration/active_record/sms_codes.erb +1 -1
  12. data/lib/generators/rodauth/migration/active_record/verify_account.erb +2 -2
  13. data/lib/generators/rodauth/migration/active_record/webauthn.erb +1 -1
  14. data/lib/generators/rodauth/migration_generator.rb +2 -22
  15. data/lib/generators/rodauth/templates/app/mailers/rodauth_mailer.rb.tt +7 -7
  16. data/lib/generators/rodauth/templates/app/misc/rodauth_main.rb.tt +1 -1
  17. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form.html.erb +1 -1
  18. data/lib/generators/rodauth/templates/app/views/rodauth/login.html.erb +2 -2
  19. data/lib/generators/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +2 -2
  20. data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/_login_form.html.erb +1 -1
  21. data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/login.html.erb +2 -2
  22. data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/multi_phase_login.html.erb +2 -2
  23. data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/webauthn_autofill.html.erb +10 -0
  24. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_autofill.html.erb +10 -0
  25. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +1 -1
  26. data/lib/generators/rodauth/templates/db/migrate/create_rodauth.rb.tt +1 -1
  27. data/lib/generators/rodauth/views_generator.rb +3 -12
  28. data/lib/rodauth/rails/app.rb +7 -9
  29. data/lib/rodauth/rails/feature/base.rb +5 -29
  30. data/lib/rodauth/rails/feature/render.rb +1 -1
  31. data/lib/rodauth/rails/railtie.rb +2 -6
  32. data/lib/rodauth/rails/version.rb +1 -1
  33. data/lib/rodauth/rails.rb +10 -10
  34. data/rodauth-rails.gemspec +2 -2
  35. metadata +9 -9
  36. data/lib/generators/rodauth/templates/app/views/rodauth/_login_form_header.html.erb +0 -3
  37. data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/_login_form_header.html.erb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df597e01d85bea28254330ac00e288d569fe709744e11ade3ada370784034b6a
4
- data.tar.gz: 2934d9ea6177fa55e383cfbcbfdca6b4b27a36a1afdb7c9971e918fbca76e604
3
+ metadata.gz: adfcbce27e52d0a53b5cd670489635c841dff9e2809c92be059286943894db6c
4
+ data.tar.gz: e98584823e926c810bc66366496df5fb3c8eed0f38e291b76b9f132480941a9c
5
5
  SHA512:
6
- metadata.gz: bf30eabb2fb372e96caf39ceb0e01696dcc45003db00703fd4eaa127bba8378a0e76c4194b0f2161851df82a066f0147ed72cedea25429657a287734f76d4e49
7
- data.tar.gz: 40f773856e54971d573995e7f6c11b9a67c42c881ce95e458739fc5a12151a954233b3e80339beff622b82e79bc5485fc6497f7dd90c09cfd42ed2ca1abe3912
6
+ metadata.gz: 845b037926a9372522da9b3507b5fd2959454bc24198f72a7832d9025ccd27f9bac3790823577e1e68c3a1e1a076472e1629825973c37cc932e2b63299e1408b
7
+ data.tar.gz: af417d7bbe9732c677ca15c6796817554fe68d5f8f3db8001b56a736db33382f3efd8f86952509d038f45f449f76d3c9ea61f1a7f5a29c1cef5f45e72cf1c9ce
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 1.10.0 (2023-07-26)
2
+
3
+ * Add `Rodauth::Rails.lib` for easier usage of Rodauth as a library in Rails apps (@janko)
4
+
5
+ ## 1.9.0 (2023-05-22)
6
+
7
+ * Add support for webauthn_autofill feature to the views generator (@janko)
8
+
9
+ * Generate view templates for two_factor_base feature only if explicitly specified (@janko)
10
+
11
+ * Set `login_param "email"` in generated Rodauth configuration (@janko)
12
+
13
+ * Handle Trilogy adapter in generators (@janko)
14
+
15
+ * Use `email_subject_prefix` in generated mailer (@janko)
16
+
17
+ * Fix typo in `unlock_account` email template (@zavan)
18
+
19
+ * Retrieve current account using `account!` in `#rails_account` method (@janko)
20
+
21
+ * Drop support for Rails 4.2 (@janko)
22
+
1
23
  ## 1.8.0 (2023-02-25)
2
24
 
3
25
  * Add table argument to `rodauth:install` generator (@janko)
data/README.md CHANGED
@@ -24,6 +24,7 @@ Provides Rails integration for the [Rodauth] authentication framework.
24
24
  * [How to build an OIDC provider using rodauth-oauth on Rails](https://honeyryderchuck.gitlab.io/httpx/2021/03/15/oidc-provider-on-rails-using-rodauth-oauth.html)
25
25
  * [What It Took to Build a Rails Integration for Rodauth](https://janko.io/what-it-took-to-build-a-rails-integration-for-rodauth/)
26
26
  * [Social Login in Rails with Rodauth](https://janko.io/social-login-in-rails-with-rodauth/)
27
+ * [Passkey Authentication with Rodauth](https://janko.io/passkey-authentication-with-rodauth/)
27
28
 
28
29
  ## Why Rodauth?
29
30
 
@@ -31,16 +32,13 @@ There are already several popular authentication solutions for Rails (Devise,
31
32
  Sorcery, Clearance, Authlogic), so why would you choose Rodauth? Here are some
32
33
  of the advantages that stand out for me:
33
34
 
34
- * multifactor authentication ([TOTP][otp], [SMS codes][sms_codes], [recovery codes][recovery_codes], [WebAuthn][webauthn])
35
+ * multifactor authentication ([TOTP][otp], [SMS codes][sms_codes], [recovery codes][recovery_codes], [passkeys][webauthn])
35
36
  * standardized [JSON API support][json] for every feature (including [JWT][jwt])
36
37
  * enterprise security features ([password complexity][password_complexity], [disallow password reuse][disallow_password_reuse], [password expiration][password_expiration], [session expiration][session_expiration], [single session][single_session], [account expiration][account_expiration])
37
- * [email authentication][email_auth] (aka "passwordless")
38
- * [audit logging][audit_logging] (for any action)
38
+ * passwordless authentication ([email][email_auth], [passkeys][webauthn_login])
39
+ * [audit logging][audit_logging] for any action
39
40
  * ability to protect password hashes even in case of SQL injection ([more details][password protection])
40
- * additional bruteforce protection for tokens ([more details][bruteforce tokens])
41
- * uniform configuration DSL (any setting can be static or dynamic)
42
- * consistent before/after hooks around everything
43
- * dedicated object encapsulating all authentication logic
41
+ * uniform configuration DSL with before/after hooks around everything
44
42
 
45
43
  ### Sequel
46
44
 
@@ -188,25 +186,6 @@ current_account #=> #<Account id=123 email="user@example.com">
188
186
  current_account.email #=> "user@example.com"
189
187
  ```
190
188
 
191
- If the session is logged in, but the account doesn't exist in the database, the
192
- session will be reset.
193
-
194
- #### Custom account model
195
-
196
- The `#rails_account` method will try to infer the account model class from the
197
- configured accounts table name. However, if the model class cannot be inferred
198
- from the table name, you can configure it manually:
199
-
200
- ```rb
201
- # app/misc/rodauth_main.rb
202
- class RodauthMain < Rodauth::Rails::Auth
203
- configure do
204
- # ...
205
- rails_account_model { Authentication::Account } # custom model name
206
- end
207
- end
208
- ```
209
-
210
189
  ### Requiring authentication
211
190
 
212
191
  You'll likely want to require authentication for certain parts of your app,
@@ -222,8 +201,8 @@ class RodauthApp < Rodauth::Rails::App
222
201
  # ...
223
202
  r.rodauth # route rodauth requests
224
203
 
225
- # require authentication for /dashboard/* and /account/* routes
226
- if r.path.start_with?("/dashboard") || r.path.start_with?("/account")
204
+ # require authentication for /dashboard/* routes
205
+ if r.path.start_with?("/dashboard")
227
206
  rodauth.require_account # redirect to login page if not authenticated
228
207
  end
229
208
  end
@@ -248,12 +227,6 @@ class DashboardController < ApplicationController
248
227
  before_action :authenticate
249
228
  end
250
229
  ```
251
- ```rb
252
- # app/controllers/posts_controller.rb
253
- class PostsController < ApplicationController
254
- before_action :authenticate, except: [:index, :show]
255
- end
256
- ```
257
230
 
258
231
  #### Routing constraints
259
232
 
@@ -282,42 +255,83 @@ Rails.application.routes.draw do
282
255
  end
283
256
  ```
284
257
 
285
- The current account can be retrieved via the `#rails_account` method:
258
+ You can specify a different Rodauth configuration by passing the configuration name:
286
259
 
287
260
  ```rb
288
261
  # config/routes.rb
289
262
  Rails.application.routes.draw do
290
- # require user to be admin
291
- constraints Rodauth::Rails.authenticated { |rodauth| rodauth.rails_account.admin? } do
263
+ constraints Rodauth::Rails.authenticated(:admin) do
292
264
  # ...
293
265
  end
294
266
  end
295
267
  ```
296
268
 
297
- You can specify the Rodauth configuration by passing the configuration name:
269
+ If you need something more custom, you can always create the routing constraint
270
+ manually:
298
271
 
299
272
  ```rb
300
273
  # config/routes.rb
301
274
  Rails.application.routes.draw do
302
- constraints Rodauth::Rails.authenticated(:admin) do
303
- # ...
275
+ constraints -> (r) { !r.env["rodauth"].logged_in? } do # or env["rodauth.admin"]
276
+ # routes when the user is not logged in
304
277
  end
305
278
  end
306
279
  ```
307
280
 
308
- If you need something more custom, you can always create the routing constraint
309
- manually:
281
+ ### Controller
282
+
283
+ Your Rodauth configuration is connected to a Rails controller (`RodauthController` by default), and
284
+ it automatically executes any callbacks and rescue handlers defined on it (or the parent controller)
285
+ around Rodauth endpoints.
310
286
 
311
287
  ```rb
312
- # config/routes.rb
313
- Rails.application.routes.draw do
314
- constraints -> (r) { !r.env["rodauth"].logged_in? } do # or "rodauth.admin"
315
- # routes when the user is not logged in
288
+ class RodauthController < ApplicationController
289
+ before_action :set_locale # executes before Rodauth endpoints
290
+ rescue_from("MyApp::SomeError") { |exception| ... } # rescues around Rodauth endpoints
291
+ end
292
+ ```
293
+
294
+ #### Calling controller methods
295
+
296
+ You can call any controller methods from your Rodauth configuration via `rails_controller_eval`:
297
+
298
+ ```rb
299
+ # app/controllers/application_controller.rb
300
+ class ApplicationController < ActionController::Base
301
+ private
302
+ def setup_tracking(account_id)
303
+ # ... some implementation ...
304
+ end
305
+ end
306
+ ```
307
+ ```rb
308
+ # app/misc/rodauth_main.rb
309
+ class RodauthMain < Rodauth::Rails::Auth
310
+ configure do
311
+ after_create_account do
312
+ rails_controller_eval { setup_tracking(account_id) }
313
+ end
316
314
  end
317
315
  end
318
316
  ```
319
317
 
320
- ### Views
318
+ ### Rails URL helpers
319
+
320
+ Inside Rodauth configuration and the `route` block you can access Rails route
321
+ helpers through `#rails_routes`:
322
+
323
+ ```rb
324
+ # app/misc/rodauth_main.rb
325
+ class RodauthMain < Rodauth::Rails::Auth
326
+ configure do
327
+ login_redirect { rails_routes.activity_path }
328
+ change_password_redirect { rails_routes.profile_path }
329
+ change_login_redirect { rails_routes.profile_path }
330
+ end
331
+ end
332
+ ```
333
+
334
+ ## Views
321
335
 
322
336
  The templates built into Rodauth are useful when getting started, but soon
323
337
  you'll want to start editing the markup. You can run the following command to
@@ -349,10 +363,10 @@ $ rails generate rodauth:views --all
349
363
  Use `--name` to generate views for a different Rodauth configuration:
350
364
 
351
365
  ```sh
352
- $ rails generate rodauth:views webauthn --name admin
366
+ $ rails generate rodauth:views webauthn two_factor_base --name admin
353
367
  ```
354
368
 
355
- #### Page titles
369
+ ### Page titles
356
370
 
357
371
  The generated configuration sets `title_instance_variable` to make page titles
358
372
  available in your views via `@page_title` instance variable, which you can then
@@ -362,9 +376,7 @@ use in your layout:
362
376
  # app/misc/rodauth_main.rb
363
377
  class RodauthMain < Rodauth::Rails::Auth
364
378
  configure do
365
- # ...
366
379
  title_instance_variable :@page_title
367
- # ...
368
380
  end
369
381
  end
370
382
  ```
@@ -376,28 +388,11 @@ end
376
388
  <title><%= @page_title || "Default title" %></title>
377
389
  <!-- ... -->
378
390
  </head>
379
- <body>
380
- <!-- ... -->
381
- </body>
391
+ <!-- ... -->
382
392
  </html>
383
393
  ```
384
394
 
385
- If you're already setting page titles via `content_for`, you can use it in
386
- generated Rodauth views, giving it the result of the corresponding
387
- `*_page_title` method:
388
-
389
- ```erb
390
- <!-- app/views/rodauth/login.html.erb -->
391
- <%= content_for :page_title, rodauth.login_page_title %>
392
- <!-- ... -->
393
- ```
394
- ```erb
395
- <!-- app/views/rodauth/change_password.html.erb -->
396
- <%= content_for :page_title, rodauth.change_password_page_title %>
397
- <!-- ... -->
398
- ```
399
-
400
- #### Layout
395
+ ### Layout
401
396
 
402
397
  To use different layouts for different Rodauth views, you can compare the
403
398
  request path in the layout method:
@@ -425,7 +420,7 @@ class RodauthController < ApplicationController
425
420
  end
426
421
  ```
427
422
 
428
- #### Turbo
423
+ ### Turbo
429
424
 
430
425
  [Turbo] has been disabled by default on all built-in and generated view
431
426
  templates, because some Rodauth actions (multi-phase login, adding recovery
@@ -434,7 +429,7 @@ codes) aren't Turbo-compatible, as they return 200 responses on POST requests.
434
429
  That being said, most of Rodauth *is* Turbo-compatible, so feel free to enable
435
430
  Turbo for actions where you want to use it.
436
431
 
437
- ### Mailer
432
+ ## Mailer
438
433
 
439
434
  The install generator will create `RodauthMailer` with default email templates,
440
435
  and configure Rodauth features that send emails as part of the authentication
@@ -443,73 +438,45 @@ flow to use it.
443
438
  ```rb
444
439
  # app/mailers/rodauth_mailer.rb
445
440
  class RodauthMailer < ApplicationMailer
446
- def verify_account(account_id, key)
447
- # ...
448
- end
449
- def reset_password(account_id, key)
450
- # ...
451
- end
452
- def verify_login_change(account_id, old_login, new_login, key)
453
- # ...
454
- end
455
- def password_changed(account_id)
456
- # ...
457
- end
458
- # def email_auth(account_id, key)
459
- # ...
460
- # end
461
- # def unlock_account(account_id, key)
462
- # ...
463
- # end
441
+ def verify_account(account_id, key) ... end
442
+ def reset_password(account_id, key) ... end
443
+ def verify_login_change(account_id, key) ... end
444
+ def password_changed(account_id) ... end
445
+ # def email_auth(account_id, key) ... end
446
+ # def unlock_account(account_id, key) ... end
464
447
  end
465
448
  ```
466
449
  ```rb
467
450
  # app/misc/rodauth_main.rb
468
451
  class RodauthMain < Rodauth::Rails::Auth
469
452
  configure do
470
- # ...
471
- create_reset_password_email do
472
- RodauthMailer.reset_password(account_id, reset_password_key_value)
473
- end
474
- create_verify_account_email do
475
- RodauthMailer.verify_account(account_id, verify_account_key_value)
476
- end
477
- create_verify_login_change_email do |_login|
478
- RodauthMailer.verify_login_change(account_id, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_key_value)
479
- end
480
- create_password_changed_email do
481
- RodauthMailer.password_changed(account_id)
482
- end
483
- # create_email_auth_email do
484
- # RodauthMailer.email_auth(account_id, email_auth_key_value)
485
- # end
486
- # create_unlock_account_email do
487
- # RodauthMailer.unlock_account(account_id, unlock_account_key_value)
488
- # end
453
+ create_reset_password_email { RodauthMailer.reset_password(account_id, reset_password_key_value) }
454
+ create_verify_account_email { RodauthMailer.verify_account(account_id, verify_account_key_value) }
455
+ create_verify_login_change_email { |_login| RodauthMailer.verify_login_change(account_id, verify_login_change_key_value) }
456
+ create_password_changed_email { RodauthMailer.password_changed(account_id) }
457
+ # create_email_auth_email { RodauthMailer.email_auth(account_id, email_auth_key_value) }
458
+ # create_unlock_account_email { RodauthMailer.unlock_account(account_id, unlock_account_key_value) }
489
459
  send_email do |email|
490
460
  # queue email delivery on the mailer after the transaction commits
491
461
  db.after_commit { email.deliver_later }
492
462
  end
493
- # ...
494
463
  end
495
464
  end
496
465
  ```
497
466
 
498
467
  This configuration calls `#deliver_later`, which uses Active Job to deliver
499
- emails in a background job. It's generally recommended to send emails
500
- asynchronously for better request throughput and the ability to retry
501
- deliveries. However, if you want to send emails synchronously, you can modify
502
- the configuration to call `#deliver_now` instead.
468
+ emails in a background job. If you want to send emails synchronously, you can
469
+ modify the configuration to call `#deliver_now` instead.
503
470
 
504
471
  If you're using a background processing library without an Active Job adapter,
505
472
  or a 3rd-party service for sending transactional emails, see [this wiki
506
473
  page][custom mailer worker] on how to set it up.
507
474
 
508
- ### Migrations
475
+ ## Migrations
509
476
 
510
477
  The install generator will create a migration for tables used by the Rodauth
511
478
  features enabled by default. For any additional features, you can use the
512
- migration generator for creating the required tables:
479
+ migration generator to create the required tables:
513
480
 
514
481
  ```sh
515
482
  $ rails generate rodauth:migration otp sms_codes recovery_codes
@@ -525,10 +492,10 @@ class CreateRodauthOtpSmsCodesRecoveryCodes < ActiveRecord::Migration
525
492
  end
526
493
  ```
527
494
 
528
- #### Table prefix
495
+ ### Table prefix
529
496
 
530
497
  If you're storing account records in a table other than `accounts`, you'll want
531
- to specify the correct table prefix when generating new migrations:
498
+ to specify the appropriate table prefix when generating new migrations:
532
499
 
533
500
  ```sh
534
501
  $ rails generate rodauth:migration base active_sessions --prefix user
@@ -549,7 +516,7 @@ class CreateRodauthUserBaseActiveSessions < ActiveRecord::Migration
549
516
  end
550
517
  ```
551
518
 
552
- #### Custom migration name
519
+ ### Custom migration name
553
520
 
554
521
  You can change the default migration name:
555
522
 
@@ -573,37 +540,23 @@ tables used by enabled authentication features.
573
540
 
574
541
  ```rb
575
542
  class Account < ActiveRecord::Base # Sequel::Model
576
- include Rodauth::Rails.model # or `Rodauth::Rails.model(:admin)`
543
+ include Rodauth::Rails.model # or Rodauth::Rails.model(:admin)
577
544
  end
578
545
  ```
579
-
580
- The password attribute can be used to set or clear the password hash. It
581
- handles both storing the password hash in a column on the accounts table, or in
582
- a separate table.
583
-
584
546
  ```rb
547
+ # setting password hash
585
548
  account = Account.create!(email: "user@example.com", password: "secret123")
586
-
587
- # when password hash is stored in a column on the accounts table
588
549
  account.password_hash #=> "$2a$12$k/Ub1I2iomi84RacqY89Hu4.M0vK7klRnRtzorDyvOkVI.hKhkNw."
589
550
 
590
- # when password hash is stored in a separate table
591
- account.password_hash #=> #<Account::PasswordHash...> (record from `account_password_hashes` table)
592
- account.password_hash.password_hash #=> "$2a$12$k/Ub1..." (inaccessible when using database authentication functions)
593
-
594
- account.password = nil # clears password hash
551
+ # clearing password hash
552
+ account.password = nil
595
553
  account.password_hash #=> nil
596
- ```
597
-
598
- The associations are defined for tables used by enabled authentication features:
599
554
 
600
- ```rb
555
+ # associations
601
556
  account.remember_key #=> #<Account::RememberKey> (record from `account_remember_keys` table)
602
557
  account.active_session_keys #=> [#<Account::ActiveSessionKey>,...] (records from `account_active_session_keys` table)
603
558
  ```
604
559
 
605
- See the [rodauth-model] documentation for more details.
606
-
607
560
  ## Multiple configurations
608
561
 
609
562
  If you need to handle multiple types of accounts that require different
@@ -649,43 +602,9 @@ Then in your application you can reference the secondary Rodauth instance:
649
602
  rodauth(:admin).login_path #=> "/admin/login"
650
603
  ```
651
604
 
652
- *NOTE: You'll likely want to save the information of which account belongs to which
653
- configuration to the database. See [this guide][account types] on how you can do
654
- that.*
655
-
656
- ### Sharing configuration
657
-
658
- If there are common settings that you want to share between Rodauth
659
- configurations, you can do so via inheritance:
660
-
661
- ```rb
662
- # app/misc/rodauth_base.rb
663
- class RodauthBase < Rodauth::Rails::Auth
664
- # common settings that are shared between multiple configurations
665
- configure do
666
- enable :login, :logout
667
- login_return_to_requested_location? true
668
- logout_redirect "/"
669
- # ...
670
- end
671
- end
672
- ```
673
- ```rb
674
- # app/misc/rodauth_main.rb
675
- class RodauthMain < RodauthBase # inherit common settings
676
- configure do
677
- # ... customize main ...
678
- end
679
- end
680
- ```
681
- ```rb
682
- # app/misc/rodauth_admin.rb
683
- class RodauthAdmin < RodauthBase # inherit common settings
684
- configure do
685
- # ... customize admin ...
686
- end
687
- end
688
- ```
605
+ You'll likely want to save the information of which account belongs to which
606
+ configuration to the database, see [this guide][account types] on how you can do
607
+ that. Note that you can also [share configuration via inheritance][inheritance].
689
608
 
690
609
  ## Outside of a request
691
610
 
@@ -772,6 +691,34 @@ Rodauth::Rails.rodauth(session: { two_factor_auth_setup: true })
772
691
  Rodauth::Rails.rodauth(:admin, params: { "param" => "value" })
773
692
  ```
774
693
 
694
+ ### Using as a library
695
+
696
+ Rodauth offers a `Rodauth.lib` method for configuring Rodauth so that it can be used as a library, instead of routing requests (see [internal_request] feature). This gem provides a `Rodauth::Rails.lib` counterpart that does the same but with Rails integration:
697
+
698
+ ```rb
699
+ # app/misc/rodauth_main.rb
700
+ require "rodauth/rails"
701
+ require "sequel/core"
702
+
703
+ RodauthMain = Rodauth::Rails.lib do
704
+ enable :create_account, :login, :close_account
705
+ db Sequel.postgres(extensions: :activerecord_connection, keep_reference: false)
706
+ # ...
707
+ end
708
+ ```
709
+ ```rb
710
+ RodauthMain.create_account(login: "email@example.com", password: "secret123")
711
+ RodauthMain.login(login: "email@example.com", password: "secret123")
712
+ RodauthMain.close_account(account_login: "email@example.com")
713
+ ```
714
+
715
+ Note that you'll want to skip requiring `rodauth-rails` on Rails boot, so that it doesn't insert the middleware automatically, and remove the initializer.
716
+
717
+ ```rb
718
+ # Gemfile
719
+ gem "rodauth-rails", require: false
720
+ ```
721
+
775
722
  ## Testing
776
723
 
777
724
  For system and integration tests, which run the whole middleware stack,
@@ -791,13 +738,13 @@ end
791
738
  ```
792
739
 
793
740
  One can write `ActionDispatch::IntegrationTest` test helpers for `login` and
794
- `logout` by making requests to the rodauth endpoints
741
+ `logout` by making requests to the Rodauth endpoints:
795
742
 
796
743
  ```rb
797
744
  # test/controllers/articles_controller_test.rb
798
745
  class ArticlesControllerTest < ActionDispatch::IntegrationTest
799
- def login(login, password)
800
- post "/login", params: { login: login, password: password }
746
+ def login(email, password)
747
+ post "/login", params: { email: email, password: password }
801
748
  assert_redirected_to "/"
802
749
  end
803
750
 
@@ -849,87 +796,48 @@ methods:
849
796
  | `rails_controller` | Controller class to use for rendering and CSRF protection. |
850
797
  | `rails_account_model` | Model class connected with the accounts table. |
851
798
 
799
+ ```rb
800
+ class RodauthMain < Rodauth::Rails::Auth
801
+ configure do
802
+ rails_controller { Authentication::RodauthController }
803
+ rails_account_model { Authentication::Account }
804
+ end
805
+ end
806
+ ```
807
+
852
808
  For the list of configuration methods provided by Rodauth, see the [feature
853
809
  documentation].
854
810
 
855
811
  ### Defining custom methods
856
812
 
857
813
  All Rodauth configuration methods are just syntax sugar for defining instance
858
- methods on the auth class. You can also define your own custom methods on the
859
- auth class:
814
+ methods on the auth class. You can also define your own custom methods:
860
815
 
861
816
  ```rb
862
817
  class RodauthMain < Rodauth::Rails::Auth
863
818
  configure do
864
- # ...
865
819
  password_match? { |password| ldap_valid?(password) }
866
- # ...
867
820
  end
868
821
 
869
- # Example external identities table
870
- def identities
871
- db[:account_identities].where(account_id: account_id).all
822
+ def admin?
823
+ rails_account.admin?
872
824
  end
873
825
 
874
826
  private
875
827
 
876
- # Example LDAP authentication
877
828
  def ldap_valid?(password)
878
829
  SimpleLdapAuthenticator.valid?(account[:email], password)
879
830
  end
880
831
  end
881
832
  ```
882
833
  ```rb
883
- rodauth.identities #=> [{ provider: "facebook", uid: "abc123", ... }, ...]
884
- ```
885
-
886
- ### Rails URL helpers
887
-
888
- Inside Rodauth configuration and the `route` block you can access Rails route
889
- helpers through `#rails_routes`:
890
-
891
- ```rb
892
- # app/misc/rodauth_main.rb
893
- class RodauthMain < Rodauth::Rails::Auth
894
- configure do
895
- login_redirect { rails_routes.activity_path }
896
- change_password_redirect { rails_routes.profile_path }
897
- change_login_redirect { rails_routes.profile_path }
898
- end
899
- end
900
- ```
901
-
902
- ### Calling controller methods
903
-
904
- When using Rodauth before/after hooks or generally overriding your Rodauth
905
- configuration, in some cases you might want to call methods defined on your
906
- controllers. You can do so with `rails_controller_eval`, for example:
907
-
908
- ```rb
909
- # app/controllers/application_controller.rb
910
- class ApplicationController < ActionController::Base
911
- private
912
- def setup_tracking(account_id)
913
- # ... some implementation ...
914
- end
915
- end
916
- ```
917
- ```rb
918
- # app/misc/rodauth_main.rb
919
- class RodauthMain < Rodauth::Rails::Auth
920
- configure do
921
- after_create_account do
922
- rails_controller_eval { setup_tracking(account_id) }
923
- end
924
- end
925
- end
834
+ rodauth.admin? #=> true
926
835
  ```
927
836
 
928
837
  ### Single-file configuration
929
838
 
930
- If you would prefer to have all Rodauth logic contained inside a single file,
931
- you call `Rodauth::Rails::App.configure` with a block, which will create an
932
- anonymous auth class.
839
+ If you would prefer, you can have all your Rodauth logic contained inside the
840
+ Rodauth app class:
933
841
 
934
842
  ```rb
935
843
  # app/misc/rodauth_app.rb
@@ -952,6 +860,19 @@ class RodauthApp < Rodauth::Rails::App
952
860
  end
953
861
  ```
954
862
 
863
+ ### Manually inserting middleware
864
+
865
+ You can choose to insert the Rodauth middleware somewhere earlier than
866
+ in front of the Rails router:
867
+
868
+ ```rb
869
+ Rodauth::Rails.configure do |config|
870
+ config.middleware = false # disable auto-insertion
871
+ end
872
+
873
+ Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
874
+ ```
875
+
955
876
  ## How it works
956
877
 
957
878
  ### Rack middleware
@@ -966,16 +887,6 @@ $ rails middleware
966
887
  # run MyApp::Application.routes
967
888
  ```
968
889
 
969
- It can be inserted at any point in the middleware stack:
970
-
971
- ```rb
972
- Rodauth::Rails.configure do |config|
973
- config.middleware = false # disable auto-insertion
974
- end
975
-
976
- Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
977
- ```
978
-
979
890
  The middleware retrieves the Rodauth app via `Rodauth::Rails.app`, which is
980
891
  specified as a string to keep the class autoloadable and reloadable in
981
892
  development.
@@ -1227,12 +1138,12 @@ conduct](CODE_OF_CONDUCT.md).
1227
1138
  [sms_codes]: http://rodauth.jeremyevans.net/rdoc/files/doc/sms_codes_rdoc.html
1228
1139
  [recovery_codes]: http://rodauth.jeremyevans.net/rdoc/files/doc/recovery_codes_rdoc.html
1229
1140
  [webauthn]: http://rodauth.jeremyevans.net/rdoc/files/doc/webauthn_rdoc.html
1141
+ [webauthn_login]: http://rodauth.jeremyevans.net/rdoc/files/doc/webauthn_login_rdoc.html
1230
1142
  [json]: http://rodauth.jeremyevans.net/rdoc/files/doc/json_rdoc.html
1231
1143
  [jwt]: http://rodauth.jeremyevans.net/rdoc/files/doc/jwt_rdoc.html
1232
1144
  [email_auth]: http://rodauth.jeremyevans.net/rdoc/files/doc/email_auth_rdoc.html
1233
1145
  [audit_logging]: http://rodauth.jeremyevans.net/rdoc/files/doc/audit_logging_rdoc.html
1234
1146
  [password protection]: https://github.com/jeremyevans/rodauth#label-Password+Hash+Access+Via+Database+Functions
1235
- [bruteforce tokens]: https://github.com/jeremyevans/rodauth#label-Tokens
1236
1147
  [password_complexity]: http://rodauth.jeremyevans.net/rdoc/files/doc/password_complexity_rdoc.html
1237
1148
  [disallow_password_reuse]: http://rodauth.jeremyevans.net/rdoc/files/doc/disallow_password_reuse_rdoc.html
1238
1149
  [password_expiration]: http://rodauth.jeremyevans.net/rdoc/files/doc/password_expiration_rdoc.html
@@ -1247,3 +1158,4 @@ conduct](CODE_OF_CONDUCT.md).
1247
1158
  [Turbo]: https://turbo.hotwired.dev/
1248
1159
  [rodauth-model]: https://github.com/janko/rodauth-model
1249
1160
  [JSON API]: https://github.com/janko/rodauth-rails/wiki/JSON-API
1161
+ [inheritance]: http://rodauth.jeremyevans.net/rdoc/files/doc/guides/share_configuration_rdoc.html