rodauth-rails 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -1
  3. data/README.md +68 -8
  4. data/lib/generators/rodauth/install_generator.rb +26 -20
  5. data/lib/generators/rodauth/migration/account_expiration.erb +7 -0
  6. data/lib/generators/rodauth/migration/active_sessions.erb +7 -0
  7. data/lib/generators/rodauth/migration/audit_logging.erb +16 -0
  8. data/lib/generators/rodauth/migration/base.erb +19 -0
  9. data/lib/generators/rodauth/migration/disallow_password_reuse.erb +5 -0
  10. data/lib/generators/rodauth/migration/email_auth.erb +7 -0
  11. data/lib/generators/rodauth/migration/jwt_refresh.erb +7 -0
  12. data/lib/generators/rodauth/migration/lockout.erb +11 -0
  13. data/lib/generators/rodauth/migration/otp.erb +7 -0
  14. data/lib/generators/rodauth/migration/password_expiration.erb +5 -0
  15. data/lib/generators/rodauth/migration/recovery_codes.erb +6 -0
  16. data/lib/generators/rodauth/migration/remember.erb +6 -0
  17. data/lib/generators/rodauth/migration/reset_password.erb +7 -0
  18. data/lib/generators/rodauth/migration/single_session.erb +5 -0
  19. data/lib/generators/rodauth/migration/sms_codes.erb +8 -0
  20. data/lib/generators/rodauth/migration/verify_account.erb +7 -0
  21. data/lib/generators/rodauth/migration/verify_login_change.erb +7 -0
  22. data/lib/generators/rodauth/migration/webauthn.erb +12 -0
  23. data/lib/generators/rodauth/migration_generator.rb +32 -0
  24. data/lib/generators/rodauth/migration_helpers.rb +69 -0
  25. data/lib/generators/rodauth/templates/app/lib/rodauth_app.rb +4 -0
  26. data/lib/generators/rodauth/templates/config/initializers/sequel.rb +1 -5
  27. data/lib/generators/rodauth/templates/db/migrate/create_rodauth.rb +2 -176
  28. data/lib/rodauth/rails/railtie.rb +6 -0
  29. data/lib/rodauth/rails/tasks.rake +32 -0
  30. data/lib/rodauth/rails/version.rb +1 -1
  31. metadata +23 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 230b201ad8b9f7c27a9ca00db1a27b4166b7ca0d202f32651fc15ff663bb860e
4
- data.tar.gz: b6b7205916994f829f8eb74c76d8b6172c52339b157f464afd2cd9bfa96f3f25
3
+ metadata.gz: f0d00b7ad2f6198fff3a5cc3c720c6f30d9296898e3fd764ddf7408e36232a6d
4
+ data.tar.gz: 9ba008116fc5521c98ed62dda5b1f6b2eccd733d06ccb0a2c5b9b4db8df94539
5
5
  SHA512:
6
- metadata.gz: fc5645e124796a66c59c51b3b1ab2f1a3b9d7168b53f0703543e42187bb29470d09d3b1103e543dad66ba9a7f940bd469383d767c7acf8fc1d1c8ac7675848e9
7
- data.tar.gz: 89cfd6289466b276240ffbb1111fef0b4274ae2479f5a1dbdaaa193333093508ddc692f47e7a8d57ffeafe70a7d25039371a7ebd88646d962f63f577039afc9c
6
+ metadata.gz: 848873e599cfb8dc8a5d274ac5fec5987cf4c895c77757a4b21529ddcd9a635ba8086c037f55c55ef097ae926549234e5abebb97a5300f0ead6118927d737d91
7
+ data.tar.gz: aa75fb48217e79c40000cf1f226f36a65fdffdcb764233572ae45341b7ab9dd2f1d8f8470e593d8260495962b1b5c352e62d0d5e71fed0cb96891da93a0f344c
@@ -1,4 +1,14 @@
1
- # 0.4.2 (2020-11-08)
1
+ ## 0.5.0 (2020-11-16)
2
+
3
+ * Support more Active Record adapters in `rodauth:install` generator (@janko)
4
+
5
+ * Add `rodauth:migration` generator for creating tables of specified features (@janko)
6
+
7
+ * Use UUIDs for primary keys if so configured in Rails generators (@janko)
8
+
9
+ * Add `rodauth:routes` rake task for printing routes handled by Rodauth middleware (@janko)
10
+
11
+ ## 0.4.2 (2020-11-08)
2
12
 
3
13
  * Drop support for Ruby 2.2 (@janko)
