rodauth-rails 1.11.0 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f902ae05472454543304221221b9681c7dab3d231d6551c7e82b6c4c1570dc8
4
- data.tar.gz: b3a1948fb603be978bddea73a44b8109f4e3c76e132b2da3a8e6aad1b36f3d14
3
+ metadata.gz: f56967000d0a2cc64e51a707783fc541d4ff37dbb3e68f1fc519ef02a0a83e65
4
+ data.tar.gz: dfe189f65d18781e42058e133f0e403ed769421fb8682e4a63078b1f7e39cb8a
5
5
  SHA512:
6
- metadata.gz: 8547335032c3e0851406932463cd62e2377c16db2145e0da6abb8a7f20745c20f9e8d54bd2b57599e335a4f9b37078cf7f1c17caa53b4dab60105c410a401469
7
- data.tar.gz: dd84bd6d57a4e8e78a6412a7ac38befa7d75ef693a6788014d383d3800a4535af71fa24239f8b0521cecc7c598766f48b2034a016a2a15235cfa9f9d2dd52761
6
+ metadata.gz: f582926f90ab796d491210e28705585e166047c3b3f093e27ad556fb5271041e5c0a34ce78a42d9ec84c5b074958938527b233b750ec944043611df6f1bf7112
7
+ data.tar.gz: 04e475c871440131db6c42c1eabcecc95a34e323cfdd2ce045f59b196439d404321ee27e64b857321df642e362168e146b15ed354a3710d3fff5160ad23f18d1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ ## 1.13.0 (2023-12-25) :christmas_tree:
2
+
3
+ * Add `#rodauth` method to controller test helpers (@janko)
4
+
5
+ * When session middleware is required by Rodauth but missing, point to Rails docs instead of Roda (@janko)
6
+
7
+ * Set `login_confirm_param` to `"email-confirm"` in default configuration for consistency (@janko)
8
+
9
+ * Set `convert_token_id_to_integer?` in default configuration to avoid DB queries on boot (@janko)
10
+
11
+ ## 1.12.0 (2023-10-20)
12
+
13
+ * Allow generating view template for `confirm_password` feature (igor-alexandrov)
14
+
15
+ * Forward all requests unhandled by the Rodauth app to the Rails router (@janko)
16
+
17
+ * Use `Rodauth::Model()` directly for including in generated account model (@janko)
18
+
19
+ * Set `{jwt,argon2}_secret` to `hmac_secret` on `rodauth:install` with `--{jwt,argon2}` (@janko)
20
+
21
+ * Expose `#turbo_stream` method in `Rodauth::Rails::Auth` when using turbo-rails gem (@janko)
22
+
23
+ * Add `#rails_cookies` method for accessing the Action Dispatch cookie jar (@janko)
24
+
1
25
  ## 1.11.0 (2023-08-21)
2
26
 
3
27
  * Exclude WebAuthn JS routes in `rodauth:routes`, since those stop being relevant with custom JS (@janko)
