devise_token_auth 1.1.5 → 1.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/app/controllers/devise_token_auth/application_controller.rb +8 -0
- data/app/controllers/devise_token_auth/concerns/resource_finder.rb +14 -1
- data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +28 -4
- data/app/controllers/devise_token_auth/confirmations_controller.rb +8 -4
- data/app/controllers/devise_token_auth/passwords_controller.rb +6 -2
- data/app/controllers/devise_token_auth/sessions_controller.rb +6 -0
- data/app/controllers/devise_token_auth/unlocks_controller.rb +6 -2
- data/app/models/devise_token_auth/concerns/user.rb +2 -7
- data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +2 -2
- data/app/views/devise_token_auth/omniauth_external_window.html.erb +1 -1
- data/config/locales/en.yml +3 -0
- data/lib/devise_token_auth/blacklist.rb +5 -1
- data/lib/devise_token_auth/engine.rb +6 -0
- data/lib/devise_token_auth/version.rb +1 -1
- data/test/controllers/devise_token_auth/confirmations_controller_test.rb +91 -19
- data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +2 -2
- data/test/controllers/devise_token_auth/passwords_controller_test.rb +73 -21
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +28 -15
- data/test/controllers/devise_token_auth/sessions_controller_test.rb +39 -10
- data/test/controllers/devise_token_auth/unlocks_controller_test.rb +21 -4
- data/test/controllers/overrides/confirmations_controller_test.rb +1 -1
- data/test/dummy/tmp/generators/app/controllers/application_controller.rb +6 -0
- data/test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb +48 -1
- data/test/lib/devise_token_auth/blacklist_test.rb +11 -3
- data/test/test_helper.rb +34 -3
- metadata +5 -5
- data/test/dummy/tmp/generators/db/migrate/20210126004321_devise_token_auth_create_azpire_v1_human_resource_users.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb2d73d7859e1754b505d6f554c8d298ba899444b4fe4e1b47d50ca9bab453e8
|
4
|
+
data.tar.gz: 3572d4ff07d68f62d8e51270959fd20451d9edb4832d576b9342939275390dee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50c95181401bedfd959a407d450f222ab185d75000825385dd691a064e831b36263eb1338d25f6378a743ac9009b73f80df3e24cb09ce5680a0e6723fc98acb9
|
7
|
+
data.tar.gz: 91910874d7e473d31eb39cf40c6860da4ab5b59aa874a0f1296faa17718103124018568cf289486a9d49a3ec1b967f14e23c18afb8d3f6cd3ec2fd837d663a83
|
@@ -75,5 +75,13 @@ module DeviseTokenAuth
|
|
75
75
|
response = response.merge(data) if data
|
76
76
|
render json: response, status: status
|
77
77
|
end
|
78
|
+
|
79
|
+
def success_message(name, email)
|
80
|
+
if Devise.paranoid
|
81
|
+
I18n.t("devise_token_auth.#{name}.sended_paranoid")
|
82
|
+
else
|
83
|
+
I18n.t("devise_token_auth.#{name}.sended", email: email)
|
84
|
+
end
|
85
|
+
end
|
78
86
|
end
|
79
87
|
end
|
@@ -20,7 +20,7 @@ module DeviseTokenAuth::Concerns::ResourceFinder
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def find_resource(field, value)
|
23
|
-
@resource = if
|
23
|
+
@resource = if database_adapter&.include?('mysql')
|
24
24
|
# fix for mysql default case insensitivity
|
25
25
|
resource_class.where("BINARY #{field} = ? AND provider= ?", value, provider).first
|
26
26
|
else
|
@@ -28,6 +28,19 @@ module DeviseTokenAuth::Concerns::ResourceFinder
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
def database_adapter
|
32
|
+
@database_adapter ||= begin
|
33
|
+
rails_version = [Rails::VERSION::MAJOR, Rails::VERSION::MINOR].join(".")
|
34
|
+
|
35
|
+
adapter =
|
36
|
+
if rails_version >= "6.1"
|
37
|
+
resource_class.try(:connection_db_config)&.try(:adapter)
|
38
|
+
else
|
39
|
+
resource_class.try(:connection_config)&.try(:[], :adapter)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
31
44
|
def resource_class(m = nil)
|
32
45
|
mapping = if m
|
33
46
|
Devise.mappings[m]
|
@@ -35,11 +35,20 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
35
35
|
access_token_name = DeviseTokenAuth.headers_names[:'access-token']
|
36
36
|
client_name = DeviseTokenAuth.headers_names[:'client']
|
37
37
|
|
38
|
+
# gets values from cookie if configured and present
|
39
|
+
parsed_auth_cookie = {}
|
40
|
+
if DeviseTokenAuth.cookie_enabled
|
41
|
+
auth_cookie = request.cookies[DeviseTokenAuth.cookie_name]
|
42
|
+
if auth_cookie.present?
|
43
|
+
parsed_auth_cookie = JSON.parse(auth_cookie)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
38
47
|
# parse header for values necessary for authentication
|
39
|
-
uid = request.headers[uid_name] || params[uid_name]
|
48
|
+
uid = request.headers[uid_name] || params[uid_name] || parsed_auth_cookie[uid_name]
|
40
49
|
@token = DeviseTokenAuth::TokenFactory.new unless @token
|
41
|
-
@token.token ||= request.headers[access_token_name] || params[access_token_name]
|
42
|
-
@token.client ||= request.headers[client_name] || params[client_name]
|
50
|
+
@token.token ||= request.headers[access_token_name] || params[access_token_name] || parsed_auth_cookie[access_token_name]
|
51
|
+
@token.client ||= request.headers[client_name] || params[client_name] || parsed_auth_cookie[client_name]
|
43
52
|
|
44
53
|
# client isn't required, set to 'default' if absent
|
45
54
|
@token.client ||= 'default'
|
@@ -101,6 +110,10 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
101
110
|
# update the response header
|
102
111
|
response.headers.merge!(auth_header)
|
103
112
|
|
113
|
+
# set a server cookie if configured
|
114
|
+
if DeviseTokenAuth.cookie_enabled
|
115
|
+
set_cookie(auth_header)
|
116
|
+
end
|
104
117
|
else
|
105
118
|
unless @resource.reload.valid?
|
106
119
|
@resource = @resource.class.find(@resource.to_param) # errors remain after reload
|
@@ -123,11 +136,22 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
123
136
|
# cleared by sign out in the meantime
|
124
137
|
return if @used_auth_by_token && @resource.tokens[@token.client].nil?
|
125
138
|
|
139
|
+
_auth_header_from_batch_request = auth_header_from_batch_request
|
140
|
+
|
126
141
|
# update the response header
|
127
|
-
response.headers.merge!(
|
142
|
+
response.headers.merge!(_auth_header_from_batch_request)
|
143
|
+
|
144
|
+
# set a server cookie if configured
|
145
|
+
if DeviseTokenAuth.cookie_enabled
|
146
|
+
set_cookie(_auth_header_from_batch_request)
|
147
|
+
end
|
128
148
|
end # end lock
|
129
149
|
end
|
130
150
|
|
151
|
+
def set_cookie(auth_header)
|
152
|
+
cookies[DeviseTokenAuth.cookie_name] = DeviseTokenAuth.cookie_attributes.merge(value: auth_header.to_json)
|
153
|
+
end
|
154
|
+
|
131
155
|
def is_batch_request?(user, client)
|
132
156
|
!params[:unbatch] &&
|
133
157
|
user.tokens[client] &&
|
@@ -55,13 +55,17 @@ module DeviseTokenAuth
|
|
55
55
|
|
56
56
|
def render_create_success
|
57
57
|
render json: {
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
success: true,
|
59
|
+
message: success_message('confirmations', @email)
|
60
|
+
}
|
61
61
|
end
|
62
62
|
|
63
63
|
def render_not_found_error
|
64
|
-
|
64
|
+
if Devise.paranoid
|
65
|
+
render_error(404, I18n.t('devise_token_auth.confirmations.sended_paranoid'))
|
66
|
+
else
|
67
|
+
render_error(404, I18n.t('devise_token_auth.confirmations.user_not_found', email: @email))
|
68
|
+
end
|
65
69
|
end
|
66
70
|
|
67
71
|
private
|
@@ -128,7 +128,7 @@ module DeviseTokenAuth
|
|
128
128
|
def render_create_success
|
129
129
|
render json: {
|
130
130
|
success: true,
|
131
|
-
message:
|
131
|
+
message: success_message('passwords', @email)
|
132
132
|
}
|
133
133
|
end
|
134
134
|
|
@@ -181,7 +181,11 @@ module DeviseTokenAuth
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def render_not_found_error
|
184
|
-
|
184
|
+
if Devise.paranoid
|
185
|
+
render_error(404, I18n.t('devise_token_auth.passwords.sended_paranoid'))
|
186
|
+
else
|
187
|
+
render_error(404, I18n.t('devise_token_auth.passwords.user_not_found', email: @email))
|
188
|
+
end
|
185
189
|
end
|
186
190
|
|
187
191
|
def validate_redirect_url_param
|
@@ -55,6 +55,12 @@ module DeviseTokenAuth
|
|
55
55
|
user.tokens.delete(client)
|
56
56
|
user.save!
|
57
57
|
|
58
|
+
if DeviseTokenAuth.cookie_enabled
|
59
|
+
# If a cookie is set with a domain specified then it must be deleted with that domain specified
|
60
|
+
# See https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html
|
61
|
+
cookies.delete(DeviseTokenAuth.cookie_name, domain: DeviseTokenAuth.cookie_attributes[:domain])
|
62
|
+
end
|
63
|
+
|
58
64
|
yield user if block_given?
|
59
65
|
|
60
66
|
render_destroy_success
|
@@ -63,7 +63,7 @@ module DeviseTokenAuth
|
|
63
63
|
def render_create_success
|
64
64
|
render json: {
|
65
65
|
success: true,
|
66
|
-
message:
|
66
|
+
message: success_message('unlocks', @email)
|
67
67
|
}
|
68
68
|
end
|
69
69
|
|
@@ -79,7 +79,11 @@ module DeviseTokenAuth
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def render_not_found_error
|
82
|
-
|
82
|
+
if Devise.paranoid
|
83
|
+
render_error(404, I18n.t('devise_token_auth.unlocks.sended_paranoid'))
|
84
|
+
else
|
85
|
+
render_error(404, I18n.t('devise_token_auth.unlocks.user_not_found', email: @email))
|
86
|
+
end
|
83
87
|
end
|
84
88
|
|
85
89
|
def resource_params
|
@@ -218,13 +218,8 @@ module DeviseTokenAuth::Concerns::User
|
|
218
218
|
end
|
219
219
|
|
220
220
|
def should_remove_tokens_after_password_reset?
|
221
|
-
|
222
|
-
encrypted_password_changed? &&
|
223
|
-
DeviseTokenAuth.remove_tokens_after_password_reset
|
224
|
-
else
|
225
|
-
saved_change_to_attribute?(:encrypted_password) &&
|
226
|
-
DeviseTokenAuth.remove_tokens_after_password_reset
|
227
|
-
end
|
221
|
+
DeviseTokenAuth.remove_tokens_after_password_reset &&
|
222
|
+
(respond_to?(:encrypted_password_changed?) && encrypted_password_changed?)
|
228
223
|
end
|
229
224
|
|
230
225
|
def remove_tokens_after_password_reset
|
@@ -23,8 +23,8 @@ module DeviseTokenAuth::Concerns::UserOmniauthCallbacks
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def sync_uid
|
26
|
-
|
27
|
-
return if postpone_email_change?
|
26
|
+
unless self.new_record?
|
27
|
+
return if devise_modules.include?(:confirmable) && !@bypass_confirmation_postpone && postpone_email_change?
|
28
28
|
end
|
29
29
|
self.uid = email if email_provider?
|
30
30
|
end
|
@@ -15,7 +15,7 @@
|
|
15
15
|
Cordova / PhoneGap)
|
16
16
|
*/
|
17
17
|
|
18
|
-
var data = JSON.parse(decodeURIComponent('<%=
|
18
|
+
var data = JSON.parse(decodeURIComponent('<%= ERB::Util.url_encode( @data.to_json ) %>'));
|
19
19
|
|
20
20
|
window.addEventListener("message", function(ev) {
|
21
21
|
if (ev.data === "requestCredentials") {
|
data/config/locales/en.yml
CHANGED
@@ -21,6 +21,7 @@ en:
|
|
21
21
|
missing_redirect_url: "Missing redirect URL."
|
22
22
|
not_allowed_redirect_url: "Redirect to '%{redirect_url}' not allowed."
|
23
23
|
sended: "An email has been sent to '%{email}' containing instructions for resetting your password."
|
24
|
+
sended_paranoid: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
24
25
|
user_not_found: "Unable to find user with email '%{email}'."
|
25
26
|
password_not_required: "This account does not require a password. Sign in using your '%{provider}' account instead."
|
26
27
|
missing_passwords: "You must fill out the fields labeled 'Password' and 'Password confirmation'."
|
@@ -28,9 +29,11 @@ en:
|
|
28
29
|
unlocks:
|
29
30
|
missing_email: "You must provide an email address."
|
30
31
|
sended: "An email has been sent to '%{email}' containing instructions for unlocking your account."
|
32
|
+
sended_paranoid: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
|
31
33
|
user_not_found: "Unable to find user with email '%{email}'."
|
32
34
|
confirmations:
|
33
35
|
sended: "An email has been sent to '%{email}' containing instructions for confirming your account."
|
36
|
+
sended_paranoid: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
|
34
37
|
user_not_found: "Unable to find user with email '%{email}'."
|
35
38
|
missing_email: "You must provide an email address."
|
36
39
|
|
@@ -1,2 +1,6 @@
|
|
1
1
|
# don't serialize tokens
|
2
|
-
Devise::Models::Authenticatable::
|
2
|
+
if defined? Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION
|
3
|
+
Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION << :tokens
|
4
|
+
else
|
5
|
+
Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION << :tokens
|
6
|
+
end
|
@@ -25,6 +25,9 @@ module DeviseTokenAuth
|
|
25
25
|
:remove_tokens_after_password_reset,
|
26
26
|
:default_callbacks,
|
27
27
|
:headers_names,
|
28
|
+
:cookie_enabled,
|
29
|
+
:cookie_name,
|
30
|
+
:cookie_attributes,
|
28
31
|
:bypass_sign_in,
|
29
32
|
:send_confirmation_email,
|
30
33
|
:require_client_password_reset_token
|
@@ -47,6 +50,9 @@ module DeviseTokenAuth
|
|
47
50
|
'expiry': 'expiry',
|
48
51
|
'uid': 'uid',
|
49
52
|
'token-type': 'token-type' }
|
53
|
+
self.cookie_enabled = false
|
54
|
+
self.cookie_name = 'auth_cookie'
|
55
|
+
self.cookie_attributes = {}
|
50
56
|
self.bypass_sign_in = true
|
51
57
|
self.send_confirmation_email = false
|
52
58
|
self.require_client_password_reset_token = false
|
@@ -92,30 +92,102 @@ class DeviseTokenAuth::ConfirmationsControllerTest < ActionController::TestCase
|
|
92
92
|
end
|
93
93
|
|
94
94
|
describe 'resend confirmation' do
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
95
|
+
describe 'without paranoid mode' do
|
96
|
+
|
97
|
+
describe 'on success' do
|
98
|
+
before do
|
99
|
+
post :create,
|
100
|
+
params: { email: @new_user.email,
|
101
|
+
redirect_url: @redirect_url },
|
102
|
+
xhr: true
|
103
|
+
@resource = assigns(:resource)
|
104
|
+
@data = JSON.parse(response.body)
|
105
|
+
@mail = ActionMailer::Base.deliveries.last
|
106
|
+
@token, @client_config = token_and_client_config_from(@mail.body)
|
107
|
+
end
|
108
|
+
|
109
|
+
test 'user should not be confirmed' do
|
110
|
+
assert_nil @resource.confirmed_at
|
111
|
+
end
|
112
|
+
|
113
|
+
test 'should generate raw token' do
|
114
|
+
assert @token
|
115
|
+
assert_equal @new_user.confirmation_token, @token
|
116
|
+
end
|
117
|
+
|
118
|
+
test 'user should receive confirmation email' do
|
119
|
+
assert_equal @resource.email, @mail['to'].to_s
|
120
|
+
end
|
121
|
+
|
122
|
+
test 'response should contain message' do
|
123
|
+
assert_equal @data['message'], I18n.t('devise_token_auth.confirmations.sended', email: @resource.email)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'on failure' do
|
128
|
+
before do
|
129
|
+
post :create,
|
130
|
+
params: { email: 'chester@cheet.ah',
|
131
|
+
redirect_url: @redirect_url },
|
132
|
+
xhr: true
|
133
|
+
@data = JSON.parse(response.body)
|
134
|
+
end
|
135
|
+
|
136
|
+
test 'response should contain errors' do
|
137
|
+
assert_equal @data['errors'], [I18n.t('devise_token_auth.confirmations.user_not_found', email: 'chester@cheet.ah')]
|
138
|
+
end
|
139
|
+
end
|
108
140
|
end
|
141
|
+
end
|
109
142
|
|
110
|
-
|
111
|
-
|
112
|
-
|
143
|
+
describe 'with paranoid mode' do
|
144
|
+
describe 'on success' do
|
145
|
+
before do
|
146
|
+
swap Devise, paranoid: true do
|
147
|
+
post :create,
|
148
|
+
params: { email: @new_user.email,
|
149
|
+
redirect_url: @redirect_url },
|
150
|
+
xhr: true
|
151
|
+
@resource = assigns(:resource)
|
152
|
+
@data = JSON.parse(response.body)
|
153
|
+
@mail = ActionMailer::Base.deliveries.last
|
154
|
+
@token, @client_config = token_and_client_config_from(@mail.body)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
test 'user should not be confirmed' do
|
159
|
+
assert_nil @resource.confirmed_at
|
160
|
+
end
|
161
|
+
|
162
|
+
test 'should generate raw token' do
|
163
|
+
assert @token
|
164
|
+
assert_equal @new_user.confirmation_token, @token
|
165
|
+
end
|
166
|
+
|
167
|
+
test 'user should receive confirmation email' do
|
168
|
+
assert_equal @resource.email, @mail['to'].to_s
|
169
|
+
end
|
170
|
+
|
171
|
+
test 'response should contain message' do
|
172
|
+
assert_equal @data['message'], I18n.t('devise_token_auth.confirmations.sended_paranoid', email: @resource.email)
|
173
|
+
end
|
113
174
|
end
|
114
175
|
|
115
|
-
|
116
|
-
|
176
|
+
describe 'on failure' do
|
177
|
+
before do
|
178
|
+
swap Devise, paranoid: true do
|
179
|
+
post :create,
|
180
|
+
params: { email: 'chester@cheet.ah',
|
181
|
+
redirect_url: @redirect_url },
|
182
|
+
xhr: true
|
183
|
+
@data = JSON.parse(response.body)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
test 'response should contain errors' do
|
188
|
+
assert_equal @data['errors'], [I18n.t('devise_token_auth.confirmations.sended_paranoid')]
|
189
|
+
end
|
117
190
|
end
|
118
|
-
|
119
191
|
end
|
120
192
|
end
|
121
193
|
|
@@ -18,7 +18,7 @@ class OmniauthTest < ActionDispatch::IntegrationTest
|
|
18
18
|
|
19
19
|
def get_parsed_data_json
|
20
20
|
encoded_json_data = @response.body.match(/var data \= JSON.parse\(decodeURIComponent\(\'(.+)\'\)\)\;/)[1]
|
21
|
-
JSON.parse(
|
21
|
+
JSON.parse(CGI.unescape(encoded_json_data))
|
22
22
|
end
|
23
23
|
|
24
24
|
describe 'success callback' do
|
@@ -346,7 +346,7 @@ class OmniauthTest < ActionDispatch::IntegrationTest
|
|
346
346
|
follow_all_redirects!
|
347
347
|
|
348
348
|
data = get_parsed_data_json
|
349
|
-
assert_equal "Redirect to
|
349
|
+
assert_equal "Redirect to '#{@bad_redirect_url}' not allowed.",
|
350
350
|
data['error']
|
351
351
|
end
|
352
352
|
|
@@ -85,37 +85,89 @@ class DeviseTokenAuth::PasswordsControllerTest < ActionController::TestCase
|
|
85
85
|
end
|
86
86
|
|
87
87
|
describe 'request password reset' do
|
88
|
-
describe 'unknown user
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
88
|
+
describe 'unknown user' do
|
89
|
+
describe 'without paranoid mode' do
|
90
|
+
before do
|
91
|
+
post :create,
|
92
|
+
params: { email: 'chester@cheet.ah',
|
93
|
+
redirect_url: @redirect_url }
|
94
|
+
@data = JSON.parse(response.body)
|
95
|
+
end
|
95
96
|
|
96
|
-
|
97
|
-
|
97
|
+
test 'unknown user should return 404' do
|
98
|
+
assert_equal 404, response.status
|
99
|
+
end
|
100
|
+
|
101
|
+
test 'errors should be returned' do
|
102
|
+
assert @data['errors']
|
103
|
+
assert_equal @data['errors'],
|
104
|
+
[I18n.t('devise_token_auth.passwords.user_not_found',
|
105
|
+
email: 'chester@cheet.ah')]
|
106
|
+
end
|
98
107
|
end
|
99
108
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
109
|
+
describe 'with paranoid mode' do
|
110
|
+
before do
|
111
|
+
swap Devise, paranoid: true do
|
112
|
+
post :create,
|
113
|
+
params: { email: 'chester@cheet.ah',
|
114
|
+
redirect_url: @redirect_url }
|
115
|
+
@data = JSON.parse(response.body)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
test 'unknown user should return 404' do
|
120
|
+
assert_equal 404, response.status
|
121
|
+
end
|
122
|
+
|
123
|
+
test 'errors should be returned' do
|
124
|
+
assert @data['errors']
|
125
|
+
assert_equal @data['errors'],
|
126
|
+
[I18n.t('devise_token_auth.passwords.sended_paranoid')]
|
127
|
+
end
|
105
128
|
end
|
106
129
|
end
|
107
130
|
|
108
131
|
describe 'successfully requested password reset' do
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
132
|
+
describe 'without paranoid mode' do
|
133
|
+
before do
|
134
|
+
post :create,
|
135
|
+
params: { email: @resource.email,
|
136
|
+
redirect_url: @redirect_url }
|
113
137
|
|
114
|
-
|
138
|
+
@data = JSON.parse(response.body)
|
139
|
+
end
|
140
|
+
|
141
|
+
test 'response should not contain extra data' do
|
142
|
+
assert_nil @data['data']
|
143
|
+
end
|
144
|
+
|
145
|
+
test 'response should contains message' do
|
146
|
+
assert_equal \
|
147
|
+
@data['message'],
|
148
|
+
I18n.t('devise_token_auth.passwords.sended', email: @resource.email)
|
149
|
+
end
|
115
150
|
end
|
116
151
|
|
117
|
-
|
118
|
-
|
152
|
+
describe 'with paranoid mode' do
|
153
|
+
before do
|
154
|
+
swap Devise, paranoid: true do
|
155
|
+
post :create,
|
156
|
+
params: { email: @resource.email,
|
157
|
+
redirect_url: @redirect_url }
|
158
|
+
@data = JSON.parse(response.body)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
test 'response should return success status' do
|
163
|
+
assert_equal 200, response.status
|
164
|
+
end
|
165
|
+
|
166
|
+
test 'response should contain message' do
|
167
|
+
assert_equal \
|
168
|
+
@data['message'],
|
169
|
+
I18n.t('devise_token_auth.passwords.sended_paranoid')
|
170
|
+
end
|
119
171
|
end
|
120
172
|
end
|
121
173
|
|
@@ -10,6 +10,17 @@ require 'test_helper'
|
|
10
10
|
|
11
11
|
class DeviseTokenAuth::RegistrationsControllerTest < ActionDispatch::IntegrationTest
|
12
12
|
describe DeviseTokenAuth::RegistrationsController do
|
13
|
+
|
14
|
+
def mock_registration_params
|
15
|
+
{
|
16
|
+
email: Faker::Internet.email,
|
17
|
+
password: 'secret123',
|
18
|
+
password_confirmation: 'secret123',
|
19
|
+
confirm_success_url: Faker::Internet.url,
|
20
|
+
unpermitted_param: '(x_x)'
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
13
24
|
describe 'Validate non-empty body' do
|
14
25
|
before do
|
15
26
|
# need to post empty data
|
@@ -41,13 +52,7 @@ class DeviseTokenAuth::RegistrationsControllerTest < ActionDispatch::Integration
|
|
41
52
|
@mails_sent = ActionMailer::Base.deliveries.count
|
42
53
|
|
43
54
|
post '/auth',
|
44
|
-
params:
|
45
|
-
email: Faker::Internet.email,
|
46
|
-
password: 'secret123',
|
47
|
-
password_confirmation: 'secret123',
|
48
|
-
confirm_success_url: Faker::Internet.url,
|
49
|
-
unpermitted_param: '(x_x)'
|
50
|
-
}
|
55
|
+
params: mock_registration_params
|
51
56
|
|
52
57
|
@resource = assigns(:resource)
|
53
58
|
@data = JSON.parse(response.body)
|
@@ -87,17 +92,10 @@ class DeviseTokenAuth::RegistrationsControllerTest < ActionDispatch::Integration
|
|
87
92
|
before do
|
88
93
|
@original_duration = Devise.allow_unconfirmed_access_for
|
89
94
|
Devise.allow_unconfirmed_access_for = nil
|
90
|
-
post '/auth',
|
91
|
-
params: {
|
92
|
-
email: Faker::Internet.email,
|
93
|
-
password: 'secret123',
|
94
|
-
password_confirmation: 'secret123',
|
95
|
-
confirm_success_url: Faker::Internet.url,
|
96
|
-
unpermitted_param: '(x_x)'
|
97
|
-
}
|
98
95
|
end
|
99
96
|
|
100
97
|
test 'auth headers were returned in response' do
|
98
|
+
post '/auth', params: mock_registration_params
|
101
99
|
assert response.headers['access-token']
|
102
100
|
assert response.headers['token-type']
|
103
101
|
assert response.headers['client']
|
@@ -105,6 +103,21 @@ class DeviseTokenAuth::RegistrationsControllerTest < ActionDispatch::Integration
|
|
105
103
|
assert response.headers['uid']
|
106
104
|
end
|
107
105
|
|
106
|
+
describe 'using auth cookie' do
|
107
|
+
before do
|
108
|
+
DeviseTokenAuth.cookie_enabled = true
|
109
|
+
end
|
110
|
+
|
111
|
+
test 'auth cookie was returned in response' do
|
112
|
+
post '/auth', params: mock_registration_params
|
113
|
+
assert response.cookies[DeviseTokenAuth.cookie_name]
|
114
|
+
end
|
115
|
+
|
116
|
+
after do
|
117
|
+
DeviseTokenAuth.cookie_enabled = false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
108
121
|
after do
|
109
122
|
Devise.allow_unconfirmed_access_for = @original_duration
|
110
123
|
end
|
@@ -17,11 +17,12 @@ class DeviseTokenAuth::SessionsControllerTest < ActionController::TestCase
|
|
17
17
|
|
18
18
|
describe 'success' do
|
19
19
|
before do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
@user_session_params = {
|
21
|
+
email: @existing_user.email,
|
22
|
+
password: @existing_user.password
|
23
|
+
}
|
24
|
+
|
25
|
+
post :create, params: @user_session_params
|
25
26
|
|
26
27
|
@resource = assigns(:resource)
|
27
28
|
@data = JSON.parse(response.body)
|
@@ -35,17 +36,27 @@ class DeviseTokenAuth::SessionsControllerTest < ActionController::TestCase
|
|
35
36
|
assert_equal @existing_user.email, @data['data']['email']
|
36
37
|
end
|
37
38
|
|
39
|
+
describe 'using auth cookie' do
|
40
|
+
before do
|
41
|
+
DeviseTokenAuth.cookie_enabled = true
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'request should return auth cookie' do
|
45
|
+
post :create, params: @user_session_params
|
46
|
+
assert response.cookies[DeviseTokenAuth.cookie_name]
|
47
|
+
end
|
48
|
+
|
49
|
+
after do
|
50
|
+
DeviseTokenAuth.cookie_enabled = false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
38
54
|
describe "with multiple clients and headers don't change in each request" do
|
39
55
|
before do
|
40
56
|
# Set the max_number_of_devices to a lower number
|
41
57
|
# to expedite tests! (Default is 10)
|
42
58
|
DeviseTokenAuth.max_number_of_devices = 2
|
43
59
|
DeviseTokenAuth.change_headers_on_each_request = false
|
44
|
-
|
45
|
-
@user_session_params = {
|
46
|
-
email: @existing_user.email,
|
47
|
-
password: @existing_user.password
|
48
|
-
}
|
49
60
|
end
|
50
61
|
|
51
62
|
test 'should limit the maximum number of concurrent devices' do
|
@@ -159,6 +170,24 @@ class DeviseTokenAuth::SessionsControllerTest < ActionController::TestCase
|
|
159
170
|
test 'session was destroyed' do
|
160
171
|
assert_equal true, @controller.reset_session_called
|
161
172
|
end
|
173
|
+
|
174
|
+
describe 'using auth cookie' do
|
175
|
+
before do
|
176
|
+
DeviseTokenAuth.cookie_enabled = true
|
177
|
+
@auth_token = @existing_user.create_new_auth_token
|
178
|
+
@controller.send(:cookies)[DeviseTokenAuth.cookie_name] = { value: @auth_token.to_json }
|
179
|
+
end
|
180
|
+
|
181
|
+
test 'auth cookie was destroyed' do
|
182
|
+
assert_equal @auth_token.to_json, @controller.send(:cookies)[DeviseTokenAuth.cookie_name] # sanity check
|
183
|
+
delete :destroy, format: :json
|
184
|
+
assert_nil @controller.send(:cookies)[DeviseTokenAuth.cookie_name]
|
185
|
+
end
|
186
|
+
|
187
|
+
after do
|
188
|
+
DeviseTokenAuth.cookie_enabled = false
|
189
|
+
end
|
190
|
+
end
|
162
191
|
end
|
163
192
|
|
164
193
|
describe 'unauthed user sign out' do
|
@@ -57,7 +57,7 @@ class DeviseTokenAuth::UnlocksControllerTest < ActionController::TestCase
|
|
57
57
|
end
|
58
58
|
|
59
59
|
describe 'request unlock' do
|
60
|
-
describe '
|
60
|
+
describe 'without paranoid mode' do
|
61
61
|
before do
|
62
62
|
post :create, params: { email: 'chester@cheet.ah' }
|
63
63
|
@data = JSON.parse(response.body)
|
@@ -68,9 +68,26 @@ class DeviseTokenAuth::UnlocksControllerTest < ActionController::TestCase
|
|
68
68
|
|
69
69
|
test 'errors should be returned' do
|
70
70
|
assert @data['errors']
|
71
|
-
assert_equal @data['errors'],
|
72
|
-
|
73
|
-
|
71
|
+
assert_equal @data['errors'], [I18n.t('devise_token_auth.unlocks.user_not_found',
|
72
|
+
email: 'chester@cheet.ah')]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'with paranoid mode' do
|
77
|
+
before do
|
78
|
+
swap Devise, paranoid: true do
|
79
|
+
post :create, params: { email: 'chester@cheet.ah' }
|
80
|
+
@data = JSON.parse(response.body)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
test 'unknown user should return 404' do
|
85
|
+
assert_equal 404, response.status
|
86
|
+
end
|
87
|
+
|
88
|
+
test 'errors should be returned' do
|
89
|
+
assert @data['errors']
|
90
|
+
assert_equal @data['errors'], [I18n.t('devise_token_auth.unlocks.sended_paranoid')]
|
74
91
|
end
|
75
92
|
end
|
76
93
|
|
@@ -38,7 +38,7 @@ class Overrides::ConfirmationsControllerTest < ActionDispatch::IntegrationTest
|
|
38
38
|
override_proof_str = '(^^,)'
|
39
39
|
|
40
40
|
# ensure present in redirect URL
|
41
|
-
override_proof_param =
|
41
|
+
override_proof_param = CGI.unescape(response.headers['Location']
|
42
42
|
.match(/override_proof=([^&]*)&/)[1])
|
43
43
|
|
44
44
|
assert_equal override_proof_str, override_proof_param
|
@@ -1,9 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Azpire::V1::HumanResource::User
|
3
|
+
class Azpire::V1::HumanResource::User
|
4
|
+
include Mongoid::Document
|
5
|
+
include Mongoid::Timestamps
|
6
|
+
include Mongoid::Locker
|
7
|
+
|
8
|
+
field :locker_locked_at, type: Time
|
9
|
+
field :locker_locked_until, type: Time
|
10
|
+
|
11
|
+
locker locked_at_field: :locker_locked_at,
|
12
|
+
locked_until_field: :locker_locked_until
|
13
|
+
|
14
|
+
## Database authenticatable
|
15
|
+
field :email, type: String, default: ''
|
16
|
+
field :encrypted_password, type: String, default: ''
|
17
|
+
|
18
|
+
## Recoverable
|
19
|
+
field :reset_password_token, type: String
|
20
|
+
field :reset_password_sent_at, type: Time
|
21
|
+
field :reset_password_redirect_url, type: String
|
22
|
+
field :allow_password_change, type: Boolean, default: false
|
23
|
+
|
24
|
+
## Rememberable
|
25
|
+
field :remember_created_at, type: Time
|
26
|
+
|
27
|
+
## Confirmable
|
28
|
+
field :confirmation_token, type: String
|
29
|
+
field :confirmed_at, type: Time
|
30
|
+
field :confirmation_sent_at, type: Time
|
31
|
+
field :unconfirmed_email, type: String # Only if using reconfirmable
|
32
|
+
|
33
|
+
## Lockable
|
34
|
+
# field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
|
35
|
+
# field :unlock_token, type: String # Only if unlock strategy is :email or :both
|
36
|
+
# field :locked_at, type: Time
|
37
|
+
|
38
|
+
## Required
|
39
|
+
field :provider, type: String
|
40
|
+
field :uid, type: String, default: ''
|
41
|
+
|
42
|
+
## Tokens
|
43
|
+
field :tokens, type: Hash, default: {}
|
44
|
+
|
4
45
|
# Include default devise modules. Others available are:
|
5
46
|
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
6
47
|
devise :database_authenticatable, :registerable,
|
7
48
|
:recoverable, :rememberable, :validatable
|
8
49
|
include DeviseTokenAuth::Concerns::User
|
50
|
+
|
51
|
+
index({ email: 1 }, { name: 'email_index', unique: true, background: true })
|
52
|
+
index({ reset_password_token: 1 }, { name: 'reset_password_token_index', unique: true, sparse: true, background: true })
|
53
|
+
index({ confirmation_token: 1 }, { name: 'confirmation_token_index', unique: true, sparse: true, background: true })
|
54
|
+
index({ uid: 1, provider: 1}, { name: 'uid_provider_index', unique: true, background: true })
|
55
|
+
# index({ unlock_token: 1 }, { name: 'unlock_token_index', unique: true, sparse: true, background: true })
|
9
56
|
end
|
@@ -3,9 +3,17 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class DeviseTokenAuth::BlacklistTest < ActiveSupport::TestCase
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
if defined? Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION
|
7
|
+
describe Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION do
|
8
|
+
test 'should include :tokens' do
|
9
|
+
assert Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION.include?(:tokens)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
else
|
13
|
+
describe Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION do
|
14
|
+
test 'should include :tokens' do
|
15
|
+
assert Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION.include?(:tokens)
|
16
|
+
end
|
9
17
|
end
|
10
18
|
end
|
11
19
|
end
|
data/test/test_helper.rb
CHANGED
@@ -15,7 +15,11 @@ require File.expand_path('dummy/config/environment', __dir__)
|
|
15
15
|
require 'active_support/testing/autorun'
|
16
16
|
require 'minitest/rails'
|
17
17
|
require 'mocha/minitest'
|
18
|
-
|
18
|
+
if DEVISE_TOKEN_AUTH_ORM == :active_record
|
19
|
+
require 'database_cleaner'
|
20
|
+
else
|
21
|
+
require 'database_cleaner/mongoid'
|
22
|
+
end
|
19
23
|
|
20
24
|
FactoryBot.definition_file_paths = [File.expand_path('factories', __dir__)]
|
21
25
|
FactoryBot.find_definitions
|
@@ -37,13 +41,40 @@ class ActiveSupport::TestCase
|
|
37
41
|
ActiveRecord::Migration.check_pending! if DEVISE_TOKEN_AUTH_ORM == :active_record
|
38
42
|
|
39
43
|
strategies = { active_record: :transaction,
|
40
|
-
mongoid: :
|
44
|
+
mongoid: :deletion }
|
41
45
|
DatabaseCleaner.strategy = strategies[DEVISE_TOKEN_AUTH_ORM]
|
42
46
|
setup { DatabaseCleaner.start }
|
43
47
|
teardown { DatabaseCleaner.clean }
|
44
48
|
|
45
49
|
# Add more helper methods to be used by all tests here...
|
46
50
|
|
51
|
+
# Execute the block setting the given values and restoring old values after
|
52
|
+
# the block is executed.
|
53
|
+
# shamelessly copied from devise test_helper.
|
54
|
+
def swap(object, new_values)
|
55
|
+
old_values = {}
|
56
|
+
new_values.each do |key, value|
|
57
|
+
old_values[key] = object.send key
|
58
|
+
object.send :"#{key}=", value
|
59
|
+
end
|
60
|
+
clear_cached_variables(new_values)
|
61
|
+
yield
|
62
|
+
ensure
|
63
|
+
clear_cached_variables(new_values)
|
64
|
+
old_values.each do |key, value|
|
65
|
+
object.send :"#{key}=", value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# shamelessly copied from devise test_helper.
|
70
|
+
def clear_cached_variables(options)
|
71
|
+
if options.key?(:case_insensitive_keys) || options.key?(:strip_whitespace_keys)
|
72
|
+
Devise.mappings.each do |_, mapping|
|
73
|
+
mapping.to.instance_variable_set(:@devise_parameter_filter, nil)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
47
78
|
def age_token(user, client_id)
|
48
79
|
if user.tokens[client_id]
|
49
80
|
user.tokens[client_id]['updated_at'] = (Time.zone.now - (DeviseTokenAuth.batch_request_buffer_throttle + 10.seconds))
|
@@ -85,7 +116,7 @@ module Rails
|
|
85
116
|
%w[get post patch put head delete get_via_redirect post_via_redirect].each do |method|
|
86
117
|
define_method(method) do |path_or_action, **args|
|
87
118
|
if Rails::VERSION::MAJOR >= 5
|
88
|
-
super path_or_action, args
|
119
|
+
super path_or_action, **args
|
89
120
|
else
|
90
121
|
super path_or_action, args[:params], args[:headers]
|
91
122
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_token_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lynn Hurley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -319,9 +319,9 @@ files:
|
|
319
319
|
- test/dummy/db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb
|
320
320
|
- test/dummy/db/schema.rb
|
321
321
|
- test/dummy/lib/migration_database_helper.rb
|
322
|
+
- test/dummy/tmp/generators/app/controllers/application_controller.rb
|
322
323
|
- test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb
|
323
324
|
- test/dummy/tmp/generators/config/initializers/devise_token_auth.rb
|
324
|
-
- test/dummy/tmp/generators/db/migrate/20210126004321_devise_token_auth_create_azpire_v1_human_resource_users.rb
|
325
325
|
- test/factories/users.rb
|
326
326
|
- test/lib/devise_token_auth/blacklist_test.rb
|
327
327
|
- test/lib/devise_token_auth/rails/custom_routes_test.rb
|
@@ -357,7 +357,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
357
357
|
- !ruby/object:Gem::Version
|
358
358
|
version: '0'
|
359
359
|
requirements: []
|
360
|
-
rubygems_version: 3.
|
360
|
+
rubygems_version: 3.1.4
|
361
361
|
signing_key:
|
362
362
|
specification_version: 4
|
363
363
|
summary: Token based authentication for rails. Uses Devise + OmniAuth.
|
@@ -432,8 +432,8 @@ test_files:
|
|
432
432
|
- test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb
|
433
433
|
- test/dummy/db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb
|
434
434
|
- test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb
|
435
|
+
- test/dummy/tmp/generators/app/controllers/application_controller.rb
|
435
436
|
- test/dummy/tmp/generators/config/initializers/devise_token_auth.rb
|
436
|
-
- test/dummy/tmp/generators/db/migrate/20210126004321_devise_token_auth_create_azpire_v1_human_resource_users.rb
|
437
437
|
- test/dummy/README.rdoc
|
438
438
|
- test/models/only_email_user_test.rb
|
439
439
|
- test/models/confirmable_user_test.rb
|
@@ -1,49 +0,0 @@
|
|
1
|
-
class DeviseTokenAuthCreateAzpireV1HumanResourceUsers < ActiveRecord::Migration[5.2]
|
2
|
-
def change
|
3
|
-
|
4
|
-
create_table(:azpire_v1_human_resource_users) do |t|
|
5
|
-
## Required
|
6
|
-
t.string :provider, :null => false, :default => "email"
|
7
|
-
t.string :uid, :null => false, :default => ""
|
8
|
-
|
9
|
-
## Database authenticatable
|
10
|
-
t.string :encrypted_password, :null => false, :default => ""
|
11
|
-
|
12
|
-
## Recoverable
|
13
|
-
t.string :reset_password_token
|
14
|
-
t.datetime :reset_password_sent_at
|
15
|
-
t.boolean :allow_password_change, :default => false
|
16
|
-
|
17
|
-
## Rememberable
|
18
|
-
t.datetime :remember_created_at
|
19
|
-
|
20
|
-
## Confirmable
|
21
|
-
t.string :confirmation_token
|
22
|
-
t.datetime :confirmed_at
|
23
|
-
t.datetime :confirmation_sent_at
|
24
|
-
t.string :unconfirmed_email # Only if using reconfirmable
|
25
|
-
|
26
|
-
## Lockable
|
27
|
-
# t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
|
28
|
-
# t.string :unlock_token # Only if unlock strategy is :email or :both
|
29
|
-
# t.datetime :locked_at
|
30
|
-
|
31
|
-
## User Info
|
32
|
-
t.string :name
|
33
|
-
t.string :nickname
|
34
|
-
t.string :image
|
35
|
-
t.string :email
|
36
|
-
|
37
|
-
## Tokens
|
38
|
-
t.text :tokens
|
39
|
-
|
40
|
-
t.timestamps
|
41
|
-
end
|
42
|
-
|
43
|
-
add_index :azpire_v1_human_resource_users, :email, unique: true
|
44
|
-
add_index :azpire_v1_human_resource_users, [:uid, :provider], unique: true
|
45
|
-
add_index :azpire_v1_human_resource_users, :reset_password_token, unique: true
|
46
|
-
add_index :azpire_v1_human_resource_users, :confirmation_token, unique: true
|
47
|
-
# add_index :azpire_v1_human_resource_users, :unlock_token, unique: true
|
48
|
-
end
|
49
|
-
end
|