4
14
 
data/README.md CHANGED
@@ -54,7 +54,6 @@ class CreateRodauth < ActiveRecord::Migration
54
54
  create_table :account_verification_keys do |t| ... end
55
55
  create_table :account_login_change_keys do |t| ... end
56
56
  create_table :account_remember_keys do |t| ... end
57
- # ...
58
57
  end
59
58
  end
60
59
  ```
@@ -88,7 +87,7 @@ ActiveRecord connection.
88
87
  require "sequel/core"
89
88
 
90
89
  # initialize Sequel and have it reuse Active Record's database connection
91
- DB = Sequel.postgres(extensions: :activerecord_connection)
90
+ DB = Sequel.connect("postgresql://", extensions: :activerecord_connection)
92
91
  ```
93
92
 
94
93
  ### Rodauth app
@@ -121,7 +120,7 @@ class RodauthController < ApplicationController
121
120
  end
122
121
  ```
123
122
 
124
- ### Account Model
123
+ ### Account model
125
124
 
126
125
  Rodauth stores user accounts in the `accounts` table, so the generator will
127
126
  also create an `Account` model for custom use.
@@ -134,8 +133,30 @@ end
134
133
 
135
134
  ## Getting started
136
135
 
137
- Let's start by adding some basic authentication navigation links to our home
138
- page:
136
+ First, let's see what routes our Rodauth middleware will handle:
137
+
138
+ ```sh
139
+ $ rails rodauth:routes
140
+ ```
141
+ ```
142
+ Routes handled by RodauthApp:
143
+
144
+ /login rodauth.login_path
145
+ /create-account rodauth.create_account_path
146
+ /verify-account-resend rodauth.verify_account_resend_path
147
+ /verify-account rodauth.verify_account_path
148
+ /change-password rodauth.change_password_path
149
+ /change-login rodauth.change_login_path
150
+ /logout rodauth.logout_path
151
+ /remember rodauth.remember_path
152
+ /reset-password-request rodauth.reset_password_request_path
153
+ /reset-password rodauth.reset_password_path
154
+ /verify-login-change rodauth.verify_login_change_path
155
+ /close-account rodauth.close_account_path
156
+ ```
157
+
158
+ We can use this information to add some basic authentication navigation links
159
+ to our home page:
139
160
 
140
161
  ```erb
141
162
  <ul>
@@ -265,7 +286,7 @@ $ rails generate rodauth:views --all
265
286
  ```
266
287
 
267
288
  You can also tell the generator to create views into another directory (in this
268
- case don't forget to rename the Rodauth controller accordingly).
289
+ case make sure to rename the Rodauth controller accordingly).
269
290
 
270
291
  ```sh
271
292
  # generates views into app/views/authentication
@@ -300,8 +321,8 @@ end
300
321
 
301
322
  ### Mailer
302
323
 
303
- Rodauth may send emails as part of the authentication flow. Most email settings
304
- can be customized:
324
+ Depending on the features you've enabled, Rodauth may send emails as part of
325
+ the authentication flow. Most email settings can be customized:
305
326
 
306
327
  ```rb
307
328
  # app/lib/rodauth_app.rb
@@ -385,6 +406,25 @@ class RodauthApp < Rodauth::Rails::App
385
406
  end
386
407
  ```
387
408
 
409
+ ### Migrations
410
+
411
+ The install generator will have created some default tables, but you can use
412
+ the migration generator to create tables for any additional Rodauth features:
413
+
414
+ ```
415
+ $ rails generate rodauth:migration otp sms_codes recovery_codes
416
+ ```
417
+ ```rb
418
+ # db/migration/*_create_rodauth_otp_sms_codes_recovery_codes.rb
419
+ class CreateRodauthOtpSmsCodesRecoveryCodes < ActiveRecord::Migration
420
+ def change
421
+ create_table :account_otp_keys do |t| ... end
422
+ create_table :account_sms_codes do |t| ... end
423
+ create_table :account_recovery_codes do |t| ... end
424
+ end
425
+ end
426
+ ```
427
+
388
428
  ### JSON API
389
429
 
390
430
  JSON API support in Rodauth is provided by the [JWT feature]. First you'll need
@@ -588,6 +628,26 @@ disables the use of database functions, though you can always turn it back on.
588
628
  use_database_authentication_functions? true
