rodauth-rails 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +39 -134
  4. data/lib/generators/rodauth/templates/INSTRUCTIONS +11 -1
  5. data/lib/generators/rodauth/templates/app/mailers/rodauth_mailer.rb +38 -52
  6. data/lib/generators/rodauth/templates/app/misc/rodauth_main.rb +9 -6
  7. data/lib/generators/rodauth/templates/app/models/account.rb +1 -0
  8. data/lib/generators/rodauth/templates/app/views/rodauth/add_recovery_codes.html.erb +0 -2
  9. data/lib/generators/rodauth/templates/app/views/rodauth/change_login.html.erb +0 -2
  10. data/lib/generators/rodauth/templates/app/views/rodauth/change_password.html.erb +0 -2
  11. data/lib/generators/rodauth/templates/app/views/rodauth/close_account.html.erb +0 -2
  12. data/lib/generators/rodauth/templates/app/views/rodauth/confirm_password.html.erb +0 -2
  13. data/lib/generators/rodauth/templates/app/views/rodauth/create_account.html.erb +0 -2
  14. data/lib/generators/rodauth/templates/app/views/rodauth/email_auth.html.erb +0 -2
  15. data/lib/generators/rodauth/templates/app/views/rodauth/login.html.erb +0 -2
  16. data/lib/generators/rodauth/templates/app/views/rodauth/logout.html.erb +0 -2
  17. data/lib/generators/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +0 -2
  18. data/lib/generators/rodauth/templates/app/views/rodauth/otp_auth.html.erb +0 -2
  19. data/lib/generators/rodauth/templates/app/views/rodauth/otp_disable.html.erb +0 -2
  20. data/lib/generators/rodauth/templates/app/views/rodauth/otp_setup.html.erb +0 -2
  21. data/lib/generators/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +0 -2
  22. data/lib/generators/rodauth/templates/app/views/rodauth/recovery_codes.html.erb +0 -2
  23. data/lib/generators/rodauth/templates/app/views/rodauth/remember.html.erb +0 -2
  24. data/lib/generators/rodauth/templates/app/views/rodauth/reset_password.html.erb +0 -2
  25. data/lib/generators/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +0 -2
  26. data/lib/generators/rodauth/templates/app/views/rodauth/sms_auth.html.erb +0 -2
  27. data/lib/generators/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +0 -2
  28. data/lib/generators/rodauth/templates/app/views/rodauth/sms_disable.html.erb +0 -2
  29. data/lib/generators/rodauth/templates/app/views/rodauth/sms_request.html.erb +0 -2
  30. data/lib/generators/rodauth/templates/app/views/rodauth/sms_setup.html.erb +0 -2
  31. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_auth.html.erb +0 -2
  32. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +0 -2
  33. data/lib/generators/rodauth/templates/app/views/rodauth/two_factor_manage.html.erb +0 -2
  34. data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account.html.erb +0 -2
  35. data/lib/generators/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +0 -2
  36. data/lib/generators/rodauth/templates/app/views/rodauth/verify_account.html.erb +0 -2
  37. data/lib/generators/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +0 -2
  38. data/lib/generators/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +0 -2
  39. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +0 -2
  40. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +0 -2
  41. data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +0 -2
  42. data/lib/generators/rodauth/templates/app/views/rodauth_mailer/verify_login_change.text.erb +2 -2
  43. data/lib/rodauth/rails/feature/render.rb +8 -1
  44. data/lib/rodauth/rails/feature.rb +0 -2
  45. data/lib/rodauth/rails/model.rb +2 -97
  46. data/lib/rodauth/rails/version.rb +1 -1
  47. data/lib/rodauth/rails.rb +3 -2
  48. data/rodauth-rails.gemspec +1 -0
  49. metadata +16 -3
  50. data/lib/rodauth/rails/feature/associations.rb +0 -54
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b5fb22e3d8c84eafedffa3463b4e0ecdf481189b8b48adc2d31005f86251d87
4
- data.tar.gz: 142e229b7c9a9b078f773f99885117268e759df2eb49e5252ce21754dcf61763
3
+ metadata.gz: 43e0f2c048024645cb8af7e744042187ded20eeca3f685bdf28a959aebf296e0
4
+ data.tar.gz: 96d02ad057f315a339bc1cda804f71e19cd629a9cb2ca5c574c515d954692673
5
5
  SHA512:
6
- metadata.gz: b1c30c5b1714a80466ad3775720be50d2f02b8d06d016638e6d1ebfb7515cd6060463b975f9810977fe74eb7330ce12b9c6ff81839e41b2e4044615c606ca7bb
7
- data.tar.gz: 4a532058b27cfc07d2ed234457b880a609c7b35186db976a547be2e83d1c18df7ac72402a9d52155819f2d97edb63b0e7742e908b6cb3ed1b40c2deae18e7e2e
6
+ metadata.gz: c943289cb0c628b37d89fcc6e2a0b22b190ba0e0c0351ffc53c726ac81b0c9f87b0b6e1f929a823724fa1aed70c5b5601279b24df5b54026cb06bb073c3b284c
7
+ data.tar.gz: afb5b6523b6c440c9b02255b047cf562dd0122a6abb8d49f7c93671981c75935d6a1a9ab1c27a9e8158578a928b70b3705db24760db803acd79abafa58cdc4ce
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 1.5.0 (2022-06-11)
2
+
3
+ * Remove `content_for` calls from generated view templates (@janko)
4
+
5
+ * Set title instance variable to `@page_title` in generated configuration (@janko)
6
+
7
+ * Set title instance variable on the controller when `title_instance_variable` is set (@HoneyryderChuck)
8
+
9
+ ## 1.4.2 (2022-05-15)
10
+
11
+ * Stop passing email addresses in mailer arguments on verifying login change (@janko)
12
+
13
+ * Extract finding account into a method in the generated mailer (@janko)
14
+
15
+ * Make generated Action Mailer integration work with secondary Rodauth configurations (@janko)
16
+
17
+ * Include `Rodauth::Rails.model` in generated Sequel account model as well (@janko)
18
+
19
+ ## 1.4.1 (2022-05-08)
20
+
21
+ * Deprecate `Rodauth::Rails::Model` constant (@janko)
22
+
23
+ * Remove `Rodauth::Rails::Auth#associations` in favour of new association registration API (@janko)
24
+
25
+ * Extract model mixin into the rodauth-model gem (@janko)
26
+
1
27
  ## 1.4.0 (2022-05-04)
2
28
 
3
29
  * Move association definitions to `#associations` Rodauth method, allowing external features to extend them (@janko)
data/README.md CHANGED
@@ -321,16 +321,26 @@ $ rails generate rodauth:views webauthn --name admin
321
321
 
322
322
  #### Page titles
323
323
 
324
- The generated view templates use `content_for(:title)` to store Rodauth's page
325
- titles, which you can then retrieve in your layout template to set the page
326
- title:
324
+ The generated configuration sets `title_instance_variable` to make page titles
325
+ available in your views via `@page_title` instance variable, which you can then
326
+ use in your layout:
327
327
 
328
+ ```rb
329
+ # app/misc/rodauth_main.rb
330
+ class RodauthMain < Rodauth::Rails::Auth
331
+ configure do
332
+ # ...
333
+ title_instance_variable :@page_title
334
+ # ...
335
+ end
336
+ end
337
+ ```
328
338
  ```erb
329
339
  <!-- app/views/layouts/application.html.erb -->
330
340
  <!DOCTYPE html>
331
341
  <html>
332
342
  <head>
333
- <title><%= content_for(:title) %></title>
343
+ <title><%= @page_title || "Default title" %></title>
334
344
  <!-- ... -->
335
345
  </head>
336
346
  <body>
@@ -339,6 +349,21 @@ title:
339
349
  </html>
340
350
  ```
341
351
 
352
+ If you're already setting page titles via `content_for`, you can use it in
353
+ generated Rodauth views, giving it the result of the corresponding
354
+ `*_page_title` method:
355
+
356
+ ```erb
357
+ <!-- app/views/rodauth/login.html.erb -->
358
+ <%= content_for :page_title, rodauth.login_page_title %>
359
+ <!-- ... -->
360
+ ```
361
+ ```erb
362
+ <!-- app/views/rodauth/change_password.html.erb -->
363
+ <%= content_for :page_title, rodauth.change_password_page_title %>
364
+ <!-- ... -->
365
+ ```
366
+
342
367
  #### Layout
343
368
 
344
369
  To use different layouts for different Rodauth views, you can compare the
@@ -484,21 +509,19 @@ end
484
509
 
485
510
  ## Model
486
511
 
487
- The `Rodauth::Rails::Model` mixin can be included into the account model, which
488
- defines a password attribute and associations for tables used by enabled
489
- authentication features.
512
+ The [rodauth-model] gem provides a `Rodauth::Model` mixin that can be included
513
+ into the account model, which defines a password attribute and associations for
514
+ tables used by enabled authentication features.
490
515
 
491
516
  ```rb
492
- class Account < ApplicationRecord
517
+ class Account < ActiveRecord::Base # Sequel::Model
493
518
  include Rodauth::Rails.model # or `Rodauth::Rails.model(:admin)`
494
519
  end
495
520
  ```
496
521
 
497
- ### Password attribute
498
-
499
- Regardless of whether you're storing the password hash in a column in the
500
- accounts table, or in a separate table, the `#password` attribute can be used
501
- to set or clear the password hash.
522
+ The password attribute can be used to set or clear the password hash. It
523
+ handles both storing the password hash in a column on the accounts table, or in
524
+ a separate table.
502
525
 
503
526
  ```rb
504
527
  account = Account.create!(email: "user@example.com", password: "secret")
@@ -514,132 +537,14 @@ account.password = nil # clears password hash
514
537
  account.password_hash #=> nil
515
538
  ```
516
539
 
517
- Note that the password attribute doesn't come with validations, making it
518
- unsuitable for forms. It was primarily intended to allow easily creating
519
- accounts in development console and in tests.
520
-
521
- ### Associations
522
-
523
- The `Rodauth::Rails::Model` mixin defines associations for Rodauth tables
524
- associated to the accounts table:
540
+ The associations are defined for tables used by enabled authentication features:
525
541
 
526
542
  ```rb
527
543
  account.remember_key #=> #<Account::RememberKey> (record from `account_remember_keys` table)
528
544
  account.active_session_keys #=> [#<Account::ActiveSessionKey>,...] (records from `account_active_session_keys` table)
529
545
  ```
530
546
 
