devise_token_auth 1.0.0 → 1.1.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.

Potentially problematic release.


This version of devise_token_auth might be problematic. Click here for more details.

Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +2 -2
  3. data/app/controllers/devise_token_auth/application_controller.rb +0 -1
  4. data/app/controllers/devise_token_auth/concerns/resource_finder.rb +11 -12
  5. data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +15 -28
  6. data/app/controllers/devise_token_auth/confirmations_controller.rb +14 -19
  7. data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +46 -21
  8. data/app/controllers/devise_token_auth/passwords_controller.rb +15 -19
  9. data/app/controllers/devise_token_auth/registrations_controller.rb +31 -39
  10. data/app/controllers/devise_token_auth/unlocks_controller.rb +1 -1
  11. data/app/models/devise_token_auth/concerns/active_record_support.rb +34 -0
  12. data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
  13. data/app/models/devise_token_auth/concerns/user.rb +9 -23
  14. data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +2 -2
  15. data/app/validators/{email_validator.rb → devise_token_auth/email_validator.rb} +1 -1
  16. data/config/locales/he.yml +50 -0
  17. data/config/locales/ja.yml +1 -1
  18. data/lib/devise_token_auth.rb +5 -3
  19. data/lib/devise_token_auth/blacklist.rb +2 -0
  20. data/lib/devise_token_auth/version.rb +1 -1
  21. data/lib/generators/devise_token_auth/install_generator.rb +3 -87
  22. data/lib/generators/devise_token_auth/install_generator_helpers.rb +98 -0
  23. data/lib/generators/devise_token_auth/install_mongoid_generator.rb +46 -0
  24. data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +0 -7
  25. data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +56 -0
  26. data/test/controllers/custom/custom_confirmations_controller_test.rb +1 -1
  27. data/test/controllers/devise_token_auth/confirmations_controller_test.rb +41 -20
  28. data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +2 -0
  29. data/test/controllers/devise_token_auth/passwords_controller_test.rb +115 -94
  30. data/test/controllers/devise_token_auth/registrations_controller_test.rb +31 -4
  31. data/test/controllers/devise_token_auth/sessions_controller_test.rb +0 -38
  32. data/test/controllers/devise_token_auth/token_validations_controller_test.rb +2 -1
  33. data/test/dummy/app/{models → active_record}/lockable_user.rb +0 -0
  34. data/test/dummy/app/{models → active_record}/mang.rb +0 -0
  35. data/test/dummy/app/{models → active_record}/only_email_user.rb +0 -0
  36. data/test/dummy/app/{models → active_record}/scoped_user.rb +2 -2
  37. data/test/dummy/app/{models → active_record}/unconfirmable_user.rb +1 -2
  38. data/test/dummy/app/{models → active_record}/unregisterable_user.rb +3 -3
  39. data/test/dummy/app/active_record/user.rb +6 -0
  40. data/test/dummy/app/controllers/overrides/sessions_controller.rb +1 -1
  41. data/test/dummy/app/models/{user.rb → concerns/favorite_color.rb} +7 -8
  42. data/test/dummy/app/mongoid/lockable_user.rb +38 -0
  43. data/test/dummy/app/mongoid/mang.rb +46 -0
  44. data/test/dummy/app/mongoid/only_email_user.rb +33 -0
  45. data/test/dummy/app/mongoid/scoped_user.rb +50 -0
  46. data/test/dummy/app/mongoid/unconfirmable_user.rb +44 -0
  47. data/test/dummy/app/mongoid/unregisterable_user.rb +47 -0
  48. data/test/dummy/app/mongoid/user.rb +49 -0
  49. data/test/dummy/config/application.rb +23 -1
  50. data/test/dummy/config/boot.rb +4 -0
  51. data/test/dummy/config/initializers/devise.rb +12 -0
  52. data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +0 -7
  53. data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +0 -7
  54. data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +0 -7
  55. data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +0 -7
  56. data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +0 -7
  57. data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +0 -7
  58. data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +0 -7
  59. data/test/dummy/db/schema.rb +1 -28
  60. data/test/dummy/tmp/generators/app/models/azpire/v1/human_resource/user.rb +9 -0
  61. data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +50 -0
  62. data/test/dummy/tmp/generators/config/routes.rb +4 -0
  63. data/test/dummy/tmp/generators/db/migrate/20190112150327_devise_token_auth_create_azpire_v1_human_resource_users.rb +56 -0
  64. data/test/lib/devise_token_auth/blacklist_test.rb +11 -0
  65. data/test/lib/generators/devise_token_auth/install_generator_test.rb +51 -31
  66. data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +51 -31
  67. data/test/models/concerns/mongoid_support_test.rb +31 -0
  68. data/test/models/only_email_user_test.rb +0 -8
  69. data/test/models/user_test.rb +1 -1
  70. data/test/test_helper.rb +12 -2
  71. metadata +91 -27
  72. data/config/initializers/devise.rb +0 -198
  73. data/test/dummy/tmp/generators/app/views/devise/mailer/confirmation_instructions.html.erb +0 -5
  74. data/test/dummy/tmp/generators/app/views/devise/mailer/reset_password_instructions.html.erb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 916c84285bb6b805d3a70a5adc8e86d83efb348e