589
629
  ```
590
630
 
631
+ To create the database functions, pass the Sequel database object into the
632
+ Rodauth method for creating database functions:
633
+
634
+ ```rb
635
+ # db/migrate/*_create_rodauth_database_functions.rb
636
+ class CreateRodauthDatabaseFunctions < ActiveRecord::Migration
637
+ def up
638
+ # ...
639
+ Rodauth.create_database_authentication_functions(DB)
640
+ # ...
641
+ end
642
+
643
+ def down
644
+ # ...
645
+ Rodauth.drop_database_authentication_functions(DB)
646
+ # ...
647
+ end
648
+ end
649
+ ```
650
+
591
651
  ### Account statuses
592
652
 
593
653
  The recommended [Rodauth migration] stores possible account status values in a
@@ -1,6 +1,6 @@
1
1
  require "rails/generators/base"
2
2
  require "rails/generators/active_record/migration"
3
-
3
+ require "generators/rodauth/migration_helpers"
4
4
  require "securerandom"
5
5
 
6
6
  module Rodauth
@@ -8,6 +8,7 @@ module Rodauth
8
8
  module Generators
9
9
  class InstallGenerator < ::Rails::Generators::Base
10
10
  include ::ActiveRecord::Generators::Migration
11
+ include MigrationHelpers
11
12
 
12
13
  source_root "#{__dir__}/templates"
13
14
  namespace "rodauth:install"
@@ -15,7 +16,7 @@ module Rodauth
15
16
  def create_rodauth_migration
16
17
  return unless defined?(ActiveRecord::Base)
17
18
 
18
- migration_template "db/migrate/create_rodauth.rb", File.join(db_migrate_path, "create_rodauth.rb")
19
+ migration_template "db/migrate/create_rodauth.rb"
19
20
  end
20
21
 
21
22
  def create_rodauth_initializer
@@ -24,7 +25,6 @@ module Rodauth
24
25
 
25
26
  def create_sequel_initializer
26
27
  return unless defined?(ActiveRecord::Base)
27
- return unless %w[postgresql mysql2 sqlite3].include?(activerecord_adapter)
28
28
  return if defined?(Sequel) && !Sequel::DATABASES.empty?
29
29
 
30
30
  template "config/initializers/sequel.rb"
@@ -48,39 +48,45 @@ module Rodauth
48
48
 
49
49
  private
50
50
 
51
- def db_migrate_path
52
- return "db/migrate" unless ActiveRecord.version >= Gem::Version.new("5.0")
53
-
54
- super
55
- end
56
-
57
- def migration_version
58
- if ActiveRecord.version >= Gem::Version.new("5.0")
59
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
51
+ def sequel_uri_scheme
52
+ if RUBY_ENGINE == "jruby"
53
+ "jdbc:#{sequel_jdbc_subadapter}"
54
+ else
55
+ sequel_adapter
60
56
  end
61
57
  end
62
58
 
63
59
  def sequel_adapter
64
60
  case activerecord_adapter
65
- when "postgresql" then "postgres#{"ql" if RUBY_ENGINE == "jruby"}"
66
- when "mysql2" then "mysql#{"2" unless RUBY_ENGINE == "jruby"}"
67
- when "sqlite3" then "sqlite"
61
+ when "sqlite3" then "sqlite"
62
+ when "oracle_enhanced" then "oracle" # https://github.com/rsim/oracle-enhanced
63
+ when "sqlserver" then "tinytds" # https://github.com/rails-sqlserver/activerecord-sqlserver-adapter
64
+ else
65
+ activerecord_adapter
68
66
  end
69
67
  end
70
68
 
71
- def activerecord_adapter
72
- if ActiveRecord::Base.respond_to?(:connection_db_config)
73
- ActiveRecord::Base.connection_db_config.adapter
69
+ def sequel_jdbc_subadapter
70
+ case activerecord_adapter
71
+ when "sqlite3" then "sqlite"
72
+ when "oracle_enhanced" then "oracle" # https://github.com/rsim/oracle-enhanced
73
+ when "sqlserver" then "mssql"
74
74
  else
75
- ActiveRecord::Base.connection_config.fetch(:adapter)
75
+ activerecord_adapter
76
76
  end
77
77
  end
78
78
 
79
79
  def api_only?
80
- return false if ::Rails.gem_version < Gem::Version.new("5.0")
80
+ return unless ::Rails.gem_version >= Gem::Version.new("5.0")
81
81
 
82
82
  ::Rails.application.config.api_only
83
83
  end
84
+
85
+ def migration_features
86
+ features = [:base, :reset_password, :verify_account, :verify_login_change]
87
+ features << :remember unless api_only?
88
+ features
89
+ end
84
90
  end
85
91
  end
86
92
  end
@@ -0,0 +1,7 @@
1
+ # Used by the account expiration feature
2
+ create_table :account_activity_times<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.datetime :last_activity_at, null: false
5
+ t.datetime :last_login_at, null: false
6
+ t.datetime :expired_at
7
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the active sessions feature
2
+ create_table :account_active_session_keys, primary_key: [:account_id, :session_id] do |t|
3
+ t.references :account, foreign_key: true<%= primary_key_type(:type) %>
4
+ t.string :session_id
5
+ t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
6
+ t.datetime :last_use, null: false, default: -> { "CURRENT_TIMESTAMP" }
7
+ end
@@ -0,0 +1,16 @@
1
+ # Used by the audit logging feature
2
+ create_table :account_authentication_audit_logs<%= primary_key_type %> do |t|
3
+ t.references :account, foreign_key: true, null: false<%= primary_key_type(:type) %>
4
+ t.datetime :at, null: false, default: -> { "CURRENT_TIMESTAMP" }
5
+ t.text :message, null: false
6
+ <% case activerecord_adapter -%>
7
+ <% when "postgresql" -%>
8
+ t.jsonb :metadata
9
+ <% when "sqlite3", "mysql2" -%>
10
+ t.json :metadata
11
+ <% else -%>
12
+ t.string :metadata
13
+ <% end -%>
14
+ t.index [:account_id, :at], name: "audit_account_at_idx"
15
+ t.index :at, name: "audit_at_idx"
16
+ end
@@ -0,0 +1,19 @@
1
+ <% if activerecord_adapter == "postgresql" -%>
2
+ enable_extension "citext"
3
+
4
+ <% end -%>
5
+ create_table :accounts<%= primary_key_type %> do |t|
6
+ <% case activerecord_adapter -%>
7
+ <% when "postgresql" -%>
8
+ t.citext :email, null: false, index: { unique: true, where: "status IN ('verified', 'unverified')" }
9
+ <% else -%>
10
+ t.string :email, null: false, index: { unique: true }
11
+ <% end -%>
12
+ t.string :status, null: false, default: "verified"
13
+ end
14
+
15
+ # Used if storing password hashes in a separate table (default)
16
+ create_table :account_password_hashes<%= primary_key_type %> do |t|
17
+ t.foreign_key :accounts, column: :id
18
+ t.string :password_hash, null: false
19
+ end
@@ -0,0 +1,5 @@
1
+ # Used by the disallow_password_reuse feature
2
+ create_table :account_previous_password_hashes do |t|
3
+ t.references :account, foreign_key: true<%= primary_key_type(:type) %>
4
+ t.string :password_hash, null: false
5
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the email auth feature
2
+ create_table :account_email_auth_keys<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :key, null: false
5
+ t.datetime :deadline, null: false
6
+ t.datetime :email_last_sent, null: false, default: -> { "CURRENT_TIMESTAMP" }
7
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the jwt refresh feature
2
+ create_table :account_jwt_refresh_keys<%= primary_key_type %> do |t|
3
+ t.references :account, foreign_key: true, null: false<%= primary_key_type(:type) %>
4
+ t.string :key, null: false
5
+ t.datetime :deadline, null: false
6
+ t.index :account_id, name: "account_jwt_rk_account_id_idx"
7
+ end
@@ -0,0 +1,11 @@
1
+ # Used by the lockout feature
2
+ create_table :account_login_failures<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.integer :number, null: false, default: 1
5
+ end
6
+ create_table :account_lockouts<%= primary_key_type %> do |t|
7
+ t.foreign_key :accounts, column: :id
8
+ t.string :key, null: false
9
+ t.datetime :deadline, null: false
10
+ t.datetime :email_last_sent
11
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the otp feature
2
+ create_table :account_otp_keys<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :key, null: false
5
+ t.integer :num_failures, null: false, default: 0
6
+ t.datetime :last_use, null: false, default: -> { "CURRENT_TIMESTAMP" }
7
+ end
@@ -0,0 +1,5 @@
1
+ # Used by the password expiration feature
2
+ create_table :account_password_change_times<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.datetime :changed_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
5
+ end
@@ -0,0 +1,6 @@
1
+ # Used by the recovery codes feature
2
+ create_table :account_recovery_codes, primary_key: [:id, :code] do |t|
3
+ t.column :id, :<%= primary_key_type(nil) || :bigint %>
4
+ t.foreign_key :accounts, column: :id
5
+ t.string :code
6
+ end
@@ -0,0 +1,6 @@
1
+ # Used by the remember me feature
2
+ create_table :account_remember_keys<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :key, null: false
5
+ t.datetime :deadline, null: false
6
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the password reset feature
2
+ create_table :account_password_reset_keys<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :key, null: false
5
+ t.datetime :deadline, null: false
6
+ t.datetime :email_last_sent, null: false, default: -> { "CURRENT_TIMESTAMP" }
7
+ end
@@ -0,0 +1,5 @@
1
+ # Used by the single session feature
2
+ create_table :account_session_keys<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :key, null: false
5
+ end
@@ -0,0 +1,8 @@
1
+ # Used by the sms codes feature
2
+ create_table :account_sms_codes<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :phone_number, null: false
5
+ t.integer :num_failures
6
+ t.string :code
7
+ t.datetime :code_issued_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
8
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the account verification feature
2
+ create_table :account_verification_keys<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :key, null: false
5
+ t.datetime :requested_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
6
+ t.datetime :email_last_sent, null: false, default: -> { "CURRENT_TIMESTAMP" }
7
+ end
@@ -0,0 +1,7 @@
1
+ # Used by the verify login change feature
2
+ create_table :account_login_change_keys<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :key, null: false
5
+ t.string :login, null: false
6
+ t.datetime :deadline, null: false
7
+ end
@@ -0,0 +1,12 @@
1
+ # Used by the webauthn feature
2
+ create_table :account_webauthn_user_ids<%= primary_key_type %> do |t|
3
+ t.foreign_key :accounts, column: :id
4
+ t.string :webauthn_id, null: false
5
+ end
6
+ create_table :account_webauthn_keys, primary_key: [:account_id, :webauthn_id] do |t|
7
+ t.references :account, foreign_key: true<%= primary_key_type(:type) %>
8
+ t.string :webauthn_id
9
+ t.string :public_key, null: false
10
+ t.integer :sign_count, null: false
11
+ t.datetime :last_use, null: false, default: -> { "CURRENT_TIMESTAMP" }
12
+ end
@@ -0,0 +1,32 @@
1
+ require "rails/generators/base"
2
+ require "rails/generators/active_record/migration"
3
+ require "generators/rodauth/migration_helpers"
4
+
5
+ module Rodauth
6
+ module Rails
7
+ module Generators
8
+ class MigrationGenerator < ::Rails::Generators::Base
9
+ include ::ActiveRecord::Generators::Migration
10
+ include MigrationHelpers
11
+
12
+ source_root "#{__dir__}/templates"
13
+ namespace "rodauth:migration"
14
+
15
+ argument :features, optional: true, type: :array,
16
+ desc: "Rodauth features to create tables for (otp, sms_codes, single_session, account_expiration etc.)",
17
+ default: %w[]
18
+
19
+ def create_rodauth_migration
20
+ return unless defined?(ActiveRecord::Base)
21
+ return if features.empty?
22
+
23
+ migration_template "db/migrate/create_rodauth.rb", "create_rodauth_#{features.join("_")}.rb"
24
+ end
25
+
26
+ def migration_features
27
+ features
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,69 @@
1
+ require "erb"
2
+
3
+ module Rodauth
4
+ module Rails
5
+ module Generators
6
+ module MigrationHelpers
7
+ attr_reader :migration_class_name
8
+
9
+ def migration_template(source, destination = File.basename(source))
10
+ @migration_class_name = destination.chomp(".rb").camelize
11
+
12
+ super source, File.join(db_migrate_path, destination)
13
+ end
14
+
15
+ private
16
+
17
+ def migration_content
18
+ migration_features
19
+ .select { |feature| File.exist?("#{__dir__}/migration/#{feature}.erb") }
20
+ .map { |feature| File.read("#{__dir__}/migration/#{feature}.erb") }
21
+ .map { |content| erb_eval(content) }
22
+ .join("\n")
23
+ .indent(4)
24
+ end
25
+
26
+ def activerecord_adapter
27
+ if ActiveRecord::Base.respond_to?(:connection_db_config)
28
+ ActiveRecord::Base.connection_db_config.adapter
29
+ else
30
+ ActiveRecord::Base.connection_config.fetch(:adapter)
31
+ end
32
+ end
33
+
34
+ def migration_version
35
+ return unless ActiveRecord.version >= Gem::Version.new("5.0")
36
+
37
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
38
+ end
39
+
40
+ def db_migrate_path
41
+ return "db/migrate" unless ActiveRecord.version >= Gem::Version.new("5.0")
42
+
43
+ super
44
+ end
45
+
46
+ def primary_key_type(key = :id)
47
+ generators = ::Rails.application.config.generators
48
+ column_type = generators.options[:active_record][:primary_key_type]
49
+
50
+ return unless column_type
51
+
52
+ if key
53
+ ", #{key}: :#{column_type}"
54
+ else
55
+ column_type
56
+ end
57
+ end
58
+
59
+ def erb_eval(content)
60
+ if ERB.version[/\d+\.\d+\.\d+/].to_s >= "2.2.0"
61
+ ERB.new(content, trim_mode: "-").result(binding)
62
+ else
63
+ ERB.new(content, 0, "-").result(binding)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -11,6 +11,10 @@ class RodauthApp < Rodauth::Rails::App
11
11
  # http://rodauth.jeremyevans.net/documentation.html
12
12
 
13
13
  # ==> General
14
+ # The secret key used for hashing public-facing tokens for various features.
15
+ # Defaults to Rails `secret_key_base`, but you can use your own secret key.
16
+ # hmac_secret "<%= SecureRandom.hex(64) %>"
17
+
14
18
  <% unless api_only? -%>
15
19
  # Specify the controller used for view rendering and CSRF verification.
16
20
  rails_controller { RodauthController }
@@ -1,8 +1,4 @@
1
1
  require "sequel/core"
2
2
 
3
3
  # initialize Sequel and have it reuse Active Record's database connection
4
- <% if RUBY_ENGINE == "jruby" -%>
5
- DB = Sequel.connect("jdbc:<%= sequel_adapter %>://", extensions: :activerecord_connection)
6
- <% else -%>
7
- DB = Sequel.<%= sequel_adapter %>(extensions: :activerecord_connection)
8
- <% end -%>
4
+ DB = Sequel.connect("<%= sequel_uri_scheme %>://", extensions: :activerecord_connection)
@@ -1,179 +1,5 @@
1
- class CreateRodauth < ActiveRecord::Migration<%= migration_version %>
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- <% if activerecord_adapter == "postgresql" -%>
4
- enable_extension "citext"
5
-
6
- <% end -%>
7
- create_table :accounts do |t|
8
- <% case activerecord_adapter -%>
9
- <% when "postgresql" -%>
10
- t.citext :email, null: false, index: { unique: true, where: "status IN ('verified', 'unverified')" }
11
- <% else -%>
12
- t.string :email, null: false, index: { unique: true }
13
- <% end -%>
14
- t.string :status, null: false, default: "verified"
15
- end
16
-
17
- # Used if storing password hashes in a separate table (default)
18
- create_table :account_password_hashes do |t|
19
- t.foreign_key :accounts, column: :id
20
- t.string :password_hash, null: false
21
- end
22
-
23
- # Used by the password reset feature
24
- create_table :account_password_reset_keys do |t|
25
- t.foreign_key :accounts, column: :id
26
- t.string :key, null: false
27
- t.datetime :deadline, null: false
28
- t.datetime :email_last_sent, null: false, default: -> { "CURRENT_TIMESTAMP" }
29
- end
30
-
31
- # Used by the account verification feature
32
- create_table :account_verification_keys do |t|
33
- t.foreign_key :accounts, column: :id
34
- t.string :key, null: false
35
- t.datetime :requested_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
36
- t.datetime :email_last_sent, null: false, default: -> { "CURRENT_TIMESTAMP" }
37
- end
38
-
39
- # Used by the verify login change feature
40
- create_table :account_login_change_keys do |t|
41
- t.foreign_key :accounts, column: :id
42
- t.string :key, null: false
43
- t.string :login, null: false
44
- t.datetime :deadline, null: false
45
- end
46
-
47
- <% unless api_only? -%>
48
- # Used by the remember me feature
49
- create_table :account_remember_keys do |t|
50
- t.foreign_key :accounts, column: :id
51
- t.string :key, null: false
52
- t.datetime :deadline, null: false
53
- end
54
- <% else -%>
55
- # # Used by the remember me feature
56
- # create_table :account_remember_keys do |t|
57
- # t.foreign_key :accounts, column: :id
58
- # t.string :key, null: false
59
- # t.datetime :deadline, null: false
60
- # end
61
- <% end -%>
62
-
63
- # # Used by the audit logging feature
64
- # create_table :account_authentication_audit_logs do |t|
65
- # t.references :account, foreign_key: true, null: false
66
- # t.datetime :at, null: false, default: -> { "CURRENT_TIMESTAMP" }
67
- # t.text :message, null: false
68
- <% case activerecord_adapter -%>
69
- <% when "postgresql" -%>
70
- # t.jsonb :metadata
71
- <% when "sqlite3", "mysql2" -%>
72
- # t.json :metadata
73
- <% else -%>
74
- # t.string :metadata
75
- <% end -%>
76
- # t.index [:account_id, :at], name: "audit_account_at_idx"
77
- # t.index :at, name: "audit_at_idx"
78
- # end
79
-
80
- # # Used by the jwt refresh feature
81
- # create_table :account_jwt_refresh_keys do |t|
82
- # t.references :account, foreign_key: true, null: false
83
- # t.string :key, null: false
84
- # t.datetime :deadline, null: false
85
- # t.index :account_id, name: "account_jwt_rk_account_id_idx"
86
- # end
87
-
88
- # # Used by the disallow_password_reuse feature
89
- # create_table :account_previous_password_hashes do |t|
90
- # t.references :account, foreign_key: true
91
- # t.string :password_hash, null: false
92
- # end
93
-
94
- # # Used by the lockout feature
95
- # create_table :account_login_failures do |t|
96
- # t.foreign_key :accounts, column: :id
97
- # t.integer :number, null: false, default: 1
98
- # end
99
- # create_table :account_lockouts do |t|
100
- # t.foreign_key :accounts, column: :id
101
- # t.string :key, null: false
102
- # t.datetime :deadline, null: false
103
- # t.datetime :email_last_sent
104
- # end
105
-
106
- # # Used by the email auth feature
107
- # create_table :account_email_auth_keys do |t|
108
- # t.foreign_key :accounts, column: :id
109
- # t.string :key, null: false
110
- # t.datetime :deadline, null: false
111
- # t.datetime :email_last_sent, null: false, default: -> { "CURRENT_TIMESTAMP" }
112
- # end
113
-
114
- # # Used by the password expiration feature
115
- # create_table :account_password_change_times do |t|
116
- # t.foreign_key :accounts, column: :id
117
- # t.datetime :changed_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
118
- # end
119
-
120
- # # Used by the account expiration feature
121
- # create_table :account_activity_times do |t|
122
- # t.foreign_key :accounts, column: :id
123
- # t.datetime :last_activity_at, null: false
124
- # t.datetime :last_login_at, null: false
125
- # t.datetime :expired_at
126
- # end
127
-
128
- # # Used by the single session feature
129
- # create_table :account_session_keys do |t|
130
- # t.foreign_key :accounts, column: :id
131
- # t.string :key, null: false
132
- # end
133
-
134
- # # Used by the active sessions feature
135
- # create_table :account_active_session_keys, primary_key: [:account_id, :session_id] do |t|
136
- # t.references :account, foreign_key: true
137
- # t.string :session_id
138
- # t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
139
- # t.datetime :last_use, null: false, default: -> { "CURRENT_TIMESTAMP" }
140
- # end
141
-
142
- # # Used by the webauthn feature
143
- # create_table :account_webauthn_user_ids do |t|
144
- # t.foreign_key :accounts, column: :id
145
- # t.string :webauthn_id, null: false
146
- # end
147
- # create_table :account_webauthn_keys, primary_key: [:account_id, :webauthn_id] do |t|
148
- # t.references :account, foreign_key: true
149
- # t.string :webauthn_id
150
- # t.string :public_key, null: false
151
- # t.integer :sign_count, null: false
152
- # t.datetime :last_use, null: false, default: -> { "CURRENT_TIMESTAMP" }
153
- # end
154
-
155
- # # Used by the otp feature
156
- # create_table :account_otp_keys do |t|
157
- # t.foreign_key :accounts, column: :id
158
- # t.string :key, null: false
159
- # t.integer :num_failures, null: false, default: 0
160
- # t.datetime :last_use, null: false, default: -> { "CURRENT_TIMESTAMP" }
161
- # end
162
-
163
- # # Used by the recovery codes feature
164
- # create_table :account_recovery_codes, primary_key: [:id, :code] do |t|
165
- # t.integer :id
166
- # t.foreign_key :accounts, column: :id
167
- # t.string :code
168
- # end
169
-
170
- # # Used by the sms codes feature
171
- # create_table :account_sms_codes do |t|
172
- # t.foreign_key :accounts, column: :id
173
- # t.string :phone_number, null: false
174
- # t.integer :num_failures
175
- # t.string :code
176
- # t.datetime :code_issued_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
177
- # end
3
+ <%= migration_content -%>
178
4
  end
179
5
  end
@@ -1,6 +1,8 @@
1
1
  require "rodauth/rails/middleware"
2
2
  require "rodauth/rails/controller_methods"
3
3
 
4
+ require "rails"
5
+
4
6
  module Rodauth
5
7
  module Rails
6
8
  class Railtie < ::Rails::Railtie
@@ -18,6 +20,10 @@ module Rodauth
18
20
  # Rodauth uses RACK_ENV to set the default bcrypt hash cost
19
21
  ENV["RACK_ENV"] = "test" if ::Rails.env.test?
20
22
  end
23
+
24
+ rake_tasks do
25
+ load "rodauth/rails/tasks.rake"
26
+ end
21
27
  end
22
28
  end
23
29
  end
@@ -0,0 +1,32 @@
1
+ namespace :rodauth do
2
+ task routes: :environment do
3
+ app = Rodauth::Rails.app
4
+
5
+ puts "Routes handled by #{app}:"
6
+ puts
7
+
8
+ app.opts[:rodauths].each do |rodauth_name, rodauth_class|
9
+ route_names = rodauth_class.routes
10
+ .map { |handle_method| handle_method.to_s.sub(/\Ahandle_/, "") }
11
+ .uniq
12
+
13
+ rodauth = rodauth_class.allocate
14
+
15
+ routes = route_names.map do |name|
16
+ [
17
+ rodauth.public_send(:"#{name}_path"),
18
+ "rodauth#{rodauth_name && "(:#{rodauth_name})"}.#{name}_path",
19
+ ]
20
+ end
21
+
22
+ padding = routes.map { |path, _| path.length }.max
23
+
24
+ route_lines = routes.map do |path, code|
25
+ "#{path.ljust(padding)} #{code}"
26
+ end
27
+
28
+ puts " #{route_lines.join("\n ")}"
29
+ puts
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "0.4.2"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
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: 0.4.2
4
+ version: 0.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: 2020-11-08 00:00:00.000000000 Z
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -98,6 +98,26 @@ files:
98
98
  - README.md
99
99
  - lib/generators/rodauth/install_generator.rb
100
100
  - lib/generators/rodauth/mailer_generator.rb
101
+ - lib/generators/rodauth/migration/account_expiration.erb
102
+ - lib/generators/rodauth/migration/active_sessions.erb
103
+ - lib/generators/rodauth/migration/audit_logging.erb
104
+ - lib/generators/rodauth/migration/base.erb
105
+ - lib/generators/rodauth/migration/disallow_password_reuse.erb
106
+ - lib/generators/rodauth/migration/email_auth.erb
107
+ - lib/generators/rodauth/migration/jwt_refresh.erb
108
+ - lib/generators/rodauth/migration/lockout.erb
109
+ - lib/generators/rodauth/migration/otp.erb
110
+ - lib/generators/rodauth/migration/password_expiration.erb
111
+ - lib/generators/rodauth/migration/recovery_codes.erb
112
+ - lib/generators/rodauth/migration/remember.erb
113
+ - lib/generators/rodauth/migration/reset_password.erb
114
+ - lib/generators/rodauth/migration/single_session.erb
115
+ - lib/generators/rodauth/migration/sms_codes.erb
116
+ - lib/generators/rodauth/migration/verify_account.erb
117
+ - lib/generators/rodauth/migration/verify_login_change.erb
118
+ - lib/generators/rodauth/migration/webauthn.erb
119
+ - lib/generators/rodauth/migration_generator.rb
120
+ - lib/generators/rodauth/migration_helpers.rb
101
121
  - lib/generators/rodauth/templates/app/controllers/rodauth_controller.rb
102
122
  - lib/generators/rodauth/templates/app/lib/rodauth_app.rb
103
123
  - lib/generators/rodauth/templates/app/mailers/rodauth_mailer.rb
@@ -175,6 +195,7 @@ files:
175
195
  - lib/rodauth/rails/feature.rb
176
196
  - lib/rodauth/rails/middleware.rb
177
197
  - lib/rodauth/rails/railtie.rb
198
+ - lib/rodauth/rails/tasks.rake
178
199
  - lib/rodauth/rails/version.rb
179
200
  - rodauth-rails.gemspec
180
201
  homepage: https://github.com/janko/rodauth-rails