531
- You can also reference the associated models directly:
532
-
533
- ```rb
534
- # model referencing the `account_authentication_audit_logs` table
535
- Account::AuthenticationAuditLog.where(message: "login").group(:account_id)
536
- ```
537
-
538
- The associated models define the inverse `belongs_to :account` association:
539
-
540
- ```rb
541
- Account::ActiveSessionKey.includes(:account).map(&:account)
542
- ```
543
-
544
- Here is an example of using associations to create a method that returns
545
- whether the account has multifactor authentication enabled:
546
-
547
- ```rb
548
- class Account < ApplicationRecord
549
- include Rodauth::Rails.model
550
-
551
- def mfa_enabled?
552
- otp_key || (sms_code && sms_code.num_failures.nil?) || recovery_codes.any?
553
- end
554
- end
555
- ```
556
-
557
- Here is another example of creating a query scope that selects accounts with
558
- multifactor authentication enabled:
559
-
560
- ```rb
561
- class Account < ApplicationRecord
562
- include Rodauth::Rails.model
563
-
564
- scope :otp_setup, -> { where(otp_key: OtpKey.all) }
565
- scope :sms_codes_setup, -> { where(sms_code: SmsCode.where(num_failures: nil)) }
566
- scope :recovery_codes_setup, -> { where(recovery_codes: RecoveryCode.all) }
567
- scope :mfa_enabled, -> { merge(otp_setup.or(sms_codes_setup).or(recovery_codes_setup)) }
568
- end
569
- ```
570
-
571
- #### Association reference
572
-
573
- Below is a list of all associations defined depending on the features loaded:
574
-
575
- | Feature | Association | Type | Model | Table (default) |
576
- | :------ | :---------- | :--- | :---- | :---- |
577
- | account_expiration | `:activity_time` | `has_one` | `ActivityTime` | `account_activity_times` |
578
- | active_sessions | `:active_session_keys` | `has_many` | `ActiveSessionKey` | `account_active_session_keys` |
579
- | audit_logging | `:authentication_audit_logs` | `has_many` | `AuthenticationAuditLog` | `account_authentication_audit_logs` |
580
- | disallow_password_reuse | `:previous_password_hashes` | `has_many` | `PreviousPasswordHash` | `account_previous_password_hashes` |
581
- | email_auth | `:email_auth_key` | `has_one` | `EmailAuthKey` | `account_email_auth_keys` |
582
- | jwt_refresh | `:jwt_refresh_keys` | `has_many` | `JwtRefreshKey` | `account_jwt_refresh_keys` |
583
- | lockout | `:lockout` | `has_one` | `Lockout` | `account_lockouts` |
584
- | lockout | `:login_failure` | `has_one` | `LoginFailure` | `account_login_failures` |
585
- | otp | `:otp_key` | `has_one` | `OtpKey` | `account_otp_keys` |
586
- | password_expiration | `:password_change_time` | `has_one` | `PasswordChangeTime` | `account_password_change_times` |
587
- | recovery_codes | `:recovery_codes` | `has_many` | `RecoveryCode` | `account_recovery_codes` |
588
- | remember | `:remember_key` | `has_one` | `RememberKey` | `account_remember_keys` |
589
- | reset_password | `:password_reset_key` | `has_one` | `PasswordResetKey` | `account_password_reset_keys` |
590
- | single_session | `:session_key` | `has_one` | `SessionKey` | `account_session_keys` |
591
- | sms_codes | `:sms_code` | `has_one` | `SmsCode` | `account_sms_codes` |
592
- | verify_account | `:verification_key` | `has_one` | `VerificationKey` | `account_verification_keys` |
593
- | verify_login_change | `:login_change_key` | `has_one` | `LoginChangeKey` | `account_login_change_keys` |
594
- | webauthn | `:webauthn_keys` | `has_many` | `WebauthnKey` | `account_webauthn_keys` |
595
- | webauthn | `:webauthn_user_id` | `has_one` | `WebauthnUserId` | `account_webauthn_user_ids` |
596
-
597
- Note that some Rodauth tables use composite primary keys, which Active Record
598
- doesn't support out of the box. For associations to work properly, you might
599
- need to add the [composite_primary_keys] gem to your Gemfile.
600
-
601
- #### Association options
602
-
603
- By default, all associations except for audit logs have `dependent: :destroy`
604
- set, to allow for easy deletion of account records in the console. You can use
605
- `:association_options` to modify global or per-association options:
606
-
607
- ```rb
608
- # don't auto-delete associations when account model is deleted
609
- Rodauth::Rails.model(association_options: { dependent: nil })
610
-
611
- # require authentication audit logs to be eager loaded before retrieval
612
- Rodauth::Rails.model(association_options: -> (name) {
613
- { strict_loading: true } if name == :authentication_audit_logs
614
- })
615
- ```
616
-
617
- #### Extending Associations
618
-
619
- External features can extend the list of associations with their own
620
- definitions, which the model mixin will pick up and declare the new associations
621
- on the model.
622
-
623
- ```rb
624
- # lib/rodauth/features/foo.rb
625
- module Rodauth
626
- Feature.define(:foo, :Foo) do
627
- auth_value_method :foo_table, :account_foos
628
- auth_value_method :foo_id_column, :id
629
-
630
- def associations
631
- list = super
632
- list << {
633
- name: :foo, # will define `Account::Foo` model
634
- type: :one, # or :many
635
- table: foo_table,
636
- foreign_key: foo_id_column
637
- }
638
- list
639
- end
640
- end
641
- end
642
- ```
547
+ See the [rodauth-model] documentation for more details.
643
548
 
