rails_jwt_auth 1.7.3 → 2.0.3

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +188 -89
  3. data/app/controllers/concerns/rails_jwt_auth/authenticable_helper.rb +15 -7
  4. data/app/controllers/concerns/rails_jwt_auth/params_helper.rb +18 -4
  5. data/app/controllers/concerns/rails_jwt_auth/render_helper.rb +10 -2
  6. data/app/controllers/rails_jwt_auth/confirmations_controller.rb +48 -10
  7. data/app/controllers/rails_jwt_auth/invitations_controller.rb +27 -9
  8. data/app/controllers/rails_jwt_auth/profiles_controller.rb +51 -0
  9. data/app/controllers/rails_jwt_auth/reset_passwords_controller.rb +65 -0
  10. data/app/controllers/rails_jwt_auth/sessions_controller.rb +7 -22
  11. data/app/controllers/rails_jwt_auth/{unlocks_controller.rb → unlock_accounts_controller.rb} +2 -2
  12. data/app/mailers/rails_jwt_auth/mailer.rb +23 -28
  13. data/app/models/concerns/rails_jwt_auth/authenticatable.rb +60 -19
  14. data/app/models/concerns/rails_jwt_auth/confirmable.rb +49 -39
  15. data/app/models/concerns/rails_jwt_auth/invitable.rb +46 -72
  16. data/app/models/concerns/rails_jwt_auth/lockable.rb +38 -46
  17. data/app/models/concerns/rails_jwt_auth/recoverable.rb +27 -26
  18. data/app/models/concerns/rails_jwt_auth/trackable.rb +13 -2
  19. data/app/views/rails_jwt_auth/mailer/confirmation_instructions.html.erb +1 -1
  20. data/app/views/rails_jwt_auth/mailer/{send_invitation.html.erb → invitation_instructions.html.erb} +1 -1
  21. data/app/views/rails_jwt_auth/mailer/password_changed_notification.html.erb +3 -0
  22. data/app/views/rails_jwt_auth/mailer/reset_password_instructions.html.erb +1 -1
  23. data/app/views/rails_jwt_auth/mailer/{send_unlock_instructions.html.erb → unlock_instructions.html.erb} +1 -1
  24. data/config/locales/en.yml +6 -6
  25. data/lib/generators/rails_jwt_auth/install_generator.rb +11 -3
  26. data/lib/generators/templates/initializer.rb +43 -29
  27. data/lib/generators/templates/migration.rb +2 -1
  28. data/lib/rails_jwt_auth/jwt_manager.rb +2 -4
  29. data/lib/rails_jwt_auth/session.rb +128 -0
  30. data/lib/rails_jwt_auth/version.rb +1 -1
  31. data/lib/rails_jwt_auth.rb +46 -47
  32. metadata +11 -9
  33. data/app/controllers/rails_jwt_auth/passwords_controller.rb +0 -32
  34. data/app/views/rails_jwt_auth/mailer/set_password_instructions.html.erb +0 -5
  35. /data/app/views/rails_jwt_auth/mailer/{email_changed.html.erb → email_change_requested_notification.html.erb} +0 -0
