rodauth-rails 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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