644
549
  ## Multiple configurations
645
550
 
@@ -1304,8 +1209,8 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
1304
1209
  [account_expiration]: http://rodauth.jeremyevans.net/rdoc/files/doc/account_expiration_rdoc.html
1305
1210
  [simple_ldap_authenticator]: https://github.com/jeremyevans/simple_ldap_authenticator
1306
1211
  [internal_request]: http://rodauth.jeremyevans.net/rdoc/files/doc/internal_request_rdoc.html
1307
- [composite_primary_keys]: https://github.com/composite-primary-keys/composite_primary_keys
1308
1212
  [path_class_methods]: https://rodauth.jeremyevans.net/rdoc/files/doc/path_class_methods_rdoc.html
1309
1213
  [account types]: https://github.com/janko/rodauth-rails/wiki/Account-Types
1310
1214
  [custom mailer worker]: https://github.com/janko/rodauth-rails/wiki/Custom-Mailer-Worker
1311
1215
  [Turbo]: https://turbo.hotwired.dev/
1216
+ [rodauth-model]: https://github.com/janko/rodauth-model
@@ -31,7 +31,17 @@ Depending on your application's configuration some manual setup may be required:
31
31
 
32
32
  * Not required for API-only Applications *
33
33
 
34
- 4. You can copy Rodauth views (for customization) to your app by running:
34
+ 4. Titles for Rodauth pages are available via @page_title instance variable
35
+ by default, you can use it in your layout file:
36
+
37
+ <head>
38
+ <title><%= @page_title || "Default title" %></title>
39
+ ...
40
+ </head>
41
+
42
+ * Not required *
43
+
44
+ 5. You can copy Rodauth views (for customization) to your app by running:
35
45
 
36
46
  rails g rodauth:views
37
47
 
@@ -1,78 +1,64 @@
1
1
  class RodauthMailer < ApplicationMailer
2
- def verify_account(account_id, key)
3
- @email_link = rodauth.verify_account_url(key: email_token(account_id, key))
4
- <% if defined?(ActiveRecord::Railtie) -%>
5
- @account = Account.find(account_id)
6
- <% else -%>
7
- @account = Account.with_pk!(account_id)
8
- <% end -%>
2
+ def verify_account(name = nil, account_id, key)
3
+ @email_link = email_link(name, :verify_account, account_id, key)
4
+ @account = find_account(name, account_id)
9
5
 
10
- mail to: @account.email, subject: rodauth.verify_account_email_subject
6
+ mail to: @account.email, subject: rodauth(name).verify_account_email_subject
11
7
  end
12
8
 
13
- def reset_password(account_id, key)
14
- @email_link = rodauth.reset_password_url(key: email_token(account_id, key))
15
- <% if defined?(ActiveRecord::Railtie) -%>
16
- @account = Account.find(account_id)
17
- <% else -%>
18
- @account = Account.with_pk!(account_id)
19
- <% end -%>
9
+ def reset_password(name = nil, account_id, key)
10
+ @email_link = email_link(name, :reset_password, account_id, key)
11
+ @account = find_account(name, account_id)
20
12
 
21
- mail to: @account.email, subject: rodauth.reset_password_email_subject
13
+ mail to: @account.email, subject: rodauth(name).reset_password_email_subject
22
14
  end
23
15
 
24
- def verify_login_change(account_id, old_login, new_login, key)
25
- @old_login = old_login
26
- @new_login = new_login
27
- @email_link = rodauth.verify_login_change_url(key: email_token(account_id, key))
28
- <% if defined?(ActiveRecord::Railtie) -%>
29
- @account = Account.find(account_id)
30
- <% else -%>
31
- @account = Account.with_pk!(account_id)
32
- <% end -%>
16
+ def verify_login_change(name = nil, account_id, key)
17
+ @email_link = email_link(name, :verify_login_change, account_id, key)
18
+ @account = find_account(name, account_id)
19
+ @new_email = @account.login_change_key.login
33
20
 
34
- mail to: new_login, subject: rodauth.verify_login_change_email_subject
21
+ mail to: @new_email, subject: rodauth(name).verify_login_change_email_subject
35
22
  end
36
23
 
37
- def password_changed(account_id)
38
- <% if defined?(ActiveRecord::Railtie) -%>
39
- @account = Account.find(account_id)
40
- <% else -%>
41
- @account = Account.with_pk!(account_id)
42
- <% end -%>
24
+ def password_changed(name = nil, account_id)
25
+ @account = find_account(name, account_id)
43
26
 
44
- mail to: @account.email, subject: rodauth.password_changed_email_subject
27
+ mail to: @account.email, subject: rodauth(name).password_changed_email_subject
45
28
  end
46
29
 
47
- # def email_auth(account_id, key)
48
- # @email_link = rodauth.email_auth_url(key: email_token(account_id, key))
49
- <% if defined?(ActiveRecord::Railtie) -%>
50
- # @account = Account.find(account_id)
51
- <% else -%>
52
- # @account = Account.with_pk!(account_id)
53
- <% end -%>
30
+ # def email_auth(name = nil, account_id, key)
31
+ # @email_link = email_link(name, :email_auth, account_id, key)
32
+ # @account = find_account(name, account_id)
54
33
 
