devise_jwt_auth 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/controllers/devise_jwt_auth/application_controller.rb +14 -11
- data/app/controllers/devise_jwt_auth/concerns/resource_finder.rb +2 -6
- data/app/controllers/devise_jwt_auth/concerns/set_user_by_token.rb +17 -19
- data/app/controllers/devise_jwt_auth/confirmations_controller.rb +10 -19
- data/app/controllers/devise_jwt_auth/omniauth_callbacks_controller.rb +32 -33
- data/app/controllers/devise_jwt_auth/passwords_controller.rb +29 -19
- 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 +18 -12
- 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 -4
- 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 -9
- data/app/models/devise_jwt_auth/concerns/user_omniauth_callbacks.rb +11 -3
- data/app/validators/devise_jwt_auth_email_validator.rb +4 -3
- data/lib/devise_jwt_auth/blacklist.rb +2 -0
- 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/install_generator.rb +7 -6
- data/lib/generators/devise_jwt_auth/install_generator_helpers.rb +14 -7
- data/lib/generators/devise_jwt_auth/install_mongoid_generator.rb +3 -2
- data/lib/generators/devise_jwt_auth/templates/devise_jwt_auth.rb +2 -3
- data/test/controllers/custom/custom_confirmations_controller_test.rb +2 -2
- data/test/controllers/custom/custom_passwords_controller_test.rb +4 -4
- 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_mang_controller_test.rb +206 -210
- data/test/controllers/demo_user_controller_test.rb +358 -374
- data/test/controllers/devise_jwt_auth/confirmations_controller_test.rb +5 -5
- data/test/controllers/devise_jwt_auth/omniauth_callbacks_controller_test.rb +6 -7
- data/test/controllers/devise_jwt_auth/passwords_controller_test.rb +11 -13
- data/test/controllers/devise_jwt_auth/refresh_token_controller_test.rb +8 -12
- data/test/controllers/devise_jwt_auth/registrations_controller_test.rb +23 -25
- data/test/controllers/devise_jwt_auth/sessions_controller_test.rb +30 -32
- 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 -1
- 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 +4 -4
- data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +4 -4
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +4 -4
- 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.ru +2 -2
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/boot.rb +1 -1
- data/test/dummy/config/environments/test.rb +11 -7
- data/test/dummy/config/initializers/figaro.rb +1 -1
- data/test/dummy/config/initializers/omniauth.rb +2 -2
- data/test/dummy/config/routes.rb +8 -8
- 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/controllers/application_controller.rb +6 -0
- data/test/dummy/tmp/generators/config/initializers/devise_jwt_auth.rb +2 -3
- data/test/dummy/tmp/generators/db/migrate/{20200228012905_devise_jwt_auth_create_users.rb → 20201006030349_devise_jwt_auth_create_users.rb} +0 -0
- data/test/factories/users.rb +5 -3
- data/test/lib/devise_jwt_auth/token_factory_test.rb +6 -6
- 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 +35 -37
- data/test/support/controllers/routes.rb +7 -5
- data/test/test_helper.rb +1 -1
- metadata +50 -54
- data/test/dummy/tmp/generators/app/models/mang.rb +0 -9
- data/test/dummy/tmp/generators/config/routes.rb +0 -9
- data/test/dummy/tmp/generators/db/migrate/20200228012905_devise_jwt_auth_create_mangs.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c1a405bebeaa7813dc0b99465db4530d29bf458fe392dd968f11b8abc5b11ab
|
4
|
+
data.tar.gz: d1c81c134b4031df4ef862041a4dfc4a0bc021f2cd538c020c23aaccc485e298
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06141ad295c58d63e8f4e87bc26be3af1b223b52ac2a865329c0ea438bfb7409e7e0466ad2fb1a70b156ba773346dca676d04b6f3fe00e1297b900a3cc482bdd
|
7
|
+
data.tar.gz: b7de2ecb350212b5fc8e91b0066bd5cb5050ca1e5c1c344a116b8d2ce77273b5f8066dc654a26ab0412bb4d8e5b679f4852a16c022cee60a04b0408e2f0a1a12
|
data/README.md
CHANGED
@@ -57,7 +57,7 @@ See our [Contribution Guidelines](https://github.com/aarona/devise_jwt_auth/blob
|
|
57
57
|
|
58
58
|
## Live Demos
|
59
59
|
|
60
|
-
Live demos will hopefully be added in the future.
|
60
|
+
Live demos will hopefully be added in the future. Currently, I have a [repository](https://github.com/aarona/dja_example) available that is a proof of concept for DJA that uses React as the client. However, the example application only supports sigining up, sigining in and singing out. It doesn't provide a way to reset a user's password for example and other things that DJA supports. Those will be added in the near future.
|
61
61
|
|
62
62
|
## License
|
63
63
|
|
@@ -20,17 +20,17 @@ module DeviseJwtAuth
|
|
20
20
|
DeviseJwtAuth.redirect_whitelist && !DeviseJwtAuth::Url.whitelisted?(redirect_url)
|
21
21
|
end
|
22
22
|
|
23
|
-
def build_redirect_headers(access_token,
|
23
|
+
def build_redirect_headers(access_token, _client, redirect_header_options = {})
|
24
24
|
{
|
25
25
|
# DeviseJwtAuth.headers_names[:"access-token"] => access_token,
|
26
26
|
# DeviseJwtAuth.headers_names[:"client"] => client,
|
27
|
-
:
|
27
|
+
config: params[:config],
|
28
28
|
|
29
29
|
# Legacy parameters which may be removed in a future release.
|
30
30
|
# Consider using "client" and "access-token" in client code.
|
31
31
|
# See: github.com/lynndylanhurley/devise_jwt_auth/issues/993
|
32
32
|
# :client_id => client,
|
33
|
-
:
|
33
|
+
token: access_token
|
34
34
|
}.merge(redirect_header_options)
|
35
35
|
end
|
36
36
|
|
@@ -42,20 +42,23 @@ module DeviseJwtAuth
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def resource_class(m = nil)
|
45
|
-
if m
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
mapping = if m
|
46
|
+
Devise.mappings[m]
|
47
|
+
else
|
48
|
+
Devise.mappings[resource_name] || Devise.mappings.values.first
|
49
|
+
end
|
50
50
|
|
51
51
|
mapping.to
|
52
52
|
end
|
53
53
|
|
54
54
|
def json_api?
|
55
55
|
return false unless defined?(ActiveModel::Serializer)
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
|
57
|
+
if ActiveModel::Serializer.respond_to?(:setup)
|
58
|
+
return ActiveModel::Serializer.setup do |config|
|
59
|
+
config.adapter == :json_api
|
60
|
+
end
|
61
|
+
end
|
59
62
|
ActiveModelSerializers.config.adapter == :json_api
|
60
63
|
end
|
61
64
|
|
@@ -8,13 +8,9 @@ module DeviseJwtAuth::Concerns::ResourceFinder
|
|
8
8
|
# honor Devise configuration for case_insensitive keys
|
9
9
|
q_value = resource_params[field.to_sym]
|
10
10
|
|
11
|
-
if resource_class.case_insensitive_keys.include?(field.to_sym)
|
12
|
-
q_value.downcase!
|
13
|
-
end
|
11
|
+
q_value.downcase! if resource_class.case_insensitive_keys.include?(field.to_sym)
|
14
12
|
|
15
|
-
if resource_class.strip_whitespace_keys.include?(field.to_sym)
|
16
|
-
q_value.strip!
|
17
|
-
end
|
13
|
+
q_value.strip! if resource_class.strip_whitespace_keys.include?(field.to_sym)
|
18
14
|
|
19
15
|
q_value
|
20
16
|
end
|
@@ -5,7 +5,6 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
5
5
|
include DeviseJwtAuth::Concerns::ResourceFinder
|
6
6
|
|
7
7
|
included do
|
8
|
-
|
9
8
|
end
|
10
9
|
|
11
10
|
protected
|
@@ -22,10 +21,10 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
22
21
|
devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
|
23
22
|
@resource = devise_warden_user if devise_warden_user
|
24
23
|
end
|
25
|
-
|
24
|
+
|
26
25
|
# user has already been found and authenticated
|
27
|
-
return @resource if @resource
|
28
|
-
|
26
|
+
return @resource if @resource&.is_a?(rc)
|
27
|
+
|
29
28
|
# TODO: Look for the access token in an 'Authentication' header
|
30
29
|
token = request.headers[DeviseJwtAuth.access_token_name]
|
31
30
|
return unless token
|
@@ -33,8 +32,9 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
33
32
|
payload = DeviseJwtAuth::TokenFactory.decode_access_token(token)
|
34
33
|
return if payload.empty?
|
35
34
|
return if payload && payload['sub'].blank?
|
35
|
+
|
36
36
|
uid = payload['sub']
|
37
|
-
|
37
|
+
|
38
38
|
# mitigate timing attacks by finding by uid instead of auth token
|
39
39
|
user = uid && rc.dta_find_by(uid: uid)
|
40
40
|
scope = rc.to_s.underscore.to_sym
|
@@ -46,10 +46,10 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
46
46
|
else
|
47
47
|
sign_in(scope, user, store: false, event: :fetch, bypass: DeviseJwtAuth.bypass_sign_in)
|
48
48
|
end
|
49
|
-
|
49
|
+
@resource = user
|
50
50
|
else
|
51
51
|
# zero all values previously set values
|
52
|
-
|
52
|
+
@resource = nil
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -65,10 +65,10 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
65
65
|
devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
|
66
66
|
@resource = devise_warden_user if devise_warden_user
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
# user has already been found and authenticated
|
70
|
-
return @resource if @resource
|
71
|
-
|
70
|
+
return @resource if @resource&.is_a?(rc)
|
71
|
+
|
72
72
|
token = request.cookies[DeviseJwtAuth.refresh_token_name]
|
73
73
|
|
74
74
|
return unless token
|
@@ -76,6 +76,7 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
76
76
|
payload = DeviseJwtAuth::TokenFactory.decode_refresh_token(token)
|
77
77
|
return if payload.empty?
|
78
78
|
return if payload && payload['sub'].blank?
|
79
|
+
|
79
80
|
uid = payload['sub']
|
80
81
|
|
81
82
|
# mitigate timing attacks by finding by uid instead of auth token
|
@@ -89,13 +90,12 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
89
90
|
else
|
90
91
|
sign_in(scope, user, store: false, event: :fetch, bypass: DeviseJwtAuth.bypass_sign_in)
|
91
92
|
end
|
92
|
-
|
93
|
+
@resource = user
|
93
94
|
else
|
94
95
|
# zero all values previously set values
|
95
|
-
|
96
|
+
@resource = nil
|
96
97
|
end
|
97
98
|
end
|
98
|
-
|
99
99
|
|
100
100
|
def update_refresh_token_cookie
|
101
101
|
response.set_cookie(DeviseJwtAuth.refresh_token_name,
|
@@ -103,15 +103,13 @@ module DeviseJwtAuth::Concerns::SetUserByToken
|
|
103
103
|
path: '/auth/refresh_token', # TODO: Use configured auth path
|
104
104
|
expires: Time.zone.now + DeviseJwtAuth.refresh_token_lifespan,
|
105
105
|
httponly: true,
|
106
|
-
secure: Rails.env.production?
|
107
|
-
)
|
106
|
+
secure: Rails.env.production?)
|
108
107
|
end
|
109
|
-
|
108
|
+
|
110
109
|
def clear_refresh_token_cookie
|
111
110
|
response.set_cookie(DeviseJwtAuth.refresh_token_name,
|
112
111
|
value: '',
|
113
112
|
path: '/auth/refresh_token', # TODO: Use configured auth path
|
114
|
-
expires: Time.zone.now
|
115
|
-
)
|
113
|
+
expires: Time.zone.now)
|
116
114
|
end
|
117
|
-
end
|
115
|
+
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module DeviseJwtAuth
|
4
4
|
class ConfirmationsController < DeviseJwtAuth::ApplicationController
|
5
|
-
|
6
5
|
def show
|
7
6
|
@resource = resource_class.confirm_by_token(resource_params[:confirmation_token])
|
8
7
|
|
@@ -12,19 +11,12 @@ module DeviseJwtAuth
|
|
12
11
|
redirect_header_options = { account_confirmation_success: true }
|
13
12
|
|
14
13
|
if signed_in?(resource_name)
|
15
|
-
|
16
|
-
|
17
|
-
# redirect_headers = build_redirect_headers(token.token,
|
18
|
-
# token.client,
|
19
|
-
# redirect_header_options)
|
20
|
-
|
21
|
-
redirect_headers = signed_in_resource.create_named_token_pair.
|
22
|
-
merge(redirect_header_options)
|
14
|
+
redirect_headers = signed_in_resource.create_named_token_pair
|
15
|
+
.merge(redirect_header_options)
|
23
16
|
|
24
|
-
# TODO: add a refresh token cookie in the response.
|
25
17
|
update_refresh_token_cookie
|
26
|
-
|
27
|
-
#redirect_to_link = signed_in_resource.build_auth_url(redirect_url, redirect_headers)
|
18
|
+
|
19
|
+
# redirect_to_link = signed_in_resource.build_auth_url(redirect_url, redirect_headers)
|
28
20
|
redirect_to_link = DeviseJwtAuth::Url.generate(redirect_url, redirect_headers)
|
29
21
|
else
|
30
22
|
redirect_to_link = DeviseJwtAuth::Url.generate(redirect_url, redirect_header_options)
|
@@ -46,11 +38,11 @@ module DeviseJwtAuth
|
|
46
38
|
return render_not_found_error unless @resource
|
47
39
|
|
48
40
|
@resource.send_confirmation_instructions({
|
49
|
-
|
50
|
-
|
51
|
-
|
41
|
+
redirect_url: redirect_url,
|
42
|
+
client_config: resource_params[:config_name]
|
43
|
+
})
|
52
44
|
|
53
|
-
|
45
|
+
render_create_success
|
54
46
|
end
|
55
47
|
|
56
48
|
protected
|
@@ -61,8 +53,8 @@ module DeviseJwtAuth
|
|
61
53
|
|
62
54
|
def render_create_success
|
63
55
|
render json: {
|
64
|
-
|
65
|
-
|
56
|
+
success: true,
|
57
|
+
message: I18n.t('devise_jwt_auth.confirmations.sended', email: @email)
|
66
58
|
}
|
67
59
|
end
|
68
60
|
|
@@ -83,6 +75,5 @@ module DeviseJwtAuth
|
|
83
75
|
DeviseJwtAuth.default_confirm_success_url
|
84
76
|
)
|
85
77
|
end
|
86
|
-
|
87
78
|
end
|
88
79
|
end
|
@@ -7,12 +7,10 @@ module DeviseJwtAuth
|
|
7
7
|
before_action :validate_auth_origin_url_param
|
8
8
|
|
9
9
|
skip_before_action :set_user_by_jwt_token, raise: false
|
10
|
-
# skip_after_action :update_auth_header
|
11
10
|
|
12
11
|
# intermediary route for successful omniauth authentication. omniauth does
|
13
12
|
# not support multiple models, so we must resort to this terrible hack.
|
14
13
|
def redirect_callbacks
|
15
|
-
|
16
14
|
# derive target redirect route from 'resource_class' param, which was set
|
17
15
|
# before authentication.
|
18
16
|
devise_mapping = get_devise_mapping
|
@@ -29,15 +27,17 @@ module DeviseJwtAuth
|
|
29
27
|
def get_redirect_route(devise_mapping)
|
30
28
|
path = "#{Devise.mappings[devise_mapping.to_sym].fullpath}/#{params[:provider]}/callback"
|
31
29
|
klass = request.scheme == 'https' ? URI::HTTPS : URI::HTTP
|
32
|
-
|
30
|
+
klass.build(host: request.host, port: request.port, path: path).to_s
|
33
31
|
end
|
34
32
|
|
35
33
|
def get_devise_mapping
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
# derive target redirect route from 'resource_class' param, which was set
|
35
|
+
# before authentication.
|
36
|
+
[
|
37
|
+
request.env['omniauth.params']['namespace_name'],
|
38
|
+
request.env['omniauth.params']['resource_class'].underscore.gsub('/', '_')
|
39
|
+
].compact.join('_')
|
40
|
+
rescue NoMethodError
|
41
41
|
default_devise_mapping
|
42
42
|
end
|
43
43
|
|
@@ -45,13 +45,13 @@ module DeviseJwtAuth
|
|
45
45
|
# find the mapping in `omniauth.params`.
|
46
46
|
#
|
47
47
|
# One example use-case here is for IDP-initiated SAML login. In that
|
48
|
-
# case, there will have been no initial request in which to save
|
48
|
+
# case, there will have been no initial request in which to save
|
49
49
|
# the devise mapping. If you are in a situation like that, and
|
50
50
|
# your app allows for you to determine somehow what the devise
|
51
51
|
# mapping should be (because, for example, it is always the same),
|
52
52
|
# then you can handle it by overriding this method.
|
53
53
|
def default_devise_mapping
|
54
|
-
raise NotImplementedError
|
54
|
+
raise NotImplementedError, 'no default_devise_mapping set'
|
55
55
|
end
|
56
56
|
|
57
57
|
def omniauth_success
|
@@ -78,10 +78,11 @@ module DeviseJwtAuth
|
|
78
78
|
render_data_or_redirect('authFailure', error: @error)
|
79
79
|
end
|
80
80
|
|
81
|
-
def validate_auth_origin_url_param
|
82
|
-
return
|
81
|
+
def validate_auth_origin_url_param
|
82
|
+
return unless auth_origin_url && blacklisted_redirect_url?(auth_origin_url)
|
83
|
+
|
84
|
+
render_error_not_allowed_auth_origin_url
|
83
85
|
end
|
84
|
-
|
85
86
|
|
86
87
|
protected
|
87
88
|
|
@@ -95,19 +96,19 @@ module DeviseJwtAuth
|
|
95
96
|
# are added as query params in our monkey patch to OmniAuth in engine.rb
|
96
97
|
def omniauth_params
|
97
98
|
unless defined?(@_omniauth_params)
|
98
|
-
if request.env['omniauth.params']
|
99
|
+
if request.env['omniauth.params']&.any?
|
99
100
|
@_omniauth_params = request.env['omniauth.params']
|
100
|
-
elsif session['dta.omniauth.params']
|
101
|
+
elsif session['dta.omniauth.params']&.any?
|
101
102
|
@_omniauth_params ||= session.delete('dta.omniauth.params')
|
102
103
|
@_omniauth_params
|
103
104
|
elsif params['omniauth_window_type']
|
104
|
-
@_omniauth_params =
|
105
|
+
@_omniauth_params =
|
106
|
+
params.slice('omniauth_window_type', 'auth_origin_url', 'resource_class', 'origin')
|
105
107
|
else
|
106
108
|
@_omniauth_params = {}
|
107
109
|
end
|
108
110
|
end
|
109
111
|
@_omniauth_params
|
110
|
-
|
111
112
|
end
|
112
113
|
|
113
114
|
# break out provider attribute assignment for easy method extension
|
@@ -120,14 +121,13 @@ module DeviseJwtAuth
|
|
120
121
|
def whitelisted_params
|
121
122
|
whitelist = params_for_resource(:sign_up)
|
122
123
|
|
123
|
-
whitelist.
|
124
|
+
whitelist.each_with_object({}) do |key, coll|
|
124
125
|
param = omniauth_params[key.to_s]
|
125
126
|
coll[key] = param if param
|
126
|
-
coll
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
-
def resource_class(
|
130
|
+
def resource_class(_mapping = nil)
|
131
131
|
if omniauth_params['resource_class']
|
132
132
|
omniauth_params['resource_class'].constantize
|
133
133
|
elsif params['resource_class']
|
@@ -149,18 +149,18 @@ module DeviseJwtAuth
|
|
149
149
|
omniauth_params['auth_origin_url'] || omniauth_params['origin']
|
150
150
|
end
|
151
151
|
|
152
|
-
|
153
152
|
def auth_origin_url
|
154
|
-
if unsafe_auth_origin_url && blacklisted_redirect_url?(unsafe_auth_origin_url)
|
155
|
-
|
156
|
-
|
157
|
-
return unsafe_auth_origin_url
|
153
|
+
return nil if unsafe_auth_origin_url && blacklisted_redirect_url?(unsafe_auth_origin_url)
|
154
|
+
|
155
|
+
unsafe_auth_origin_url
|
158
156
|
end
|
159
157
|
|
160
158
|
# in the success case, omniauth_window_type is in the omniauth_params.
|
161
159
|
# in the failure case, it is in a query param. See monkey patch above
|
162
160
|
def omniauth_window_type
|
163
|
-
|
161
|
+
return params['omniauth_window_type'] if omniauth_params.nil?
|
162
|
+
|
163
|
+
omniauth_params['omniauth_window_type']
|
164
164
|
end
|
165
165
|
|
166
166
|
# this sesison value is set by the redirect_callbacks method. its purpose
|
@@ -208,7 +208,10 @@ module DeviseJwtAuth
|
|
208
208
|
end
|
209
209
|
|
210
210
|
def render_error_not_allowed_auth_origin_url
|
211
|
-
message =
|
211
|
+
message =
|
212
|
+
I18n.t('devise_jwt_auth.omniauth.not_allowed_redirect_url',
|
213
|
+
redirect_url: unsafe_auth_origin_url)
|
214
|
+
|
212
215
|
render_data_or_redirect('authFailure', error: message)
|
213
216
|
end
|
214
217
|
|
@@ -218,7 +221,6 @@ module DeviseJwtAuth
|
|
218
221
|
end
|
219
222
|
|
220
223
|
def render_data_or_redirect(message, data, user_data = {})
|
221
|
-
|
222
224
|
# We handle inAppBrowser and newWindow the same, but it is nice
|
223
225
|
# to support values in case people need custom implementations for each case
|
224
226
|
# (For example, nbrustein does not allow new users to be created if logging in with
|
@@ -245,7 +247,7 @@ module DeviseJwtAuth
|
|
245
247
|
end
|
246
248
|
|
247
249
|
def fallback_render(text)
|
248
|
-
|
250
|
+
render inline: %(
|
249
251
|
|
250
252
|
<html>
|
251
253
|
<head></head>
|
@@ -271,9 +273,7 @@ module DeviseJwtAuth
|
|
271
273
|
provider: auth_hash['provider']
|
272
274
|
).first_or_initialize
|
273
275
|
|
274
|
-
if @resource.new_record?
|
275
|
-
handle_new_resource
|
276
|
-
end
|
276
|
+
handle_new_resource if @resource.new_record?
|
277
277
|
|
278
278
|
# sync user info with provider, update/generate auth token
|
279
279
|
assign_provider_attrs(@resource, auth_hash)
|
@@ -287,5 +287,4 @@ module DeviseJwtAuth
|
|
287
287
|
@resource
|
288
288
|
end
|
289
289
|
end
|
290
|
-
|
291
290
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
module DeviseJwtAuth
|
4
4
|
class PasswordsController < DeviseJwtAuth::ApplicationController
|
5
5
|
before_action :validate_redirect_url_param, only: [:create, :edit]
|
6
|
-
# skip_after_action :update_auth_header, only: [:create, :edit]
|
7
6
|
|
8
7
|
# this action is responsible for generating password reset tokens and sending emails
|
9
8
|
def create
|
@@ -22,7 +21,7 @@ module DeviseJwtAuth
|
|
22
21
|
)
|
23
22
|
|
24
23
|
if @resource.errors.empty?
|
25
|
-
|
24
|
+
render_create_success
|
26
25
|
else
|
27
26
|
render_create_error @resource.errors
|
28
27
|
end
|
@@ -36,12 +35,13 @@ module DeviseJwtAuth
|
|
36
35
|
# if a user is not found, return nil
|
37
36
|
@resource = resource_class.with_reset_password_token(resource_params[:reset_password_token])
|
38
37
|
|
39
|
-
if @resource
|
38
|
+
if @resource&.reset_password_period_valid?
|
40
39
|
# TODO: add a token invalidator
|
41
40
|
# token = @resource.create_token unless require_client_password_reset_token?
|
42
41
|
|
43
42
|
# ensure that user is confirmed
|
44
43
|
@resource.skip_confirmation! if confirmable_enabled? && !@resource.confirmed_at
|
44
|
+
|
45
45
|
# allow user to change password once without current_password
|
46
46
|
@resource.allow_password_change = true if recoverable_enabled?
|
47
47
|
@resource.save!
|
@@ -49,16 +49,19 @@ module DeviseJwtAuth
|
|
49
49
|
yield @resource if block_given?
|
50
50
|
|
51
51
|
if require_client_password_reset_token?
|
52
|
-
redirect_to DeviseJwtAuth::Url.generate(
|
52
|
+
redirect_to DeviseJwtAuth::Url.generate(
|
53
|
+
@redirect_url,
|
54
|
+
reset_password_token: resource_params[:reset_password_token]
|
55
|
+
)
|
53
56
|
else
|
54
57
|
redirect_header_options = { reset_password: true }
|
55
|
-
redirect_headers = @resource.create_named_token_pair
|
56
|
-
|
58
|
+
redirect_headers = @resource.create_named_token_pair
|
59
|
+
.merge(redirect_header_options)
|
57
60
|
|
58
61
|
# TODO: do we put the refresh token here?
|
59
62
|
# we do if token exists (see line 41)
|
60
63
|
update_refresh_token_cookie
|
61
|
-
|
64
|
+
|
62
65
|
redirect_to_link = DeviseJwtAuth::Url.generate(@redirect_url, redirect_headers)
|
63
66
|
|
64
67
|
redirect_to redirect_to_link
|
@@ -82,9 +85,7 @@ module DeviseJwtAuth
|
|
82
85
|
return render_update_error_unauthorized unless @resource
|
83
86
|
|
84
87
|
# make sure account doesn't use oauth2 provider
|
85
|
-
unless @resource.provider == 'email'
|
86
|
-
return render_update_error_password_not_required
|
87
|
-
end
|
88
|
+
return render_update_error_password_not_required unless @resource.provider == 'email'
|
88
89
|
|
89
90
|
# ensure that password params were sent
|
90
91
|
unless password_resource_params[:password] && password_resource_params[:password_confirmation]
|
@@ -100,16 +101,20 @@ module DeviseJwtAuth
|
|
100
101
|
# send refresh cookie
|
101
102
|
# send access token
|
102
103
|
update_refresh_token_cookie
|
103
|
-
|
104
|
+
render_update_success
|
104
105
|
else
|
105
|
-
|
106
|
+
render_update_error
|
106
107
|
end
|
107
108
|
end
|
108
109
|
|
109
110
|
protected
|
110
111
|
|
111
112
|
def resource_update_method
|
112
|
-
allow_password_change =
|
113
|
+
allow_password_change =
|
114
|
+
recoverable_enabled? &&
|
115
|
+
@resource.allow_password_change == true ||
|
116
|
+
require_client_password_reset_token?
|
117
|
+
|
113
118
|
if DeviseJwtAuth.check_current_password_before_update == false || allow_password_change
|
114
119
|
'update'
|
115
120
|
else
|
@@ -128,9 +133,10 @@ module DeviseJwtAuth
|
|
128
133
|
def render_error_not_allowed_redirect_url
|
129
134
|
response = {
|
130
135
|
status: 'error',
|
131
|
-
data:
|
136
|
+
data: resource_data
|
132
137
|
}
|
133
|
-
message = I18n.t('devise_jwt_auth.passwords.not_allowed_redirect_url',
|
138
|
+
message = I18n.t('devise_jwt_auth.passwords.not_allowed_redirect_url',
|
139
|
+
redirect_url: @redirect_url)
|
134
140
|
render_error(422, message, response)
|
135
141
|
end
|
136
142
|
|
@@ -157,7 +163,8 @@ module DeviseJwtAuth
|
|
157
163
|
end
|
158
164
|
|
159
165
|
def render_update_error_password_not_required
|
160
|
-
render_error(422, I18n.t('devise_jwt_auth.passwords.password_not_required',
|
166
|
+
render_error(422, I18n.t('devise_jwt_auth.passwords.password_not_required',
|
167
|
+
provider: @resource.provider.humanize))
|
161
168
|
end
|
162
169
|
|
163
170
|
def render_update_error_missing_password
|
@@ -170,7 +177,7 @@ module DeviseJwtAuth
|
|
170
177
|
data: resource_data,
|
171
178
|
message: I18n.t('devise_jwt_auth.passwords.successfully_updated')
|
172
179
|
}.merge!(@resource.create_named_token_pair)
|
173
|
-
|
180
|
+
|
174
181
|
render json: response_body
|
175
182
|
end
|
176
183
|
|
@@ -203,11 +210,14 @@ module DeviseJwtAuth
|
|
203
210
|
)
|
204
211
|
|
205
212
|
return render_create_error_missing_redirect_url unless @redirect_url
|
206
|
-
|
213
|
+
|
214
|
+
render_error_not_allowed_redirect_url if blacklisted_redirect_url?(@redirect_url)
|
207
215
|
end
|
208
216
|
|
209
217
|
def reset_password_token_as_raw?(recoverable)
|
210
|
-
recoverable &&
|
218
|
+
recoverable &&
|
219
|
+
recoverable.reset_password_token.present? &&
|
220
|
+
!require_client_password_reset_token?
|
211
221
|
end
|
212
222
|
|
213
223
|
def require_client_password_reset_token?
|