@@ -0,0 +1,128 @@
1
+ module RailsJwtAuth
2
+ class Session
3
+ attr_reader :user, :errors, :jwt
4
+
5
+ Errors = Struct.new :details # simulate ActiveModel::Errors
6
+
7
+ def initialize(params={})
8
+ @auth_field_value = (params[RailsJwtAuth.auth_field_name] || '').strip
9
+ @auth_field_value.downcase! if RailsJwtAuth.downcase_auth_field
10
+ @password = params[:password]
11
+
12
+ find_user if @auth_field_value.present?
13
+ end
14
+
15
+ def valid?
16
+ validate!
17
+
18
+ !errors?
19
+ end
20
+
21
+ def generate!(request)
22
+ if valid?
23
+ user.clean_reset_password if recoverable?
24
+ user.clean_lock if lockable?
25
+ user.track_session_info(request) if trackable?
26
+ user.load_auth_token
27
+
28
+ unless user.save
29
+ add_error(RailsJwtAuth.model_name.underscore, :invalid)
30
+
31
+ return false
32
+ end
33
+
34
+ generate_jwt(request)
35
+
36
+ true
37
+ else
38
+ user.failed_attempt if lockable?
39
+
40
+ false
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def validate!
47
+ # Can't use ActiveModel::Validations since we have dynamic fields
48
+ @errors = Errors.new({})
49
+
50
+ validate_auth_field_presence
51
+ validate_password_presence
52
+ validate_user_exist
53
+ validate_user_is_confirmed if confirmable?
54
+ validate_user_is_not_locked if lockable?
55
+ validate_user_password unless errors?
56
+ validate_custom
57
+ end
58
+
59
+ def find_user
60
+ @user = RailsJwtAuth.model.where(RailsJwtAuth.auth_field_name => @auth_field_value).first
61
+ end
62
+
63
+ def confirmable?
64
+ @user&.kind_of?(RailsJwtAuth::Confirmable)
65
+ end
66
+
67
+ def lockable?
68
+ @user&.kind_of?(RailsJwtAuth::Lockable)
69
+ end
70
+
71
+ def recoverable?
72
+ @user&.kind_of?(RailsJwtAuth::Recoverable)
73
+ end
74
+
75
+ def trackable?
76
+ @user&.kind_of?(RailsJwtAuth::Trackable)
77
+ end
78
+
79
+ def user?
80
+ @user.present?
81
+ end
82
+
83
+ def field_error(field)
84
+ RailsJwtAuth.avoid_email_errors ? :session : field
85
+ end
86
+
87
+ def validate_auth_field_presence
88
+ add_error(RailsJwtAuth.auth_field_name, :blank) if @auth_field_value.blank?
89
+ end
90
+
91
+ def validate_password_presence
92
+ add_error(:password, :blank) if @password.blank?
93
+ end
94
+
95
+ def validate_user_exist
96
+ add_error(field_error(RailsJwtAuth.auth_field_name), :invalid) unless @user
97
+ end
98
+
99
+ def validate_user_password
100
+ add_error(field_error(:password), :invalid) unless @user.authenticate(@password)
101
+ end
102
+
103
+ def validate_user_is_confirmed
104
+ add_error(RailsJwtAuth.email_field_name, :unconfirmed) unless @user.confirmed?
105
+ end
106
+
107
+ def validate_user_is_not_locked
108
+ add_error(RailsJwtAuth.email_field_name, :locked) if @user.access_locked?
109
+ end
110
+
111
+ def validate_custom
112
+ # allow add custom validations overwriting this method
113
+ end
114
+
115
+ def add_error(field, detail)
116
+ @errors.details[field.to_sym] ||= []
117
+ @errors.details[field.to_sym].push({error: detail})
118
+ end
119
+
120
+ def errors?
121
+ @errors.details.any?
122
+ end
123
+
124
+ def generate_jwt(request)
125
+ @jwt = JwtManager.encode(user.to_token_payload(request))
126
+ end
127
+ end
128
+ end
@@ -1,3 +1,3 @@
1
1
  module RailsJwtAuth
2
- VERSION = '1.7.3'
2
+ VERSION = '2.0.3'
3
3
  end
@@ -1,15 +1,16 @@
1
+ require 'active_support/core_ext/integer/time'
1
2
  require 'bcrypt'
2
3
 
3
4
  require 'rails_jwt_auth/engine'
4
5
  require 'rails_jwt_auth/jwt_manager'
6
+ require 'rails_jwt_auth/session'
5
7
 
6
8
  module RailsJwtAuth
7
- InvalidEmailField = Class.new(StandardError)
8
- InvalidAuthField = Class.new(StandardError)
9
9
  NotConfirmationsUrl = Class.new(StandardError)
10
10
  NotInvitationsUrl = Class.new(StandardError)
11
11
  NotResetPasswordsUrl = Class.new(StandardError)
12
- NotSetPasswordsUrl = Class.new(StandardError)
12
+ NotUnlockUrl = Class.new(StandardError)
13
+ InvalidJwtPayload = Class.new(StandardError)
13
14
 
14
15
  mattr_accessor :model_name
15
16
  self.model_name = 'User'
@@ -20,6 +21,12 @@ module RailsJwtAuth
20
21
  mattr_accessor :email_field_name
21
22
  self.email_field_name = 'email'
22
23
 
24
+ mattr_accessor :email_regex
25
+ self.email_regex = URI::MailTo::EMAIL_REGEXP
26
+
27
+ mattr_accessor :downcase_auth_field
28
+ self.downcase_auth_field = false
29
+
23
30
  mattr_accessor :jwt_expiration_time
24
31
  self.jwt_expiration_time = 7.days
25
32
 
@@ -29,11 +36,17 @@ module RailsJwtAuth
29
36
  mattr_accessor :simultaneous_sessions
30
37
  self.simultaneous_sessions = 2
31
38
 
39
+ mattr_accessor :mailer_name
40
+ self.mailer_name = 'RailsJwtAuth::Mailer'
41
+
32
42
  mattr_accessor :mailer_sender