55
- # mail to: @account.email, subject: rodauth.email_auth_email_subject
34
+ # mail to: @account.email, subject: rodauth(name).email_auth_email_subject
56
35
  # end
57
36
 
58
- # def unlock_account(account_id, key)
59
- # @email_link = rodauth.unlock_account_url(key: email_token(account_id, key))
60
- <% if defined?(ActiveRecord::Railtie) -%>
61
- # @account = Account.find(account_id)
62
- <% else -%>
63
- # @account = Account.with_pk!(account_id)
64
- <% end -%>
37
+ # def unlock_account(name = nil, account_id, key)
38
+ # @email_link = email_link(name, :unlock_account, account_id, key)
39
+ # @account = find_account(name, account_id)
65
40
 
66
- # mail to: @account.email, subject: rodauth.unlock_account_email_subject
41
+ # mail to: @account.email, subject: rodauth(name).unlock_account_email_subject
67
42
  # end
68
43
 
69
44
  private
70
45
 
71
- def email_token(account_id, key)
72
- "#{account_id}_#{rodauth.compute_hmac(key)}"
46
+ def find_account(_name, account_id)
47
+ <% if defined?(ActiveRecord::Railtie) -%>
48
+ Account.find(account_id)
49
+ <% else -%>
50
+ Account.with_pk!(account_id)
51
+ <% end -%>
52
+ end
53
+
54
+ def email_link(name, action, account_id, key)
55
+ instance = rodauth(name)
56
+ instance.instance_variable_set(:@account, { id: account_id })
57
+ instance.instance_variable_set(:"@#{action}_key_value", key)
58
+ instance.public_send(:"#{action}_email_link")
73
59
  end
74
60
 
75
- def rodauth(name = nil)
61
+ def rodauth(name)
76
62
  RodauthApp.rodauth(name).allocate
77
63
  end
78
64
  end
@@ -31,6 +31,9 @@ class RodauthMain < Rodauth::Rails::Auth
31
31
  # Specify the controller used for view rendering and CSRF verification.
32
32
  rails_controller { RodauthController }
33
33
 
34
+ # Set on Rodauth controller with the title of the current page.
35
+ title_instance_variable :@page_title
36
+
34
37
  # Store account status in an integer column without foreign key constraint.
35
38
  account_status_column :status
36
39
 
@@ -56,22 +59,22 @@ class RodauthMain < Rodauth::Rails::Auth
56
59
  # ==> Emails
57
60
  # Use a custom mailer for delivering authentication emails.
58
61
  create_reset_password_email do
59
- RodauthMailer.reset_password(account_id, reset_password_key_value)
62
+ RodauthMailer.reset_password(*self.class.configuration_name, account_id, reset_password_key_value)
60
63
  end
61
64
  create_verify_account_email do
62
- RodauthMailer.verify_account(account_id, verify_account_key_value)
65
+ RodauthMailer.verify_account(*self.class.configuration_name, account_id, verify_account_key_value)
63
66
  end
64
67
  create_verify_login_change_email do |_login|
65
- RodauthMailer.verify_login_change(account_id, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_key_value)
68
+ RodauthMailer.verify_login_change(*self.class.configuration_name, account_id, verify_login_change_key_value)
66
69
  end
67
70
  create_password_changed_email do
68
- RodauthMailer.password_changed(account_id)
71
+ RodauthMailer.password_changed(*self.class.configuration_name, account_id)
69
72
  end
70
73
  # create_email_auth_email do
71
- # RodauthMailer.email_auth(account_id, email_auth_key_value)
74
+ # RodauthMailer.email_auth(*self.class.configuration_name, account_id, email_auth_key_value)
72
75
  # end
73
76
  # create_unlock_account_email do
74
- # RodauthMailer.unlock_account(account_id, unlock_account_key_value)
77
+ # RodauthMailer.unlock_account(*self.class.configuration_name, account_id, unlock_account_key_value)
75
78
  # end
76
79
  send_email do |email|
77
80
  # queue email delivery on the mailer after the transaction commits
@@ -9,6 +9,7 @@ class Account < ApplicationRecord
9
9
  end
10
10
  <% else -%>
11
11
  class Account < Sequel::Model
12
+ include Rodauth::Rails.model
12
13
  plugin :enum
13
14
  enum :status, unverified: 1, verified: 2, closed: 3
14
15
  end
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.add_recovery_codes_page_title %>
2
-
3
1
  <pre id="recovery-codes"><%= rodauth.recovery_codes.map { |s| h(s) }.join("\n\n") %></pre>
4
2
 
5
3
  <% if rodauth.can_add_recovery_codes? %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.change_login_page_title %>
2
-
3
1
  <%= form_with url: rodauth.change_login_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "login", rodauth.login_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.change_password_page_title %>
2
-
3
1
  <%= form_with url: rodauth.change_password_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.change_password_requires_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.close_account_page_title %>
2
-
3
1
  <%= form_with url: rodauth.close_account_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.close_account_requires_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.confirm_password_page_title %>
2
-
3
1
  <%= form_with url: rodauth.confirm_password_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "password", rodauth.password_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.create_account_page_title %>
2
-
3
1
  <%= form_with url: rodauth.create_account_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "login", rodauth.login_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.email_auth_page_title %>
2
-
3
1
  <%= form_with url: rodauth.email_auth_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.submit rodauth.login_button, class: "btn btn-primary" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.login_page_title %>
