devise_token_auth_multitenancy 1.1.3.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +13 -0
  3. data/README.md +103 -0
  4. data/Rakefile +42 -0
  5. data/app/controllers/devise_token_auth/application_controller.rb +79 -0
  6. data/app/controllers/devise_token_auth/concerns/resource_finder.rb +44 -0
  7. data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +162 -0
  8. data/app/controllers/devise_token_auth/confirmations_controller.rb +82 -0
  9. data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +287 -0
  10. data/app/controllers/devise_token_auth/passwords_controller.rb +206 -0
  11. data/app/controllers/devise_token_auth/registrations_controller.rb +205 -0
  12. data/app/controllers/devise_token_auth/sessions_controller.rb +131 -0
  13. data/app/controllers/devise_token_auth/token_validations_controller.rb +31 -0
  14. data/app/controllers/devise_token_auth/unlocks_controller.rb +89 -0
  15. data/app/models/devise_token_auth/concerns/active_record_support.rb +16 -0
  16. data/app/models/devise_token_auth/concerns/confirmable_support.rb +27 -0
  17. data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
  18. data/app/models/devise_token_auth/concerns/tokens_serialization.rb +19 -0
  19. data/app/models/devise_token_auth/concerns/user.rb +257 -0
  20. data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +28 -0
  21. data/app/validators/devise_token_auth_email_validator.rb +23 -0
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  23. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  24. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  25. data/app/views/devise_token_auth/omniauth_external_window.html.erb +38 -0
  26. data/config/locales/da-DK.yml +52 -0
  27. data/config/locales/de.yml +51 -0
  28. data/config/locales/en.yml +57 -0
  29. data/config/locales/es.yml +51 -0
  30. data/config/locales/fr.yml +51 -0
  31. data/config/locales/he.yml +52 -0
  32. data/config/locales/it.yml +48 -0
  33. data/config/locales/ja.yml +48 -0
  34. data/config/locales/ko.yml +51 -0
  35. data/config/locales/nl.yml +32 -0
  36. data/config/locales/pl.yml +51 -0
  37. data/config/locales/pt-BR.yml +48 -0
  38. data/config/locales/pt.yml +51 -0
  39. data/config/locales/ro.yml +48 -0
  40. data/config/locales/ru.yml +52 -0
  41. data/config/locales/sq.yml +48 -0
  42. data/config/locales/sv.yml +52 -0
  43. data/config/locales/uk.yml +61 -0
  44. data/config/locales/vi.yml +52 -0
  45. data/config/locales/zh-CN.yml +48 -0
  46. data/config/locales/zh-HK.yml +50 -0
  47. data/config/locales/zh-TW.yml +50 -0
  48. data/lib/devise_token_auth/blacklist.rb +2 -0
  49. data/lib/devise_token_auth/controllers/helpers.rb +161 -0
  50. data/lib/devise_token_auth/controllers/url_helpers.rb +10 -0
  51. data/lib/devise_token_auth/engine.rb +96 -0
  52. data/lib/devise_token_auth/errors.rb +8 -0
  53. data/lib/devise_token_auth/rails/routes.rb +116 -0
  54. data/lib/devise_token_auth/token_factory.rb +126 -0
  55. data/lib/devise_token_auth/url.rb +44 -0
  56. data/lib/devise_token_auth/version.rb +5 -0
  57. data/lib/devise_token_auth.rb +14 -0
  58. data/lib/generators/devise_token_auth/USAGE +31 -0
  59. data/lib/generators/devise_token_auth/install_generator.rb +91 -0
  60. data/lib/generators/devise_token_auth/install_generator_helpers.rb +98 -0
  61. data/lib/generators/devise_token_auth/install_mongoid_generator.rb +46 -0
  62. data/lib/generators/devise_token_auth/install_views_generator.rb +18 -0
  63. data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +60 -0
  64. data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +49 -0
  65. data/lib/generators/devise_token_auth/templates/user.rb.erb +9 -0
  66. data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +56 -0
  67. data/lib/tasks/devise_token_auth_tasks.rake +6 -0
  68. data/test/controllers/custom/custom_confirmations_controller_test.rb +25 -0
  69. data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +33 -0
  70. data/test/controllers/custom/custom_passwords_controller_test.rb +79 -0
  71. data/test/controllers/custom/custom_registrations_controller_test.rb +63 -0
  72. data/test/controllers/custom/custom_sessions_controller_test.rb +39 -0
  73. data/test/controllers/custom/custom_token_validations_controller_test.rb +42 -0
  74. data/test/controllers/demo_group_controller_test.rb +151 -0
  75. data/test/controllers/demo_mang_controller_test.rb +284 -0
  76. data/test/controllers/demo_user_controller_test.rb +629 -0
  77. data/test/controllers/devise_token_auth/confirmations_controller_test.rb +191 -0
  78. data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +441 -0
  79. data/test/controllers/devise_token_auth/passwords_controller_test.rb +780 -0
  80. data/test/controllers/devise_token_auth/registrations_controller_test.rb +907 -0
  81. data/test/controllers/devise_token_auth/sessions_controller_test.rb +503 -0
  82. data/test/controllers/devise_token_auth/token_validations_controller_test.rb +102 -0
  83. data/test/controllers/devise_token_auth/unlocks_controller_test.rb +196 -0
  84. data/test/controllers/overrides/confirmations_controller_test.rb +47 -0
  85. data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +53 -0
  86. data/test/controllers/overrides/passwords_controller_test.rb +64 -0
  87. data/test/controllers/overrides/registrations_controller_test.rb +46 -0
  88. data/test/controllers/overrides/sessions_controller_test.rb +35 -0
  89. data/test/controllers/overrides/token_validations_controller_test.rb +43 -0
  90. data/test/dummy/README.rdoc +28 -0
  91. data/test/dummy/app/active_record/confirmable_user.rb +11 -0
  92. data/test/dummy/app/active_record/lockable_user.rb +7 -0
  93. data/test/dummy/app/active_record/mang.rb +5 -0
  94. data/test/dummy/app/active_record/only_email_user.rb +7 -0
  95. data/test/dummy/app/active_record/scoped_user.rb +9 -0
  96. data/test/dummy/app/active_record/unconfirmable_user.rb +9 -0
  97. data/test/dummy/app/active_record/unregisterable_user.rb +9 -0
  98. data/test/dummy/app/active_record/user.rb +6 -0
  99. data/test/dummy/app/controllers/application_controller.rb +18 -0
  100. data/test/dummy/app/controllers/auth_origin_controller.rb +7 -0
  101. data/test/dummy/app/controllers/custom/confirmations_controller.rb +13 -0
  102. data/test/dummy/app/controllers/custom/omniauth_callbacks_controller.rb +13 -0
  103. data/test/dummy/app/controllers/custom/passwords_controller.rb +39 -0
  104. data/test/dummy/app/controllers/custom/registrations_controller.rb +39 -0
  105. data/test/dummy/app/controllers/custom/sessions_controller.rb +29 -0
  106. data/test/dummy/app/controllers/custom/token_validations_controller.rb +19 -0
  107. data/test/dummy/app/controllers/demo_group_controller.rb +15 -0
  108. data/test/dummy/app/controllers/demo_mang_controller.rb +14 -0
  109. data/test/dummy/app/controllers/demo_user_controller.rb +27 -0
  110. data/test/dummy/app/controllers/overrides/confirmations_controller.rb +28 -0
  111. data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +16 -0
  112. data/test/dummy/app/controllers/overrides/passwords_controller.rb +35 -0
  113. data/test/dummy/app/controllers/overrides/registrations_controller.rb +29 -0
  114. data/test/dummy/app/controllers/overrides/sessions_controller.rb +36 -0
  115. data/test/dummy/app/controllers/overrides/token_validations_controller.rb +23 -0
  116. data/test/dummy/app/helpers/application_helper.rb +1058 -0
  117. data/test/dummy/app/models/concerns/favorite_color.rb +19 -0
  118. data/test/dummy/app/mongoid/confirmable_user.rb +52 -0
  119. data/test/dummy/app/mongoid/lockable_user.rb +38 -0
  120. data/test/dummy/app/mongoid/mang.rb +46 -0
  121. data/test/dummy/app/mongoid/only_email_user.rb +33 -0
  122. data/test/dummy/app/mongoid/scoped_user.rb +50 -0
  123. data/test/dummy/app/mongoid/unconfirmable_user.rb +44 -0
  124. data/test/dummy/app/mongoid/unregisterable_user.rb +47 -0
  125. data/test/dummy/app/mongoid/user.rb +49 -0
  126. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  127. data/test/dummy/config/application.rb +48 -0
  128. data/test/dummy/config/application.yml.bk +0 -0
  129. data/test/dummy/config/boot.rb +11 -0
  130. data/test/dummy/config/environment.rb +7 -0
  131. data/test/dummy/config/environments/development.rb +46 -0
  132. data/test/dummy/config/environments/production.rb +84 -0
  133. data/test/dummy/config/environments/test.rb +50 -0
  134. data/test/dummy/config/initializers/assets.rb +10 -0
  135. data/test/dummy/config/initializers/backtrace_silencers.rb +9 -0
  136. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  137. data/test/dummy/config/initializers/devise.rb +290 -0
  138. data/test/dummy/config/initializers/devise_token_auth.rb +55 -0
  139. data/test/dummy/config/initializers/figaro.rb +3 -0
  140. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  141. data/test/dummy/config/initializers/inflections.rb +18 -0
  142. data/test/dummy/config/initializers/mime_types.rb +6 -0
  143. data/test/dummy/config/initializers/omniauth.rb +11 -0
  144. data/test/dummy/config/initializers/session_store.rb +5 -0
  145. data/test/dummy/config/initializers/wrap_parameters.rb +16 -0
  146. data/test/dummy/config/routes.rb +57 -0
  147. data/test/dummy/config/spring.rb +3 -0
  148. data/test/dummy/config.ru +18 -0
  149. data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +58 -0
  150. data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +57 -0
  151. data/test/dummy/db/migrate/20140829044006_add_operating_thetan_to_user.rb +8 -0
  152. data/test/dummy/db/migrate/20140916224624_add_favorite_color_to_mangs.rb +7 -0
  153. data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +55 -0
  154. data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +56 -0
  155. data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +56 -0
  156. data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +56 -0
  157. data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +56 -0
  158. data/test/dummy/db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb +49 -0
  159. data/test/dummy/db/schema.rb +198 -0
  160. data/test/dummy/lib/migration_database_helper.rb +43 -0
  161. data/test/factories/users.rb +41 -0
  162. data/test/lib/devise_token_auth/blacklist_test.rb +11 -0
  163. data/test/lib/devise_token_auth/token_factory_test.rb +191 -0
  164. data/test/lib/devise_token_auth/url_test.rb +26 -0
  165. data/test/lib/generators/devise_token_auth/install_generator_test.rb +217 -0
  166. data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +222 -0
  167. data/test/lib/generators/devise_token_auth/install_views_generator_test.rb +25 -0
  168. data/test/models/concerns/mongoid_support_test.rb +31 -0
  169. data/test/models/concerns/tokens_serialization_test.rb +70 -0
  170. data/test/models/confirmable_user_test.rb +35 -0
  171. data/test/models/only_email_user_test.rb +29 -0
  172. data/test/models/user_test.rb +108 -0
  173. data/test/support/controllers/routes.rb +43 -0
  174. data/test/test_helper.rb +103 -0
  175. metadata +483 -0