4
- data.tar.gz: 38deed793c1466de04cd75ab4861627a5eb18447
2
+ SHA256:
3
+ metadata.gz: 5baf8b0a539be2dcf9b1add5ee2dfaac82753127a6180500c653e7d710c04da3
4
+ data.tar.gz: 794584507c533b59b88c724c810f7099d06221ff35faab7ee558f92d6849688e
5
5
  SHA512:
6
- metadata.gz: 4b631710faf5afc08a2f0f0fc89a96e63c7fe07d0c7a985a19d3b5c0a18801401afe67525aa6e0a078195ca4d24c58b6a6651da667c2a7a7f40723d4974dc850
7
- data.tar.gz: 8707ad62656749fc88de275533456b93c17545f854e40f03920365c2ba9a11c170af44787118c4d8bc59ef593c5535ce8e09c512338c0de8af860c7e2500746f
6
+ metadata.gz: 58f70c5a715ef337e2d949261f0c774f020831f9755d12fc37b04ca4cba2e416080658946bdb95f5fc1625a3a53c3836202b9e9842dbf420363959be163786cc
7
+ data.tar.gz: 8991c6cea21651fff0c98561ac6004bd4a75e04e78ad1af749c04e71fcb9caf8ebb19255ecb78ae91e610b6db05d878d9cf41492560941ea131bcefb7ea0bc0b
data/README.md CHANGED
@@ -19,7 +19,7 @@ Also, it maintains a session for each client/device, so you can have as many ses
19
19
 
20
20
  * Seamless integration with:
21
21
  * [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) for [AngularJS](https://github.com/angular/angular.js)
22
- * [Angular2-Token](https://github.com/neroniaky/angular2-token) for [Angular2](https://github.com/angular/angular)
22
+ * [Angular-Token](https://github.com/neroniaky/angular-token) for [Angular](https://github.com/angular/angular)
23
23
  * [redux-token-auth](https://github.com/kylecorbelli/redux-token-auth) for [React with Redux](https://github.com/reactjs/react-redux)
24
24
  * [jToker](https://github.com/lynndylanhurley/j-toker) for [jQuery](https://jquery.com/)
25
25
  * Oauth2 authentication using [OmniAuth](https://github.com/intridea/omniauth).
@@ -69,7 +69,7 @@ See our [Contribution Guidelines](https://github.com/lynndylanhurley/devise_toke
69
69
 
70
70
  [Here is a demo](http://ng-token-auth-demo.herokuapp.com/) of this app running with the [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) module and [AngularJS](https://github.com/angular/angular.js).
71
71
 
72
- [Here is a demo](https://angular2-token.herokuapp.com) of this app running with the [Angular2-Token](https://github.com/neroniaky/angular2-token) service and [Angular2](https://github.com/angular/angular).
72
+ [Here is a demo](https://stackblitz.com/github/neroniaky/angular-token) of this app running with the [Angular-Token](https://github.com/neroniaky/angular-token) service and [Angular](https://github.com/angular/angular).
73
73
 
74
74
  [Here is a demo](https://j-toker-demo.herokuapp.com/) of this app using the [jToker](https://github.com/lynndylanhurley/j-toker) plugin and [React](http://facebook.github.io/react/).
75
75
 
@@ -3,7 +3,6 @@
3
3
  module DeviseTokenAuth
4
4
  class ApplicationController < DeviseController
5
5
  include DeviseTokenAuth::Concerns::SetUserByToken
6
- include DeviseTokenAuth::Concerns::ResourceFinder
7
6
 
8
7
  def resource_data(opts = {})
9
8
  response_data = opts[:resource_json] || @resource.as_json
@@ -20,21 +20,20 @@ module DeviseTokenAuth::Concerns::ResourceFinder
20
20
  end
21
21
 
22
22
  def find_resource(field, value)
23
- # fix for mysql default case insensitivity
24
- q = "#{field.to_s} = ? AND provider='#{provider.to_s}'"
25
- if ActiveRecord::Base.connection.adapter_name.downcase.starts_with? 'mysql'
26
- q = 'BINARY ' + q
27
- end
28
-
29
- @resource = resource_class.where(q, value).first
23
+ @resource = if resource_class.try(:connection_config).try(:[], :adapter).try(:include?, 'mysql')
24
+ # fix for mysql default case insensitivity
25
+ resource_class.where("BINARY #{field} = ? AND provider= ?", value, provider).first
26
+ else
27
+ resource_class.dta_find_by(field => value, 'provider' => provider)
28
+ end
30
29
  end
31
30
 
32
31
  def resource_class(m = nil)
33
- if m
34
- mapping = Devise.mappings[m]
35
- else
36
- mapping = Devise.mappings[resource_name] || Devise.mappings.values.first
37
- end
32
+ mapping = if m
33
+ Devise.mappings[m]
34
+ else
35
+ Devise.mappings[resource_name] || Devise.mappings.values.first
36
+ end
38
37
 
39
38
  mapping.to
40
39
  end
@@ -23,18 +23,6 @@ module DeviseTokenAuth::Concerns::SetUserByToken
23
23
  @is_batch_request ||= nil
24
24
  end
25
25
 
26
- def ensure_pristine_resource
27
- if @resource.changed?
28
- # Stash pending changes in the resource before reloading.
29
- changes = @resource.changes
30
- @resource.reload
31
- end
32
- yield
33
- ensure
34
- # Reapply pending changes
35
- @resource.assign_attributes(changes) if changes
36
- end
37
-
38
26
  # user auth
39
27
  def set_user_by_token(mapping = nil)
40
28
  # determine target authentication class
@@ -80,14 +68,15 @@ module DeviseTokenAuth::Concerns::SetUserByToken
80
68
  return false unless @token
81
69
 
82
70
  # mitigate timing attacks by finding by uid instead of auth token
83
- user = uid && rc.find_by(uid: uid)
71
+ user = uid && rc.dta_find_by(uid: uid)
72
+ scope = rc.to_s.underscore.to_sym
84
73
 
85
74
  if user && user.valid_token?(@token, @client_id)
86
75
  # sign_in with bypass: true will be deprecated in the next version of Devise
87
76
  if respond_to?(:bypass_sign_in) && DeviseTokenAuth.bypass_sign_in
88
- bypass_sign_in(user, scope: :user)
77
+ bypass_sign_in(user, scope: scope)
89
78
  else
90
- sign_in(:user, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
79
+ sign_in(scope, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
91
80
  end
92
81
  return @resource = user
93
82
  else
@@ -130,25 +119,23 @@ module DeviseTokenAuth::Concerns::SetUserByToken
130
119
  private
131
120
 
132
121
  def refresh_headers
133
- ensure_pristine_resource do
134
- # Lock the user record during any auth_header updates to ensure
135
- # we don't have write contention from multiple threads
136
- @resource.with_lock do
137
- # should not append auth header if @resource related token was
138
- # cleared by sign out in the meantime
139
- return if @used_auth_by_token && @resource.tokens[@client_id].nil?
140
-
141
- # update the response header
142
- response.headers.merge!(auth_header_from_batch_request)
143
- end # end lock
144
- end # end ensure_pristine_resource
122
+ # Lock the user record during any auth_header updates to ensure
123
+ # we don't have write contention from multiple threads
124
+ @resource.with_lock do
125
+ # should not append auth header if @resource related token was
126
+ # cleared by sign out in the meantime
127
+ return if @used_auth_by_token && @resource.tokens[@client_id].nil?
128
+
129
+ # update the response header
130
+ response.headers.merge!(auth_header_from_batch_request)
131
+ end # end lock
145
132
  end
146
133
 
147
134
  def is_batch_request?(user, client_id)
148
135
  !params[:unbatch] &&
149
136
  user.tokens[client_id] &&
150
137
  user.tokens[client_id]['updated_at'] &&
151
- Time.parse(user.tokens[client_id]['updated_at']) > @request_started_at - DeviseTokenAuth.batch_request_buffer_throttle
138
+ user.tokens[client_id]['updated_at'].to_time > @request_started_at - DeviseTokenAuth.batch_request_buffer_throttle
152
139
  end
153
140
 
154
141
  def auth_header_from_batch_request
@@ -5,32 +5,27 @@ module DeviseTokenAuth
5
5
  def show
6
6
  @resource = resource_class.confirm_by_token(params[:confirmation_token])
7
7
 
8
- if @resource && @resource.id
9
- expiry = nil
10
- if defined?(@resource.sign_in_count) && @resource.sign_in_count > 0
11
- expiry = (Time.zone.now + 1.second).to_i
12
- end
13
-
14
- client_id, token = @resource.create_token expiry: expiry
15
-
16
- sign_in(@resource)
17
- @resource.save!
18
-
8
+ if @resource.errors.empty?
19
9
  yield @resource if block_given?
20
10
 
21
11
  redirect_header_options = { account_confirmation_success: true }
22
- redirect_headers = build_redirect_headers(token,
23
- client_id,
24
- redirect_header_options)
25
12
 
26
- # give redirect value from params priority
27
- @redirect_url = params[:redirect_url]
13
+ # give redirect value from params priority or fall back to default value if provided
14
+ redirect_url = params[:redirect_url] || DeviseTokenAuth.default_confirm_success_url
15
+
16
+ if signed_in?(resource_name)
17
+ client_id, token = signed_in_resource.create_token
28
18
 
29
- # fall back to default value if provided
30
- @redirect_url ||= DeviseTokenAuth.default_confirm_success_url
19
+ redirect_headers = build_redirect_headers(token,
20
+ client_id,
21
+ redirect_header_options)
31
22
 
23
+ redirect_to_link = signed_in_resource.build_auth_url(redirect_url, redirect_headers)
24
+ else
25
+ redirect_to_link = DeviseTokenAuth::Url.generate(redirect_url, redirect_header_options)
26
+ end
32
27
 
33
- redirect_to(@resource.build_auth_url(@redirect_url, redirect_headers))
28
+ redirect_to(redirect_to_link)
34
29
  else
35
30
  raise ActionController::RoutingError, 'Not Found'
36
31
  end
@@ -12,11 +12,8 @@ module DeviseTokenAuth
12
12
 
13
13
  # derive target redirect route from 'resource_class' param, which was set
14
14
  # before authentication.
15
- devise_mapping = [request.env['omniauth.params']['namespace_name'],
16
- request.env['omniauth.params']['resource_class'].underscore.gsub('/', '_')].compact.join('_')
17
- path = "#{Devise.mappings[devise_mapping.to_sym].fullpath}/#{params[:provider]}/callback"
18
- klass = request.scheme == 'https' ? URI::HTTPS : URI::HTTP
19
- redirect_route = klass.build(host: request.host, port: request.port, path: path).to_s
15
+ devise_mapping = get_devise_mapping
16
+ redirect_route = get_redirect_route(devise_mapping)
20
17
 
21
18
  # preserve omniauth info for success route. ignore 'extra' in twitter
22
19
  # auth response to avoid CookieOverflow.
@@ -26,6 +23,34 @@ module DeviseTokenAuth
26
23
  redirect_to redirect_route
27
24
  end
28
25
 
26
+ def get_redirect_route(devise_mapping)
27
+ path = "#{Devise.mappings[devise_mapping.to_sym].fullpath}/#{params[:provider]}/callback"
28
+ klass = request.scheme == 'https' ? URI::HTTPS : URI::HTTP
29
+ redirect_route = klass.build(host: request.host, port: request.port, path: path).to_s
30
+ end
31
+
32
+ def get_devise_mapping
33
+ # derive target redirect route from 'resource_class' param, which was set
34
+ # before authentication.
35
+ devise_mapping = [request.env['omniauth.params']['namespace_name'],
36
+ request.env['omniauth.params']['resource_class'].underscore.gsub('/', '_')].compact.join('_')
37
+ rescue NoMethodError => err
38
+ default_devise_mapping
39
+ end
40
+
41
+ # This method will only be called if `get_devise_mapping` cannot
42
+ # find the mapping in `omniauth.params`.
43
+ #
44
+ # One example use-case here is for IDP-initiated SAML login. In that
45
+ # case, there will have been no initial request in which to save
46
+ # the devise mapping. If you are in a situation like that, and
47
+ # your app allows for you to determine somehow what the devise
48
+ # mapping should be (because, for example, it is always the same),
49
+ # then you can handle it by overriding this method.
50
+ def default_devise_mapping
51
+ raise NotImplementedError.new('no default_devise_mapping set')
52
+ end
53
+
29
54
  def omniauth_success
30
55
  get_resource_from_auth_hash
31
56
  set_token_on_resource
@@ -37,7 +62,7 @@ module DeviseTokenAuth
37
62
  end
38
63
 
39
64
  sign_in(:user, @resource, store: false, bypass: false)
40
-
65
+
41
66
  @resource.save!
42
67
 
43
68
  yield @resource if block_given?
@@ -79,7 +104,7 @@ module DeviseTokenAuth
79
104
 
80
105
  # break out provider attribute assignment for easy method extension
81
106
  def assign_provider_attrs(user, auth_hash)
82
- attrs = auth_hash['info'].slice(*user.attributes.keys)
107
+ attrs = auth_hash['info'].slice(*user.attribute_names)
83
108
  user.assign_attributes(attrs)
84
109
  end
85
110
 
@@ -136,16 +161,6 @@ module DeviseTokenAuth
136
161
  true
137
162
  end
138
163
 
139
- # necessary for access to devise_parameter_sanitizers
140
- def devise_mapping
141
- if omniauth_params
142
- Devise.mappings[[omniauth_params['namespace_name'],
143
- omniauth_params['resource_class'].underscore].compact.join('_').to_sym]
144
- else
145
- request.env['devise.mapping']
146
- end
147
- end
148
-
149
164
  def set_random_password
150
165
  # set crazy password for new oauth users. this is only used to prevent
151
166
  # access via email sign-in.
@@ -214,6 +229,15 @@ module DeviseTokenAuth
214
229
  </html>)
215
230
  end
216
231
 
232
+ def handle_new_resource
233
+ @oauth_registration = true
234
+ set_random_password
235
+ end
236
+
237
+ def assign_whitelisted_params?
238
+ true
239
+ end
240
+
217
241
  def get_resource_from_auth_hash
218
242
  # find or create user by provider and provider uid
219
243
  @resource = resource_class.where(
@@ -222,16 +246,17 @@ module DeviseTokenAuth
222
246
  ).first_or_initialize
223
247
 
224
248
  if @resource.new_record?
225
- @oauth_registration = true
226
- set_random_password
249
+ handle_new_resource
227
250
  end
228
251
 
229
252
  # sync user info with provider, update/generate auth token
230
253
  assign_provider_attrs(@resource, auth_hash)
231
254
 
232
255
  # assign any additional (whitelisted) attributes
233
- extra_params = whitelisted_params
234
- @resource.assign_attributes(extra_params) if extra_params
256
+ if assign_whitelisted_params?
257
+ extra_params = whitelisted_params
258
+ @resource.assign_attributes(extra_params) if extra_params
259
+ end
235
260
 
236
261
  @resource
237
262
  end
@@ -3,6 +3,7 @@
3
3
  module DeviseTokenAuth
4
4
  class PasswordsController < DeviseTokenAuth::ApplicationController
5
5
  before_action :set_user_by_token, only: [:update]
6
+ before_action :validate_redirect_url_param, only: [:create, :edit]
6
7
  skip_after_action :update_auth_header, only: [:create, :edit]
7
8
 
8
9
  # this action is responsible for generating password reset tokens and
@@ -10,15 +11,6 @@ module DeviseTokenAuth
10
11
  def create
11
12
  return render_create_error_missing_email unless resource_params[:email]
12
13
 
13
- # give redirect value from params priority
14
- @redirect_url = params.fetch(
15
- :redirect_url,
16
- DeviseTokenAuth.default_password_reset_url
17
- )
18
-
19
- return render_create_error_missing_redirect_url unless @redirect_url
20
- return render_create_error_not_allowed_redirect_url if blacklisted_redirect_url?
21
-
22
14
  @email = get_case_insensitive_field_from_resource_params(:email)
23
15
  @resource = find_resource(:uid, @email)
24
16
 
@@ -44,7 +36,7 @@ module DeviseTokenAuth
44
36
  # this is where users arrive after visiting the password reset confirmation link
45
37
  def edit
46
38
  # if a user is not found, return nil
47
- @resource = with_reset_password_token(resource_params[:reset_password_token])
39
+ @resource = resource_class.with_reset_password_token(resource_params[:reset_password_token])
48
40
 
49
41
  if @resource && @resource.reset_password_period_valid?
50
42
  client_id, token = @resource.create_token
@@ -63,7 +55,7 @@ module DeviseTokenAuth
63
55
  redirect_headers = build_redirect_headers(token,
64
56
  client_id,
65
57
  redirect_header_options)
66
- redirect_to(@resource.build_auth_url(params[:redirect_url],
58
+ redirect_to(@resource.build_auth_url(@redirect_url,
67
59
  redirect_headers))
68
60
  else
69
61
  render_edit_error
@@ -114,7 +106,7 @@ module DeviseTokenAuth
114
106
  render_error(401, I18n.t('devise_token_auth.passwords.missing_redirect_url'))
115
107
  end
116
108
 
117
- def render_create_error_not_allowed_redirect_url
109
+ def render_error_not_allowed_redirect_url
118
110
  response = {
119
111
  status: 'error',
120
112
  data: resource_data
@@ -178,15 +170,19 @@ module DeviseTokenAuth
178
170
  params.permit(*params_for_resource(:account_update))
179
171
  end
180
172
 
181
- def with_reset_password_token token
182
- recoverable = resource_class.with_reset_password_token(token)
183
-
184
- recoverable.reset_password_token = token if recoverable && recoverable.reset_password_token.present?
185
- recoverable
186
- end
187
-
188
173
  def render_not_found_error
189
174
  render_error(404, I18n.t('devise_token_auth.passwords.user_not_found', email: @email))
190
175
  end
176
+
177
+ def validate_redirect_url_param
178
+ # give redirect value from params priority
179
+ @redirect_url = params.fetch(
180
+ :redirect_url,
181
+ DeviseTokenAuth.default_password_reset_url
182
+ )
183
+
184
+ return render_create_error_missing_redirect_url unless @redirect_url
185
+ return render_error_not_allowed_redirect_url if blacklisted_redirect_url?
186
+ end
191
187
  end
192
188
  end
@@ -30,40 +30,37 @@ module DeviseTokenAuth
30
30
  # if whitelist is set, validate redirect_url against whitelist
31
31
  return render_create_error_redirect_url_not_allowed if blacklisted_redirect_url?
32
32
 
33
- begin
34
- # override email confirmation, must be sent manually from ctrl
35
- resource_class.set_callback('create', :after, :send_on_create_confirmation_instructions)
36
- resource_class.skip_callback('create', :after, :send_on_create_confirmation_instructions)
37
-
38
- if @resource.respond_to? :skip_confirmation_notification!
39
- # Fix duplicate e-mails by disabling Devise confirmation e-mail
40
- @resource.skip_confirmation_notification!
41
- end
33
+ # override email confirmation, must be sent manually from ctrl
34
+ resource_class.set_callback('create', :after, :send_on_create_confirmation_instructions)
35
+ resource_class.skip_callback('create', :after, :send_on_create_confirmation_instructions)
42
36
 
43
- if @resource.save
44
- yield @resource if block_given?
37
+ if @resource.respond_to? :skip_confirmation_notification!
38
+ # Fix duplicate e-mails by disabling Devise confirmation e-mail
39
+ @resource.skip_confirmation_notification!
40
+ end
45
41
 
46
- if @resource.confirmed?
47
- # email auth has been bypassed, authenticate user
48
- @client_id, @token = @resource.create_token
49
- @resource.save!
50
- update_auth_header
51
- else
52
- # user will require email authentication
53
- @resource.send_confirmation_instructions(
54
- client_config: params[:config_name],
55
- redirect_url: @redirect_url
56
- )
57
- end
58
-
59
- render_create_success
60
- else
61
- clean_up_passwords @resource
62
- render_create_error
42
+ if @resource.save
43
+ yield @resource if block_given?
44
+
45
+ unless @resource.confirmed?
46
+ # user will require email authentication
47
+ @resource.send_confirmation_instructions({
48
+ client_config: params[:config_name],
49
+ redirect_url: @redirect_url
50
+ })
51
+ end
52
+
53
+ if active_for_authentication?
54
+ # email auth has been bypassed, authenticate user
55
+ @client_id, @token = @resource.create_token
56
+ @resource.save!
57
+ update_auth_header
63
58
  end
64
- rescue ActiveRecord::RecordNotUnique
59
+
60
+ render_create_success
61
+ else
65
62
  clean_up_passwords @resource
66
- render_create_error_email_already_exists
63
+ render_create_error
67
64
  end
68
65
  end
69
66
 
@@ -145,15 +142,6 @@ module DeviseTokenAuth
145
142
  }, status: 422
146
143
  end
147
144
 
148
- def render_create_error_email_already_exists
149
- response = {
150
- status: 'error',
151
- data: resource_data
152
- }
153
- message = I18n.t('devise_token_auth.registrations.email_already_exists', email: @resource.email)
154
- render_error(422, message, response)
155
- end
156
-
157
145
  def render_update_success
158
146
  render json: {
159
147
  status: 'success',
@@ -208,5 +196,9 @@ module DeviseTokenAuth
208
196
  def validate_post_data which, message
209
197
  render_error(:unprocessable_entity, message, status: 'error') if which.empty?
210
198
  end
199
+
200
+ def active_for_authentication?
201
+ !@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?
202
+ end
211
203
  end
212
204
  end