33
43
  self.mailer_sender = 'initialize-mailer_sender@example.com'
34
44
 
35
- mattr_accessor :send_email_changed_notification
36
- self.send_email_changed_notification = true
45
+ mattr_accessor :send_email_change_requested_notification
46
+ self.send_email_change_requested_notification = true
47
+
48
+ mattr_accessor :send_password_changed_notification
49
+ self.send_password_changed_notification = true
37
50
 
38
51
  mattr_accessor :confirmation_expiration_time
39
52
  self.confirmation_expiration_time = 1.day
@@ -44,18 +57,6 @@ module RailsJwtAuth
44
57
  mattr_accessor :invitation_expiration_time
45
58
  self.invitation_expiration_time = 2.days
46
59
 
47
- mattr_accessor :confirmations_url
48
- self.confirmations_url = nil
49
-
50
- mattr_accessor :reset_passwords_url
51
- self.reset_passwords_url = nil
52
-
53
- mattr_accessor :set_passwords_url
54
- self.set_passwords_url = nil
55
-
56
- mattr_accessor :invitations_url
57
- self.invitations_url = nil
58
-
59
60
  mattr_accessor :deliver_later
60
61
  self.deliver_later = false
61
62
 
@@ -72,51 +73,49 @@ module RailsJwtAuth
72
73
  self.unlock_in = 60.minutes
73
74
 
74
75
  mattr_accessor :reset_attempts_in
75
- self.unlock_in = 60.minutes
76
+ self.reset_attempts_in = 60.minutes
76
77
 
77
- mattr_accessor :unlock_url
78
- self.unlock_url = nil
78
+ mattr_accessor :confirm_email_url
79
+ self.confirm_email_url = nil
79
80
 
80
- def self.model
81
- model_name.constantize
82
- end
81
+ mattr_accessor :reset_password_url
82
+ self.reset_password_url = nil
83
83
 
84
- def self.table_name
85
- model_name.underscore.pluralize
86
- end
84
+ mattr_accessor :accept_invitation_url
85
+ self.accept_invitation_url = nil
86
+
87
+ mattr_accessor :unlock_account_url
88
+ self.unlock_account_url = nil
89
+
90
+ mattr_accessor :avoid_email_errors
91
+ self.avoid_email_errors = true
87
92
 
88
93
  def self.setup
89
94
  yield self
90
95
  end
91
96
 
92
- def self.auth_field_name!
93
- field_name = RailsJwtAuth.auth_field_name
94
- klass = RailsJwtAuth.model
95
-
96
- unless field_name.present? &&
97
- (klass.respond_to?(:column_names) && klass.column_names.include?(field_name) ||
98
- klass.respond_to?(:fields) && klass.fields[field_name])
99
- raise RailsJwtAuth::InvalidAuthField
100
- end
101
-
102
- field_name
97
+ def self.model
98
+ model_name.constantize
103
99
  end
104
100
 
105
- def self.email_field_name!
106
- field_name = RailsJwtAuth.email_field_name
107
- klass = RailsJwtAuth.model
101
+ def self.mailer
102
+ mailer_name.constantize
103
+ end
108
104
 
109
- unless field_name.present? &&
110
- (klass.respond_to?(:column_names) && klass.column_names.include?(field_name) ||
111
- klass.respond_to?(:fields) && klass.fields[field_name])
112
- raise RailsJwtAuth::InvalidEmailField
113
- end
105
+ def self.table_name
106
+ model_name.underscore.pluralize
107
+ end
114
108
 
115
- field_name
109
+ # Thanks to https://github.com/heartcombo/devise/blob/master/lib/devise.rb#L496
110
+ def self.friendly_token(length = 24)
111
+ # To calculate real characters, we must perform this operation.
112
+ # See SecureRandom.urlsafe_base64
113
+ rlength = (length * 3 / 4) - 1
114
+ SecureRandom.urlsafe_base64(rlength, true).tr('lIO0', 'sxyz')
116
115
  end
117
116
 
118
117
  def self.send_email(method, user)
119
- mailer = RailsJwtAuth::Mailer.with(user_id: user.id.to_s).public_send(method)
118
+ mailer = RailsJwtAuth.mailer.with(user_id: user.id.to_s).public_send(method)
120
119
  RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver
121
120
  end
122
121
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_jwt_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.3
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - rjurado
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-15 00:00:00.000000000 Z
11
+ date: 2021-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt
@@ -67,10 +67,11 @@ files:
67
67
  - app/controllers/concerns/rails_jwt_auth/render_helper.rb