2
-
3
1
  <%= render "login_form_header" %>
4
2
  <%= render "login_form" %>
5
3
  <%= render "login_form_footer" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.logout_page_title %>
2
-
3
1
  <%= form_with url: rodauth.logout_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.features.include?(:active_sessions) %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.multi_phase_login_page_title %>
2
-
3
1
  <%= render "login_form_header" %>
4
2
  <%== rodauth.render_multi_phase_login_forms %>
5
3
  <%= render "login_form_footer" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.otp_auth_page_title %>
2
-
3
1
  <%= form_with url: rodauth.otp_auth_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.otp_disable_page_title %>
2
-
3
1
  <%= form_with url: rodauth.otp_disable_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.two_factor_modifications_require_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.otp_setup_page_title %>
2
-
3
1
  <%= form_with url: rodauth.otp_setup_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <%= form.hidden_field rodauth.otp_setup_param, value: rodauth.otp_user_key, id: "otp-key" %>
5
3
  <%= form.hidden_field rodauth.otp_setup_raw_param, value: rodauth.otp_key, id: "otp-hmac-secret" if rodauth.otp_keys_use_hmac? %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.recovery_auth_page_title %>
2
-
3
1
  <%= form_with url: rodauth.recovery_auth_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "recovery-code", rodauth.recovery_codes_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.recovery_codes_page_title %>
2
-
3
1
  <%= form_with url: rodauth.recovery_codes_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.two_factor_modifications_require_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.remember_page_title %>
2
-
3
1
  <%= form_with url: rodauth.remember_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <fieldset class="form-group mb-3">
5
3
  <div class="form-check">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.reset_password_page_title %>
2
-
3
1
  <%= form_with url: rodauth.reset_password_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "password", rodauth.password_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.reset_password_request_page_title %>
2
-
3
1
  <%= form_with url: rodauth.reset_password_request_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <%== rodauth.reset_password_explanatory_text %>
5
3
 
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.sms_auth_page_title %>
2
-
3
1
  <%= form_with url: rodauth.sms_auth_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "sms-code", rodauth.sms_code_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.sms_confirm_page_title %>
2
-
3
1
  <%= form_with url: rodauth.sms_confirm_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.label "sms-code", rodauth.sms_code_label, class: "form-label" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.sms_disable_page_title %>
2
-
3
1
  <%= form_with url: rodauth.sms_disable_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.two_factor_modifications_require_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.sms_request_page_title %>
2
-
3
1
  <%= form_with url: rodauth.sms_request_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.submit rodauth.sms_request_button, class: "btn btn-primary" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.sms_setup_page_title %>
2
-
3
1
  <%= form_with url: rodauth.sms_setup_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.two_factor_modifications_require_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.two_factor_auth_page_title %>
2
-
3
1
  <ul>
4
2
  <% rodauth.two_factor_auth_links.sort.each do |_, link, text| %>
5
3
  <li><%= link_to text, link %></li>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.two_factor_disable_page_title %>
2
-
3
1
  <%= form_with url: rodauth.two_factor_disable_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.two_factor_modifications_require_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.two_factor_manage_page_title %>
2
-
3
1
  <% if rodauth.two_factor_setup_links.any? %>
4
2
  <%== rodauth.two_factor_setup_heading %>
5
3
 
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.unlock_account_page_title %>
2
-
3
1
  <%= form_with url: rodauth.unlock_account_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <%== rodauth.unlock_account_explanatory_text %>
5
3
 
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.unlock_account_request_page_title %>
2
-
3
1
  <%= form_with url: rodauth.unlock_account_request_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <%= form.hidden_field rodauth.login_param, value: params[rodauth.login_param] %>
5
3
 
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.verify_account_page_title %>
2
-
3
1
  <%= form_with url: rodauth.verify_account_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <% if rodauth.verify_account_set_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.resend_verify_account_page_title %>
2
-
3
1
  <%= form_with url: rodauth.verify_account_resend_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <%== rodauth.verify_account_resend_explanatory_text %>
5
3
 
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.verify_login_change_page_title %>
2
-
3
1
  <%= form_with url: rodauth.verify_login_change_path, method: :post, data: { turbo: false } do |form| %>
4
2
  <div class="form-group mb-3">
5
3
  <%= form.submit rodauth.verify_login_change_button, class: "btn btn-primary" %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.webauthn_auth_page_title %>
2
-
3
1
  <% cred = rodauth.webauth_credential_options_for_get %>
4
2
 
5
3
  <%= form_with url: rodauth.webauthn_auth_form_path, method: :post, id: "webauthn-auth-form", data: { credential_options: cred.as_json.to_json, turbo: false } do |form| %>
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.webauthn_remove_page_title %>
2
-
3
1
  <%= form_with url: rodauth.webauthn_remove_path, method: :post, id: "webauthn-remove-form", data: { turbo: false } do |form| %>
4
2
  <% if rodauth.two_factor_modifications_require_password? %>
5
3
  <div class="form-group mb-3">
@@ -1,5 +1,3 @@
1
- <% content_for :title, rodauth.webauthn_setup_page_title %>
2
-
3
1
  <% cred = rodauth.new_webauthn_credential %>
4
2
 
5
3
  <%= form_with url: rodauth.webauthn_setup_path, method: :post, id: "webauthn-setup-form", data: { credential_options: cred.as_json.to_json, turbo: false } do |form| %>
