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.
- checksums.yaml +4 -4
- data/README.md +188 -89
- data/app/controllers/concerns/rails_jwt_auth/authenticable_helper.rb +15 -7
- data/app/controllers/concerns/rails_jwt_auth/params_helper.rb +18 -4
- data/app/controllers/concerns/rails_jwt_auth/render_helper.rb +10 -2
- data/app/controllers/rails_jwt_auth/confirmations_controller.rb +48 -10
- data/app/controllers/rails_jwt_auth/invitations_controller.rb +27 -9
- data/app/controllers/rails_jwt_auth/profiles_controller.rb +51 -0
- data/app/controllers/rails_jwt_auth/reset_passwords_controller.rb +65 -0
- data/app/controllers/rails_jwt_auth/sessions_controller.rb +7 -22
- data/app/controllers/rails_jwt_auth/{unlocks_controller.rb → unlock_accounts_controller.rb} +2 -2
- data/app/mailers/rails_jwt_auth/mailer.rb +23 -28
- data/app/models/concerns/rails_jwt_auth/authenticatable.rb +60 -19
- data/app/models/concerns/rails_jwt_auth/confirmable.rb +49 -39
- data/app/models/concerns/rails_jwt_auth/invitable.rb +46 -72
- data/app/models/concerns/rails_jwt_auth/lockable.rb +38 -46
- data/app/models/concerns/rails_jwt_auth/recoverable.rb +27 -26
- data/app/models/concerns/rails_jwt_auth/trackable.rb +13 -2
- data/app/views/rails_jwt_auth/mailer/confirmation_instructions.html.erb +1 -1
- data/app/views/rails_jwt_auth/mailer/{send_invitation.html.erb → invitation_instructions.html.erb} +1 -1
- data/app/views/rails_jwt_auth/mailer/password_changed_notification.html.erb +3 -0
- data/app/views/rails_jwt_auth/mailer/reset_password_instructions.html.erb +1 -1
- data/app/views/rails_jwt_auth/mailer/{send_unlock_instructions.html.erb → unlock_instructions.html.erb} +1 -1
- data/config/locales/en.yml +6 -6
- data/lib/generators/rails_jwt_auth/install_generator.rb +11 -3
- data/lib/generators/templates/initializer.rb +43 -29
- data/lib/generators/templates/migration.rb +2 -1
- data/lib/rails_jwt_auth/jwt_manager.rb +2 -4
- data/lib/rails_jwt_auth/session.rb +128 -0
- data/lib/rails_jwt_auth/version.rb +1 -1
- data/lib/rails_jwt_auth.rb +46 -47
- metadata +11 -9
- data/app/controllers/rails_jwt_auth/passwords_controller.rb +0 -32
- data/app/views/rails_jwt_auth/mailer/set_password_instructions.html.erb +0 -5
- /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
|
data/lib/rails_jwt_auth.rb
CHANGED
@@ -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
|
-
|
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 :
|
36
|
-
self.
|
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.
|
76
|
+
self.reset_attempts_in = 60.minutes
|
76
77
|
|
77
|
-
mattr_accessor :
|
78
|
-
self.
|
78
|
+
mattr_accessor :confirm_email_url
|
79
|
+
self.confirm_email_url = nil
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
end
|
81
|
+
mattr_accessor :reset_password_url
|
82
|
+
self.reset_password_url = nil
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
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.
|
93
|
-
|
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.
|
106
|
-
|
107
|
-
|
101
|
+
def self.mailer
|
102
|
+
mailer_name.constantize
|
103
|
+
end
|
108
104
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
raise RailsJwtAuth::InvalidEmailField
|
113
|
-
end
|
105
|
+
def self.table_name
|
106
|
+
model_name.underscore.pluralize
|
107
|
+
end
|
114
108
|
|
115
|
-
|
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
|
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:
|
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:
|
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/
|
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/
|
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/
|
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/
|
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.
|
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
|
File without changes
|