devise_jwt_auth 0.1.4 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/controllers/devise_jwt_auth/application_controller.rb +11 -22
- data/app/controllers/devise_jwt_auth/concerns/resource_finder.rb +3 -7
- data/app/controllers/devise_jwt_auth/concerns/set_user_by_token.rb +22 -18
- data/app/controllers/devise_jwt_auth/confirmations_controller.rb +10 -19
- data/app/controllers/devise_jwt_auth/omniauth_callbacks_controller.rb +38 -46
- data/app/controllers/devise_jwt_auth/passwords_controller.rb +34 -36
- data/app/controllers/devise_jwt_auth/refresh_token_controller.rb +4 -1
- data/app/controllers/devise_jwt_auth/registrations_controller.rb +40 -21
- data/app/controllers/devise_jwt_auth/sessions_controller.rb +21 -21
- data/app/controllers/devise_jwt_auth/unlocks_controller.rb +5 -4
- data/app/models/devise_jwt_auth/concerns/active_record_support.rb +3 -0
- data/app/models/devise_jwt_auth/concerns/confirmable_support.rb +7 -14
- data/app/models/devise_jwt_auth/concerns/mongoid_support.rb +3 -0
- data/app/models/devise_jwt_auth/concerns/tokens_serialization.rb +4 -1
- data/app/models/devise_jwt_auth/concerns/user.rb +18 -11
- data/app/models/devise_jwt_auth/concerns/user_omniauth_callbacks.rb +11 -3
- data/app/validators/devise_jwt_auth_email_validator.rb +12 -2
- data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
- data/lib/devise_jwt_auth/blacklist.rb +3 -1
- data/lib/devise_jwt_auth/controllers/url_helpers.rb +1 -2
- data/lib/devise_jwt_auth/engine.rb +4 -4
- data/lib/devise_jwt_auth/rails/routes.rb +35 -24
- data/lib/devise_jwt_auth/token_factory.rb +3 -2
- data/lib/devise_jwt_auth/url.rb +2 -4
- data/lib/devise_jwt_auth/version.rb +1 -1
- data/lib/generators/devise_jwt_auth/USAGE +1 -1
- data/lib/generators/devise_jwt_auth/install_generator.rb +7 -6
- data/lib/generators/devise_jwt_auth/install_generator_helpers.rb +27 -6
- data/lib/generators/devise_jwt_auth/install_mongoid_generator.rb +3 -2
- data/lib/generators/devise_jwt_auth/templates/devise_jwt_auth.rb +6 -7
- data/lib/generators/devise_jwt_auth/templates/devise_jwt_auth_create_users.rb.erb +15 -11
- data/lib/generators/devise_jwt_auth/templates/user.rb.erb +2 -2
- data/test/controllers/custom/custom_confirmations_controller_test.rb +2 -2
- data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +1 -1
- data/test/controllers/custom/custom_passwords_controller_test.rb +8 -8
- data/test/controllers/custom/custom_refresh_token_controller_test.rb +2 -3
- data/test/controllers/custom/custom_registrations_controller_test.rb +2 -2
- data/test/controllers/demo_group_controller_test.rb +0 -24
- data/test/controllers/demo_mang_controller_test.rb +4 -224
- data/test/controllers/demo_user_controller_test.rb +6 -432
- data/test/controllers/devise_jwt_auth/confirmations_controller_test.rb +5 -5
- data/test/controllers/devise_jwt_auth/omniauth_callbacks_controller_test.rb +9 -10
- data/test/controllers/devise_jwt_auth/passwords_controller_test.rb +34 -35
- data/test/controllers/devise_jwt_auth/refresh_token_controller_test.rb +8 -12
- data/test/controllers/devise_jwt_auth/registrations_controller_test.rb +12 -26
- data/test/controllers/devise_jwt_auth/sessions_controller_test.rb +32 -34
- data/test/controllers/devise_jwt_auth/unlocks_controller_test.rb +2 -2
- data/test/controllers/overrides/confirmations_controller_test.rb +1 -1
- data/test/controllers/overrides/passwords_controller_test.rb +1 -6
- data/test/controllers/overrides/refresh_token_controller_test.rb +1 -2
- data/test/controllers/overrides/registrations_controller_test.rb +1 -1
- data/test/dummy/app/controllers/custom/refresh_token_controller.rb +2 -1
- data/test/dummy/app/controllers/custom/registrations_controller.rb +1 -1
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +3 -16
- data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +4 -4
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +4 -16
- data/test/dummy/app/controllers/overrides/refresh_token_controller.rb +1 -1
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +2 -2
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +2 -2
- data/test/dummy/app/models/concerns/favorite_color.rb +11 -9
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/boot.rb +1 -1
- data/test/dummy/config/environments/development.rb +2 -2
- data/test/dummy/config/environments/test.rb +11 -7
- data/test/dummy/config/initializers/devise_jwt_auth.rb +1 -0
- data/test/dummy/config/initializers/figaro.rb +1 -1
- data/test/dummy/config/initializers/omniauth.rb +2 -2
- data/test/dummy/config/routes.rb +10 -8
- data/test/dummy/config.ru +2 -2
- data/test/dummy/db/migrate/20141222035835_devise_jwt_auth_create_only_email_users.rb +9 -9
- data/test/dummy/db/migrate/20190924101113_devise_jwt_auth_create_confirmable_users.rb +6 -5
- data/test/dummy/db/schema.rb +170 -170
- data/test/dummy/tmp/generators/app/models/user.rb +8 -0
- data/test/dummy/tmp/generators/config/initializers/devise_jwt_auth.rb +6 -7
- data/test/dummy/tmp/generators/db/migrate/{20200210193225_devise_jwt_auth_create_azpire_v1_human_resource_users.rb → 20220123023137_devise_jwt_auth_create_users.rb} +20 -17
- data/test/factories/users.rb +5 -3
- data/test/lib/devise_jwt_auth/blacklist_test.rb +2 -2
- data/test/lib/devise_jwt_auth/token_factory_test.rb +7 -7
- data/test/lib/generators/devise_jwt_auth/install_generator_test.rb +3 -20
- data/test/lib/generators/devise_jwt_auth/install_generator_with_namespace_test.rb +4 -21
- data/test/models/concerns/tokens_serialization_test.rb +68 -68
- data/test/models/user_test.rb +0 -38
- data/test/support/controllers/routes.rb +7 -5
- data/test/test_helper.rb +1 -1
- metadata +45 -71
- data/test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb +0 -9
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DeviseJwtAuth
|
4
|
+
# Controller that handles sending refresh tokens.
|
4
5
|
class RefreshTokenController < DeviseJwtAuth::ApplicationController
|
5
6
|
before_action :set_user_by_refresh_token
|
6
7
|
|
@@ -14,6 +15,7 @@ module DeviseJwtAuth
|
|
14
15
|
end
|
15
16
|
|
16
17
|
protected
|
18
|
+
|
17
19
|
def resource_data
|
18
20
|
response_data = @resource.as_json
|
19
21
|
response_data['type'] = @resource.class.name.parameterize if json_api?
|
@@ -23,10 +25,11 @@ module DeviseJwtAuth
|
|
23
25
|
def render_refresh_token_success
|
24
26
|
response_data = {
|
25
27
|
status: 'success',
|
26
|
-
data:
|
28
|
+
data: resource_data
|
27
29
|
}
|
28
30
|
|
29
31
|
response_data.merge!(@resource.create_named_token_pair) if active_for_authentication?
|
32
|
+
|
30
33
|
render json: response_data
|
31
34
|
end
|
32
35
|
|
@@ -28,10 +28,17 @@ module DeviseJwtAuth
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# if whitelist is set, validate redirect_url against whitelist
|
31
|
-
|
31
|
+
if blacklisted_redirect_url?(@redirect_url)
|
32
|
+
return render_create_error_redirect_url_not_allowed
|
33
|
+
end
|
32
34
|
|
33
35
|
# override email confirmation, must be sent manually from ctrl
|
34
|
-
callback_name = defined?(ActiveRecord) && resource_class < ActiveRecord::Base
|
36
|
+
callback_name = if defined?(ActiveRecord) && resource_class < ActiveRecord::Base
|
37
|
+
:commit
|
38
|
+
else
|
39
|
+
:create
|
40
|
+
end
|
41
|
+
|
35
42
|
resource_class.set_callback(callback_name, :after, :send_on_create_confirmation_instructions)
|
36
43
|
resource_class.skip_callback(callback_name, :after, :send_on_create_confirmation_instructions)
|
37
44
|
|
@@ -46,9 +53,9 @@ module DeviseJwtAuth
|
|
46
53
|
unless @resource.confirmed?
|
47
54
|
# user will require email authentication
|
48
55
|
@resource.send_confirmation_instructions({
|
49
|
-
|
50
|
-
|
51
|
-
|
56
|
+
client_config: params[:config_name],
|
57
|
+
redirect_url: @redirect_url
|
58
|
+
})
|
52
59
|
end
|
53
60
|
|
54
61
|
update_refresh_token_cookie if active_for_authentication?
|
@@ -98,17 +105,17 @@ module DeviseJwtAuth
|
|
98
105
|
@resource.provider = provider
|
99
106
|
|
100
107
|
# honor devise configuration for case_insensitive_keys
|
101
|
-
if resource_class.case_insensitive_keys.include?(:email)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
108
|
+
@resource.email = if resource_class.case_insensitive_keys.include?(:email)
|
109
|
+
sign_up_params[:email].try(:downcase)
|
110
|
+
else
|
111
|
+
sign_up_params[:email]
|
112
|
+
end
|
106
113
|
end
|
107
114
|
|
108
115
|
def render_create_error_missing_confirm_success_url
|
109
116
|
response = {
|
110
117
|
status: 'error',
|
111
|
-
data:
|
118
|
+
data: resource_data
|
112
119
|
}
|
113
120
|
message = I18n.t('devise_jwt_auth.registrations.missing_confirm_success_url')
|
114
121
|
render_error(422, message, response)
|
@@ -117,26 +124,30 @@ module DeviseJwtAuth
|
|
117
124
|
def render_create_error_redirect_url_not_allowed
|
118
125
|
response = {
|
119
126
|
status: 'error',
|
120
|
-
data:
|
127
|
+
data: resource_data
|
121
128
|
}
|
122
|
-
message = I18n.t(
|
129
|
+
message = I18n.t(
|
130
|
+
'devise_jwt_auth.registrations.redirect_url_not_allowed',
|
131
|
+
redirect_url: @redirect_url
|
132
|
+
)
|
123
133
|
render_error(422, message, response)
|
124
134
|
end
|
125
135
|
|
126
136
|
def render_create_success
|
127
137
|
response_data = {
|
128
138
|
status: 'success',
|
129
|
-
data:
|
139
|
+
data: resource_data
|
130
140
|
}
|
131
141
|
|
132
142
|
response_data.merge!(@resource.create_named_token_pair) if active_for_authentication?
|
143
|
+
|
133
144
|
render json: response_data
|
134
145
|
end
|
135
146
|
|
136
147
|
def render_create_error
|
137
148
|
render json: {
|
138
149
|
status: 'error',
|
139
|
-
data:
|
150
|
+
data: resource_data,
|
140
151
|
errors: resource_errors
|
141
152
|
}, status: 422
|
142
153
|
end
|
@@ -144,7 +155,7 @@ module DeviseJwtAuth
|
|
144
155
|
def render_update_success
|
145
156
|
render json: {
|
146
157
|
status: 'success',
|
147
|
-
data:
|
158
|
+
data: resource_data
|
148
159
|
}
|
149
160
|
end
|
150
161
|
|
@@ -162,12 +173,17 @@ module DeviseJwtAuth
|
|
162
173
|
def render_destroy_success
|
163
174
|
render json: {
|
164
175
|
status: 'success',
|
165
|
-
message: I18n.t(
|
176
|
+
message: I18n.t(
|
177
|
+
'devise_jwt_auth.registrations.account_with_uid_destroyed',
|
178
|
+
uid: @resource.uid
|
179
|
+
)
|
166
180
|
}
|
167
181
|
end
|
168
182
|
|
169
183
|
def render_destroy_error
|
170
|
-
render_error(404,
|
184
|
+
render_error(404,
|
185
|
+
I18n.t('devise_jwt_auth.registrations.account_to_destroy_not_found'),
|
186
|
+
status: 'error')
|
171
187
|
end
|
172
188
|
|
173
189
|
private
|
@@ -175,7 +191,8 @@ module DeviseJwtAuth
|
|
175
191
|
def resource_update_method
|
176
192
|
if DeviseJwtAuth.check_current_password_before_update == :attributes
|
177
193
|
'update_with_password'
|
178
|
-
elsif DeviseJwtAuth.check_current_password_before_update == :password &&
|
194
|
+
elsif DeviseJwtAuth.check_current_password_before_update == :password &&
|
195
|
+
account_update_params.key?(:password)
|
179
196
|
'update_with_password'
|
180
197
|
elsif account_update_params.key?(:current_password)
|
181
198
|
'update_with_password'
|
@@ -189,10 +206,12 @@ module DeviseJwtAuth
|
|
189
206
|
end
|
190
207
|
|
191
208
|
def validate_account_update_params
|
192
|
-
validate_post_data account_update_params, I18n.t(
|
209
|
+
validate_post_data account_update_params, I18n.t(
|
210
|
+
'errors.messages.validate_account_update_params'
|
211
|
+
)
|
193
212
|
end
|
194
213
|
|
195
|
-
def validate_post_data
|
214
|
+
def validate_post_data(which, message)
|
196
215
|
render_error(:unprocessable_entity, message, status: 'error') if which.empty?
|
197
216
|
end
|
198
217
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# see http://www.emilsoman.com/blog/2013/05/18/building-a-tested/
|
4
3
|
module DeviseJwtAuth
|
5
4
|
class SessionsController < DeviseJwtAuth::ApplicationController
|
6
5
|
before_action :set_user_by_token, only: [:destroy]
|
@@ -21,11 +20,17 @@ module DeviseJwtAuth
|
|
21
20
|
@resource = find_resource(field, q_value)
|
22
21
|
end
|
23
22
|
|
24
|
-
if @resource &&
|
23
|
+
if @resource &&
|
24
|
+
valid_params?(field, q_value) &&
|
25
|
+
(!@resource.respond_to?(:active_for_authentication?) ||
|
26
|
+
@resource.active_for_authentication?)
|
25
27
|
valid_password = @resource.valid_password?(resource_params[:password])
|
26
|
-
if (@resource.respond_to?(:valid_for_authentication?) &&
|
28
|
+
if (@resource.respond_to?(:valid_for_authentication?) &&
|
29
|
+
!@resource.valid_for_authentication? { valid_password }) ||
|
30
|
+
!valid_password
|
27
31
|
return render_create_error_bad_credentials
|
28
32
|
end
|
33
|
+
|
29
34
|
@token = @resource.create_token
|
30
35
|
@resource.save
|
31
36
|
|
@@ -35,7 +40,9 @@ module DeviseJwtAuth
|
|
35
40
|
|
36
41
|
update_refresh_token_cookie
|
37
42
|
render_create_success
|
38
|
-
elsif @resource &&
|
43
|
+
elsif @resource &&
|
44
|
+
!(!@resource.respond_to?(:active_for_authentication?) ||
|
45
|
+
@resource.active_for_authentication?)
|
39
46
|
if @resource.respond_to?(:locked_at) && @resource.locked_at
|
40
47
|
render_create_error_account_locked
|
41
48
|
else
|
@@ -48,18 +55,13 @@ module DeviseJwtAuth
|
|
48
55
|
|
49
56
|
def destroy
|
50
57
|
# TODO: logout? update token version?
|
51
|
-
|
58
|
+
|
52
59
|
# remove auth instance variables so that after_action does not run
|
53
60
|
user = remove_instance_variable(:@resource) if @resource
|
54
|
-
# client = @token.client if @token.client
|
55
|
-
# @token.clear!
|
56
|
-
|
57
|
-
if user # && client && user.tokens[client]
|
58
|
-
# user.tokens.delete(client)
|
59
|
-
# user.save!
|
60
61
|
|
62
|
+
if user
|
61
63
|
yield user if block_given?
|
62
|
-
|
64
|
+
clear_refresh_token_cookie
|
63
65
|
render_destroy_success
|
64
66
|
else
|
65
67
|
render_destroy_error
|
@@ -78,17 +80,15 @@ module DeviseJwtAuth
|
|
78
80
|
|
79
81
|
# iterate thru allowed auth keys, use first found
|
80
82
|
resource_class.authentication_keys.each do |k|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
next unless resource_params[k]
|
84
|
+
|
85
|
+
auth_val = resource_params[k]
|
86
|
+
auth_key = k
|
87
|
+
break
|
86
88
|
end
|
87
89
|
|
88
90
|
# honor devise configuration for case_insensitive_keys
|
89
|
-
if resource_class.case_insensitive_keys.include?(auth_key)
|
90
|
-
auth_val.downcase!
|
91
|
-
end
|
91
|
+
auth_val.downcase! if resource_class.case_insensitive_keys.include?(auth_key)
|
92
92
|
|
93
93
|
{ key: auth_key, val: auth_val }
|
94
94
|
end
|
@@ -118,7 +118,7 @@ module DeviseJwtAuth
|
|
118
118
|
|
119
119
|
def render_destroy_success
|
120
120
|
render json: {
|
121
|
-
success:true
|
121
|
+
success: true
|
122
122
|
}, status: 200
|
123
123
|
end
|
124
124
|
|
@@ -22,7 +22,7 @@ module DeviseJwtAuth
|
|
22
22
|
)
|
23
23
|
|
24
24
|
if @resource.errors.empty?
|
25
|
-
|
25
|
+
render_create_success
|
26
26
|
else
|
27
27
|
render_create_error @resource.errors
|
28
28
|
end
|
@@ -38,8 +38,8 @@ module DeviseJwtAuth
|
|
38
38
|
yield @resource if block_given?
|
39
39
|
|
40
40
|
redirect_header_options = { unlock: true }
|
41
|
-
redirect_headers = @resource.create_named_token_pair
|
42
|
-
merge(redirect_header_options)
|
41
|
+
redirect_headers = @resource.create_named_token_pair
|
42
|
+
.merge(redirect_header_options)
|
43
43
|
|
44
44
|
update_refresh_token_cookie
|
45
45
|
redirect_url = after_unlock_path_for(@resource)
|
@@ -52,7 +52,8 @@ module DeviseJwtAuth
|
|
52
52
|
end
|
53
53
|
|
54
54
|
private
|
55
|
-
|
55
|
+
|
56
|
+
def after_unlock_path_for(_resource)
|
56
57
|
# TODO: This should probably be a configuration option at the very least.
|
57
58
|
# Use confirmation controller / tests as a template for building out this feature.
|
58
59
|
'/'
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# ActiveSupport Concern for confirming users
|
1
4
|
module DeviseJwtAuth::Concerns::ConfirmableSupport
|
2
5
|
extend ActiveSupport::Concern
|
3
6
|
|
@@ -6,22 +9,12 @@ module DeviseJwtAuth::Concerns::ConfirmableSupport
|
|
6
9
|
# for not to use `will_save_change_to_email?` & `email_changed?` methods.
|
7
10
|
def postpone_email_change?
|
8
11
|
postpone = self.class.reconfirmable &&
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
email_was != email &&
|
13
|
+
!@bypass_confirmation_postpone &&
|
14
|
+
email.present? &&
|
15
|
+
(!@skip_reconfirmation_in_callback || !email_was.nil?)
|
13
16
|
@bypass_confirmation_postpone = false
|
14
17
|
postpone
|
15
18
|
end
|
16
19
|
end
|
17
|
-
|
18
|
-
protected
|
19
|
-
|
20
|
-
def email_value_in_database
|
21
|
-
if Devise.rails51? && respond_to?(:email_in_database)
|
22
|
-
email_in_database
|
23
|
-
else
|
24
|
-
email_was
|
25
|
-
end
|
26
|
-
end
|
27
20
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Dumping and loading serialized tokens in JSON format.
|
1
4
|
module DeviseJwtAuth::Concerns::TokensSerialization
|
2
5
|
# Serialization hash to json
|
3
6
|
def self.dump(object)
|
4
|
-
object
|
7
|
+
object&.each_value(&:compact!)
|
5
8
|
JSON.generate(object)
|
6
9
|
end
|
7
10
|
|
@@ -22,14 +22,20 @@ module DeviseJwtAuth::Concerns::User
|
|
22
22
|
include DeviseJwtAuth::Concerns::MongoidSupport
|
23
23
|
end
|
24
24
|
|
25
|
-
if DeviseJwtAuth.default_callbacks
|
26
|
-
include DeviseJwtAuth::Concerns::UserOmniauthCallbacks
|
27
|
-
end
|
25
|
+
include DeviseJwtAuth::Concerns::UserOmniauthCallbacks if DeviseJwtAuth.default_callbacks
|
28
26
|
|
29
27
|
# don't use default devise email validation
|
30
|
-
def email_required
|
31
|
-
|
32
|
-
|
28
|
+
def email_required?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
def email_changed?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
def will_save_change_to_email?
|
37
|
+
false
|
38
|
+
end
|
33
39
|
|
34
40
|
if DeviseJwtAuth.send_confirmation_email && devise_modules.include?(:confirmable)
|
35
41
|
include DeviseJwtAuth::Concerns::ConfirmableSupport
|
@@ -37,6 +43,7 @@ module DeviseJwtAuth::Concerns::User
|
|
37
43
|
|
38
44
|
def password_required?
|
39
45
|
return false unless provider == 'email'
|
46
|
+
|
40
47
|
super
|
41
48
|
end
|
42
49
|
|
@@ -77,11 +84,11 @@ module DeviseJwtAuth::Concerns::User
|
|
77
84
|
end
|
78
85
|
|
79
86
|
def create_token(token_options = {})
|
80
|
-
DeviseJwtAuth::TokenFactory.create_access_token({sub: uid}.merge(token_options))
|
87
|
+
DeviseJwtAuth::TokenFactory.create_access_token({ sub: uid }.merge(token_options))
|
81
88
|
end
|
82
89
|
|
83
90
|
def create_refresh_token(token_options = {})
|
84
|
-
DeviseJwtAuth::TokenFactory.create_refresh_token({sub: uid}.merge(token_options))
|
91
|
+
DeviseJwtAuth::TokenFactory.create_refresh_token({ sub: uid }.merge(token_options))
|
85
92
|
end
|
86
93
|
end
|
87
94
|
|
@@ -93,12 +100,12 @@ module DeviseJwtAuth::Concerns::User
|
|
93
100
|
|
94
101
|
# this must be done from the controller so that additional params
|
95
102
|
# can be passed on from the client
|
96
|
-
def send_confirmation_notification
|
103
|
+
def send_confirmation_notification?
|
104
|
+
false
|
105
|
+
end
|
97
106
|
|
98
107
|
def build_auth_url(base_url, args)
|
99
108
|
args[:uid] = uid
|
100
|
-
args[:expiry] = tokens[args[:client_id]]['expiry']
|
101
|
-
|
102
109
|
DeviseJwtAuth::Url.generate(base_url, args)
|
103
110
|
end
|
104
111
|
|
@@ -4,12 +4,20 @@ module DeviseJwtAuth::Concerns::UserOmniauthCallbacks
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
validates :email, presence: true,if: :email_provider?
|
8
|
-
validates :email,
|
7
|
+
validates :email, presence: true, if: :email_provider?
|
8
|
+
validates :email,
|
9
|
+
devise_jwt_auth_email: true,
|
10
|
+
allow_nil: true,
|
11
|
+
allow_blank: true,
|
12
|
+
if: :email_provider?
|
13
|
+
|
9
14
|
validates_presence_of :uid, unless: :email_provider?
|
10
15
|
|
11
16
|
# only validate unique emails among email registration users
|
12
|
-
validates :email,
|
17
|
+
validates :email,
|
18
|
+
uniqueness: { case_sensitive: false, scope: :provider },
|
19
|
+
on: :create,
|
20
|
+
if: :email_provider?
|
13
21
|
|
14
22
|
# keep uid in sync with email
|
15
23
|
before_save :sync_uid
|
@@ -1,9 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Email field validator.
|
3
4
|
class DeviseJwtAuthEmailValidator < ActiveModel::EachValidator
|
5
|
+
EMAIL_REGEXP = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def validate?(email)
|
9
|
+
email =~ EMAIL_REGEXP
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
def validate_each(record, attribute, value)
|
5
|
-
unless value
|
6
|
-
record.errors[attribute] << email_invalid_message
|
14
|
+
unless DeviseJwtAuthEmailValidator.validate?(value)
|
15
|
+
# record.errors[attribute] << email_invalid_message
|
16
|
+
record.errors.add(attribute, email_invalid_message)
|
7
17
|
end
|
8
18
|
end
|
9
19
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<p><%= t '.request_reset_link_msg' %></p>
|
4
4
|
|
5
|
-
<p><%= link_to t('.password_change_link'), edit_password_url(@resource, reset_password_token: @token,
|
5
|
+
<p><%= link_to t('.password_change_link'), edit_password_url(@resource, reset_password_token: @token, redirect_url: message['redirect-url'].to_s).html_safe %></p>
|
6
6
|
|
7
7
|
<p><%= t '.ignore_mail_msg' %></p>
|
8
8
|
<p><%= t '.no_changes_msg' %></p>
|
@@ -33,7 +33,7 @@ module DeviseJwtAuth
|
|
33
33
|
|
34
34
|
self.send_new_access_token_on_each_request = false
|
35
35
|
self.refresh_token_lifespan = 1.week
|
36
|
-
self.access_token_lifespan =
|
36
|
+
self.access_token_lifespan = 15.minutes
|
37
37
|
self.refresh_token_name = 'refresh-token'
|
38
38
|
self.access_token_name = 'access-token'
|
39
39
|
self.refresh_token_encryption_key = 'your-refresh-token-secret-key-here'
|
@@ -51,12 +51,12 @@ module DeviseJwtAuth
|
|
51
51
|
self.send_confirmation_email = false
|
52
52
|
self.require_client_password_reset_token = false
|
53
53
|
|
54
|
-
def self.setup
|
54
|
+
def self.setup
|
55
55
|
yield self
|
56
56
|
|
57
57
|
Rails.application.config.after_initialize do
|
58
58
|
if defined?(::OmniAuth)
|
59
|
-
::OmniAuth
|
59
|
+
::OmniAuth.config.path_prefix = Devise.omniauth_path_prefix = omniauth_prefix
|
60
60
|
|
61
61
|
# Omniauth currently does not pass along omniauth.params upon failure redirect
|
62
62
|
# see also: https://github.com/intridea/omniauth/issues/626
|
@@ -84,7 +84,7 @@ module DeviseJwtAuth
|
|
84
84
|
fail!(mocked_auth)
|
85
85
|
else
|
86
86
|
@env['omniauth.auth'] = mocked_auth
|
87
|
-
OmniAuth.config.before_callback_phase
|
87
|
+
OmniAuth.config.before_callback_phase&.call(@env)
|
88
88
|
call_app!
|
89
89
|
end
|
90
90
|
end
|
@@ -8,14 +8,13 @@ module ActionDispatch::Routing
|
|
8
8
|
opts[:skip] ||= []
|
9
9
|
|
10
10
|
# check for ctrl overrides, fall back to defaults
|
11
|
-
sessions_ctrl
|
12
|
-
registrations_ctrl
|
13
|
-
passwords_ctrl
|
14
|
-
confirmations_ctrl
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
unlocks_ctrl = opts[:controllers][:unlocks] || 'devise_jwt_auth/unlocks'
|
11
|
+
sessions_ctrl = opts[:controllers][:sessions] || 'devise_jwt_auth/sessions'
|
12
|
+
registrations_ctrl = opts[:controllers][:registrations] || 'devise_jwt_auth/registrations'
|
13
|
+
passwords_ctrl = opts[:controllers][:passwords] || 'devise_jwt_auth/passwords'
|
14
|
+
confirmations_ctrl = opts[:controllers][:confirmations] || 'devise_jwt_auth/confirmations'
|
15
|
+
refresh_token_ctrl = opts[:controllers][:refresh_token] || 'devise_jwt_auth/refresh_token'
|
16
|
+
omniauth_ctrl = opts[:controllers][:omniauth_callbacks] || 'devise_jwt_auth/omniauth_callbacks'
|
17
|
+
unlocks_ctrl = opts[:controllers][:unlocks] || 'devise_jwt_auth/unlocks'
|
19
18
|
|
20
19
|
# define devise controller mappings
|
21
20
|
controllers = { sessions: sessions_ctrl,
|
@@ -26,7 +25,7 @@ module ActionDispatch::Routing
|
|
26
25
|
controllers[:unlocks] = unlocks_ctrl if unlocks_ctrl
|
27
26
|
|
28
27
|
# remove any unwanted devise modules
|
29
|
-
opts[:skip].each{ |item| controllers.delete(item) }
|
28
|
+
opts[:skip].each { |item| controllers.delete(item) }
|
30
29
|
|
31
30
|
devise_for resource.pluralize.underscore.gsub('/', '_').to_sym,
|
32
31
|
class_name: resource,
|
@@ -44,12 +43,12 @@ module ActionDispatch::Routing
|
|
44
43
|
|
45
44
|
# clear scope so controller routes aren't namespaced
|
46
45
|
@scope = ActionDispatch::Routing::Mapper::Scope.new(
|
47
|
-
path:
|
46
|
+
path: '',
|
48
47
|
shallow_path: '',
|
49
|
-
constraints:
|
50
|
-
defaults:
|
51
|
-
options:
|
52
|
-
parent:
|
48
|
+
constraints: {},
|
49
|
+
defaults: {},
|
50
|
+
options: {},
|
51
|
+
parent: nil
|
53
52
|
)
|
54
53
|
|
55
54
|
mapping_name = resource.underscore.gsub('/', '_')
|
@@ -57,22 +56,34 @@ module ActionDispatch::Routing
|
|
57
56
|
|
58
57
|
devise_scope mapping_name.to_sym do
|
59
58
|
# path to refresh access tokens
|
60
|
-
|
61
|
-
|
59
|
+
unless opts[:skip].include?(:refresh_token)
|
60
|
+
get "#{full_path}/refresh_token", controller: refresh_token_ctrl.to_s, action: 'show'
|
61
|
+
end
|
62
62
|
|
63
63
|
# omniauth routes. only define if omniauth is installed and not skipped.
|
64
64
|
if defined?(::OmniAuth) && !opts[:skip].include?(:omniauth_callbacks)
|
65
|
-
match "#{full_path}/failure",
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
match "#{
|
65
|
+
match "#{full_path}/failure",
|
66
|
+
controller: omniauth_ctrl,
|
67
|
+
action: 'omniauth_failure',
|
68
|
+
via: [:get]
|
69
|
+
match "#{full_path}/:provider/callback",
|
70
|
+
controller: omniauth_ctrl,
|
71
|
+
action: 'omniauth_success',
|
72
|
+
via: [:get]
|
73
|
+
match "#{DeviseJwtAuth.omniauth_prefix}/:provider/callback",
|
74
|
+
controller: omniauth_ctrl,
|
75
|
+
action: 'redirect_callbacks',
|
76
|
+
via: [:get, :post]
|
77
|
+
match "#{DeviseJwtAuth.omniauth_prefix}/failure",
|
78
|
+
controller: omniauth_ctrl,
|
79
|
+
action: 'omniauth_failure',
|
80
|
+
via: [:get, :post]
|
70
81
|
|
71
82
|
# preserve the resource class thru oauth authentication by setting name of
|
72
83
|
# resource as "resource_class" param
|
73
|
-
match "#{full_path}/:provider", to: redirect{ |params, request|
|
84
|
+
match "#{full_path}/:provider", to: redirect { |params, request|
|
74
85
|
# get the current querystring
|
75
|
-
qs = CGI
|
86
|
+
qs = CGI.parse(request.env['QUERY_STRING'])
|
76
87
|
|
77
88
|
# append name of current resource
|
78
89
|
qs['resource_class'] = [resource]
|
@@ -80,7 +91,7 @@ module ActionDispatch::Routing
|
|
80
91
|
|
81
92
|
set_omniauth_path_prefix!(DeviseJwtAuth.omniauth_prefix)
|
82
93
|
|
83
|
-
redirect_params = {}.tap { |hash| qs.each{ |k, v| hash[k] = v.first } }
|
94
|
+
redirect_params = {}.tap { |hash| qs.each { |k, v| hash[k] = v.first } }
|
84
95
|
|
85
96
|
if DeviseJwtAuth.redirect_whitelist
|
86
97
|
redirect_url = request.params['auth_origin_url']
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'jwt'
|
2
4
|
|
3
5
|
module DeviseJwtAuth
|
4
6
|
# A token management factory which allow generate token objects and check them.
|
5
7
|
module TokenFactory
|
6
|
-
|
7
8
|
def self.create_refresh_token(payload)
|
8
9
|
if payload[:exp].blank? && payload['exp'].blank?
|
9
10
|
payload[:exp] = (Time.zone.now + DeviseJwtAuth.refresh_token_lifespan).to_i
|
@@ -33,7 +34,7 @@ module DeviseJwtAuth
|
|
33
34
|
rescue TypeError
|
34
35
|
{}
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
def self.decode_access_token(token)
|
38
39
|
JWT.decode(token, DeviseJwtAuth.access_token_encryption_key).first
|
39
40
|
rescue JWT::ExpiredSignature
|