68
68
  - app/controllers/rails_jwt_auth/confirmations_controller.rb
69
69
  - app/controllers/rails_jwt_auth/invitations_controller.rb
70
- - app/controllers/rails_jwt_auth/passwords_controller.rb
70
+ - app/controllers/rails_jwt_auth/profiles_controller.rb
71
71
  - app/controllers/rails_jwt_auth/registrations_controller.rb
72
+ - app/controllers/rails_jwt_auth/reset_passwords_controller.rb
72
73
  - app/controllers/rails_jwt_auth/sessions_controller.rb
73
- - app/controllers/rails_jwt_auth/unlocks_controller.rb
74
+ - app/controllers/rails_jwt_auth/unlock_accounts_controller.rb
74
75
  - app/controllers/unauthorized_controller.rb
75
76
  - app/mailers/rails_jwt_auth/mailer.rb
76
77
  - app/models/concerns/rails_jwt_auth/authenticatable.rb
@@ -80,11 +81,11 @@ files:
80
81
  - app/models/concerns/rails_jwt_auth/recoverable.rb
81
82
  - app/models/concerns/rails_jwt_auth/trackable.rb
82
83
  - app/views/rails_jwt_auth/mailer/confirmation_instructions.html.erb
83
- - app/views/rails_jwt_auth/mailer/email_changed.html.erb
84
+ - app/views/rails_jwt_auth/mailer/email_change_requested_notification.html.erb
85
+ - app/views/rails_jwt_auth/mailer/invitation_instructions.html.erb
86
+ - app/views/rails_jwt_auth/mailer/password_changed_notification.html.erb
84
87
  - app/views/rails_jwt_auth/mailer/reset_password_instructions.html.erb
85
- - app/views/rails_jwt_auth/mailer/send_invitation.html.erb
86
- - app/views/rails_jwt_auth/mailer/send_unlock_instructions.html.erb
87
- - app/views/rails_jwt_auth/mailer/set_password_instructions.html.erb
88
+ - app/views/rails_jwt_auth/mailer/unlock_instructions.html.erb
88
89
  - config/locales/en.yml
89
90
  - lib/generators/rails_jwt_auth/install_generator.rb
90
91
  - lib/generators/rails_jwt_auth/migrate_generator.rb
@@ -93,6 +94,7 @@ files:
93
94
  - lib/rails_jwt_auth.rb
94
95
  - lib/rails_jwt_auth/engine.rb
95
96
  - lib/rails_jwt_auth/jwt_manager.rb
97
+ - lib/rails_jwt_auth/session.rb
96
98
  - lib/rails_jwt_auth/spec_helpers.rb
97
99
  - lib/rails_jwt_auth/version.rb
98
100
  homepage: https://github.com/rjurado01/rails_jwt_auth
@@ -114,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
116
  - !ruby/object:Gem::Version
115
117
  version: '0'
116
118
  requirements: []
117
- rubygems_version: 3.1.2
119
+ rubygems_version: 3.1.4
118
120
  signing_key:
119
121
  specification_version: 4
120
122
  summary: Rails jwt authentication.
@@ -1,32 +0,0 @@
1
- module RailsJwtAuth
2
- class PasswordsController < ApplicationController
3
- include ParamsHelper
4
- include RenderHelper
5
-
6
- def create
7
- email_field = RailsJwtAuth.email_field_name
8
-
9
- if password_create_params[email_field].blank?
10
- return render_422(email_field => [{error: :blank}])
11
- end
12
-
13
- user = RailsJwtAuth.model.where(
14
- email_field => password_create_params[email_field].to_s.strip.downcase
15
- ).first
16
-
17
- return render_422(email_field => [{error: :not_found}]) unless user
18
-
19
- user.send_reset_password_instructions ? render_204 : render_422(user.errors.details)
20
- end
21
-
22
- def update
23
- return render_404 unless
24
- params[:id] &&
25
- (user = RailsJwtAuth.model.where(reset_password_token: params[:id]).first)
26
-
27
- return render_422(password: [{error: :blank}]) if password_update_params[:password].blank?
28
-
29
- user.update(password_update_params) ? render_204 : render_422(user.errors.details)
30
- end
31
- end
32
- end
@@ -1,5 +0,0 @@
1
- <p>Hello <%= @user[RailsJwtAuth.email_field_name] %>!</p>
2
-
3
- <p>You need to define your password to complete registration. You can do this through the link below.</p>
4
-
5
- <p><%= link_to 'Set my password', @reset_passwords_url.html_safe %></p>