@@ -0,0 +1,780 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ # was the web request successful?
6
+ # was the user redirected to the right page?
7
+ # was the user successfully authenticated?
8
+ # was the correct object stored in the response?
9
+ # was the appropriate message delivered in the json payload?
10
+
11
+ class DeviseTokenAuth::PasswordsControllerTest < ActionController::TestCase
12
+ describe DeviseTokenAuth::PasswordsController do
13
+ describe 'Password reset' do
14
+ before do
15
+ @resource = create(:user, :confirmed)
16
+ @redirect_url = 'http://ng-token-auth.dev'
17
+ end
18
+
19
+ describe 'not email should return 401' do
20
+ before do
21
+ @auth_headers = @resource.create_new_auth_token
22
+ @new_password = Faker::Internet.password
23
+
24
+ post :create,
25
+ params: { redirect_url: @redirect_url }
26
+ @data = JSON.parse(response.body)
27
+ end
28
+
29
+ test 'response should fail' do
30
+ assert_equal 401, response.status
31
+ end
32
+
33
+ test 'error message should be returned' do
34
+ assert @data['errors']
35
+ assert_equal @data['errors'],
36
+ [I18n.t('devise_token_auth.passwords.missing_email')]
37
+ end
38
+ end
39
+
40
+ describe 'not redirect_url should return 401' do
41
+ before do
42
+ @auth_headers = @resource.create_new_auth_token
43
+ @new_password = Faker::Internet.password
44
+ end
45
+
46
+ describe 'for create' do
47
+ before do
48
+ post :create,
49
+ params: { email: 'chester@cheet.ah' }
50
+ @data = JSON.parse(response.body)
51
+ end
52
+
53
+ test 'response should fail' do
54
+ assert_equal 401, response.status
55
+ end
56
+
57
+ test 'error message should be returned' do
58
+ assert @data['errors']
59
+ assert_equal(
60
+ @data['errors'],
61
+ [I18n.t('devise_token_auth.passwords.missing_redirect_url')]
62
+ )
63
+ end
64
+ end
65
+
66
+ describe 'for edit' do
67
+ before do
68
+ get_reset_token
69
+ get :edit, params: { reset_password_token: @mail_reset_token}
70
+ @data = JSON.parse(response.body)
71
+ end
72
+
73
+ test 'response should fail' do
74
+ assert_equal 401, response.status
75
+ end
76
+
77
+ test 'error message should be returned' do
78
+ assert @data['errors']
79
+ assert_equal(
80
+ @data['errors'],
81
+ [I18n.t('devise_token_auth.passwords.missing_redirect_url')]
82
+ )
83
+ end
84
+ end
85
+ end
86
+
87
+ describe 'request password reset' do
88
+ describe 'unknown user should return 404' do
89
+ before do
90
+ post :create,
91
+ params: { email: 'chester@cheet.ah',
92
+ redirect_url: @redirect_url }
93
+ @data = JSON.parse(response.body)
94
+ end
95
+
96
+ test 'unknown user should return 404' do
97
+ assert_equal 404, response.status
98
+ end
99
+
100
+ test 'errors should be returned' do
101
+ assert @data['errors']
102
+ assert_equal @data['errors'],
103
+ [I18n.t('devise_token_auth.passwords.user_not_found',
104
+ email: 'chester@cheet.ah')]
105
+ end
106
+ end
107
+
108
+ describe 'successfully requested password reset' do
109
+ before do
110
+ post :create,
111
+ params: { email: @resource.email,
112
+ redirect_url: @redirect_url }
113
+
114
+ @data = JSON.parse(response.body)
115
+ end
116
+
117
+ test 'response should not contain extra data' do
118
+ assert_nil @data['data']
119
+ end
120
+ end
121
+
122
+ describe 'case-sensitive email' do
123
+ before do
124
+ post :create,
125
+ params: { email: @resource.email,
126
+ redirect_url: @redirect_url }
127
+
128
+ @mail = ActionMailer::Base.deliveries.last
129
+ @resource.reload
130
+ @data = JSON.parse(response.body)
131
+
132
+ @mail_config_name = CGI.unescape(@mail.body.match(/config=([^&]*)&/)[1])
133
+ @mail_redirect_url = CGI.unescape(@mail.body.match(/redirect_url=([^&]*)&/)[1])
134
+ @mail_reset_token = @mail.body.match(/reset_password_token=(.*)\"/)[1]
135
+ end
136
+
137
+ test 'response should return success status' do
138
+ assert_equal 200, response.status
139
+ end
140
+
141
+ test 'response should contains message' do
142
+ assert_equal \
143
+ @data['message'],
144
+ I18n.t('devise_token_auth.passwords.sended', email: @resource.email)
145
+ end
146
+
147
+ test 'action should send an email' do
148
+ assert @mail
149
+ end
150
+
151
+ test 'the email should be addressed to the user' do
152
+ assert_equal @mail.to.first, @resource.email
153
+ end
154
+
155
+ test 'the email body should contain a link with redirect url as a query param' do
156
+ assert_equal @redirect_url, @mail_redirect_url
157
+ end
158
+
159
+ test 'the client config name should fall back to "default"' do
160
+ assert_equal 'default', @mail_config_name
161
+ end
162
+
163
+ test 'the email body should contain a link with reset token as a query param' do
164
+ user = User.reset_password_by_token(reset_password_token: @mail_reset_token)
165
+
166
+ assert_equal user.id, @resource.id
167
+ end
168
+
169
+ describe 'password reset link failure' do
170
+ test 'response should return 404' do
171
+ assert_raises(ActionController::RoutingError) do
172
+ get :edit,
173
+ params: { reset_password_token: 'bogus',
174
+ redirect_url: @mail_redirect_url }
175
+ end
176
+ end
177
+ end
178
+
179
+ describe 'password reset link success' do
180
+ before do
181
+ get :edit,
182
+ params: { reset_password_token: @mail_reset_token,
183
+ redirect_url: @mail_redirect_url }
184
+
185
+ @resource.reload
186
+
187
+ raw_qs = response.location.split('?')[1]
188
+ @qs = Rack::Utils.parse_nested_query(raw_qs)
189
+
190
+ @access_token = @qs['access-token']
191
+ @client_id = @qs['client_id']
192
+ @client = @qs['client']
193
+ @expiry = @qs['expiry']
194
+ @reset_password = @qs['reset_password']
195
+ @token = @qs['token']
196
+ @uid = @qs['uid']
197
+ end
198
+
199
+ test 'response should have success redirect status' do
200
+ assert_equal 302, response.status
201
+ end
202
+
203
+ test 'response should contain auth params' do
204
+ assert @access_token
205
+ assert @client
206
+ assert @client_id
207
+ assert @expiry
208
+ assert @reset_password
209
+ assert @token
210
+ assert @uid
211
+ end
212
+
213
+ test 'response auth params should be valid' do
214
+ assert @resource.valid_token?(@token, @client_id)
215
+ assert @resource.valid_token?(@access_token, @client)
216
+ end
217
+ end
218
+ end
219
+
220
+ describe 'case-insensitive email' do
221
+ before do
222
+ @resource_class = User
223
+ @request_params = {
224
+ email: @resource.email.upcase,
225
+ redirect_url: @redirect_url
226
+ }
227
+ end
228
+
229
+ test 'response should return success status if configured' do
230
+ @resource_class.case_insensitive_keys = [:email]
231
+ post :create, params: @request_params
232
+ assert_equal 200, response.status
233
+ end
234
+
235
+ test 'response should return failure status if not configured' do
236
+ @resource_class.case_insensitive_keys = []
237
+ post :create, params: @request_params
238
+ assert_equal 404, response.status
239
+ end
240
+ end
241
+
242
+ describe 'Checking reset_password_token' do
243
+ before do
244
+ post :create, params: {
245
+ email: @resource.email,
246
+ redirect_url: @redirect_url
247
+ }
248
+
249
+ @mail = ActionMailer::Base.deliveries.last
250
+ @mail_redirect_url = CGI.unescape(@mail.body.match(/redirect_url=([^&]*)&/)[1])
251
+ @mail_reset_token = @mail.body.match(/reset_password_token=(.*)\"/)[1]
252
+
253
+ @resource.reload
254
+ end
255
+
256
+ describe 'reset_password_token is valid' do
257
+
258
+ test 'mail_reset_token should be the same as reset_password_token' do
259
+ assert_equal Devise.token_generator.digest(self, :reset_password_token, @mail_reset_token), @resource.reset_password_token
260
+ end
261
+
262
+ test 'reset_password_token should not be rewritten by origin mail_reset_token' do
263
+ get :edit, params: {
264
+ reset_password_token: @mail_reset_token,
265
+ redirect_url: @mail_redirect_url
266
+ }
267
+ @resource.reload
268
+
269
+ assert_equal Devise.token_generator.digest(self, :reset_password_token, @mail_reset_token), @resource.reset_password_token
270
+ end
271
+
272
+ test 'response should return success status' do
273
+ get :edit, params: {
274
+ reset_password_token: @mail_reset_token,
275
+ redirect_url: @mail_redirect_url
276
+ }
277
+
278
+ assert_equal 302, response.status
279
+ end
280
+
281
+ test 'reset_password_sent_at should be valid' do
282
+ assert_equal @resource.reset_password_period_valid?, true
283
+
284
+ get :edit, params: {
285
+ reset_password_token: @mail_reset_token,
286
+ redirect_url: @mail_redirect_url
287
+ }
288
+
289
+ @resource.reload
290
+ assert_equal Devise.token_generator.digest(self, :reset_password_token, @mail_reset_token), @resource.reset_password_token
291
+ end
292
+
293
+ test 'reset_password_sent_at should be expired' do
294
+ assert_equal @resource.reset_password_period_valid?, true
295
+
296
+ @resource.update reset_password_sent_at: @resource.reset_password_sent_at - Devise.reset_password_within - 1.seconds
297
+ assert_equal @resource.reset_password_period_valid?, false
298
+
299
+ assert_raises(ActionController::RoutingError) {
300
+ get :edit, params: {
301
+ reset_password_token: @mail_reset_token,
302
+ redirect_url: @mail_redirect_url
303
+ }
304
+ }
305
+ end
306
+ end
307
+
308
+ describe 'reset_password_token is not valid' do
309
+ test 'response should return error status' do
310
+ @resource.update reset_password_token: 'koskoskoskos'
311
+
312
+ assert_not_equal Devise.token_generator.digest(self, :reset_password_token, @mail_reset_token), @resource.reset_password_token
313
+
314
+ assert_raises(ActionController::RoutingError) {
315
+ get :edit, params: {
316
+ reset_password_token: @mail_reset_token,
317
+ redirect_url: @mail_redirect_url
318
+ }
319
+ }
320
+ end
321
+ end
322
+ end
323
+ end
324
+
325
+ describe 'Using default_password_reset_url' do
326
+ before do
327
+ @resource = create(:user, :confirmed)
328
+ @redirect_url = 'http://ng-token-auth.dev'
329
+
330
+ DeviseTokenAuth.default_password_reset_url = @redirect_url
331
+
332
+ post :create,
333
+ params: { email: @resource.email,
334
+ redirect_url: @redirect_url }
335
+
336
+ @mail = ActionMailer::Base.deliveries.last
337
+ @resource.reload
338
+
339
+ @sent_redirect_url = CGI.unescape(@mail.body.match(/redirect_url=([^&]*)&/)[1])
340
+ end
341
+
342
+ teardown do
343
+ DeviseTokenAuth.default_password_reset_url = nil
344
+ end
345
+
346
+ test 'response should return success status' do
347
+ assert_equal 200, response.status
348
+ end
349
+
350
+ test 'action should send an email' do
351
+ assert @mail
352
+ end
353
+
354
+ test 'the email body should contain a link with redirect url as a query param' do
355
+ assert_equal @redirect_url, @sent_redirect_url
356
+ end
357
+ end
358
+
359
+ describe 'Using redirect_whitelist' do
360
+ before do
361
+ @good_redirect_url = @redirect_url
362
+ @bad_redirect_url = Faker::Internet.url
363
+ DeviseTokenAuth.redirect_whitelist = [@good_redirect_url]
364
+ end
365
+
366
+ teardown do
367
+ DeviseTokenAuth.redirect_whitelist = nil
368
+ end
369
+
370
+ describe 'for create' do
371
+ test 'request to whitelisted redirect should be successful' do
372
+ post :create,
373
+ params: { email: @resource.email,
374
+ redirect_url: @good_redirect_url }
375
+
376
+ assert_equal 200, response.status
377
+ end
378
+
379
+ test 'request to non-whitelisted redirect should fail' do
380
+ post :create,
381
+ params: { email: @resource.email,
382
+ redirect_url: @bad_redirect_url }
383
+
384
+ assert_equal 422, response.status
385
+ end
386
+
387
+ test 'request to non-whitelisted redirect should return error message' do
388
+ post :create,
389
+ params: { email: @resource.email,
390
+ redirect_url: @bad_redirect_url }
391
+
392
+ @data = JSON.parse(response.body)
393
+ assert @data['errors']
394
+ assert_equal @data['errors'],
395
+ [I18n.t('devise_token_auth.passwords.not_allowed_redirect_url',
396
+ redirect_url: @bad_redirect_url)]
397
+ end
398
+ end
399
+
400
+ describe 'for edit' do
401
+ before do
402
+ @auth_headers = @resource.create_new_auth_token
403
+ @new_password = Faker::Internet.password
404
+
405
+ get_reset_token
406
+ end
407
+
408
+ test 'request to whitelisted redirect should be successful' do
409
+ get :edit, params: { reset_password_token: @mail_reset_token, redirect_url: @good_redirect_url }
410
+
411
+ assert_equal 302, response.status
412
+ end
413
+
414
+ test 'request to non-whitelisted redirect should fail' do
415
+ get :edit, params: { reset_password_token: @mail_reset_token, redirect_url: @bad_redirect_url }
416
+
417
+ assert_equal 422, response.status
418
+ end
419
+
420
+ test 'request to non-whitelisted redirect should return error message' do
421
+ get :edit, params: { reset_password_token: @mail_reset_token, redirect_url: @bad_redirect_url }
422
+
423
+ @data = JSON.parse(response.body)
424
+ assert @data['errors']
425
+ assert_equal @data['errors'],
426
+ [I18n.t('devise_token_auth.passwords.not_allowed_redirect_url',
427
+ redirect_url: @bad_redirect_url)]
428
+ end
429
+ end
430
+ end
431
+
432
+ describe 'change password with current password required' do
433
+ before do
434
+ DeviseTokenAuth.check_current_password_before_update = :password
435
+ end
436
+
437
+ after do
438
+ DeviseTokenAuth.check_current_password_before_update = false
439
+ end
440
+
441
+ describe 'success' do
442
+ before do
443
+ DeviseTokenAuth.require_client_password_reset_token = false
444
+ @auth_headers = @resource.create_new_auth_token
445
+ request.headers.merge!(@auth_headers)
446
+ @new_password = Faker::Internet.password
447
+ @resource.update password: 'secret123', password_confirmation: 'secret123'
448
+
449
+ put :update,
450
+ params: { password: @new_password,
451
+ password_confirmation: @new_password,
452
+ current_password: 'secret123' }
453
+
454
+ @data = JSON.parse(response.body)
455
+ @resource.reload
456
+ end
457
+
458
+ test 'request should be successful' do
459
+ assert_equal 200, response.status
460
+ end
461
+ end
462
+
463
+ describe 'success with after password reset' do
464
+ before do
465
+ # create a new password reset request
466
+ post :create, params: { email: @resource.email,
467
+ redirect_url: @redirect_url }
468
+
469
+ @mail = ActionMailer::Base.deliveries.last
470
+ @mail_redirect_url = CGI.unescape(@mail.body.match(/redirect_url=([^&]*)&/)[1])
471
+ @mail_reset_token = @mail.body.match(/reset_password_token=(.*)\"/)[1]
472
+
473
+ # confirm via password reset email link
474
+ get :edit, params: { reset_password_token: @mail_reset_token,
475
+ redirect_url: @mail_redirect_url }
476
+
477
+ @resource.reload
478
+ @allow_password_change_after_reset = @resource.allow_password_change
479
+
480
+ @auth_headers = @resource.create_new_auth_token
481
+ request.headers.merge!(@auth_headers)
482
+ @new_password = Faker::Internet.password
483
+
484
+ put :update, params: { password: @new_password,
485
+ password_confirmation: @new_password }
486
+
487
+ @data = JSON.parse(response.body)
488
+ @resource.reload
489
+ @allow_password_change = @resource.allow_password_change
490
+ @resource.reload
491
+ end
492
+
493
+ test 'request should be successful' do
494
+ assert_equal 200, response.status
495
+ end
496
+
497
+ test 'changes allow_password_change to true on reset' do
498
+ assert_equal true, @allow_password_change_after_reset
499
+ end
500
+
501
+ test 'sets allow_password_change false' do
502
+ assert_equal false, @allow_password_change
503
+ end
504
+ end
505
+
506
+ describe 'current password mismatch error' do
507
+ before do
508
+ DeviseTokenAuth.require_client_password_reset_token = false
509
+ @auth_headers = @resource.create_new_auth_token
510
+ request.headers.merge!(@auth_headers)
511
+ @new_password = Faker::Internet.password
512
+
513
+ put :update, params: { password: @new_password,
514
+ password_confirmation: @new_password,
515
+ current_password: 'not_very_secret321' }
516
+ end
517
+
518
+ test 'response should fail unauthorized' do
519
+ assert_equal 422, response.status
520
+ end
521
+ end
522
+ end
523
+
524
+ describe 'change password' do
525
+ describe 'using reset token' do
526
+ before do
527
+ DeviseTokenAuth.require_client_password_reset_token = true
528
+ @redirect_url = 'http://client-app.dev'
529
+ get_reset_token
530
+ edit_url = CGI.unescape(@mail.body.match(/href=\"(.+)\"/)[1])
531
+ query_parts = Rack::Utils.parse_nested_query(URI.parse(edit_url).query)
532
+ get :edit, params: query_parts
533
+ end
534
+
535
+ test 'request should be redirect' do
536
+ assert_equal 302, response.status
537
+ end
538
+
539
+ test 'request should redirect to correct redirect url' do
540
+ host = URI.parse(response.location).host
541
+ query_parts = Rack::Utils.parse_nested_query(URI.parse(response.location).query)
542
+
543
+ assert_equal 'client-app.dev', host
544
+ assert_equal @mail_reset_token, query_parts['reset_password_token']
545
+ assert_equal 1, query_parts.keys.size
546
+ end
547
+
548
+ teardown do
549
+ DeviseTokenAuth.require_client_password_reset_token = false
550
+ end
551
+ end
552
+
553
+ describe 'with valid headers' do
554
+ before do
555
+ @auth_headers = @resource.create_new_auth_token
556
+ request.headers.merge!(@auth_headers)
557
+ @new_password = Faker::Internet.password
558
+
559
+ put :update, params: { password: @new_password,
560
+ password_confirmation: @new_password }
561
+
562
+ @data = JSON.parse(response.body)
563
+ @resource.reload
564
+ end
565
+
566
+ test 'request should be successful' do
567
+ assert_equal 200, response.status
568
+ end
569
+
570
+ test 'request should return success message' do
571
+ assert @data['message']
572
+ assert_equal @data['message'],
573
+ I18n.t('devise_token_auth.passwords.successfully_updated')
574
+ end
575
+
576
+ test 'new password should authenticate user' do
577
+ assert @resource.valid_password?(@new_password)
578
+ end
579
+
580
+ test 'reset_password_token should be removed' do
581
+ assert_nil @resource.reset_password_token
582
+ end
583
+ end
584
+
585
+ describe 'password mismatch error' do
586
+ before do
587
+ @auth_headers = @resource.create_new_auth_token
588
+ request.headers.merge!(@auth_headers)
589
+ @new_password = Faker::Internet.password
590
+
591
+ put :update, params: { password: 'chong',
592
+ password_confirmation: 'bong' }
593
+ end
594
+
595
+ test 'response should fail' do
596
+ assert_equal 422, response.status
597
+ end
598
+ end
599
+
600
+ describe 'without valid headers' do
601
+ before do
602
+ @resource.create_new_auth_token
603
+ new_password = Faker::Internet.password
604
+
605
+ put :update, params: { password: new_password,
606
+ password_confirmation: new_password }
607
+ end
608
+
609
+ test 'response should fail' do
610
+ assert_equal 401, response.status
611
+ end
612
+ end
613
+
614
+ describe 'with valid reset password token' do
615
+ before do
616
+ reset_password_token = @resource.send_reset_password_instructions
617
+ @new_password = Faker::Internet.password
618
+ @params = { password: @new_password,
619
+ password_confirmation: @new_password,
620
+ reset_password_token: reset_password_token }
621
+ end
622
+
623
+ describe 'with require_client_password_reset_token disabled' do
624
+ before do
625
+ DeviseTokenAuth.require_client_password_reset_token = false
626
+ put :update, params: @params
627
+
628
+ @data = JSON.parse(response.body)
629
+ @resource.reload
630
+ end
631
+
632
+ test 'request should be not be successful' do
633
+ assert_equal 401, response.status
634
+ end
635
+ end
636
+
637
+ describe 'with require_client_password_reset_token enabled' do
638
+ before do
639
+ DeviseTokenAuth.require_client_password_reset_token = true
640
+ put :update, params: @params
641
+
642
+ @data = JSON.parse(response.body)
643
+ @resource.reload
644
+ end
645
+
646
+ test 'request should be successful' do
647
+ assert_equal 200, response.status
648
+ end
649
+
650
+ test 'request should return success message' do
651
+ assert @data['message']
652
+ assert_equal @data['message'],
653
+ I18n.t('devise_token_auth.passwords.successfully_updated')
654
+ end
655
+
656
+ test 'new password should authenticate user' do
657
+ assert @resource.valid_password?(@new_password)
658
+ end
659
+
660
+ teardown do
661
+ DeviseTokenAuth.require_client_password_reset_token = false
662
+ end
663
+ end
664
+ end
665
+
666
+ describe 'with invalid reset password token' do
667
+ before do
668
+ DeviseTokenAuth.require_client_password_reset_token = true
669
+ @resource.update reset_password_token: 'koskoskoskos'
670
+ put :update, params: @params
671
+ @data = JSON.parse(response.body)
672
+ @resource.reload
673
+ end
674
+
675
+ test 'request should fail' do
676
+ assert_equal 401, response.status
677
+ end
678
+
679
+ test 'new password should not authenticate user' do
680
+ assert !@resource.valid_password?(@new_password)
681
+ end
682
+
683
+ teardown do
684
+ DeviseTokenAuth.require_client_password_reset_token = false
685
+ end
686
+ end
687
+ end
688
+ end
689
+
690
+ describe 'Alternate user class' do
691
+ setup do
692
+ @request.env['devise.mapping'] = Devise.mappings[:mang]
693
+ end
694
+
695
+ teardown do
696
+ @request.env['devise.mapping'] = Devise.mappings[:user]
697
+ end
698
+
699
+ before do
700
+ @resource = create(:mang_user, :confirmed)
701
+ @redirect_url = 'http://ng-token-auth.dev'
702
+ get_reset_token
703
+ end
704
+
705
+ test 'response should return success status' do
706
+ assert_equal 200, response.status
707
+ end
708
+
709
+ test 'the email body should contain a link with reset token as a query param' do
710
+ user = Mang.reset_password_by_token(reset_password_token: @mail_reset_token)
711
+
712
+ assert_equal user.id, @resource.id
713
+ end
714
+ end
715
+
716
+ describe 'unconfirmed user' do
717
+ before do
718
+ @resource = create(:user)
719
+ @redirect_url = 'http://ng-token-auth.dev'
720
+
721
+ get_reset_token
722
+
723
+ get :edit, params: { reset_password_token: @mail_reset_token,
724
+ redirect_url: @mail_redirect_url }
725
+
726
+ @resource.reload
727
+ end
728
+ end
729
+
730
+ describe 'unconfirmable user' do
731
+ setup do
732
+ @request.env['devise.mapping'] = Devise.mappings[:unconfirmable_user]
733
+ end
734
+
735
+ teardown do
736
+ @request.env['devise.mapping'] = Devise.mappings[:user]
737
+ end
738
+
739
+ before do
740
+ @resource = unconfirmable_users(:user)
741
+
742
+ get_reset_token
743
+
744
+ get :edit, params: { reset_password_token: @mail_reset_token,
745
+ redirect_url: @mail_redirect_url }
746
+
747
+ @resource.reload
748
+ end
749
+ end
750
+
751
+ describe 'alternate user type' do
752
+ before do
753
+ @resource = create(:user, :confirmed)
754
+ @redirect_url = 'http://ng-token-auth.dev'
755
+ @config_name = 'altUser'
756
+
757
+ params = { email: @resource.email,
758
+ redirect_url: @redirect_url,
759
+ config_name: @config_name }
760
+ get_reset_token params
761
+ end
762
+
763
+ test 'config_name param is included in the confirmation email link' do
764
+ assert_equal @config_name, @mail_config_name
765
+ end
766
+ end
767
+
768
+ def get_reset_token(params = nil)
769
+ params ||= { email: @resource.email, redirect_url: @redirect_url }
770
+ post :create, params: params
771
+
772
+ @mail = ActionMailer::Base.deliveries.last
773
+ @resource.reload
774
+
775
+ @mail_config_name = CGI.unescape(@mail.body.match(/config=([^&]*)&/)[1])
776
+ @mail_redirect_url = CGI.unescape(@mail.body.match(/redirect_url=([^&]*)&/)[1])
777
+ @mail_reset_token = @mail.body.match(/reset_password_token=(.*)\"/)[1]
778
+ end
779
+ end
780
+ end