@@ -1,8 +1,8 @@
1
1
  Someone with an account has requested their login be changed to this email address:
2
2
 
3
- Old email: <%= @old_login %>
3
+ Old email: <%= @account.email %>
4
4
 
5
- New email: <%= @new_login %>
5
+ New email: <%= @new_email %>
6
6
 
7
7
  If you did not request this login change, please ignore this message. If you
8
8
  requested this login change, please go to
@@ -8,7 +8,8 @@ module Rodauth
8
8
 
9
9
  # Renders templates with layout. First tries to render a user-defined
10
10
  # template, otherwise falls back to Rodauth's template.
11
- def view(page, *)
11
+ def view(page, title)
12
+ set_title(title)
12
13
  rails_render(action: page.tr("-", "_"), layout: true) ||
13
14
  rails_render(html: super.html_safe, layout: true, formats: :html)
14
15
  end
@@ -50,6 +51,12 @@ module Rodauth
50
51
  html = html.gsub(/<form(.+)>/, '<form\1 data-turbo="false">') if meth == :view
51
52
  html
52
53
  end
54
+
55
+ def set_title(title)
56
+ if title_instance_variable
57
+ rails_controller_instance.instance_variable_set(title_instance_variable, title)
58
+ end
59
+ end
53
60
  end
54
61
  end
55
62
  end
@@ -11,7 +11,6 @@ module Rodauth
11
11
  require "rodauth/rails/feature/email"
12
12
  require "rodauth/rails/feature/instrumentation"
13
13
  require "rodauth/rails/feature/internal_request"
14
- require "rodauth/rails/feature/associations"
15
14
 
16
15
  include Rodauth::Rails::Feature::Base
17
16
  include Rodauth::Rails::Feature::Callbacks
@@ -20,6 +19,5 @@ module Rodauth
20
19
  include Rodauth::Rails::Feature::Email
21
20
  include Rodauth::Rails::Feature::Instrumentation
22
21
  include Rodauth::Rails::Feature::InternalRequest
23
- include Rodauth::Rails::Feature::Associations
24
22
  end
25
23
  end
@@ -1,101 +1,6 @@
1
1
  module Rodauth
2
2
  module Rails
3
- class Model < Module
4
- ASSOCIATION_TYPES = { one: :has_one, many: :has_many }
5
-
6
- def initialize(auth_class, association_options: {})
7
- @auth_class = auth_class
8
- @association_options = association_options
9
-
10
- define_methods
11
- end
12
-
13
- def included(model)
14
- fail Rodauth::Rails::Error, "must be an Active Record model" unless model < ActiveRecord::Base
15
-
16
- define_associations(model)
17
- end
18
-
19
- private
20
-
21
- def define_methods
22
- rodauth = @auth_class.allocate.freeze
23
-
24
- attr_reader :password
25
-
26
- define_method(:password=) do |password|
27
- @password = password
28
- password_hash = rodauth.send(:password_hash, password) if password
29
- set_password_hash(password_hash)
30
- end
31
-
32
- define_method(:set_password_hash) do |password_hash|
33
- if rodauth.account_password_hash_column
34
- public_send(:"#{rodauth.account_password_hash_column}=", password_hash)
35
- else
36
- if password_hash
37
- record = self.password_hash || build_password_hash
38
- record.public_send(:"#{rodauth.password_hash_column}=", password_hash)
39
- else
40
- self.password_hash&.mark_for_destruction
41
- end
42
- end
43
- end
44
- end
45
-
46
- def define_associations(model)
47
- define_password_hash_association(model) unless rodauth.account_password_hash_column
48
-
49
- rodauth.associations.each do |association|
50
- define_association(model, **association, type: ASSOCIATION_TYPES.fetch(association[:type]))
51
- end
52
- end
53
-
54
- def define_password_hash_association(model)
55
- password_hash_id_column = rodauth.password_hash_id_column
56
- scope = -> { select(password_hash_id_column) } if rodauth.send(:use_database_authentication_functions?)
57
-
58
- define_association model,
59
- type: :has_one,
60
- name: :password_hash,
61
- table: rodauth.password_hash_table,
62
- foreign_key: password_hash_id_column,
63
- scope: scope,
64
- autosave: true
65
- end
66
-
67
- def define_association(model, type:, name:, table:, foreign_key:, scope: nil, **options)
68
- associated_model = Class.new(model.superclass)
69
- associated_model.table_name = table
70
- associated_model.belongs_to :account,
71
- class_name: model.name,
72
- foreign_key: foreign_key,
73
- inverse_of: name
74
-
75
- model.const_set(name.to_s.singularize.camelize, associated_model)
76
-
77
- unless name == :authentication_audit_logs
78
- dependent = type == :has_many ? :delete_all : :delete
79
- end
80
-
81
- model.public_send type, name, scope,
82
- class_name: associated_model.name,
83
- foreign_key: foreign_key,
84
- dependent: dependent,
85
- inverse_of: :account,
86
- **options,
87
- **association_options(name)
88
- end
89
-
90
- def association_options(name)
91
- options = @association_options
92
- options = options.call(name) if options.respond_to?(:call)
93
- options || {}
94
- end
95
-
96
- def rodauth
97
- @auth_class.allocate
98
- end
99
- end
3
+ Model = Rodauth::Model
4
+ deprecate_constant :Model
100
5
  end