data/README.md CHANGED
@@ -10,18 +10,20 @@ Provides Rails integration for the [Rodauth] authentication framework.
10
10
  * [Rails demo](https://github.com/janko/rodauth-demo-rails)
11
11
  * [JSON API guide](https://github.com/janko/rodauth-rails/wiki/JSON-API)
12
12
  * [OmniAuth guide](https://github.com/janko/rodauth-rails/wiki/OmniAuth)
13
+ * [JSON Request Documentation for Rodauth](https://documenter.getpostman.com/view/26686011/2s9YC7SWn9)
13
14
 
14
15
  🎥 Screencasts:
15
16
 
16
17
  * [Rails Authentication with Rodauth](https://www.youtube.com/watch?v=2hDpNikacf0)
17
18
  * [Multifactor Authentication with Rodauth](https://www.youtube.com/watch?v=9ON-kgXpz2A&list=PLkGQXZLACDTGKsaRWstkHQdm2CUmT3SZ-) ([TOTP](https://youtu.be/9ON-kgXpz2A), [Recovery Codes](https://youtu.be/lkFCcE1Q5-w))
19
+ * [Add Admin Accounts](https://www.youtube.com/watch?v=N6z7AtKSpNI)
18
20
 
19
21
  📚 Articles:
20
22
 
21
23
  * [Rodauth: A Refreshing Authentication Solution for Ruby](https://janko.io/rodauth-a-refreshing-authentication-solution-for-ruby/)
22
24
  * [Rails Authentication with Rodauth](https://janko.io/adding-authentication-in-rails-with-rodauth/)
23
25
  * [Multifactor Authentication in Rails with Rodauth](https://janko.io/adding-multifactor-authentication-in-rails-with-rodauth/)
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)
26
+ * [How to build an OIDC provider using rodauth-oauth on Rails](https://honeyryderchuck.gitlab.io/2021/03/15/oidc-provider-on-rails-using-rodauth-oauth.html)
25
27
  * [What It Took to Build a Rails Integration for Rodauth](https://janko.io/what-it-took-to-build-a-rails-integration-for-rodauth/)
26
28
  * [Social Login in Rails with Rodauth](https://janko.io/social-login-in-rails-with-rodauth/)
27
29
  * [Passkey Authentication with Rodauth](https://janko.io/passkey-authentication-with-rodauth/)
@@ -44,11 +46,7 @@ of the advantages that stand out for me:
44
46
 
45
47
  One common concern for people coming from other Rails authentication frameworks
46
48
  is the fact that Rodauth uses [Sequel] for database interaction instead of
47
- Active Record. Sequel has powerful APIs for building advanced queries,
48
- supporting complex SQL expressions, database-agnostic date arithmetic, SQL
49
- function calls and more, all without having to drop down to raw SQL.
50
-
51
- For Rails apps using Active Record, rodauth-rails configures Sequel to [reuse
49
+ Active Record. For Rails apps using Active Record, rodauth-rails configures Sequel to [reuse
52
50
  Active Record's database connection][sequel-activerecord_connection]. This
53
51
  makes it run smoothly alongside Active Record, even allowing calling Active
54
52
  Record code from within Rodauth configuration. So, for all intents and
@@ -68,7 +66,28 @@ Next, run the install generator:
68
66
  $ rails generate rodauth:install
69
67
  ```
70
68
 
71
- This will use the `accounts` table. If you want a different table name:
69
+ This generator will create a Rodauth app and configuration with common
70
+ authentication features enabled, a database migration with tables required by
71
+ those features, a mailer with default templates, and a few other files.
72
+
73
+ Feel free to remove any features you don't need, along with their corresponding
74
+ tables. Afterwards, run the migration:
75
+
76
+ ```sh
77
+ $ rails db:migrate
78
+ ```
79
+
80
+ For your mailer to be able to generate email links, you'll need to set up
81
+ default URL options in each environment. Here is a possible configuration for
82
+ `config/environments/development.rb`:
83
+
84
+ ```rb
85
+ config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
86
+ ```
87
+
88
+ ### Install options
89
+
90
+ The install generator will use the `accounts` table by default. You can specify a different table name:
72
91
 
73
92
  ```sh
74
93
  $ rails generate rodauth:install users
@@ -90,25 +109,6 @@ $ rails generate rodauth:install --argon2
90
109
  $ bundle add argon2
91
110
  ```
92
111
 
93
- This generator will create a Rodauth app and configuration with common
94
- authentication features enabled, a database migration with tables required by
95
- those features, a mailer with default templates, and a few other files.
96
-
97
- Feel free to remove any features you don't need, along with their corresponding
98
- tables. Afterwards, run the migration:
99
-
100
- ```sh
101
- $ rails db:migrate
102
- ```
103
-
104
- For your mailer to be able to generate email links, you'll need to set up
105
- default URL options in each environment. Here is a possible configuration for
106
- `config/environments/development.rb`:
107
-
108
- ```rb
109
- config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
110
- ```
111
-
112
112
  ## Usage
113
113
 
114
114
  The Rodauth app will be called for each request before it reaches the Rails
@@ -153,7 +153,7 @@ navigation header:
153
153
 
154
154
  ```erb
155
155
  <% if rodauth.logged_in? %>
156
- <%= link_to "Sign out", rodauth.logout_path, method: :post %>
156
+ <%= link_to "Sign out", rodauth.logout_path, data: { turbo_method: :post } %>
157
157
  <% else %>
158
158
  <%= link_to "Sign in", rodauth.login_path %>
159
159
  <%= link_to "Sign up", rodauth.create_account_path %>
@@ -181,28 +181,18 @@ class ApplicationController < ActionController::Base
181
181
  end
182
182
  ```
183
183
 
184
- ```rb
185
- current_account #=> #<Account id=123 email="user@example.com">
186
- current_account.email #=> "user@example.com"
187
- ```
188
-
189
184
  ### Requiring authentication
190
185
 
191
- You'll likely want to require authentication for certain parts of your app,
192
- redirecting the user to the login page if they're not logged in. You can do this
193
- in your Rodauth app's routing block, which helps keep the authentication logic
194
- encapsulated:
186
+ You can require authentication for routes at the middleware level in in your Rodauth
187
+ app's routing block, which helps keep the authentication logic encapsulated:
195
188
 
196
189
  ```rb
197
190
  # app/misc/rodauth_app.rb
198
191
  class RodauthApp < Rodauth::Rails::App
199
- # ...
200
192
  route do |r|
201
- # ...
202
193
  r.rodauth # route rodauth requests
203
194
 
204
- # require authentication for /dashboard/* routes
205
- if r.path.start_with?("/dashboard")
195
+ if r.path.start_with?("/dashboard") # /dashboard/* routes
206
196
  rodauth.require_account # redirect to login page if not authenticated
207
197
  end
208
198
  end
@@ -212,7 +202,6 @@ end
212
202
  You can also require authentication at the controller layer:
213
203
 
214
204
  ```rb
215
- # app/controllers/application_controller.rb
216
205
  class ApplicationController < ActionController::Base
217
206
  private
218
207
 
@@ -222,68 +211,46 @@ class ApplicationController < ActionController::Base
222
211
  end
223
212
  ```
224
213
  ```rb
225
- # app/controllers/dashboard_controller.rb
226
214
  class DashboardController < ApplicationController
227
215
  before_action :authenticate
228
216
  end
229
217
  ```
230
218
 
231
- #### Routing constraints
232
-
233
- In some cases it makes sense to require authentication at the Rails router
234
- level. You can do this via the built-in `authenticated` routing constraint:
219
+ Additionally, routes can be authenticated at the Rails router level:
235
220
 
236
221
  ```rb
237
222
  # config/routes.rb
238
223
  Rails.application.routes.draw do
239
224
  constraints Rodauth::Rails.authenticate do
240
- # ... authenticated routes ...
225
+ # ... these routes will require authentication ...
241
226
  end
242
- end
243
- ```
244
-
245
- If you want additional conditions, you can pass in a block, which is
246
- called with the Rodauth instance:
247
227
 
248
- ```rb
249
- # config/routes.rb
250
- Rails.application.routes.draw do
251
- # require multifactor authentication to be setup
252
228
  constraints Rodauth::Rails.authenticate { |rodauth| rodauth.uses_two_factor_authentication? } do
253
- # ...
229
+ # ... these routes will be available only if 2FA is setup ...
254
230
  end
255
- end
256
- ```
257
231
 
258
- You can specify a different Rodauth configuration by passing the configuration name:
259
-
260
- ```rb
261
- # config/routes.rb
262
- Rails.application.routes.draw do
263
232
  constraints Rodauth::Rails.authenticate(:admin) do
264
- # ...
233
+ # ... these routes will be authenticated with secondary "admin" configuration ...
265
234
  end
266
- end
267
- ```
268
235
 
269
- If you need something more custom, you can always create the routing constraint
270
- manually:
271
-
272
- ```rb
273
- # config/routes.rb
274
- Rails.application.routes.draw do
275
236
  constraints -> (r) { !r.env["rodauth"].logged_in? } do # or env["rodauth.admin"]
276
- # routes when the user is not logged in
237
+ # ... these routes will be available only if not authenticated ...
277
238
  end
278
239
  end
279
240
  ```
280
241
 
281
242
  ### Controller
282
243
 
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.
244
+ Your Rodauth configuration is linked to a Rails controller, which is primarily used to render views and handle CSRF protection, but will also execute any callbacks and rescue handlers defined on it around Rodauth endpoints.
286
245
 
246
+ ```rb
247
+ # app/misc/rodauth_main.rb
248
+ class RodauthMain < Rodauth::Rails::Auth
249
+ configure do
250
+ rails_controller { RodauthController }
251
+ end
252
+ end
253
+ ```
287
254
  ```rb
288
255
  class RodauthController < ApplicationController
289
256
  before_action :set_locale # executes before Rodauth endpoints
@@ -291,42 +258,28 @@ class RodauthController < ApplicationController
291
258
  end
292
259
  ```
293
260
 
294
- #### Calling controller methods
261
+ Various methods are available in your Rodauth configuration to bridge the gap with the controller:
295
262
 
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
263
  ```rb
308
- # app/misc/rodauth_main.rb
309
264
  class RodauthMain < Rodauth::Rails::Auth
310
265
  configure do
266
+ # calling methods on the controller:
311
267
  after_create_account do
312
- rails_controller_eval { setup_tracking(account_id) }
268
+ rails_controller_eval { some_controller_method(account_id) }
313
269
  end
314
- end
315
- end
316
- ```
317
270
 
318
- ### Rails URL helpers
271
+ # accessing Rails URL helpers:
272
+ login_redirect { rails_routes.dashboard_path }
319
273
 
320
- Inside Rodauth configuration and the `route` block you can access Rails route
321
- helpers through `#rails_routes`:
274
+ # accessing Rails request object:
275
+ after_change_password do
276
+ if rails_request.format.turbo_stream?
277
+ return_response rails_render(turbo_stream: [turbo_stream.replace(...)])
278
+ end
279
+ end
322
280
 
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 }
281
+ # accessing Rails cookies:
282
+ after_login { rails_cookies.permanent[:last_account_id] = account_id }
330
283
  end
331
284
  end
332
285
  ```
@@ -338,97 +291,29 @@ you'll want to start editing the markup. You can run the following command to
338
291
  copy Rodauth templates into your Rails app:
339
292
 
340
293
  ```sh
341
- $ rails generate rodauth:views # bootstrap views
342
- # or
343
- $ rails generate rodauth:views --css=tailwind # tailwind views (requires @tailwindcss/forms plugin)
294
+ $ rails generate rodauth:views
344
295
  ```
345
296
 
346
297
  This will generate views for Rodauth features you have currently enabled into
347
- the `app/views/rodauth` directory, provided that `RodauthController` is set for
348
- the main configuration.
298
+ the `app/views/rodauth` directory (provided that `RodauthController` is set for
299
+ the main configuration).
349
300
 
350
- You can pass a list of Rodauth features to the generator to create views for
351
- these features (this will not remove any existing views):
301
+ The generator accepts various options:
352
302
 
353
303
  ```sh
354
- $ rails generate rodauth:views login create_account lockout otp
355
- ```
304
+ # generate views with Tailwind markup (requires @tailwindcss/forms plugin)
305
+ $ rails generate rodauth:views --css=tailwind
356
306
 
357
- Or you can generate views for all features:
307
+ # specify Rodauth features to generate views for
308
+ $ rails generate rodauth:views login create_account lockout otp
358
309
 
359
- ```sh
310
+ # generate views for all Rodauth features
360
311
  $ rails generate rodauth:views --all
361
- ```
362
312
 
363
- Use `--name` to generate views for a different Rodauth configuration:
364
-
365
- ```sh
313
+ # specify a different Rodauth configuration
366
314
  $ rails generate rodauth:views webauthn two_factor_base --name admin
367
315
  ```
368
316
 
369
- ### Page titles
370
-
371
- The generated configuration sets `title_instance_variable` to make page titles
372
- available in your views via `@page_title` instance variable, which you can then
373
- use in your layout:
374
-
375
- ```rb
376
- # app/misc/rodauth_main.rb
377
- class RodauthMain < Rodauth::Rails::Auth
378
- configure do
379
- title_instance_variable :@page_title
380
- end
381
- end
382
- ```
383
- ```erb
384
- <!-- app/views/layouts/application.html.erb -->
385
- <!DOCTYPE html>
386
- <html>
387
- <head>
388
- <title><%= @page_title || "Default title" %></title>
389
- <!-- ... -->
390
- </head>
391
- <!-- ... -->
392
- </html>
393
- ```
394
-
395
- ### Layout
396
-
397
- To use different layouts for different Rodauth views, you can compare the
398
- request path in the layout method:
399
-
400
- ```rb
401
- # app/controllers/rodauth_controller.rb
402
- class RodauthController < ApplicationController
403
- layout :rodauth_layout
404
-
405
- private
406
-
407
- def rodauth_layout
408
- case request.path
409
- when rodauth.login_path,
410
- rodauth.create_account_path,
411
- rodauth.verify_account_path,
412
- rodauth.verify_account_resend_path,
413
- rodauth.reset_password_path,
414
- rodauth.reset_password_request_path
415
- "authentication"
416
- else
417
- "dashboard"
418
- end
419
- end
420
- end
421
- ```
422
-
423
- ### Turbo
424
-
425
- [Turbo] has been disabled by default on all built-in and generated view
426
- templates, because some Rodauth actions (multi-phase login, adding recovery
427
- codes) aren't Turbo-compatible, as they return 200 responses on POST requests.
428
-
429
- That being said, most of Rodauth *is* Turbo-compatible, so feel free to enable
430
- Turbo for actions where you want to use it.
431
-
432
317
  ## Mailer
433
318
 
434
319
  The install generator will create `RodauthMailer` with default email templates,
@@ -492,8 +377,6 @@ class CreateRodauthOtpSmsCodesRecoveryCodes < ActiveRecord::Migration
492
377
  end
493
378
  ```
494
379
 
495
- ### Table prefix
496
-
497
380
  If you're storing account records in a table other than `accounts`, you'll want
498
381
  to specify the appropriate table prefix when generating new migrations:
499
382
 
@@ -516,15 +399,13 @@ class CreateRodauthUserBaseActiveSessions < ActiveRecord::Migration
516
399
  end
517
400
  ```
518
401
 
519
- ### Custom migration name
520
-
521
402
  You can change the default migration name:
522
403
 
523
404
  ```sh
524
405
  $ rails generate rodauth:migration email_auth --name create_account_email_auth_keys
525
406
  ```
526
407
  ```rb
527
- # db/migration/*_create_account_email_auth_keys
408
+ # db/migration/*_create_account_email_auth_keys.rb
528
409
  class CreateAccountEmailAuthKeys < ActiveRecord::Migration
529
410
  def change
530
411
  create_table :account_email_auth_keys do |t| ... end
@@ -540,7 +421,7 @@ tables used by enabled authentication features.
540
421
 
541
422
  ```rb
542
423
  class Account < ActiveRecord::Base # Sequel::Model
543
- include Rodauth::Rails.model # or Rodauth::Rails.model(:admin)
424
+ include Rodauth::Model(RodauthMain)
544
425
  end
545
426
  ```
546
427
  ```rb
@@ -573,6 +454,10 @@ class RodauthApp < Rodauth::Rails::App
573
454
  route do |r|
574
455
  r.rodauth # route primary rodauth requests
575
456
  r.rodauth(:admin) # route secondary rodauth requests
457
+
458
+ if request.path.start_with?("/admin")
459
+ rodauth(:admin).require_account
460
+ end
576
461
  end
577
462
  end
578
463
  ```
@@ -599,6 +484,7 @@ end
599
484
  Then in your application you can reference the secondary Rodauth instance:
600
485
 
601
486
  ```rb
487
+ rodauth(:admin).authenticated? # checks "admin_account_id" session value
602
488
  rodauth(:admin).login_path #=> "/admin/login"
603
489
  ```
604
490
 
@@ -608,66 +494,24 @@ that. Note that you can also [share configuration via inheritance][inheritance].
608
494
 
609
495
  ## Outside of a request
610
496
 
611
- ### Calling actions
612
-
613
- In some cases you might need to use Rodauth more programmatically. If you want
614
- to perform authentication operations outside of request context, Rodauth ships
615
- with the [internal_request] feature just for that.
497
+ The [internal_request] and [path_class_methods] features are supported, with defaults taken from `config.action_mailer.default_url_options`.
616
498
 
617
499
  ```rb
618
- # app/misc/rodauth_main.rb
619
- class RodauthMain < Rodauth::Rails::Auth
620
- configure do
621
- enable :internal_request
622
- end
623
- end
624
- ```
625
- ```rb
626
- # primary configuration
500
+ # internal requests
627
501
  RodauthApp.rodauth.create_account(login: "user@example.com", password: "secret123")
628
- RodauthApp.rodauth.verify_account(account_login: "user@example.com")
629
-
630
- # secondary configuration
631
- RodauthApp.rodauth(:admin).close_account(account_login: "user@example.com")
632
- ```
633
-
634
- ### Generating URLs
635
-
636
- For generating authentication URLs outside of a request use the
637
- [path_class_methods] plugin:
638
-
639
- ```rb
640
- # app/misc/rodauth_main.rb
641
- class RodauthMain < Rodauth::Rails::Auth
642
- configure do
643
- enable :path_class_methods
644
- create_account_route "register"
645
- end
646
- end
647
- ```
648
- ```rb
649
- # primary configuration
650
- RodauthApp.rodauth.create_account_path # => "/register"
651
- RodauthApp.rodauth.verify_account_url(key: "abc123") #=> "https://example.com/verify-account?key=abc123"
502
+ RodauthApp.rodauth(:admin).verify_account(account_login: "admin@example.com")
652
503
 
653
- # secondary configuration
654
- RodauthApp.rodauth(:admin).close_account_path(foo: "bar") #=> "/admin/close-account?foo=bar"
504
+ # path and URL methods
505
+ RodauthApp.rodauth.close_account_path #=> "/close-account"
506
+ RodauthApp.rodauth(:admin).otp_setup_url #=> "http://localhost:3000/admin/otp-setup"
655
507
  ```
656
508
 
657
509
  ### Calling instance methods
658
510
 
659
511
  If you need to access Rodauth methods not exposed as internal requests, you can
660
- use `Rodauth::Rails.rodauth` to retrieve the Rodauth instance used by the
661
- internal_request feature:
512
+ use `Rodauth::Rails.rodauth` to retrieve the Rodauth instance (this requires enabling
513
+ the internal_request feature):
662
514
 
663
- ```rb
664
- # app/misc/rodauth_main.rb
665
- class RodauthMain < Rodauth::Rails::Auth
666
- configure do
667
- enable :internal_request # this is required
668
- end
669
- end
670
- ```
671
515
  ```rb
672
516
  account = Account.find_by!(email: "user@example.com")
673
517
  rodauth = Rodauth::Rails.rodauth(account: account) #=> #<RodauthMain::InternalRequest ...>
@@ -693,8 +537,12 @@ Rodauth::Rails.rodauth(:admin, params: { "param" => "value" })
693
537
 
694
538
  ### Using as a library
695
539
 
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:
540
+ Rodauth offers a [`Rodauth.lib`][library] method for when you want to use it as a library (via [internal requests][internal_request]), as opposed to having it route requests. This gem provides a `Rodauth::Rails.lib` counterpart that does the same but with Rails integration:
697
541
 
542
+ ```rb
543
+ # skip require on boot to avoid inserting Rodauth middleware
544
+ gem "rodauth-rails", require: false
545
+ ```
698
546
  ```rb
699
547
  # app/misc/rodauth_main.rb
700
548
  require "rodauth/rails"
@@ -712,23 +560,6 @@ RodauthMain.login(login: "email@example.com", password: "secret123")
712
560
  RodauthMain.close_account(account_login: "email@example.com")
713
561
  ```
714
562
 
715
- Note that you'll want to skip requiring `rodauth-rails` on Rails boot, to avoid it automatically inserting the Rodauth middleware, and remove some unnecessary files generated by the install generator.
716
-
717
- ```rb
718
- # Gemfile
719
- gem "rodauth-rails", require: false
720
- ```
721
- ```sh
722
- $ rm config/initializers/rodauth.rb app/misc/rodauth_app.rb app/controllers/rodauth_controller.rb
723
- ```
724
-
725
- The `Rodauth::Rails.lib` call will forward any Rodauth [plugin options] passed to it:
726
-
727
- ```rb
728
- # skips loading Roda render plugin and Tilt gem (used for rendering built-in templates)
729
- Rodauth::Rails.lib(render: false) { ... }
730
- ```
731
-
732
563
  ## Testing
733
564
 
734
565
  For system and integration tests, which run the whole middleware stack,
@@ -762,7 +593,7 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest
762
593
  post "/logout"
763
594
  assert_redirected_to "/"
764
595
  end
765
-
596
+
766
597
  test "required authentication" do
767
598
  get :index
768
599
 
@@ -786,14 +617,11 @@ end
786
617
  ```
787
618
 
788
619
  For more examples and information about testing with rodauth, see
789
- [this wiki page about testing](https://github.com/janko/rodauth-rails/wiki/Testing).
620
+ [this wiki page about testing](https://github.com/janko/rodauth-rails/wiki/Testing).
790
621
 
791
622
  ## Configuring
792
623
 
793
- ### Configuration methods
794
-
795
- The `rails` feature rodauth-rails loads provides the following configuration
796
- methods:
624
+ The `rails` feature rodauth-rails loads provides the following configuration methods:
797
625
 
798
626
  | Name | Description |
799
627
  | :---- | :---------- |
@@ -806,70 +634,6 @@ methods:
806
634
  | `rails_controller` | Controller class to use for rendering and CSRF protection. |
807
635
  | `rails_account_model` | Model class connected with the accounts table. |
808
636
 
809
- ```rb
810
- class RodauthMain < Rodauth::Rails::Auth
811
- configure do
812
- rails_controller { Authentication::RodauthController }
813
- rails_account_model { Authentication::Account }
814
- end
815
- end
816
- ```
817
-
818
- For the list of configuration methods provided by Rodauth, see the [feature
819
- documentation].
820
-
821
- ### Defining custom methods
822
-
823
- All Rodauth configuration methods are just syntax sugar for defining instance
824
- methods on the auth class. You can also define your own custom methods:
825
-
826
- ```rb
827
- class RodauthMain < Rodauth::Rails::Auth
828
- configure do
829
- password_match? { |password| ldap_valid?(password) }
830
- end
831
-
832
- def admin?
833
- rails_account.admin?
834
- end
835
-
836
- private
837
-
838
- def ldap_valid?(password)
839
- SimpleLdapAuthenticator.valid?(account[:email], password)
840
- end
841
- end
842
- ```
843
- ```rb
844
- rodauth.admin? #=> true
845
- ```
846
-
847
- ### Single-file configuration
848
-
849
- If you would prefer, you can have all your Rodauth logic contained inside the
850
- Rodauth app class:
851
-
852
- ```rb
853
- # app/misc/rodauth_app.rb
854
- class RodauthApp < Rodauth::Rails::App
855
- # primary configuration
856
- configure do
857
- enable :login, :logout, :create_account, :verify_account
858
- # ...
859
- end
860
-
861
- # secondary configuration
862
- configure(:admin) do
863
- enable :email_auth, :single_session
864
- # ...
865
- end
866
-
867
- route do |r|
868
- # ...
869
- end
870
- end
871
- ```
872
-
873
637
  ### Manually inserting middleware
874
638
 
875
639
  You can choose to insert the Rodauth middleware somewhere earlier than
@@ -880,7 +644,7 @@ Rodauth::Rails.configure do |config|
880
644
  config.middleware = false # disable auto-insertion
881
645
  end
882
646
 
883
- Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
647
+ Rails.configuration.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
884
648
  ```
885
649
 
886
650
  ## How it works
@@ -888,7 +652,7 @@ Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Ra
888
652
  ### Rack middleware
889
653
 
890
654
  The railtie inserts [`Rodauth::Rails::Middleware`](/lib/rodauth/rails/middleware.rb)
891
- at the end of the middleware stack, which calls your Rodauth app around each request.
655
+ at the end of the middleware stack, which is just a wrapper around your Rodauth app.
892
656
 
893
657
  ```sh
894
658
  $ rails middleware
@@ -897,34 +661,15 @@ $ rails middleware
897
661
  # run MyApp::Application.routes
898
662
  ```
899
663
 
900
- The middleware retrieves the Rodauth app via `Rodauth::Rails.app`, which is
901
- specified as a string to keep the class autoloadable and reloadable in
902
- development.
903
-
904
- ```rb
905
- Rodauth::Rails.configure do |config|
906
- config.app = "RodauthApp"
907
- end
908
- ```
909
-
910
- In addition to Zeitwerk compatibility, this extra layer catches Rodauth redirects
911
- that happen on the controller level (e.g. when calling
912
- `rodauth.require_account` in a `before_action` filter).
913
-
914
664
  ### Roda app
915
665
 
916
666
  The [`Rodauth::Rails::App`](/lib/rodauth/rails/app.rb) class is a [Roda]
917
- subclass that provides a convenience layer for Rodauth:
918
-
919
- * uses Action Dispatch flash messages
920
- * provides syntax sugar for loading the rodauth plugin
921
- * saves Rodauth object(s) to Rack env hash
922
- * propagates edited headers to Rails responses
667
+ subclass that provides a convenience layer over Rodauth.
923
668
 
924
669
  #### Configure block
925
670
 
926
- The `configure` call loads the rodauth plugin. By convention, it receives an
927
- auth class and configuration name as positional arguments (forwarded as
671
+ The `configure` call is a wrapper around `plugin :rodauth`. By convention, it receives an
672
+ auth class and configuration name as positional arguments (which get converted into
928
673
  `:auth_class` and `:name` plugin options), a block for anonymous auth classes,
929
674
  and also accepts any additional plugin options.
930
675
 
@@ -956,29 +701,21 @@ class RodauthApp < Rodauth::Rails::App
956
701
  end
957
702
  ```
958
703
 
959
- #### Routing prefix
704
+ #### Rack env
960
705
 
961
- If you use a routing prefix, you don't need to add a call to `r.on` like with
962
- vanilla Rodauth, as `r.rodauth` has been modified to automatically route the
963
- prefix.
706
+ The app sets Rodauth objects for each registered configuration in the Rack env,
707
+ so that they're accessible downstream by the Rails router, controllers and views:
964
708
 
965
709
  ```rb
966
- class RodauthApp < Rodauth::Rails::App
967
- configure do
968
- prefix "/user"
969
- end
970
-
971
- route do |r|
972
- r.rodauth # no need to wrap with `r.on("user") { ... }`
973
- end
974
- end
710
+ request.env["rodauth"] #=> #<RodauthMain>
711
+ request.env["rodauth.admin"] #=> #<RodauthAdmin> (if using multiple configurations)
975
712
  ```
976
713
 
977
714
  ### Auth class
978
715
 
979
716
  The [`Rodauth::Rails::Auth`](/lib/rodauth/rails/auth.rb) class is a subclass of
980
717
  `Rodauth::Auth`, which preloads the `rails` rodauth feature, sets [HMAC] secret to
981
- Rails' secret key base, and modifies some [configuration defaults](#rodauth-defaults).
718
+ Rails' secret key base, and modifies some [configuration defaults][restoring defaults].
982
719
 
983
720
  ```rb
984
721
  class RodauthMain < Rodauth::Rails::Auth
@@ -1000,128 +737,6 @@ The [`rails`](/lib/rodauth/rails/feature.rb) Rodauth feature loaded by
1000
737
  * uses Action Controller instrumentation around Rodauth requests
1001
738
  * uses Action Mailer's default URL options when calling Rodauth outside of a request
1002
739
 
1003
- ### Controller
1004
-
1005
- The Rodauth app stores the `Rodauth::Rails::Auth` instances in the Rack env
1006
- hash, which is then available in your Rails app:
1007
-
1008
- ```rb
1009
- request.env["rodauth"] #=> #<RodauthMain>
1010
- request.env["rodauth.admin"] #=> #<RodauthAdmin> (if using multiple configurations)
1011
- ```
1012
-
1013
- For convenience, this object can be accessed via the `#rodauth` method in views
1014
- and controllers:
1015
-
1016
- ```rb
1017
- class MyController < ApplicationController
1018
- def my_action
1019
- rodauth #=> #<RodauthMain>
1020
- rodauth(:admin) #=> #<RodauthAdmin> (if using multiple configurations)
1021
- end
1022
- end
1023
- ```
1024
- ```erb
1025
- <% rodauth #=> #<RodauthMain> %>
1026
- <% rodauth(:admin) #=> #<RodauthAdmin> (if using multiple configurations) %>
1027
- ```
1028
-
1029
- ## Rodauth defaults
1030
-
1031
- rodauth-rails changes some of the default Rodauth settings for easier setup:
1032
-
1033
- ### Database functions
1034
-
1035
- By default, on PostgreSQL, MySQL, and Microsoft SQL Server Rodauth uses
1036
- database functions to access password hashes, with the user running the
1037
- application unable to get direct access to password hashes. This reduces the
1038
- risk of an attacker being able to access password hashes and use them to attack
1039
- other sites.
1040
-
1041
- While this is useful additional security, it is also more complex to set up and
1042
- to reason about, as it requires having two different database users and making
1043
- sure the correct migration is run for the correct user.
1044
-
1045
- To keep with Rails' "convention over configuration" doctrine, rodauth-rails
1046
- disables the use of database functions, though you can always turn it back on.
1047
-
1048
- ```rb
1049
- use_database_authentication_functions? true
1050
- ```
1051
-
1052
- To create the database functions, pass the Sequel database object into the
1053
- Rodauth method for creating database functions:
1054
-
1055
- ```rb
1056
- # db/migrate/*_create_rodauth_database_functions.rb
1057
- require "rodauth/migrations"
1058
-
1059
- class CreateRodauthDatabaseFunctions < ActiveRecord::Migration
1060
- def up
1061
- Rodauth.create_database_authentication_functions(db)
1062
- end
1063
-
1064
- def down
1065
- Rodauth.drop_database_authentication_functions(db)
1066
- end
1067
-
1068
- private
1069
-
1070
- def db
1071
- RodauthMain.allocate.db
1072
- end
1073
- end
1074
- ```
1075
-
1076
- ### Account statuses
1077
-
1078
- The recommended [Rodauth migration] stores possible account status values in a
1079
- separate table, and creates a foreign key on the accounts table, which ensures
1080
- only a valid status value will be persisted. Unfortunately, this doesn't work
1081
- when the database is restored from the schema file, in which case the account
1082
- statuses table will be empty. This happens in tests by default, but it's also
1083
- not unusual to do it in development.
1084
-
1085
- To address this, rodauth-rails uses a `status` column without a separate table.
1086
- If you're worried about invalid status values creeping in, you may use enums
1087
- instead. Alternatively, you can always go back to the setup recommended by
1088
- Rodauth.
1089
-
1090
- ```rb
1091
- # in the migration:
1092
- create_table :account_statuses do |t|
1093
- t.string :name, null: false, unique: true
1094
- end
1095
- execute "INSERT INTO account_statuses (id, name) VALUES (1, 'Unverified'), (2, 'Verified'), (3, 'Closed')"
1096
-
1097
- create_table :accounts do |t|
1098
- # ...
1099
- t.references :status, foreign_key: { to_table: :account_statuses }, null: false, default: 1
1100
- # ...
1101
- end
1102
- ```
1103
- ```diff
1104
- class RodauthMain < Rodauth::Rails::Auth
1105
- configure do
1106
- # ...
1107
- - account_status_column :status
1108
- # ...
1109
- end
1110
- end
1111
- ```
1112
-
1113
- ### Deadline values
1114
-
1115
- To simplify changes to the database schema, rodauth-rails configures Rodauth
1116
- to set deadline values for various features in Ruby, instead of relying on
1117
- the database to set default column values.
1118
-
1119
- You can easily change this back:
1120
-
1121
- ```rb
1122
- set_deadline_values? false
1123
- ```
1124
-
1125
740
  ## License
1126
741
 
1127
742
  The gem is available as open source under the terms of the [MIT
@@ -1135,12 +750,10 @@ conduct](CODE_OF_CONDUCT.md).
1135
750
 
1136
751
  [Rodauth]: https://github.com/jeremyevans/rodauth
1137
752
  [Sequel]: https://github.com/jeremyevans/sequel
1138
- [feature documentation]: http://rodauth.jeremyevans.net/documentation.html
1139
753
  [Bootstrap]: https://getbootstrap.com/
1140
754
  [Roda]: http://roda.jeremyevans.net/
1141
755
  [HMAC]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-HMAC
1142
756
  [database authentication functions]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Password+Hash+Access+Via+Database+Functions
1143
- [Rodauth migration]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Creating+tables
1144
757
  [sequel-activerecord_connection]: https://github.com/janko/sequel-activerecord_connection
1145
758
  [plugin options]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Plugin+Options
1146
759
  [hmac]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-HMAC
@@ -1169,3 +782,5 @@ conduct](CODE_OF_CONDUCT.md).
1169
782
  [rodauth-model]: https://github.com/janko/rodauth-model
1170
783
  [JSON API]: https://github.com/janko/rodauth-rails/wiki/JSON-API
1171
784
  [inheritance]: http://rodauth.jeremyevans.net/rdoc/files/doc/guides/share_configuration_rdoc.html
785
+ [library]: https://github.com/jeremyevans/rodauth#label-Using+Rodauth+as+a+Library
786
+ [restoring defaults]: https://github.com/janko/rodauth-rails/wiki/Restoring-Rodauth-Defaults
@@ -66,7 +66,7 @@ module Rodauth
66
66
  end
67
67
 
68
68
  def create_fixtures
69
- generator_options = ::Rails.application.config.generators.options
69
+ generator_options = ::Rails.configuration.generators.options
70
70
  if generator_options[:test_unit][:fixture] && generator_options[:test_unit][:fixture_replacement].nil?
71
71
  test_dir = generator_options[:rails][:test_framework] == :rspec ? "spec" : "test"
72
72
  template "test/fixtures/accounts.yml", "#{test_dir}/fixtures/#{table_prefix.pluralize}.yml"
@@ -101,17 +101,21 @@ module Rodauth
101
101
  options[:argon2]
102
102
  end
103
103
 
104
+ def primary_key_integer?
105
+ !::Rails.configuration.generators.options.dig(:active_record, :primary_key_type)
106
+ end
107
+
104
108
  def sequel_activerecord_integration?
105
109
  defined?(ActiveRecord::Railtie) &&
106
110
  (!defined?(Sequel) || Sequel::DATABASES.empty?)
107
111
  end
108
112
 
109
113
  def session_store?
110
- !!::Rails.application.config.session_store
114
+ !!::Rails.configuration.session_store
111
115
  end
112
116
 
113
117
  def api_only?
114
- ::Rails.application.config.api_only
118
+ ::Rails.configuration.api_only
115
119
  end
116
120
 
117
121
  def sequel_adapter
@@ -120,7 +120,7 @@ module Rodauth
120
120
  end
121
121
 
122
122
  def primary_key_type(key = :id)
123
- generators = ::Rails.application.config.generators
123
+ generators = ::Rails.configuration.generators
124
124
  column_type = generators.options[:active_record][:primary_key_type]
125
125
 
126
126
  if key
@@ -20,6 +20,9 @@ class RodauthMain < Rodauth::Rails::Auth
20
20
  db Sequel.<%= sequel_adapter %>(extensions: :activerecord_connection, keep_reference: false)
21
21
  <% end -%>
22
22
 
23
+ # Avoid DB query that checks accounts table schema at boot time.
24
+ convert_token_id_to_integer? <%= primary_key_integer? %>
25
+
23
26
  <% end -%>
24
27
  # Change prefix of table and foreign key column names from default "account"
25
28
  <% if table -%>
@@ -46,7 +49,7 @@ class RodauthMain < Rodauth::Rails::Auth
46
49
  <% if argon2? -%>
47
50
 
48
51
  # Use a rotatable password pepper when hashing passwords with Argon2.
49
- # argon2_secret "<SECRET_KEY>"
52
+ # argon2_secret { hmac_secret }
50
53
 
51
54
  # Since we're using argon2, prevent loading the bcrypt gem to save memory.
52
55
  require_bcrypt? false
@@ -54,7 +57,7 @@ class RodauthMain < Rodauth::Rails::Auth
54
57
  <% if jwt? -%>
55
58
 
56
59
  # Set JWT secret, which is used to cryptographically protect the token.
57
- jwt_secret "<%= SecureRandom.hex(64) %>"
60
+ jwt_secret { hmac_secret }
58
61
  <% end -%>
59
62
  <% if json? || jwt? -%>
60
63
 
@@ -72,7 +75,7 @@ class RodauthMain < Rodauth::Rails::Auth
72
75
  # Specify the controller used for view rendering, CSRF, and callbacks.
73
76
  rails_controller { RodauthController }
74
77
 
75
- # Set in Rodauth controller instance with the title of the current page.
78
+ # Make built-in page titles accessible in your views via an instance variable.
76
79
  title_instance_variable :@page_title
77
80
 
78
81
  # Store account status in an integer column without foreign key constraint.
@@ -86,6 +89,7 @@ class RodauthMain < Rodauth::Rails::Auth
86
89
 
87
90
  # Change some default param keys.
88
91
  login_param "email"
92
+ login_confirm_param "email-confirm"
89
93
  # password_confirm_param "confirm_password"
90
94
 
91
95
  # Redirect back to originally requested location after authentication.
@@ -1,6 +1,6 @@
1
1
  <% if defined?(ActiveRecord::Railtie) -%>
2
2
  class <%= table_prefix.camelize %> < ApplicationRecord
3
- include Rodauth::Rails.model
3
+ include Rodauth::Model(RodauthMain)
4
4
  <% if ActiveRecord.version >= Gem::Version.new("7.0") -%>
5
5
  enum :status, unverified: 1, verified: 2, closed: 3
6
6
  <% else -%>
@@ -9,7 +9,7 @@ class <%= table_prefix.camelize %> < ApplicationRecord
9
9
  end
10
10
  <% else -%>
11
11
  class <%= table_prefix.camelize %> < Sequel::Model
12
- include Rodauth::Rails.model
12
+ include Rodauth::Model(RodauthMain)
13
13
  plugin :enum
14
14
  enum :status, unverified: 1, verified: 2, closed: 3
15
15
  end
@@ -41,6 +41,7 @@ module Rodauth
41
41
  recovery_codes: %w[recovery_codes add_recovery_codes recovery_auth],
42
42
  webauthn: %w[webauthn_setup webauthn_auth webauthn_remove],
43
43
  webauthn_autofill: %w[webauthn_autofill],
44
+ confirm_password: %w[confirm_password],
44
45
  }
45
46
 
46
47
  def create_views
@@ -120,7 +121,7 @@ module Rodauth
120
121
  end
121
122
 
122
123
  def tailwind?
123
- ::Rails.application.config.generators.options[:rails][:template_engine] == :tailwindcss ||
124
+ ::Rails.configuration.generators.options[:rails][:template_engine] == :tailwindcss ||
124
125
  options[:css]&.downcase&.start_with?("tailwind")
125
126
  end
126
127
  end
@@ -5,7 +5,7 @@ module Rodauth
5
5
  module Rails
6
6
  # The superclass for creating a Rodauth middleware.
7
7
  class App < Roda
8
- plugin :middleware, forward_response_headers: true do |middleware|
8
+ plugin :middleware, forward_response_headers: true, next_if_not_found: true do |middleware|
9
9
  middleware.class_eval do
10
10
  def self.inspect
11
11
  "#{superclass}::Middleware"
@@ -54,6 +54,10 @@ module Rodauth
54
54
  ::Rails.application.routes.url_helpers
55
55
  end
56
56
 
57
+ def rails_cookies
58
+ rails_request.cookie_jar
59
+ end
60
+
57
61
  def rails_request
58
62
  ActionDispatch::Request.new(env)
59
63
  end
@@ -77,7 +81,7 @@ module Rodauth
77
81
  if prefix.present? && remaining_path == path_info
78
82
  on prefix[1..-1] do
79
83
  super
80
- pass # forward other {prefix}/* requests downstream
84
+ pass
81
85
  end
82
86
  else
83
87
  super
@@ -32,7 +32,7 @@ module Rodauth
32
32
  end
33
33
 
34
34
  def rails_controller
35
- if only_json? && ::Rails.application.config.api_only
35
+ if only_json? && ::Rails.configuration.api_only
36
36
  ActionController::API
37
37
  else
38
38
  ActionController::Base
@@ -47,7 +47,13 @@ module Rodauth
47
47
  raise Error, "cannot infer account model, please set `rails_account_model` in your rodauth configuration"
48
48
  end
49
49
 
50
- delegate :rails_routes, :rails_request, to: :scope
50
+ delegate :rails_routes, :rails_cookies, :rails_request, to: :scope
51
+
52
+ def session
53
+ super
54
+ rescue Roda::RodaError
55
+ fail Rodauth::Rails::Error, "There is no session middleware configured, see instructions on how to add it: https://guides.rubyonrails.org/api_app.html#using-session-middlewares"
56
+ end
51
57
 
52
58
  private
53
59
 
@@ -47,7 +47,7 @@ module Rodauth
47
47
  def rails_url_options
48
48
  return nil unless defined?(ActionMailer)
49
49
 
50
- ::Rails.application.config.action_mailer.default_url_options or
50
+ ::Rails.configuration.action_mailer.default_url_options or
51
51
  fail Error, "There is no information to set the URL host from. Please set config.action_mailer.default_url_options in your Rails application, or configure #domain and #base_url in your Rodauth configuration."
52
52
  end
53
53
  end
@@ -28,6 +28,12 @@ module Rodauth
28
28
  super.html_safe
29
29
  end
30
30
 
31
+ if defined?(::Turbo)
32
+ def turbo_stream
33
+ rails_controller_instance.send(:turbo_stream)
34
+ end
35
+ end
36
+
31
37
  private
32
38
 
33
39
  # Calls the Rails renderer, returning nil if a template is missing.
@@ -21,9 +21,9 @@ module Rodauth
21
21
 
22
22
  # Check whether it's a request to an asset managed by Sprockets or Propshaft.
23
23
  def asset_request?(env)
24
- return false unless ::Rails.application.config.respond_to?(:assets)
24
+ return false unless ::Rails.configuration.respond_to?(:assets)
25
25
 
26
- env["PATH_INFO"] =~ %r(\A/{0,2}#{::Rails.application.config.assets.prefix})
26
+ env["PATH_INFO"] =~ %r(\A/{0,2}#{::Rails.configuration.assets.prefix})
27
27
  end
28
28
  end
29
29
  end
@@ -35,6 +35,10 @@ module Rodauth
35
35
 
36
36
  response
37
37
  end
38
+
39
+ def rodauth(name = nil)
40
+ @controller.rodauth(name)
41
+ end
38
42
  end
39
43
  end
40
44
  end
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "1.11.0"
3
+ VERSION = "1.13.0"
4
4
  end
5
5
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.add_dependency "railties", ">= 5.0", "< 8"
20
20
  spec.add_dependency "rodauth", "~> 2.30"
21
- spec.add_dependency "roda", "~> 3.55"
21
+ spec.add_dependency "roda", "~> 3.73"
22
22
  spec.add_dependency "sequel-activerecord_connection", "~> 1.1"
23
23
  spec.add_dependency "rodauth-model", "~> 0.2"
24
24
  spec.add_dependency "tilt"
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.11.0
4
+ version: 1.13.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: 2023-08-21 00:00:00.000000000 Z
11
+ date: 2023-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '3.55'
53
+ version: '3.73'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '3.55'
60
+ version: '3.73'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: sequel-activerecord_connection
63
63
  requirement: !ruby/object:Gem::Requirement