101
6
  end
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "1.4.0"
3
+ VERSION = "1.5.0"
4
4
  end
5
5
  end
data/lib/rodauth/rails.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "rodauth/rails/version"
2
2
  require "rodauth/rails/railtie"
3
+ require "rodauth/model"
3
4
 
4
5
  module Rodauth
5
6
  module Rails
@@ -15,7 +16,7 @@ module Rodauth
15
16
  @middleware = true
16
17
 
17
18
  class << self
18
- def rodauth(name = nil, query: nil, form: nil, account: nil, **options)
19
+ def rodauth(name = nil, account: nil, **options)
19
20
  auth_class = app.rodauth!(name)
20
21
 
21
22
  unless auth_class.features.include?(:internal_request)
@@ -43,7 +44,7 @@ module Rodauth
43
44
  end
44
45
 
45
46
  def model(name = nil, **options)
46
- Rodauth::Rails::Model.new(app.rodauth!(name), **options)
47
+ Rodauth::Model.new(app.rodauth!(name), **options)
47
48
  end
48
49
 
49
50
  # routing constraint that requires authentication
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.add_dependency "rodauth", "~> 2.23"
21
21
  spec.add_dependency "roda", "~> 3.55"
22
22
  spec.add_dependency "sequel-activerecord_connection", "~> 1.1"
23
+ spec.add_dependency "rodauth-model", "~> 0.2"
23
24
  spec.add_dependency "tilt"
24
25
  spec.add_dependency "bcrypt"
25
26
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-04 00:00:00.000000000 Z
11
+ date: 2022-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -72,6 +72,20 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '1.1'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rodauth-model
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.2'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.2'
75
89
  - !ruby/object:Gem::Dependency
76
90
  name: tilt
77
91
  requirement: !ruby/object:Gem::Requirement
@@ -264,7 +278,6 @@ files:
264
278
  - lib/rodauth/rails/auth.rb
265
279
  - lib/rodauth/rails/controller_methods.rb
266
280
  - lib/rodauth/rails/feature.rb
267
- - lib/rodauth/rails/feature/associations.rb
268
281
  - lib/rodauth/rails/feature/base.rb
269
282
  - lib/rodauth/rails/feature/callbacks.rb
270
283
  - lib/rodauth/rails/feature/csrf.rb
@@ -1,54 +0,0 @@
1
- module Rodauth
2
- module Rails
3
- module Feature
4
- module Associations
5
- def associations
6
- list = []
7
-
8
- features.each do |feature|
9
- case feature
10
- when :remember
11
- list << { name: :remember_key, type: :one, table: remember_table, foreign_key: remember_id_column }
12
- when :verify_account
13
- list << { name: :verification_key, type: :one, table: verify_account_table, foreign_key: verify_account_id_column }
14
- when :reset_password
15
- list << { name: :password_reset_key, type: :one, table: reset_password_table, foreign_key: reset_password_id_column }
16
- when :verify_login_change
17
- list << { name: :login_change_key, type: :one, table: verify_login_change_table, foreign_key: verify_login_change_id_column }
18
- when :lockout
19
- list << { name: :lockout, type: :one, table: account_lockouts_table, foreign_key: account_lockouts_id_column }
20
- list << { name: :login_failure, type: :one, table: account_login_failures_table, foreign_key: account_login_failures_id_column }
21
- when :email_auth
22
- list << { name: :email_auth_key, type: :one, table: email_auth_table, foreign_key: email_auth_id_column }
23
- when :account_expiration
24
- list << { name: :activity_time, type: :one, table: account_activity_table, foreign_key: account_activity_id_column }
25
- when :active_sessions
26
- list << { name: :active_session_keys, type: :many, table: active_sessions_table, foreign_key: active_sessions_account_id_column }
27
- when :audit_logging
28
- list << { name: :authentication_audit_logs, type: :many, table: audit_logging_table, foreign_key: audit_logging_account_id_column }
29
- when :disallow_password_reuse
30
- list << { name: :previous_password_hashes, type: :many, table: previous_password_hash_table, foreign_key: previous_password_account_id_column }
31
- when :jwt_refresh
32
- list << { name: :jwt_refresh_keys, type: :many, table: jwt_refresh_token_table, foreign_key: jwt_refresh_token_account_id_column }
33
- when :password_expiration
34
- list << { name: :password_change_time, type: :one, table: password_expiration_table, foreign_key: password_expiration_id_column }
35
- when :single_session
36
- list << { name: :session_key, type: :one, table: single_session_table, foreign_key: single_session_id_column }
37
- when :otp
38
- list << { name: :otp_key, type: :one, table: otp_keys_table, foreign_key: otp_keys_id_column }
39
- when :sms_codes
40
- list << { name: :sms_code, type: :one, table: sms_codes_table, foreign_key: sms_id_column }
41
- when :recovery_codes
42
- list << { name: :recovery_codes, type: :many, table: recovery_codes_table, foreign_key: recovery_codes_id_column }
43
- when :webauthn
44
- list << { name: :webauthn_user_id, type: :one, table: webauthn_user_ids_table, foreign_key: webauthn_user_ids_account_id_column }
45
- list << { name: :webauthn_keys, type: :many, table: webauthn_keys_table, foreign_key: webauthn_keys_account_id_column }
46
- end
47
- end
48
-
49
- list
50
- end
51
- end
52
- end
53
- end
54
- end